mediawiki-extensions-Visual.../modules/ve/ui/inspectors/ve.ui.SpecialCharacterInspector.js
Timo Tijhof cf7f2b141d Set up node-jscs, pass it, and configure in local Gruntfile
Let's experiment with this via our local Gruntfile. If it works
fine we can install it in Jenkins (similar to node-csslint).

Verify through $ npm install && npm test;

Fixed all outstanding violations.

Also:
* Added syntaxhighight to ignore.
* Added imetests (which contain unformatted JSON) to ignore.
* In ve.dm.ModelRegistry#matchTypeRegExps, removed redundant
  !! cast from the [+!!withFunc] statement which was hitting
  a bug in node-jscs. All callers to this local private function
  pass a literal boolean true/false so no need to cast it.
* Removed "/* key .. , value */" from ve.setProp, though this
  wasn't caught by node-jscs, found it when searching for " , ".
* Made npm.devDependencies fixed instead of using tilde-ranges.
  This too often leads to strange bugs or sudden changes. Fixed
  them at the version they were currently ranging to.

Bug: 54218
Change-Id: Ib2630806f3946874c8b01e58cf171df83a28da29
2013-12-06 10:37:27 -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.removeable = 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 );