Browse Source

Implemented body region and a base EditorUIView.

Piotrek Koszuliński 10 years ago
parent
commit
d9c7fbf41b

+ 10 - 6
packages/ckeditor5-engine/src/editorui.js → packages/ckeditor5-engine/src/editorui/editorui.js

@@ -5,15 +5,17 @@
 
 'use strict';
 
-import Controller from './ui/controller.js';
-import utils from './utils.js';
-import ObservableMixin from './observablemixin.js';
-import ComponentFactory from './ui/componentfactory.js';
+import Controller from '../ui/controller.js';
+import ControllerCollection from '../ui/controllercollection.js';
+import ComponentFactory from '../ui/componentfactory.js';
+import ObservableMixin from '../observablemixin.js';
+import utils from '../utils.js';
 
 /**
  * Base class for the editor main view controllers.
  *
  * @memberOf core
+ * @class core.editorui.EditorUI
  * @extends core.ui.Controller
  * @mixes core.ObservableMixin
  */
@@ -24,15 +26,17 @@ export default class EditorUI extends Controller {
 
 		/**
 		 * @readonly
-		 * @member {core.Editor} core.EditorUI.editor
+		 * @member {core.Editor} core.EditorUI#editor
 		 */
 		this.editor = editor;
 
 		/**
 		 * @readonly
-		 * @type {core.ui.ComponentFactory}
+		 * @member {core.ui.ComponentFactory} core.EditorUI#featureComponents
 		 */
 		this.featureComponents = new ComponentFactory( editor );
+
+		this.collections.add( new ControllerCollection( 'body' ) );
 	}
 }
 

+ 56 - 0
packages/ckeditor5-engine/src/editorui/editoruiview.js

@@ -0,0 +1,56 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import View from '../ui/view.js';
+
+/**
+ * Base class for the editor main views.
+ *
+ * @class core.editorui.EditorUIView
+ * @extends core.ui.View
+ */
+
+export default class EditorUIView extends View {
+	constructor( model ) {
+		super( model );
+
+		this._createBodyRegion();
+
+		/**
+		 * The element holding elements of the 'body' region.
+		 *
+		 * @private
+		 * @type HTMLElement
+		 * @property _bodyRegionContainer
+		 */
+	}
+
+	destroy() {
+		this._bodyRegionContainer.remove();
+		this._bodyRegionContainer = null;
+	}
+
+	/**
+	 * Creates and appends to `<body>` the 'body' region container.
+	 *
+	 * @private
+	 */
+	_createBodyRegion() {
+		const bodyElement = document.createElement( 'div' );
+		document.body.appendChild( bodyElement );
+
+		this.applyTemplateToElement( bodyElement, {
+			attributes: {
+				class: 'ck-body'
+			}
+		} );
+
+		this._bodyRegionContainer = bodyElement;
+
+		this.register( 'body', () => bodyElement );
+	}
+}

+ 1 - 1
packages/ckeditor5-engine/src/ui/toolbar/toolbarview.js

@@ -27,7 +27,7 @@ export default class ToolbarView extends View {
 		this.template = {
 			tag: 'div',
 			attributes: {
-				class: 'ck-toolbar'
+				class: [ 'ck-toolbar' ]
 			}
 		};
 

+ 1 - 1
packages/ckeditor5-engine/tests/_utils/ui/boxededitorui/boxededitorui.js

@@ -5,7 +5,7 @@
 
 'use strict';
 
-import EditorUI from '/ckeditor5/core/editorui.js';
+import EditorUI from '/ckeditor5/core/editorui/editorui.js';
 import ControllerCollection from '/ckeditor5/core/ui/controllercollection.js';
 
 export default class BoxedEditorUI extends EditorUI {

+ 4 - 2
packages/ckeditor5-engine/tests/_utils/ui/boxededitorui/boxededitoruiview.js

@@ -5,17 +5,19 @@
 
 'use strict';
 
-import View from '/ckeditor5/core/ui/view.js';
+import EditorUIView from '/ckeditor5/core/editorui/editoruiview.js';
 
-export default class BoxedEditorUIView extends View {
+export default class BoxedEditorUIView extends EditorUIView {
 	constructor( model ) {
 		super( model );
 
 		this.template = {
 			tag: 'div',
+
 			attributes: {
 				class: 'ck-box'
 			},
+
 			children: [
 				{
 					tag: 'div',

+ 3 - 2
packages/ckeditor5-engine/tests/_utils/ui/boxlesseditorui/boxlesseditorui.js

@@ -5,7 +5,7 @@
 
 'use strict';
 
-import EditorUI from '/ckeditor5/core/editorui.js';
+import EditorUI from '/ckeditor5/core/editorui/editorui.js';
 import ControllerCollection from '/ckeditor5/core/ui/controllercollection.js';
 
 export default class BoxlessEditorUI extends EditorUI {
@@ -16,7 +16,8 @@ export default class BoxlessEditorUI extends EditorUI {
 
 		/**
 		 * @private
-		 * @property {View} _view
+		 * @type {core.ui.View}
+		 * @property _view
 		 */
 	}
 

+ 23 - 0
packages/ckeditor5-engine/tests/_utils/ui/floatingtoolbar/floatingtoolbar.js

@@ -0,0 +1,23 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import Toolbar from '/ckeditor5/ui/toolbar/toolbar.js';
+
+/**
+ * The editor toolbar controller class.
+ *
+ * @class ui-default.toolbar.Toolbar
+ * @extends core.ui.toolbar.Toolbar
+ */
+
+export default class FloatingToolbar extends Toolbar {
+	constructor( editor, model, view ) {
+		super( editor, model, view );
+
+		model.bind( 'isVisible' ).to( editor.editable, 'isFocused' );
+	}
+}

+ 27 - 0
packages/ckeditor5-engine/tests/_utils/ui/floatingtoolbar/floatingtoolbarview.js

@@ -0,0 +1,27 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import ToolbarView from '/ckeditor5/ui/toolbar/toolbarview.js';
+
+export default class FloatingToolbarView extends ToolbarView {
+	constructor( model ) {
+		super( model );
+
+		const bind = this.attributeBinder;
+
+		this.template.attributes.class.push(
+			bind.to( 'isVisible', value => value ? 'ck-visible' : 'ck-hidden' )
+		);
+
+		// This has a high chance to break if someone defines "on" in the parent template.
+		// See https://github.com/ckeditor/ckeditor5-core/issues/219
+		this.template.on = {
+			// Added just for fun, but needed to keep the focus in the editable.
+			mousedown: ( evt ) => evt.preventDefault()
+		};
+	}
+}

+ 18 - 15
packages/ckeditor5-engine/tests/creator/manual/_assets/styles.css

@@ -1,25 +1,28 @@
-.ck-box {
-	background: rgb( 200, 200, 200 );
-	padding: 1px 0;
+.ck-body {
+	margin: 10px 0;
+	border: solid 3px red;
 }
-
-.ck-box-region {
-	background: rgb( 240, 240, 240 );
-	padding: 5px;
-	margin: 1px;
+.ck-body::before {
+	content: '[[ ck-body region ]]';
 }
-.ck-box-region:first-child {
-	margin-top: 0;
-}
-.ck-box-region:last-child {
-	margin-bottom: 0;
+
+.ck-box {
+	margin: 10px 0;
 }
 
 .ck-main {
-	background: #FFF;
+	border: solid 1px rgb( 200, 200, 200 );
+	padding: 5px
+}
+
+.ck-toolbar {
+	border: solid 1px rgb( 200, 200, 200 );
+	background: rgb( 240, 240, 240 );
+	padding: 5px;
 }
 
-.ck-top {
+.ck-toolbar.ck-hidden {
+	opacity: 0.3;
 }
 
 .ck-button {

+ 2 - 43
packages/ckeditor5-engine/tests/creator/manual/_utils/creator/classiccreator.js

@@ -13,8 +13,7 @@ import FramedEditableView from '/tests/core/_utils/ui/editable/framed/framededit
 import Model from '/ckeditor5/core/ui/model.js';
 import Toolbar from '/ckeditor5/ui/toolbar/toolbar.js';
 import ToolbarView from '/ckeditor5/ui/toolbar/toolbarview.js';
-import Button from '/ckeditor5/ui/button/button.js';
-import ButtonView from '/ckeditor5/ui/button/buttonview.js';
+import imitateFeatures from '../imitatefeatures.js';
 
 export default class ClassicCreator extends Creator {
 	constructor( editor ) {
@@ -24,7 +23,7 @@ export default class ClassicCreator extends Creator {
 	}
 
 	create() {
-		this._imitateFeatures();
+		imitateFeatures( this.editor );
 
 		this._replaceElement();
 		this._setupEditable();
@@ -72,44 +71,4 @@ export default class ClassicCreator extends Creator {
 
 		return editorUI;
 	}
-
-	/**
-	 * Immitates that some features were loaded and did their job.
-	 */
-	_imitateFeatures() {
-		const editor = this.editor;
-
-		const boldModel = new Model( {
-			isEnabled: true,
-			isOn: false,
-			label: 'bold'
-		} );
-
-		boldModel.on( 'executed', () => {
-			/* global console */
-			console.log( 'bold executed' );
-
-			boldModel.isOn = !boldModel.isOn;
-		} );
-
-		editor.ui.featureComponents.add( 'bold', Button, ButtonView, boldModel );
-
-		const italicModel = new Model( {
-			isEnabled: true,
-			isOn: false,
-			label: 'italic'
-		} );
-
-		italicModel.on( 'executed', () => {
-			/* global console */
-			console.log( 'italic executed' );
-
-			italicModel.isOn = !italicModel.isOn;
-		} );
-
-		editor.ui.featureComponents.add( 'italic', Button, ButtonView, italicModel );
-
-		window.boldModel = boldModel;
-		window.italicModel = italicModel;
-	}
 }

+ 23 - 2
packages/ckeditor5-engine/tests/creator/manual/_utils/creator/inlinecreator.js

@@ -6,10 +6,14 @@
 'use strict';
 
 import Creator from '/ckeditor5/core/creator.js';
-import View from '/ckeditor5/core/ui/view.js';
+import EditorUIView from '/ckeditor5/core/editorui/editoruiview.js';
 import BoxlessEditorUI from '/tests/core/_utils/ui/boxlesseditorui/boxlesseditorui.js';
 import InlineEditable from '/tests/core/_utils/ui/editable/inline/inlineeditable.js';
 import InlineEditableView from '/tests/core/_utils/ui/editable/inline/inlineeditableview.js';
+import Model from '/ckeditor5/core/ui/model.js';
+import FloatingToolbar from '/tests/core/_utils/ui/floatingtoolbar/floatingtoolbar.js';
+import FloatingToolbarView from '/tests/core/_utils/ui/floatingtoolbar/floatingtoolbarview.js';
+import imitateFeatures from '../imitatefeatures.js';
 
 export default class InlineCreator extends Creator {
 	constructor( editor ) {
@@ -19,7 +23,10 @@ export default class InlineCreator extends Creator {
 	}
 
 	create() {
+		imitateFeatures( this.editor );
+
 		this._setupEditable();
+		this._setupToolbar();
 
 		return super.create()
 			.then( () => this.loadDataFromEditorElement() );
@@ -37,6 +44,20 @@ export default class InlineCreator extends Creator {
 		this.editor.ui.add( 'editable', this.editor.editable );
 	}
 
+	_setupToolbar() {
+		const toolbar1Model = new Model();
+		const toolbar2Model = new Model();
+
+		const toolbar1 = new FloatingToolbar( this.editor, toolbar1Model, new FloatingToolbarView( toolbar1Model ) );
+		const toolbar2 = new FloatingToolbar( this.editor, toolbar2Model, new FloatingToolbarView( toolbar2Model ) );
+
+		toolbar1.addButtons( this.editor.config.toolbar );
+		toolbar2.addButtons( this.editor.config.toolbar.reverse() );
+
+		this.editor.ui.collections.get( 'body' ).add( toolbar1 );
+		this.editor.ui.collections.get( 'body' ).add( toolbar2 );
+	}
+
 	_createEditable() {
 		const editable = new InlineEditable( this.editor );
 		const editableView = new InlineEditableView( editable.viewModel, this.editor.element );
@@ -49,7 +70,7 @@ export default class InlineCreator extends Creator {
 	_createEditorUI() {
 		const editorUI = new BoxlessEditorUI( this.editor );
 
-		editorUI.view = new View( editorUI.viewModel );
+		editorUI.view = new EditorUIView( editorUI.viewModel );
 
 		return editorUI;
 	}

+ 50 - 0
packages/ckeditor5-engine/tests/creator/manual/_utils/imitatefeatures.js

@@ -0,0 +1,50 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import Model from '/ckeditor5/core/ui/model.js';
+import Button from '/ckeditor5/ui/button/button.js';
+import ButtonView from '/ckeditor5/ui/button/buttonview.js';
+
+/**
+ * Immitates that some features were loaded and did their job.
+ *
+ * @param {core.Editor} editor
+ */
+export default function imitateFeatures( editor ) {
+	const boldModel = new Model( {
+		isEnabled: true,
+		isOn: false,
+		label: 'bold'
+	} );
+
+	boldModel.on( 'executed', () => {
+		/* global console */
+		console.log( 'bold executed' );
+
+		boldModel.isOn = !boldModel.isOn;
+	} );
+
+	editor.ui.featureComponents.add( 'bold', Button, ButtonView, boldModel );
+
+	const italicModel = new Model( {
+		isEnabled: true,
+		isOn: false,
+		label: 'italic'
+	} );
+
+	italicModel.on( 'executed', () => {
+		/* global console */
+		console.log( 'italic executed' );
+
+		italicModel.isOn = !italicModel.isOn;
+	} );
+
+	editor.ui.featureComponents.add( 'italic', Button, ButtonView, italicModel );
+
+	window.boldModel = boldModel;
+	window.italicModel = italicModel;
+}

+ 4 - 0
packages/ckeditor5-engine/tests/creator/manual/creator-classic.md

@@ -5,15 +5,19 @@
   * Framed editor should be created.
   * It should be rectangular (400x400).
   * Original element should disappear.
+  * There should be a toolbar with "bold" and "italic" buttons.
 3. Click "Destroy editor".
 4. Expected:
   * Editor should be destroyed.
   * Original element should be visible.
   * The element should contain its data (updated).
+  * The 'ck-body region' should be removed.
 
 ## Notes:
 
 * You can play with:
   * `editor.editable.isEditable`,
   * `editor.ui.width/height`.
+  * `boldModel.isEnabled` and `italicModel.isEnabled`.
 * Changes to `editable.isFocused/isEditable` should be logged to the console.
+* Clicks on the buttons should be logged to the console.

+ 4 - 0
packages/ckeditor5-engine/tests/creator/manual/creator-inline.html

@@ -1,3 +1,7 @@
+<head>
+	<link rel="stylesheet" href="%TEST_DIR%_assets/styles.css">
+</head>
+
 <div id="editor">
 	<h1>Hello world!</h1>
 	<p>This is an editor instance.</p>

+ 2 - 1
packages/ckeditor5-engine/tests/creator/manual/creator-inline.js

@@ -15,7 +15,8 @@ let editor, observer;
 
 function initEditor() {
 	CKEDITOR.create( '#editor', {
-		creator: InlineCreator
+		creator: InlineCreator,
+		toolbar: [ 'bold', 'italic' ]
 	} )
 	.then( ( newEditor ) => {
 		console.log( 'Editor was initialized', newEditor );

+ 8 - 1
packages/ckeditor5-engine/tests/creator/manual/creator-inline.md

@@ -3,12 +3,19 @@
 1. Click "Init editor".
 2. Expected:
   * Inline editor should be created.
+  * There should be **two** toolbars:
+    * one with "bold" and "italic" buttons,
+    * second with "italic" and "bold" buttons.
 3. Click "Destroy editor".
 4. Expected:
   * Editor should be destroyed (the element should not be editable).
   * The element should contain its data (updated).
+  * The 'ck-body region' should be removed.
 
 ## Notes:
 
-* You can play with `editor.editable.isEditable`.
+* You can play with:
+  * `editor.editable.isEditable`.
+  * `boldModel.isEnabled` and `italicModel.isEnabled`.
 * Changes to `editable.isFocused/isEditable` should be logged to the console.
+* Buttons' states should be synchronised between toolbars (they share models).

+ 1 - 1
packages/ckeditor5-engine/tests/editorui.js → packages/ckeditor5-engine/tests/editorui/editorui.js

@@ -6,7 +6,7 @@
 'use strict';
 
 import Editor from '/ckeditor5/core/editor.js';
-import EditorUI from '/ckeditor5/core/editorui.js';
+import EditorUI from '/ckeditor5/core/editorui/editorui.js';
 
 describe( 'EditorUI', () => {
 	let editor, editorUI;