mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-25 23:05:35 +00:00
1572ec1569
This is a major refactor of user interface context, frame, dialog and inspector classes, including adding several new classes which generalize managing inspectors/dialogs (which are now subclasses of window). New classes: * ve.ui.Window.js - base class for inspector and dialog classes * ve.ui.WindowSet.js - manages mutually exclusive windows, used by surface and context for dialogs and inspectors respectively * ve.ui.DialogFactory - generates dialogs * ve.ui.IconButtonWidget - used in inspector for buttons in the head Refactored classes: * ve.ui.Context - moved inspector management to window set * ve.ui.Frame - made iframes initialize asynchronously * ve.ui.Dialog and ve.ui.Inspector - moved initialization to async initialize method Other interesting bits: ve.ui.*Icons*.css, *.svg, *.png, *.ai * Merged icon stylesheets so all icons are available inside windows * Renamed inspector icon to window ve.ui.*.css * Reorganized styles so that different windows can include only what they need * Moved things to where they belonged (some things were in strange places) ve.init.Target.js, ve.init.mw.ViewPageTarget.js, ve.init.sa.Target.js * Removed dialog management - dialogs are managed by the surface now ve.ui.*Dialog.js * Renamed title message static property * Added registration ve.ui.*Inspector.js * Switch to accept surface object rather than context, which conforms to the more general window class without losing any functionality (in fact, most of the time the surface was what we actually wanted) ve.ui.MenuWidget.js, ve.ui.MWLinkTargetInputWidget.js * Using surface overly rather than passing an overlay around through constructors Change-Id: Ifd16a1003ff44c48ee7b2c66928cf9cc858b2564
161 lines
3.8 KiB
JavaScript
161 lines
3.8 KiB
JavaScript
/*!
|
|
* VisualEditor UserInterface DropdownTool class.
|
|
*
|
|
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
*/
|
|
|
|
/**
|
|
* UserInterface dropdown tool.
|
|
*
|
|
* @abstract
|
|
* @class
|
|
* @extends ve.ui.Tool
|
|
* @constructor
|
|
* @param {ve.ui.Toolbar} toolbar
|
|
* @param {Object} [config] Config options
|
|
*/
|
|
ve.ui.DropdownTool = function VeUiDropdownTool( toolbar, config ) {
|
|
// Parent constructor
|
|
ve.ui.Tool.call( this, toolbar, config );
|
|
|
|
// Properties
|
|
this.menu = new ve.ui.MenuWidget();
|
|
this.$icon = this.$$( '<div class="ve-ui-dropdownTool-icon ve-ui-icon-down"></div>' );
|
|
this.$label = this.$$( '<div class="ve-ui-dropdownTool-label"></div>' );
|
|
this.$labelText = this.$$( '<span> </span>' );
|
|
|
|
// Events
|
|
this.$$( document )
|
|
.add( this.toolbar.getSurface().getView().$ )
|
|
.mousedown( ve.bind( this.onBlur, this ) );
|
|
this.$.on( {
|
|
'mousedown': ve.bind( this.onMouseDown, this ),
|
|
'mouseup': ve.bind( this.onMouseUp, this )
|
|
} );
|
|
this.menu.on( 'select', ve.bind( this.onMenuItemSelect, this ) );
|
|
|
|
// Initialization
|
|
this.$
|
|
.append( this.$icon, this.$label, this.menu.$ )
|
|
.addClass(
|
|
've-ui-dropdownTool ve-ui-dropdownTool-' +
|
|
( this.constructor.static.cssName || this.constructor.static.name )
|
|
);
|
|
if ( this.constructor.static.titleMessage ) {
|
|
this.$.attr( 'title', ve.msg( this.constructor.static.titleMessage ) );
|
|
}
|
|
this.$label.append( this.$labelText );
|
|
};
|
|
|
|
/* Inheritance */
|
|
|
|
ve.inheritClass( ve.ui.DropdownTool, ve.ui.Tool );
|
|
|
|
/* Methods */
|
|
|
|
/**
|
|
* Handle the mouse button being pressed.
|
|
*
|
|
* @method
|
|
* @param {jQuery.Event} e Mouse down event
|
|
*/
|
|
ve.ui.DropdownTool.prototype.onMouseDown = function ( e ) {
|
|
if ( e.which === 1 ) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Handle the mouse button being released.
|
|
*
|
|
* @method
|
|
* @param {jQuery.Event} e Mouse up event
|
|
*/
|
|
ve.ui.DropdownTool.prototype.onMouseUp = function ( e ) {
|
|
if ( e.which === 1 ) {
|
|
// Toggle menu
|
|
if ( this.menu.isVisible() ) {
|
|
this.menu.hide();
|
|
} else {
|
|
this.menu.show();
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Handle focus being lost.
|
|
*
|
|
* The event is actually generated from a mousedown on an element outside the menu, so it is not
|
|
* a normal blur event object.
|
|
*
|
|
* @method
|
|
* @param {jQuery.Event} e Mouse down event
|
|
*/
|
|
ve.ui.DropdownTool.prototype.onBlur = function ( e ) {
|
|
if ( e.which === 1 ) {
|
|
this.menu.hide();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Handle one of the items in the menu being selected.
|
|
*
|
|
* This should not be overridden in subclasses, it simple connects events from the internal menu
|
|
* to the onSelect method.
|
|
*
|
|
* @method
|
|
* @param {ve.ui.MenuItemWidget|null} item Selected menu item, null if none is selected
|
|
*/
|
|
ve.ui.DropdownTool.prototype.onMenuItemSelect = function ( item ) {
|
|
if ( this.toolbar.getSurface().isEnabled() ) {
|
|
this.setLabel( item && item.label );
|
|
this.onSelect( item );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Handle dropdown option being selected.
|
|
*
|
|
* This is an abstract method that must be overridden in a concrete subclass.
|
|
*
|
|
* @abstract
|
|
* @method
|
|
* @param {ve.ui.MenuItemWidget} item Menu item
|
|
*/
|
|
ve.ui.DropdownTool.prototype.onSelect = function () {
|
|
throw new Error(
|
|
've.ui.DropdownTool.onSelect not implemented in this subclass:' + this.constructor
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Handle toolbar state being cleared.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ui.DropdownTool.prototype.onClearState = function () {
|
|
this.setLabel();
|
|
};
|
|
|
|
/**
|
|
* Set the label.
|
|
*
|
|
* If the label value is empty, undefined or only contains whitespace an empty label will be used.
|
|
*
|
|
* @method
|
|
* @param {jQuery|string} [value] Label text
|
|
* @chainable
|
|
*/
|
|
ve.ui.DropdownTool.prototype.setLabel = function ( value ) {
|
|
if ( typeof value === 'string' && value.length && /[^\s]*/.test( value ) ) {
|
|
this.$labelText.text( value );
|
|
} else if ( value instanceof jQuery ) {
|
|
this.$labelText.empty().append( value );
|
|
} else {
|
|
this.$labelText.html( ' ' );
|
|
}
|
|
return this;
|
|
};
|