/*!
* Aloha Editor
* Author & Copyright (c) 2011 Gentics Software GmbH
* aloha-sales@gentics.com
* Licensed under the terms of http://www.aloha-editor.com/license.html
*/
define( [
'aloha',
'aloha/jquery',
'aloha/plugin',
'aloha/floatingmenu',
'i18n!wai-lang/nls/i18n',
'i18n!aloha/nls/i18n',
'wai-lang/languages',
'css!wai-lang/css/wai-lang.css'
], function( Aloha, jQuery, Plugin, FloatingMenu, i18n, i18nCore ) {
var WAI_LANG_CLASS = 'aloha-wai-lang',
GENTICS = window.GENTICS,
addMarkupToSelectionButton,
langField;
return Plugin.create( 'wai-lang', {
/**
* Configure the available languages (i18n) for this plugin
*/
languages: [ 'en', 'de' ],
/**
* Default configuration allows spans everywhere
*/
config: [ 'span' ],
/**
* the defined object types to be used for this instance
*/
objectTypeFilter: [ 'language' ],
/**
* Initialize the plugin:
* Initializes UI components, and binds their event listeners.
*/
init: function() {
if ( this.settings.objectTypeFilter ) {
this.objectTypeFilter = this.settings.objectTypeFilter;
}
this.createButtons();
this.subscribeEvents();
this.bindInteractions();
},
/**
* Subscribe for events
*/
subscribeEvents: function() {
var that = this;
// add the event handler for selection change
Aloha.bind( 'aloha-editable-activated', function( event, rangeObject ) {
var config;
// show/hide the button according to the configuration
config = that.getEditableConfig( Aloha.activeEditable.obj );
if ( jQuery.inArray( 'span', config ) !== -1 ) {
addMarkupToSelectionButton.show();
} else {
addMarkupToSelectionButton.hide();
return;
}
} );
// add the event handler for selection change
Aloha.bind( 'aloha-selection-changed', function( event, rangeObject ) {
var foundMarkup;
foundMarkup = that.findLangMarkup( rangeObject );
if ( foundMarkup ) {
addMarkupToSelectionButton.setPressed( true );
FloatingMenu.setScope( 'wai-lang' );
langField.setTargetObject( foundMarkup, 'lang' );
} else {
langField.setTargetObject( null );
}
} );
},
/**
* Initialize the buttons:
* Places the Wai-Lang UI buttons into the floating menu.
*/
createButtons: function() {
var that = this;
// Button for adding a language markup to the current selection
addMarkupToSelectionButton = new Aloha.ui.Button( {
'name' : 'wailang',
'iconClass' : 'aloha-button aloha-button-wai-lang',
'size' : 'small',
'onclick' : function() {
that.addRemoveMarkupToSelection();
},
'tooltip' : i18n.t( 'button.add-wai-lang.tooltip' ),
'toggle' : true
} );
FloatingMenu.addButton(
'Aloha.continuoustext',
addMarkupToSelectionButton,
i18nCore.t( 'floatingmenu.tab.format' ),
1
);
// Add the new scope for the wai languages plugin tab
FloatingMenu.createScope( 'wai-lang', 'Aloha.continuoustext' );
langField = new Aloha.ui.AttributeField( {
'name' : 'wailangfield',
'width' : 320,
'valueField' : 'id',
'minChars' : 1
} );
langField.setTemplate(
'
' +
'
![]({url})
' +
'
{name}
' +
'
'
);
langField.setObjectTypeFilter( this.objectTypeFilter );
// add the input field for links
FloatingMenu.addButton(
'wai-lang',
langField,
i18n.t( 'floatingmenu.tab.wai-lang' ),
1
);
var removeButton = new Aloha.ui.Button( {
'name' : 'removewailang',
'iconClass' : 'aloha-button aloha-button-wai-lang-remove',
'size' : 'small',
'onclick' : function() {
that.removeLangMarkup();
},
'tooltip' : i18n.t( 'button.add-wai-lang-remove.tooltip' ),
'toggle' : false
} );
FloatingMenu.addButton(
'wai-lang',
removeButton,
i18n.t( 'floatingmenu.tab.wai-lang' ),
1
);
},
/**
* Given a range object, finds and returns a Wai-Lang wrapper DOM
* element within the range.
*
* @param {GENTICS.Utils.RangeObject} range
* @return {?DOMObject} the dom object found, or false if nothing found
*/
findLangMarkup: function( range ) {
range = range || Aloha.Selection.getRangeObject();
if ( Aloha.activeEditable ) {
return range.findMarkup( function() {
return jQuery( this ).hasClass( WAI_LANG_CLASS )
|| jQuery( this ).is( '[lang]' );
}, Aloha.activeEditable.obj );
}
return null;
},
/**
* Check whether the range is within a span that contains a lang
* attribute.
*
* @param {GENTICS.Utils.RangeObject} range range where to insert the
* object (at start or end)
* @return {?DOMObject} the dom object found, or false if nothing found
* @hide
*/
findLanguageMarkup: function( range ) {
range = range || Aloha.Selection.getRangeObject();
if ( Aloha.activeEditable ) {
return range.findMarkup( function() {
return this.nodeName === 'SPAN';
}, Aloha.activeEditable.obj );
}
return null;
},
/**
*
*/
removeLangMarkup: function() {
var range = Aloha.Selection.getRangeObject(),
foundMarkup = this.findLangMarkup( range );
if ( foundMarkup ) {
// remove the abbr
GENTICS.Utils.Dom.removeFromDOM( foundMarkup, range, true );
// select the (possibly modified) range
range.select();
FloatingMenu.setScope( 'Aloha.continousText' );
langField.setTargetObject( null );
FloatingMenu.doLayout();
}
},
/**
* Parse a all editables for elements that have a lang attribute and
* bind an onclick event
*/
bindInteractions: function() {
var that = this;
// on blur check if lang is empty, if so remove the tag
langField.addListener( 'blur', function( obj, event ) {
// @todo check for a valid value -- now it's also possible to insert abcd; but that's not valid
if ( !this.getValue() ) {
that.removeMarkup();
}
} );
Aloha.ready( function() {
that.handleExistingSpans();
} );
},
/**
* Find all existing spans and register hotkey hotkeys and make
* annotations of languages visible.
*/
handleExistingSpans: function() {
var that = this;
// Add the Link shortcut to all editables
jQuery.each( Aloha.editables, function( key, editable ) {
// Hotkey for adding new language annotations: CTRL+I
editable.obj.keydown( that.handleKeyDown );
} );
jQuery.each( Aloha.editables, function( key, editable ) {
// Find all spans with lang attributes and add some css and
// event handlers
editable.obj.find( 'span[lang]' ).each( function( i ) {
that.makeVisible( this );
} );
} );
},
/**
* @param {Event} e
* @return {?Boolean}
*/
handleKeyDown: function( e ) {
if ( e.metaKey && e.which === 73 ) {
if ( this.findLangMarkup() ) {
FloatingMenu.activateTabOfButton( 'wailangfield' );
langField.focus();
} else {
this.addMarkupToSelection();
}
// Prevent from further handling.
// on a MAC Safari, cursor would jump to location bar.
// We have to use ESC and then META+I instead.
return false;
}
},
/**
* Make the given element visible by adding some styles to it.
*/
makeVisible: function( element ) {
// Make existing spans with language attribute visible
// Flags can be added via the metaview plugin
jQuery( element ).css(
'background-image',
'url(' + Aloha.getPluginUrl( 'wai-lang' ) + '/img/flags/' +
jQuery( element ).attr( 'lang' ) + '.png)'
);
jQuery( element ).addClass( WAI_LANG_CLASS );
},
/**
* Format the current selection or if collapsed the current word as
* element that should be annotated.
*/
formatLanguageSpan: function() {
if ( Aloha.activeEditable ) {
var range = Aloha.Selection.getRangeObject();
if ( this.findLanguageMarkup( range ) ) {
this.removeMarkup();
} else {
this.insertMarkup();
}
}
},
/**
* Toggles markup around selection.
*/
addRemoveMarkupToSelection: function() {
if ( addMarkupToSelectionButton.pressed ) {
this.removeLangMarkup();
} else {
this.addMarkupToSelection( false );
}
},
/**
* Retrieves the current selected range, and wraps it with wai-lang
* content.
*/
addMarkupToSelection: function() {
var range = Aloha.Selection.getRangeObject();
// Do not add markup to an area that already contains a markup
if ( this.findLangMarkup( range ) ) {
return;
}
FloatingMenu.activateTabOfButton( 'wailangfield' );
FloatingMenu.setScope( 'wai-lang' );
if ( range.isCollapsed() ) {
GENTICS.Utils.Dom.extendToWord( range );
}
if ( !range.isCollapsed() ) {
GENTICS.Utils.Dom.addMarkup( range,
jQuery( '' ),
false );
}
range.select();
// langField.focus();
},
/**
* Remove an a tag.
*/
removeMarkup: function() {
var foundMarkup = this.findLangMarkup(),
range;
if ( foundMarkup ) {
range = Aloha.Selection.getRangeObject();
GENTICS.Utils.Dom.removeFromDOM( foundMarkup, range, true );
// select the (possibly modified) range
range.select();
}
},
/**
* Make the given jQuery object (representing an editable) clean for saving
* Find all elements with lang attributes and remove the attribute.
* @param {jQuery} obj jQuery object to make clean
*/
makeClean: function( obj ) {
obj.find( 'span[lang]' ).each( function() {
jQuery( this ).removeClass( WAI_LANG_CLASS );
} );
}
} );
} );