2013-07-02 20:40:54 +00:00
|
|
|
/*!
|
|
|
|
* VisualEditor UserInterface MWParameterSearchWidget class.
|
|
|
|
*
|
|
|
|
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
|
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an ve.ui.MWParameterSearchWidget object.
|
|
|
|
*
|
|
|
|
* @class
|
|
|
|
* @extends ve.ui.SearchWidget
|
|
|
|
*
|
|
|
|
* @constructor
|
2013-09-25 10:21:09 +00:00
|
|
|
* @param {Object} [config] Configuration options
|
2013-07-02 20:40:54 +00:00
|
|
|
*/
|
|
|
|
ve.ui.MWParameterSearchWidget = function VeUiMWParameterSearchWidget( template, config ) {
|
|
|
|
// Configuration intialization
|
2013-09-20 07:09:06 +00:00
|
|
|
config = ve.extendObject( {
|
2013-07-02 20:40:54 +00:00
|
|
|
'placeholder': ve.msg( 'visualeditor-parameter-input-placeholder' )
|
2013-09-20 07:09:06 +00:00
|
|
|
}, config );
|
2013-07-02 20:40:54 +00:00
|
|
|
|
|
|
|
// Parent constructor
|
|
|
|
ve.ui.SearchWidget.call( this, config );
|
|
|
|
|
|
|
|
// Properties
|
|
|
|
this.template = template;
|
|
|
|
this.index = [];
|
|
|
|
|
|
|
|
// Events
|
|
|
|
this.template.connect( this, { 'add': 'buildIndex', 'remove': 'buildIndex' } );
|
|
|
|
|
|
|
|
// Initialization
|
|
|
|
this.$.addClass( 've-ui-mwParameterSearchWidget' );
|
|
|
|
this.buildIndex();
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Inheritance */
|
|
|
|
|
|
|
|
ve.inheritClass( ve.ui.MWParameterSearchWidget, ve.ui.SearchWidget );
|
|
|
|
|
|
|
|
/* Events */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @event select
|
|
|
|
* @param {string|null} name Parameter name or null if no item is selected
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Methods */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle select widget select events.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @param {string} value New value
|
|
|
|
*/
|
|
|
|
ve.ui.MWParameterSearchWidget.prototype.onQueryChange = function () {
|
|
|
|
// Parent method
|
|
|
|
ve.ui.SearchWidget.prototype.onQueryChange.call( this );
|
|
|
|
|
|
|
|
// Populate
|
|
|
|
this.addResults();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle select widget select events.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @param {ve.ui.OptionWidget} item Selected item
|
|
|
|
* @emits select
|
|
|
|
*/
|
|
|
|
ve.ui.MWParameterSearchWidget.prototype.onResultsSelect = function ( item ) {
|
|
|
|
this.emit( 'select', item && item.getData() ? item.getData().name : null );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build a serchable index of parameters.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @param {ve.dm.MWTemplateSpecModel} spec Template specification
|
|
|
|
*/
|
|
|
|
ve.ui.MWParameterSearchWidget.prototype.buildIndex = function () {
|
|
|
|
var i, len, name, label, aliases, description,
|
|
|
|
spec = this.template.getSpec(),
|
|
|
|
knownParams = spec.getParameterNames();
|
|
|
|
|
|
|
|
this.index.length = 0;
|
|
|
|
for ( i = 0, len = knownParams.length; i < len; i++ ) {
|
|
|
|
name = knownParams[i];
|
2013-07-11 00:33:21 +00:00
|
|
|
// Skip parameters already in use
|
|
|
|
if ( this.template.hasParameter( name ) ) {
|
2013-07-02 20:40:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
label = spec.getParameterLabel( name );
|
|
|
|
aliases = spec.getParameterAliases( name );
|
|
|
|
description = spec.getParameterDescription( name );
|
|
|
|
|
|
|
|
this.index.push( {
|
2013-08-30 22:20:21 +00:00
|
|
|
'text': [ name, label, aliases.join( ' ' ), description ].join( ' ' ),
|
2013-07-02 20:40:54 +00:00
|
|
|
'name': name,
|
|
|
|
'label': label,
|
|
|
|
'aliases': aliases,
|
|
|
|
'description': description
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Re-populate
|
|
|
|
this.onQueryChange();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle media query response events.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
*/
|
|
|
|
ve.ui.MWParameterSearchWidget.prototype.addResults = function () {
|
|
|
|
var i, len, item,
|
|
|
|
exactMatch = false,
|
2013-07-10 19:04:11 +00:00
|
|
|
value = this.query.getValue().trim(),
|
2013-07-02 20:40:54 +00:00
|
|
|
query = value.toLowerCase(),
|
|
|
|
items = [];
|
|
|
|
|
|
|
|
for ( i = 0, len = this.index.length; i < len; i++ ) {
|
|
|
|
item = this.index[i];
|
|
|
|
if ( item.text.indexOf( query ) >= 0 ) {
|
|
|
|
items.push( new ve.ui.MWParameterResultWidget( item, { '$$': this.$$ } ) );
|
2013-07-10 19:04:11 +00:00
|
|
|
if ( item.name === value || ve.indexOf( value, item.aliases ) !== -1 ) {
|
2013-07-02 20:40:54 +00:00
|
|
|
exactMatch = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-10 19:04:11 +00:00
|
|
|
if ( !exactMatch && value.length && !this.template.hasParameter( value ) ) {
|
2013-07-02 20:40:54 +00:00
|
|
|
items.unshift( new ve.ui.MWParameterResultWidget( {
|
|
|
|
'name': value,
|
|
|
|
'label': value,
|
|
|
|
'aliases': [],
|
|
|
|
'description': ve.msg( 'visualeditor-parameter-search-unknown' )
|
|
|
|
}, { '$$': this.$$ } ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !items.length ) {
|
|
|
|
items.push( new ve.ui.MWParameterResultWidget(
|
|
|
|
{
|
|
|
|
'name': null,
|
|
|
|
'label': '',
|
|
|
|
'aliases': [],
|
|
|
|
'description': ve.msg( 'visualeditor-parameter-search-no-unused' )
|
|
|
|
},
|
|
|
|
{ '$$': this.$$, 'disabled': true }
|
|
|
|
) );
|
|
|
|
}
|
|
|
|
|
|
|
|
this.results.addItems( items );
|
|
|
|
if ( query.length ) {
|
Single-click insertion
Objectives:
* Reduce the number of clicks and mouse maneuvers required to insert
media, references or template parameters
* Make use of highlighting with mouse movement or arrow key presses,
similar to menus, to suggest action when clicked
* Improve the way media search results look and feel
Changes:
ve.ui.SelectWidget.js
* Add mouseleave handler to un-highlight when the mouse exits the widget
* Document highlight events (already being emitted)
ve.ui.SearchWidget.js
* Propagate both select and highlight events from results widget
* Make arrow keys change highlight instead of selection
* Get rid of enter event, make enter key select highlighted item instead
* Provide direct access to results widget through getResults method
ve.ui.MenuWidget.js
* Use the selected item as a starting point if nothing is currently
highlighted when adjusting the highlight position
ve.ui.Dialog.js
* Add footless option to hide the foot element and make the body extend
all the way down to the bottom
* Remove applyButton, which only some dialogs need, and should be creating
themselves, along with other buttons as needed
ve.ui.Widget.css
* Change highlight and selected colors of option widgets to match other
selection colors used elsewhere
* Leave selected and highlighted widget looking selected
ve.ui.Frame.css
* Add background color to combat any color that might have been applied to
the frame body in the imported CSS from the parent frame
ve.ui.Dialog.css
* Add rules for footless mode
ve.ui.MWReferenceResultWidget.js,
ve.ui.MWParameterResultWidget.js,
ve.ui.MWMediaResultWidget.js
* Allow highlighting
ve.ui.MWParamterSearchWidget.js
* Switch from selecting the first item when filtering to highlighting
ve-mw/ve.ui.Widget.js
* Adjust media result widget styling to better match other elements
ve.ui.MWTransclusionDialog.js,
ve.ui.MWReferenceListDialog.js,
ve.ui.MWReferenceEditDialog.js,
ve.ui.MWMetaDialog.js
ve.ui.MWMediaEditDialog.js
* Add apply button, as per it being removed from parent class
ve.ui.MWTransclusionDialog.js,
ve.ui.MWReferenceInsertDialog.js,
ve.ui.MWMediaInsertDialog.js
* Insert parameter/reference/media on select, instead of clicking an
insert button
* Use 'insert' instead of 'apply' as argument for close method
Bug: 50774
Bug: 51143
Change-Id: Ia18e79f1f8df2540f465468edb01f5ce989bf843
2013-07-15 21:07:53 +00:00
|
|
|
this.results.highlightItem( this.results.getFirstSelectableItem() );
|
2013-07-02 20:40:54 +00:00
|
|
|
}
|
|
|
|
};
|