mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-12-02 09:57:01 +00:00
b3281bd87a
Also... * Update OOjs UI to v0.1.0-pre (5ffe63d088) * Make template parameter text boxes shorter (3em down from 10em) * Reorder extendObject calls to not modify incoming config objects * Allow level option to default to 0, rather than specifically defining it * Use icon button widgets with remove icons for parameter, placeholder, template and content removal buttons Change-Id: I29db9d814fab5cf4debd0fc7bab6f51475cb0f94
233 lines
5.7 KiB
JavaScript
233 lines
5.7 KiB
JavaScript
/*!
|
||
* VisualEditor UserInterface SpecialCharacterInspector class.
|
||
*
|
||
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
||
* @license The MIT License (MIT); see LICENSE.txt
|
||
*/
|
||
|
||
/**
|
||
* Special character inspector.
|
||
*
|
||
* @class
|
||
* @extends ve.ui.Inspector
|
||
*
|
||
* @constructor
|
||
* @param {ve.ui.WindowSet} windowSet Window set this inspector is part of
|
||
* @param {Object} [config] Configuration options
|
||
*/
|
||
ve.ui.SpecialCharacterInspector = function VeUiSpecialCharacterInspector( windowSet, config ) {
|
||
|
||
// Parent constructor
|
||
ve.ui.Inspector.call( this, windowSet, config );
|
||
|
||
this.characters = null;
|
||
this.$buttonDomList = null;
|
||
this.initialSelection = null;
|
||
this.addedChar = null;
|
||
this.categories = null;
|
||
|
||
// Fallback character list in case no list is found anywhere
|
||
this.minimalCharacterList =
|
||
{
|
||
'accents': {
|
||
'à': 'à',
|
||
'á': 'á',
|
||
'â': 'â',
|
||
'ä': 'ä',
|
||
'ç': 'ç',
|
||
'è': 'è',
|
||
'é': 'é',
|
||
'ê': 'ê',
|
||
'ë': 'ë',
|
||
'ì': 'ì',
|
||
'í': 'í',
|
||
'î': 'î',
|
||
'ï': 'ï',
|
||
'ò': 'ò',
|
||
'ó': 'ó',
|
||
'ô': 'ô',
|
||
'ö': 'ö',
|
||
'ø': 'ø',
|
||
'ù': 'ù',
|
||
'ú': 'ú',
|
||
'û': 'û',
|
||
'ü': 'ü'
|
||
},
|
||
'symbols': {
|
||
'−': '−',
|
||
'—': '—',
|
||
'°': '°',
|
||
'″': '″',
|
||
'′': '′',
|
||
'←': '←',
|
||
'→': '→',
|
||
'·': '·',
|
||
'§': '§'
|
||
}
|
||
};
|
||
};
|
||
|
||
/* Inheritance */
|
||
|
||
OO.inheritClass( ve.ui.SpecialCharacterInspector, ve.ui.Inspector );
|
||
|
||
/* Static properties */
|
||
|
||
ve.ui.SpecialCharacterInspector.static.name = 'specialcharacter';
|
||
|
||
ve.ui.SpecialCharacterInspector.static.icon = 'specialcharacter';
|
||
|
||
ve.ui.SpecialCharacterInspector.static.titleMessage = 'visualeditor-specialcharacterinspector-title';
|
||
|
||
ve.ui.SpecialCharacterInspector.static.removable = false;
|
||
|
||
/* Methods */
|
||
|
||
/**
|
||
* Handle frame ready events.
|
||
*
|
||
* @method
|
||
*/
|
||
ve.ui.SpecialCharacterInspector.prototype.initialize = function () {
|
||
// Parent method
|
||
ve.ui.Inspector.prototype.initialize.call( this );
|
||
|
||
this.$spinner = this.$( '<div>' ).addClass( 've-specialchar-spinner' );
|
||
this.$form.append( this.$spinner );
|
||
};
|
||
|
||
/**
|
||
* Handle the inspector being setup.
|
||
*
|
||
* @method
|
||
* @param {Object} [data] Inspector opening data
|
||
*/
|
||
ve.ui.SpecialCharacterInspector.prototype.setup = function ( data ) {
|
||
// Parent method
|
||
ve.ui.Inspector.prototype.setup.call( this, data );
|
||
|
||
// Preserve initial selection so we can collapse cursor position
|
||
// after we're done adding
|
||
this.initialSelection = this.surface.getModel().getSelection();
|
||
|
||
this.getCharList().done( ve.bind( function () {
|
||
// Now we can rebuild our button list
|
||
// We only want to rebuild the list if we don't already have it
|
||
if ( !this.$buttonDomList ) {
|
||
// Start with the spinner showing
|
||
this.$spinner.show();
|
||
this.buildButtonList().done( ve.bind( function () {
|
||
// Append the new button list
|
||
this.$form.append( this.$buttonDomList );
|
||
// Done, hide the spinner
|
||
this.$spinner.hide();
|
||
|
||
}, this ) );
|
||
}
|
||
}, this ) );
|
||
|
||
};
|
||
|
||
/**
|
||
* Get the special character list object
|
||
* This can also be an AJAX call with default fallback
|
||
*
|
||
* @returns {jQuery.Promise}
|
||
*/
|
||
ve.ui.SpecialCharacterInspector.prototype.getCharList = function () {
|
||
var charslist, charobj,
|
||
deferred = $.Deferred();
|
||
|
||
// Don't request the character list again if we already have it
|
||
if ( !this.characters ) {
|
||
|
||
// Get the character list
|
||
charslist = ve.msg( 'visualeditor-specialcharinspector-characterlist-insert' );
|
||
try {
|
||
charobj = $.parseJSON( charslist );
|
||
} catch ( err ) {
|
||
// There was no character list found, or the character list message is
|
||
// invalid json string. Force a fallback to the minimal character list
|
||
charobj = this.minimalCharacterList;
|
||
ve.log( 've.ui.SpecialCharacterInspector: Could not parse the Special Character list; using default.');
|
||
ve.log( err.message );
|
||
} finally {
|
||
this.characters = charobj;
|
||
deferred.resolve();
|
||
}
|
||
}
|
||
|
||
return deferred.promise();
|
||
};
|
||
|
||
/**
|
||
* Builds the button DOM list based on the character list
|
||
*
|
||
* @returns {jQuery.Promise}
|
||
*/
|
||
ve.ui.SpecialCharacterInspector.prototype.buildButtonList = function () {
|
||
var category, categoryButtons,
|
||
deferred = $.Deferred(),
|
||
$widgetOutput = this.$( '<div>' ).addClass( 've-specialchar-list' );
|
||
|
||
if ( !this.characters ) {
|
||
deferred.reject();
|
||
}
|
||
|
||
for ( category in this.characters ) {
|
||
categoryButtons = new ve.ui.GroupButtonWidget( {
|
||
'groupName': category,
|
||
'group': this.characters[category],
|
||
'aggregations': { 'click': 'click' }
|
||
} );
|
||
|
||
categoryButtons.connect( this, { 'click': 'onSpecialCharAdd' } );
|
||
|
||
$widgetOutput
|
||
.append( this.$( '<h2>').text( category ) )
|
||
.append( categoryButtons.$element );
|
||
}
|
||
|
||
this.$buttonDomList = $widgetOutput;
|
||
deferred.resolve();
|
||
return deferred.promise();
|
||
};
|
||
|
||
/**
|
||
* Handle the click event on the button groups. The value of the selection will be inserted
|
||
* into the text
|
||
*
|
||
* @param {OO.ui.PushButtonWidget} button The value attached to the clicked button
|
||
*/
|
||
ve.ui.SpecialCharacterInspector.prototype.onSpecialCharAdd = function ( button ) {
|
||
var fragment = this.surface.getModel().getFragment( null, true ),
|
||
value = button.returnValue;
|
||
|
||
// Insert the character
|
||
if ( value !== undefined ) {
|
||
// get the insertion value (it could be in any category)
|
||
this.addedChar = value;
|
||
fragment.insertContent( value, false );
|
||
}
|
||
};
|
||
|
||
/**
|
||
* @inheritdoc
|
||
*/
|
||
ve.ui.SpecialCharacterInspector.prototype.teardown = function ( data ) {
|
||
var selection;
|
||
// Collapse selection after the inserted content
|
||
if ( this.addedChar ) {
|
||
selection = new ve.Range( this.initialSelection.start + this.addedChar.length );
|
||
this.surface.execute( 'content', 'select', selection );
|
||
}
|
||
// reset
|
||
this.addedChar = null;
|
||
// Parent method
|
||
ve.ui.Inspector.prototype.teardown.call( this, data );
|
||
};
|
||
|
||
/* Registration */
|
||
|
||
ve.ui.inspectorFactory.register( ve.ui.SpecialCharacterInspector );
|