/* exported ToolbarConfigurator */
/* global ToolbarConfigurator */
'use strict';
window.ToolbarConfigurator = {};
( function() {
/**
* @class ToolbarConfigurator.FullToolbarEditor
* @constructor
*/
function FullToolbarEditor() {
this.instanceid = 'fte' + CKEDITOR.tools.getNextId();
this.textarea = new CKEDITOR.dom.element( 'textarea' );
this.textarea.setAttributes( {
id: this.instanceid,
name: this.instanceid,
contentEditable: true
} );
this.buttons = null;
this.editorInstance = null;
}
// Expose the class.
ToolbarConfigurator.FullToolbarEditor = FullToolbarEditor;
/**
* @param {Function} callback
* @param {Object} cfg
*/
FullToolbarEditor.prototype.init = function( callback ) {
var that = this;
document.body.appendChild( this.textarea.$ );
CKEDITOR.replace( this.instanceid );
this.editorInstance = CKEDITOR.instances[ this.instanceid ];
this.editorInstance.once( 'configLoaded', function( e ) {
var cfg = e.editor.config;
// We want all the buttons.
delete cfg.removeButtons;
delete cfg.toolbarGroups;
delete cfg.toolbar;
ToolbarConfigurator.AbstractToolbarModifier.extendPluginsConfig( cfg );
e.editor.once( 'loaded', function() {
that.buttons = FullToolbarEditor.toolbarToButtons( that.editorInstance.toolbar );
that.buttonsByGroup = FullToolbarEditor.groupButtons( that.buttons );
that.buttonNamesByGroup = that.groupButtonNamesByGroup( that.buttons );
e.editor.container.hide();
if ( typeof callback === 'function' )
callback( that.buttons );
} );
} );
};
/**
* Group array of button names by their group parents.
*
* @param {Array} buttons
* @returns {Object}
*/
FullToolbarEditor.prototype.groupButtonNamesByGroup = function( buttons ) {
var that = this,
groups = FullToolbarEditor.groupButtons( buttons );
for ( var groupName in groups ) {
var currGroup = groups[ groupName ];
groups[ groupName ] = FullToolbarEditor.map( currGroup, function( button ) {
return that.getCamelCasedButtonName( button.name );
} );
}
return groups;
};
/**
* Returns group literal.
*
* @param {String} name
* @returns {Object}
*/
FullToolbarEditor.prototype.getGroupByName = function( name ) {
var groups = this.editorInstance.config.toolbarGroups || this.getFullToolbarGroupsConfig();
var max = groups.length;
for ( var i = 0; i < max; i += 1 ) {
if ( groups[ i ].name === name )
return groups[ i ];
}
return null;
};
/**
* @param {String} name
* @returns {String | null}
*/
FullToolbarEditor.prototype.getCamelCasedButtonName = function( name ) {
var items = this.editorInstance.ui.items;
for ( var key in items ) {
if ( items[ key ].name == name )
return key;
}
return null;
};
/**
* Returns full toolbarGroups config value which is used when
* there is no toolbarGroups field in config.
*
* @param {Boolean} [pickSeparators=false]
* @returns {Array}
*/
FullToolbarEditor.prototype.getFullToolbarGroupsConfig = function( pickSeparators ) {
pickSeparators = ( pickSeparators === true ? true : false );
var result = [],
toolbarGroups = this.editorInstance.toolbar;
var max = toolbarGroups.length;
for ( var i = 0; i < max; i += 1 ) {
var currentGroup = toolbarGroups[ i ],
copiedGroup = {};
if ( typeof currentGroup.name != 'string' ) {
// this is not a group
if ( pickSeparators ) {
result.push( '/' );
}
continue;
}
copiedGroup.name = currentGroup.name;
if ( currentGroup.groups )
copiedGroup.groups = Array.prototype.slice.call( currentGroup.groups );
result.push( copiedGroup );
}
return result;
};
/**
* Filters array items based on checker provided in second argument.
* Returns new array.
*
* @param {Array} arr
* @param {Function} checker
* @returns {Array}
*/
FullToolbarEditor.filter = function( arr, checker ) {
var max = ( arr && arr.length ? arr.length : 0 ),
result = [];
for ( var i = 0; i < max; i += 1 ) {
if ( checker( arr[ i ] ) )
result.push( arr[ i ] );
}
return result;
};
/**
* Simplified http://underscorejs.org/#map functionality
*
* @param {Array | Object} enumerable
* @param {Function} modifier
* @returns {Array | Object}
*/
FullToolbarEditor.map = function( enumerable, modifier ) {
var result;
if ( CKEDITOR.tools.isArray( enumerable ) ) {
result = [];
var max = enumerable.length;
for ( var i = 0; i < max; i += 1 )
result.push( modifier( enumerable[ i ] ) );
} else {
result = {};
for ( var key in enumerable )
result[ key ] = modifier( enumerable[ key ] );
}
return result;
};
/**
* Group buttons by their parent names.
*
* @static
* @param {Array} buttons
* @returns {Object} The object (`name => group`) representing CKEDITOR.ui.button or CKEDITOR.ui.richCombo
*/
FullToolbarEditor.groupButtons = function( buttons ) {
var groups = {};
var max = buttons.length;
for ( var i = 0; i < max; i += 1 ) {
var currBtn = buttons[ i ],
currBtnGroupName = currBtn.toolbar.split( ',' )[ 0 ];
groups[ currBtnGroupName ] = groups[ currBtnGroupName ] || [];
groups[ currBtnGroupName ].push( currBtn );
}
return groups;
};
/**
* Pick all buttons from toolbar.
*
* @static
* @param {Array} groups
* @returns {Array}
*/
FullToolbarEditor.toolbarToButtons = function( groups ) {
var buttons = [];
var max = groups.length;
for ( var i = 0; i < max; i += 1 ) {
var currentGroup = groups[ i ];
if ( typeof currentGroup == 'object' )
buttons = buttons.concat( FullToolbarEditor.groupToButtons( groups[ i ] ) );
}
return buttons;
};
/**
* Creates HTML button representation for view.
*
* @static
* @param {CKEDITOR.ui.button | CKEDITOR.ui.richCombo} button
* @returns {CKEDITOR.dom.element}
*/
FullToolbarEditor.createToolbarButton = function( button ) {
var $button = new CKEDITOR.dom.element( 'a' ),
icon = FullToolbarEditor.createIcon( button.name, button.icon, button.command );
$button.setStyle( 'float', 'none' );
$button.addClass( 'cke_' + ( CKEDITOR.lang.dir == 'rtl' ? 'rtl' : 'ltr' ) );
if ( button instanceof CKEDITOR.ui.button ) {
$button.addClass( 'cke_button' );
$button.addClass( 'cke_toolgroup' );
$button.append( icon );
} else if ( CKEDITOR.ui.richCombo && button instanceof CKEDITOR.ui.richCombo ) {
var comboLabel = new CKEDITOR.dom.element( 'span' ),
comboOpen = new CKEDITOR.dom.element( 'span' ),
comboArrow = new CKEDITOR.dom.element( 'span' );
$button.addClass( 'cke_combo_button' );
comboLabel.addClass( 'cke_combo_text' );
comboLabel.addClass( 'cke_combo_inlinelabel' );
comboLabel.setText( button.label );
comboOpen.addClass( 'cke_combo_open' );
comboArrow.addClass( 'cke_combo_arrow' );
comboOpen.append( comboArrow );
$button.append( comboLabel );
$button.append( comboOpen );
}
return $button;
};
/**
* Create and return icon element.
*
* @param {String} name
* @param {String} icon
* @param {String} command
* @static
* @returns {CKEDITOR.dom.element}
*/
FullToolbarEditor.createIcon = function( name, icon, command ) {
var iconStyle = CKEDITOR.skin.getIconStyle( name, ( CKEDITOR.lang.dir == 'rtl' ) );
// We don't know exactly how to get icon style. Especially for extra plugins,
// Which definition may vary.
iconStyle = iconStyle || CKEDITOR.skin.getIconStyle( icon, ( CKEDITOR.lang.dir == 'rtl' ) );
iconStyle = iconStyle || CKEDITOR.skin.getIconStyle( command, ( CKEDITOR.lang.dir == 'rtl' ) );
var iconElement = new CKEDITOR.dom.element( 'span' );
iconElement.addClass( 'cke_button_icon' );
iconElement.addClass( 'cke_button__' + name + '_icon' );
iconElement.setAttribute( 'style', iconStyle );
iconElement.setStyle( 'float', 'none' );
return iconElement;
};
/**
* Create and return button element
*
* @param {String} text
* @param {String} cssClasses
* @returns {CKEDITOR.dom.element}
*/
FullToolbarEditor.createButton = function( text, cssClasses ) {
var $button = new CKEDITOR.dom.element( 'button' );
$button.addClass( 'button-a' );
$button.setAttribute( 'type', 'button' );
if ( typeof cssClasses == 'string' ) {
cssClasses = cssClasses.split( ' ' );
var i = cssClasses.length;
while ( i-- ) {
$button.addClass( cssClasses[ i ] );
}
}
$button.setHtml( text );
return $button;
};
/**
* @static
* @param {Object} group
* @returns {Array} representing HTML buttons for view
*/
FullToolbarEditor.groupToButtons = function( group ) {
var buttons = [],
items = group.items;
var max = items ? items.length : 0;
for ( var i = 0; i < max; i += 1 ) {
var item = items[ i ];
if ( item instanceof CKEDITOR.ui.button || CKEDITOR.ui.richCombo && item instanceof CKEDITOR.ui.richCombo ) {
item.$ = FullToolbarEditor.createToolbarButton( item );
buttons.push( item );
}
}
return buttons;
};
} )();