Bladeren bron

Merge tag 'v1.0.0-beta.1' into stable

Release: v1.0.0-beta.1.
Piotrek Koszuliński 7 jaren geleden
bovenliggende
commit
32d8aa2aee

+ 1 - 1
packages/ckeditor5-enter/.eslintrc.js

@@ -1,5 +1,5 @@
 /**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md.
  */
 

+ 15 - 11
packages/ckeditor5-enter/.travis.yml

@@ -1,24 +1,28 @@
 sudo: required
 dist: trusty
 addons:
+  firefox: "latest"
   apt:
     sources:
-      - google-chrome
+    - google-chrome
     packages:
-      - google-chrome-stable
+    - google-chrome-stable
 language: node_js
 node_js:
-  - "6"
+- '6'
 cache:
-  - node_modules
+- node_modules
 before_install:
-  - export DISPLAY=:99.0
-  - sh -e /etc/init.d/xvfb start
+- export DISPLAY=:99.0
+- sh -e /etc/init.d/xvfb start
 install:
-  - npm install @ckeditor/ckeditor5-dev-tests
-  - ckeditor5-dev-tests-install-dependencies
+- npm install @ckeditor/ckeditor5-dev-tests
+- ckeditor5-dev-tests-install-dependencies
 script:
-  - ckeditor5-dev-tests-travis
+- ckeditor5-dev-tests-travis
 after_success:
-  - codeclimate-test-reporter < coverage/lcov.info
-  - ckeditor5-dev-tests-save-revision
+- ckeditor5-dev-tests-save-revision
+env:
+  global:
+  - secure: SPDh6kK3kSU86f/lHGThairJeeOfCs7KSt6Yc2m6PLgxHoR543PCjf9yZlaHa5tR6tTH11UQ43Gux4EPfq+oE0RsBink6LYUV4mPfKkWBIEmiLPyXWwIaAmGnTpdXxRhWPYqf5eETuyxpC86DKTOi76ZBVdlb9UZ190ew0aK3mWJbtgcqUilGeqRQXoug1jHPwixZ8rRfmbzbN0tWksRIsB/LS2GTN0DISoM/VnBUF1VdfeRfQZVD+xfQ6nOnPfgxn8DGPXLm9t2JVz3XWYSNKyucfoIKYS8TIgDk0r14VZ7hk7z0/TizGuzNHNDTUjGhgkmbsFL538s8YFt0TdRCQJs4H+q3DdnjXK0CAmh6ua9toGOqFwa1T0xrFjrylAAvjeOITEw+jNtUyhh12uysIf5Z7ZF48lUBN1PvtvUjrVxSQVVvCWWj/lIZ8GiXFlvx0V66E3nvTztz7o6lcYBWk71Lj1CyPBd1u2o45upZgcpE8oI6QItQCN1y6cxZJvx6lNNIpk8KHpY5/7afJsN57rLP+OJIyrvwUS2DMlnW/SJjkIHPNxwUIzLSPSyT5bYbpmqzaHY8Nyz1udMZZGO0iAQMqYZMfZCRNmPxmf8gZGV2JSbo4fsaap8bgXjKyubRmQ+hIpLcDKySK4GXlq/AnLnSOJNkUSm6ieu61v4IWQ=
+  - secure: OL5aVyDg0PuoRbWa5cC5nuWCSQDldGhqBeBJFkNobvar8StQ0bE1r81xEsTqioQ++ykaXa1KguwNGWG87JrtkWlpe12MQqLIYeKDpDiqnopgTSwA0IyXHdwjZ85XUs1PAFUuTOUCeFhK0uWaM7ojvJ4wG3gHgsJMjDoDeApp0ZRFWuk2Si3tM4eZ4urRSGvE7g0j9QTVbUkNKjhNL54lAzqYcWsvM9ClQK1BU8qKlJ4eaxfSpRSjWvOU0Vt4JT72WEWUO4PEKBUsgobe1t4W5dB16ATB6HJFGxF1dMXuvmKWjkV1o0ZUu4TWEPxqZ2xm0RYz1SOZYZCBeJJ0Z2DL1tivS1RdDPThJlrenGX8Za+v3ZflhKdl/lBNFN4TdMclegtL8N0gmymruoiUlwZ0WrwZSE2bD5qkqAJ1m6bZxiSdl8st8r/7VrEUQbKh/Sgw6Io8kgFjK5eEHUcQVSQceXzMnn386R00qVhzJpL84VNKw9iVMF9SboXfsv6o768X38P8558iXsSFFOloPLmCP+YUy/6QvkDmdp76XnQ+2rJqWS2z5t+Q/9QMztkI8Ua0n3JFzMOysrxs2XgHTFlzcxjqdbGhlwJj1iPBMu/Ujc2es+cFjkEz0ouej6giBq+UVa0t8bbZHpK/o7e00oROBQTKYNHkyzOzXb4RMuY13kE=

+ 11 - 0
packages/ckeditor5-enter/CHANGELOG.md

@@ -1,6 +1,17 @@
 Changelog
 =========
 
+## [1.0.0-beta.1](https://github.com/ckeditor/ckeditor5-enter/compare/v1.0.0-alpha.2...v1.0.0-beta.1) (2018-03-15)
+
+### Bug fixes
+
+* `EnterObserver` will stop the `keydown` event when the `enter` event is stopped. Closes: https://github.com/ckeditor/ckeditor5/issues/753. ([b9a7a1e](https://github.com/ckeditor/ckeditor5-enter/commit/b9a7a1e))
+
+### Other changes
+
+* Aligned code to the changes in the engine. ([39e4b4c](https://github.com/ckeditor/ckeditor5-enter/commit/39e4b4c))
+
+
 ## [1.0.0-alpha.2](https://github.com/ckeditor/ckeditor5-enter/compare/v1.0.0-alpha.1...v1.0.0-alpha.2) (2017-11-14)
 
 Internal changes only (updated dependencies, documentation, etc.).

+ 1 - 1
packages/ckeditor5-enter/LICENSE.md

@@ -2,7 +2,7 @@ Software License Agreement
 ==========================
 
 **CKEditor 5 Enter Feature** – https://github.com/ckeditor/ckeditor5-enter <br>
-Copyright (c) 2003-2017, [CKSource](http://cksource.com) Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2018, [CKSource](http://cksource.com) Frederico Knabben. All rights reserved.
 
 Licensed under the terms of any of the following licenses at your choice:
 

+ 3 - 1
packages/ckeditor5-enter/README.md

@@ -4,7 +4,9 @@ CKEditor 5 Enter feature
 [![Join the chat at https://gitter.im/ckeditor/ckeditor5](https://badges.gitter.im/ckeditor/ckeditor5.svg)](https://gitter.im/ckeditor/ckeditor5?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-enter.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter)
 [![Build Status](https://travis-ci.org/ckeditor/ckeditor5-enter.svg?branch=master)](https://travis-ci.org/ckeditor/ckeditor5-enter)
-[![Test Coverage](https://codeclimate.com/github/ckeditor/ckeditor5-enter/badges/coverage.svg)](https://codeclimate.com/github/ckeditor/ckeditor5-enter/coverage)
+[![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=d3hvenZqQVZERFQ5d09FWXdyT0ozVXhLaVltRFRjTTUyZGpvQWNmWVhUUT0tLUZqNlJ1YWRUd0RvdEVOaEptM1B2Q0E9PQ==--c9d3dee40b9b4471ff3fb516d9ecf8d09292c7e0)](https://www.browserstack.com/automate/public-build/d3hvenZqQVZERFQ5d09FWXdyT0ozVXhLaVltRFRjTTUyZGpvQWNmWVhUUT0tLUZqNlJ1YWRUd0RvdEVOaEptM1B2Q0E9PQ==--c9d3dee40b9b4471ff3fb516d9ecf8d09292c7e0)
+[![Coverage Status](https://coveralls.io/repos/github/ckeditor/ckeditor5-enter/badge.svg?branch=master)](https://coveralls.io/github/ckeditor/ckeditor5-enter?branch=master)
+<br>
 [![Dependency Status](https://david-dm.org/ckeditor/ckeditor5-enter/status.svg)](https://david-dm.org/ckeditor/ckeditor5-enter)
 [![devDependency Status](https://david-dm.org/ckeditor/ckeditor5-enter/dev-status.svg)](https://david-dm.org/ckeditor/ckeditor5-enter?type=dev)
 

+ 12 - 12
packages/ckeditor5-enter/package.json

@@ -1,26 +1,26 @@
 {
   "name": "@ckeditor/ckeditor5-enter",
-  "version": "1.0.0-alpha.2",
+  "version": "1.0.0-beta.1",
   "description": "Enter feature for CKEditor 5.",
   "keywords": [
     "ckeditor5",
     "ckeditor5-feature"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^1.0.0-alpha.2",
-    "@ckeditor/ckeditor5-engine": "^1.0.0-alpha.2",
-    "@ckeditor/ckeditor5-utils": "^1.0.0-alpha.2"
+    "@ckeditor/ckeditor5-core": "^1.0.0-beta.1",
+    "@ckeditor/ckeditor5-engine": "^1.0.0-beta.1",
+    "@ckeditor/ckeditor5-utils": "^1.0.0-beta.1"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-basic-styles": "^1.0.0-alpha.2",
-    "@ckeditor/ckeditor5-editor-classic": "^1.0.0-alpha.2",
-    "@ckeditor/ckeditor5-heading": "^1.0.0-alpha.2",
-    "@ckeditor/ckeditor5-typing": "^1.0.0-alpha.2",
-    "@ckeditor/ckeditor5-undo": "^1.0.0-alpha.2",
-    "eslint": "^4.8.0",
-    "eslint-config-ckeditor5": "^1.0.6",
+    "@ckeditor/ckeditor5-basic-styles": "^1.0.0-beta.1",
+    "@ckeditor/ckeditor5-editor-classic": "^1.0.0-beta.1",
+    "@ckeditor/ckeditor5-heading": "^1.0.0-beta.1",
+    "@ckeditor/ckeditor5-typing": "^1.0.0-beta.1",
+    "@ckeditor/ckeditor5-undo": "^1.0.0-beta.1",
+    "eslint": "^4.15.0",
+    "eslint-config-ckeditor5": "^1.0.7",
     "husky": "^0.14.3",
-    "lint-staged": "^4.2.3"
+    "lint-staged": "^6.0.0"
   },
   "engines": {
     "node": ">=6.0.0",

+ 6 - 5
packages/ckeditor5-enter/src/enter.js

@@ -1,5 +1,5 @@
 /**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md.
  */
 
@@ -26,17 +26,18 @@ export default class Enter extends Plugin {
 
 	init() {
 		const editor = this.editor;
-		const editingView = editor.editing.view;
+		const view = editor.editing.view;
+		const viewDocument = view.document;
 
-		editingView.addObserver( EnterObserver );
+		view.addObserver( EnterObserver );
 
 		editor.commands.add( 'enter', new EnterCommand( editor ) );
 
 		// TODO We may use the keystroke handler for that.
-		this.listenTo( editingView, 'enter', ( evt, data ) => {
+		this.listenTo( viewDocument, 'enter', ( evt, data ) => {
 			editor.execute( 'enter' );
 			data.preventDefault();
-			editingView.scrollToTheSelection();
+			view.scrollToTheSelection();
 		}, { priority: 'low' } );
 	}
 }

+ 20 - 22
packages/ckeditor5-enter/src/entercommand.js

@@ -1,5 +1,5 @@
 /**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md.
  */
 
@@ -8,7 +8,6 @@
  */
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
-import Position from '@ckeditor/ckeditor5-engine/src/model/position';
 
 /**
  * Enter command. It is used by the {@link module:enter/enter~Enter Enter feature} to handle the <kbd>Enter</kbd> key.
@@ -20,68 +19,67 @@ export default class EnterCommand extends Command {
 	 * @inheritDoc
 	 */
 	execute() {
-		const doc = this.editor.document;
-		const batch = doc.batch();
+		const model = this.editor.model;
+		const doc = model.document;
 
-		doc.enqueueChanges( () => {
-			enterBlock( this.editor.data, batch, doc.selection, doc.schema );
-
-			this.fire( 'afterExecute', { batch } );
+		model.change( writer => {
+			enterBlock( this.editor.model, writer, doc.selection, model.schema );
+			this.fire( 'afterExecute', { writer } );
 		} );
 	}
 }
 
 // Creates a new block in the way that the <kbd>Enter</kbd> key is expected to work.
 //
-// @param {engine.controller.DataController} dataController
-// @param {module:engine/model/batch~Batch} batch A batch to which the deltas will be added.
+// @param {module:engine/model~Model} model
+// @param {module:engine/model/writer~Writer} writer
 // @param {module:engine/model/selection~Selection} selection Selection on which the action should be performed.
 // @param {module:engine/model/schema~Schema} schema
-function enterBlock( dataController, batch, selection, schema ) {
+function enterBlock( model, writer, selection, schema ) {
 	const isSelectionEmpty = selection.isCollapsed;
 	const range = selection.getFirstRange();
 	const startElement = range.start.parent;
 	const endElement = range.end.parent;
 
 	// Don't touch the roots and other limit elements.
-	if ( schema.limits.has( startElement.name ) || schema.limits.has( endElement.name ) ) {
+	if ( schema.isLimit( startElement ) || schema.isLimit( endElement ) ) {
 		// Delete the selected content but only if inside a single limit element.
 		// Abort, when crossing limit elements boundary (e.g. <limit1>x[x</limit1>donttouchme<limit2>y]y</limit2>).
 		// This is an edge case and it's hard to tell what should actually happen because such a selection
 		// is not entirely valid.
 		if ( !isSelectionEmpty && startElement == endElement ) {
-			dataController.deleteContent( selection, batch );
+			model.deleteContent( selection );
 		}
 
 		return;
 	}
 
 	if ( isSelectionEmpty ) {
-		splitBlock( batch, selection, range.start );
+		splitBlock( writer, selection, range.start );
 	} else {
 		const leaveUnmerged = !( range.start.isAtStart && range.end.isAtEnd );
 		const isContainedWithinOneElement = ( startElement == endElement );
 
-		dataController.deleteContent( selection, batch, { leaveUnmerged } );
+		model.deleteContent( selection, { leaveUnmerged } );
 
 		if ( leaveUnmerged ) {
 			// Partially selected elements.
 			//
 			// <h>x[xx]x</h>		-> <h>x^x</h>			-> <h>x</h><h>^x</h>
 			if ( isContainedWithinOneElement ) {
-				splitBlock( batch, selection, selection.focus );
+				splitBlock( writer, selection, selection.focus );
 			}
 			// Selection over multiple elements.
 			//
 			// <h>x[x</h><p>y]y<p>	-> <h>x^</h><p>y</p>	-> <h>x</h><p>^y</p>
 			else {
-				selection.setCollapsedAt( endElement );
+				writer.setSelection( endElement, 0 );
 			}
 		}
 	}
 }
 
-function splitBlock( batch, selection, splitPos ) {
+function splitBlock( writer, selection, splitPos ) {
 	const oldElement = splitPos.parent;
 	const newElement = new oldElement.constructor( oldElement.name, oldElement.getAttributes() );
 
@@ -89,15 +87,15 @@ function splitBlock( batch, selection, splitPos ) {
 		// If the split is at the end of element, instead of splitting, just create a clone of position's parent
 		// element and insert it after split element. The result is the same but less operations are done
 		// and it's more semantically correct (when it comes to operational transformation).
-		batch.insert( Position.createAfter( splitPos.parent ), newElement );
+		writer.insert( newElement, splitPos.parent, 'after' );
 	} else if ( splitPos.isAtStart ) {
 		// If the split is at the start of element, instead of splitting, just create a clone of position's parent
 		// element and insert it before split element. The result is the same but less operations are done
 		// and it's more semantically correct (when it comes to operational transformation).
-		batch.insert( Position.createBefore( splitPos.parent ), newElement );
+		writer.insert( newElement, splitPos.parent, 'before' );
 	} else {
-		batch.split( splitPos );
+		writer.split( splitPos );
 	}
 
-	selection.setCollapsedAt( splitPos.parent.nextSibling );
+	writer.setSelection( splitPos.parent.nextSibling, 0 );
 }

+ 15 - 3
packages/ckeditor5-enter/src/enterobserver.js

@@ -1,5 +1,5 @@
 /**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md.
  */
 
@@ -17,12 +17,24 @@ import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
  * @extends module:engine/view/observer~Observer
  */
 export default class EnterObserver extends Observer {
-	constructor( document ) {
-		super( document );
+	constructor( view ) {
+		super( view );
+
+		const document = this.document;
 
 		document.on( 'keydown', ( evt, data ) => {
 			if ( this.isEnabled && data.keyCode == keyCodes.enter ) {
+				// Save the event object to check later if it was stopped or not.
+				let event;
+				document.once( 'enter', evt => ( event = evt ), { priority: 'highest' } );
+
 				document.fire( 'enter', new DomEventData( document, data.domEvent ) );
+
+				// Stop `keydown` event if `enter` event was stopped.
+				// https://github.com/ckeditor/ckeditor5/issues/753
+				if ( event && event.stop.called ) {
+					evt.stop();
+				}
 			}
 		} );
 	}

+ 6 - 8
packages/ckeditor5-enter/tests/enter.js

@@ -1,5 +1,5 @@
 /**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md.
  */
 
@@ -9,7 +9,7 @@ import EnterCommand from '../src/entercommand';
 import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';
 
 describe( 'Enter feature', () => {
-	let editor, editingView;
+	let editor, viewDocument;
 
 	beforeEach( () => {
 		return VirtualTestEditor
@@ -18,7 +18,7 @@ describe( 'Enter feature', () => {
 			} )
 			.then( newEditor => {
 				editor = newEditor;
-				editingView = editor.editing.view;
+				viewDocument = editor.editing.view.document;
 			} );
 	} );
 
@@ -28,10 +28,9 @@ describe( 'Enter feature', () => {
 
 	it( 'listens to the editing view enter event', () => {
 		const spy = editor.execute = sinon.spy();
-		const view = editor.editing.view;
 		const domEvt = getDomEvent();
 
-		view.fire( 'enter', new DomEventData( editingView, domEvt ) );
+		viewDocument.fire( 'enter', new DomEventData( viewDocument, domEvt ) );
 
 		expect( spy.calledOnce ).to.be.true;
 		expect( spy.calledWithExactly( 'enter' ) ).to.be.true;
@@ -40,12 +39,11 @@ describe( 'Enter feature', () => {
 	} );
 
 	it( 'scrolls the editing document to the selection after executing the command', () => {
-		const view = editor.editing.view;
 		const domEvt = getDomEvent();
 		const executeSpy = editor.execute = sinon.spy();
-		const scrollSpy = sinon.stub( view, 'scrollToTheSelection' );
+		const scrollSpy = sinon.stub( editor.editing.view, 'scrollToTheSelection' );
 
-		view.fire( 'enter', new DomEventData( editingView, domEvt ) );
+		viewDocument.fire( 'enter', new DomEventData( viewDocument, domEvt ) );
 
 		sinon.assert.calledOnce( scrollSpy );
 		sinon.assert.callOrder( executeSpy, scrollSpy );

+ 35 - 36
packages/ckeditor5-enter/tests/entercommand.js

@@ -1,5 +1,5 @@
 /**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md.
  */
 
@@ -9,56 +9,55 @@ import InsertDelta from '@ckeditor/ckeditor5-engine/src/model/delta/insertdelta'
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 describe( 'EnterCommand', () => {
-	let editor, doc, schema, command;
+	let editor, model, doc, schema, command;
 
 	beforeEach( () => {
 		return ModelTestEditor.create()
 			.then( newEditor => {
 				editor = newEditor;
-				doc = editor.document;
+				model = editor.model;
+				doc = model.document;
 
 				command = new EnterCommand( editor );
 				editor.commands.add( 'enter', command );
 
-				schema = doc.schema;
+				schema = model.schema;
 
 				// Note: We could use real names like 'paragraph', but that would make test patterns too long.
 				// Plus, this is actually a good test that the algorithm can be used for any model.
-				schema.registerItem( 'img', '$inline' );
-				schema.registerItem( 'p', '$block' );
-				schema.registerItem( 'h', '$block' );
-				schema.registerItem( 'inlineLimit' );
-				schema.registerItem( 'blockLimit' );
-
-				schema.allow( { name: 'inlineLimit', inside: 'p' } );
-				schema.allow( { name: '$text', inside: 'inlineLimit' } );
-				schema.allow( { name: '$text', inside: '$root' } );
-				schema.allow( { name: 'blockLimit', inside: '$root' } );
-				schema.allow( { name: 'p', inside: 'blockLimit' } );
-
-				schema.limits.add( 'inlineLimit' );
-				schema.limits.add( 'blockLimit' );
+				schema.register( 'img', { allowWhere: '$block' } );
+				schema.register( 'p', {
+					inheritAllFrom: '$block',
+					allowIn: 'blockLimit'
+				} );
+				schema.register( 'h', { inheritAllFrom: '$block' } );
+				schema.register( 'inlineLimit', {
+					allowIn: 'p',
+					isLimit: true
+				} );
+				schema.register( 'blockLimit', {
+					allowIn: '$root',
+					isLimit: true
+				} );
+				schema.extend( '$text', {
+					allowIn: [ 'inlineLimit', '$root' ]
+				} );
 			} );
 	} );
 
 	describe( 'EnterCommand', () => {
-		it( 'enters a block using enqueueChanges', () => {
-			setData( doc, '<p>foo[]</p>' );
+		it( 'enters a block using parent batch', () => {
+			setData( model, '<p>foo[]</p>' );
 
-			doc.enqueueChanges( () => {
+			model.change( writer => {
+				expect( writer.batch.deltas ).to.length( 0 );
 				editor.execute( 'enter' );
-
-				// We expect that command is executed in enqueue changes block. Since we are already in
-				// an enqueued block, the command execution will be postponed. Hence, no changes.
-				expect( getData( doc, { withoutSelection: true } ) ).to.equal( '<p>foo</p>' );
+				expect( writer.batch.deltas ).to.length.above( 0 );
 			} );
-
-			// After all enqueued changes are done, the command execution is reflected.
-			expect( getData( doc, { withoutSelection: true } ) ).to.equal( '<p>foo</p><p></p>' );
 		} );
 
 		it( 'creates InsertDelta if enter is at the beginning of block', () => {
-			setData( doc, '<p>[]foo</p>' );
+			setData( model, '<p>[]foo</p>' );
 
 			editor.execute( 'enter' );
 
@@ -68,7 +67,7 @@ describe( 'EnterCommand', () => {
 		} );
 
 		it( 'creates InsertDelta if enter is at the end of block', () => {
-			setData( doc, '<p>foo[]</p>' );
+			setData( model, '<p>foo[]</p>' );
 
 			editor.execute( 'enter' );
 
@@ -167,21 +166,21 @@ describe( 'EnterCommand', () => {
 			);
 
 			it( 'leaves one empty element after two were fully selected (backward)', () => {
-				setData( doc, '<p>[abc</p><p>def]</p>' );
+				setData( model, '<p>[abc</p><p>def]</p>' );
 				// @TODO: Add option for setting selection direction to model utils.
 				doc.selection._lastRangeBackward = true;
 
 				command.execute();
 
-				expect( getData( doc ) ).to.equal( '<p>[]</p>' );
+				expect( getData( model ) ).to.equal( '<p>[]</p>' );
 			} );
 
 			it( 'uses DataController.deleteContent', () => {
 				const spy = sinon.spy();
 
-				editor.data.on( 'deleteContent', spy );
+				editor.model.on( 'deleteContent', spy );
 
-				setData( doc, '<p>[x]</p>' );
+				setData( model, '<p>[x]</p>' );
 
 				command.execute();
 
@@ -191,11 +190,11 @@ describe( 'EnterCommand', () => {
 
 		function test( title, input, output ) {
 			it( title, () => {
-				setData( doc, input );
+				setData( model, input );
 
 				command.execute();
 
-				expect( getData( doc ) ).to.equal( output );
+				expect( getData( model ) ).to.equal( output );
 			} );
 		}
 	} );

+ 33 - 6
packages/ckeditor5-enter/tests/enterobserver.js

@@ -1,27 +1,30 @@
 /**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md.
  */
 
 /* globals document */
 
-import ViewDocument from '@ckeditor/ckeditor5-engine/src/view/document';
+import View from '@ckeditor/ckeditor5-engine/src/view/view';
 import EnterObserver from '../src/enterobserver';
 import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';
+import createViewRoot from '@ckeditor/ckeditor5-engine/tests/view/_utils/createroot';
 import { getCode } from '@ckeditor/ckeditor5-utils/src/keyboard';
 
 describe( 'EnterObserver', () => {
-	let viewDocument;
+	let view, viewDocument;
 
 	beforeEach( () => {
-		viewDocument = new ViewDocument();
-		viewDocument.addObserver( EnterObserver );
+		view = new View();
+		viewDocument = view.document;
+		view.addObserver( EnterObserver );
 	} );
 
 	// See #10.
 	it( 'can be initialized', () => {
 		expect( () => {
-			viewDocument.createRoot( document.createElement( 'div' ) );
+			createViewRoot( viewDocument );
+			view.attachDomRoot( document.createElement( 'div' ) );
 		} ).to.not.throw();
 	} );
 
@@ -49,6 +52,30 @@ describe( 'EnterObserver', () => {
 
 			expect( spy.calledOnce ).to.be.false;
 		} );
+
+		it( 'should stop keydown event when enter event is stopped', () => {
+			const keydownSpy = sinon.spy();
+			viewDocument.on( 'keydown', keydownSpy );
+			viewDocument.on( 'enter', evt => evt.stop() );
+
+			viewDocument.fire( 'keydown', new DomEventData( viewDocument, getDomEvent(), {
+				keyCode: getCode( 'enter' )
+			} ) );
+
+			sinon.assert.notCalled( keydownSpy );
+		} );
+
+		it( 'should not stop keydown event when enter event is not stopped', () => {
+			const keydownSpy = sinon.spy();
+			viewDocument.on( 'keydown', keydownSpy );
+			viewDocument.on( 'enter', evt => evt.stop() );
+
+			viewDocument.fire( 'keydown', new DomEventData( viewDocument, getDomEvent(), {
+				keyCode: getCode( 'x' )
+			} ) );
+
+			sinon.assert.calledOnce( keydownSpy );
+		} );
 	} );
 
 	function getDomEvent() {

+ 2 - 2
packages/ckeditor5-enter/tests/manual/enter.js

@@ -1,5 +1,5 @@
 /**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md.
  */
 
@@ -16,7 +16,7 @@ import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
 		plugins: [ Enter, Typing, Heading, Undo, Bold, Italic ],
-		toolbar: [ 'headings', 'bold', 'italic', 'undo', 'redo' ]
+		toolbar: [ 'heading', '|', 'bold', 'italic', 'undo', 'redo' ]
 	} )
 	.then( editor => {
 		window.editor = editor;