Source: admin/javascript/engine/libs/editor_instances.js

/* --------------------------------------------------------------
 editor_instances.js 2016-09-09
 Gambio GmbH
 http://www.gambio.de
 Copyright (c) 2016 Gambio GmbH
 Released under the GNU General Public License (Version 2)
 [http://www.gnu.org/licenses/gpl-2.0.html]
 --------------------------------------------------------------
 */

jse.libs.editor_instances = jse.libs.editor_instances || {};

/**
 * ## Editor Instances Library
 *
 * This library provides a common API for editor widget instances manipulation. 
 * 
 * @module Admin/Libs/editor_instances
 * @exports jse.libs.editor_instances
 */
(function(exports) {
	
	'use strict';
	
	/**
	 * Editor construct methods
	 *
	 * @type {Object}
	 */
	const constructors = {
		ckeditor($textarea) {
			const tags = [
				'p',
				'div', 
				'script', 
				'style', 
				'form'
			];
			
			const formattingRules = {
				indent : true,
				breakBeforeOpen : true,
				breakAfterOpen : true,
				breakBeforeClose : true,
				breakAfterClose : true
			};
			
			const config = {
				filebrowserBrowseUrl: 'includes/ckeditor/filemanager/index.html',
				baseHref: jse.core.config.get('appUrl') + '/admin',
				enterMode: CKEDITOR.ENTER_BR,
				shiftEnterMode: CKEDITOR.ENTER_P,
				language: jse.core.config.get('languageCode'),
				useRelPath: true,
				on: {
					instanceReady(event) {
						for (let tag of tags) {
							this.dataProcessor.writer.setRules(tag, formattingRules); 
						}
					}
				}
			};
			
			const name = $textarea.attr('name');
			CKEDITOR.replace(name, config);
			return CKEDITOR.instances[name];
		},
		codemirror($textarea) {
			const config = {
				mode: 'htmlmixed',
				lineNumbers: true,
				lineWrapping: true
			};
			
			return CodeMirror.fromTextArea($textarea[0], config);
		}
	};
	
	/**
	 * Editor destruct methods
	 *
	 * @type {Object}
	 */
	const destructors = {
		ckeditor($textarea) {
			const name = $textarea.attr('name');
			CKEDITOR.instances[name].destroy();
		},
		codemirror($textarea) {
			const instance = $textarea.siblings('.CodeMirror')[0].CodeMirror;
			instance.toTextArea();
		}
	};
	
	/**
	 * Editor instance methods
	 * 
	 * @type {Object}
	 */
	const getInstance = {
		ckeditor($textarea) {
			return CKEDITOR.instances[$textarea.attr('name')];
		}, 
		codemirror($textarea) {
			return $textarea.siblings('.CodeMirror')[0].CodeMirror;
		}
	};
	
	/**
	 * Create new editor instance. 
	 * 
	 * @param {jQuery} $textarea Textarea selector to be modified.
	 * @param {String} type Provide a type that is supported by the widget. 
	 * 
	 * @return {CKEditor|CodeMirror} Returns the create editor instance.
	 */
	exports.create = function($textarea, type) {
		if (constructors[type] === undefined) {
			throw new Error('Provided editor type is not supported: ' + type);
		}
		
		const instance = constructors[type]($textarea);
		instance.type = type;
		
		return instance;
	};
	
	/**
	 * Switch to a new editor type. 
	 * 
	 * @param {jQuery} $textarea Textarea selector to be modified.
	 * @param {String} currentType Provide the current editor type. 
	 * @param {String} newType Provide the new editor type.
	 * 
	 * @return {CKEditor|CodeMirror} Returns the new editor instance. 
	 */
	exports.switch = function($textarea, currentType, newType) {
		if (destructors[currentType] === undefined) {
			throw new Error('Provided editor type is not supported: ' + currentType);
		}
		
		destructors[currentType]($textarea);
		
		return exports.create($textarea, newType);
	};
	
	/**
	 * Destroy an existing editor instance.
	 * 
	 * @param {jQuery} $textarea Textarea selector to be destroyed.
	 * @param {String} customInitEventType Optional (''), if the editor was initialized with a custom init-event-type, 
	 * then this must be unbound by editor destroy.
	 */
	exports.destroy = function($textarea, customInitEventType = '') {
		if (customInitEventType && customInitEventType !== 'JSENGINE_INIT_FINISHED') {
			$(window).off(customInitEventType);
		}
		
		const type = $textarea.data('editorType'); 
		
		if (destructors[type] === undefined) {
			throw new Error('Provided editor type is not supported: ' + type);
		}
		
		destructors[type]($textarea);
	};
	
	/**
	 * Get an editor instance. 
	 * 
	 * @param {jQuery} $textarea Textarea selector from which the instance will be retrieved.
	 * 
	 * @return {CKEditor|CodeMirror} Returns the corresponding editor instance. 
	 */
	exports.getInstance = function($textarea) {
		const type = $textarea.data('editorType');
		
		if (destructors[type] === undefined) {
			throw new Error('Provided editor type is not supported: ' + type);
		}
		
		return getInstance[type]($textarea);
	};
	
})(jse.libs.editor_instances);