mediawiki-extensions-Visual.../modules/ve/ui/inspectors/ve.ui.SpecialCharacterInspector.js
Trevor Parscal b3281bd87a Spell removable and movable using modern English
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
2013-12-06 12:24:36 -08:00

233 lines
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
* 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 );