diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2015-06-04 07:31:04 +0200 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2015-06-04 07:58:39 +0200 |
commit | f6d65e533c62f6deb21342d4901ece24497b433e (patch) | |
tree | f28adf0362d14bcd448f7b65a7aaf38650f923aa /vendor/oojs/oojs-ui/src/toolgroups/PopupToolGroup.js | |
parent | c27b2e832fe25651ef2410fae85b41072aae7519 (diff) |
Update to MediaWiki 1.25.1
Diffstat (limited to 'vendor/oojs/oojs-ui/src/toolgroups/PopupToolGroup.js')
-rw-r--r-- | vendor/oojs/oojs-ui/src/toolgroups/PopupToolGroup.js | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/vendor/oojs/oojs-ui/src/toolgroups/PopupToolGroup.js b/vendor/oojs/oojs-ui/src/toolgroups/PopupToolGroup.js new file mode 100644 index 00000000..0fbdf4fc --- /dev/null +++ b/vendor/oojs/oojs-ui/src/toolgroups/PopupToolGroup.js @@ -0,0 +1,187 @@ +/** + * Popup list of tools with an icon and optional label. + * + * @abstract + * @class + * @extends OO.ui.ToolGroup + * @mixins OO.ui.IconElement + * @mixins OO.ui.IndicatorElement + * @mixins OO.ui.LabelElement + * @mixins OO.ui.TitledElement + * @mixins OO.ui.ClippableElement + * @mixins OO.ui.TabIndexedElement + * + * @constructor + * @param {OO.ui.Toolbar} toolbar + * @param {Object} [config] Configuration options + * @cfg {string} [header] Text to display at the top of the pop-up + */ +OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) { + // Allow passing positional parameters inside the config object + if ( OO.isPlainObject( toolbar ) && config === undefined ) { + config = toolbar; + toolbar = config.toolbar; + } + + // Configuration initialization + config = config || {}; + + // Parent constructor + OO.ui.PopupToolGroup.super.call( this, toolbar, config ); + + // Properties + this.active = false; + this.dragging = false; + this.onBlurHandler = this.onBlur.bind( this ); + this.$handle = $( '<span>' ); + + // Mixin constructors + OO.ui.IconElement.call( this, config ); + OO.ui.IndicatorElement.call( this, config ); + OO.ui.LabelElement.call( this, config ); + OO.ui.TitledElement.call( this, config ); + OO.ui.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) ); + OO.ui.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) ); + + // Events + this.$handle.on( { + keydown: this.onHandleMouseKeyDown.bind( this ), + keyup: this.onHandleMouseKeyUp.bind( this ), + mousedown: this.onHandleMouseKeyDown.bind( this ), + mouseup: this.onHandleMouseKeyUp.bind( this ) + } ); + + // Initialization + this.$handle + .addClass( 'oo-ui-popupToolGroup-handle' ) + .append( this.$icon, this.$label, this.$indicator ); + // If the pop-up should have a header, add it to the top of the toolGroup. + // Note: If this feature is useful for other widgets, we could abstract it into an + // OO.ui.HeaderedElement mixin constructor. + if ( config.header !== undefined ) { + this.$group + .prepend( $( '<span>' ) + .addClass( 'oo-ui-popupToolGroup-header' ) + .text( config.header ) + ); + } + this.$element + .addClass( 'oo-ui-popupToolGroup' ) + .prepend( this.$handle ); +}; + +/* Setup */ + +OO.inheritClass( OO.ui.PopupToolGroup, OO.ui.ToolGroup ); +OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.IconElement ); +OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.IndicatorElement ); +OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.LabelElement ); +OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.TitledElement ); +OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.ClippableElement ); +OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.TabIndexedElement ); + +/* Methods */ + +/** + * @inheritdoc + */ +OO.ui.PopupToolGroup.prototype.setDisabled = function () { + // Parent method + OO.ui.PopupToolGroup.super.prototype.setDisabled.apply( this, arguments ); + + if ( this.isDisabled() && this.isElementAttached() ) { + this.setActive( false ); + } +}; + +/** + * Handle focus being lost. + * + * The event is actually generated from a mouseup/keyup, so it is not a normal blur event object. + * + * @param {jQuery.Event} e Mouse up or key up event + */ +OO.ui.PopupToolGroup.prototype.onBlur = function ( e ) { + // Only deactivate when clicking outside the dropdown element + if ( $( e.target ).closest( '.oo-ui-popupToolGroup' )[ 0 ] !== this.$element[ 0 ] ) { + this.setActive( false ); + } +}; + +/** + * @inheritdoc + */ +OO.ui.PopupToolGroup.prototype.onMouseKeyUp = function ( e ) { + // Only close toolgroup when a tool was actually selected + if ( + !this.isDisabled() && this.pressed && this.pressed === this.getTargetTool( e ) && + ( e.which === 1 || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) + ) { + this.setActive( false ); + } + return OO.ui.PopupToolGroup.super.prototype.onMouseKeyUp.call( this, e ); +}; + +/** + * Handle mouse up and key up events. + * + * @param {jQuery.Event} e Mouse up or key up event + */ +OO.ui.PopupToolGroup.prototype.onHandleMouseKeyUp = function ( e ) { + if ( + !this.isDisabled() && + ( e.which === 1 || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) + ) { + return false; + } +}; + +/** + * Handle mouse down and key down events. + * + * @param {jQuery.Event} e Mouse down or key down event + */ +OO.ui.PopupToolGroup.prototype.onHandleMouseKeyDown = function ( e ) { + if ( + !this.isDisabled() && + ( e.which === 1 || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) + ) { + this.setActive( !this.active ); + return false; + } +}; + +/** + * Switch into active mode. + * + * When active, mouseup events anywhere in the document will trigger deactivation. + */ +OO.ui.PopupToolGroup.prototype.setActive = function ( value ) { + value = !!value; + if ( this.active !== value ) { + this.active = value; + if ( value ) { + this.getElementDocument().addEventListener( 'mouseup', this.onBlurHandler, true ); + this.getElementDocument().addEventListener( 'keyup', this.onBlurHandler, true ); + + // Try anchoring the popup to the left first + this.$element.addClass( 'oo-ui-popupToolGroup-active oo-ui-popupToolGroup-left' ); + this.toggleClipping( true ); + if ( this.isClippedHorizontally() ) { + // Anchoring to the left caused the popup to clip, so anchor it to the right instead + this.toggleClipping( false ); + this.$element + .removeClass( 'oo-ui-popupToolGroup-left' ) + .addClass( 'oo-ui-popupToolGroup-right' ); + this.toggleClipping( true ); + } + } else { + this.getElementDocument().removeEventListener( 'mouseup', this.onBlurHandler, true ); + this.getElementDocument().removeEventListener( 'keyup', this.onBlurHandler, true ); + this.$element.removeClass( + 'oo-ui-popupToolGroup-active oo-ui-popupToolGroup-left oo-ui-popupToolGroup-right' + ); + this.toggleClipping( false ); + } + } +}; |