Explorar o código

Exported utils to... utils.

Piotrek Koszuliński %!s(int64=9) %!d(string=hai) anos
pai
achega
fcce14d4bf
Modificáronse 7 ficheiros con 262 adicións e 659 borrados
  1. 0 118
      ckeditor.js
  2. 1 1
      package.json
  3. 0 26
      src/creator/creator.js
  4. 0 158
      src/creator/standardcreator.js
  5. 0 356
      src/editor.js
  6. 166 0
      src/editor/editor.js
  7. 95 0
      src/editor/standardeditor.js

+ 0 - 118
ckeditor.js

@@ -1,118 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import Editor from './ckeditor5/editor.js';
-import Collection from './ckeditor5/utils/collection.js';
-import CKEditorError from './ckeditor5/utils/ckeditorerror.js';
-import isArrayLike from './ckeditor5/utils/lib/lodash/isArrayLike.js';
-import clone from './ckeditor5/utils/lib/lodash/clone.js';
-import uid from './ckeditor5/utils/uid.js';
-
-/**
- * This is the API entry point. The entire CKEditor code runs under this object.
- *
- * @namespace CKEDITOR
- */
-const CKEDITOR = {
-	/**
-	 * A collection containing all editor instances created.
-	 *
-	 * @readonly
-	 * @member {utils.Collection} CKEDITOR.instances
-	 */
-	instances: new Collection(),
-
-	/**
-	 * Creates an editor instance for the provided DOM element.
-	 *
-	 * The creation of editor instances is an asynchronous operation, therefore a promise is returned by this
-	 * method.
-	 *
-	 *		CKEDITOR.create( '#content' );
-	 *
-	 *		CKEDITOR.create( '#content' ).then( ( editor ) => {
-	 *			// Manipulate "editor" here.
-	 *		} );
-	 *
-	 * @method CKEDITOR.create
-	 * @param {String|HTMLElement|HTMLCollection|NodeList|Array.<HTMLElement>|Object.<String, HTMLElement>} elements
-	 * One or more elements on which the editor will be initialized. Different creators can handle these
-	 * elements differently, but usually a creator loads the data from the element and either makes
-	 * it editable or hides it and inserts the editor UI next to it.
-	 * @returns {Promise} A promise, which will be fulfilled with the created editor.
-	 */
-	create( elements, config ) {
-		return new Promise( ( resolve ) => {
-			const editor = new Editor( normalizeElements( elements ), config );
-
-			this.instances.add( editor );
-
-			// Remove the editor from `instances` when destroyed.
-			editor.once( 'destroy', () => {
-				this.instances.remove( editor );
-			} );
-
-			resolve(
-				// Initializes the editor, which returns a promise.
-				editor.init()
-					.then( () => {
-						// After initialization, return the created editor.
-						return editor;
-					} )
-			);
-		} );
-	}
-};
-
-export default CKEDITOR;
-
-function normalizeElements( elements ) {
-	let elementsObject;
-
-	// If a query selector has been passed, transform it into a real element.
-	if ( typeof elements == 'string' ) {
-		elementsObject = toElementsObject( document.querySelectorAll( elements ) );
-	}
-	// Arrays and array-like objects.
-	else if ( isArrayLike( elements ) ) {
-		elementsObject = toElementsObject( elements );
-	}
-	// Single HTML element.
-	else if ( elements instanceof HTMLElement ) {
-		elementsObject = toElementsObject( [ elements ] );
-	}
-	// Object.
-	else {
-		elementsObject = clone( elements );
-	}
-
-	if ( !Object.keys( elementsObject ).length ) {
-		throw new CKEditorError( 'ckeditor5-create-no-elements: No elements have been passed to CKEDITOR.create()' );
-	}
-
-	return elementsObject;
-}
-
-function toElementsObject( elements ) {
-	return Array.from( elements ).reduce( ( ret, el ) => {
-		ret[ getEditorElementName( el ) ] = el;
-
-		return ret;
-	}, {} );
-}
-
-function getEditorElementName( element ) {
-	if ( element.id ) {
-		return element.id;
-	}
-
-	if ( element.dataset.editable ) {
-		return element.dataset.editable;
-	}
-
-	return 'editable' + uid();
-}

+ 1 - 1
package.json

@@ -19,7 +19,7 @@
     "ckeditor5-ui": "ckeditor/ckeditor5-ui",
     "ckeditor5-ui-default": "ckeditor/ckeditor5-ui-default",
     "ckeditor5-undo": "ckeditor/ckeditor5-undo",
-    "ckeditor5-utils": "ckeditor/ckeditor5-utils",
+    "ckeditor5-utils": "ckeditor/ckeditor5-utils#t/39",
     "requirejs": "Reinmar/requirejs"
   },
   "devDependencies": {

+ 0 - 26
src/creator/creator.js

@@ -1,26 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import Plugin from '../plugin.js';
-
-/**
- * Base creator class.
- *
- * @memberOf ckeditor5.creator
- * @extends ckeditor5.Plugin
- */
-export default class Creator extends Plugin {
-	/**
-	 * The creator's trigger. This method is called by the editor to finalize
-	 * the editor creation.
-	 *
-	 * @returns {Promise}
-	 */
-	create() {
-		return Promise.resolve();
-	}
-}

+ 0 - 158
src/creator/standardcreator.js

@@ -1,158 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import Creator from './creator.js';
-import HtmlDataProcessor from '../engine/dataprocessor/htmldataprocessor.js';
-
-/**
- * Standard creator for browser environment.
- *
- * @memberOf ckeditor5.creator
- * @extends ckeditor5.creator.Creator
- */
-export default class StandardCreator extends Creator {
-	/**
-	 * Creates an instance of the standard creator. Initializes the engine ({@link engine.model.Document document},
-	 * {@link engine.EditingController editing controller} and
-	 * {@link engine.DataController data controller}).
-	 *
-	 * @param {ckeditor5.Editor} editor The editor instance.
-	 * @param {engine.dataProcessor.DataProcessor} [dataProcessor=engine.dataProcessor.HtmlDataProcessor] The data
-	 * processor to use. If no data processor is provided {@link engine.dataProcessor.HtmlDataProcessor HtmlDataProcessor}
-	 * will be used.
-	 */
-	constructor( editor, dataProcessor = new HtmlDataProcessor() ) {
-		super( editor );
-
-		editor.data.processor = dataProcessor;
-
-		/**
-		 * The elements replaced by {@link ckeditor5.creator.StandardCreator#_replaceElement} and their replacements.
-		 *
-		 * @private
-		 * @member {Array.<Object>} ckeditor5.creator.StandardCreator#_replacedElements
-		 */
-		this._replacedElements = [];
-	}
-
-	destroy() {
-		super.destroy();
-
-		this._restoreElements();
-	}
-
-	/**
-	 * Updates the {@link ckeditor5.Editor#element editor element}'s content with the data.
-	 *
-	 * @param [elementName='main'] If not specified, the first element will be used.
-	 */
-	updateEditorElement( elementName = 'main' ) {
-		StandardCreator.setDataInElement(
-			this.editor.elements.get( this.editor.firstElementName ),
-			this.editor.getData( elementName )
-		);
-	}
-
-	/**
-	 * Updates all {@link ckeditor5.Editor#element editor elements} content with the data taken from
-	 * their corresponding editables.
-	 */
-	updateEditorElements() {
-		this.editor.elements.forEach( ( editorElement, elementName ) => {
-			this.updateEditorElement( elementName );
-		} );
-	}
-
-	/**
-	 * Loads the data from the given {@link ckeditor5.Editor#element editor element} to the editable.
-	 *
-	 * @param [elementName='main']
-	 */
-	loadDataFromEditorElement( elementName = 'main' ) {
-		this.editor.setData(
-			StandardCreator.getDataFromElement( this.editor.elements.get( this.editor.firstElementName ) ),
-			elementName
-		);
-	}
-
-	/**
-	 * Loads the data from all {@link ckeditor5.Editor#element editor elements} to their corresponding editables.
-	 */
-	loadDataFromEditorElements() {
-		this.editor.elements.forEach( ( editorElement, elementName ) => {
-			this.loadDataFromEditorElement( elementName );
-		} );
-	}
-
-	/**
-	 * Gets data from a given source element.
-	 *
-	 * @param {HTMLElement} el The element from which the data will be retrieved.
-	 * @returns {String} The data string.
-	 */
-	static getDataFromElement( el ) {
-		if ( el instanceof HTMLTextAreaElement ) {
-			return el.value;
-		}
-
-		return el.innerHTML;
-	}
-
-	/**
-	 * Sets data in a given element.
-	 *
-	 * @param {HTMLElement} el The element in which the data will be set.
-	 * @param {String} data The data string.
-	 */
-	static setDataInElement( el, data ) {
-		if ( el instanceof HTMLTextAreaElement ) {
-			el.value = data;
-		}
-
-		el.innerHTML = data;
-	}
-
-	/**
-	 * Hides one of the {@link ckeditor5.Editor#elements editor elements} and, if specified, inserts the the given element
-	 * (e.g. the editor's UI main element) next to it.
-	 *
-	 * The effect of this method will be automatically reverted by {@link ckeditor5.creator.StandardCreator#destroy destroy}.
-	 *
-	 * The second argument may not be passed and then the element will be replaced by nothing, so in other words it will
-	 * be hidden.
-	 *
-	 * @protected
-	 * @param {HTMLElement} element The element to replace.
-	 * @param {HTMLElement} [newElement] The replacement element. If not passed, then the `element` will just be hidden.
-	 */
-	_replaceElement( element, newElement ) {
-		this._replacedElements.push( { element, newElement } );
-
-		element.style.display = 'none';
-
-		if ( newElement ) {
-			element.parentNode.insertBefore( newElement, element.nextSibling );
-		}
-	}
-
-	/**
-	 * Restores what the {@link ckeditor5.creator.StandardCreator#_replaceElement _replaceElement} did.
-	 *
-	 * @protected
-	 */
-	_restoreElements() {
-		this._replacedElements.forEach( ( { element, newElement } ) => {
-			element.style.display = '';
-
-			if ( newElement ) {
-				newElement.remove();
-			}
-		} );
-
-		this._replacedElements = [];
-	}
-}

+ 0 - 356
src/editor.js

@@ -1,356 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import ObservableMixin from './utils/observablemixin.js';
-import Config from './utils/config.js';
-import PluginCollection from './plugincollection.js';
-import Locale from './utils/locale.js';
-import KeystrokeHandler from './keystrokehandler.js';
-import EditingController from './engine/editingcontroller.js';
-import DataController from './engine/datacontroller.js';
-import Document from './engine/model/document.js';
-
-import CKEditorError from './utils/ckeditorerror.js';
-import isArray from './utils/lib/lodash/isArray.js';
-import nth from './utils/nth.js';
-import mix from './utils/mix.js';
-
-/**
- * Represents a single editor instance.
- *
- * @memberOf ckeditor5
- * @mixes utils.ObservaleMixin
- */
-export default class Editor {
-	/**
-	 * Creates a new instance of the Editor class.
-	 *
-	 * This constructor should be rarely used. When creating new editor instance use instead the
-	 * {@link CKEDITOR#create `CKEDITOR.create()` method}.
-	 *
-	 * @param {Object.<String, HTMLElement>|null} [elements] The DOM elements that will be the source
-	 * for the created editor.
-	 * @param {Object} config The editor config.
-	 */
-	constructor( elements, config ) {
-		/**
-		 * The original host page elements upon which the editor is created.
-		 *
-		 * @readonly
-		 * @member {Map.<String, HTMLElement>|null} ckeditor5.Editor#elements
-		 */
-		if ( elements ) {
-			this.elements = new Map();
-
-			for ( let name in elements ) {
-				this.elements.set( name, elements[ name ] );
-			}
-		} else {
-			this.elements = null;
-		}
-
-		/**
-		 * Holds all configurations specific to this editor instance.
-		 *
-		 * @readonly
-		 * @member {utils.Config} ckeditor5.Editor#config
-		 */
-		this.config = config = new Config( config );
-
-		/**
-		 * The plugins loaded and in use by this editor instance.
-		 *
-		 * @readonly
-		 * @member {ckeditor5.PluginCollection} ckeditor5.Editor#plugins
-		 */
-		this.plugins = new PluginCollection( this );
-
-		/**
-		 * Commands registered to the editor.
-		 *
-		 * @readonly
-		 * @member {Map.<ckeditor5.command.Command>} ckeditor5.Editor#commands
-		 */
-		this.commands = new Map();
-
-		/**
-		 * @readonly
-		 * @member {utils.Locale} ckeditor5.Editor#locale
-		 */
-		this.locale = new Locale( config.lang );
-
-		/**
-		 * Shorthand for {@link utils.Locale#t}.
-		 *
-		 * @see utils.Locale#t
-		 * @method ckeditor5.Editor#t
-		 */
-		this.t = this.locale.t;
-
-		/**
-		 * Tree Model document managed by this editor.
-		 *
-		 * This property is set by the {@link ckeditor5.creator.Creator}.
-		 *
-		 * @readonly
-		 * @member {engine.model.Document} ckeditor5.Editor#document
-		 */
-		this.document = new Document();
-
-		/**
-		 * Instance of the {@link engine.EditingController editing controller}.
-		 *
-		 * This property is set by the {@link ckeditor5.creator.Creator}.
-		 *
-		 * @readonly
-		 * @member {engine.EditingController} ckeditor5.Editor#editing
-		 */
-		this.editing = new EditingController( this.document );
-
-		/**
-		 * Instance of the {@link engine.DataController data controller}.
-		 *
-		 * This property is set by the {@link ckeditor5.creator.Creator}.
-		 *
-		 * @readonly
-		 * @member {engine.DataController} ckeditor5.Editor#data
-		 */
-		this.data = new DataController( this.document );
-
-		/**
-		 * Instance of the {@link ckeditor5.KeystrokeHandler}.
-		 *
-		 * This property is set by the {@link ckeditor5.creator.Creator}.
-		 *
-		 * @readonly
-		 * @member {engine.treecontroller.DataController} ckeditor5.Editor#keystrokes
-		 */
-		this.keystrokes = new KeystrokeHandler( this );
-
-		/**
-		 * The chosen creator.
-		 *
-		 * @protected
-		 * @member {ckeditor5.creator.Creator} ckeditor5.Editor#_creator
-		 */
-	}
-
-	/**
-	 * First element from {@link ckeditor5.Editor#elements}.
-	 *
-	 * @readonly
-	 * @type {HTMLElement|null}
-	 */
-	get firstElement() {
-		if ( !this.elements ) {
-			return null;
-		}
-
-		return nth( 0, this.elements )[ 1 ];
-	}
-
-	/**
-	 * Name of the first element from {@link ckeditor5.Editor#elements}.
-	 *
-	 * @readonly
-	 * @type {String|null}
-	 */
-	get firstElementName() {
-		if ( !this.elements ) {
-			return null;
-		}
-
-		return nth( 0, this.elements )[ 0 ];
-	}
-
-	/**
-	 * Initializes the editor instance object after its creation.
-	 *
-	 * The initialization consists of the following procedures:
-	 *
-	 * * Loading and initializing the configured features and creator.
-	 * * Firing the editor creator.
-	 *
-	 * This method should be rarely used as {@link CKEDITOR#create} calls it one should never use the `Editor`
-	 * constructor directly.
-	 *
-	 * @returns {Promise} A promise which resolves once the initialization is completed.
-	 */
-	init() {
-		const that = this;
-		const config = this.config;
-		let creatorName = config.creator;
-
-		if ( !creatorName ) {
-			/**
-			 * The `config.creator` option was not defined.
-			 *
-			 * @error editor-undefined-creator
-			 */
-			return Promise.reject(
-				new CKEditorError( 'editor-undefined-creator: The config.creator option was not defined.' )
-			);
-		}
-
-		return loadPlugins()
-			.then( initPlugins )
-			.then( fireCreator );
-
-		function loadPlugins() {
-			let plugins = config.features || [];
-
-			// Handle features passed as a string.
-			if ( !isArray( plugins ) ) {
-				plugins = plugins.split( ',' );
-			}
-
-			plugins.push( creatorName );
-
-			return that.plugins.load( plugins );
-		}
-
-		function initPlugins( loadedPlugins ) {
-			return loadedPlugins.reduce( ( promise, plugin ) => {
-				return promise.then( plugin.init.bind( plugin ) );
-			}, Promise.resolve() );
-		}
-
-		function fireCreator() {
-			// We can always get the creator by its name because config.creator (which is requried) is passed
-			// to PluginCollection.load().
-			that._creator = that.plugins.get( creatorName );
-
-			// Finally fire the creator. It may be asynchronous, returning a promise.
-			return that._creator.create();
-		}
-	}
-
-	/**
-	 * Destroys the editor instance, releasing all resources used by it. If the editor replaced an element, the
-	 * element will be recovered.
-	 *
-	 * @fires ckeditor5.Editor#destroy
-	 * @returns {Promise} A promise that resolves once the editor instance is fully destroyed.
-	 */
-	destroy() {
-		this.fire( 'destroy' );
-		this.stopListening();
-
-		// Note: The destruction order should be the reverse of the initialization order.
-		return Promise.resolve()
-			.then( () => {
-				return this._creator && this._creator.destroy();
-			} )
-			.then( () => this.editables.destroy() )
-			.then( () => {
-				this.document.destroy();
-				this.editing.destroy();
-				this.data.destroy();
-			} );
-	}
-
-	/**
-	 * Sets the data in the specified editor's editable root.
-	 *
-	 * @param {*} data The data to load.
-	 * @param {String} [editableRootName] The name of the editable root to which the data should be loaded.
-	 * If not specified and if there's only one editable root added to the editor, then the data will be loaded
-	 * to that editable.
-	 */
-	setData( data, editableRootName ) {
-		if ( !this.data ) {
-			/**
-			 * Data controller has not been defined yet, so methds like {@link ckeditor5.Editor#setData} and
-			 * {@link ckeditor5.Editor#getData} cannot be used.
-			 *
-			 * @error editor-no-datacontroller
-			 */
-			throw new CKEditorError( 'editor-no-datacontroller: Data controller has not been defined yet.' );
-		}
-
-		this.data.set( data, editableRootName || this._getDefaultRootName() );
-	}
-
-	/**
-	 * Gets the data from the specified editor's editable root.
-	 *
-	 * @param {String} [editableRootName] The name of the editable root to get the data from.
-	 * If not specified and if there's only one editable root added to the editor, then the data will be retrieved
-	 * from it.
-	 */
-	getData( editableRootName ) {
-		if ( !this.data ) {
-			throw new CKEditorError( 'editor-no-datacontroller: Data controller has not been defined yet.' );
-		}
-
-		return this.data.get( editableRootName || this._getDefaultRootName() );
-	}
-
-	/**
-	 * Executes specified command with given parameter.
-	 *
-	 * @param {String} commandName Name of command to execute.
-	 * @param {*} [commandParam] If set, command will be executed with this parameter.
-	 */
-	execute( commandName, commandParam ) {
-		let command = this.commands.get( commandName );
-
-		if ( !command ) {
-			/**
-			 * Specified command has not been added to the editor.
-			 *
-			 * @error editor-command-not-found
-			 */
-			throw new CKEditorError( 'editor-command-not-found: Specified command has not been added to the editor.' );
-		}
-
-		command._execute( commandParam );
-	}
-
-	/**
-	 * Returns name of the editable root if there is only one. If there are multiple or no editable roots, throws an error.
-	 *
-	 * Note: The error message makes sense only for methods like {@link ckeditor5.Editor#setData} and
-	 * {@link ckeditor5.Editor#getData}.
-	 *
-	 * @private
-	 * @returns {String}
-	 */
-	_getDefaultRootName() {
-		const rootNames = Array.from( this.document.rootNames );
-
-		if ( rootNames.length > 1 ) {
-			/**
-			 * The name of the editable root must be specified. There are multiple editable roots added to the editor,
-			 * so the name of the editable must be specified.
-			 *
-			 * @error editor-editable-root-name-missing
-			 */
-			throw new CKEditorError( 'editor-editable-root-name-missing: The name of the editable root must be specified.' );
-		}
-
-		if ( rootNames.length === 0 ) {
-			/**
-			 * The editor does not contain any editable roots, so the data cannot be set or read from it.
-			 *
-			 * @error editor-no-editable-roots
-			 */
-			throw new CKEditorError( 'editor-no-editable-roots: There are no editable roots defined.' );
-		}
-
-		return rootNames[ 0 ];
-	}
-}
-
-mix( Editor, ObservableMixin );
-
-/**
- * Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to
- * perform the clean-up in any plugin.
- *
- * @event ckeditor5.Editor#destroy
- */

+ 166 - 0
src/editor/editor.js

@@ -0,0 +1,166 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import EmitterMixin from '../utils/emittermixin.js';
+import Config from '../utils/config.js';
+import PluginCollection from '../plugincollection.js';
+import Locale from '../utils/locale.js';
+import DataController from '../engine/datacontroller.js';
+import Document from '../engine/model/document.js';
+
+import CKEditorError from '../utils/ckeditorerror.js';
+import isArray from '../utils/lib/lodash/isArray.js';
+import mix from '../utils/mix.js';
+
+/**
+ * Represents a single editor instance.
+ *
+ * @memberOf ckeditor5
+ * @mixes utils.EmitterMixin
+ */
+export default class Editor {
+	/**
+	 * Creates a new instance of the Editor class.
+	 *
+	 * @param {Object} config The editor config.
+	 */
+	constructor( config ) {
+		/**
+		 * Holds all configurations specific to this editor instance.
+		 *
+		 * @readonly
+		 * @member {utils.Config} ckeditor5.Editor#config
+		 */
+		this.config = new Config( config );
+
+		/**
+		 * The plugins loaded and in use by this editor instance.
+		 *
+		 * @readonly
+		 * @member {ckeditor5.PluginCollection} ckeditor5.Editor#plugins
+		 */
+		this.plugins = new PluginCollection( this );
+
+		/**
+		 * Commands registered to the editor.
+		 *
+		 * @readonly
+		 * @member {Map.<ckeditor5.command.Command>} ckeditor5.Editor#commands
+		 */
+		this.commands = new Map();
+
+		/**
+		 * @readonly
+		 * @member {utils.Locale} ckeditor5.Editor#locale
+		 */
+		this.locale = new Locale( this.config.get( 'lang' ) );
+
+		/**
+		 * Shorthand for {@link utils.Locale#t}.
+		 *
+		 * @see utils.Locale#t
+		 * @method ckeditor5.Editor#t
+		 */
+		this.t = this.locale.t;
+
+		/**
+		 * Tree Model document managed by this editor.
+		 *
+		 * @readonly
+		 * @member {engine.model.Document} ckeditor5.Editor#document
+		 */
+		this.document = new Document();
+
+		/**
+		 * Instance of the {@link engine.DataController data controller}.
+		 *
+		 * @readonly
+		 * @member {engine.DataController} ckeditor5.Editor#data
+		 */
+		this.data = new DataController( this.document );
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @returns {Promise} A promise which resolves once the initialization is completed.
+	 */
+	initPlugins() {
+		const that = this;
+		const config = this.config;
+
+		return loadPlugins()
+			.then( initPlugins );
+
+		function loadPlugins() {
+			let plugins = config.features || [];
+
+			// Handle features passed as a string.
+			if ( !isArray( plugins ) ) {
+				plugins = plugins.split( ',' );
+			}
+
+			return that.plugins.load( plugins );
+		}
+
+		function initPlugins( loadedPlugins ) {
+			return loadedPlugins.reduce( ( promise, plugin ) => {
+				return promise.then( plugin.init.bind( plugin ) );
+			}, Promise.resolve() );
+		}
+	}
+
+	/**
+	 * Destroys the editor instance, releasing all resources used by it. If the editor replaced an element, the
+	 * element will be recovered.
+	 *
+	 * @fires ckeditor5.Editor#destroy
+	 * @returns {Promise} A promise that resolves once the editor instance is fully destroyed.
+	 */
+	destroy() {
+		this.fire( 'destroy' );
+		this.stopListening();
+
+		// Note: The destruction order should be the reverse of the initialization order.
+		return Promise.resolve()
+			.then( () => {
+				this.document.destroy();
+				this.editing.destroy();
+				this.data.destroy();
+			} );
+	}
+
+	/**
+	 * Executes specified command with given parameter.
+	 *
+	 * @param {String} commandName Name of command to execute.
+	 * @param {*} [commandParam] If set, command will be executed with this parameter.
+	 */
+	execute( commandName, commandParam ) {
+		let command = this.commands.get( commandName );
+
+		if ( !command ) {
+			/**
+			 * Specified command has not been added to the editor.
+			 *
+			 * @error editor-command-not-found
+			 */
+			throw new CKEditorError( 'editor-command-not-found: Specified command has not been added to the editor.' );
+		}
+
+		command._execute( commandParam );
+	}
+}
+
+mix( Editor, EmitterMixin );
+
+/**
+ * Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to
+ * perform the clean-up in any plugin.
+ *
+ * @event ckeditor5.Editor#destroy
+ */

+ 95 - 0
src/editor/standardeditor.js

@@ -0,0 +1,95 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import Editor from './editor.js';
+import KeystrokeHandler from '../keystrokehandler.js';
+import EditingController from '../engine/editingcontroller.js';
+
+import CKEditorError from '../utils/ckeditorerror.js';
+import getDataFromElement from '../utils/dom/getdatafromelement.js';
+import setDataInElement from '../utils/dom/setdatainelement.js';
+
+/**
+ * Represents a single editor instance.
+ *
+ * @memberOf ckeditor5
+ * @mixes utils.ObservaleMixin
+ */
+export default class StandardEditor extends Editor {
+	/**
+	 * Creates a new instance of the Editor class.
+	 *
+	 * @param {HTMLElement} [element] The DOM element that will be the source
+	 * for the created editor.
+	 * @param {Object} config The editor config.
+	 */
+	constructor( element, config ) {
+		super( config );
+
+		this.element = element;
+
+		/**
+		 * Instance of the {@link engine.EditingController editing controller}.
+		 *
+		 * @readonly
+		 * @member {engine.EditingController} ckeditor5.editor.StandardEditor#editing
+		 */
+		this.editing = new EditingController( this.document );
+
+		/**
+		 * Instance of the {@link ckeditor5.KeystrokeHandler}.
+		 *
+		 * @readonly
+		 * @member {engine.treecontroller.DataController} ckeditor5.editor.StandardEditor#keystrokes
+		 */
+		this.keystrokes = new KeystrokeHandler( this );
+	}
+
+	/**
+	 * Sets the data in the editor's main root.
+	 *
+	 * @param {*} data The data to load.
+	 */
+	setData( data ) {
+		if ( !this.data ) {
+			/**
+			 * Data controller has not been defined yet, so methds like {@link ckeditor5.editor.StandardEditor#setData} and
+			 * {@link ckeditor5.editor.StandardEditor#getData} cannot be used.
+			 *
+			 * @error editor-no-datacontroller
+			 */
+			throw new CKEditorError( 'editor-no-datacontroller: Data controller has not been defined yet.' );
+		}
+
+		this.data.set( data );
+	}
+
+	/**
+	 * Gets the data from the editor's main root.
+	 */
+	getData() {
+		if ( !this.data ) {
+			throw new CKEditorError( 'editor-no-datacontroller: Data controller has not been defined yet.' );
+		}
+
+		return this.data.get();
+	}
+
+	/**
+	 * Updates the {@link ckeditor5.Editor#element editor element}'s content with the data.
+	 */
+	updateEditorElement() {
+		setDataInElement( this.element, this.getData() );
+	}
+
+	/**
+	 * Loads the data from the {@link ckeditor5.Editor#element editor element} to the main root.
+	 */
+	loadDataFromEditorElement() {
+		this.setData( getDataFromElement( this.element ) );
+	}
+}