8
0
Просмотр исходного кода

Merge branch 'master' into t/1146

Piotrek Koszuliński 8 лет назад
Родитель
Сommit
6a5b469e6f
34 измененных файлов с 171 добавлено и 122 удалено
  1. 30 0
      packages/ckeditor5-engine/docs/api/engine.md
  2. 11 4
      packages/ckeditor5-engine/package.json
  3. 2 2
      packages/ckeditor5-engine/src/conversion/buildmodelconverter.js
  4. 10 1
      packages/ckeditor5-engine/src/conversion/viewconsumable.js
  5. 2 2
      packages/ckeditor5-engine/src/conversion/viewconversiondispatcher.js
  6. 1 0
      packages/ckeditor5-engine/src/model/delta/attributedelta.js
  7. 8 4
      packages/ckeditor5-engine/src/model/delta/basic-transformations.js
  8. 2 1
      packages/ckeditor5-engine/src/model/delta/insertdelta.js
  9. 4 3
      packages/ckeditor5-engine/src/model/delta/markerdelta.js
  10. 2 1
      packages/ckeditor5-engine/src/model/delta/mergedelta.js
  11. 2 1
      packages/ckeditor5-engine/src/model/delta/movedelta.js
  12. 2 1
      packages/ckeditor5-engine/src/model/delta/removedelta.js
  13. 2 0
      packages/ckeditor5-engine/src/model/delta/renamedelta.js
  14. 2 1
      packages/ckeditor5-engine/src/model/delta/splitdelta.js
  15. 2 1
      packages/ckeditor5-engine/src/model/delta/unwrapdelta.js
  16. 2 1
      packages/ckeditor5-engine/src/model/delta/weakinsertdelta.js
  17. 2 1
      packages/ckeditor5-engine/src/model/delta/wrapdelta.js
  18. 4 3
      packages/ckeditor5-engine/src/model/document.js
  19. 7 9
      packages/ckeditor5-engine/src/model/documentselection.js
  20. 4 2
      packages/ckeditor5-engine/src/model/liveposition.js
  21. 12 21
      packages/ckeditor5-engine/src/model/markercollection.js
  22. 8 10
      packages/ckeditor5-engine/src/model/node.js
  23. 15 13
      packages/ckeditor5-engine/src/model/position.js
  24. 2 1
      packages/ckeditor5-engine/src/model/range.js
  25. 6 15
      packages/ckeditor5-engine/src/model/schema.js
  26. 1 1
      packages/ckeditor5-engine/src/model/selection.js
  27. 2 2
      packages/ckeditor5-engine/src/model/textproxy.js
  28. 2 2
      packages/ckeditor5-engine/src/model/treewalker.js
  29. 4 4
      packages/ckeditor5-engine/src/model/writer.js
  30. 2 2
      packages/ckeditor5-engine/src/view/position.js
  31. 1 1
      packages/ckeditor5-engine/src/view/selection.js
  32. 1 1
      packages/ckeditor5-engine/src/view/treewalker.js
  33. 6 10
      packages/ckeditor5-engine/src/view/writer.js
  34. 8 1
      packages/ckeditor5-engine/tests/view/document/document.js

+ 30 - 0
packages/ckeditor5-engine/docs/api/engine.md

@@ -0,0 +1,30 @@
+---
+category: api-reference
+---
+
+# CKEditor 5 editing engine
+
+[![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-engine.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)
+
+Editing engine is the heart of CKEditor 5. It is a framework for implementing editing features.
+
+## Documentation
+
+See the introduction to the {@link framework/guides/architecture/intro#Editing-engine editing engine architecture}.
+
+## Installation
+
+```bash
+npm install --save @ckeditor/ckeditor5-engine
+```
+
+## Contribute
+
+The source code of this package is available on GitHub in https://github.com/ckeditor/ckeditor5-engine.
+
+## External links
+
+* [`@ckeditor/ckeditor5-engine` on npm](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)
+* [`ckeditor/ckeditor5-engine` on GitHub](https://github.com/ckeditor/ckeditor5-engine)
+* [Issue tracker](https://github.com/ckeditor/ckeditor5-engine/issues)
+* [Changelog](https://github.com/ckeditor/ckeditor5-engine/blob/master/CHANGELOG.md)

+ 11 - 4
packages/ckeditor5-engine/package.json

@@ -1,9 +1,10 @@
 {
   "name": "@ckeditor/ckeditor5-engine",
   "version": "0.11.0",
-  "description": "CKEditor 5 Editing Engine",
+  "description": "CKEditor 5 editing engine.",
   "keywords": [
-    "CKEditor"
+    "ckeditor5",
+    "ckeditor5-lib"
   ],
   "dependencies": {
     "@ckeditor/ckeditor5-utils": "^0.10.0"
@@ -14,13 +15,14 @@
     "@ckeditor/ckeditor5-core": "^0.9.0",
     "@ckeditor/ckeditor5-editor-classic": "^0.8.0",
     "@ckeditor/ckeditor5-enter": "^0.10.0",
+    "@ckeditor/ckeditor5-essentials": "^0.3.0",
     "@ckeditor/ckeditor5-heading": "^0.10.0",
     "@ckeditor/ckeditor5-list": "^0.7.0",
     "@ckeditor/ckeditor5-paragraph": "^0.9.0",
     "@ckeditor/ckeditor5-typing": "^0.10.0",
     "@ckeditor/ckeditor5-undo": "^0.9.0",
     "@ckeditor/ckeditor5-widget": "^0.2.0",
-    "eslint-config-ckeditor5": "^1.0.5",
+    "eslint-config-ckeditor5": "^1.0.6",
     "gulp": "^3.9.1",
     "guppy-pre-commit": "^0.4.0"
   },
@@ -35,5 +37,10 @@
   "repository": {
     "type": "git",
     "url": "https://github.com/ckeditor/ckeditor5-engine.git"
-  }
+  },
+  "files": [
+    "lang",
+    "src",
+    "theme"
+  ]
 }

+ 2 - 2
packages/ckeditor5-engine/src/conversion/buildmodelconverter.js

@@ -315,12 +315,12 @@ class ModelConverterBuilder {
 
 		if ( this._from.type != 'marker' ) {
 			/**
-			 * To highlight conversion is supported only for model markers.
+			 * Conversion to a highlight is supported only from model markers.
 			 *
 			 * @error build-model-converter-non-marker-to-highlight
 			 */
 			throw new CKEditorError(
-				'build-model-converter-non-marker-to-highlight: Conversion to highlight is supported ' +
+				'build-model-converter-non-marker-to-highlight: Conversion to a highlight is supported ' +
 				'only from model markers.'
 			);
 		}

+ 10 - 1
packages/ckeditor5-engine/src/conversion/viewconsumable.js

@@ -490,7 +490,16 @@ class ViewElementConsumables {
 		for ( const name of items ) {
 			if ( type === 'attribute' && ( name === 'class' || name === 'style' ) ) {
 				/**
-				 * Class and style attributes should be handled separately.
+				 * Class and style attributes should be handled separately in
+				 * {@link module:engine/conversion/viewconsumable~ViewConsumable#add `ViewConsumable#add()`}.
+				 *
+				 * What you have done is trying to use:
+				 *
+				 *		consumables.add( { attribute: [ 'class', 'style' ] } );
+				 *
+				 * While each class and style should be registered separately:
+				 *
+				 *		consumables.add( { class: 'some-class', style: 'font-weight' } );
 				 *
 				 * @error viewconsumable-invalid-attribute
 				 */

+ 2 - 2
packages/ckeditor5-engine/src/conversion/viewconversiondispatcher.js

@@ -184,14 +184,14 @@ export default class ViewConversionDispatcher {
 		// Handle incorrect `data.output`.
 		if ( data.output && !( data.output instanceof ModelNode || data.output instanceof ModelDocumentFragment ) ) {
 			/**
-			 * Dropped incorrect conversion result.
+			 * Incorrect conversion result was dropped.
 			 *
 			 * Item may be converted to either {@link module:engine/model/node~Node model node} or
 			 * {@link module:engine/model/documentfragment~DocumentFragment model document fragment}.
 			 *
 			 * @error view-conversion-dispatcher-incorrect-result
 			 */
-			log.warn( 'view-conversion-dispatcher-incorrect-result: Dropped incorrect conversion result.', [ input, data.output ] );
+			log.warn( 'view-conversion-dispatcher-incorrect-result: Incorrect conversion result was dropped.', [ input, data.output ] );
 
 			return null;
 		}

+ 1 - 0
packages/ckeditor5-engine/src/model/delta/attributedelta.js

@@ -20,6 +20,7 @@ import Range from '../range';
  * To provide specific OT behavior and better collisions solving, methods to change attributes
  * ({@link module:engine/model/batch~Batch#setAttribute} and {@link module:engine/model/batch~Batch#removeAttribute})
  * use `AttributeDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
  * @extends module:engine/model/delta/delta~Delta
  */
 export default class AttributeDelta extends Delta {

+ 8 - 4
packages/ckeditor5-engine/src/model/delta/basic-transformations.js

@@ -141,8 +141,10 @@ addTransformationCase( MarkerDelta, RenameDelta, transformMarkerDelta );
 
 // Add special case for MoveDelta x MergeDelta transformation.
 addTransformationCase( MoveDelta, MergeDelta, ( a, b, context ) => {
-	// Do not apply special transformation case if `MergeDelta` has `NoOperation` as the second operation.
-	if ( !b.position ) {
+	const undoMode = context.aWasUndone || context.bWasUndone;
+
+	// Do not apply special transformation case in undo mode or if `MergeDelta` has `NoOperation` as the second operation.
+	if ( undoMode || !b.position ) {
 		return defaultTransform( a, b, context );
 	}
 
@@ -185,8 +187,10 @@ addTransformationCase( MergeDelta, InsertDelta, ( a, b, context ) => {
 
 // Add special case for MergeDelta x MoveDelta transformation.
 addTransformationCase( MergeDelta, MoveDelta, ( a, b, context ) => {
-	// Do not apply special transformation case if `MergeDelta` has `NoOperation` as the second operation.
-	if ( !a.position ) {
+	const undoMode = context.aWasUndone || context.bWasUndone;
+
+	// Do not apply special transformation case in undo mode or if `MergeDelta` has `NoOperation` as the second operation.
+	if ( undoMode || !a.position ) {
 		return defaultTransform( a, b, context );
 	}
 

+ 2 - 1
packages/ckeditor5-engine/src/model/delta/insertdelta.js

@@ -19,9 +19,10 @@ import Range from '../../model/range.js';
 import Position from '../../model/position.js';
 
 /**
- * @classdesc
  * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#insert Batch#insert} method
  * uses the `InsertDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class InsertDelta extends Delta {
 	/**

+ 4 - 3
packages/ckeditor5-engine/src/model/delta/markerdelta.js

@@ -14,10 +14,11 @@ import MarkerOperation from '../operation/markeroperation';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
 /**
- * @classdesc
  * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#setMarker Batch#setMarker}
  * and {@link module:engine/model/batch~Batch#removeMarker Batch#removeMarker} methods use the `MarkerDelta` class which inherits
  * from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class MarkerDelta extends Delta {
 	/**
@@ -102,11 +103,11 @@ register( 'removeMarker', function( markerOrName ) {
 
 	if ( !this.document.markers.has( name ) ) {
 		/**
-		 * Trying to remove marker that does not exist.
+		 * Trying to remove marker which does not exist.
 		 *
 		 * @error batch-removeMarker-no-marker
 		 */
-		throw new CKEditorError( 'batch-removeMarker-no-marker: Trying to remove marker that does not exist.' );
+		throw new CKEditorError( 'batch-removeMarker-no-marker: Trying to remove marker which does not exist.' );
 	}
 
 	const oldRange = this.document.markers.get( name ).getRange();

+ 2 - 1
packages/ckeditor5-engine/src/model/delta/mergedelta.js

@@ -18,9 +18,10 @@ import MoveOperation from '../operation/moveoperation';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
 /**
- * @classdesc
  * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#merge} method
  * uses the `MergeDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class MergeDelta extends Delta {
 	/**

+ 2 - 1
packages/ckeditor5-engine/src/model/delta/movedelta.js

@@ -16,9 +16,10 @@ import Range from '../range';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
 /**
- * @classdesc
  * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#move} method
  * uses the `MoveDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class MoveDelta extends Delta {
 	/**

+ 2 - 1
packages/ckeditor5-engine/src/model/delta/removedelta.js

@@ -15,9 +15,10 @@ import Position from '../position';
 import Range from '../range';
 
 /**
- * @classdesc
  * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#remove} method
  * uses the `RemoveDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class RemoveDelta extends MoveDelta {
 	/**

+ 2 - 0
packages/ckeditor5-engine/src/model/delta/renamedelta.js

@@ -18,6 +18,8 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 /**
  * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#rename Batch#rename} method
  * uses the `RenameDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class RenameDelta extends Delta {
 	/**

+ 2 - 1
packages/ckeditor5-engine/src/model/delta/splitdelta.js

@@ -18,9 +18,10 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 import MergeDelta from '../delta/mergedelta';
 
 /**
- * @classdesc
  * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#split} method
  * uses `SplitDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class SplitDelta extends Delta {
 	/**

+ 2 - 1
packages/ckeditor5-engine/src/model/delta/unwrapdelta.js

@@ -17,9 +17,10 @@ import MoveOperation from '../operation/moveoperation';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
 /**
- * @classdesc
  * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#merge} method
  * uses the `UnwrapDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class UnwrapDelta extends Delta {
 	/**

+ 2 - 1
packages/ckeditor5-engine/src/model/delta/weakinsertdelta.js

@@ -14,9 +14,10 @@ import InsertOperation from '../operation/insertoperation';
 import { normalizeNodes } from './../writer';
 
 /**
- * @classdesc
  * To provide specific OT behavior and better collisions solving, the {@link module:engine/model/batch~Batch#insert} method
  * uses the `WeakInsertDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class WeakInsertDelta extends InsertDelta {
 	/**

+ 2 - 1
packages/ckeditor5-engine/src/model/delta/wrapdelta.js

@@ -19,9 +19,10 @@ import MoveOperation from '../operation/moveoperation';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
 /**
- * @classdesc
  * To provide specific OT behavior and better collisions solving, {@link module:engine/model/batch~Batch#merge} method
  * uses the `WrapDelta` class which inherits from the `Delta` class and may overwrite some methods.
+ *
+ * @extends module:engine/model/delta/delta~Delta
  */
 export default class WrapDelta extends Delta {
 	/**

+ 4 - 3
packages/ckeditor5-engine/src/model/document.js

@@ -116,7 +116,8 @@ export default class Document {
 			for ( const range of this.selection.getRanges() ) {
 				if ( !this._validateSelectionRange( range ) ) {
 					/**
-					 * Range from document selection starts or ends at incorrect position.
+					 * Range from {@link module:engine/model/documentselection~DocumentSelection document selection}
+					 * starts or ends at incorrect position.
 					 *
 					 * @error document-selection-wrong-position
 					 * @param {module:engine/model/range~Range} range
@@ -195,7 +196,7 @@ export default class Document {
 			/**
 			 * Root with specified name already exists.
 			 *
-			 * @error document-createRoot-name-exists
+			 * @error model-document-createRoot-name-exists
 			 * @param {module:engine/model/document~Document} doc
 			 * @param {String} name
 			 */
@@ -254,7 +255,7 @@ export default class Document {
 			/**
 			 * Root with specified name does not exist.
 			 *
-			 * @error document-getRoot-root-not-exist
+			 * @error model-document-getRoot-root-not-exist
 			 * @param {String} name
 			 */
 			throw new CKEditorError(

+ 7 - 9
packages/ckeditor5-engine/src/model/documentselection.js

@@ -262,13 +262,15 @@ export default class DocumentSelection extends Selection {
 	 */
 	static createFromSelection() {
 		/**
+		 * Cannot create a new `DocumentSelection` instance.
+		 *
 		 * `DocumentSelection#createFromSelection()` is not available. There can be only one
 		 * `DocumentSelection` per document instance, so creating new `DocumentSelection`s this way
 		 * would be unsafe.
 		 *
 		 * @error documentselection-cannot-create
 		 */
-		throw new CKEditorError( 'documentselection-cannot-create: Cannot create new DocumentSelection instance.' );
+		throw new CKEditorError( 'documentselection-cannot-create: Cannot create a new DocumentSelection instance.' );
 	}
 
 	/**
@@ -326,11 +328,7 @@ export default class DocumentSelection extends Selection {
 		this.listenTo( liveRange, 'change:range', ( evt, oldRange, data ) => {
 			// If `LiveRange` is in whole moved to the graveyard, fix that range.
 			if ( liveRange.root == this._document.graveyard ) {
-				const sourceStart = data.sourcePosition;
-				const howMany = data.range.end.offset - data.range.start.offset;
-				const sourceRange = Range.createFromPositionAndShift( sourceStart, howMany );
-
-				this._fixGraveyardSelection( liveRange, sourceRange );
+				this._fixGraveyardSelection( liveRange, data.sourcePosition );
 			}
 
 			// Whenever a live range from selection changes, fire an event informing about that change.
@@ -663,12 +661,12 @@ export default class DocumentSelection extends Selection {
 	 *
 	 * @private
 	 * @param {module:engine/model/liverange~LiveRange} liveRange The range from selection, that ended up in the graveyard root.
-	 * @param {module:engine/model/range~Range} removedRange Range which removing had caused moving `liveRange` to the graveyard root.
+	 * @param {module:engine/model/position~Position} removedRangeStart Start position of a range which was removed.
 	 */
-	_fixGraveyardSelection( liveRange, removedRange ) {
+	_fixGraveyardSelection( liveRange, removedRangeStart ) {
 		// The start of the removed range is the closest position to the `liveRange` - the original selection range.
 		// This is a good candidate for a fixed selection range.
-		const positionCandidate = Position.createFromPosition( removedRange.start );
+		const positionCandidate = Position.createFromPosition( removedRangeStart );
 
 		// Find a range that is a correct selection range and is closest to the start of removed range.
 		const selectionRange = this._document.getNearestSelectionRange( positionCandidate );

+ 4 - 2
packages/ckeditor5-engine/src/model/liveposition.js

@@ -43,11 +43,13 @@ export default class LivePosition extends Position {
 
 		if ( !this.root.is( 'rootElement' ) ) {
 			/**
-			 * LivePosition root has to be an instance of RootElement.
+			 * LivePosition's root has to be an instance of RootElement.
 			 *
 			 * @error liveposition-root-not-rootelement
 			 */
-			throw new CKEditorError( 'model-liveposition-root-not-rootelement: LivePosition root has to be an instance of RootElement.' );
+			throw new CKEditorError(
+				'model-liveposition-root-not-rootelement: LivePosition\'s root has to be an instance of RootElement.'
+			);
 		}
 
 		/**

+ 12 - 21
packages/ckeditor5-engine/src/model/markercollection.js

@@ -142,7 +142,7 @@ export default class MarkerCollection {
 	}
 
 	/**
-	 * Destroys markers collection.
+	 * Destroys marker collection and all markers inside it.
 	 */
 	destroy() {
 		for ( const marker of this._markers.values() ) {
@@ -176,7 +176,7 @@ export default class MarkerCollection {
 	}
 
 	/**
-	 * Destroys marker.
+	 * Destroys the marker.
 	 *
 	 * @private
 	 * @param {module:engine/model/markercollection~Marker} marker Marker to destroy.
@@ -241,7 +241,7 @@ class Marker {
 	 */
 	constructor( name, liveRange ) {
 		/**
-		 * Marker name.
+		 * Marker's name.
 		 *
 		 * @readonly
 		 * @member {String} #name
@@ -268,12 +268,7 @@ class Marker {
 	 */
 	getStart() {
 		if ( !this._liveRange ) {
-			/**
-			 * Operating on destroyed marker instance.
-			 *
-			 * @error marker-destroyed
-			 */
-			throw new CKEditorError( 'marker-destroyed: Operating on destroyed marker instance.' );
+			throw new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );
 		}
 
 		return Position.createFromPosition( this._liveRange.start );
@@ -286,12 +281,7 @@ class Marker {
 	 */
 	getEnd() {
 		if ( !this._liveRange ) {
-			/**
-			 * Operating on destroyed marker instance.
-			 *
-			 * @error marker-destroyed
-			 */
-			throw new CKEditorError( 'marker-destroyed: Operating on destroyed marker instance.' );
+			throw new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );
 		}
 
 		return Position.createFromPosition( this._liveRange.end );
@@ -311,12 +301,7 @@ class Marker {
 	 */
 	getRange() {
 		if ( !this._liveRange ) {
-			/**
-			 * Operating on destroyed marker instance.
-			 *
-			 * @error marker-destroyed
-			 */
-			throw new CKEditorError( 'marker-destroyed: Operating on destroyed marker instance.' );
+			throw new CKEditorError( 'marker-destroyed: Cannot use a destroyed marker instance.' );
 		}
 
 		return Range.createFromRange( this._liveRange );
@@ -352,3 +337,9 @@ class Marker {
 }
 
 mix( Marker, EmitterMixin );
+
+/**
+ * Cannot use a {@link module:engine/model/markercollection~MarkerCollection#destroy destroyed marker} instance.
+ *
+ * @error marker-destroyed
+ */

+ 8 - 10
packages/ckeditor5-engine/src/model/node.js

@@ -84,11 +84,6 @@ export default class Node {
 		}
 
 		if ( ( pos = this.parent.getChildIndex( this ) ) === null ) {
-			/**
-			 * The node's parent does not contain this node.
-			 *
-			 * @error node-not-found-in-parent
-			 */
 			throw new CKEditorError( 'model-node-not-found-in-parent: The node\'s parent does not contain this node.' );
 		}
 
@@ -113,11 +108,6 @@ export default class Node {
 		}
 
 		if ( ( pos = this.parent.getChildStartOffset( this ) ) === null ) {
-			/**
-			 * The node's parent does not contain this node.
-			 *
-			 * @error node-not-found-in-parent
-			 */
 			throw new CKEditorError( 'model-node-not-found-in-parent: The node\'s parent does not contain this node.' );
 		}
 
@@ -411,3 +401,11 @@ export default class Node {
 	 * @returns {Boolean}
 	 */
 }
+
+/**
+ * The node's parent does not contain this node.
+ *
+ * This error may be thrown from corrupted trees.
+ *
+ * @error model-node-not-found-in-parent
+ */

+ 15 - 13
packages/ckeditor5-engine/src/model/position.js

@@ -45,21 +45,23 @@ export default class Position {
 	constructor( root, path ) {
 		if ( !root.is( 'element' ) && !root.is( 'documentFragment' ) ) {
 			/**
-			 * Position root invalid.
+			 * Position root is invalid.
 			 *
-			 * @error position-root-invalid.
+			 * Positions can only be anchored in elements or document fragments.
+			 *
+			 * @error model-position-root-invalid
 			 */
 			throw new CKEditorError( 'model-position-root-invalid: Position root invalid.' );
 		}
 
 		if ( !( path instanceof Array ) || path.length === 0 ) {
 			/**
-			 * Position path must be an Array with at least one item.
+			 * Position path must be an array with at least one item.
 			 *
-			 * @error position-path-incorrect
+			 * @error model-position-path-incorrect
 			 * @param path
 			 */
-			throw new CKEditorError( 'model-position-path-incorrect: Position path must be an Array with at least one item.', { path } );
+			throw new CKEditorError( 'model-position-path-incorrect: Position path must be an array with at least one item.', { path } );
 		}
 
 		// Normalize the root and path (if element was passed).
@@ -686,12 +688,12 @@ export default class Position {
 	static createAfter( item ) {
 		if ( !item.parent ) {
 			/**
-			 * You can not make position after root.
+			 * You can not make a position after a root element.
 			 *
-			 * @error position-after-root
+			 * @error model-position-after-root
 			 * @param {module:engine/model/item~Item} root
 			 */
-			throw new CKEditorError( 'model-position-after-root: You can not make position after root.', { root: item } );
+			throw new CKEditorError( 'model-position-after-root: You cannot make a position after root.', { root: item } );
 		}
 
 		return this.createFromParentAndOffset( item.parent, item.endOffset );
@@ -706,12 +708,12 @@ export default class Position {
 	static createBefore( item ) {
 		if ( !item.parent ) {
 			/**
-			 * You can not make position before root.
+			 * You can not make a position before a root element.
 			 *
-			 * @error position-before-root
+			 * @error model-position-before-root
 			 * @param {module:engine/model/item~Item} root
 			 */
-			throw new CKEditorError( 'model-position-before-root: You can not make position before root.', { root: item } );
+			throw new CKEditorError( 'model-position-before-root: You cannot make a position before root.', { root: item } );
 		}
 
 		return this.createFromParentAndOffset( item.parent, item.startOffset );
@@ -729,7 +731,7 @@ export default class Position {
 			/**
 			 * Position parent have to be a model element or model document fragment.
 			 *
-			 * @error position-parent-incorrect
+			 * @error model-position-parent-incorrect
 			 */
 			throw new CKEditorError( 'model-position-parent-incorrect: Position parent have to be a element or document fragment.' );
 		}
@@ -766,7 +768,7 @@ export default class Position {
 			/**
 			 * Cannot create position for document. Root with specified name does not exist.
 			 *
-			 * @error position-fromjson-no-root
+			 * @error model-position-fromjson-no-root
 			 * @param {String} rootName
 			 */
 			throw new CKEditorError(

+ 2 - 1
packages/ckeditor5-engine/src/model/range.js

@@ -778,7 +778,8 @@ export default class Range {
 	static createFromRanges( ranges ) {
 		if ( ranges.length === 0 ) {
 			/**
-			 * At least one range has to be passed.
+			 * At least one range has to be passed to
+			 * {@link module:engine/model/range~Range.createFromRanges `Range.createFromRanges()`}.
 			 *
 			 * @error range-create-from-ranges-empty-array
 			 */

+ 6 - 15
packages/ckeditor5-engine/src/model/schema.js

@@ -274,11 +274,6 @@ export default class Schema {
 		}
 
 		if ( !!isExtending && !this.hasItem( isExtending ) ) {
-			/**
-			 * Item with specified name does not exist in schema.
-			 *
-			 * @error model-schema-no-item
-			 */
 			throw new CKEditorError( 'model-schema-no-item: Item with specified name does not exist in schema.' );
 		}
 
@@ -303,11 +298,6 @@ export default class Schema {
 	 */
 	itemExtends( childItemName, parentItemName ) {
 		if ( !this.hasItem( childItemName ) || !this.hasItem( parentItemName ) ) {
-			/**
-			 * Item with specified name does not exist in schema.
-			 *
-			 * @error model-schema-no-item
-			 */
 			throw new CKEditorError( 'model-schema-no-item: Item with specified name does not exist in schema.' );
 		}
 
@@ -470,11 +460,6 @@ export default class Schema {
 	 */
 	_getItem( itemName ) {
 		if ( !this.hasItem( itemName ) ) {
-			/**
-			 * Item with specified name does not exist in schema.
-			 *
-			 * @error model-schema-no-item
-			 */
 			throw new CKEditorError( 'model-schema-no-item: Item with specified name does not exist in schema.' );
 		}
 
@@ -759,3 +744,9 @@ function matchPaths( schema, pathToCheck, registeredPath ) {
 
 	return true;
 }
+
+/**
+ * Item with specified name does not exist in schema.
+ *
+ * @error model-schema-no-item
+ */

+ 1 - 1
packages/ckeditor5-engine/src/model/selection.js

@@ -717,7 +717,7 @@ export default class Selection {
 				/**
 				 * Trying to add a range that intersects with another range from selection.
 				 *
-				 * @error selection-range-intersects
+				 * @error model-selection-range-intersects
 				 * @param {module:engine/model/range~Range} addedRange Range that was added to the selection.
 				 * @param {module:engine/model/range~Range} intersectingRange Range from selection that intersects with `addedRange`.
 				 */

+ 2 - 2
packages/ckeditor5-engine/src/model/textproxy.js

@@ -60,7 +60,7 @@ export default class TextProxy {
 
 		if ( offsetInText < 0 || offsetInText > textNode.offsetSize ) {
 			/**
-			 * Given offsetInText value is incorrect.
+			 * Given `offsetInText` value is incorrect.
 			 *
 			 * @error model-textproxy-wrong-offsetintext
 			 */
@@ -69,7 +69,7 @@ export default class TextProxy {
 
 		if ( length < 0 || offsetInText + length > textNode.offsetSize ) {
 			/**
-			 * Given length value is incorrect.
+			 * Given `length` value is incorrect.
 			 *
 			 * @error model-textproxy-wrong-length
 			 */

+ 2 - 2
packages/ckeditor5-engine/src/model/treewalker.js

@@ -38,9 +38,9 @@ export default class TreeWalker {
 	constructor( options = {} ) {
 		if ( !options.boundaries && !options.startPosition ) {
 			/**
-			 * Neither boundaries nor starting position have been defined.
+			 * Neither boundaries nor starting position of a `TreeWalker` have been defined.
 			 *
-			 * @error tree-walker-no-start-position
+			 * @error model-tree-walker-no-start-position
 			 */
 			throw new CKEditorError( 'model-tree-walker-no-start-position: Neither boundaries nor starting position have been defined.' );
 		}

+ 4 - 4
packages/ckeditor5-engine/src/model/writer.js

@@ -82,12 +82,12 @@ export function insert( position, nodes ) {
 export function remove( range ) {
 	if ( !range.isFlat ) {
 		/**
-		 * Trying to remove a range that starts and ends in different element.
+		 * Trying to remove a range which starts and ends in different element.
 		 *
 		 * @error model-writer-remove-range-not-flat
 		 */
 		throw new CKEditorError( 'model-writer-remove-range-not-flat: ' +
-			'Trying to remove a range that starts and ends in different element.' );
+			'Trying to remove a range which starts and ends in different element.' );
 	}
 
 	const parent = range.start.parent;
@@ -116,12 +116,12 @@ export function remove( range ) {
 export function move( sourceRange, targetPosition ) {
 	if ( !sourceRange.isFlat ) {
 		/**
-		 * Trying to move a range that starts and ends in different element.
+		 * Trying to move a range which starts and ends in different element.
 		 *
 		 * @error model-writer-move-range-not-flat
 		 */
 		throw new CKEditorError( 'model-writer-move-range-not-flat: ' +
-			'Trying to move a range that starts and ends in different element.' );
+			'Trying to move a range which starts and ends in different element.' );
 	}
 
 	const nodes = this.remove( sourceRange );

+ 2 - 2
packages/ckeditor5-engine/src/view/position.js

@@ -352,7 +352,7 @@ export default class Position {
 			/**
 			 * You can not make a position after a root.
 			 *
-			 * @error position-after-root
+			 * @error view-position-after-root
 			 * @param {module:engine/view/node~Node} root
 			 */
 			throw new CKEditorError( 'view-position-after-root: You can not make position after root.', { root: item } );
@@ -377,7 +377,7 @@ export default class Position {
 			/**
 			 * You cannot make a position before a root.
 			 *
-			 * @error position-before-root
+			 * @error view-position-before-root
 			 * @param {module:engine/view/node~Node} root
 			 */
 			throw new CKEditorError( 'view-position-before-root: You can not make position before root.', { root: item } );

+ 1 - 1
packages/ckeditor5-engine/src/view/selection.js

@@ -605,7 +605,7 @@ export default class Selection {
 				/**
 				 * Trying to add a range that intersects with another range from selection.
 				 *
-				 * @error selection-range-intersects
+				 * @error view-selection-range-intersects
 				 * @param {module:engine/view/range~Range} addedRange Range that was added to the selection.
 				 * @param {module:engine/view/range~Range} intersectingRange Range from selection that intersects with `addedRange`.
 				 */

+ 1 - 1
packages/ckeditor5-engine/src/view/treewalker.js

@@ -40,7 +40,7 @@ export default class TreeWalker {
 			/**
 			 * Neither boundaries nor starting position have been defined.
 			 *
-			 * @error tree-walker-no-start-position
+			 * @error view-tree-walker-no-start-position
 			 */
 			throw new CKEditorError( 'view-tree-walker-no-start-position: Neither boundaries nor starting position have been defined.' );
 		}

+ 6 - 10
packages/ckeditor5-engine/src/view/writer.js

@@ -470,11 +470,6 @@ export function move( sourceRange, targetPosition ) {
  */
 export function wrap( range, attribute ) {
 	if ( !( attribute instanceof AttributeElement ) ) {
-		/**
-		 * Attribute element need to be instance of attribute element.
-		 *
-		 * @error view-writer-wrap-invalid-attribute
-		 */
 		throw new CKEditorError( 'view-writer-wrap-invalid-attribute' );
 	}
 
@@ -537,11 +532,6 @@ export function wrap( range, attribute ) {
  */
 export function wrapPosition( position, attribute ) {
 	if ( !( attribute instanceof AttributeElement ) ) {
-		/**
-		 * Attribute element need to be instance of attribute element.
-		 *
-		 * @error view-writer-wrap-invalid-attribute
-		 */
 		throw new CKEditorError( 'view-writer-wrap-invalid-attribute' );
 	}
 
@@ -665,6 +655,12 @@ export function rename( viewElement, newName ) {
 	return newElement;
 }
 
+/**
+ * Attribute element need to be instance of attribute element.
+ *
+ * @error view-writer-wrap-invalid-attribute
+ */
+
 // Returns first parent container of specified {@link module:engine/view/position~Position Position}.
 // Position's parent node is checked as first, then next parents are checked.
 // Note that {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.

+ 8 - 1
packages/ckeditor5-engine/tests/view/document/document.js

@@ -339,9 +339,16 @@ describe( 'Document', () => {
 
 		it( 'scrolls to the first range in selection with an offset', () => {
 			const stub = testUtils.sinon.stub( global.window, 'scrollTo' );
-			const root = viewDocument.createRoot( document.createElement( 'div' ) );
+			const root = viewDocument.createRoot( domRoot );
 			const range = ViewRange.createIn( root );
 
+			// Make sure the window will have to scroll to the domRoot.
+			Object.assign( domRoot.style, {
+				position: 'absolute',
+				top: '-1000px',
+				left: '-1000px'
+			} );
+
 			viewDocument.selection.addRange( range );
 
 			viewDocument.scrollToTheSelection();