/*!
- * OOjs UI v0.12.4
+ * OOjs UI v0.12.5
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-08-13T21:01:12Z
+ * Date: 2015-08-19T02:10:25Z
*/
@-webkit-keyframes oo-ui-progressBarWidget-slide {
from {
.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
display: inline-block;
vertical-align: middle;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-buttonElement-frameless {
display: inline-block;
}
.oo-ui-iconElement .oo-ui-iconElement-icon,
.oo-ui-iconElement.oo-ui-iconElement-icon {
- opacity: 0.8;
background-size: contain;
background-position: center center;
+ background-repeat: no-repeat;
+}
+.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-iconElement.oo-ui-iconElement-icon {
+ opacity: 0.8;
}
.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
- opacity: 0.8;
background-size: contain;
background-position: center center;
+ background-repeat: no-repeat;
+}
+.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
+.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
+ opacity: 0.8;
}
.oo-ui-lookupElement > .oo-ui-menuSelectWidget {
z-index: 1;
.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
display: block;
position: absolute;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
display: inline-block;
.oo-ui-toolGroup .oo-ui-tool-link {
text-decoration: none;
}
-.oo-ui-toolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
- background-position: center center;
- background-repeat: no-repeat;
-}
.oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
margin-left: 0;
}
.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
position: absolute;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
cursor: default;
position: absolute;
z-index: 4;
}
-.oo-ui-popupToolGroup .oo-ui-toolGroup-tools .oo-ui-iconElement-icon {
- background-repeat: no-repeat;
- background-position: center center;
-}
.oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
display: block;
}
.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
position: absolute;
- background-repeat: no-repeat;
- background-position: center center;
}
.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
.oo-ui-iconWidget {
display: inline-block;
vertical-align: middle;
- background-position: center center;
- background-repeat: no-repeat;
line-height: 2.5em;
height: 1.875em;
width: 1.875em;
.oo-ui-indicatorWidget {
display: inline-block;
vertical-align: middle;
- background-position: center center;
- background-repeat: no-repeat;
line-height: 2.5em;
height: 0.9375em;
width: 0.9375em;
position: absolute;
top: 0;
height: 100%;
- background-repeat: no-repeat;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
.oo-ui-dropdownWidget {
display: inline-block;
position: relative;
- margin: 0.25em 0;
width: 100%;
max-width: 50em;
margin-right: 0.5em;
.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
position: absolute;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-dropdownWidget > .oo-ui-menuSelectWidget {
z-index: 1;
display: inline-block;
position: relative;
vertical-align: middle;
- margin: 0.25em 0;
width: 100%;
max-width: 50em;
margin-right: 0.5em;
.oo-ui-selectFileWidget-handle > .oo-ui-iconElement-icon,
.oo-ui-selectFileWidget-handle > .oo-ui-selectFileWidget-clearButton {
position: absolute;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-selectFileWidget-handle > input[type="file"] {
position: absolute;
.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
float: left;
background-position: right center;
- background-repeat: no-repeat;
}
.oo-ui-outlineControlsWidget-items {
float: left;
/*!
- * OOjs UI v0.12.4
+ * OOjs UI v0.12.5
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-08-13T21:01:12Z
+ * Date: 2015-08-19T02:10:25Z
*/
@-webkit-keyframes oo-ui-progressBarWidget-slide {
from {
.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
display: inline-block;
vertical-align: middle;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-buttonElement-frameless {
display: inline-block;
box-shadow: inset 0 0 0 1px #1f4999;
border-color: #1f4999;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
color: #1f4999;
border-color: #1f4999;
box-shadow: inset 0 0 0 1px #005946;
border-color: #005946;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
color: #005946;
border-color: #005946;
box-shadow: inset 0 0 0 1px #73100a;
border-color: #73100a;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
color: #73100a;
border-color: #73100a;
box-shadow: inset 0 0 0 1px #ffffff;
border-color: #347bff;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
color: #ffffff;
background-color: #1f4999;
box-shadow: inset 0 0 0 1px #ffffff;
border-color: #00af89;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
color: #ffffff;
background-color: #005946;
box-shadow: inset 0 0 0 1px #ffffff;
border-color: #d11d13;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
color: #ffffff;
background-color: #73100a;
.oo-ui-iconElement.oo-ui-iconElement-icon {
background-size: contain;
background-position: center center;
+ background-repeat: no-repeat;
}
.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
background-size: contain;
background-position: center center;
+ background-repeat: no-repeat;
}
.oo-ui-lookupElement > .oo-ui-menuSelectWidget {
z-index: 1;
.oo-ui-fieldLayout-messages > li {
margin: 0;
padding: 0;
+ display: table;
}
.oo-ui-fieldLayout-messages .oo-ui-iconWidget {
- margin-right: 0.5em;
+ display: table-cell;
+ border-right: 0.5em solid transparent;
}
.oo-ui-fieldLayout-messages .oo-ui-labelWidget {
+ display: table-cell;
padding: 0;
line-height: 1.875em;
vertical-align: middle;
.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
display: block;
position: absolute;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
display: inline-block;
.oo-ui-toolGroup .oo-ui-tool-link {
text-decoration: none;
}
-.oo-ui-toolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
- background-position: center center;
- background-repeat: no-repeat;
-}
.oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
margin-left: 0;
}
.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
position: absolute;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
cursor: default;
position: absolute;
z-index: 4;
}
-.oo-ui-popupToolGroup .oo-ui-toolGroup-tools .oo-ui-iconElement-icon {
- background-repeat: no-repeat;
- background-position: center center;
-}
.oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
display: block;
}
.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
position: absolute;
- background-repeat: no-repeat;
- background-position: center center;
}
.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
.oo-ui-iconWidget {
display: inline-block;
vertical-align: middle;
- background-position: center center;
- background-repeat: no-repeat;
line-height: 2.5em;
height: 1.875em;
width: 1.875em;
.oo-ui-indicatorWidget {
display: inline-block;
vertical-align: middle;
- background-position: center center;
- background-repeat: no-repeat;
line-height: 2.5em;
height: 0.9375em;
width: 0.9375em;
position: absolute;
top: 0;
height: 100%;
- background-repeat: no-repeat;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
.oo-ui-dropdownWidget {
display: inline-block;
position: relative;
- margin: 0.25em 0;
width: 100%;
max-width: 50em;
background: #ffffff;
.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
position: absolute;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-dropdownWidget > .oo-ui-menuSelectWidget {
z-index: 1;
display: inline-block;
position: relative;
vertical-align: middle;
- margin: 0.25em 0;
width: 100%;
max-width: 50em;
margin-right: 0.5em;
.oo-ui-selectFileWidget-handle > .oo-ui-iconElement-icon,
.oo-ui-selectFileWidget-handle > .oo-ui-selectFileWidget-clearButton {
position: absolute;
- background-position: center center;
- background-repeat: no-repeat;
}
.oo-ui-selectFileWidget-handle > input[type="file"] {
position: absolute;
.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
float: left;
background-position: right center;
- background-repeat: no-repeat;
}
.oo-ui-outlineControlsWidget-items {
float: left;
/*!
- * OOjs UI v0.12.4
+ * OOjs UI v0.12.5
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-08-13T21:01:04Z
+ * Date: 2015-08-19T02:10:17Z
*/
( function ( OO ) {
};
};
+/**
+ * Proxy for `node.addEventListener( eventName, handler, true )`, if the browser supports it.
+ * Otherwise falls back to non-capturing event listeners.
+ *
+ * @param {HTMLElement} node
+ * @param {string} eventName
+ * @param {Function} handler
+ */
+OO.ui.addCaptureEventListener = function ( node, eventName, handler ) {
+ if ( node.addEventListener ) {
+ node.addEventListener( eventName, handler, true );
+ } else {
+ node.attachEvent( 'on' + eventName, handler );
+ }
+};
+
+/**
+ * Proxy for `node.removeEventListener( eventName, handler, true )`, if the browser supports it.
+ * Otherwise falls back to non-capturing event listeners.
+ *
+ * @param {HTMLElement} node
+ * @param {string} eventName
+ * @param {Function} handler
+ */
+OO.ui.removeCaptureEventListener = function ( node, eventName, handler ) {
+ if ( node.addEventListener ) {
+ node.removeEventListener( eventName, handler, true );
+ } else {
+ node.detachEvent( 'on' + eventName, handler );
+ }
+};
+
/**
* Reconstitute a JavaScript object corresponding to a widget created by
* the PHP implementation.
this.$element.addClass( 'oo-ui-buttonElement-pressed' );
// Run the mouseup handler no matter where the mouse is when the button is let go, so we can
// reliably remove the pressed class
- this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
+ OO.ui.addCaptureEventListener( this.getElementDocument(), 'mouseup', this.onMouseUpHandler );
// Prevent change of focus unless specifically configured otherwise
if ( this.constructor.static.cancelButtonMouseDownEvents ) {
return false;
}
this.$element.removeClass( 'oo-ui-buttonElement-pressed' );
// Stop listening for mouseup, since we only needed this once
- this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
+ OO.ui.removeCaptureEventListener( this.getElementDocument(), 'mouseup', this.onMouseUpHandler );
};
/**
this.$element.addClass( 'oo-ui-buttonElement-pressed' );
// Run the keyup handler no matter where the key is when the button is let go, so we can
// reliably remove the pressed class
- this.getElementDocument().addEventListener( 'keyup', this.onKeyUpHandler, true );
+ OO.ui.addCaptureEventListener( this.getElementDocument(), 'keyup', this.onKeyUpHandler );
};
/**
}
this.$element.removeClass( 'oo-ui-buttonElement-pressed' );
// Stop listening for keyup, since we only needed this once
- this.getElementDocument().removeEventListener( 'keyup', this.onKeyUpHandler, true );
+ OO.ui.removeCaptureEventListener( this.getElementDocument(), 'keyup', this.onKeyUpHandler );
};
/**
};
/**
- * LookupElement is a mixin that creates a {@link OO.ui.TextInputMenuSelectWidget menu} of suggested values for
+ * LookupElement is a mixin that creates a {@link OO.ui.FloatingMenuSelectWidget menu} of suggested values for
* a {@link OO.ui.TextInputWidget text input widget}. Suggested values are based on the characters the user types
* into the text input field and, in general, the menu is only displayed when the user types. If a suggested value is chosen
* from the lookup menu, that value becomes the value of the input field.
// Properties
this.$overlay = config.$overlay || this.$element;
- this.lookupMenu = new OO.ui.TextInputMenuSelectWidget( this, {
+ this.lookupMenu = new OO.ui.FloatingMenuSelectWidget( {
widget: this,
input: this,
- $container: config.$container
+ $container: config.$container || this.$element
} );
this.allowSuggestionsWhenEmpty = config.allowSuggestionsWhenEmpty || false;
* Get lookup menu.
*
* @private
- * @return {OO.ui.TextInputMenuSelectWidget}
+ * @return {OO.ui.FloatingMenuSelectWidget}
*/
OO.ui.mixin.LookupElement.prototype.getLookupMenu = function () {
return this.lookupMenu;
this.pressed = this.getTargetTool( e );
if ( this.pressed ) {
this.pressed.setActive( true );
- this.getElementDocument().addEventListener( 'mouseup', this.onCapturedMouseKeyUpHandler, true );
- this.getElementDocument().addEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, true );
+ OO.ui.addCaptureEventListener( this.getElementDocument(), 'mouseup', this.onCapturedMouseKeyUpHandler );
+ OO.ui.addCaptureEventListener( this.getElementDocument(), 'keyup', this.onCapturedMouseKeyUpHandler );
}
return false;
}
* @param {Event} e Mouse up or key up event
*/
OO.ui.ToolGroup.prototype.onCapturedMouseKeyUp = function ( e ) {
- this.getElementDocument().removeEventListener( 'mouseup', this.onCapturedMouseKeyUpHandler, true );
- this.getElementDocument().removeEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, true );
+ OO.ui.removeCaptureEventListener( this.getElementDocument(), 'mouseup', this.onCapturedMouseKeyUpHandler );
+ OO.ui.removeCaptureEventListener( this.getElementDocument(), 'keyup', this.onCapturedMouseKeyUpHandler );
// onMouseKeyUp may be called a second time, depending on where the mouse is when the button is
// released, but since `this.pressed` will no longer be true, the second call will be ignored.
this.onMouseKeyUp( e );
}, this );
};
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.getReadyProcess = function ( data ) {
+ data = data || {};
+
+ // Parent method
+ return OO.ui.MessageDialog.parent.prototype.getReadyProcess.call( this, data )
+ .next( function () {
+ // Focus the primary action button
+ var actions = this.actions.get();
+ actions = actions.filter( function ( action ) {
+ return action.getFlags().indexOf( 'primary' ) > -1;
+ } );
+ if ( actions.length > 0 ) {
+ actions[0].$button.focus();
+ }
+ }, this );
+};
+
/**
* @inheritdoc
*/
special = this.actions.getSpecial();
others = this.actions.getOthers();
+
if ( special.safe ) {
this.$actions.append( special.safe.$element );
special.safe.toggleFramed( false );
* @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a "help" icon will appear
* in the upper-right corner of the rendered field; clicking it will display the text in a popup.
* For important messages, you are advised to use `notices`, as they are always shown.
+ *
+ * @throws {Error} An error is thrown if no widget is specified
*/
OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
// Allow passing positional parameters inside the config object
fieldWidget = config.fieldWidget;
}
+ // Make sure we have required constructor arguments
+ if ( fieldWidget === undefined ) {
+ throw new Error( 'Widget not found' );
+ }
+
var hasInputWidget = fieldWidget.constructor.static.supportsSimpleLabel,
div, i;
if ( this.active !== value ) {
this.active = value;
if ( value ) {
- this.getElementDocument().addEventListener( 'mouseup', this.onBlurHandler, true );
- this.getElementDocument().addEventListener( 'keyup', this.onBlurHandler, true );
+ OO.ui.addCaptureEventListener( this.getElementDocument(), 'mouseup', this.onBlurHandler );
+ OO.ui.addCaptureEventListener( this.getElementDocument(), 'keyup', this.onBlurHandler );
this.$clippable.css( 'left', '' );
// Try anchoring the popup to the left first
} );
}
} else {
- this.getElementDocument().removeEventListener( 'mouseup', this.onBlurHandler, true );
- this.getElementDocument().removeEventListener( 'keyup', this.onBlurHandler, true );
+ OO.ui.removeCaptureEventListener( this.getElementDocument(), 'mouseup', this.onBlurHandler );
+ OO.ui.removeCaptureEventListener( this.getElementDocument(), 'keyup', this.onBlurHandler );
this.$element.removeClass(
'oo-ui-popupToolGroup-active oo-ui-popupToolGroup-left oo-ui-popupToolGroup-right'
);
// Properties
this.allowArbitrary = !!config.allowArbitrary;
this.$overlay = config.$overlay || this.$element;
- this.menu = new OO.ui.MenuSelectWidget( $.extend(
+ this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend(
{
widget: this,
$input: this.$input,
+ $container: this.$element,
filterFromInput: true,
disabled: this.isDisabled()
},
*
* @constructor
* @param {Object} [config] Configuration options
- * @cfg {Object} [menu] Configuration options to pass to menu widget
+ * @cfg {Object} [menu] Configuration options to pass to {@link OO.ui.FloatingMenuSelectWidget menu select widget}
+ * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where
+ * the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the
+ * containing `<div>` and has a larger area. By default, the menu uses relative positioning.
*/
OO.ui.DropdownWidget = function OoUiDropdownWidget( config ) {
// Configuration initialization
// Properties (must be set before TabIndexedElement constructor call)
this.$handle = this.$( '<span>' );
+ this.$overlay = config.$overlay || this.$element;
// Mixin constructors
OO.ui.mixin.IconElement.call( this, config );
OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );
// Properties
- this.menu = new OO.ui.MenuSelectWidget( $.extend( { widget: this }, config.menu ) );
+ this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend( {
+ widget: this,
+ $container: this.$element
+ }, config.menu ) );
// Events
this.$handle.on( {
.append( this.$icon, this.$label, this.$indicator );
this.$element
.addClass( 'oo-ui-dropdownWidget' )
- .append( this.$handle, this.menu.$element );
+ .append( this.$handle );
+ this.$overlay.append( this.menu.$element );
};
/* Setup */
* pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer'
* (the value must contain only numbers); when RegExp, a regular expression that must match the
* value for it to be considered valid; when Function, a function receiving the value as parameter
- * that must return true, or promise that resolves, for it to be considered valid.
+ * that must return true, or promise resolving to true, for it to be considered valid.
*/
OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
// Configuration initialization
*
* @constructor
* @param {Object} [config] Configuration options
- * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.MenuSelectWidget menu select widget}.
+ * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.FloatingMenuSelectWidget menu select widget}.
* @cfg {Object} [input] Configuration options to pass to the {@link OO.ui.TextInputWidget text input widget}.
* @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where
* the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the
role: 'combobox',
'aria-autocomplete': 'list'
} );
- this.menu = new OO.ui.TextInputMenuSelectWidget( this.input, $.extend(
+ this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend(
{
widget: this,
input: this.input,
+ $container: this.input.$element,
disabled: this.isDisabled()
},
config.menu
/**
* Get the combobox's menu.
- * @return {OO.ui.TextInputMenuSelectWidget} Menu widget
+ * @return {OO.ui.FloatingMenuSelectWidget} Menu widget
*/
OO.ui.ComboBoxWidget.prototype.getMenu = function () {
return this.menu;
*/
OO.ui.PopupWidget.prototype.bindMouseDownListener = function () {
// Capture clicks outside popup
- this.getElementWindow().addEventListener( 'mousedown', this.onMouseDownHandler, true );
+ OO.ui.addCaptureEventListener( this.getElementWindow(), 'mousedown', this.onMouseDownHandler );
};
/**
* @private
*/
OO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {
- this.getElementWindow().removeEventListener( 'mousedown', this.onMouseDownHandler, true );
+ OO.ui.removeCaptureEventListener( this.getElementWindow(), 'mousedown', this.onMouseDownHandler );
};
/**
* @private
*/
OO.ui.PopupWidget.prototype.bindKeyDownListener = function () {
- this.getElementWindow().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
+ OO.ui.addCaptureEventListener( this.getElementWindow(), 'keydown', this.onDocumentKeyDownHandler );
};
/**
* @private
*/
OO.ui.PopupWidget.prototype.unbindKeyDownListener = function () {
- this.getElementWindow().removeEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
+ OO.ui.removeCaptureEventListener( this.getElementWindow(), 'keydown', this.onDocumentKeyDownHandler );
};
/**
/**
* SearchWidgets combine a {@link OO.ui.TextInputWidget text input field}, where users can type a search query,
- * and a {@link OO.ui.TextInputMenuSelectWidget menu} of search results, which is displayed beneath the query
+ * and a menu of search results, which is displayed beneath the query
* field. Unlike {@link OO.ui.mixin.LookupElement lookup menus}, search result menus are always visible to the user.
* Users can choose an item from the menu or type a query into the text field to search for a matching result item.
* In general, search widgets are used inside a separate {@link OO.ui.Dialog dialog} window.
if ( item && item.isSelectable() ) {
this.pressItem( item );
this.selecting = item;
- this.getElementDocument().addEventListener(
+ OO.ui.addCaptureEventListener(
+ this.getElementDocument(),
'mouseup',
- this.onMouseUpHandler,
- true
+ this.onMouseUpHandler
);
- this.getElementDocument().addEventListener(
+ OO.ui.addCaptureEventListener(
+ this.getElementDocument(),
'mousemove',
- this.onMouseMoveHandler,
- true
+ this.onMouseMoveHandler
);
}
}
this.selecting = null;
}
- this.getElementDocument().removeEventListener(
- 'mouseup',
- this.onMouseUpHandler,
- true
- );
- this.getElementDocument().removeEventListener(
- 'mousemove',
- this.onMouseMoveHandler,
- true
- );
+ OO.ui.removeCaptureEventListener( this.getElementDocument(), 'mouseup',
+ this.onMouseUpHandler );
+ OO.ui.removeCaptureEventListener( this.getElementDocument(), 'mousemove',
+ this.onMouseMoveHandler );
return false;
};
* @protected
*/
OO.ui.SelectWidget.prototype.bindKeyDownListener = function () {
- this.getElementWindow().addEventListener( 'keydown', this.onKeyDownHandler, true );
+ OO.ui.addCaptureEventListener( this.getElementWindow(), 'keydown', this.onKeyDownHandler );
};
/**
* @protected
*/
OO.ui.SelectWidget.prototype.unbindKeyDownListener = function () {
- this.getElementWindow().removeEventListener( 'keydown', this.onKeyDownHandler, true );
+ OO.ui.removeCaptureEventListener( this.getElementWindow(), 'keydown', this.onKeyDownHandler );
};
/**
* @protected
*/
OO.ui.SelectWidget.prototype.bindKeyPressListener = function () {
- this.getElementWindow().addEventListener( 'keypress', this.onKeyPressHandler, true );
+ OO.ui.addCaptureEventListener( this.getElementWindow(), 'keypress', this.onKeyPressHandler );
};
/**
* @protected
*/
OO.ui.SelectWidget.prototype.unbindKeyPressListener = function () {
- this.getElementWindow().removeEventListener( 'keypress', this.onKeyPressHandler, true );
+ OO.ui.removeCaptureEventListener( this.getElementWindow(), 'keypress', this.onKeyPressHandler );
this.clearKeyPressBuffer();
};
// Auto-hide
if ( this.autoHide ) {
- this.getElementDocument().addEventListener(
- 'mousedown', this.onDocumentMouseDownHandler, true
- );
+ OO.ui.addCaptureEventListener( this.getElementDocument(), 'mousedown', this.onDocumentMouseDownHandler );
}
} else {
this.unbindKeyDownListener();
this.unbindKeyPressListener();
- this.getElementDocument().removeEventListener(
- 'mousedown', this.onDocumentMouseDownHandler, true
- );
+ OO.ui.removeCaptureEventListener( this.getElementDocument(), 'mousedown', this.onDocumentMouseDownHandler );
this.toggleClipping( false );
}
}
};
/**
- * TextInputMenuSelectWidget is a menu that is specially designed to be positioned beneath
- * a {@link OO.ui.TextInputWidget text input} field. The menu's position is automatically
- * calculated and maintained when the menu is toggled or the window is resized.
+ * FloatingMenuSelectWidget is a menu that will stick under a specified
+ * container, even when it is inserted elsewhere in the document (for example,
+ * in a OO.ui.Window's $overlay). This is sometimes necessary to prevent the
+ * menu from being clipped too aggresively.
+ *
+ * The menu's position is automatically calculated and maintained when the menu
+ * is toggled or the window is resized.
+ *
* See OO.ui.ComboBoxWidget for an example of a widget that uses this class.
*
* @class
* @extends OO.ui.MenuSelectWidget
*
* @constructor
- * @param {OO.ui.TextInputWidget} inputWidget Text input widget to provide menu for
+ * @param {OO.ui.Widget} [inputWidget] Widget to provide the menu for.
+ * Deprecated, omit this parameter and specify `$container` instead.
* @param {Object} [config] Configuration options
- * @cfg {jQuery} [$container=input.$element] Element to render menu under
+ * @cfg {jQuery} [$container=inputWidget.$element] Element to render menu under
*/
-OO.ui.TextInputMenuSelectWidget = function OoUiTextInputMenuSelectWidget( inputWidget, config ) {
- // Allow passing positional parameters inside the config object
+OO.ui.FloatingMenuSelectWidget = function OoUiFloatingMenuSelectWidget( inputWidget, config ) {
+ // Allow 'inputWidget' parameter and config for backwards compatibility
if ( OO.isPlainObject( inputWidget ) && config === undefined ) {
config = inputWidget;
inputWidget = config.inputWidget;
config = config || {};
// Parent constructor
- OO.ui.TextInputMenuSelectWidget.parent.call( this, config );
+ OO.ui.FloatingMenuSelectWidget.parent.call( this, config );
// Properties
- this.inputWidget = inputWidget;
+ this.inputWidget = inputWidget; // For backwards compatibility
this.$container = config.$container || this.inputWidget.$element;
this.onWindowResizeHandler = this.onWindowResize.bind( this );
// Initialization
+ this.$element.addClass( 'oo-ui-floatingMenuSelectWidget' );
+ // For backwards compatibility
this.$element.addClass( 'oo-ui-textInputMenuSelectWidget' );
};
/* Setup */
-OO.inheritClass( OO.ui.TextInputMenuSelectWidget, OO.ui.MenuSelectWidget );
+OO.inheritClass( OO.ui.FloatingMenuSelectWidget, OO.ui.MenuSelectWidget );
+
+// For backwards compatibility
+OO.ui.TextInputMenuSelectWidget = OO.ui.FloatingMenuSelectWidget;
/* Methods */
* @private
* @param {jQuery.Event} e Window resize event
*/
-OO.ui.TextInputMenuSelectWidget.prototype.onWindowResize = function () {
+OO.ui.FloatingMenuSelectWidget.prototype.onWindowResize = function () {
this.position();
};
/**
* @inheritdoc
*/
-OO.ui.TextInputMenuSelectWidget.prototype.toggle = function ( visible ) {
+OO.ui.FloatingMenuSelectWidget.prototype.toggle = function ( visible ) {
visible = visible === undefined ? !this.isVisible() : !!visible;
var change = visible !== this.isVisible();
}
// Parent method
- OO.ui.TextInputMenuSelectWidget.parent.prototype.toggle.call( this, visible );
+ OO.ui.FloatingMenuSelectWidget.parent.prototype.toggle.call( this, visible );
if ( change ) {
if ( this.isVisible() ) {
* @private
* @chainable
*/
-OO.ui.TextInputMenuSelectWidget.prototype.position = function () {
+OO.ui.FloatingMenuSelectWidget.prototype.position = function () {
var $container = this.$container,
pos = OO.ui.Element.static.getRelativePosition( $container, this.$element.offsetParent() );