ソースを参照

Merge pull request #11 from ckeditor/t/9

Made classic creator a classic editor
Piotr Jasiun 9 年 前
コミット
59ee172c89

+ 101 - 0
packages/ckeditor5-editor-classic/src/classic.js

@@ -0,0 +1,101 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import StandardEditor from '../editor/standardeditor.js';
+
+import HtmlDataProcessor from '../engine/dataprocessor/htmldataprocessor.js';
+
+import ClassicEditorUI from './classiceditorui.js';
+import BoxedEditorUIView from '../ui/editorui/boxed/boxededitoruiview.js';
+
+import ElementReplacer from '../utils/elementreplacer.js';
+
+/**
+ * Classic editor. Uses inline editable and sticky toolbar, all
+ * enclosed in a boxed UI.
+ *
+ * @memberOf editor-classic
+ * @extends ckeditor5.editor.StandardEditor
+ */
+export default class ClassicEditor extends StandardEditor {
+	/**
+	 * Creates an instance of the classic editor.
+	 *
+	 * @param {HTMLElement} element The DOM element that will be the source for the created editor.
+	 * The data will be loaded from it and loaded back to it once the editor is destroyed.
+	 * @param {Object} config The editor config.
+	 */
+	constructor( element, config ) {
+		super( element, config );
+
+		this.document.createRoot();
+
+		this.editing.createRoot( 'div' );
+
+		this.data.processor = new HtmlDataProcessor();
+
+		this.ui = new ClassicEditorUI( this );
+		this.ui.view = new BoxedEditorUIView( this.ui.viewModel, this.locale );
+
+		/**
+		 * The element replacer instance used to hide editor element.
+		 *
+		 * @protected
+		 * @member {utils.ElementReplacer} editor-classic.Classic#_elementReplacer
+		 */
+		this._elementReplacer = new ElementReplacer();
+	}
+
+	/**
+	 * Destroys the editor instance, releasing all resources used by it.
+	 *
+	 * Updates the original editor element with the data.
+	 *
+	 * @returns {Promise}
+	 */
+	destroy() {
+		this.updateEditorElement();
+		this._elementReplacer.restore();
+
+		return this.ui.destroy()
+			.then( () => super.destroy() );
+	}
+
+	/**
+	 * Creates a classic editor instance.
+	 *
+	 *		ClassicEditor.create( document.querySelector( '#editor' ), {
+	 *			features: [ 'delete', 'enter', 'typing', 'paragraph', 'undo', 'basic-styles/bold', 'basic-styles/italic' ],
+	 *			toolbar: [ 'bold', 'italic', 'undo', 'redo' ]
+	 *		} )
+	 *		.then( editor => {
+	 *			console.log( 'Editor was initialized', editor );
+	 *		} )
+	 *		.catch( err => {
+	 *			console.error( err.stack );
+	 *		} );
+	 *
+	 * @param {HTMLElement} element See {@link ckeditor5.editor.ClassicEditor#constructor}'s param.
+	 * @param {Object} config See {@link ckeditor5.editor.ClassicEditor#constructor}'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 ClassicEditor( element, config );
+
+			resolve(
+				editor.initPlugins()
+					.then( () => editor._elementReplacer.replace( element, editor.ui.view.element ) )
+					.then( () => editor.ui.init() )
+					.then( () => editor.editing.view.attachDomRoot( editor.ui.editableElement ) )
+					.then( () => editor.loadDataFromEditorElement() )
+					.then( () => editor )
+			);
+		} );
+	}
+}

+ 0 - 109
packages/ckeditor5-editor-classic/src/classiccreator.js

@@ -1,109 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import StandardCreator from '../creator/standardcreator.js';
-
-import HtmlDataProcessor from '../engine/dataprocessor/htmldataprocessor.js';
-import Editable from '../editable.js';
-
-import { createEditableUI, createEditorUI } from '../ui/creator-utils.js';
-
-import BoxedEditorUI from '../ui/editorui/boxed/boxededitorui.js';
-import BoxedEditorUIView from '../ui/editorui/boxed/boxededitoruiview.js';
-
-import EditableUI from '../ui/editableui/editableui.js';
-import InlineEditableUIView from '../ui/editableui/inline/inlineeditableuiview.js';
-
-import Model from '../ui/model.js';
-import StickyToolbar from '../ui/bindings/stickytoolbar.js';
-import StickyToolbarView from '../ui/stickytoolbar/stickytoolbarview.js';
-
-import { imitateFeatures, imitateDestroyFeatures } from './utils/imitatefeatures.js';
-
-/**
- * Classic editor creator using inline editable and sticky toolbar, all
- * enclosed in a boxed UI.
- *
- * @memberOf creator-classic
- * @extends ckeditor5.creator.StandardCreator
- */
-export default class ClassicCreator extends StandardCreator {
-	/**
-	 * Creates an instance of the classic creator.
-	 *
-	 * @param {ckeditor5.Editor} The editor instance.
-	 */
-	constructor( editor ) {
-		super( editor, new HtmlDataProcessor() );
-
-		const editableName = editor.firstElementName;
-		editor.editables.add( new Editable( editor, editableName ) );
-		editor.document.createRoot( editableName );
-
-		// UI.
-		createEditorUI( editor, BoxedEditorUI, BoxedEditorUIView );
-	}
-
-	/**
-	 * Creates editor UI and loads startup data into the editor.
-	 *
-	 * @returns {Promise}
-	 */
-	create() {
-		const editor = this.editor;
-		const editable = editor.editables.get( 0 );
-
-		// Features mock.
-		imitateFeatures( editor );
-
-		// UI.
-		this._replaceElement( editor.firstElement, editor.ui.view.element );
-		this._createToolbar();
-		editor.ui.add( 'main', createEditableUI( editor, editable, EditableUI, InlineEditableUIView ) );
-
-		// Init.
-		return super.create()
-			.then( () => editor.ui.init() )
-			// We'll be able to do that much earlier once the loading will be done to the document model,
-			// rather than straight to the editable.
-			.then( () => this.loadDataFromEditorElement() );
-	}
-
-	/**
-	 * Updates the original editor element with data and destroys
-	 * the UI.
-	 *
-	 * @returns {Promise}
-	 */
-	destroy() {
-		imitateDestroyFeatures();
-
-		this.updateEditorElement();
-
-		super.destroy();
-
-		return this.editor.ui.destroy();
-	}
-
-	/**
-	 * Creates editor sticky toolbar and fills it with children using the configuration.
-	 *
-	 * @protected
-	 */
-	_createToolbar() {
-		const editor = this.editor;
-
-		// Note: StickyToolbar and StickyToolbarView share the same model. It may change in the future.
-		const toolbarModel = new Model();
-		const toolbarView = new StickyToolbarView( toolbarModel, editor.locale );
-		const toolbar = new StickyToolbar( toolbarModel, toolbarView, editor );
-
-		toolbar.addButtons( editor.config.toolbar );
-
-		this.editor.ui.add( 'top', toolbar );
-	}
-}

+ 110 - 0
packages/ckeditor5-editor-classic/src/classiceditorui.js

@@ -0,0 +1,110 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import BoxedEditorUI from '../ui/editorui/boxed/boxededitorui.js';
+
+import EditableUI from '../ui/editableui/editableui.js';
+import InlineEditableUIView from '../ui/editableui/inline/inlineeditableuiview.js';
+
+import Model from '../ui/model.js';
+import Toolbar from '../ui/bindings/toolbar.js';
+import StickyToolbarView from '../ui/stickytoolbar/stickytoolbarview.js';
+
+/**
+ * Classic editor UI. Uses inline editable and sticky toolbar, all
+ * enclosed in a boxed UI.
+ *
+ * @memberOf editor-classic
+ * @extends ui.editorUI.boxed.BoxedEditorUI
+ */
+export default class ClassicEditorUI extends BoxedEditorUI {
+	/**
+	 * Creates an instance of the classic editor UI.
+	 *
+	 * @param {ckeditor5.editor.Editor} editor
+	 */
+	constructor( editor ) {
+		super( editor );
+
+		/**
+		 * Toolbar controller.
+		 *
+		 * @readonly
+		 * @member {ui.toolbar.Toolbar} editor-classic.ClassicEditorUI#toolbar
+		 */
+		this.toolbar = this._createToolbar();
+
+		/**
+		 * Editable UI controller.
+		 *
+		 * @readonly
+		 * @member {ui.editableUI.EditableUI} editor-classic.ClassicEditorUI#editable
+		 */
+		this.editable = this._createEditableUI();
+	}
+
+	/**
+	 * The editing host.
+	 *
+	 * @readonly
+	 * @type {HTMLElement}
+	 */
+	get editableElement() {
+		return this.editable.view.element;
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		if ( this.editor.config.toolbar ) {
+			this.toolbar.addButtons( this.editor.config.toolbar );
+		}
+
+		return super.init();
+	}
+
+	/**
+	 * Creates editor sticky toolbar.
+	 *
+	 * @protected
+	 * @returns {ui.toolbar.Toolbar}
+	 */
+	_createToolbar() {
+		const editor = this.editor;
+
+		const toolbarModel = new Model();
+		const toolbarView = new StickyToolbarView( toolbarModel, editor.locale );
+		const toolbar = new Toolbar( toolbarModel, toolbarView, editor );
+
+		toolbarModel.bind( 'isActive' ).to( editor.editing.view.getRoot(), 'isFocused' );
+
+		this.add( 'top', toolbar );
+
+		return toolbar;
+	}
+
+	/**
+	 * Creates editor main editable.
+	 *
+	 * @protected
+	 * @returns {ui.editableUI.EditableUI}
+	 */
+	_createEditableUI() {
+		const editor = this.editor;
+
+		const editable = editor.editing.view.getRoot();
+		const editableUI = new EditableUI( editor, editable );
+		const editableUIView = new InlineEditableUIView( editableUI.viewModel, editor.locale );
+
+		editableUI.view = editableUIView;
+
+		this.add( 'main', editableUI );
+
+		return editableUI;
+	}
+}

+ 0 - 112
packages/ckeditor5-editor-classic/src/utils/imitatefeatures.js

@@ -1,112 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import Model from '../../ui/model.js';
-import Button from '../../ui/button/button.js';
-import ButtonView from '../../ui/button/buttonview.js';
-
-import Collection from '/ckeditor5/utils/collection.js';
-
-import ListDropdown from '/ckeditor5/ui/dropdown/list/listdropdown.js';
-import ListDropdownView from '/ckeditor5/ui/dropdown/list/listdropdownview.js';
-
-/**
- * Immitates that some features were loaded and did their job.
- *
- * @param {ckeditor5.Editor} editor
- */
-export function imitateFeatures( editor ) {
-	const t = editor.t;
-
-	const boldModel = new Model( {
-		isEnabled: true,
-		isOn: false,
-		label: t( 'Bold' ),
-		icon: 'bold',
-		iconAlign: 'LEFT'
-	} );
-
-	// Note – most of the contents of this file is ignored, as it's a temporary file that will
-	// be replaced with real features.
-
-	/* istanbul ignore next */
-	boldModel.on( 'execute', () => {
-		/* global console */
-		console.log( 'bold executed' );
-
-		boldModel.isOn = !boldModel.isOn;
-	} );
-
-	editor.ui.featureComponents.add( 'bold', Button, ButtonView, boldModel );
-
-	// -------------------------------------------------------------------------------------------
-
-	/* istanbul ignore next */
-	const italicModel = new Model( {
-		isEnabled: true,
-		isOn: false,
-		label: t( 'Italic' ),
-		icon: 'italic',
-		iconAlign: 'LEFT'
-	} );
-
-	/* istanbul ignore next */
-	italicModel.on( 'execute', () => {
-		/* global console */
-		console.log( 'italic executed' );
-
-		italicModel.isOn = !italicModel.isOn;
-	} );
-
-	editor.ui.featureComponents.add( 'italic', Button, ButtonView, italicModel );
-
-	window.boldModel = boldModel;
-	window.italicModel = italicModel;
-
-	// -------------------------------------------------------------------------------------------
-
-	const fontCollection = new Collection( { idProperty: 'label' } );
-
-	/* istanbul ignore next */
-	[ 'Arial', 'Times New Roman', 'Comic Sans MS', 'Georgia', 'Trebuchet MS', 'Verdana' ]
-		.sort()
-		.forEach( font => {
-			fontCollection.add( new Model( { label: font, style: `font-family: "${ font }"` } ) );
-		} );
-
-	/* istanbul ignore next */
-	const fontListModel = new Model( {
-		items: fontCollection
-	} );
-
-	/* istanbul ignore next */
-	fontListModel.on( 'execute', ( evtInfo, itemModel ) => {
-		/* global console */
-		console.log( 'Font list item executed', itemModel );
-	} );
-
-	/* istanbul ignore next */
-	const fontModel = new Model( {
-		label: t( 'Font' ),
-		isEnabled: true,
-		isOn: false,
-		content: fontListModel
-	} );
-
-	editor.ui.featureComponents.add( 'font', ListDropdown, ListDropdownView, fontModel );
-
-	window.fontCollection = fontCollection;
-	window.fontModel = fontModel;
-	window.Model = Model;
-}
-
-export function imitateDestroyFeatures() {
-	delete window.boldModel;
-	delete window.italicModel;
-	delete window.fontCollection;
-	delete window.Model;
-}

+ 113 - 0
packages/ckeditor5-editor-classic/tests/classic.js

@@ -0,0 +1,113 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* bender-tags: editor, browser-only */
+
+'use strict';
+
+import ClassicEditorUI from '/ckeditor5/creator-classic/classiceditorui.js';
+import BoxedEditorUIView from '/ckeditor5/ui/editorui/boxed/boxededitoruiview.js';
+
+import HtmlDataProcessor from '/ckeditor5/engine/dataprocessor/htmldataprocessor.js';
+
+import ClassicEditor from '/ckeditor5/creator-classic/classic.js';
+
+import testUtils from '/tests/ckeditor5/_utils/utils.js';
+import count from '/ckeditor5/utils/count.js';
+
+testUtils.createSinonSandbox();
+
+describe( 'ClassicEditor', () => {
+	let editor, editorElement;
+
+	beforeEach( () => {
+		editorElement = document.createElement( 'div' );
+		editorElement.innerHTML = '<p><strong>foo</strong> bar</p>';
+
+		document.body.appendChild( editorElement );
+	} );
+
+	afterEach( () => {
+		editorElement.remove();
+	} );
+
+	describe( 'constructor', () => {
+		beforeEach( () => {
+			editor = new ClassicEditor( editorElement );
+		} );
+
+		it( 'creates a single div editable root in the view', () => {
+			expect( editor.editing.view.getRoot() ).to.have.property( 'name', 'div' );
+		} );
+
+		it( 'creates a single document root', () => {
+			expect( count( editor.document.rootNames ) ).to.equal( 1 );
+			expect( editor.document.getRoot() ).to.have.property( 'name', '$root' );
+		} );
+
+		it( 'creates the UI using BoxedEditorUI classes', () => {
+			expect( editor.ui ).to.be.instanceof( ClassicEditorUI );
+			expect( editor.ui.view ).to.be.instanceof( BoxedEditorUIView );
+		} );
+
+		it( 'uses HTMLDataProcessor', () => {
+			expect( editor.data.processor ).to.be.instanceof( HtmlDataProcessor );
+		} );
+	} );
+
+	describe( 'create', () => {
+		beforeEach( function() {
+			return ClassicEditor.create( editorElement, {
+					features: [ 'paragraph', 'basic-styles/bold' ]
+				} )
+				.then( newEditor => {
+					editor = newEditor;
+				} );
+		} );
+
+		it( 'creates an instance which inherits from the ClassicEditor', () => {
+			expect( editor ).to.be.instanceof( ClassicEditor );
+		} );
+
+		it( 'inserts editor UI next to editor element', () => {
+			expect( editor.ui.view.element.previousSibling ).to.equal( editorElement );
+		} );
+
+		it( 'attaches editable UI as view\'s DOM root', () => {
+			expect( editor.editing.view.getDomRoot() ).to.equal( editor.ui.editable.view.element );
+		} );
+
+		it( 'loads data from the editor element', () => {
+			expect( editor.getData() ).to.equal( '<p><strong>foo</strong> bar</p>' );
+		} );
+	} );
+
+	describe( 'destroy', () => {
+		beforeEach( function() {
+			return ClassicEditor.create( editorElement, { features: [ 'paragraph' ] } )
+				.then( newEditor => {
+					editor = newEditor;
+				} );
+		} );
+
+		it( 'sets the data back to the editor element', () => {
+			editor.setData( '<p>foo</p>' );
+
+			return editor.destroy()
+				.then( () => {
+					expect( editorElement.innerHTML ).to.equal( '<p>foo</p>' );
+				} );
+		} );
+
+		it( 'restores the editor element', () => {
+			expect( editor.element.style.display ).to.equal( 'none' );
+
+			return editor.destroy()
+				.then( () => {
+					expect( editor.element.style.display ).to.equal( '' );
+				} );
+		} );
+	} );
+} );

+ 0 - 3
packages/ckeditor5-editor-classic/tests/classiccreator.html

@@ -1,3 +0,0 @@
-<head>
-	<link rel="stylesheet" href="%APPS_DIR%ckeditor/build/amd/theme/ckeditor.css">
-</head>

+ 0 - 185
packages/ckeditor5-editor-classic/tests/classiccreator.js

@@ -1,185 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* bender-tags: creator */
-
-'use strict';
-
-import Editor from '/ckeditor5/editor.js';
-
-import BoxedEditorUI from '/ckeditor5/ui/editorui/boxed/boxededitorui.js';
-import BoxedEditorUIView from '/ckeditor5/ui/editorui/boxed/boxededitoruiview.js';
-
-import EditableUI from '/ckeditor5/ui/editableui/editableui.js';
-import InlineEditableUIView from '/ckeditor5/ui/editableui/inline/inlineeditableuiview.js';
-
-import StickyToolbar from '/ckeditor5/ui/bindings/stickytoolbar.js';
-import StickyToolbarView from '/ckeditor5/ui/stickytoolbar/stickytoolbarview.js';
-
-import StandardCreator from '/ckeditor5/creator/standardcreator.js';
-import ClassicCreator from '/ckeditor5/creator-classic/classiccreator.js';
-import HtmlDataProcessor from '/ckeditor5/engine/dataprocessor/htmldataprocessor.js';
-
-import testUtils from '/tests/ckeditor5/_utils/utils.js';
-
-testUtils.createSinonSandbox();
-
-describe( 'ClassicCreator', () => {
-	let creator, editor, fooElement, barElement;
-
-	beforeEach( function() {
-		fooElement = document.createElement( 'div' );
-		fooElement.setAttribute( 'class', 'first' );
-		fooElement.setAttribute( 'data-test', this.currentTest.title );
-
-		document.body.appendChild( fooElement );
-
-		barElement = document.createElement( 'div' );
-		barElement.setAttribute( 'class', 'second' );
-		barElement.setAttribute( 'data-test', this.currentTest.title );
-
-		document.body.appendChild( barElement );
-
-		editor = new Editor(
-			{
-				foo: fooElement,
-				bar: barElement
-			},
-			{
-				toolbar: [ 'bold', 'italic' ]
-			}
-		);
-
-		creator = new ClassicCreator( editor, new HtmlDataProcessor() );
-	} );
-
-	describe( 'constructor', () => {
-		it( 'inherits from the StandardCreator', () => {
-			expect( creator ).to.be.instanceof( StandardCreator );
-		} );
-
-		it( 'creates a single instance of Editable ', () => {
-			expect( editor.editables ).to.have.length( 1 );
-			expect( editor.editables.get( 0 ).name ).to.equal( 'foo' );
-		} );
-
-		it( 'creates the UI using BoxedEditorUI classes', () => {
-			expect( editor.ui ).to.be.instanceof( BoxedEditorUI );
-			expect( editor.ui.view ).to.be.instanceof( BoxedEditorUIView );
-		} );
-
-		it( 'creates a single document root', () => {
-			expect( editor.document.rootNames ).to.have.members( [ 'foo' ] );
-		} );
-	} );
-
-	describe( 'create', () => {
-		it( 'returns a promise', () => {
-			expect( creator.create() ).to.be.instanceof( Promise );
-		} );
-
-		it( 'calls _replaceElement', () => {
-			const spy = testUtils.sinon.spy( creator, '_replaceElement' );
-
-			return creator.create().then( () => {
-				expect( spy.calledOnce ).to.be.true;
-			} );
-		} );
-
-		it( 'calls _createToolbar', () => {
-			const spy = testUtils.sinon.spy( creator, '_createToolbar' );
-
-			return creator.create().then( () => {
-				expect( spy.calledOnce ).to.be.true;
-			} );
-		} );
-
-		it( 'creates the editable using EditableUI Controller in main region', () => {
-			return creator.create().then( () => {
-				expect( editor.ui.collections.get( 'main' ) ).to.have.length( 1 );
-				expect( editor.ui.collections.get( 'main' ).get( 0 ) ).to.be.instanceof( EditableUI );
-			} );
-		} );
-
-		it( 'creates the editable using InlineEditableUIView in main region', () => {
-			return creator.create().then( () => {
-				expect( editor.ui.collections.get( 'main' ).get( 0 ).view ).to.be.instanceof( InlineEditableUIView );
-			} );
-		} );
-
-		it( 'binds the editable to InlineEditableUIView', () => {
-			return creator.create().then( () => {
-				const editableUIView = editor.ui.collections.get( 'main' ).get( 0 ).view;
-
-				expect( editor.editables.get( 0 ).domElement ).to.equal( editableUIView.element );
-			} );
-		} );
-
-		it( 'initializes the editor.ui', () => {
-			const spy = testUtils.sinon.spy( editor.ui, 'init' );
-
-			return creator.create().then( () => {
-				expect( spy.calledOnce ).to.be.true;
-			} );
-		} );
-
-		it( 'calls loadDataFromEditorElement', () => {
-			const spy = testUtils.sinon.spy( creator, 'loadDataFromEditorElement' );
-
-			return creator.create().then( () => {
-				expect( spy.calledOnce ).to.be.true;
-			} );
-		} );
-	} );
-
-	describe( 'destroy', () => {
-		it( 'returns a promise', () => {
-			return creator.create().then( () => {
-				expect( creator.destroy() ).to.be.instanceof( Promise );
-			} );
-		} );
-
-		it( 'destroys parent class', () => {
-			const spy = testUtils.sinon.spy( StandardCreator.prototype, 'destroy' );
-
-			return creator.create().then( () => {
-				return creator.destroy().then( () => {
-					expect( spy.calledOnce ).to.be.true;
-				} );
-			} );
-		} );
-
-		it( 'calls updateEditorElement', () => {
-			const spy = testUtils.sinon.spy( creator, 'updateEditorElement' );
-
-			return creator.create().then( () => {
-				return creator.destroy().then( () => {
-					expect( spy.calledOnce ).to.be.true;
-				} );
-			} );
-		} );
-
-		it( 'destroys the UI', () => {
-			return creator.create().then( () => {
-				return creator.destroy().then( () => {
-					expect( editor.ui.collections ).to.be.null;
-				} );
-			} );
-		} );
-	} );
-
-	describe( '_createToolbar', () => {
-		it( 'creates toolbar using StickyToolbar and StickyToolbarView', () => {
-			return creator.create().then( () => {
-				expect( editor.ui.collections.get( 'top' ) ).to.have.length( 1 );
-
-				const toolbar = editor.ui.collections.get( 'top' ).get( 0 );
-
-				expect( toolbar ).to.be.instanceof( StickyToolbar );
-				expect( toolbar.view ).to.be.instanceof( StickyToolbarView );
-			} );
-		} );
-	} );
-} );

+ 77 - 0
packages/ckeditor5-editor-classic/tests/classiceditorui.js

@@ -0,0 +1,77 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* bender-tags: editor, browser-only */
+
+'use strict';
+
+import ClassicEditorUI from '/ckeditor5/creator-classic/classiceditorui.js';
+import BoxedEditorUIView from '/ckeditor5/ui/editorui/boxed/boxededitoruiview.js';
+
+import Toolbar from '/ckeditor5/ui/toolbar/toolbar.js';
+import StickyToolbarView from '/ckeditor5/ui/stickytoolbar/stickytoolbarview.js';
+
+import EditableUI from '/ckeditor5/ui/editableui/editableui.js';
+import InlineEditableUIView from '/ckeditor5/ui/editableui/inline/inlineeditableuiview.js';
+
+import ClassicTestEditor from '/tests/ckeditor5/_utils/classictesteditor.js';
+
+describe( 'ClassicEditorUI', () => {
+	let editorElement, editor, editorUI;
+
+	beforeEach( () => {
+		editorElement = document.createElement( 'div' );
+		document.body.appendChild( editorElement );
+
+		editor = new ClassicTestEditor( editorElement );
+		editorUI = new ClassicEditorUI( editor );
+		editorUI.view = new BoxedEditorUIView( editorUI.viewModel, editor.locale );
+	} );
+
+	describe( 'constructor', () => {
+		it( 'creates toolbar', () => {
+			expect( editorUI.toolbar ).to.be.instanceof( Toolbar );
+			expect( editorUI.toolbar.view ).to.be.instanceof( StickyToolbarView );
+		} );
+
+		it( 'creates editable', () => {
+			expect( editorUI.editable ).to.be.instanceof( EditableUI );
+			expect( editorUI.editable.view ).to.be.instanceof( InlineEditableUIView );
+		} );
+	} );
+
+	describe( 'editableElement', () => {
+		it( 'returns editable\'s view element', () => {
+			document.body.appendChild( editorUI.view.element );
+
+			return editorUI.init()
+				.then( () => {
+					expect( editorUI.editableElement.getAttribute( 'contentEditable' ) ).to.equal( 'true' );
+				} );
+		} );
+	} );
+
+	describe( 'init', () => {
+		it( 'adds buttons', () => {
+			editor.config.set( 'toolbar', [ 'foo', 'bar' ] );
+
+			document.body.appendChild( editorUI.view.element );
+
+			const spy = sinon.stub( editorUI.toolbar, 'addButtons' );
+
+			return editorUI.init()
+				.then( () => {
+					expect( spy.calledOnce ).to.be.true;
+					expect( spy.args[ 0 ][ 0 ] ).to.deep.equal( [ 'foo', 'bar' ] );
+				} );
+		} );
+
+		it( 'returns a promise', () => {
+			document.body.appendChild( editorUI.view.element );
+
+			expect( editorUI.init() ).to.be.instanceof( Promise );
+		} );
+	} );
+} );

packages/ckeditor5-editor-classic/tests/manual/classiccreator.html → packages/ckeditor5-editor-classic/tests/manual/classic.html


+ 10 - 8
packages/ckeditor5-editor-classic/tests/manual/classiccreator.js

@@ -7,26 +7,28 @@
 
 'use strict';
 
-import CKEDITOR from '/ckeditor.js';
-import ClassicCreator from '/ckeditor5/creator-classic/classiccreator.js';
+import ClassicEditor from '/ckeditor5/creator-classic/classic.js';
 import testUtils from '/tests/utils/_utils/utils.js';
 
 let editor, editable, observer;
 
 function initEditor() {
-	CKEDITOR.create( '#editor', {
-		creator: ClassicCreator,
-		toolbar: [ 'bold', 'italic', 'font' ]
+	ClassicEditor.create( document.querySelector( '#editor' ), {
+		features: [ 'delete', 'enter', 'typing', 'paragraph', 'undo', 'basic-styles/bold', 'basic-styles/italic' ],
+		toolbar: [ 'bold', 'italic', 'undo', 'redo' ]
 	} )
-	.then( ( newEditor ) => {
+	.then( newEditor => {
 		console.log( 'Editor was initialized', newEditor );
 		console.log( 'You can now play with it using global `editor` and `editable` variables.' );
 
 		window.editor = editor = newEditor;
-		window.editable = editable = editor.editables.get( 0 );
+		window.editable = editable = editor.editing.view.getRoot();
 
 		observer = testUtils.createObserver();
-		observer.observe( 'Editable', editable );
+		observer.observe( 'Editable', editable, [ 'isFocused' ] );
+	} )
+	.catch( err => {
+		console.error( err.stack );
 	} );
 }
 

+ 4 - 6
packages/ckeditor5-editor-classic/tests/manual/classiccreator.md

@@ -4,7 +4,7 @@
 2. Expected:
   * Framed editor should be created.
   * Original element should disappear.
-  * There should be a toolbar with "Bold" and "Italic" buttons.
+  * There should be a toolbar with "Bold", "Italic", "Undo" and "Redo" buttons.
 3. Click "Destroy editor".
 4. Expected:
   * Editor should be destroyed.
@@ -15,9 +15,7 @@
 ## Notes:
 
 * You can play with:
-  * `editable.isEditable`,
-  * `boldModel.isEnabled`, `italicModel.isEnabled` and `fontModel.isEnabled`.
-  * `fontModel.isOn`.
-* Changes to `editable.isFocused/isEditable` should be logged to the console.
-* Clicks on the buttons should be logged to the console.
+  * `editable.isReadOnly`,
+* Changes to `editable.isFocused` should be logged to the console.
+* Features should work.