text: ﻿/**
   * @file Configuration helper plugin for CKEditor
   * Copyright (C) 2012 Alfonso Martínez de Lizarrondo
   *
   */
  /* global CKEDITOR */
  (function() {
  	'use strict';
  
  	// Check if the browser supports the placeholder attribute on textareas natively.
  	var supportsPlaceholder = 'placeholder' in document.createElement( 'textarea' );
  
  	// If the data is "empty" (BR, P) or the placeholder then return an empty string.
  	// Otherwise return the original data
  	function dataIsEmpty( data ) {
  		if ( !data)
  			return true;
  
  		if ( data.length > 20 )
  			return false;
  
  		var value = data.replace( /[\n|\t]*/g, '' ).toLowerCase();
  		if ( !value || value == '<br>' || value == '<p>&nbsp;<br></p>' || value == '<p><br></p>' || value == '<div><br></div>' || value == '<p>&nbsp;</p>' || value == '&nbsp;' || value == ' ' || value == '&nbsp;<br>' || value == ' <br>' )
  			return true;
  
  		return false;
  	}
  
  	function addPlaceholder(ev) {
  		var editor = ev.editor;
  
  		// do not add placeholder in readOnly mode
  		if (editor.readOnly)
  			return;
  
  		var root = editor.editable();
  		var placeholder = ev.listenerData;
  		if (!root)
  			return;
  
  		if (editor.mode == 'wysiwyg') {
  			// If the blur is due to a dialog, don't apply the placeholder
  			if ( CKEDITOR.dialog._.currentTop )
  				return;
  
  			if ( !root )
  				return;
  
  			if ( dataIsEmpty( root.getHtml() ) ) {
  				root.setHtml( placeholder );
  				root.addClass( 'placeholder' );
  			}
  		}
  
  		if (editor.mode == 'source') {
  			if ( supportsPlaceholder ) {
  				if (ev.name == 'mode') {
  					root.setAttribute( 'placeholder', placeholder );
  				}
  				return;
  			}
  
  			if ( dataIsEmpty( root.getValue() ) ) {
  				root.setValue( placeholder );
  				root.addClass( 'placeholder' );
  			}
  		}
  	}
  
  	function removePlaceholder(ev) {
  		var editor = ev.editor;
  		var root = editor.editable();
  		if (!root)
  			return;
  
  		if (editor.mode == 'wysiwyg' ) {
  			if (!root.hasClass( 'placeholder' ))
  				return;
  
  			root.removeClass( 'placeholder' );
  			// fill it properly
  			if (CKEDITOR.dtd[ root.getName() ]['p']) {
  				var value = '';
  				if ( editor.enterMode === CKEDITOR.ENTER_P ) {
  					value = '<p><br/></p>';
  				} else if (editor.enterMode === CKEDITOR.ENTER_DIV) {
  					value = '<div><br/><\/div>';
  				} else {
  					// This is for CKEDITOR.ENTER_BR
  					value = '<br/>';
  					// FireFox prepends an additional line
  					if (CKEDITOR.env.gecko || CKEDITOR.env.ie) {
  						value = ' ';
  					}
  				}
  				root.setHtml(value);
  				// Set caret in position
  				var range = new CKEDITOR.dom.range(editor.document);
  				range.moveToElementEditablePosition(root.getFirst(), true);
  				editor.getSelection().selectRanges([ range ]);
  			} else {
  				root.setHtml(' ');
  			}
  		}
  
  		if (editor.mode == 'source') {
  			if ( !root.hasClass( 'placeholder' ) )
  				return;
  
  			root.removeClass( 'placeholder' );
  			root.setValue( '' );
  		}
  	}
  
  	function handleReadOnlyChange(ev) {
  		var editor = ev.editor;
  		if (editor.readOnly) {
  			removePlaceholder(ev);
  		} else {
  			addPlaceholder(ev);
  		}
  	}
  
  	function getLang( element ) {
  		if (!element)
  			return null;
  
  		return element.getAttribute( 'lang' ) || getLang( element.getParent() );
  	}
  
  	CKEDITOR.plugins.add( 'confighelper', {
  		getPlaceholderCss : function() {
  			return '.placeholder{ color: #999; }';
  		},
  
  		onLoad : function() {
  			CKEDITOR.addCss( this.getPlaceholderCss() );
  		},
  
  		init : function( editor ) {
  
  			// correct focus status after switch mode
  			editor.on( 'mode', function( ev ) {
  				// Let's update to match reality
  				ev.editor.focusManager.hasFocus = false;
  				// Now focus it:
  			});
  
  			// Placeholder - Start
  			// Get the placeholder from the replaced element or from the configuration
  			var placeholder = editor.element.getAttribute( 'placeholder' ) || editor.config.placeholder;
  
  			if (placeholder) {
  				// CSS for textarea mode
  				var node = CKEDITOR.document.getHead().append( 'style' );
  				node.setAttribute( 'type', 'text/css' );
  				var content = 'textarea.placeholder { color: #999; font-style: italic; }';
  
  				if ( CKEDITOR.env.ie && CKEDITOR.env.version < 11)
  					node.$.styleSheet.cssText = content;
  				else
  					node.$.innerHTML = content;
  
  				// Watch for the calls to getData to remove the placeholder
  				editor.on( 'getData', function( ev ) {
  					var element = editor.editable();
  
  					if ( element && element.hasClass( 'placeholder' ) )
  						ev.data.dataValue = '';
  				});
  
  				// Watch for setData to remove placeholder class
  				editor.on('setData', function(ev) {
  					if ( CKEDITOR.dialog._.currentTop )
  						return;
  
  					if ( editor.mode == 'source' && supportsPlaceholder )
  						return;
  
  					var root = editor.editable();
  
  					if ( !root )
  						return;
  
  					if ( !dataIsEmpty( ev.data.dataValue ) ) {
  						// Remove the class if new data is not empty
  						if ( root.hasClass( 'placeholder' ) )
  							root.removeClass( 'placeholder' );
  					} else {
  						// if data is empty, set it to the placeholder
  						addPlaceholder(ev);
  					}
  				});
  
  				editor.on('blur', addPlaceholder, null, placeholder);
  				editor.on('mode', addPlaceholder, null, placeholder);
  				editor.on('contentDom', addPlaceholder, null, placeholder);
  
  				editor.on('focus', removePlaceholder);
  				editor.on('key', removePlaceholder);
  				editor.on('beforeModeUnload', removePlaceholder);
  
  				editor.on('readOnly', handleReadOnlyChange, null, placeholder);
  			} // Placeholder - End
  
  
  			// SCAYT lang from element lang:
  			var lang = editor.config.contentsLanguage || getLang( editor.element );
  			if ( lang && editor.plugins.scayt && !editor.config.scayt_sLang ) {
  				try {
  					// Remove the stored language
  					if (localStorage)
  						localStorage.removeItem( 'scayt_0_lang' );
  				} catch (e) { /* */}
  
  				// Convert from HTML5 Lang to spellchecker.net values
  				var map = {
  					'en'   : 'en_US',
  					'en-us': 'en_US',
  					'en-gb': 'en_GB',
  					'pt-br': 'pt_BR',
  					'da'   : 'da_DK',
  					'da-dk': 'da_DK',
  					'nl-nl': 'nl_NL',
  					'en-ca': 'en_CA',
  					'fi-fi': 'fi_FI',
  					'fr'   : 'fr_FR',
  					'fr-fr': 'fr_FR',
  					'fr-ca': 'fr_CA',
  					'de'   : 'de_DE',
  					'de-de': 'de_DE',
  					'el-gr': 'el_GR',
  					'it'   : 'it_IT',
  					'it-it': 'it_IT',
  					'nb-no': 'nb_NO',
  					'pt'   : 'pt_PT',
  					'pt-pt': 'pt_PT',
  					'es'   : 'es_ES',
  					'es-es': 'es_ES',
  					'sv-se': 'sv_SE'
  				};
  				editor.config.scayt_sLang = map[ lang.toLowerCase() ];
  			}
  
  			// Parse the config to turn it into a js object
  			// format= dialogName:tabName:fieldName
  			var parseDefinitionToObject = function( value ) {
  				// Allow JSON definitions
  				if (typeof value == 'object')
  					return value;
  
  				var contents = value.split( ';' ),
  					tabsToProcess = {},
  					i;
  
  				for ( i = 0; i < contents.length; i++ ) {
  					var parts = contents[ i ].split( ':' );
  					if ( parts.length == 3 ) {
  						var dialogName = parts[ 0 ],
  							tabName = parts[ 1 ],
  							fieldName = parts[ 2 ];
  
  						if ( !tabsToProcess[ dialogName ] )
  							tabsToProcess[ dialogName ] = {};
  						if ( !tabsToProcess[ dialogName ][ tabName ] )
  							tabsToProcess[ dialogName ][ tabName ] = [];
  
  						tabsToProcess[ dialogName ][ tabName ].push( fieldName );
  					}
  				}
  				return tabsToProcess;
  			};
  
  			// Customize dialogs:
  			function customizeDialogs( ev ) {
  				if ( editor != ev.editor )
  					return;
  
  				var dialogName = ev.data.name,
  					dialogDefinition = ev.data.definition,
  					tabsToProcess,
  					i, name, fields, tab;
  
  				if (dialogName == 'tableProperties')
  					dialogName = 'table';
  
  				// Parse the config to turn it into a js object
  				if ( !( 'removeDialogFields' in editor._ ) && editor.config.removeDialogFields )
  					editor._.removeDialogFields = parseDefinitionToObject( editor.config.removeDialogFields );
  
  				// Remove fields of this dialog.
  				if ( editor._.removeDialogFields && ( tabsToProcess = editor._.removeDialogFields[ dialogName ] ) ) {
  					for ( name in tabsToProcess ) {
  						fields = tabsToProcess[ name ];
  						tab = dialogDefinition.getContents( name );
  						if (!tab)
  							continue;
  
  						for ( i = 0; i < fields.length ; i++ )
  							tab.remove( fields[ i ] );
  					}
  				}
  
  
  				if ( !( 'hideDialogFields' in editor._ ) && editor.config.hideDialogFields )
  					editor._.hideDialogFields = parseDefinitionToObject( editor.config.hideDialogFields );
  
  				// Remove fields of this dialog.
  				if ( editor._.hideDialogFields && ( tabsToProcess = editor._.hideDialogFields[ dialogName ] ) ) {
  					for ( name in tabsToProcess ) {
  						fields = tabsToProcess[ name ];
  						tab = dialogDefinition.getContents( name );
  						if (!tab)
  							continue;
  
  						for ( i = 0; i < fields.length ; i++ )
  							tab.get( fields[ i ] ).hidden = true;
  					}
  				}
  
  				// Set default values.
  				if ( editor.config.dialogFieldsDefaultValues && ( tabsToProcess = editor.config.dialogFieldsDefaultValues[ dialogName ] ) ) {
  					for ( name in tabsToProcess ) {
  						fields = tabsToProcess[ name ];
  						tab = dialogDefinition.getContents( name );
  						if (!tab)
  							continue;
  
  						for ( var fieldName in fields ) {
  							var dialogField = tab.get( fieldName );
  							if ( dialogField )
  								dialogField[ 'default' ] = fields[ fieldName ];
  						}
  					}
  				}
  
  
  			}
  
  			CKEDITOR.on( 'dialogDefinition', customizeDialogs );
  			editor.once( 'beforeDestroy', function() {
  				CKEDITOR.removeListener( 'dialogDefinition', customizeDialogs );
  			});
  
  		}
  	} );
  
  })();
  
   /**
    * Allows to define which dialog fiels must be removed
    * @name CKEDITOR.config.removeDialogFields
    * @type {String}
    * @example
    *	editor.config.removeDialogFields = "image:info:txtBorder;image:info:txtHSpace";
    */
  
   /**
    * Allows to define which dialog fiels must be hidden
    * @name CKEDITOR.config.hideDialogFields
    * @type {String}
    * @example
    *	editor.config.hideDialogFields = "image:info:htmlPreview";
    */
  
   /**
    * Allows to define default values for dialog fields
    * @name CKEDITOR.config.dialogFieldsDefaultValues
    * @type {Object}
    * @example
  	config.dialogFieldsDefaultValues =
  	{
  		image:
  			{
  				advanced:
  					{
  						txtGenClass : 'myClass',
  						txtGenTitle : 'Image title'
  					}
  			}
  	};
    */
  
  
   /**
    * Placeholder text for empty editor
    * @name CKEDITOR.config.placeholder
    * @type {String}
    * @example
    *	editor.config.placeholder = "Please, type here...";
    */
  