/*!
- * OOjs UI v0.1.0-pre (51f922ba17)
+ * OOjs UI v0.1.0-pre (46ccd5b3a7)
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: Fri Feb 28 2014 16:33:26 GMT-0800 (PST)
+ * Date: Wed Mar 12 2014 17:44:18 GMT-0700 (PDT)
*/
( function () {
OO.ui.bind = $.proxy;
+/**
+ * @property {Object}
+ */
+OO.ui.Keys = {
+ 'UNDEFINED': 0,
+ 'BACKSPACE': 8,
+ 'DELETE': 46,
+ 'LEFT': 37,
+ 'RIGHT': 39,
+ 'UP': 38,
+ 'DOWN': 40,
+ 'ENTER': 13,
+ 'END': 35,
+ 'HOME': 36,
+ 'TAB': 9,
+ 'PAGEUP': 33,
+ 'PAGEDOWN': 34,
+ 'ESCAPE': 27,
+ 'SHIFT': 16,
+ 'SPACE': 32
+};
+
/**
* Get the user's language and any fallback languages.
*
* In environments that provide a localization system, this function should be overridden to
* return the user's language(s). The default implementation returns English (en) only.
*
- * @returns {string[]} Language codes, in descending order of priority
+ * @return {string[]} Language codes, in descending order of priority
*/
OO.ui.getUserLanguages = function () {
return [ 'en' ];
* @param {Object.<string,Mixed>} obj Object keyed by language code
* @param {string|null} [lang] Language code, if omitted or null defaults to any user language
* @param {string} [fallback] Fallback code, used if no matching language can be found
- * @returns {Mixed} Local value
+ * @return {Mixed} Local value
*/
OO.ui.getLocalValue = function ( obj, lang, fallback ) {
var i, len, langs;
* @abstract
* @param {string} key Message key
* @param {Mixed...} [params] Message parameters
- * @returns {string} Translated message with parameters substituted
+ * @return {string} Translated message with parameters substituted
*/
OO.ui.msg = function ( key ) {
var message = messages[key], params = Array.prototype.slice.call( arguments, 1 );
return message;
};
+/** */
OO.ui.deferMsg = function ( key ) {
return function () {
return OO.ui.msg( key );
};
};
+/** */
OO.ui.resolveMsg = function ( msg ) {
if ( $.isFunction( msg ) ) {
return msg();
};
} )();
-
-// Add more as you need
-OO.ui.Keys = {
- 'UNDEFINED': 0,
- 'BACKSPACE': 8,
- 'DELETE': 46,
- 'LEFT': 37,
- 'RIGHT': 39,
- 'UP': 38,
- 'DOWN': 40,
- 'ENTER': 13,
- 'END': 35,
- 'HOME': 36,
- 'TAB': 9,
- 'PAGEUP': 33,
- 'PAGEDOWN': 34,
- 'ESCAPE': 27,
- 'SHIFT': 16,
- 'SPACE': 32
-};
/**
* DOM element abstraction.
*
- * @class
* @abstract
+ * @class
*
* @constructor
* @param {Object} [config] Configuration options
/* Static Properties */
-/**
- * @static
- * @property
- * @inheritable
- */
OO.ui.Element.static = {};
/**
/* Static Methods */
/**
- * Gets a jQuery function within a specific document.
+ * Get a jQuery function within a specific document.
*
* @static
* @param {jQuery|HTMLElement|HTMLDocument|Window} context Context to bind the function to
* @param {OO.ui.Frame} [frame] Frame of the document context
- * @returns {Function} Bound jQuery function
+ * @return {Function} Bound jQuery function
*/
OO.ui.Element.getJQuery = function ( context, frame ) {
function wrapper( selector ) {
*
* @static
* @param {jQuery|HTMLElement|HTMLDocument|Window} obj Object to get the document for
- * @returns {HTMLDocument} Document object
+ * @return {HTMLDocument} Document object
* @throws {Error} If context is invalid
*/
OO.ui.Element.getDocument = function ( obj ) {
*
* @static
* @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the window for
- * @returns {Window} Window object
+ * @return {Window} Window object
*/
OO.ui.Element.getWindow = function ( obj ) {
var doc = this.getDocument( obj );
*
* @static
* @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the direction for
- * @returns {string} Text direction, either `ltr` or `rtl`
+ * @return {string} Text direction, either `ltr` or `rtl`
*/
OO.ui.Element.getDir = function ( obj ) {
var isDoc, isWin;
* @param {Window} from Window of the child frame
* @param {Window} [to=window] Window of the parent frame
* @param {Object} [offset] Offset to start with, used internally
- * @returns {Object} Offset object, containing left and top properties
+ * @return {Object} Offset object, containing left and top properties
*/
OO.ui.Element.getFrameOffset = function ( from, to, offset ) {
var i, len, frames, frame, rect;
* @static
* @param {jQuery} $from
* @param {jQuery} $to
- * @returns {Object} Translated position coordinates, containing top and left properties
+ * @return {Object} Translated position coordinates, containing top and left properties
*/
OO.ui.Element.getRelativePosition = function ( $from, $to ) {
var from = $from.offset(),
};
/**
- * Scroll element into view
+ * Scroll element into view.
*
* @static
* @param {HTMLElement} el Element to scroll into view
*
* Override this method to base the result on instance information.
*
- * @returns {string} HTML tag name
+ * @return {string} HTML tag name
*/
OO.ui.Element.prototype.getTagName = function () {
return this.constructor.static.tagName;
/**
* Get the DOM document.
*
- * @returns {HTMLDocument} Document object
+ * @return {HTMLDocument} Document object
*/
OO.ui.Element.prototype.getElementDocument = function () {
return OO.ui.Element.getDocument( this.$element );
/**
* Get the DOM window.
*
- * @returns {Window} Window object
+ * @return {Window} Window object
*/
OO.ui.Element.prototype.getElementWindow = function () {
return OO.ui.Element.getWindow( this.$element );
/**
* Get closest scrollable container.
*
- * @method
* @see #static-method-getClosestScrollableContainer
*/
OO.ui.Element.prototype.getClosestScrollableElementContainer = function () {
/**
* Get group element is in.
*
- * @returns {OO.ui.GroupElement|null} Group element, null if none
+ * @return {OO.ui.GroupElement|null} Group element, null if none
*/
OO.ui.Element.prototype.getElementGroup = function () {
return this.elementGroup;
};
/**
- * Scroll element into view
+ * Scroll element into view.
*
- * @method
* @see #static-method-scrollIntoView
* @param {Object} [config={}]
*/
/* Static Properties */
+/**
+ * @static
+ * @inheritdoc
+ */
OO.ui.Frame.static.tagName = 'iframe';
/* Events */
* There are two ways to specify a title: set the static `title` property or provide a `title`
* property in the configuration options. The latter will override the former.
*
- * @class
* @abstract
+ * @class
* @extends OO.ui.Element
* @mixins OO.EventEmitter
*
/**
* Check if window is visible.
*
- * @method
- * @returns {boolean} Window is visible
+ * @return {boolean} Window is visible
*/
OO.ui.Window.prototype.isVisible = function () {
return this.visible;
/**
* Check if window is opening.
*
- * @method
- * @returns {boolean} Window is opening
+ * @return {boolean} Window is opening
*/
OO.ui.Window.prototype.isOpening = function () {
return this.opening;
/**
* Check if window is closing.
*
- * @method
- * @returns {boolean} Window is closing
+ * @return {boolean} Window is closing
*/
OO.ui.Window.prototype.isClosing = function () {
return this.closing;
/**
* Get the window frame.
*
- * @method
- * @returns {OO.ui.Frame} Frame of window
+ * @return {OO.ui.Frame} Frame of window
*/
OO.ui.Window.prototype.getFrame = function () {
return this.frame;
/**
* Get the title of the window.
*
- * @returns {string} Title text
+ * @return {string} Title text
*/
OO.ui.Window.prototype.getTitle = function () {
return this.title;
/**
* Get the window icon.
*
- * @returns {string} Symbolic name of icon
+ * @return {string} Symbolic name of icon
*/
OO.ui.Window.prototype.getIcon = function () {
return this.icon;
};
/**
- * Set the position of window to fit with contents..
+ * Set the position of window to fit with contents.
*
* @param {string} left Left offset
* @param {string} top Top offset
*
* Once this method is called, this.$$ can be used to create elements within the frame.
*
- * @method
* @fires initialize
* @chainable
*/
*
* When you override this method, you must call the parent method at the very beginning.
*
- * @method
* @abstract
* @param {Object} [data] Window opening data
*/
*
* When you override this method, you must call the parent method at the very end.
*
- * @method
* @abstract
* @param {Object} [data] Window closing data
*/
*
* Do not override this method. See #setup for a way to make changes each time the window opens.
*
- * @method
* @param {Object} [data] Window opening data
* @fires open
* @chainable
*
* See #teardown for a way to do something each time the window closes.
*
- * @method
* @param {Object} [data] Window closing data
* @fires close
* @chainable
this.factory = factory;
/**
- * List of all windows associated with this window set
+ * List of all windows associated with this window set.
+ *
* @property {OO.ui.Window[]}
*/
this.windowList = [];
/**
* Mapping of OO.ui.Window objects created by name from the #factory.
+ *
* @property {Object}
*/
this.windows = {};
/**
* Handle a window that's being opened.
*
- * @method
* @param {OO.ui.Window} win Window that's being opened
* @param {Object} [config] Window opening information
* @fires opening
/**
* Handle a window that's been opened.
*
- * @method
* @param {OO.ui.Window} win Window that's been opened
* @param {Object} [config] Window opening information
* @fires open
/**
* Handle a window that's being closed.
*
- * @method
* @param {OO.ui.Window} win Window that's being closed
* @param {Object} [config] Window closing information
* @fires closing
/**
* Handle a window that's been closed.
*
- * @method
* @param {OO.ui.Window} win Window that's been closed
* @param {Object} [config] Window closing information
* @fires close
/**
* Get the current window.
*
- * @method
- * @returns {OO.ui.Window} Current window
+ * @return {OO.ui.Window} Current window
*/
OO.ui.WindowSet.prototype.getCurrentWindow = function () {
return this.currentWindow;
throw new Error( 'Unknown window: ' + name );
}
if ( !( name in this.windows ) ) {
- win = this.windows[name] = this.factory.create( name, this, { '$': this.$ } );
+ win = this.windows[name] = this.createWindow( name );
this.addWindow( win );
}
return this.windows[name];
};
+/**
+ * Create a window for use in this window set.
+ *
+ * @param {string} name Symbolic name of window
+ * @return {OO.ui.Window} Window with specified name
+ */
+OO.ui.WindowSet.prototype.createWindow = function ( name ) {
+ return this.factory.create( name, { '$': this.$ } );
+};
+
/**
* Add a given window to this window set.
*
this.$element.append( win.$element );
};
/**
- * Modal dialog box.
- *
- * @class
* @abstract
+ * @class
* @extends OO.ui.Window
*
* @constructor
* @param {Object} [config] Configuration options
* @cfg {boolean} [footless] Hide foot
- * @cfg {boolean} [small] Make the dialog small
+ * @cfg {string} [size='large'] Symbolic name of dialog size, `small`, `medium` or `large`
*/
OO.ui.Dialog = function OoUiDialog( config ) {
// Configuration initialization
- config = config || {};
+ config = $.extend( { 'size': 'large' }, config );
// Parent constructor
OO.ui.Window.call( this, config );
// Properties
this.visible = false;
this.footless = !!config.footless;
- this.small = !!config.small;
+ this.size = null;
this.onWindowMouseWheelHandler = OO.ui.bind( this.onWindowMouseWheel, this );
this.onDocumentKeyDownHandler = OO.ui.bind( this.onDocumentKeyDown, this );
// Initialization
this.$element.addClass( 'oo-ui-dialog' );
+ this.setSize( config.size );
};
/* Inheritance */
*/
OO.ui.Dialog.static.name = '';
+/**
+ * Map of symbolic size names and CSS classes.
+ *
+ * @static
+ * @property {Object}
+ * @inheritable
+ */
+OO.ui.Dialog.static.sizeCssClasses = {
+ 'small': 'oo-ui-dialog-small',
+ 'medium': 'oo-ui-dialog-medium',
+ 'large': 'oo-ui-dialog-large'
+};
+
/* Methods */
/**
* Handle close button click events.
- *
- * @method
*/
OO.ui.Dialog.prototype.onCloseButtonClick = function () {
this.close( { 'action': 'cancel' } );
/**
* Handle window mouse wheel events.
*
- * @method
* @param {jQuery.Event} e Mouse wheel event
*/
OO.ui.Dialog.prototype.onWindowMouseWheel = function () {
/**
* Handle document key down events.
*
- * @method
* @param {jQuery.Event} e Key down event
*/
OO.ui.Dialog.prototype.onDocumentKeyDown = function ( e ) {
/**
* Handle frame document key down events.
*
- * @method
* @param {jQuery.Event} e Key down event
*/
OO.ui.Dialog.prototype.onFrameDocumentKeyDown = function ( e ) {
this.$element.addClass( 'oo-ui-dialog-open' );
};
+/**
+ * Set dialog size.
+ *
+ * @param {string} [size='large'] Symbolic name of dialog size, `small`, `medium` or `large`
+ */
+OO.ui.Dialog.prototype.setSize = function ( size ) {
+ var name, state, cssClass,
+ sizeCssClasses = OO.ui.Dialog.static.sizeCssClasses;
+
+ if ( !sizeCssClasses[size] ) {
+ size = 'large';
+ }
+ this.size = size;
+ for ( name in sizeCssClasses ) {
+ state = name === size;
+ cssClass = sizeCssClasses[name];
+ this.$element.toggleClass( cssClass, state );
+ if ( this.frame.$content ) {
+ this.frame.$content.toggleClass( cssClass, state );
+ }
+ }
+};
+
/**
* @inheritdoc
*/
if ( this.footless ) {
this.frame.$content.addClass( 'oo-ui-dialog-content-footless' );
}
- if ( this.small ) {
- this.$frame.addClass( 'oo-ui-window-frame-small' );
- }
this.closeButton.$element.addClass( 'oo-ui-window-closeButton' );
this.$head.append( this.closeButton.$element );
};
/**
* Container for elements.
*
- * @class
* @abstract
+ * @class
* @extends OO.ui.Element
* @mixins OO.EventEmitter
*
/**
* User interface control.
*
- * @class
* @abstract
+ * @class
* @extends OO.ui.Element
* @mixins OO.EventEmitter
*
/**
* Check if the widget is disabled.
*
- * @method
* @param {boolean} Button is disabled
*/
OO.ui.Widget.prototype.isDisabled = function () {
/**
* Update the disabled state, in case of changes in parent widget.
*
- * @method
* @chainable
*/
OO.ui.Widget.prototype.updateDisabled = function () {
*
* This should probably change the widgets's appearance and prevent it from being used.
*
- * @method
* @param {boolean} disabled Disable widget
* @chainable
*/
/**
* Generic toolbar tool.
*
- * @class
* @abstract
+ * @class
* @extends OO.ui.Widget
* @mixins OO.ui.IconedElement
*
/* Static Properties */
+/**
+ * @static
+ * @inheritdoc
+ */
OO.ui.Tool.static.tagName = 'span';
/**
/**
* Check if this tool is compatible with given data.
*
- * @method
* @static
+ * @method
* @inheritable
* @param {Mixed} data Data to check
- * @returns {boolean} Tool can be used with data
+ * @return {boolean} Tool can be used with data
*/
OO.ui.Tool.static.isCompatibleWith = function () {
return false;
* This is an abstract method that must be overridden in a concrete subclass.
*
* @abstract
- * @method
*/
OO.ui.Tool.prototype.onUpdateState = function () {
throw new Error(
* This is an abstract method that must be overridden in a concrete subclass.
*
* @abstract
- * @method
*/
OO.ui.Tool.prototype.onSelect = function () {
throw new Error(
/**
* Check if the button is active.
*
- * @method
* @param {boolean} Button is active
*/
OO.ui.Tool.prototype.isActive = function () {
/**
* Make the button appear active or inactive.
*
- * @method
* @param {boolean} state Make button appear active
*/
OO.ui.Tool.prototype.setActive = function ( state ) {
/**
* Get the tool title.
*
- * @method
* @param {string|Function} title Title text or a function that returns text
* @chainable
*/
/**
* Get the tool title.
*
- * @method
- * @returns {string} Title text
+ * @return {string} Title text
*/
OO.ui.Tool.prototype.getTitle = function () {
return this.title;
/**
* Get the tool's symbolic name.
*
- * @method
- * @returns {string} Symbolic name of tool
+ * @return {string} Symbolic name of tool
*/
OO.ui.Tool.prototype.getName = function () {
return this.constructor.static.name;
/**
* Update the title.
- *
- * @method
*/
OO.ui.Tool.prototype.updateTitle = function () {
var titleTooltips = this.toolGroup.constructor.static.titleTooltips,
/**
* Destroy tool.
- *
- * @method
*/
OO.ui.Tool.prototype.destroy = function () {
this.toolbar.disconnect( this );
/**
* Get the tool factory.
*
- * @method
- * @returns {OO.Factory} Tool factory
+ * @return {OO.Factory} Tool factory
*/
OO.ui.Toolbar.prototype.getToolFactory = function () {
return this.toolFactory;
/**
* Handles mouse down events.
*
- * @method
* @param {jQuery.Event} e Mouse down event
*/
OO.ui.Toolbar.prototype.onMouseDown = function ( e ) {
* Setup toolbar.
*
* Tools can be specified in the following ways:
- * - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
- * - All tools in a group: `{ 'group': 'group-name' }`
- * - All tools: `'*'` - Using this will make the group a list with a "More" label by default
*
- * @method
+ * - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
+ * - All tools in a group: `{ 'group': 'group-name' }`
+ * - All tools: `'*'` - Using this will make the group a list with a "More" label by default
+ *
* @param {Object.<string,Array>} groups List of tool group configurations
* @param {Array|string} [groups.include] Tools to include
* @param {Array|string} [groups.exclude] Tools to exclude
* This is a stub that should be overridden to provide access to accelerator information.
*
* @param {string} name Symbolic name of tool
- * @returns {string|undefined} Tool accelerator label if available
+ * @return {string|undefined} Tool accelerator label if available
*/
OO.ui.Toolbar.prototype.getToolAccelerator = function () {
return undefined;
/* Methods */
+/** */
OO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, demote ) {
var i, len, included, promoted, demoted,
auto = [],
* Get a flat list of names from a list of names or groups.
*
* Tools can be specified in the following ways:
- * - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
- * - All tools in a group: `{ 'group': 'group-name' }`
- * - All tools: `'*'`
+ *
+ * - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
+ * - All tools in a group: `{ 'group': 'group-name' }`
+ * - All tools: `'*'`
*
* @private
* @param {Array|string} collection List of tools
* @param {Object} [used] Object with names that should be skipped as properties; extracted
- * names will be added as properties
+ * names will be added as properties
* @return {string[]} List of extracted names
*/
OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
/**
* Collection of tools.
*
- * @class
+ * Tools can be specified in the following ways:
+ *
+ * - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
+ * - All tools in a group: `{ 'group': 'group-name' }`
+ * - All tools: `'*'`
+ *
* @abstract
+ * @class
* @extends OO.ui.Widget
* @mixins OO.ui.GroupElement
*
- * Tools can be specified in the following ways:
- * - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
- * - All tools in a group: `{ 'group': 'group-name' }`
- * - All tools: `'*'`
- *
* @constructor
* @param {OO.ui.Toolbar} toolbar
* @param {Object} [config] Configuration options
/**
* Handle mouse down events.
*
- * @method
* @param {jQuery.Event} e Mouse down event
*/
OO.ui.ToolGroup.prototype.onMouseDown = function ( e ) {
/**
* Handle captured mouse up events.
*
- * @method
* @param {Event} e Mouse up event
*/
OO.ui.ToolGroup.prototype.onCapturedMouseUp = function ( e ) {
/**
* Handle mouse up events.
*
- * @method
* @param {jQuery.Event} e Mouse up event
*/
OO.ui.ToolGroup.prototype.onMouseUp = function ( e ) {
/**
* Handle mouse over events.
*
- * @method
* @param {jQuery.Event} e Mouse over event
*/
OO.ui.ToolGroup.prototype.onMouseOver = function ( e ) {
/**
* Handle mouse out events.
*
- * @method
* @param {jQuery.Event} e Mouse out event
*/
OO.ui.ToolGroup.prototype.onMouseOut = function ( e ) {
* Only tool links are considered, which prevents other elements in the tool such as popups from
* triggering tool group interactions.
*
- * @method
* @private
* @param {jQuery.Event} e
- * @returns {OO.ui.Tool|null} Tool, `null` if none was found
+ * @return {OO.ui.Tool|null} Tool, `null` if none was found
*/
OO.ui.ToolGroup.prototype.getTargetTool = function ( e ) {
var tool,
* Handle tool registry register events.
*
* If a tool is registered after the group is created, we must repopulate the list to account for:
+ *
* - a tool being added that may be included
* - a tool already included being overridden
*
/**
* Add and remove tools based on configuration.
- *
- * @method
*/
OO.ui.ToolGroup.prototype.populate = function () {
var i, len, name, tool,
/**
* Destroy tool group.
- *
- * @method
*/
OO.ui.ToolGroup.prototype.destroy = function () {
var name;
this.ignoreFocus = false;
this.stackLayout = new OO.ui.StackLayout( { '$': this.$, 'continuous': !!config.continuous } );
this.autoFocus = !!config.autoFocus;
+ this.outlineVisible = false;
this.outlined = !!config.outlined;
if ( this.outlined ) {
this.editable = !!config.editable;
this.gridLayout = new OO.ui.GridLayout(
[this.outlinePanel, this.stackLayout], { '$': this.$, 'widths': [1, 2] }
);
+ this.outlineVisible = true;
if ( this.editable ) {
this.outlineControlsWidget = new OO.ui.OutlineControlsWidget(
this.outlineWidget,
if ( this.outlined ) {
this.outlineWidget.connect( this, { 'select': 'onOutlineWidgetSelect' } );
}
- // Event 'focus' does not bubble, but 'focusin' does
- this.stackLayout.onDOMEvent( 'focusin', OO.ui.bind( this.onStackLayoutFocus, this ) );
+ if ( this.autoFocus ) {
+ // Event 'focus' does not bubble, but 'focusin' does
+ this.stackLayout.onDOMEvent( 'focusin', OO.ui.bind( this.onStackLayoutFocus, this ) );
+ }
// Initialization
this.$element.addClass( 'oo-ui-bookletLayout' );
return this.editable;
};
+/**
+ * Check if booklet has editing controls.
+ *
+ * @method
+ * @returns {boolean} Booklet is outlined
+ */
+OO.ui.BookletLayout.prototype.isOutlineVisible = function () {
+ return this.outlined && this.outlineVisible;
+};
+
+/**
+ * Hide or show the outline.
+ *
+ * @param {boolean} [show] Show outline, omit to invert current state
+ * @chainable
+ */
+OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {
+ if ( this.outlined ) {
+ show = show === undefined ? !this.outlineVisible : !!show;
+ this.outlineVisible = show;
+ this.gridLayout.layout( show ? [ 1, 2 ] : [ 0, 1 ], [ 1 ] );
+ }
+
+ return this;
+};
+
/**
* Get the outline widget.
*
var selectedItem,
page = this.pages[name];
- if ( this.outlined ) {
- selectedItem = this.outlineWidget.getSelectedItem();
- if ( selectedItem && selectedItem.getData() !== name ) {
- this.outlineWidget.selectItem( this.outlineWidget.getItemFromData( name ) );
+ if ( name !== this.currentPageName ) {
+ if ( this.outlined ) {
+ selectedItem = this.outlineWidget.getSelectedItem();
+ if ( selectedItem && selectedItem.getData() !== name ) {
+ this.outlineWidget.selectItem( this.outlineWidget.getItemFromData( name ) );
+ }
}
- }
-
- if ( page ) {
- if ( this.currentPageName && this.pages[this.currentPageName] ) {
- this.pages[this.currentPageName].setActive( false );
+ if ( page ) {
+ if ( this.currentPageName && this.pages[this.currentPageName] ) {
+ this.pages[this.currentPageName].setActive( false );
+ }
+ this.currentPageName = name;
+ this.stackLayout.setItem( page );
+ page.setActive( true );
+ this.emit( 'set', page );
}
- this.currentPageName = name;
- this.stackLayout.setItem( page );
- page.setActive( true );
- this.emit( 'set', page );
}
};
* @chainable
*/
OO.ui.StackLayout.prototype.setItem = function ( item ) {
- if ( !this.continuous ) {
- this.$items.css( 'display', '' );
- }
- if ( $.inArray( item, this.items ) !== -1 ) {
+ if ( item !== this.currentItem ) {
if ( !this.continuous ) {
- item.$element.css( 'display', 'block' );
+ this.$items.css( 'display', '' );
}
- } else {
- item = null;
+ if ( $.inArray( item, this.items ) !== -1 ) {
+ if ( !this.continuous ) {
+ item.$element.css( 'display', 'block' );
+ }
+ } else {
+ item = null;
+ }
+ this.currentItem = item;
+ this.emit( 'set', item );
}
- this.currentItem = item;
- this.emit( 'set', item );
return this;
};
return this;
};
+/**
+ * Creates an OO.ui.IconWidget object.
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.IconedElement
+ * @mixins OO.ui.TitledElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.IconWidget = function OoUiIconWidget( config ) {
+ // Config intialization
+ config = config || {};
+
+ // Parent constructor
+ OO.ui.Widget.call( this, config );
+
+ // Mixin constructors
+ OO.ui.IconedElement.call( this, this.$element, config );
+ OO.ui.TitledElement.call( this, this.$element, config );
+
+ // Initialization
+ this.$element.addClass( 'oo-ui-iconWidget' );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.ui.IconWidget, OO.ui.Widget );
+
+OO.mixinClass( OO.ui.IconWidget, OO.ui.IconedElement );
+OO.mixinClass( OO.ui.IconWidget, OO.ui.TitledElement );
+
+/* Static Properties */
+
+OO.ui.IconWidget.static.tagName = 'span';
+/**
+ * Creates an OO.ui.IndicatorWidget object.
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.IndicatedElement
+ * @mixins OO.ui.TitledElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.IndicatorWidget = function OoUiIndicatorWidget( config ) {
+ // Config intialization
+ config = config || {};
+
+ // Parent constructor
+ OO.ui.Widget.call( this, config );
+
+ // Mixin constructors
+ OO.ui.IndicatedElement.call( this, this.$element, config );
+ OO.ui.TitledElement.call( this, this.$element, config );
+
+ // Initialization
+ this.$element.addClass( 'oo-ui-indicatorWidget' );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.ui.IndicatorWidget, OO.ui.Widget );
+
+OO.mixinClass( OO.ui.IndicatorWidget, OO.ui.IndicatedElement );
+OO.mixinClass( OO.ui.IndicatorWidget, OO.ui.TitledElement );
+
+/* Static Properties */
+
+OO.ui.IndicatorWidget.static.tagName = 'span';
/**
* Container for multiple related buttons.
*
return this;
};
/**
- * Create an OO.ui.ButtonSelect object.
+ * Create an OO.ui.ButtonOptionWidget object.
*
* @class
* @extends OO.ui.OptionWidget
* @cfg {string} [icon] Symbolic name of icon
* @cfg {boolean} [multiline=false] Allow multiple lines of text
* @cfg {boolean} [autosize=false] Automatically resize to fit content
+ * @cfg {boolean} [maxRows=10] Maximum number of rows to make visible when autosizing
*/
OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
- config = config || {};
+ config = $.extend( { 'maxRows': 10 }, config );
// Parent constructor
OO.ui.InputWidget.call( this, config );
this.pending = 0;
this.multiline = !!config.multiline;
this.autosize = !!config.autosize;
+ this.maxRows = config.maxRows;
// Events
this.$input.on( 'keypress', OO.ui.bind( this.onKeyPress, this ) );
+ this.$element.on( 'DOMNodeInsertedIntoDocument', OO.ui.bind( this.onElementAttach, this ) );
// Initialization
this.$element.addClass( 'oo-ui-textInputWidget' );
}
};
+/**
+ * Handles element attach events.
+ *
+ * @param {jQuery.Event} e Element attach event
+ */
+OO.ui.TextInputWidget.prototype.onElementAttach = function () {
+ this.adjustSize();
+};
+
/**
* @inheritdoc
*/
OO.ui.TextInputWidget.prototype.onEdit = function () {
- var $clone, scrollHeight, innerHeight, outerHeight;
+ this.adjustSize();
+
+ // Parent method
+ return OO.ui.InputWidget.prototype.onEdit.call( this );
+};
+
+/**
+ * Automatically adjust the size of the text input.
+ *
+ * This only affects multi-line inputs that are auto-sized.
+ *
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.adjustSize = function() {
+ var $clone, scrollHeight, innerHeight, outerHeight, maxInnerHeight, idealHeight;
- // Automatic size adjustment
if ( this.multiline && this.autosize ) {
$clone = this.$input.clone()
.val( this.$input.val() )
$clone.css( 'height', '' );
innerHeight = $clone.innerHeight();
outerHeight = $clone.outerHeight();
+ // Measure max rows height
+ $clone.attr( 'rows', this.maxRows ).css( 'height', 'auto' );
+ maxInnerHeight = $clone.innerHeight();
+ $clone.removeAttr( 'rows' ).css( 'height', '' );
$clone.remove();
+ idealHeight = Math.min( maxInnerHeight, scrollHeight );
// Only apply inline height when expansion beyond natural height is needed
this.$input.css(
'height',
// Use the difference between the inner and outer height as a buffer
- scrollHeight > outerHeight ? scrollHeight + ( outerHeight - innerHeight ) : ''
+ idealHeight > outerHeight ? idealHeight + ( outerHeight - innerHeight ) : ''
);
}
-
- // Parent method
- return OO.ui.InputWidget.prototype.onEdit.call( this );
+ return this;
};
/**