瀏覽代碼

Removed source files, moved to ckeditor5-core.

Szymon Kupś 9 年之前
父節點
當前提交
9f6e905eb4

+ 1 - 0
package.json

@@ -9,6 +9,7 @@
   ],
   "dependencies": {
     "ckeditor5-basic-styles": "ckeditor/ckeditor5-basic-styles",
+    "ckeditor5-core": "ckeditor/ckeditor5-core",
     "ckeditor5-editor-classic": "ckeditor/ckeditor5-editor-classic",
     "ckeditor5-engine": "ckeditor/ckeditor5-engine",
     "ckeditor5-enter": "ckeditor/ckeditor5-enter",

+ 0 - 185
src/command/attributecommand.js

@@ -1,185 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Command from './command.js';
-import TreeWalker from '../engine/model/treewalker.js';
-import Range from '../engine/model/range.js';
-
-/**
- * An extension of basic {@link ckeditor5.command.Command} class, which provides utilities for a command that sets a single
- * attribute on a text or element with value `true`. AttributeCommand uses {@link engine.model.Document#selection} to
- * decide which nodes (if any) should be changed, and applies or removes attributes from them.
- * See {@link engine.view.Converter#execute} for more.
- *
- * The command checks {@link engine.model.Document#schema} to decide if it should be enabled.
- * See {@link engine.view.Converter#checkSchema} for more.
- *
- * @memberOf ckeditor5.command
- */
-export default class AttributeCommand extends Command {
-	/**
-	 * @see ckeditor5.command.Command
-	 * @param {ckeditor5.Editor} editor
-	 * @param {String} attributeKey Attribute that will be set by the command.
-	 */
-	constructor( editor, attributeKey ) {
-		super( editor );
-
-		/**
-		 * Attribute that will be set by the command.
-		 *
-		 * @member {String} ckeditor5.command.AttributeCommand#attributeKey
-		 */
-		this.attributeKey = attributeKey;
-
-		/**
-		 * Flag indicating whether command is active. For collapsed selection it means that typed characters will have
-		 * the command's attribute set. For range selection it means that all nodes inside have the attribute applied.
-		 *
-		 * @observable
-		 * @member {Boolean} ckeditor5.command.AttributeCommand#value
-		 */
-		this.set( 'value', false );
-
-		this.listenTo( this.editor.document.selection, 'change:attribute', () => {
-			this.value = this.editor.document.selection.hasAttribute( this.attributeKey );
-		} );
-	}
-
-	/**
-	 * Checks {@link engine.model.Document#schema} to decide if the command should be enabled:
-	 * * if selection is on range, the command is enabled if any of nodes in that range can have bold,
-	 * * if selection is collapsed, the command is enabled if text with bold is allowed in that node.
-	 *
-	 * @private
-	 * @returns {Boolean}
-	 */
-	_checkEnabled() {
-		const selection = this.editor.document.selection;
-		const schema = this.editor.document.schema;
-
-		if ( selection.isCollapsed ) {
-			// Check whether schema allows for a test with `attributeKey` in caret position.
-			return schema.check( { name: '$text', inside: selection.getFirstPosition(), attributes: this.attributeKey } );
-		} else {
-			const ranges = selection.getRanges();
-
-			// For all ranges, check nodes in them until you find a node that is allowed to have `attributeKey` attribute.
-			for ( let range of ranges ) {
-				const walker = new TreeWalker( { boundaries: range, mergeCharacters: true } );
-				let last = walker.position;
-				let step = walker.next();
-
-				// Walk the range.
-				while ( !step.done ) {
-					// If returned item does not have name property, it is a model.TextFragment.
-					const name = step.value.item.name || '$text';
-
-					if ( schema.check( { name: name, inside: last, attributes: this.attributeKey } ) ) {
-						// If we found a node that is allowed to have the attribute, return true.
-						return true;
-					}
-
-					last = walker.position;
-					step = walker.next();
-				}
-			}
-		}
-
-		// If we haven't found such node, return false.
-		return false;
-	}
-
-	/**
-	 * Executes the command: adds or removes attributes to nodes or selection.
-	 *
-	 * If the command is active (`value == true`), it will remove attributes. Otherwise, it will set attributes.
-	 *
-	 * The execution result differs, depending on the {@link engine.model.Document#selection}:
-	 * * if selection is on a range, the command applies the attribute on all nodes in that ranges
-	 * (if they are allowed to have this attribute by the{@link engine.model.Schema schema}),
-	 * * if selection is collapsed in non-empty node, the command applies attribute to the {@link engine.model.Document#selection}
-	 * itself (note that typed characters copy attributes from selection),
-	 * * if selection is collapsed in empty node, the command applies attribute to the parent node of selection (note
-	 * that selection inherits all attributes from a node if it is in empty node).
-	 *
-	 * If the command is disabled (`isEnabled == false`) when it is executed, nothing will happen.
-	 *
-	 * @private
-	 * @param {Boolean} [forceValue] If set it will force command behavior. If `true`, command will apply attribute,
-	 * otherwise command will remove attribute. If not set, command will look for it's current value to decide what it should do.
-	 */
-	_doExecute( forceValue ) {
-		const document = this.editor.document;
-		const selection = document.selection;
-		const value = ( forceValue === undefined ) ? !this.value : forceValue;
-
-		if ( selection.isCollapsed ) {
-			if ( value ) {
-				selection.setAttribute( this.attributeKey, true );
-			} else {
-				selection.removeAttribute( this.attributeKey );
-			}
-		} else {
-			// If selection has non-collapsed ranges, we change attribute on nodes inside those ranges.
-			document.enqueueChanges( () => {
-				const ranges = this._getSchemaValidRanges( selection.getRanges() );
-
-				// Keep it as one undo step.
-				const batch = document.batch();
-
-				for ( let range of ranges ) {
-					if ( value ) {
-						batch.setAttribute( range, this.attributeKey, value );
-					} else {
-						batch.removeAttribute( range, this.attributeKey );
-					}
-				}
-			} );
-		}
-	}
-
-	/**
-	 * Walks through given array of ranges and removes parts of them that are not allowed by schema to have the
-	 * attribute set. This is done by breaking a range in two and omitting the not allowed part.
-	 *
-	 * @private
-	 * @param {Array.<engine.model.Range>} ranges Ranges to be validated.
-	 * @returns {Array.<engine.model.Range>} Ranges without invalid parts.
-	 */
-	_getSchemaValidRanges( ranges ) {
-		const validRanges = [];
-
-		for ( let range of ranges ) {
-			const walker = new TreeWalker( { boundaries: range, mergeCharacters: true } );
-			let step = walker.next();
-
-			let last = range.start;
-			let from = range.start;
-			let to = range.end;
-
-			while ( !step.done ) {
-				const name = step.value.item.name || '$text';
-
-				if ( !this.editor.document.schema.check( { name: name, inside: last, attributes: this.attributeKey } ) ) {
-					if ( !from.isEqual( last ) ) {
-						validRanges.push( new Range( from, last ) );
-					}
-
-					from = walker.position;
-				}
-
-				last = walker.position;
-				step = walker.next();
-			}
-
-			if ( from && !from.isEqual( to ) ) {
-				validRanges.push( new Range( from, to ) );
-			}
-		}
-
-		return validRanges;
-	}
-}

+ 0 - 141
src/command/command.js

@@ -1,141 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import ObservableMixin from '../utils/observablemixin.js';
-import mix from '../utils/mix.js';
-
-/**
- * The base class for CKEditor commands.
- *
- * Commands are main way to manipulate editor contents and state. They are mostly used by UI elements (or by other
- * commands) to make changes in Tree Model. Commands are available in every part of code that has access to
- * {@link ckeditor5.Editor} instance, since they are registered in it and executed through {@link ckeditor5.Editor#execute}.
- * Commands instances are available through {@link ckeditor5.Editor#commands}.
- *
- * This is an abstract base class for all commands.
- *
- * @memberOf ckeditor5.command
- * @mixes utils.ObservableMixin
- */
-export default class Command {
-	/**
-	 * Creates a new Command instance.
-	 *
-	 * @param {ckeditor5.Editor} editor Editor on which this command will be used.
-	 */
-	constructor( editor ) {
-		/**
-		 * Editor on which this command will be used.
-		 *
-		 * @readonly
-		 * @member {ckeditor5.Editor} ckeditor5.command.Command#editor
-		 */
-		this.editor = editor;
-
-		/**
-		 * Flag indicating whether a command is enabled or disabled.
-		 * A disabled command should do nothing upon it's execution.
-		 *
-		 * @observable
-		 * @member {Boolean} ckeditor5.command.Command#isEnabled
-		 */
-		this.set( 'isEnabled', true );
-
-		// If schema checking function is specified, add it to the `refreshState` listeners.
-		// Feature will be disabled if it does not apply to schema requirements.
-		if ( this._checkEnabled ) {
-			this.on( 'refreshState', ( evt, data ) => {
-				data.isEnabled = this._checkEnabled();
-			} );
-		}
-	}
-
-	destroy() {
-		this.stopListening();
-	}
-
-	/**
-	 * Fires `refreshState` event and checks it's resolve value to decide whether command should be enabled or not.
-	 * Other parts of code might listen to `refreshState` event on this command and add their callbacks. This
-	 * way the responsibility of deciding whether a command should be enabled is shared.
-	 *
-	 * @fires {@link ckeditor5.command.Command#refreshState refreshState}
-	 */
-	refreshState() {
-		const data = { isEnabled: true };
-		this.fire( 'refreshState', data );
-
-		this.isEnabled = data.isEnabled;
-	}
-
-	/**
-	 * Executes the command if it is enabled.
-	 *
-	 * @protected
-	 * @param {*} param Parameter passed to {@link ckeditor5.command.Command#execute execute} method of this command.
-	 */
-	_execute( param ) {
-		if ( this.isEnabled ) {
-			this._doExecute( param );
-		}
-	}
-
-	/**
-	 * Disables the command. This should be used only by the command itself. Other parts of code should add
-	 * listeners to `refreshState` event.
-	 *
-	 * @protected
-	 */
-	_disable() {
-		this.on( 'refreshState', disableCallback );
-		this.refreshState();
-	}
-
-	/**
-	 * Enables the command (internally). This should be used only by the command itself. Command will be enabled if
-	 * other listeners does not return false on `refreshState` event callbacks. Firing {@link ckeditor5.command.Command#_enable}
-	 * does not guarantee that {@link ckeditor5.command.Command#isEnabled} will be set to true, as it depends on other listeners.
-	 *
-	 * @protected
-	 */
-	_enable() {
-		this.off( 'refreshState', disableCallback );
-		this.refreshState();
-	}
-
-	/**
-	 * Executes command.
-	 * This is an abstract method that should be overwritten in child classes.
-	 *
-	 * @protected
-	 */
-	_doExecute() {}
-
-	/**
-	 * Checks if a command should be enabled according to its own rules. Mostly it will check schema to see if the command
-	 * is allowed to be executed in given position. This method can be defined in child class (but is not obligatory).
-	 * If it is defined, it will be added as a callback to `refreshState` event.
-	 *
-	 * @protected
-	 * @method ckeditor5.command.Command#_checkEnabled
-	 * @returns {Boolean} `true` if command should be enabled according to {@link engine.model.Document#schema}. `false` otherwise.
-	 */
-}
-
-function disableCallback( evt, data ) {
-	data.isEnabled = false;
-}
-
-mix( Command, ObservableMixin );
-
-/**
- * Fired whenever command has to have its {@link ckeditor5.command.Command#isEnabled} property refreshed. Every feature,
- * command or other class which needs to disable command (set `isEnabled` to `false`) should listen to this
- * event.
- *
- * @event ckeditor5.command.Command#refreshState
- * @param {Object} data
- * @param {Boolean} [data.isEnabled=true]
- */

+ 0 - 194
src/editor/editor.js

@@ -1,194 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-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';
-
-/**
- * Class representing a basic editor. It contains a base architecture, without much additional logic.
- *
- * See also {@link ckeditor5.editor.StandardEditor}.
- *
- * @memberOf ckeditor5.editor
- * @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 );
-
-		/**
-		 * Instance of the {@link engine.EditingController editing controller}.
-		 *
-		 * This property is set by more specialized editor classes (such as {@link ckeditor5.editor.StandardEditor}),
-		 * however, it's required for features to work as their engine-related parts will try to connect converters.
-		 *
-		 * When defining a virtual editor class, like one working in Node.js, it's possible to plug a virtual
-		 * editing controller which only instantiates necessary properties, but without any observers and listeners.
-		 *
-		 * @readonly
-		 * @member {engine.EditingController} ckeditor5.editor.Editor#editing
-		 */
-	}
-
-	/**
-	 * Loads and initilizes plugins specified in config features.
-	 *
-	 * @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.get( '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.
-	 *
-	 * @fires ckeditor5.editor.Editor#destroy
-	 * @returns {Promise} A promise that resolves once the editor instance is fully destroyed.
-	 */
-	destroy() {
-		this.fire( 'destroy' );
-		this.stopListening();
-
-		return Promise.resolve()
-			.then( () => {
-				this.document.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 );
-	}
-
-	/**
-	 * Creates a basic editor instance.
-	 *
-	 * @param {Object} config See {@link ckeditor5.editor.StandardEditor}'s param.
-	 * @returns {Promise} Promise resolved once editor is ready.
-	 * @returns {ckeditor5.editor.StandardEditor} return.editor The editor instance.
-	 */
-	static create( config ) {
-		return new Promise( ( resolve ) => {
-			const editor = new this( config );
-
-			resolve(
-				editor.initPlugins()
-					.then( () => editor )
-			);
-		} );
-	}
-}
-
-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.Editor#destroy
- */

+ 0 - 118
src/editor/standardeditor.js

@@ -1,118 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Editor from './editor.js';
-import KeystrokeHandler from '../keystrokehandler.js';
-import EditingController from '../engine/editingcontroller.js';
-
-import getDataFromElement from '../utils/dom/getdatafromelement.js';
-import setDataInElement from '../utils/dom/setdatainelement.js';
-
-/**
- * Class representing a typical browser-based editor. It handles a single source element and
- * uses {@link engine.EditingController}.
- *
- * @memberOf ckeditor5.editor
- */
-export default class StandardEditor extends Editor {
-	/**
-	 * Creates a new instance of the standard editor.
-	 *
-	 * @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 );
-
-		/**
-		 * The element on which the editor has been initialized.
-		 *
-		 * @readonly
-		 * @member {HTMLElement} ckeditor5.editor.StandardEditor#element
-		 */
-		this.element = element;
-
-		// Documented in Editor.
-		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 );
-
-		/**
-		 * Editor UI instance.
-		 *
-		 * This property is set by more specialized editor constructors. However, it's required
-		 * for features to work (their UI-related part will try to interact with editor UI),
-		 * so every editor class which is meant to work with default features should set this property.
-		 *
-		 * @readonly
-		 * @member {ui.editorUI.EditorUI} ckeditor5.editor.StandardEditor#ui
-		 */
-	}
-
-	/**
-	 * @inheritDoc
-	 */
-	destroy() {
-		return Promise.resolve()
-			.then( () => this.editing.destroy() )
-			.then( super.destroy() );
-	}
-
-	/**
-	 * Sets the data in the editor's main root.
-	 *
-	 * @param {*} data The data to load.
-	 */
-	setData( data ) {
-		this.data.set( data );
-	}
-
-	/**
-	 * Gets the data from the editor's main root.
-	 */
-	getData() {
-		return this.data.get();
-	}
-
-	/**
-	 * Updates the {@link ckeditor5.editor.StandardEditor#element editor element}'s content with the data.
-	 */
-	updateEditorElement() {
-		setDataInElement( this.element, this.getData() );
-	}
-
-	/**
-	 * Loads the data from the {@link ckeditor5.editor.StandardEditor#element editor element} to the main root.
-	 */
-	loadDataFromEditorElement() {
-		this.setData( getDataFromElement( this.element ) );
-	}
-
-	/**
-	 * Creates a standard editor instance.
-	 *
-	 * @param {HTMLElement} element See {@link ckeditor5.editor.StandardEditor}'s param.
-	 * @param {Object} config See {@link ckeditor5.editor.StandardEditor}'s param.
-	 * @returns {Promise} Promise resolved once editor is ready.
-	 * @returns {ckeditor5.editor.StandardEditor} return.editor The editor instance.
-	 */
-	static create( element, config ) {
-		return new Promise( ( resolve ) => {
-			const editor = new this( element, config );
-
-			resolve(
-				editor.initPlugins()
-					.then( () => editor )
-			);
-		} );
-	}
-}

+ 0 - 20
src/feature.js

@@ -1,20 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Plugin from './plugin.js';
-
-/**
- * The base class for CKEditor feature classes. Features are main way to enhance CKEditor abilities with tools,
- * utilities, services and components.
- *
- * The main responsibilities for Feature are:
- * * setting required dependencies (see {@link ckeditor5.Plugin#requires},
- * * configuring, instantiating and registering commands to editor,
- * * registering converters to editor (if the feature operates on Tree Model),
- * * setting and registering UI components (if the feature uses it).
- *
- * @memberOf ckeditor5
- */
-export default class Feature extends Plugin {}

+ 0 - 107
src/keystrokehandler.js

@@ -1,107 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import EmitterMixin from './utils/emittermixin.js';
-import { getCode, parseKeystroke } from './utils/keyboard.js';
-
-/**
- * Keystroke handler. Its instance is available in {@link ckeditor5.Editor#keystrokes} so features
- * can register their keystrokes.
- *
- * E.g. an undo feature would do this:
- *
- *		editor.keystrokes.set( 'ctrl + Z', 'undo' );
- *		editor.keystrokes.set( 'ctrl + shift + Z', 'redo' );
- *		editor.keystrokes.set( 'ctrl + Y', 'redo' );
- *
- * @memberOf ckeditor5
- */
-export default class KeystrokeHandler {
-	/**
-	 * Creates an instance of the keystroke handler.
-	 *
-	 * @param {engine.treeView.TreeView} editingView
-	 */
-	constructor( editor ) {
-		/**
-		 * The editor instance.
-		 *
-		 * @readonly
-		 * @member {ckeditor5.Editor} ckeditor5.KeystrokeHandler#editor
-		 */
-		this.editor = editor;
-
-		/**
-		 * Listener used to listen to events for easier keystroke handler destruction.
-		 *
-		 * @private
-		 * @member {utils.Emitter} ckeditor5.KeystrokeHandler#_listener
-		 */
-		this._listener = Object.create( EmitterMixin );
-
-		/**
-		 * Map of the defined keystrokes. Keystroke codes are the keys.
-		 *
-		 * @private
-		 * @member {Map} ckeditor5.KeystrokeHandler#_keystrokes
-		 */
-		this._keystrokes = new Map();
-
-		this._listener.listenTo( editor.editing.view, 'keydown', ( evt, data ) => {
-			const handled = this.press( data );
-
-			if ( handled ) {
-				data.preventDefault();
-			}
-		} );
-	}
-
-	/**
-	 * Registers a handler for the specified keystroke.
-	 *
-	 * The handler can be specified as a command name or a callback.
-	 *
-	 * @param {String|Array.<String|Number>} keystroke Keystroke defined in a format accepted by
-	 * the {@link utils.keyboard.parseKeystroke} function.
-	 * @param {String|Function} callback If a string is passed, then the keystroke will
-	 * {@link ckeditor5.Editor#execute execute a command}.
-	 * If a function, then it will be called with the
-	 * {@link engine.view.observer.keyObserver.KeyEventData key event data} object.
-	 */
-	set( keystroke, callback ) {
-		this._keystrokes.set( parseKeystroke( keystroke ), callback );
-	}
-
-	/**
-	 * Triggers a keystroke handler for a specified key combination, if such a keystroke was {@link #set defined}.
-	 *
-	 * @param {engine.view.observer.keyObserver.KeyEventData} keyEventData Key event data.
-	 * @returns {Boolean} Whether the keystroke was handled.
-	 */
-	press( keyEventData ) {
-		const keyCode = getCode( keyEventData );
-		const callback = this._keystrokes.get( keyCode );
-
-		if ( !callback ) {
-			return false;
-		}
-
-		if ( typeof callback == 'string' ) {
-			this.editor.execute( callback );
-		} else {
-			callback( keyEventData );
-		}
-
-		return true;
-	}
-
-	/**
-	 * Destroys the keystroke handler.
-	 */
-	destroy() {
-		this._keystrokes = new Map();
-		this._listener.stopListening();
-	}
-}

+ 0 - 35
src/load__amd.js

@@ -1,35 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-// We import the 'require' module, so Require.JS gives us a localized version of require().
-// Otherwise we would use the global one which resolves paths relatively to the base dir.
-import require from 'require';
-
-/**
- * Loads a module.
- *
- *		load( 'ckeditor5/editor.js' )
- *			.then( ( EditorModule ) => {
- *				const Editor = EditorModule.default;
- *			} );
- *
- * @param {String} modulePath Path to the module, relative to `ckeditor.js`'s parent directory (the root).
- * @returns {Promise}
- */
-export default function load( modulePath ) {
-	modulePath = '../' + modulePath;
-
-	return new Promise( ( resolve, reject ) => {
-		require(
-			[ modulePath ],
-			( module ) => {
-				resolve( module );
-			},
-			( err ) => {
-				reject( err );
-			}
-		);
-	} );
-}

+ 0 - 14
src/load__cjs.js

@@ -1,14 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* global require */
-
-export default function load( modulePath ) {
-	modulePath = '../' + modulePath;
-
-	return new Promise( ( resolve ) => {
-		resolve( require( modulePath ) );
-	} );
-}

+ 0 - 16
src/load__esnext.js

@@ -1,16 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* global System */
-
-export default function load( modulePath ) {
-	modulePath = '../' + modulePath;
-
-	return System
-		.import( modulePath )
-		.then( ( module ) => {
-			return module;
-		} );
-}

+ 0 - 59
src/plugin.js

@@ -1,59 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import ObservableMixin from './utils/observablemixin.js';
-import mix from './utils/mix.js';
-
-/**
- * The base class for CKEditor plugin classes.
- *
- * @memberOf ckeditor5
- * @mixes utils.ObservaleMixin
- */
-export default class Plugin {
-	/**
-	 * Creates a new Plugin instance.
-	 *
-	 * @param {ckeditor5.Editor} editor
-	 */
-	constructor( editor ) {
-		/**
-		 * @readonly
-		 * @member {ckeditor5.Editor} ckeditor5.Plugin#editor
-		 */
-		this.editor = editor;
-	}
-
-	/**
-	 * An array of plugins required by this plugin.
-	 *
-	 * To keep a plugin class definition tight it's recommended to define this property as a static getter:
-	 *
-	 *		import Image from './image.js';
-	 *
-	 *		export default class ImageCaption extends Feature {
-     *			static get requires() {
-     *				return [ Image ];
-     *			}
-	 *		}
-	 *
-	 * @static
-	 * @member {Function[]} ckeditor5.Plugin.requires
-	 */
-
-	/**
-	 * @returns {null|Promise}
-	 */
-	init() {}
-
-	/**
-	 * Destroys the plugin.
-	 *
-	 * @returns {null|Promise}
-	 */
-	destroy() {}
-}
-
-mix( Plugin, ObservableMixin );

+ 0 - 173
src/plugincollection.js

@@ -1,173 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Plugin from './plugin.js';
-import CKEditorError from './utils/ckeditorerror.js';
-import log from './utils/log.js';
-import load from './load.js';
-
-/**
- * Manages a list of CKEditor plugins, including loading, resolving dependencies and initialization.
- *
- * @memberOf ckeditor5
- */
-export default class PluginCollection {
-	/**
-	 * Creates an instance of the PluginCollection class, initializing it with a set of plugins.
-	 *
-	 * @param {ckeditor5.Editor} editor
-	 */
-	constructor( editor ) {
-		/**
-		 * @protected
-		 * @member {ckeditor5.Editor} ckeditor5.PluginCollection#_editor
-		 */
-		this._editor = editor;
-
-		/**
-		 * @protected
-		 * @member {Map} ckeditor5.PluginCollection#_plugins
-		 */
-		this._plugins = new Map();
-	}
-
-	/**
-	 * Collection iterator. Returns `[ key, plugin ]` pairs. Plugins which are
-	 * kept in the collection twice (under their name and class) will be returned twice.
-	 */
-	[ Symbol.iterator ]() {
-		return this._plugins[ Symbol.iterator ]();
-	}
-
-	/**
-	 * Gets the plugin instance by its name or class.
-	 *
-	 * @param {String/Function} key The name of the plugin or the class.
-	 * @returns {ckeditor5.Plugin}
-	 */
-	get( key ) {
-		return this._plugins.get( key );
-	}
-
-	/**
-	 * Loads a set of plugins and add them to the collection.
-	 *
-	 * @param {String[]} plugins An array of plugins to load.
-	 * @returns {Promise} A promise which gets resolved once all plugins are loaded and available into the
-	 * collection.
-	 * @param {ckeditor5.Plugin[]} returns.loadedPlugins The array of loaded plugins.
-	 */
-	load( plugins ) {
-		const that = this;
-		const editor = this._editor;
-		const loading = new Set();
-		const loaded = [];
-
-		return Promise.all( plugins.map( loadPlugin ) )
-			.then( () => loaded );
-
-		function loadPlugin( pluginClassOrName ) {
-			// The plugin is already loaded or being loaded - do nothing.
-			if ( that.get( pluginClassOrName ) || loading.has( pluginClassOrName ) ) {
-				return;
-			}
-
-			let promise = ( typeof pluginClassOrName == 'string' ) ?
-				loadPluginByName( pluginClassOrName ) :
-				loadPluginByClass( pluginClassOrName );
-
-			return promise
-				.catch( ( err ) => {
-					/**
-					 * It was not possible to load the plugin.
-					 *
-					 * @error plugincollection-load
-					 * @param {String} plugin The name of the plugin that could not be loaded.
-					 */
-					log.error( 'plugincollection-load: It was not possible to load the plugin.', { plugin: pluginClassOrName } );
-
-					throw err;
-				} );
-		}
-
-		function loadPluginByName( pluginName ) {
-			return load( PluginCollection.getPluginPath( pluginName ) )
-				.then( ( PluginModule ) => {
-					return loadPluginByClass( PluginModule.default, pluginName );
-				} );
-		}
-
-		function loadPluginByClass( PluginClass, pluginName ) {
-			return new Promise( ( resolve ) => {
-				loading.add( PluginClass );
-
-				assertIsPlugin( PluginClass );
-
-				if ( PluginClass.requires ) {
-					PluginClass.requires.forEach( loadPlugin );
-				}
-
-				const plugin = new PluginClass( editor );
-				that._add( PluginClass, plugin );
-				loaded.push( plugin );
-
-				// Expose the plugin also by its name if loaded through load() by name.
-				if ( pluginName ) {
-					that._add( pluginName, plugin );
-				}
-
-				resolve();
-			} );
-		}
-
-		function assertIsPlugin( LoadedPlugin ) {
-			if ( !( LoadedPlugin.prototype instanceof Plugin ) ) {
-				/**
-				 * The loaded plugin module is not an instance of Plugin.
-				 *
-				 * @error plugincollection-instance
-				 * @param {LoadedPlugin} plugin The class which is meant to be loaded as a plugin.
-				 */
-				throw new CKEditorError(
-					'plugincollection-instance: The loaded plugin module is not an instance of Plugin.',
-					{ plugin: LoadedPlugin }
-				);
-			}
-		}
-	}
-
-	/**
-	 * Resolves a simplified plugin name to a real path. The returned
-	 * paths are relative to the main `ckeditor.js` file, but they do not start with `./`.
-	 *
-	 * For instance:
-	 *
-	 * * `foo` will be transformed to `ckeditor5/foo/foo.js`,
-	 * * `ui/controller` to `ckeditor5/ui/controller.js` and
-	 * * `foo/bar/bom` to `ckeditor5/foo/bar/bom.js`.
-	 *
-	 * @param {String} name
-	 * @returns {String} Path to the module.
-	 */
-	static getPluginPath( name ) {
-		// Resolve shortened feature names to `featureName/featureName`.
-		if ( name.indexOf( '/' ) < 0 ) {
-			name = name + '/' + name;
-		}
-
-		return 'ckeditor5/' + name + '.js';
-	}
-
-	/**
-	 * Adds the plugin to the collection. Exposed mainly for testing purposes.
-	 *
-	 * @protected
-	 * @param {String/Function} key The name or the plugin class.
-	 * @param {ckeditor5.Plugin} plugin The instance of the plugin.
-	 */
-	_add( key, plugin ) {
-		this._plugins.set( key, plugin );
-	}
-}

+ 0 - 23
tests/.jshintrc

@@ -1,23 +0,0 @@
-{
-  "browser": true,
-  "esnext": true,
-  "expr": true,
-  "immed": true,
-  "loopfunc": true,
-  "noarg": true,
-  "nonbsp": true,
-  "strict": "implied",
-  "undef": true,
-  "unused": true,
-  "varstmt": true,
-  "globals": {
-    "after": false,
-    "afterEach": false,
-    "before": false,
-    "beforeEach": false,
-    "describe": false,
-    "expect": false,
-    "it": false,
-    "sinon": false
-  }
-}

+ 0 - 93
tests/_utils-tests/classictesteditor.js

@@ -1,93 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import StandardEditor from '/ckeditor5/editor/standardeditor.js';
-import ClassicTestEditor from '/tests/ckeditor5/_utils/classictesteditor.js';
-import HtmlDataProcessor from '/ckeditor5/engine/dataprocessor/htmldataprocessor.js';
-import BoxedEditorUI from '/ckeditor5/ui/editorui/boxed/boxededitorui.js';
-import Feature from '/ckeditor5/feature.js';
-
-import { getData } from '/tests/engine/_utils/model.js';
-import testUtils from '/tests/ckeditor5/_utils/utils.js';
-
-testUtils.createSinonSandbox();
-
-describe( 'ClassicTestEditor', () => {
-	let editorElement;
-
-	beforeEach( () => {
-		editorElement = document.createElement( 'div' );
-		document.body.appendChild( editorElement );
-	} );
-
-	describe( 'constructor', () => {
-		it( 'creates an instance of editor', () => {
-			const editor = new ClassicTestEditor( editorElement, { foo: 1 } );
-
-			expect( editor ).to.be.instanceof( StandardEditor );
-
-			expect( editor.config.get( 'foo' ) ).to.equal( 1 );
-			expect( editor ).to.have.property( 'element', editorElement );
-		} );
-
-		it( 'creates model and view roots', () => {
-			const editor = new ClassicTestEditor( { foo: 1 } );
-
-			expect( editor.document.getRoot() ).to.have.property( 'name', '$root' );
-			expect( editor.editing.view.getRoot() ).to.have.property( 'name', 'div' );
-			expect( editor.data.processor ).to.be.instanceof( HtmlDataProcessor );
-		} );
-	} );
-
-	describe( 'create', () => {
-		it( 'creates an instance of editor', () => {
-			return ClassicTestEditor.create( editorElement, { foo: 1 } )
-				.then( editor => {
-					expect( editor ).to.be.instanceof( ClassicTestEditor );
-
-					expect( editor.config.get( 'foo' ) ).to.equal( 1 );
-					expect( editor ).to.have.property( 'element', editorElement );
-				} );
-		} );
-
-		it( 'creates and initilizes the UI', () => {
-			return ClassicTestEditor.create( editorElement, { foo: 1 } )
-				.then( editor => {
-					expect( editor.ui ).to.be.instanceof( BoxedEditorUI );
-				} );
-		} );
-
-		it( 'loads data from the editor element', () => {
-			editorElement.innerHTML = 'foo';
-
-			class FeatureTextInRoot extends Feature {
-				init() {
-					this.editor.document.schema.allow( { name: '$text', inside: '$root' } );
-				}
-			}
-
-			return ClassicTestEditor.create( editorElement, { features: [ FeatureTextInRoot ] } )
-				.then( editor => {
-					expect( getData( editor.document, { withoutSelection: true } ) ).to.equal( 'foo' );
-				} );
-		} );
-	} );
-
-	describe( 'destroy', () => {
-		it( 'destroys UI and calls super.destroy()', () => {
-			return ClassicTestEditor.create( editorElement, { foo: 1 } )
-				.then( editor => {
-					const superSpy = testUtils.sinon.spy( StandardEditor.prototype, 'destroy' );
-					const uiSpy = sinon.spy( editor.ui, 'destroy' );
-
-					return editor.destroy()
-						.then( () => {
-							expect( superSpy.calledOnce ).to.be.true;
-							expect( uiSpy.calledOnce ).to.be.true;
-						} );
-				} );
-		} );
-	} );
-} );

+ 0 - 35
tests/_utils-tests/createsinonsandbox.js

@@ -1,35 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import testUtils from '/tests/ckeditor5/_utils/utils.js';
-
-const obj = {
-	method() {}
-};
-const origMethod = obj.method;
-let spy;
-
-testUtils.createSinonSandbox();
-
-describe( 'testUtils.createSinonSandbox()', () => {
-	it( 'creates a sandbox', () => {
-		expect( testUtils.sinon ).to.be.an( 'object' );
-		expect( testUtils.sinon ).to.have.property( 'spy' );
-	} );
-
-	// This test is needed for the following one.
-	it( 'really works', () => {
-		spy = testUtils.sinon.spy( obj, 'method' );
-
-		expect( obj ).to.have.property( 'method', spy );
-	} );
-
-	it( 'restores spies after each test', () => {
-		obj.method();
-
-		sinon.assert.notCalled( spy );
-		expect( obj ).to.have.property( 'method', origMethod );
-	} );
-} );

+ 0 - 83
tests/_utils-tests/modeltesteditor.js

@@ -1,83 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Editor from '/ckeditor5/editor/editor.js';
-import ModelTestEditor from '/tests/ckeditor5/_utils/modeltesteditor.js';
-import HtmlDataProcessor from '/ckeditor5/engine/dataprocessor/htmldataprocessor.js';
-import { getData, setData } from '/tests/engine/_utils/model.js';
-
-import testUtils from '/tests/ckeditor5/_utils/utils.js';
-
-testUtils.createSinonSandbox();
-
-describe( 'ModelTestEditor', () => {
-	describe( 'constructor', () => {
-		it( 'creates an instance of editor', () => {
-			const editor = new ModelTestEditor( { foo: 1 } );
-
-			expect( editor ).to.be.instanceof( Editor );
-
-			expect( editor.config.get( 'foo' ) ).to.equal( 1 );
-		} );
-
-		it( 'creates model and view roots', () => {
-			const editor = new ModelTestEditor( { foo: 1 } );
-
-			expect( editor.document.getRoot() ).to.have.property( 'name', '$root' );
-			expect( editor.data.processor ).to.be.instanceof( HtmlDataProcessor );
-		} );
-	} );
-
-	describe( 'create', () => {
-		it( 'creates an instance of editor', () => {
-			return ModelTestEditor.create( { foo: 1 } )
-				.then( editor => {
-					expect( editor ).to.be.instanceof( ModelTestEditor );
-
-					expect( editor.config.get( 'foo' ) ).to.equal( 1 );
-				} );
-		} );
-	} );
-
-	describe( 'setData', () => {
-		let editor;
-
-		beforeEach( () => {
-			return ModelTestEditor.create()
-				.then( newEditor => {
-					editor = newEditor;
-
-					editor.document.schema.allow( { name: '$text', inside: '$root' } );
-				} );
-		} );
-
-		it( 'should set data of the first root', () => {
-			editor.document.createRoot( '$root', 'secondRoot' );
-
-			editor.setData( 'foo' );
-
-			expect( getData( editor.document, { rootName: 'main', withoutSelection: true } ) ).to.equal( 'foo' );
-		} );
-	} );
-
-	describe( 'getData', () => {
-		let editor;
-
-		beforeEach( () => {
-			return ModelTestEditor.create()
-				.then( newEditor => {
-					editor = newEditor;
-
-					editor.document.schema.allow( { name: '$text', inside: '$root' } );
-				} );
-		} );
-
-		it( 'should set data of the first root', () => {
-			setData( editor.document, 'foo' );
-
-			expect( editor.getData() ).to.equal( 'foo' );
-		} );
-	} );
-} );

+ 0 - 120
tests/_utils-tests/module__amd.js

@@ -1,120 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* global require, bender */
-
-import testUtils from '/tests/ckeditor5/_utils/utils.js';
-import moduleTestUtils from '/tests/ckeditor5/_utils/module.js';
-
-testUtils.createSinonSandbox();
-
-describe( 'amdTestUtils', () => {
-	const getModulePath = moduleTestUtils.getModulePath;
-
-	describe( 'getModulePath()', () => {
-		it( 'generates a path from a simple name', () => {
-			const path = getModulePath( 'foo' );
-
-			expect( path ).to.equal( '/ckeditor5/foo.js' );
-		} );
-
-		it( 'generates an absolute path from a simple path', () => {
-			const path = getModulePath( 'engine/dataController' );
-
-			expect( path ).to.equal( '/ckeditor5/engine/dataController.js' );
-		} );
-
-		it( 'does not process an absolute path', () => {
-			const path = getModulePath( '/foo/bar/bom.js' );
-
-			expect( path ).to.equal( '/foo/bar/bom.js' );
-		} );
-	} );
-
-	describe( 'define()', () => {
-		it( 'defines a module by using global define()', () => {
-			const spy = testUtils.sinon.spy( window, 'define' );
-			const expectedDeps = [ 'exports' ].concat( [ 'bar', 'ckeditor' ].map( getModulePath ) );
-
-			moduleTestUtils.define( 'test1', [ 'bar', 'ckeditor' ], () => {} );
-
-			expect( spy.calledOnce ).to.be.true;
-			expect( spy.args[ 0 ][ 0 ] ).to.equal( getModulePath( 'test1' ) );
-			expect( spy.args[ 0 ][ 1 ] ).to.deep.equal( expectedDeps );
-		} );
-
-		it( 'maps body args and returned value', () => {
-			const spy = testUtils.sinon.spy( window, 'define' );
-			const bodySpy = sinon.spy( () => 'ret' );
-
-			moduleTestUtils.define( 'test2', [ 'bar', 'ckeditor' ], bodySpy );
-
-			const realBody = spy.args[ 0 ][ 2 ];
-			const exportsObj = {};
-
-			expect( realBody ).to.be.a( 'function' );
-
-			realBody( exportsObj, { default: 'arg' } );
-
-			expect( exportsObj ).to.have.property( 'default', 'ret', 'it wraps the ret value with an ES6 module obj' );
-			expect( bodySpy.calledOnce ).to.be.true;
-			expect( bodySpy.args[ 0 ][ 0 ] ).to.equal( 'arg', 'it unwraps the args' );
-		} );
-
-		it( 'works with module name and body', () => {
-			const spy = testUtils.sinon.spy( window, 'define' );
-
-			moduleTestUtils.define( 'test1', () => {} );
-
-			expect( spy.calledOnce ).to.be.true;
-			expect( spy.args[ 0 ][ 0 ] ).to.equal( getModulePath( 'test1' ) );
-			expect( spy.args[ 0 ][ 1 ] ).to.deep.equal( [ 'exports' ] );
-			expect( spy.args[ 0 ][ 2 ] ).to.be.a( 'function' );
-		} );
-
-		// Note: this test only checks whether Require.JS doesn't totally fail when creating a circular dependency.
-		// The value of dependencies are not available anyway inside the amdTestUtils.define() callbacks because
-		// we lose the late-binding by immediately mapping modules to their default exports.
-		it( 'works with circular dependencies', ( done ) => {
-			moduleTestUtils.define( 'test-circular-a', [ 'test-circular-b' ], () => {
-				return 'a';
-			} );
-
-			moduleTestUtils.define( 'test-circular-b', [ 'test-circular-a' ], () => {
-				return 'b';
-			} );
-
-			require( [ 'test-circular-a', 'test-circular-b' ].map( moduleTestUtils.getModulePath ), ( a, b ) => {
-				expect( a ).to.have.property( 'default', 'a' );
-				expect( b ).to.have.property( 'default', 'b' );
-
-				done();
-			} );
-		} );
-	} );
-
-	describe( 'require', () => {
-		it( 'blocks Bender and loads modules through global require()', () => {
-			let requireCb;
-			const deferCbSpy = sinon.spy();
-
-			testUtils.sinon.stub( bender, 'defer', () => deferCbSpy );
-			testUtils.sinon.stub( window, 'require', ( deps, cb ) => {
-				requireCb = cb;
-			} );
-
-			const modules = moduleTestUtils.require( { foo: 'foo/oof', bar: 'bar' } );
-
-			expect( deferCbSpy.called ).to.be.false;
-
-			requireCb( { default: 1 }, { default: 2 } );
-
-			expect( deferCbSpy.calledOnce ).to.be.true;
-
-			expect( modules ).to.have.property( 'foo', 1 );
-			expect( modules ).to.have.property( 'bar', 2 );
-		} );
-	} );
-} );

+ 0 - 101
tests/_utils-tests/module__cjs.js

@@ -1,101 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* global require, process */
-
-import testUtils from '/tests/ckeditor5/_utils/utils.js';
-import moduleTestUtils from '/tests/ckeditor5/_utils/module.js';
-
-testUtils.createSinonSandbox();
-
-const path = require( 'path' );
-const cjsDir = path.join( process.cwd(), 'build', 'cjs' );
-
-describe( 'module utilities', () => {
-	const getModulePath = moduleTestUtils.getModulePath;
-
-	describe( 'getModulePath()', () => {
-		it( 'generates absolute path from a plugin name', () => {
-			const modulePath = getModulePath( 'foo' );
-
-			expect( modulePath ).to.equal( path.join( cjsDir,  '/ckeditor5/foo/foo.js' ) );
-		} );
-
-		it( 'generates an absolute path from a simple path', () => {
-			const modulePath = getModulePath( 'core/editor' );
-
-			expect( modulePath ).to.equal( path.join( cjsDir, '/ckeditor5/core/editor.js' ) );
-		} );
-
-		it( 'does not process an absolute path', () => {
-			const modulePath = getModulePath( '/foo/bar/bom.js' );
-
-			expect( modulePath ).to.equal( path.join( cjsDir, '/foo/bar/bom.js' ) );
-		} );
-	} );
-
-	describe( 'define()', () => {
-		it( 'defines a module using mockery', () => {
-			const mockery = require( 'mockery' );
-			const spy = testUtils.sinon.spy( mockery, 'registerMock' );
-
-			moduleTestUtils.define( 'test1', [ '/ckeditor.js', 'bar' ],  () => {}  );
-
-			expect( spy.calledOnce ).to.be.true;
-			expect( spy.args[ 0 ][ 0 ] ).to.equal( getModulePath( 'test1' ) );
-		} );
-
-		it( 'works with module name and body', () => {
-			const mockery = require( 'mockery' );
-			const spy = testUtils.sinon.spy( mockery, 'registerMock' );
-			const bodySpy = testUtils.sinon.spy( () => {} );
-
-			moduleTestUtils.define( 'test1', bodySpy );
-
-			expect( spy.calledOnce ).to.be.true;
-			expect( spy.args[ 0 ][ 0 ] ).to.equal( getModulePath( 'test1' ) );
-			expect( bodySpy.calledOnce ).to.be.true;
-
-			// No dependencies are passed - check if no arguments were passed to the function.
-			expect( bodySpy.args[ 0 ].length ).to.equal( 0 );
-		} );
-
-		// Note: this test only checks whether CommonJS version of `define()` doesn't totally fail when creating a
-		// circular dependency. The value of dependencies are not available anyway inside the
-		// amdTestUtils.define() callbacks because we lose the late-binding by immediately mapping modules to
-		// their default exports.
-		it( 'works with circular dependencies', () => {
-			moduleTestUtils.define( 'test-circular-a', [ 'test-circular-b' ], () => {
-				return 'a';
-			} );
-
-			moduleTestUtils.define( 'test-circular-b', [ 'test-circular-a' ], () => {
-				return 'b';
-			} );
-
-			const a = require( moduleTestUtils.getModulePath( 'test-circular-a' ) );
-			expect( a ).to.have.property( 'default', 'a' );
-
-			const b = require( moduleTestUtils.getModulePath( 'test-circular-b' ) );
-			expect( b ).to.have.property( 'default', 'b' );
-		} );
-	} );
-
-	describe( 'require', () => {
-		it( 'creates object with loaded modules', () => {
-			// Create first module using mockery library.
-			const mockery = require( 'mockery' );
-			mockery.registerMock( moduleTestUtils.getModulePath( 'module1' ), { default: 'foo' } );
-
-			// Create second module using define.
-			moduleTestUtils.define( 'module2', () => 'bar' );
-
-			const loadedModules = moduleTestUtils.require( { module1: 'module1',  module2: 'module2' } );
-
-			expect( loadedModules.module1 ).to.equal( 'foo' );
-			expect( loadedModules.module2 ).to.equal( 'bar' );
-		} );
-	} );
-} );

+ 0 - 43
tests/_utils-tests/virtualtesteditor.js

@@ -1,43 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import StandardEditor from '/ckeditor5/editor/standardeditor.js';
-import VirtualTestEditor from '/tests/ckeditor5/_utils/virtualtesteditor.js';
-import HtmlDataProcessor from '/ckeditor5/engine/dataprocessor/htmldataprocessor.js';
-
-import testUtils from '/tests/ckeditor5/_utils/utils.js';
-
-testUtils.createSinonSandbox();
-
-describe( 'VirtualTestEditor', () => {
-	describe( 'constructor', () => {
-		it( 'creates an instance of editor', () => {
-			const editor = new VirtualTestEditor( { foo: 1 } );
-
-			expect( editor ).to.be.instanceof( StandardEditor );
-
-			expect( editor.config.get( 'foo' ) ).to.equal( 1 );
-		} );
-
-		it( 'creates model and view roots', () => {
-			const editor = new VirtualTestEditor( { foo: 1 } );
-
-			expect( editor.document.getRoot() ).to.have.property( 'name', '$root' );
-			expect( editor.editing.view.getRoot() ).to.have.property( 'name', 'div' );
-			expect( editor.data.processor ).to.be.instanceof( HtmlDataProcessor );
-		} );
-	} );
-
-	describe( 'create', () => {
-		it( 'creates an instance of editor', () => {
-			return VirtualTestEditor.create( { foo: 1 } )
-				.then( editor => {
-					expect( editor ).to.be.instanceof( VirtualTestEditor );
-
-					expect( editor.config.get( 'foo' ) ).to.equal( 1 );
-				} );
-		} );
-	} );
-} );

+ 0 - 59
tests/_utils/classictesteditor.js

@@ -1,59 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import StandardEditor from '/ckeditor5/editor/standardeditor.js';
-
-import HtmlDataProcessor from '/ckeditor5/engine/dataprocessor/htmldataprocessor.js';
-
-import BoxedEditorUI from '/ckeditor5/ui/editorui/boxed/boxededitorui.js';
-import BoxedEditorUIView from '/ckeditor5/ui/editorui/boxed/boxededitoruiview.js';
-
-/**
- * A simplified classic editor. Useful for testing features.
- *
- * @memberOf tests.ckeditor5._utils
- * @extends ckeditor5.editor.StandardEditor
- */
-export default class ClassicTestEditor extends StandardEditor {
-	/**
-	 * @inheritDoc
-	 */
-	constructor( element, config ) {
-		super( element, config );
-
-		this.document.createRoot();
-
-		this.editing.createRoot( 'div' );
-
-		this.data.processor = new HtmlDataProcessor();
-
-		this.ui = new BoxedEditorUI( this );
-		this.ui.view = new BoxedEditorUIView( this.locale );
-	}
-
-	/**
-	 * @inheritDoc
-	 */
-	destroy() {
-		return this.ui.destroy()
-			.then( () => super.destroy() );
-	}
-
-	/**
-	 * @inheritDoc
-	 */
-	static create( element, config ) {
-		return new Promise( ( resolve ) => {
-			const editor = new this( element, config );
-
-			resolve(
-				editor.initPlugins()
-					.then( () => editor.ui.init() )
-					.then( () => editor.loadDataFromEditorElement() )
-					.then( () => editor )
-			);
-		} );
-	}
-}

+ 0 - 59
tests/_utils/modeltesteditor.js

@@ -1,59 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Editor from '/ckeditor5/editor/editor.js';
-import HtmlDataProcessor from '/ckeditor5/engine/dataprocessor/htmldataprocessor.js';
-
-/**
- * A simple editor implementation with a functional model part of the engine (the document).
- * It contains a full data pipeline but no editing pipeline.
- *
- * Should work in Node.js. If not now, then in the future :).
- *
- * @memberOf tests.ckeditor5._utils
- */
-export default class ModelTestEditor extends Editor {
-	constructor( config ) {
-		super( config );
-
-		this.document.createRoot();
-
-		this.data.processor = new HtmlDataProcessor();
-	}
-
-	/**
-	 * Sets the data in the editor's main root.
-	 *
-	 * @param {*} data The data to load.
-	 */
-	setData( data ) {
-		this.data.set( data );
-	}
-
-	/**
-	 * Gets the data from the editor's main root.
-	 */
-	getData() {
-		return this.data.get();
-	}
-
-	/**
-	 * Creates a virtual, element-less editor instance.
-	 *
-	 * @param {Object} config See {@link ckeditor5.editor.StandardEditor}'s param.
-	 * @returns {Promise} Promise resolved once editor is ready.
-	 * @returns {ckeditor5.editor.VirtualTestEditor} return.editor The editor instance.
-	 */
-	static create( config ) {
-		return new Promise( ( resolve ) => {
-			const editor = new this( config );
-
-			resolve(
-				editor.initPlugins()
-					.then( () => editor )
-			);
-		} );
-	}
-}

+ 0 - 133
tests/_utils/module__amd.js

@@ -1,133 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* globals bender, define, require */
-
-/**
- * AMD tools related to CKEditor.
- */
-const utils = {
-	/**
-	 * Helper for generating a full module path from a simplified name (similar to simplified plugin naming convention).
-	 *
-	 * Transforms:
-	 *
-	 * * `foo/bar` -> `/ckeditor5/foo/bar.js`
-	 *
-	 * If the path is already absolute, then it will be returned without any changes.
-	 *
-	 * @param {String} modulePath The simplified path.
-	 * @returns {String} The real path.
-	 */
-	getModulePath( modulePath ) {
-		// Do nothing – path is already absolute.
-		if ( modulePath.startsWith( '/' ) ) {
-			return modulePath;
-		}
-
-		return '/ckeditor5/' + modulePath + '.js';
-	},
-
-	/**
-	 * Shorthand for defining an AMD module.
-	 *
-	 * This method uses {@link #getModulePath} to process module and dependency paths so you need to use
-	 * the simplified notation.
-	 *
-	 * For simplicity the dependencies passed to the `body` will be unwrapped
-	 * from the ES6 module object (so only the default export will be available). Also the returned value
-	 * will be automatically handled as a default export.
-	 *
-	 * If you need to define a module which has access to other exports or can export more values,
-	 * use the global `define()` function:
-	 *
-	 *		define( 'my/module', [ 'exports', 'foo', ... ], ( FooModule, ... ) {
-	 *			const FooClass = FooModule.default;
-	 *			const FooOtherProp = FooModule.otherProp;
-	 *
-	 *			exports.default = MyClass;
-	 *			exports.otherProp = 1;
-	 *		} );
-	 *
-	 * **Note:** Since this method automatically unwraps modules from the ES6 module object when passing them
-	 * to the `body` function, circular dependencies will not work. If you need them, either use the raw `define()`
-	 * as shown above, or keep all the definitions outside modules and only access the variables from the scope:
-	 *
-	 *		PluginE = createPlugin( 'E' );
-	 *		PluginF = createPlugin( 'F' );
-	 *
-	 *		PluginF.requires = [ PluginE ];
-	 *		PluginE.requires = [ PluginF ];
-	 *
-	 *		amdTestUtils.define( 'E/E', [ 'plugin', 'F/F' ], () => {
-	 *			return PluginE;
-	 *		} );
-	 *
-	 *		amdTestUtils.define( 'F/F', [ 'plugin', 'E/E' ], () => {
-	 *			return PluginF;
-	 *		} );
-	 *
-	 * @param {String} path Path to the module.
-	 * @param {String[]} deps Dependencies of the module.
-	 * @param {Function} body Module body.
-	 */
-	define( path, deps, body ) {
-		if ( arguments.length == 2 ) {
-			body = deps;
-			deps = [];
-		}
-
-		deps = deps.map( utils.getModulePath );
-
-		// Use the exports object instead of returning from modules in order to handle circular deps.
-		// http://requirejs.org/docs/api.html#circular
-		deps.unshift( 'exports' );
-
-		define( utils.getModulePath( path ), deps, function( exports ) {
-			const loadedDeps = Array.from( arguments ).slice( 1 ).map( ( module ) => module.default );
-
-			exports.default = body.apply( this, loadedDeps );
-		} );
-	},
-
-	/**
-	 * Gets an object which holds the CKEditor modules guaranteed to be loaded before tests start.
-	 *
-	 * This method uses {@link #getModulePath} to process module and dependency paths so you need to use
-	 * the simplified notation.
-	 *
-	 *		const modules = amdTestUtils.require( { modelDocument: 'engine/model/document' } );
-	 *
-	 *		// Later on, inside tests:
-	 *		const ModelDocument = modules.modelDocument;
-	 *
-	 * @params {Object} modules The object (`ref => modulePath`) with modules to be loaded.
-	 * @returns {Object} The object that will hold the loaded modules.
-	 */
-	require( modules ) {
-		const resolved = {};
-		const paths = [];
-		const names = [];
-		const done = bender.defer();
-
-		for ( let name in modules ) {
-			names.push( name );
-			paths.push( utils.getModulePath( modules[ name ] ) );
-		}
-
-		require( paths, function( ...loaded ) {
-			for ( let i = 0; i < names.length; i++ ) {
-				resolved[ names[ i ] ] = loaded[ i ].default;
-			}
-
-			// Finally give green light for tests to start.
-			done();
-		} );
-
-		return resolved;
-	}
-};
-
-export default utils;

+ 0 - 119
tests/_utils/module__cjs.js

@@ -1,119 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* globals require, process */
-
-const mockery = require( 'mockery' );
-mockery.enable( {
-	warnOnReplace: false,
-	warnOnUnregistered: false
-} );
-const mocked = [];
-
-const path = require( 'path' );
-
-/**
- * CommonJS tools related to CKEditor.
- */
-const utils = {
-	/**
-	 * Helper for generating an absolute module path from a simplified name.
-	 *
-	 * Transforms:
-	 *
-	 * * `foo` -> `/path/dist/cjs/ckeditor5/foo/foo.js`
-	 * * `foo/bar` -> `/path/dist/cjs/ckeditor5/foo/bar.js`
-	 * * `/ckeditor5/foo.js` -> `/path/dist/cjs/ckeditor5/foo.js`
-	 *
-	 * @param {String} modulePath The simplified path.
-	 * @returns {String} The real path.
-	 */
-	getModulePath( modulePath ) {
-		// Do nothing – path is already absolute.
-		if ( modulePath.startsWith( '/' ) ) {
-			return path.join( process.cwd(), 'build', 'cjs', modulePath );
-		}
-
-		if ( modulePath.indexOf( '/' ) < 0 ) {
-			modulePath = modulePath + '/' + modulePath;
-		}
-
-		return path.join( process.cwd(), 'build', 'cjs', 'ckeditor5', modulePath + '.js' );
-	},
-
-	/**
-	 * Defines module in AMD style using CommonJS modules.
-	 *
-	 * This method uses {@link #getModulePath} to process module and dependency paths so you need to use
-	 * the simplified notation.
-	 *
-	 * For simplicity the dependencies passed to the `body` will be unwrapped
-	 * from the ES6 module object (so only the default export will be available). Also the returned value
-	 * will be automatically handled as a default export.
-	 *
-	 * See also module__amd.js file description.
-	 *
-	 * @param {String} path Path to the module.
-	 * @param {String[]} deps Dependencies of the module.
-	 * @param {Function} body Module body.
-	 */
-	define( path, deps, body ) {
-		if ( arguments.length == 2 ) {
-			body = deps;
-			deps = [];
-		}
-
-		deps = deps
-			.map( ( dependency ) => utils.getModulePath( dependency ) )
-			.map( ( dependency )  => {
-				// Checking if module is already mocked - if module was not mocked it might be a real module.
-				// Using require.resolve to check if module really exists without loading it ( it throws if module is
-				// not present). When module is not mocked and does not exist it will be undefined in module body.
-				try {
-					if ( mocked.indexOf( dependency ) < 0 ) {
-						// Test if required module exists without loading it.
-						require.resolve( dependency );
-					}
-				} catch ( e ) {
-					return;
-				}
-
-				// Return only default export.
-				return require( dependency ).default;
-			} );
-
-		mocked.push( utils.getModulePath( path ) );
-		mockery.registerMock( utils.getModulePath( path ), {
-			default: body.apply( this, deps )
-		} );
-	},
-
-	/**
-	 * Gets an object which holds the CKEditor modules. This function uses synchronous CommonJS `require()`
-	 * method, which means that after executing this method all modules are already loaded.
-	 *
-	 * This method uses {@link #getModulePath} to process module and dependency paths so you need to use
-	 * the simplified notation.
-	 *
-	 *		const modules = amdTestUtils.require( { editor: 'core/Editor' } );
-	 *
-	 *		// Later on, inside tests:
-	 *		const Editor = modules.editor;
-	 *
-	 * @params {Object} modules The object (`ref => modulePath`) with modules to be loaded.
-	 * @returns {Object} The object that will hold the loaded modules.
-	 */
-	require( modules ) {
-		const resolved = {};
-
-		for ( let name in modules ) {
-			resolved[ name ] = require( utils.getModulePath( modules[ name ] ) ).default;
-		}
-
-		return resolved;
-	}
-};
-
-export default utils;

+ 0 - 37
tests/_utils/utils.js

@@ -1,37 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/**
- * General test utils for CKEditor.
- */
-const utils = {
-	/**
-	 * Creates Sinon sandbox in {@link bender#sinon} and plugs `afterEach()` callback which
-	 * restores all spies and stubs created in this sandbox.
-	 *
-	 * See https://github.com/ckeditor/ckeditor5-design/issues/72 and http://sinonjs.org/docs/#sinon-sandbox
-	 *
-	 * Usage:
-	 *
-	 *		// Directly in the test file:
-	 *		testUtils.createSinonSandbox();
-	 *
-	 *		// Then inside tests you can use bender.sinon:
-	 *		it( 'does something', () => {
-	 *			testUtils.sinon.spy( obj, 'method' );
-	 *		} );
-	 */
-	createSinonSandbox() {
-		before( () => {
-			utils.sinon = sinon.sandbox.create();
-		} );
-
-		afterEach( () => {
-			utils.sinon.restore();
-		} );
-	}
-};
-
-export default utils;

+ 0 - 45
tests/_utils/virtualtesteditor.js

@@ -1,45 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import StandardEditor from '/ckeditor5/editor/standardeditor.js';
-import HtmlDataProcessor from '/ckeditor5/engine/dataprocessor/htmldataprocessor.js';
-
-/**
- * A simple editor implementation useful for testing the engine part of the features.
- * It contains full data pipepilne and the engine pipeline but without rendering to DOM.
- *
- * Should work in Node.js. If not now, then in the future :).
- *
- * @memberOf tests.ckeditor5._utils
- */
-export default class VirtualTestEditor extends StandardEditor {
-	constructor( config ) {
-		super( null, config );
-
-		this.document.createRoot();
-
-		this.editing.createRoot( 'div' );
-
-		this.data.processor = new HtmlDataProcessor();
-	}
-
-	/**
-	 * Creates a virtual, element-less editor instance.
-	 *
-	 * @param {Object} config See {@link ckeditor5.editor.StandardEditor}'s param.
-	 * @returns {Promise} Promise resolved once editor is ready.
-	 * @returns {ckeditor5.editor.VirtualTestEditor} return.editor The editor instance.
-	 */
-	static create( config ) {
-		return new Promise( ( resolve ) => {
-			const editor = new this( config );
-
-			resolve(
-				editor.initPlugins()
-					.then( () => editor )
-			);
-		} );
-	}
-}

+ 0 - 264
tests/command/attributecommand.js

@@ -1,264 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Editor from '/ckeditor5/editor/editor.js';
-import Document from '/ckeditor5/engine/model/document.js';
-import AttributeCommand from '/ckeditor5/command/attributecommand.js';
-import Text from '/ckeditor5/engine/model/text.js';
-import Range from '/ckeditor5/engine/model/range.js';
-import Position from '/ckeditor5/engine/model/position.js';
-import Element from '/ckeditor5/engine/model/element.js';
-import writer from '/ckeditor5/engine/model/writer.js';
-import { itemAt } from '/tests/engine/model/_utils/utils.js';
-
-let editor, command, modelDoc, root;
-
-const attrKey = 'bold';
-
-beforeEach( () => {
-	editor = new Editor();
-	editor.document = new Document();
-
-	modelDoc = editor.document;
-	root = modelDoc.createRoot();
-
-	command = new AttributeCommand( editor, attrKey );
-
-	modelDoc.schema.registerItem( 'p', '$block' );
-	modelDoc.schema.registerItem( 'h1', '$block' );
-	modelDoc.schema.registerItem( 'img', '$inline' );
-
-	// Allow block in "root" (DIV)
-	modelDoc.schema.allow( { name: '$block', inside: '$root' } );
-
-	// Bold text is allowed only in P.
-	modelDoc.schema.allow( { name: '$text', attributes: 'bold', inside: 'p' } );
-	modelDoc.schema.allow( { name: 'p', attributes: 'bold', inside: '$root' } );
-
-	// Disallow bold on image.
-	modelDoc.schema.disallow( { name: 'img', attributes: 'bold', inside: '$root' } );
-} );
-
-afterEach( () => {
-	command.destroy();
-} );
-
-describe( 'value', () => {
-	it( 'should be set to true or false basing on selection attribute', () => {
-		modelDoc.selection.setAttribute( attrKey, true );
-		expect( command.value ).to.be.true;
-
-		modelDoc.selection.removeAttribute( attrKey );
-		expect( command.value ).to.be.false;
-	} );
-} );
-
-describe( '_doExecute', () => {
-	let p;
-
-	beforeEach( () => {
-		let attrs = {};
-		attrs[ attrKey ] = true;
-
-		root.insertChildren( 0, [
-			new Element( 'p', [] , [
-				new Text( 'abc' ),
-				new Text( 'foobar', attrs ),
-				new Text( 'xyz' )
-			] ),
-			new Element( 'p' )
-		] );
-
-		p = root.getChild( 0 );
-	} );
-
-	it( 'should add attribute on selected nodes if the command value was false', () => {
-		modelDoc.selection.addRange( new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 5 ] ) ) );
-
-		expect( command.value ).to.be.false;
-
-		command._doExecute();
-
-		expect( command.value ).to.be.true;
-
-		expect( p.getChild( 0 ).hasAttribute( attrKey ) ).to.be.false;
-		expect( itemAt( p, 1 ).hasAttribute( attrKey ) ).to.be.true;
-		expect( itemAt( p, 2 ).hasAttribute( attrKey ) ).to.be.true;
-	} );
-
-	it( 'should remove attribute from selected nodes if the command value was true', () => {
-		modelDoc.selection.addRange( new Range( new Position( root, [ 0, 3 ] ), new Position( root, [ 0, 6 ] ) ) );
-
-		expect( command.value ).to.be.true;
-
-		command._doExecute();
-
-		expect( command.value ).to.be.false;
-		expect( itemAt( p, 3 ).hasAttribute( attrKey ) ).to.be.false;
-		expect( itemAt( p, 4 ).hasAttribute( attrKey ) ).to.be.false;
-		expect( itemAt( p, 5 ).hasAttribute( attrKey ) ).to.be.false;
-	} );
-
-	it( 'should add attribute on selected nodes if execute parameter was set to true', () => {
-		modelDoc.selection.addRange( new Range( new Position( root, [ 0, 7 ] ), new Position( root, [ 0, 10 ] ) ) );
-
-		expect( command.value ).to.be.true;
-
-		command._doExecute( true );
-
-		expect( command.value ).to.be.true;
-		expect( itemAt( p, 9 ).hasAttribute( attrKey ) ).to.be.true;
-	} );
-
-	it( 'should remove attribute on selected nodes if execute parameter was set to false', () => {
-		modelDoc.selection.addRange( new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 5 ] ) ) );
-
-		expect( command.value ).to.be.false;
-
-		command._doExecute( false );
-
-		expect( command.value ).to.be.false;
-		expect( itemAt( p, 3 ).hasAttribute( attrKey ) ).to.be.false;
-		expect( itemAt( p, 4 ).hasAttribute( attrKey ) ).to.be.false;
-	} );
-
-	it( 'should change selection attribute if selection is collapsed in non-empty parent', () => {
-		modelDoc.selection.addRange( new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 1 ] ) ) );
-
-		expect( command.value ).to.be.false;
-
-		command._doExecute();
-
-		expect( command.value ).to.be.true;
-		expect( modelDoc.selection.hasAttribute( 'bold' ) ).to.be.true;
-
-		command._doExecute();
-
-		expect( command.value ).to.be.false;
-		expect( modelDoc.selection.hasAttribute( 'bold' ) ).to.be.false;
-	} );
-
-	it( 'should not store attribute change on selection if selection is collapsed in non-empty parent', () => {
-		modelDoc.selection.addRange( new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 1 ] ) ) );
-		command._doExecute();
-
-		// It should not save that bold was executed at position ( root, [ 0, 1 ] ).
-
-		// Simulate clicking right arrow key by changing selection ranges.
-		modelDoc.selection.setRanges( [ new Range( new Position( root, [ 0, 2 ] ), new Position( root, [ 0, 2 ] ) ) ] );
-
-		// Get back to previous selection.
-		modelDoc.selection.setRanges( [ new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 1 ] ) ) ] );
-
-		expect( command.value ).to.be.false;
-	} );
-
-	it( 'should change selection attribute and store it if selection is collapsed in empty parent', () => {
-		modelDoc.selection.setRanges( [ new Range( new Position( root, [ 1, 0 ] ), new Position( root, [ 1, 0 ] ) ) ] );
-
-		expect( command.value ).to.be.false;
-
-		command._doExecute();
-
-		expect( command.value ).to.be.true;
-		expect( modelDoc.selection.hasAttribute( 'bold' ) ).to.be.true;
-
-		// Attribute should be stored.
-		// Simulate clicking somewhere else in the editor.
-		modelDoc.selection.setRanges( [ new Range( new Position( root, [ 0, 2 ] ), new Position( root, [ 0, 2 ] ) ) ] );
-
-		expect( command.value ).to.be.false;
-
-		// Go back to where attribute was stored.
-		modelDoc.selection.setRanges( [ new Range( new Position( root, [ 1, 0 ] ), new Position( root, [ 1, 0 ] ) ) ] );
-
-		// Attribute should be restored.
-		expect( command.value ).to.be.true;
-
-		command._doExecute();
-
-		expect( command.value ).to.be.false;
-		expect( modelDoc.selection.hasAttribute( 'bold' ) ).to.be.false;
-	} );
-
-	it( 'should not apply attribute change where it would invalid schema', () => {
-		writer.insert( Position.createFromParentAndOffset( p, 3 ), new Element( 'image' ) );
-		writer.insert( Position.createFromParentAndOffset( p, 12 ), new Element( 'image' ) );
-
-		modelDoc.selection.setRanges( [ new Range( new Position( root, [ 0, 2 ] ), new Position( root, [ 0, 13 ] ) ) ] );
-
-		expect( command.isEnabled ).to.be.true;
-
-		command._doExecute();
-
-		let expectedHas = [ 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ];
-
-		let i = 0;
-
-		for ( let node of Range.createFromElement( p ).getItems( { singleCharacters: true } ) ) {
-			expect( node.hasAttribute( attrKey ) ).to.equal( !!expectedHas[ i++ ] );
-		}
-	} );
-} );
-
-describe( '_checkEnabled', () => {
-	beforeEach( () => {
-		root.insertChildren( 0, [
-			new Element( 'p', [], [
-				new Text( 'foo' ),
-				new Element( 'img' ),
-				new Element( 'img' ),
-				new Text( 'bar' )
-			] ),
-			new Element( 'h1' ),
-			new Element( 'p' )
-		] );
-	} );
-
-	describe( 'when selection is collapsed', () => {
-		it( 'should return true if characters with the attribute can be placed at caret position', () => {
-			modelDoc.selection.setRanges( [ new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 1 ] ) ) ] );
-			expect( command._checkEnabled() ).to.be.true;
-		} );
-
-		it( 'should return false if characters with the attribute cannot be placed at caret position', () => {
-			modelDoc.selection.setRanges( [ new Range( new Position( root, [ 1, 0 ] ), new Position( root, [ 1, 0 ] ) ) ] );
-			expect( command._checkEnabled() ).to.be.false;
-
-			modelDoc.selection.setRanges( [ new Range( new Position( root, [ 2 ] ), new Position( root, [ 2 ] ) ) ] );
-			expect( command._checkEnabled() ).to.be.false;
-		} );
-	} );
-
-	describe( 'when selection is not collapsed', () => {
-		it( 'should return true if there is at least one node in selection that can have the attribute', () => {
-			// Simple selection on a few characters.
-			modelDoc.selection.setRanges( [ new Range( new Position( root, [ 0, 0 ] ), new Position( root, [ 0, 3 ] ) ) ] );
-			expect( command._checkEnabled() ).to.be.true;
-
-			// Selection spans over characters but also include nodes that can't have attribute.
-			modelDoc.selection.setRanges( [ new Range( new Position( root, [ 0, 2 ] ), new Position( root, [ 0, 6 ] ) ) ] );
-			expect( command._checkEnabled() ).to.be.true;
-
-			// Selection on whole root content. Characters in P can have an attribute so it's valid.
-			modelDoc.selection.setRanges( [ new Range( new Position( root, [ 0 ] ), new Position( root, [ 3 ] ) ) ] );
-			expect( command._checkEnabled() ).to.be.true;
-
-			// Selection on empty P. P can have the attribute.
-			modelDoc.selection.setRanges( [ new Range( new Position( root, [ 2 ] ), new Position( root, [ 3 ] ) ) ] );
-			expect( command._checkEnabled() ).to.be.true;
-		} );
-
-		it( 'should return false if there are no nodes in selection that can have the attribute', () => {
-			// Selection on DIV which can't have bold text.
-			modelDoc.selection.setRanges( [ new Range( new Position( root, [ 1 ] ), new Position( root, [ 2 ] ) ) ] );
-			expect( command._checkEnabled() ).to.be.false;
-
-			// Selection on two images which can't be bold.
-			modelDoc.selection.setRanges( [ new Range( new Position( root, [ 0, 3 ] ), new Position( root, [ 0, 5 ] ) ) ] );
-			expect( command._checkEnabled() ).to.be.false;
-		} );
-	} );
-} );

+ 0 - 160
tests/command/command.js

@@ -1,160 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Editor from '/ckeditor5/editor/editor.js';
-import Command from '/ckeditor5/command/command.js';
-
-let editor, command;
-
-class CommandWithSchema extends Command {
-	constructor( editor, schemaValid ) {
-		super( editor );
-
-		this.schemaValid = schemaValid;
-	}
-
-	_checkEnabled() {
-		return this.schemaValid;
-	}
-}
-
-beforeEach( () => {
-	editor = new Editor();
-	command = new Command( editor );
-} );
-
-afterEach( () => {
-	// Might be redundant if editor destroys the commands.
-	command.destroy();
-	editor.destroy();
-} );
-
-describe( 'constructor', () => {
-	it( 'should create a new command instance, that is enabled and bound to given editor', () => {
-		expect( command ).to.have.property( 'editor' ).equal( editor );
-		expect( command.isEnabled ).to.be.true;
-	} );
-
-	it( 'Command should have _doExecute method', () => {
-		expect( () => {
-			command._doExecute();
-		} ).not.to.throw;
-	} );
-
-	it( 'should add listener to its refreshState event if checkSchema method is present', () => {
-		expect( command._checkEnabled ).to.be.undefined;
-
-		command._checkEnabled = sinon.spy();
-		command.refreshState();
-
-		expect( command._checkEnabled.called ).to.be.false;
-
-		let newCommand = new CommandWithSchema( editor, true );
-		sinon.spy( newCommand, '_checkEnabled' );
-
-		newCommand.refreshState();
-
-		expect( newCommand._checkEnabled.calledOnce ).to.be.true;
-	} );
-} );
-
-describe( 'destroy', () => {
-	it( 'should stop listening', () => {
-		sinon.spy( command, 'stopListening' );
-
-		command.destroy();
-
-		expect( command.stopListening.calledOnce ).to.be.true;
-	} );
-} );
-
-describe( 'refreshState', () => {
-	it( 'should fire refreshState event', () => {
-		let spy = sinon.spy();
-
-		command.on( 'refreshState', spy );
-		command.refreshState();
-
-		expect( spy.called ).to.be.true;
-	} );
-
-	it( 'should set isEnabled property to the value passed by object-reference', () => {
-		command.on( 'refreshState', ( evt, data ) => {
-			data.isEnabled = true;
-		} );
-
-		expect( command.isEnabled ).to.be.true;
-	} );
-
-	it( 'should set isEnabled to false if _checkEnabled returns false', () => {
-		let disabledCommand = new CommandWithSchema( editor, false );
-
-		disabledCommand.refreshState();
-
-		expect( disabledCommand.isEnabled ).to.be.false;
-	} );
-} );
-
-describe( 'disable', () => {
-	it( 'should make command disabled', () => {
-		command._disable();
-
-		expect( command.isEnabled ).to.be.false;
-	} );
-
-	it( 'should not make command disabled if there is a high-priority listener forcing command to be enabled', () => {
-		command.on( 'refreshState', ( evt ) => {
-			evt.stop();
-
-			return true;
-		}, command, 1 );
-
-		command._disable();
-
-		expect( command.isEnabled ).to.be.true;
-	} );
-} );
-
-describe( 'enable', () => {
-	it( 'should make command enabled if it was previously disabled by disable()', () => {
-		command._disable();
-		command._enable();
-
-		expect( command.isEnabled ).to.be.true;
-	} );
-
-	it( 'should not make command enabled if there are other listeners disabling it', () => {
-		command._disable();
-
-		command.on( 'refreshState', ( evt, data ) => {
-			data.isEnabled = false;
-		} );
-
-		command.refreshState();
-		command._enable();
-
-		expect( command.isEnabled ).to.be.false;
-	} );
-} );
-
-describe( '_execute', () => {
-	it( 'should not execute command if it is disabled', () => {
-		command._disable();
-
-		sinon.spy( command, '_doExecute' );
-
-		command._execute();
-
-		expect( command._doExecute.called ).to.be.false;
-	} );
-
-	it( 'should execute command if it is enabled', () => {
-		sinon.spy( command, '_doExecute' );
-
-		command._execute();
-
-		expect( command._doExecute.called ).to.be.true;
-	} );
-} );

+ 0 - 76
tests/editor/editor-base.js

@@ -1,76 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* bender-tags: editor */
-
-import Editor from '/ckeditor5/editor/editor.js';
-import Command from '/ckeditor5/command/command.js';
-import Locale from '/ckeditor5/utils/locale.js';
-import CKEditorError from '/ckeditor5/utils/ckeditorerror.js';
-
-describe( 'Editor', () => {
-	describe( 'locale', () => {
-		it( 'is instantiated and t() is exposed', () => {
-			const editor = new Editor();
-
-			expect( editor.locale ).to.be.instanceof( Locale );
-			expect( editor.t ).to.equal( editor.locale.t );
-		} );
-
-		it( 'is configured with the config.lang', () => {
-			const editor = new Editor( { lang: 'pl' } );
-
-			expect( editor.locale.lang ).to.equal( 'pl' );
-		} );
-	} );
-
-	describe( 'destroy', () => {
-		it( 'should fire "destroy"', () => {
-			const editor = new Editor();
-			let spy = sinon.spy();
-
-			editor.on( 'destroy', spy );
-
-			return editor.destroy().then( () => {
-				expect( spy.calledOnce ).to.be.true;
-			} );
-		} );
-
-		it( 'should destroy all components it initialized', () => {
-			const editor = new Editor();
-
-			const spy1 = sinon.spy( editor.data, 'destroy' );
-			const spy2 = sinon.spy( editor.document, 'destroy' );
-
-			return editor.destroy()
-				.then( () => {
-					expect( spy1.calledOnce ).to.be.true;
-					expect( spy2.calledOnce ).to.be.true;
-				} );
-		} );
-	} );
-
-	describe( 'execute', () => {
-		it( 'should execute specified command', () => {
-			const editor = new Editor();
-
-			let command = new Command( editor );
-			sinon.spy( command, '_execute' );
-
-			editor.commands.set( 'commandName', command );
-			editor.execute( 'commandName' );
-
-			expect( command._execute.calledOnce ).to.be.true;
-		} );
-
-		it( 'should throw an error if specified command has not been added', () => {
-			const editor = new Editor();
-
-			expect( () => {
-				editor.execute( 'command' );
-			} ).to.throw( CKEditorError, /^editor-command-not-found:/ );
-		} );
-	} );
-} );

+ 0 - 175
tests/editor/editor.js

@@ -1,175 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* bender-tags: editor, browser-only */
-
-import moduleUtils from '/tests/ckeditor5/_utils/module.js';
-import Editor from '/ckeditor5/editor/editor.js';
-import Plugin from '/ckeditor5/plugin.js';
-import Config from '/ckeditor5/utils/config.js';
-import PluginCollection from '/ckeditor5/plugincollection.js';
-
-const pluginClasses = {};
-
-before( () => {
-	pluginDefinition( 'A/A' );
-	pluginDefinition( 'B/B' );
-	pluginDefinition( 'C/C', [ 'B/B' ] );
-	pluginDefinition( 'D/D', [ 'C/C' ] );
-} );
-
-describe( 'Editor', () => {
-	describe( 'constructor', () => {
-		it( 'should create a new editor instance', () => {
-			const editor = new Editor();
-
-			expect( editor.config ).to.be.an.instanceof( Config );
-			expect( editor.commands ).to.be.an.instanceof( Map );
-
-			expect( editor.plugins ).to.be.an.instanceof( PluginCollection );
-			expect( getPlugins( editor ) ).to.be.empty;
-		} );
-	} );
-
-	describe( 'plugins', () => {
-		it( 'should be empty on new editor', () => {
-			const editor = new Editor();
-
-			expect( getPlugins( editor ) ).to.be.empty;
-		} );
-	} );
-
-	describe( 'create', () => {
-		it( 'should return a promise that resolves properly', () => {
-			let promise = Editor.create();
-
-			expect( promise ).to.be.an.instanceof( Promise );
-
-			return promise;
-		} );
-
-		it( 'loads plugins', () => {
-			return Editor.create( {
-					features: [ 'A' ]
-				} )
-				.then( editor => {
-					expect( getPlugins( editor ).length ).to.equal( 1 );
-
-					expect( editor.plugins.get( 'A' ) ).to.be.an.instanceof( Plugin );
-				} );
-		} );
-	} );
-
-	describe( 'initPlugins', () => {
-		it( 'should load features', () => {
-			const editor = new Editor( {
-				features: [ 'A', 'B' ]
-			} );
-
-			expect( getPlugins( editor ) ).to.be.empty;
-
-			return editor.initPlugins().then( () => {
-				expect( getPlugins( editor ).length ).to.equal( 2 );
-
-				expect( editor.plugins.get( 'A' ) ).to.be.an.instanceof( Plugin );
-				expect( editor.plugins.get( 'B' ) ).to.be.an.instanceof( Plugin );
-			} );
-		} );
-
-		it( 'should load features passed as a string', () => {
-			const editor = new Editor( {
-				features: 'A,B'
-			} );
-
-			expect( getPlugins( editor ) ).to.be.empty;
-
-			return editor.initPlugins().then( () => {
-				expect( getPlugins( editor ).length ).to.equal( 2 );
-
-				expect( editor.plugins.get( 'A' ) ).to.be.an.instanceof( Plugin );
-				expect( editor.plugins.get( 'B' ) ).to.be.an.instanceof( Plugin );
-			} );
-		} );
-
-		it( 'should initialize plugins in the right order', () => {
-			const editor = new Editor( {
-				features: [ 'A', 'D' ]
-			} );
-
-			return editor.initPlugins().then( () => {
-				sinon.assert.callOrder(
-					editor.plugins.get( pluginClasses[ 'A/A' ] ).init,
-					editor.plugins.get( pluginClasses[ 'B/B' ] ).init,
-					editor.plugins.get( pluginClasses[ 'C/C' ] ).init,
-					editor.plugins.get( pluginClasses[ 'D/D' ] ).init
-				);
-			} );
-		} );
-
-		it( 'should initialize plugins in the right order, waiting for asynchronous ones', () => {
-			class PluginAsync extends Plugin {}
-			const asyncSpy = sinon.spy().named( 'async-call-spy' );
-
-			// Synchronous plugin that depends on an asynchronous one.
-			pluginDefinition( 'sync/sync', [ 'async/async' ] );
-
-			moduleUtils.define( 'async/async', () => {
-				PluginAsync.prototype.init = sinon.spy( () => {
-					return new Promise( ( resolve ) => {
-						setTimeout( () => {
-							asyncSpy();
-							resolve();
-						}, 0 );
-					} );
-				} );
-
-				return PluginAsync;
-			} );
-
-			const editor = new Editor( {
-				features: [ 'A', 'sync' ]
-			} );
-
-			return editor.initPlugins().then( () => {
-				sinon.assert.callOrder(
-					editor.plugins.get( pluginClasses[ 'A/A' ] ).init,
-					editor.plugins.get( PluginAsync ).init,
-					// This one is called with delay by the async init.
-					asyncSpy,
-					editor.plugins.get( pluginClasses[ 'sync/sync' ] ).init
-				);
-			} );
-		} );
-	} );
-} );
-
-// @param {String} name Name of the plugin.
-// @param {String[]} deps Dependencies of the plugin (only other plugins).
-function pluginDefinition( name, deps ) {
-	moduleUtils.define( name, deps || [], function() {
-		class NewPlugin extends Plugin {}
-
-		NewPlugin.prototype.init = sinon.spy().named( name );
-		NewPlugin.requires = Array.from( arguments );
-
-		pluginClasses[ name ] = NewPlugin;
-
-		return NewPlugin;
-	} );
-}
-
-// Returns an array of loaded plugins.
-function getPlugins( editor ) {
-	const plugins = [];
-
-	for ( let entry of editor.plugins ) {
-		// Keep only plugins kept under their classes.
-		if ( typeof entry[ 0 ] == 'function' ) {
-			plugins.push( entry[ 1 ] );
-		}
-	}
-
-	return plugins;
-}

+ 0 - 137
tests/editor/standardeditor.js

@@ -1,137 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* bender-tags: editor, browser-only */
-
-import StandardEditor from '/ckeditor5/editor/standardeditor.js';
-import HtmlDataProcessor from '/ckeditor5/engine/dataprocessor/htmldataprocessor.js';
-import { getData, setData } from '/tests/engine/_utils/model.js';
-
-import EditingController from '/ckeditor5/engine/editingcontroller.js';
-import KeystrokeHandler from '/ckeditor5/keystrokehandler.js';
-import Feature from '/ckeditor5/feature.js';
-
-describe( 'StandardEditor', () => {
-	let editorElement;
-
-	beforeEach( () => {
-		editorElement = document.createElement( 'div' );
-		document.body.appendChild( editorElement );
-	} );
-
-	describe( 'constructor', () => {
-		it( 'sets all properties', () => {
-			const editor = new StandardEditor( editorElement, { foo: 1 } );
-
-			expect( editor ).to.have.property( 'element', editorElement );
-			expect( editor.editing ).to.be.instanceof( EditingController );
-			expect( editor.keystrokes ).to.be.instanceof( KeystrokeHandler );
-		} );
-
-		it( 'sets config', () => {
-			const editor = new StandardEditor( editorElement, { foo: 1 } );
-
-			expect( editor.config.get( 'foo' ) ).to.equal( 1 );
-		} );
-	} );
-
-	describe( 'create', () => {
-		it( 'initializes editor with plugins and config', () => {
-			class FeatureFoo extends Feature {}
-
-			return StandardEditor.create( editorElement, {
-					foo: 1,
-					features: [ FeatureFoo ]
-				} )
-				.then( editor => {
-					expect( editor ).to.be.instanceof( StandardEditor );
-
-					expect( editor.config.get( 'foo' ) ).to.equal( 1 );
-					expect( editor ).to.have.property( 'element', editorElement );
-
-					expect( editor.plugins.get( FeatureFoo ) ).to.be.instanceof( FeatureFoo );
-				} );
-		} );
-	} );
-
-	describe( 'setData', () => {
-		let editor;
-
-		beforeEach( () => {
-			return StandardEditor.create( editorElement )
-				.then( newEditor => {
-					editor = newEditor;
-
-					editor.data.processor = new HtmlDataProcessor();
-
-					editor.document.schema.allow( { name: '$text', inside: '$root' } );
-				} );
-		} );
-
-		it( 'should set data of the first root', () => {
-			editor.document.createRoot();
-			editor.document.createRoot( '$root', 'secondRoot' );
-
-			editor.editing.createRoot( 'div' );
-			editor.editing.createRoot( 'div', 'secondRoot' );
-
-			editor.setData( 'foo' );
-
-			expect( getData( editor.document, { rootName: 'main', withoutSelection: true } ) ).to.equal( 'foo' );
-		} );
-	} );
-
-	describe( 'getData', () => {
-		let editor;
-
-		beforeEach( () => {
-			return StandardEditor.create( editorElement )
-				.then( newEditor => {
-					editor = newEditor;
-
-					editor.data.processor = new HtmlDataProcessor();
-
-					editor.document.schema.allow( { name: '$text', inside: '$root' } );
-				} );
-		} );
-
-		it( 'should get data of the first root', () => {
-			editor.document.createRoot();
-			editor.document.createRoot( '$root', 'secondRoot' );
-
-			editor.editing.createRoot( 'div' );
-			editor.editing.createRoot( 'div', 'secondRoot' );
-
-			setData( editor.document, 'foo' );
-
-			expect( editor.getData() ).to.equal( 'foo' );
-		} );
-	} );
-
-	describe( 'updateEditorElement', () => {
-		it( 'sets data to editor element', () => {
-			const editor = new StandardEditor( editorElement );
-
-			editor.data.get = () => '<p>foo</p>';
-
-			editor.updateEditorElement();
-
-			expect( editorElement.innerHTML ).to.equal( '<p>foo</p>' );
-		} );
-	} );
-
-	describe( 'loadDataFromEditorElement', () => {
-		it( 'sets data to editor element', () => {
-			const editor = new StandardEditor( editorElement );
-
-			sinon.stub( editor.data, 'set' );
-			editorElement.innerHTML = '<p>foo</p>';
-
-			editor.loadDataFromEditorElement();
-
-			expect( editor.data.set.calledWithExactly( '<p>foo</p>' ) ).to.be.true;
-		} );
-	} );
-} );

+ 0 - 132
tests/keystrokehandler.js

@@ -1,132 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* bender-tags: browser-only */
-
-import VirtualTestEditor from '/tests/ckeditor5/_utils/virtualtesteditor.js';
-import KeystrokeHandler from '/ckeditor5/keystrokehandler.js';
-import { keyCodes } from '/ckeditor5/utils/keyboard.js';
-
-describe( 'KeystrokeHandler', () => {
-	let editor;
-
-	beforeEach( () => {
-		return VirtualTestEditor.create()
-			.then( newEditor => {
-				editor = newEditor;
-				editor.keystrokes = new KeystrokeHandler( editor );
-			} );
-	} );
-
-	describe( 'constructor', () => {
-		it( 'triggers #press on #keydown', () => {
-			const spy = sinon.spy( editor.keystrokes, 'press' );
-			const keyEvtData = { keyCode: 1 };
-
-			editor.editing.view.fire( 'keydown', keyEvtData );
-
-			expect( spy.calledOnce ).to.be.true;
-			expect( spy.calledWithExactly( keyEvtData ) );
-		} );
-
-		it( 'prevents default when keystroke was handled', () => {
-			editor.keystrokes.press = () => true;
-
-			const keyEvtData = { keyCode: 1, preventDefault: sinon.spy() };
-
-			editor.editing.view.fire( 'keydown', keyEvtData );
-
-			expect( keyEvtData.preventDefault.calledOnce ).to.be.true;
-		} );
-	} );
-
-	describe( 'press', () => {
-		it( 'executes a command', () => {
-			const spy = sinon.stub( editor, 'execute' );
-
-			editor.keystrokes.set( 'ctrl + A', 'foo' );
-
-			const wasHandled = editor.keystrokes.press( getCtrlA() );
-
-			expect( spy.calledOnce ).to.be.true;
-			expect( spy.calledWithExactly( 'foo' ) ).to.be.true;
-			expect( wasHandled ).to.be.true;
-		} );
-
-		it( 'executes a callback', () => {
-			const spy = sinon.spy();
-			const keyEvtData = getCtrlA();
-
-			editor.keystrokes.set( 'ctrl + A', spy );
-
-			const wasHandled = editor.keystrokes.press( keyEvtData );
-
-			expect( spy.calledOnce ).to.be.true;
-			expect( spy.calledWithExactly( keyEvtData ) ).to.be.true;
-			expect( wasHandled ).to.be.true;
-		} );
-
-		it( 'returns false when no handler', () => {
-			const keyEvtData = getCtrlA();
-
-			const wasHandled = editor.keystrokes.press( keyEvtData );
-
-			expect( wasHandled ).to.be.false;
-		} );
-	} );
-
-	describe( 'set', () => {
-		it( 'handles array format', () => {
-			const spy = sinon.spy();
-
-			editor.keystrokes.set( [ 'ctrl', 'A' ], spy );
-
-			expect( editor.keystrokes.press( getCtrlA() ) ).to.be.true;
-		} );
-
-		it( 'overrides existing keystroke', () => {
-			const spy1 = sinon.spy();
-			const spy2 = sinon.spy();
-
-			editor.keystrokes.set( [ 'ctrl', 'A' ], spy1 );
-			editor.keystrokes.set( [ 'ctrl', 'A' ], spy2 );
-
-			editor.keystrokes.press( getCtrlA() );
-
-			expect( spy1.calledOnce ).to.be.false;
-			expect( spy2.calledOnce ).to.be.true;
-		} );
-	} );
-
-	describe( 'destroy', () => {
-		it( 'detaches #keydown listener', () => {
-			const spy = sinon.spy( editor.keystrokes, 'press' );
-
-			editor.keystrokes.destroy();
-
-			editor.editing.view.fire( 'keydown', { keyCode: 1 } );
-
-			expect( spy.called ).to.be.false;
-		} );
-
-		it( 'removes all keystrokes', () => {
-			const spy = sinon.spy();
-			const keystrokeHandler = editor.keystrokes;
-
-			keystrokeHandler.set( 'ctrl + A', spy );
-
-			keystrokeHandler.destroy();
-
-			const wasHandled = keystrokeHandler.press( getCtrlA() );
-
-			expect( wasHandled ).to.be.false;
-			expect( spy.called ).to.be.false;
-		} );
-	} );
-} );
-
-function getCtrlA() {
-	return { keyCode: keyCodes.a, ctrlKey: true };
-}

+ 0 - 23
tests/load.js

@@ -1,23 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import load from '/ckeditor5/load.js';
-
-describe( 'load()', () => {
-	it( 'loads plugin.js', () => {
-		return load( 'ckeditor5/plugin.js' )
-			.then( ( PluginModule ) => {
-				expect( PluginModule.default ).to.be.a( 'function' );
-			} );
-	} );
-
-	it( 'loads ckeditor5/editor/editor.js', () => {
-		return load( 'ckeditor5/editor/editor.js' )
-			.then( ( EditorModule ) => {
-				expect( EditorModule.default ).to.be.a( 'function' );
-			} );
-	} );
-} );
-

+ 0 - 21
tests/plugin.js

@@ -1,21 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Plugin from '/ckeditor5/plugin.js';
-import Editor from '/ckeditor5/editor/editor.js';
-
-let editor;
-
-before( () => {
-	editor = new Editor();
-} );
-
-describe( 'constructor', () => {
-	it( 'should set the `editor` property', () => {
-		let plugin = new Plugin( editor );
-
-		expect( plugin ).to.have.property( 'editor' ).to.equal( editor );
-	} );
-} );

+ 0 - 320
tests/plugincollection.js

@@ -1,320 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* bender-tags: browser-only */
-
-import moduleUtils from '/tests/ckeditor5/_utils/module.js';
-import testUtils from '/tests/ckeditor5/_utils/utils.js';
-import Editor from '/ckeditor5/editor/editor.js';
-import PluginCollection from '/ckeditor5/plugincollection.js';
-import Plugin from '/ckeditor5/plugin.js';
-import Feature from '/ckeditor5/feature.js';
-import CKEditorError from '/ckeditor5/utils/ckeditorerror.js';
-import log from '/ckeditor5/utils/log.js';
-
-let editor;
-let PluginA, PluginB, PluginC, PluginD, PluginE, PluginF, PluginG, PluginH, PluginI;
-class TestError extends Error {}
-class GrandPlugin extends Feature {}
-
-testUtils.createSinonSandbox();
-
-before( () => {
-	PluginA = createPlugin( 'A' );
-	PluginB = createPlugin( 'B' );
-	PluginC = createPlugin( 'C' );
-	PluginD = createPlugin( 'D' );
-	PluginE = createPlugin( 'E' );
-	PluginF = createPlugin( 'F' );
-	PluginG = createPlugin( 'G', GrandPlugin );
-	PluginH = createPlugin( 'H' );
-	PluginI = createPlugin( 'I' );
-
-	PluginC.requires = [ PluginB ];
-	PluginD.requires = [ PluginA, PluginC ];
-	PluginF.requires = [ PluginE ];
-	PluginE.requires = [ PluginF ];
-	PluginH.requires = [ PluginI ];
-
-	editor = new Editor();
-} );
-
-// Create fake plugins that will be used on tests.
-
-moduleUtils.define( 'A/A', () => {
-	return PluginA;
-} );
-
-moduleUtils.define( 'B/B', () => {
-	return PluginB;
-} );
-
-moduleUtils.define( 'C/C', [ 'editor/editor', 'B/B' ], () => {
-	return PluginC;
-} );
-
-moduleUtils.define( 'D/D', [ 'editor/editor', 'A/A', 'C/C' ], () => {
-	return PluginD;
-} );
-
-moduleUtils.define( 'E/E', [ 'editor/editor', 'F/F' ], () => {
-	return PluginE;
-} );
-
-moduleUtils.define( 'F/F', [ 'editor/editor', 'E/E' ], () => {
-	return PluginF;
-} );
-
-moduleUtils.define( 'G/G', () => {
-	return PluginG;
-} );
-
-moduleUtils.define( 'H/H', () => {
-	return PluginH;
-} );
-
-moduleUtils.define( 'I/I', () => {
-	return PluginI;
-} );
-
-// Erroneous cases.
-
-moduleUtils.define( 'X/X', () => {
-	throw new TestError( 'Some error inside a plugin' );
-} );
-
-moduleUtils.define( 'Y/Y', () => {
-	return class {};
-} );
-
-/////////////
-
-describe( 'load', () => {
-	it( 'should not fail when trying to load 0 plugins (empty array)', () => {
-		let plugins = new PluginCollection( editor );
-
-		return plugins.load( [] )
-			.then( () => {
-				expect( getPlugins( plugins ) ).to.be.empty();
-			} );
-	} );
-
-	it( 'should add collection items for loaded plugins', () => {
-		let plugins = new PluginCollection( editor );
-
-		return plugins.load( [ 'A', 'B' ] )
-			.then( () => {
-				expect( getPlugins( plugins ).length ).to.equal( 2 );
-
-				expect( plugins.get( PluginA ) ).to.be.an.instanceof( PluginA );
-				expect( plugins.get( PluginB ) ).to.be.an.instanceof( PluginB );
-
-				expect( plugins.get( 'A' ) ).to.be.an.instanceof( PluginA );
-				expect( plugins.get( 'B' ) ).to.be.an.instanceof( PluginB );
-			} );
-	} );
-
-	it( 'should load dependency plugins', () => {
-		let plugins = new PluginCollection( editor );
-		let spy = sinon.spy( plugins, '_add' );
-
-		return plugins.load( [ 'A', 'C' ] )
-			.then( ( loadedPlugins ) => {
-				expect( getPlugins( plugins ).length ).to.equal( 3 );
-
-				expect( getPluginNames( getPluginsFromSpy( spy ) ) )
-					.to.deep.equal( [ 'A', 'B', 'C' ], 'order by plugins._add()' );
-				expect( getPluginNames( loadedPlugins ) )
-					.to.deep.equal( [ 'A', 'B', 'C' ], 'order by returned value' );
-			} );
-	} );
-
-	it( 'should be ok when dependencies are loaded first', () => {
-		let plugins = new PluginCollection( editor );
-		let spy = sinon.spy( plugins, '_add' );
-
-		return plugins.load( [ 'A', 'B', 'C' ] )
-			.then( ( loadedPlugins ) => {
-				expect( getPlugins( plugins ).length ).to.equal( 3 );
-
-				expect( getPluginNames( getPluginsFromSpy( spy ) ) )
-					.to.deep.equal( [ 'A', 'B', 'C' ], 'order by plugins._add()' );
-				expect( getPluginNames( loadedPlugins ) )
-					.to.deep.equal( [ 'A', 'B', 'C' ], 'order by returned value' );
-			} );
-	} );
-
-	it( 'should load deep dependency plugins', () => {
-		let plugins = new PluginCollection( editor );
-		let spy = sinon.spy( plugins, '_add' );
-
-		return plugins.load( [ 'D' ] )
-			.then( ( loadedPlugins ) => {
-				expect( getPlugins( plugins ).length ).to.equal( 4 );
-
-				// The order must have dependencies first.
-				expect( getPluginNames( getPluginsFromSpy( spy ) ) )
-					.to.deep.equal( [ 'A', 'B', 'C', 'D' ], 'order by plugins._add()' );
-				expect( getPluginNames( loadedPlugins ) )
-					.to.deep.equal( [ 'A', 'B', 'C', 'D' ], 'order by returned value' );
-			} );
-	} );
-
-	it( 'should handle cross dependency plugins', () => {
-		let plugins = new PluginCollection( editor );
-		let spy = sinon.spy( plugins, '_add' );
-
-		return plugins.load( [ 'A', 'E' ] )
-			.then( ( loadedPlugins ) => {
-				expect( getPlugins( plugins ).length ).to.equal( 3 );
-
-				// The order must have dependencies first.
-				expect( getPluginNames( getPluginsFromSpy( spy ) ) )
-					.to.deep.equal( [ 'A', 'F', 'E' ], 'order by plugins._add()' );
-				expect( getPluginNames( loadedPlugins ) )
-					.to.deep.equal( [ 'A', 'F', 'E' ], 'order by returned value' );
-			} );
-	} );
-
-	it( 'should load grand child classes', () => {
-		let plugins = new PluginCollection( editor );
-
-		return plugins.load( [ 'G' ] )
-			.then( () => {
-				expect( getPlugins( plugins ).length ).to.equal( 1 );
-			} );
-	} );
-
-	it( 'should make plugin available to get by name when plugin was loaded as dependency first', () => {
-		let plugins = new PluginCollection( editor );
-
-		return plugins.load( [ 'H', 'I' ] )
-			.then( () => {
-				expect( plugins.get( 'I' ) ).to.be.instanceof( PluginI );
-			} );
-	} );
-
-	it( 'should set the `editor` property on loaded plugins', () => {
-		let plugins = new PluginCollection( editor );
-
-		return plugins.load( [ 'A', 'B' ] )
-			.then( () => {
-				expect( plugins.get( 'A' ).editor ).to.equal( editor );
-				expect( plugins.get( 'B' ).editor ).to.equal( editor );
-			} );
-	} );
-
-	it( 'should reject on invalid plugin names (forward require.js loading error)', () => {
-		let logSpy = testUtils.sinon.stub( log, 'error' );
-
-		let plugins = new PluginCollection( editor );
-
-		return plugins.load( [ 'A', 'BAD', 'B' ] )
-			// Throw here, so if by any chance plugins.load() was resolved correctly catch() will be stil executed.
-			.then( () => {
-				throw new Error( 'Test error: this promise should not be resolved successfully' );
-			} )
-			.catch( ( err ) => {
-				expect( err ).to.be.an.instanceof( Error );
-				// Make sure it's the Require.JS error, not the one thrown above.
-				expect( err.message ).to.match( /^Script error for/ );
-
-				sinon.assert.calledOnce( logSpy );
-				expect( logSpy.args[ 0 ][ 0 ] ).to.match( /^plugincollection-load:/ );
-			} );
-	} );
-
-	it( 'should reject on broken plugins (forward the error thrown in a plugin)', () => {
-		let logSpy = testUtils.sinon.stub( log, 'error' );
-
-		let plugins = new PluginCollection( editor );
-
-		return plugins.load( [ 'A', 'X', 'B' ] )
-			// Throw here, so if by any chance plugins.load() was resolved correctly catch() will be stil executed.
-			.then( () => {
-				throw new Error( 'Test error: this promise should not be resolved successfully' );
-			} )
-			.catch( ( err ) => {
-				expect( err ).to.be.an.instanceof( TestError );
-				expect( err ).to.have.property( 'message', 'Some error inside a plugin' );
-
-				sinon.assert.calledOnce( logSpy );
-				expect( logSpy.args[ 0 ][ 0 ] ).to.match( /^plugincollection-load:/ );
-			} );
-	} );
-
-	it( 'should reject when loading a module which is not a plugin', () => {
-		let logSpy = testUtils.sinon.stub( log, 'error' );
-
-		let plugins = new PluginCollection( editor );
-
-		return plugins.load( [ 'Y' ] )
-			// Throw here, so if by any chance plugins.load() was resolved correctly catch() will be stil executed.
-			.then( () => {
-				throw new Error( 'Test error: this promise should not be resolved successfully' );
-			} )
-			.catch( ( err ) => {
-				expect( err ).to.be.an.instanceof( CKEditorError );
-				expect( err.message ).to.match( /^plugincollection-instance/ );
-
-				sinon.assert.calledOnce( logSpy );
-				expect( logSpy.args[ 0 ][ 0 ] ).to.match( /^plugincollection-load:/ );
-			} );
-	} );
-} );
-
-describe( 'getPluginPath()', () => {
-	it( 'generates path for modules within some package', () => {
-		const p = PluginCollection.getPluginPath( 'some/ba' );
-
-		expect( p ).to.equal( 'ckeditor5/some/ba.js' );
-	} );
-
-	it( 'generates path from simplified feature name', () => {
-		const p = PluginCollection.getPluginPath( 'foo' );
-
-		expect( p ).to.equal( 'ckeditor5/foo/foo.js' );
-	} );
-} );
-
-function createPlugin( name, baseClass ) {
-	baseClass = baseClass || Plugin;
-
-	const P = class extends baseClass {
-		constructor( editor ) {
-			super( editor );
-			this._pluginName = name;
-		}
-	};
-
-	P._pluginName = name;
-
-	return P;
-}
-
-function getPlugins( pluginCollection ) {
-	const plugins = [];
-
-	for ( let entry of pluginCollection ) {
-		// Keep only plugins kept under their classes.
-		if ( typeof entry[ 0 ] == 'function' ) {
-			plugins.push( entry[ 1 ] );
-		}
-	}
-
-	return plugins;
-}
-
-function getPluginsFromSpy( addSpy ) {
-	return addSpy.args
-		.map( ( arg ) => arg[ 0 ] )
-		// Entries may be kept twice in the plugins map - once as a pluginName => plugin, once as pluginClass => plugin.
-		// Return only pluginClass => plugin entries as these will always represent all plugins.
-		.filter( ( plugin ) => typeof plugin == 'function' );
-}
-
-function getPluginNames( plugins ) {
-	return plugins.map( ( plugin ) => plugin._pluginName );
-}