8
0
Pārlūkot izejas kodu

Merge branch 'master' into i/7890

panr 5 gadi atpakaļ
vecāks
revīzija
808c4c427f
22 mainītis faili ar 286 papildinājumiem un 258 dzēšanām
  1. 3 2
      docs/framework/guides/contributing/testing-environment.md
  2. 1 1
      package.json
  3. 22 13
      packages/ckeditor5-engine/docs/_snippets/framework/extending-content-custom-element-converter.js
  4. 3 1
      packages/ckeditor5-engine/docs/framework/guides/deep-dive/conversion-extending-output.md
  5. 1 0
      packages/ckeditor5-engine/docs/framework/guides/deep-dive/conversion-introduction.md
  6. 2 0
      packages/ckeditor5-engine/docs/framework/guides/deep-dive/conversion-preserving-custom-content.md
  7. 49 44
      packages/ckeditor5-engine/docs/framework/guides/deep-dive/custom-element-conversion.md
  8. 6 0
      packages/ckeditor5-engine/src/conversion/downcastdispatcher.js
  9. 3 0
      packages/ckeditor5-engine/src/conversion/downcasthelpers.js
  10. 111 108
      packages/ckeditor5-engine/src/conversion/upcastdispatcher.js
  11. 3 4
      packages/ckeditor5-engine/src/model/utils/insertcontent.js
  12. 29 31
      packages/ckeditor5-engine/src/view/downcastwriter.js
  13. 3 3
      packages/ckeditor5-image/docs/features/image.md
  14. 21 21
      packages/ckeditor5-image/lang/contexts.json
  15. 0 1
      packages/ckeditor5-image/src/image/imageediting.js
  16. 2 2
      packages/ckeditor5-image/src/imageinsert/ui/imageinsertformrowview.js
  17. 8 8
      packages/ckeditor5-image/src/imageinsert/ui/imageinsertpanelview.js
  18. 2 2
      packages/ckeditor5-image/src/imageupload.js
  19. 1 1
      packages/ckeditor5-image/src/imageupload/imageuploadui.js
  20. 1 1
      packages/ckeditor5-table/src/converters/upcasttable.js
  21. 1 1
      packages/ckeditor5-table/src/tablewalker.js
  22. 14 14
      packages/ckeditor5-utils/src/collection.js

+ 3 - 2
docs/framework/guides/contributing/testing-environment.md

@@ -54,11 +54,12 @@ In order to start the manual tests server, use the `yarn run manual` task.
 
 The task accepts the following options:
 
-* `--source-map` (alias `-s`) – Whether to generate useful source maps for the code.
 * `--files` – Specifies test files to run. Accepts a package name or a glob. For example `--files=ckeditor5` will only run tests from the CKEditor 5 main package. Read more about the [rules for converting the `--files` option to a glob pattern](https://github.com/ckeditor/ckeditor5-dev/tree/master/packages/ckeditor5-dev-tests#rules-for-converting---files-option-to-glob-pattern).
-* `--additionalLanguages="ar,pl,..."` – Specifies extra languages to the [CKEditor 5 webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin). Check out the {@link features/ui-language UI language guide} to learn more.
+* `--language="pl"` – The main language build in into all test editors, passed to the [CKEditor 5 webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin).  Check out the {@link features/ui-language UI language guide} to learn more. When unspecified, `'en'` is passed to the test runner.
+* `--additionalLanguages="ar,pl,..."` – Specifies extra languages passed to the [CKEditor 5 webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin). Check out the {@link features/ui-language UI language guide} to learn more.
 * `--debug` (alias `-d`) – Allows specifying custom debug flags. For example, the `--debug engine` option uncomments the `// @if CK_DEBUG_ENGINE //` lines in the code. Note that by default `--debug` is set to `true` even if you did not specify it. This enables the base set of debug logs (`// @if CK_DEBUG //`) which should always be enabled in the testing environment. You can completely turn off the debug mode by setting the `--debug false` option.
 * `--port` – Specifies the port for the server to use. Defaults to `8125`.
+* `--identityFile="/path/to/file.js"` – Path to the file containing the license key(s) for closed–source features.
 
 It starts the server available at http://localhost:8125.
 

+ 1 - 1
package.json

@@ -79,7 +79,7 @@
     "@ckeditor/ckeditor5-comments": "^22.0.0",
     "@ckeditor/ckeditor5-dev-docs": "^23.2.0",
     "@ckeditor/ckeditor5-dev-env": "^23.2.0",
-    "@ckeditor/ckeditor5-dev-tests": "^23.2.0",
+    "@ckeditor/ckeditor5-dev-tests": "^23.3.0",
     "@ckeditor/ckeditor5-dev-utils": "^23.2.0",
     "@ckeditor/ckeditor5-dev-webpack-plugin": "^23.2.0",
     "@ckeditor/ckeditor5-export-pdf": "^1.0.0",

+ 22 - 13
packages/ckeditor5-engine/docs/_snippets/framework/extending-content-custom-element-converter.js

@@ -9,7 +9,7 @@ import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud
 
 class InfoBox {
 	constructor( editor ) {
-		// Schema definition
+		// Schema definition.
 		editor.model.schema.register( 'infoBox', {
 			allowWhere: '$block',
 			allowContentOf: '$root',
@@ -21,7 +21,7 @@ class InfoBox {
 		editor.conversion.for( 'upcast' )
 			.add( dispatcher => dispatcher.on( 'element:div', upcastConverter ) );
 
-		// The downcast conversion must be split as we need a widget in the editing pipeline.
+		// The downcast conversion must be split as you need a widget in the editing pipeline.
 		editor.conversion.for( 'editingDowncast' )
 			.add( dispatcher => dispatcher.on( 'insert:infoBox', editingDowncastConverter ) );
 		editor.conversion.for( 'dataDowncast' )
@@ -32,46 +32,51 @@ class InfoBox {
 function upcastConverter( event, data, conversionApi ) {
 	const viewInfoBox = data.viewItem;
 
-	// Detect that view element is an info-box div.
+	// Detect that a view element is an info box <div>.
 	// Otherwise, it should be handled by another converter.
 	if ( !viewInfoBox.hasClass( 'info-box' ) ) {
 		return;
 	}
 
-	// Create a model structure.
+	// Create the model structure.
 	const modelElement = conversionApi.writer.createElement( 'infoBox', {
 		infoBoxType: getTypeFromViewElement( viewInfoBox )
 	} );
 
-	// Try to safely insert element - if it returns false the element can't be safely inserted
-	// into the content, and the conversion process must stop.
+	// Try to safely insert the element into the model structure.
+	// If `safeInsert()` returns `false`, the element cannot be safely inserted
+	// into the content and the conversion process must stop.
+	// This may happen if the data that you are converting has an incorrect structure
+	// (e.g. it was copied from an external website).
 	if ( !conversionApi.safeInsert( modelElement, data.modelCursor ) ) {
 		return;
 	}
 
-	// Mark info-box div as handled by this converter.
+	// Mark the info box <div> as handled by this converter.
 	conversionApi.consumable.consume( viewInfoBox, { name: true } );
 
-	// Let's assume that the HTML structure is always the same.
+	// Let us assume that the HTML structure is always the same.
+	// Note: For full bulletproofing this converter, you should also check
+	// whether these elements are the right ones.
 	const viewInfoBoxTitle = viewInfoBox.getChild( 0 );
 	const viewInfoBoxContent = viewInfoBox.getChild( 1 );
 
-	// Mark info-box inner elements as handled by this converter.
+	// Mark info box inner elements (title and content <div>s) as handled by this converter.
 	conversionApi.consumable.consume( viewInfoBoxTitle, { name: true } );
 	conversionApi.consumable.consume( viewInfoBoxContent, { name: true } );
 
-	// Let the editor handle children of the info-box content conversion.
+	// Let the editor handle the children of <div class="info-box-content">.
 	conversionApi.convertChildren( viewInfoBoxContent, modelElement );
 
-	// Conversion requires updating result data structure properly.
+	// Finally, update the conversion's modelRange and modelCursor.
 	conversionApi.updateConversionResult( modelElement, data );
 }
 
 function editingDowncastConverter( event, data, conversionApi ) {
 	let { infoBox, infoBoxContent, infoBoxTitle } = createViewElements( data, conversionApi );
 
-	// Decorate view items as widgets.
-	infoBox = toWidget( infoBox, conversionApi.writer, { label: 'simple box widget' } );
+	// Decorate view items as a widget and widget editable area.
+	infoBox = toWidget( infoBox, conversionApi.writer, { label: 'info box widget' } );
 	infoBoxContent = toWidgetEditable( infoBoxContent, conversionApi.writer );
 
 	insertViewElements( data, conversionApi, infoBox, infoBoxTitle, infoBoxContent );
@@ -118,7 +123,11 @@ function insertViewElements( data, conversionApi, infoBox, infoBoxTitle, infoBox
 		infoBoxContent
 	);
 
+	// The default mapping between the model <infoBox> and its view representation.
 	conversionApi.mapper.bindElements( data.item, infoBox );
+	// However, since the model <infoBox> content needs to end up in the inner
+	// <div class="info-box-content">, you need to bind one with another overriding
+	// a part of the default binding.
 	conversionApi.mapper.bindElements( data.item, infoBoxContent );
 
 	conversionApi.writer.insert(

+ 3 - 1
packages/ckeditor5-engine/docs/framework/guides/deep-dive/conversion-extending-output.md

@@ -355,4 +355,6 @@ Add some CSS styles for `.my-heading` to see the customization in action:
 
 ## What's next?
 
-If you would like to read more about how to make CKEditor 5 accept more content, refer to the {@link framework/guides/deep-dive/conversion-preserving-custom-content Preserving custom content} guide.
+If you would like to read more about how to make CKEditor 5 accept more content, refer to the {@link framework/guides/deep-dive/conversion-preserving-custom-content Preserving custom content} guide.
+
+If you want to learn how to create complex view structures or how to move from {@link module:engine/conversion/conversion~Conversion two-way} or {@link module:engine/conversion/conversion~Conversion#for one-way} converters to event-based ones, refer to the {@link framework/guides/deep-dive/custom-element-conversion Custom element conversion} guide.

+ 1 - 0
packages/ckeditor5-engine/docs/framework/guides/deep-dive/conversion-introduction.md

@@ -126,3 +126,4 @@ Once you understand more about the conversion of model attributes, you can check
 
 * {@link framework/guides/deep-dive/conversion-extending-output Extending the editor output} &mdash; How to extend the output of existing CKEditor 5 features.
 * {@link framework/guides/deep-dive/conversion-preserving-custom-content Preserving custom content} &mdash; How to make CKEditor 5 accept more content.
+* {@link framework/guides/deep-dive/custom-element-conversion Custom element conversion} &mdash; How to deal with complex view structures during the model-to-view conversion.

+ 2 - 0
packages/ckeditor5-engine/docs/framework/guides/deep-dive/conversion-preserving-custom-content.md

@@ -487,3 +487,5 @@ ClassicEditor
 ## What's next?
 
 If you would like to read more about how to extend the output of existing CKEditor 5 features, refer to the {@link framework/guides/deep-dive/conversion-extending-output Extending the editor output} guide.
+
+If you want to learn how to create complex view structures or how to move from {@link module:engine/conversion/conversion~Conversion two-way} or {@link module:engine/conversion/conversion~Conversion#for one-way} converters to event-based ones, refer to the {@link framework/guides/deep-dive/custom-element-conversion Custom element conversion} guide.

+ 49 - 44
packages/ckeditor5-engine/docs/framework/guides/deep-dive/custom-element-conversion.md

@@ -8,28 +8,31 @@ order: 40
 
 There are three levels on which elements can be converted:
 
-* By using the two-way converter: {@link module:engine/conversion/conversion~Conversion#elementToElement `conversion.elementToElement()`}. It is a fully declarative API. It is the least powerful option but it is the easiest one to use.
-* By using one-way converters: for example {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `conversion.for( 'downcast' ).elementToElement()`} and {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToElement `conversion.for( 'upcast' ).elementToElement()`}. In this case, you need to define at least two converters (for upcast and downcast), but the "how" part becomes a callback, and hence you gain more control over it.
-* Finally, by using event-based converters. In this case, you need to listen to events fired by {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} and {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}. This method has the full access to every bit of logic that a converter needs to implement and therefore it can be used to write the most complex conversion methods.
+* By using the two-way converter: {@link module:engine/conversion/conversion~Conversion#elementToElement `conversion.elementToElement()`}.
+  This is a fully declarative API. It is the least powerful option but it is the easiest one to use.
+* By using one-way converters: for example {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `conversion.for( 'downcast' ).elementToElement()`} and {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToElement `conversion.for( 'upcast' ).elementToElement()`}.
+  In this case, you need to define at least two converters (for upcast and downcast), but the "how" part becomes a callback, and hence you gain more control over it.
+* Finally, by using event-based converters.
+  In this case, you need to listen to events fired by {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} and {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}. This method has full access to every bit of logic that a converter needs to implement and therefore it can be used to write the most complex conversion methods.
 
-In this guide, we will show you how to migrate from a simple two-way converter to an event-based converters as the requirements regarding the feature get more complex.
+This guide explains how to migrate from a simple two-way converter to an event-based converter as the requirements regarding the feature get more complex.
 
 ## Introduction
 
-Let's assume that content in your application contains "info boxes". As for now, it was only required to wrap part of a content in a `<div>` element that would look in the data and editing views like this:
+Let us assume that the content in your application contains "info boxes". As for now, it was only required to wrap a part of the content in a `<div>` element that would look like this in the data and editing views:
 
 ```html
 <div class="info-box">
-	<!-- any editable content -->
+	<!-- Any editable content. -->
 	<p>This is <strong>important!</strong></p>
 </div>
 ```
 
-This data is represented in the model as the following structure:
+The data is represented in the model as the following structure:
 
 ```html
 <infoBox>
-	<!-- any $block content: -->
+	<!-- Any $block content. -->
 	<paragraph><$text>This is </$text><$text bold="true">important!</$text></paragraph>
 </infoBox>
 ```
@@ -39,14 +42,14 @@ This can be easily done with the below schema and converters in a simple `InfoBo
 ```js
 class InfoBox {
 	constructor( editor ) {
-		// 1. Define infoBox as an object that can be contained any other content.
+		// 1. Define infoBox as an object that can contain any other content.
 		editor.model.schema.register( 'infoBox', {
 			allowWhere: '$block',
 			allowContentOf: '$root',
 			isObject: true
 		} );
 
-		// 2. Conversion is straight forward:
+		// 2. The conversion is straightforward:
 		editor.conversion.elementToElement( {
 			model: 'infoBox',
 			view: {
@@ -60,7 +63,7 @@ class InfoBox {
 
 ## Migrating to an event-based converter
 
-Let's now assume that the requirements have changed and there is a need for adding an additional element in the data and editing views that will display the type of the info box (warning, error, info, etc.).
+Let us now assume that the requirements have changed and there is a need for adding an additional element in the data and editing views that will display the type of the info box (warning, error, info, etc.).
 
 The new info box structure:
 
@@ -68,56 +71,56 @@ The new info box structure:
 <div class="info-box info-box-warning">
 	<div class="info-box-title">Warning</div>
 	<div class="info-box-content">
-		<!-- any editable content -->
+		<!-- Any editable content. -->
 		<p>This is <strong>important!</strong></p>
 	</div>
 </div>
 ```
 
-The "Warning" part should not be editable. It defines a type of the info box so we can store this  bit of information as an attribute of the `<infoBox>` element:
+The "Warning" part should not be editable. It defines the type of the info box so you can store this bit of information as an attribute of the `<infoBox>` element:
 
 ```html
 <infoBox infoBoxType="warning">
-	<!-- any $block content: -->
+	<!-- Any $block content. -->
 	<paragraph><$text>This is </$text><$text bold="true">important!</$text></paragraph>
 </infoBox>
 ```
 
-Let's see how to update our basic implementation to cover these requirements.
+Let us see how to update the basic implementation to cover these requirements.
 
 ### Demo
 
-Below is a demo of the editor with the example info box.
+Below is a demo of the editor with a sample info box.
 
 {@snippet framework/extending-content-custom-element-converter}
 
 ### Schema
 
-The type of the box is defined by the additional class on the main `<div>` but it is also represented as text in `<div class="info-box-title">`. All the info box content must be now placed inside `<div class="info-box-content">` instead of the main wrapper.
+The type of the box is defined by an additional class on the main `<div>` but it is also represented as text in `<div class="info-box-title">`. All the info box content must now be placed inside `<div class="info-box-content">` instead of the main wrapper.
 
-For the above requirements we can see that the model structure of the `infoBox` does not need to change much. We can still use a single element in the model. The only addition to the model is an attribute that will hold information about the info box type:
+For the above requirements you can see that the model structure of the `infoBox` does not need to change much. You can still use a single element in the model. The only addition to the model is an attribute that will store information about the info box type:
 
 ```js
 editor.model.schema.register( 'infoBox', {
 	allowWhere: '$block',
 	allowContentOf: '$root',
 	isObject: true,
-	allowAttributes: [ 'infoBoxType' ] // Added
+	allowAttributes: [ 'infoBoxType' ] // Added.
 } );
 ```
 
 ### Event-based upcast converter
 
-The conversion of the type of the box itself could be achieved by using {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `attributeToAttribute()`} (`info-box-*` CSS classes to the `infoBoxType` model attribute). However, two more changes were made to the data format that we need to handle:
+The conversion of the type of the box itself can be achieved by using {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `attributeToAttribute()`} (`info-box-*` CSS classes to the `infoBoxType` model attribute). However, two more changes were made to the data format that you need to handle:
 
-* There is the new `<div class="info-box-title">` element that should be ignored during upcast conversion as it duplicates the information conveyed by the main element's CSS class.
-* The content of the info box is now located inside another element (previously it was located directly in the main wrapper).
+* There is a new `<div class="info-box-title">` element that should be ignored during the upcast conversion as it duplicates the information conveyed by the main element's CSS class.
+* The content of the info box is now located inside another element. Previously it was located directly in the main wrapper.
 
-Neither two-way nor one-way converters can handle such conversion. Therefore, we need to use an event-based converter with the following behavior:
+Neither two-way nor one-way converters can handle such conversion. Therefore, you need to use an event-based converter with the following behavior:
 
-1. Create model `<infoBox>` element with `infoBoxType` attribute.
-1. Skip conversion of `<div class="info-box-title">` as the information about type can be obtained from the wrapper's CSS classes.
-1. Convert children of `<div class="info-box-content">` and insert them directly into `<infoBox>`.
+1. Create a model `<infoBox>` element with the `infoBoxType` attribute.
+1. Skip the conversion of `<div class="info-box-title">` as the information about type can be obtained from the wrapper's CSS classes.
+1. Convert the children of `<div class="info-box-content">` and insert them directly into `<infoBox>`.
 
 ```js
 function upcastConverter( event, data, conversionApi ) {
@@ -129,16 +132,16 @@ function upcastConverter( event, data, conversionApi ) {
 		return;
 	}
 
-	// Create a model structure.
+	// Create the model structure.
 	const modelElement = conversionApi.writer.createElement( 'infoBox', {
 		infoBoxType: getTypeFromViewElement( viewInfoBox )
 	} );
 
 	// Try to safely insert the element into the model structure.
-	// If `safeInsert()` returns `false` the element cannot be safely inserted
-	// into the content, and the conversion process must stop.
-	// This may happen if the data that we are converting has incorrect structure
-	// (e.g. was copied from an external website).
+	// If `safeInsert()` returns `false`, the element cannot be safely inserted
+	// into the content and the conversion process must stop.
+	// This may happen if the data that you are converting has an incorrect structure
+	// (e.g. it was copied from an external website).
 	if ( !conversionApi.safeInsert( modelElement, data.modelCursor ) ) {
 		return;
 	}
@@ -146,8 +149,8 @@ function upcastConverter( event, data, conversionApi ) {
 	// Mark the info box <div> as handled by this converter.
 	conversionApi.consumable.consume( viewInfoBox, { name: true } );
 
-	// Let's assume that the HTML structure is always the same.
-	// Note: for full bulletproofing this converter we should also check
+	// Let us assume that the HTML structure is always the same.
+	// Note: For full bulletproofing this converter, you should also check
 	// whether these elements are the right ones.
 	const viewInfoBoxTitle = viewInfoBox.getChild( 0 );
 	const viewInfoBoxContent = viewInfoBox.getChild( 1 );
@@ -156,14 +159,14 @@ function upcastConverter( event, data, conversionApi ) {
 	conversionApi.consumable.consume( viewInfoBoxTitle, { name: true } );
 	conversionApi.consumable.consume( viewInfoBoxContent, { name: true } );
 
-	// Let the editor handle children of <div class="info-box-content">.
+	// Let the editor handle the children of <div class="info-box-content">.
 	conversionApi.convertChildren( viewInfoBoxContent, modelElement );
 
 	// Finally, update the conversion's modelRange and modelCursor.
 	conversionApi.updateConversionResult( modelElement, data );
 }
 
-// Helper function to read the type from the view classes.
+// A helper function to read the type from the view classes.
 function getTypeFromViewElement( viewElement ) {
 	if ( viewElement.hasClass( 'info-box-info' ) ) {
 		return 'Info';
@@ -177,7 +180,7 @@ function getTypeFromViewElement( viewElement ) {
 }
 ```
 
-This upcast converter callback can now be plugged by adding a listener to the {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#element `UpcastDispatcher#element` event}. We will listen to `element:div` to ensure that the callback is called only for `<div>` elements.
+This upcast converter callback can now be plugged by adding a listener to the {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#element `UpcastDispatcher#element` event}. You will listen to `element:div` to ensure that the callback is called only for `<div>` elements.
 
 ```js
 editor.conversion.for( 'upcast' )
@@ -186,10 +189,12 @@ editor.conversion.for( 'upcast' )
 
 ### Event-based downcast converter
 
-The missing bit are the downcast converters for the editing and data pipelines. We want to use the widget system to make the info box behave like an "object". The other aspect that we need to take care of is the fact that the view structure has more elements than the model structure. In this case, we could actually use one-way converters. However, we will showcase how an event-based converter would look.
+The missing bits are the downcast converters for the editing and data pipelines.
+
+You will want to use the widget system to make the info box behave like an "object". Another aspect that you need to take care of is the fact that the view structure has more elements than the model structure. In this case, you could actually use one-way converters. However, this tutorial will showcase how an event-based converter would look.
 
 <info-box>
-	See the {@link framework/guides/tutorials/implementing-a-block-widget Implementing a block widget} to learn about the widget system.
+	See the {@link framework/guides/tutorials/implementing-a-block-widget Implementing a block widget} guide to learn about the widget system.
 </info-box>
 
 The remaining downcast converters:
@@ -248,9 +253,9 @@ function insertViewElements( data, conversionApi, infoBox, infoBoxTitle, infoBox
 
 	// The default mapping between the model <infoBox> and its view representation.
 	conversionApi.mapper.bindElements( data.item, infoBox );
-	// However, since the model <infoBox> content need to end up in the inner
-	// <div class="info-box-content"> we need to bind one with another overriding
-	// part of the default binding.
+	// However, since the model <infoBox> content needs to end up in the inner
+	// <div class="info-box-content">, you need to bind one with another overriding
+	// a part of the default binding.
 	conversionApi.mapper.bindElements( data.item, infoBoxContent );
 
 	conversionApi.writer.insert(
@@ -271,12 +276,12 @@ editor.conversion.for( 'dataDowncast' )
 
 ### Updated plugin code
 
-The updated `InfoBox` plugin that glues all this together:
+The updated `InfoBox` plugin that glues the event-based converters together:
 
 ```js
 class InfoBox {
 	constructor( editor ) {
-		// Schema definition
+		// Schema definition.
 		editor.model.schema.register( 'infoBox', {
 			allowWhere: '$block',
 			allowContentOf: '$root',
@@ -288,7 +293,7 @@ class InfoBox {
 		editor.conversion.for( 'upcast' )
 			.add( dispatcher => dispatcher.on( 'element:div', upcastConverter ) );
 
-		// The downcast conversion must be split as we need a widget in the editing pipeline.
+		// The downcast conversion must be split as you need a widget in the editing pipeline.
 		editor.conversion.for( 'editingDowncast' )
 			.add( dispatcher => dispatcher.on( 'insert:infoBox', editingDowncastConverter ) );
 		editor.conversion.for( 'dataDowncast' )

+ 6 - 0
packages/ckeditor5-engine/src/conversion/downcastdispatcher.js

@@ -75,6 +75,12 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
  * When providing custom listeners for downcast dispatcher, remember to use the provided
  * {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer} to apply changes to the view document.
  *
+ * You can read more about conversion in the following guides:
+ *
+ * * {@glink framework/guides/deep-dive/conversion/conversion-introduction Advanced conversion concepts &mdash; attributes}
+ * * {@glink framework/guides/deep-dive/conversion/conversion-extending-output Extending the editor output }
+ * * {@glink framework/guides/deep-dive/conversion/custom-element-conversion Custom element conversion}
+ *
  * An example of a custom converter for the downcast dispatcher:
  *
  *		// You will convert inserting a "paragraph" model element into the model.

+ 3 - 0
packages/ckeditor5-engine/src/conversion/downcasthelpers.js

@@ -62,6 +62,9 @@ export default class DowncastHelpers extends ConversionHelpers {
 	 * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter
 	 * to the conversion process.
 	 *
+	 * You can read more about element-to-element conversion in the
+	 * {@glink framework/guides/deep-dive/conversion/custom-element-conversion Custom element conversion} guide.
+	 *
 	 * @method #elementToElement
 	 * @param {Object} config Conversion configuration.
 	 * @param {String} config.model The name of the model element to convert.

+ 111 - 108
packages/ckeditor5-engine/src/conversion/upcastdispatcher.js

@@ -18,24 +18,24 @@ import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
 import mix from '@ckeditor/ckeditor5-utils/src/mix';
 
 /**
- * `UpcastDispatcher` is a central point of the view to model conversion, which is a process of
- * converting given {@link module:engine/view/documentfragment~DocumentFragment view document fragment} or
+ * Upcast dispatcher is a central point of the view-to-model conversion, which is a process of
+ * converting a given {@link module:engine/view/documentfragment~DocumentFragment view document fragment} or
  * {@link module:engine/view/element~Element view element} into a correct model structure.
  *
  * During the conversion process, the dispatcher fires events for all {@link module:engine/view/node~Node view nodes}
  * from the converted view document fragment.
- * Special callbacks called "converters" should listen to these events in order to convert these view nodes.
+ * Special callbacks called "converters" should listen to these events in order to convert the view nodes.
  *
  * The second parameter of the callback is the `data` object with the following properties:
  *
- * * `data.viewItem` contains {@link module:engine/view/node~Node view node} or
+ * * `data.viewItem` contains a {@link module:engine/view/node~Node view node} or a
  * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}
  * that is converted at the moment and might be handled by the callback.
  * * `data.modelRange` is used to point to the result
  * of the current conversion (e.g. the element that is being inserted)
- * and is always a {@link module:engine/model/range~Range} when the succeeds.
+ * and is always a {@link module:engine/model/range~Range} when the conversion succeeds.
  * * `data.modelCursor` is a {@link module:engine/model/position~Position position} on which the converter should insert
- * newly created items.
+ * the newly created items.
  *
  * The third parameter of the callback is an instance of {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi}
  * which provides additional tools for converters.
@@ -47,11 +47,11 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
  *
  * Examples of event-based converters:
  *
- *		// Converter for links (<a>).
+ *		// A converter for links (<a>).
  *		editor.data.upcastDispatcher.on( 'element:a', ( evt, data, conversionApi ) => {
  *			if ( conversionApi.consumable.consume( data.viewItem, { name: true, attributes: [ 'href' ] } ) ) {
- *				// <a> element is inline and is represented by an attribute in the model.
- *				// This is why we need to convert only children.
+ *				// The <a> element is inline and is represented by an attribute in the model.
+ *				// This is why you need to convert only children.
  *				const { modelRange } = conversionApi.convertChildren( data.viewItem, data.modelCursor );
  *
  *				for ( let item of modelRange.getItems() ) {
@@ -62,9 +62,9 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
  *			}
  *		} );
  *
- *		// Convert <p>'s font-size style.
+ *		// Convert <p> element's font-size style.
  *		// Note: You should use a low-priority observer in order to ensure that
- *		// it's executed after the element-to-element converter.
+ *		// it is executed after the element-to-element converter.
  *		editor.data.upcastDispatcher.on( 'element:p', ( evt, data, conversionApi ) => {
  *			const { consumable, schema, writer } = conversionApi;
  *
@@ -74,7 +74,7 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
  *
  *			const fontSize = data.viewItem.getStyle( 'font-size' );
  *
- *			// Don't go for the model element after data.modelCursor because it might happen
+ *			// Do not go for the model element after data.modelCursor because it might happen
  *			// that a single view element was converted to multiple model elements. Get all of them.
  *			for ( const item of data.modelRange.getItems( { shallow: true } ) ) {
  *				if ( schema.checkAttribute( item, 'fontSize' ) ) {
@@ -85,27 +85,27 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
  *
  *		// Convert all elements which have no custom converter into a paragraph (autoparagraphing).
  *		editor.data.upcastDispatcher.on( 'element', ( evt, data, conversionApi ) => {
- *			// Check if element can be converted.
+ *			// Check if an element can be converted.
  *			if ( !conversionApi.consumable.test( data.viewItem, { name: data.viewItem.name } ) ) {
- *				// When element is already consumed by higher priority converters then do nothing.
+ *				// When an element is already consumed by higher priority converters, do nothing.
  *				return;
  *			}
  *
  *			const paragraph = conversionApi.writer.createElement( 'paragraph' );
  *
- *			// Try to safely insert paragraph at model cursor - it will find an allowed parent for a current element.
+ *			// Try to safely insert a paragraph at the model cursor - it will find an allowed parent for the current element.
  *			if ( !conversionApi.safeInsert( paragraph, data.modelCursor ) ) {
- *				// When element was not inserted it means that we can't insert paragraph at this position.
+ *				// When an element was not inserted, it means that you cannot insert a paragraph at this position.
  *				return;
  *			}
  *
  *			// Consume the inserted element.
  *			conversionApi.consumable.consume( data.viewItem, { name: data.viewItem.name } ) );
  *
- *			// Convert children to paragraph.
+ *			// Convert the children to a paragraph.
  *			const { modelRange } = conversionApi.convertChildren( data.viewItem,  paragraph ) );
  *
- *			// Update `modelRange` and `modelCursor` in a `data` as a conversion result.
+ *			// Update `modelRange` and `modelCursor` in the `data` as a conversion result.
  *			conversionApi.updateConversionResult( paragraph, data );
  *		}, { priority: 'low' } );
  *
@@ -117,17 +117,17 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
  */
 export default class UpcastDispatcher {
 	/**
-	 * Creates a `UpcastDispatcher` that operates using passed API.
+	 * Creates an upcast dispatcher that operates using the passed API.
 	 *
 	 * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi
-	 * @param {Object} [conversionApi] Additional properties for interface that will be passed to events fired
-	 * by `UpcastDispatcher`.
+	 * @param {Object} [conversionApi] Additional properties for an interface that will be passed to events fired
+	 * by the upcast dispatcher.
 	 */
 	constructor( conversionApi = {} ) {
 		/**
-		 * List of the elements that were created during splitting.
+		 * The list of elements that were created during splitting.
 		 *
-		 * After conversion process the list is cleared.
+		 * After the conversion process the list is cleared.
 		 *
 		 * @private
 		 * @type {Map.<module:engine/model/element~Element,Array.<module:engine/model/element~Element>>}
@@ -135,9 +135,9 @@ export default class UpcastDispatcher {
 		this._splitParts = new Map();
 
 		/**
-		 * List of cursor parent elements that were created during splitting.
+		 * The list of cursor parent elements that were created during splitting.
 		 *
-		 * After conversion process the list is cleared.
+		 * After the conversion process the list is cleared.
 		 *
 		 * @private
 		 * @type {Map.<module:engine/model/element~Element,Array.<module:engine/model/element~Element>>}
@@ -145,8 +145,8 @@ export default class UpcastDispatcher {
 		this._cursorParents = new Map();
 
 		/**
-		 * Position in the temporary structure where the converted content is inserted. The structure reflect the context of
-		 * the target position where the content will be inserted. This property is build based on the context parameter of the
+		 * The position in the temporary structure where the converted content is inserted. The structure reflects the context of
+		 * the target position where the content will be inserted. This property is built based on the context parameter of the
 		 * convert method.
 		 *
 		 * @private
@@ -155,7 +155,7 @@ export default class UpcastDispatcher {
 		this._modelCursor = null;
 
 		/**
-		 * Interface passed by dispatcher to the events callbacks.
+		 * An interface passed by the dispatcher to the event callbacks.
 		 *
 		 * @member {module:engine/conversion/upcastdispatcher~UpcastConversionApi}
 		 */
@@ -179,11 +179,11 @@ export default class UpcastDispatcher {
 	 * @fires text
 	 * @fires documentFragment
 	 * @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/element~Element} viewItem
-	 * Part of the view to be converted.
-	 * @param {module:engine/model/writer~Writer} writer Instance of model writer.
+	 * The part of the view to be converted.
+	 * @param {module:engine/model/writer~Writer} writer An instance of the model writer.
 	 * @param {module:engine/model/schema~SchemaContextDefinition} [context=['$root']] Elements will be converted according to this context.
-	 * @returns {module:engine/model/documentfragment~DocumentFragment} Model data that is a result of the conversion process
-	 * wrapped in `DocumentFragment`. Converted marker elements will be set as that document fragment's
+	 * @returns {module:engine/model/documentfragment~DocumentFragment} Model data that is the result of the conversion process
+	 * wrapped in `DocumentFragment`. Converted marker elements will be set as the document fragment's
 	 * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.
 	 */
 	convert( viewItem, writer, context = [ '$root' ] ) {
@@ -419,9 +419,9 @@ export default class UpcastDispatcher {
 	}
 
 	/**
-	 * Registers that `splitPart` element is a split part of the `originalPart` element.
+	 * Registers that a `splitPart` element is a split part of the `originalPart` element.
 	 *
-	 * Data set by this method is used by {@link #_getSplitParts} and {@link #_removeEmptyElements}.
+	 * The data set by this method is used by {@link #_getSplitParts} and {@link #_removeEmptyElements}.
 	 *
 	 * @private
 	 * @param {module:engine/model/element~Element} originalPart
@@ -480,36 +480,37 @@ export default class UpcastDispatcher {
 	}
 
 	/**
-	 * Fired before the first conversion event, at the beginning of upcast (view to model conversion) process.
+	 * Fired before the first conversion event, at the beginning of the upcast (view-to-model conversion) process.
 	 *
 	 * @event viewCleanup
 	 * @param {module:engine/view/documentfragment~DocumentFragment|module:engine/view/element~Element}
-	 * viewItem Part of the view to be converted.
+	 * viewItem A part of the view to be converted.
 	 */
 
 	/**
-	 * Fired when {@link module:engine/view/element~Element} is converted.
+	 * Fired when an {@link module:engine/view/element~Element} is converted.
 	 *
-	 * `element` is a namespace event for a class of events. Names of actually called events follow this pattern:
-	 * `element:<elementName>` where `elementName` is the name of converted element. This way listeners may listen to
-	 * all elements conversion or to conversion of specific elements.
+	 * `element` is a namespace event for a class of events. Names of actually called events follow the pattern of
+	 * `element:<elementName>` where `elementName` is the name of the converted element. This way listeners may listen to
+	 * a conversion of all or just specific elements.
 	 *
 	 * @event element
-	 * @param {module:engine/conversion/upcastdispatcher~UpcastConversionData} data Conversion data. Keep in mind that this object is shared
-	 * by reference between all callbacks that will be called. This means that callbacks can override values if needed, and those values
-	 * will be available in other callbacks.
-	 * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion utilities to be used by callback.
+	 * @param {module:engine/conversion/upcastdispatcher~UpcastConversionData} data The conversion data. Keep in mind that this object is
+	 * shared by reference between all callbacks that will be called. This means that callbacks can override values if needed, and these
+	 * values will be available in other callbacks.
+	 * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion utilities to be used by the
+	 * callback.
 	 */
 
 	/**
-	 * Fired when {@link module:engine/view/text~Text} is converted.
+	 * Fired when a {@link module:engine/view/text~Text} is converted.
 	 *
 	 * @event text
 	 * @see #event:element
 	 */
 
 	/**
-	 * Fired when {@link module:engine/view/documentfragment~DocumentFragment} is converted.
+	 * Fired when a {@link module:engine/view/documentfragment~DocumentFragment} is converted.
 	 *
 	 * @event documentFragment
 	 * @see #event:element
@@ -582,54 +583,55 @@ function createContextTree( contextDefinition, writer ) {
 }
 
 /**
- * A set of conversion utils available as the third parameter of
+ * A set of conversion utilities available as the third parameter of the
  * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher upcast dispatcher}'s events.
  *
  * @interface module:engine/conversion/upcastdispatcher~UpcastConversionApi
  */
 
 /**
- * Starts conversion of given item by firing an appropriate event.
+ * Starts the conversion of a given item by firing an appropriate event.
  *
- * Every fired event is passed (as first parameter) an object with `modelRange` property. Every event may set and/or
- * modify that property. When all callbacks are done, the final value of `modelRange` property is returned by this method.
- * The `modelRange` must be {@link module:engine/model/range~Range model range} or `null` (as set by default).
+ * Every fired event is passed (as the first parameter) an object with the `modelRange` property. Every event may set and/or
+ * modify that property. When all callbacks are done, the final value of the `modelRange` property is returned by this method.
+ * The `modelRange` must be a {@link module:engine/model/range~Range model range} or `null` (as set by default).
  *
  * @method #convertItem
  * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element
  * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:text
  * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:documentFragment
  * @param {module:engine/view/item~Item} viewItem Item to convert.
- * @param {module:engine/model/position~Position} modelCursor Position of conversion.
- * @returns {Object} result Conversion result.
- * @returns {module:engine/model/range~Range|null} result.modelRange Model range containing result of item conversion,
- * created and modified by callbacks attached to fired event, or `null` if the conversion result was incorrect.
- * @returns {module:engine/model/position~Position} result.modelCursor Position where conversion should be continued.
+ * @param {module:engine/model/position~Position} modelCursor The conversion position.
+ * @returns {Object} result The conversion result.
+ * @returns {module:engine/model/range~Range|null} result.modelRange The model range containing the result of the item conversion,
+ * created and modified by callbacks attached to the fired event, or `null` if the conversion result was incorrect.
+ * @returns {module:engine/model/position~Position} result.modelCursor The position where the conversion should be continued.
  */
 
 /**
- * Starts conversion of all children of given item by firing appropriate events for all those children.
+ * Starts the conversion of all children of a given item by firing appropriate events for all the children.
  *
  * @method #convertChildren
  * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element
  * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:text
  * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:documentFragment
- * @param {module:engine/view/item~Item} viewItem Element which children should be converted.
- * @param {module:engine/model/position~Position|module:engine/model/element~Element} positionOrElement Position or element of conversion.
- * @returns {Object} result Conversion result.
- * @returns {module:engine/model/range~Range} result.modelRange Model range containing results of conversion of all children of given item.
- * When no children was converted then range is collapsed.
- * @returns {module:engine/model/position~Position} result.modelCursor Position where conversion should be continued.
+ * @param {module:engine/view/item~Item} viewItem An element whose children should be converted.
+ * @param {module:engine/model/position~Position|module:engine/model/element~Element} positionOrElement A position or an element of
+ * the conversion.
+ * @returns {Object} result The conversion result.
+ * @returns {module:engine/model/range~Range} result.modelRange The model range containing the results of the conversion of all children
+ * of the given item. When no child was converted, the range is collapsed.
+ * @returns {module:engine/model/position~Position} result.modelCursor The position where the conversion should be continued.
  */
 
 /**
- * Safely inserts an element to the document checking {@link module:engine/model/schema~Schema schema} to find allowed parent for
- * an element that we are going to insert starting from given position. If current parent does not allow to insert element
- * but one of the ancestors does then split nodes to allowed parent.
+ * Safely inserts an element to the document, checking the {@link module:engine/model/schema~Schema schema} to find an allowed parent for
+ * an element that you are going to insert, starting from the given position. If the current parent does not allow to insert the element
+ * but one of the ancestors does, then splits the nodes to allowed parent.
  *
- * If schema allows to insert node in given position, nothing is split.
+ * If the schema allows to insert the node in a given position, nothing is split.
  *
- * If it was not possible to find allowed parent, `false` is returned, nothing is split.
+ * If it was not possible to find an allowed parent, `false` is returned and nothing is split.
  *
  * Otherwise, ancestors are split.
  *
@@ -649,22 +651,22 @@ function createContextTree( contextDefinition, writer ) {
  *			return;
  *		}
  *
- * The split result is saved and {@link #updateConversionResult} should be used to update
+ * The split result is saved and {@link #updateConversionResult} should be used to update the
  * {@link module:engine/conversion/upcastdispatcher~UpcastConversionData conversion data}.
  *
  * @method #safeInsert
- * @param {module:engine/model/node~Node} node Node to insert.
- * @param {module:engine/model/position~Position} position Position on which element is going to be inserted.
- * @returns {Boolean} Split result. If it was not possible to find allowed position `false` is returned.
+ * @param {module:engine/model/node~Node} node The node to insert.
+ * @param {module:engine/model/position~Position} position The position where an element is going to be inserted.
+ * @returns {Boolean} The split result. If it was not possible to find an allowed position, `false` is returned.
  */
 
 /**
- * Updates the conversion result and sets proper {@link module:engine/conversion/upcastdispatcher~UpcastConversionData#modelRange} and
- * next {@link module:engine/conversion/upcastdispatcher~UpcastConversionData#modelCursor} after the conversion.
- * Used together with {@link #safeInsert} enables you to easily convert elements without worrying if the node was split
- * during its children conversion.
+ * Updates the conversion result and sets a proper {@link module:engine/conversion/upcastdispatcher~UpcastConversionData#modelRange} and
+ * the next {@link module:engine/conversion/upcastdispatcher~UpcastConversionData#modelCursor} after the conversion.
+ * Used together with {@link #safeInsert}, it enables you to easily convert elements without worrying if the node was split
+ * during the conversion of its children.
  *
- * Example of a usage in a converter code:
+ * A usage example in converter code:
  *
  *		const myElement = conversionApi.writer.createElement( 'myElement' );
  *
@@ -680,19 +682,19 @@ function createContextTree( contextDefinition, writer ) {
  * @method #updateConversionResult
  * @param {module:engine/model/element~Element} element
  * @param {module:engine/conversion/upcastdispatcher~UpcastConversionData} data Conversion data.
- * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion utilities to be used by callback.
+ * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion utilities to be used by the callback.
  */
 
 /**
- * Checks {@link module:engine/model/schema~Schema schema} to find allowed parent for element that we are going to insert
- * starting from given position. If current parent does not allow to insert element but one of the ancestors does then
- * split nodes to allowed parent.
+ * Checks the {@link module:engine/model/schema~Schema schema} to find an allowed parent for an element that is going to be inserted
+ * starting from the given position. If the current parent does not allow inserting an element but one of the ancestors does, the method
+ * splits nodes to allowed parent.
  *
- * If schema allows to insert node in given position, nothing is split and object with that position is returned.
+ * If the schema allows inserting the node in the given position, nothing is split and an object with that position is returned.
  *
- * If it was not possible to find allowed parent, `null` is returned, nothing is split.
+ * If it was not possible to find an allowed parent, `null` is returned and nothing is split.
  *
- * Otherwise, ancestors are split and object with position and the copy of the split element is returned.
+ * Otherwise, ancestors are split and an object with a position and the copy of the split element is returned.
  *
  * For instance, if `<image>` is not allowed in `<paragraph>` but is allowed in `$root`:
  *
@@ -702,23 +704,23 @@ function createContextTree( contextDefinition, writer ) {
  *
  *		<paragraph>foo</paragraph>[]<paragraph>bar</paragraph>
  *
- * In the sample above position between `<paragraph>` elements will be returned as `position` and the second `paragraph`
+ * In the example above, the position between `<paragraph>` elements will be returned as `position` and the second `paragraph`
  * as `cursorParent`.
  *
  * **Note:** This is an advanced method. For most cases {@link #safeInsert} and {@link #updateConversionResult} should be used.
  *
  * @method #splitToAllowedParent
- * @param {module:engine/model/position~Position} position Position on which element is going to be inserted.
- * @param {module:engine/model/node~Node} node Node to insert.
- * @returns {Object|null} Split result. If it was not possible to find allowed position `null` is returned.
- * @returns {module:engine/model/position~Position} position between split elements.
- * @returns {module:engine/model/element~Element} [cursorParent] Element inside which cursor should be placed to
- * continue conversion. When element is not defined it means that there was no split.
+ * @param {module:engine/model/position~Position} position The position where the element is going to be inserted.
+ * @param {module:engine/model/node~Node} node The node to insert.
+ * @returns {Object|null} The split result. If it was not possible to find an allowed position, `null` is returned.
+ * @returns {module:engine/model/position~Position} The position between split elements.
+ * @returns {module:engine/model/element~Element} [cursorParent] The element inside which the cursor should be placed to
+ * continue the conversion. When the element is not defined it means that there was no split.
  */
 
 /**
- * Returns all the split parts of given `element` that were created during upcasting through using {@link #splitToAllowedParent}.
- * It enables you to easily track those elements and continue processing them after they are split during their children conversion.
+ * Returns all the split parts of the given `element` that were created during upcasting through using {@link #splitToAllowedParent}.
+ * It enables you to easily track these elements and continue processing them after they are split during the conversion of their children.
  *
  *		<paragraph>Foo<image />bar<image />baz</paragraph> ->
  *		<paragraph>Foo</paragraph><image /><paragraph>bar</paragraph><image /><paragraph>baz</paragraph>
@@ -726,9 +728,9 @@ function createContextTree( contextDefinition, writer ) {
  * For a reference to any of above paragraphs, the function will return all three paragraphs (the original element included),
  * sorted in the order of their creation (the original element is the first one).
  *
- * If given `element` was not split, an array with single element is returned.
+ * If the given `element` was not split, an array with a single element is returned.
  *
- * Example of a usage in a converter code:
+ * A usage example in the converter code:
  *
  *		const myElement = conversionApi.writer.createElement( 'myElement' );
  *
@@ -747,9 +749,9 @@ function createContextTree( contextDefinition, writer ) {
  *		// Setting `data.modelCursor` to continue after the last split element:
  *		data.modelCursor = conversionApi.writer.createPositionAfter( lastSplitPart );
  *
- * **Tip:** if you are unable to get a reference to the original element (for example because the code is split into multiple converters
- * or even classes) but it was already converted, you might want to check first element in `data.modelRange`. This is a common situation
- * if an attribute converter is separated from an element converter.
+ * **Tip:** If you are unable to get a reference to the original element (for example because the code is split into multiple converters
+ * or even classes) but it has already been converted, you may want to check the first element in `data.modelRange`. This is a common
+ * situation if an attribute converter is separated from an element converter.
  *
  * **Note:** This is an advanced method. For most cases {@link #safeInsert} and {@link #updateConversionResult} should be used.
  *
@@ -759,18 +761,19 @@ function createContextTree( contextDefinition, writer ) {
  */
 
 /**
- * Stores information about what parts of processed view item are still waiting to be handled. After a piece of view item
- * was converted, appropriate consumable value should be {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consumed}.
+ * Stores information about what parts of the processed view item are still waiting to be handled. After a piece of view item
+ * was converted, an appropriate consumable value should be
+ * {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consumed}.
  *
  * @member {module:engine/conversion/viewconsumable~ViewConsumable} #consumable
  */
 
 /**
- * Custom data stored by converters for conversion process. Custom properties of this object can be defined and use to
+ * Custom data stored by converters for the conversion process. Custom properties of this object can be defined and use to
  * pass parameters between converters.
  *
- * The difference between this property and `data` parameter of
- * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element} is that `data` parameters allows you
+ * The difference between this property and the `data` parameter of
+ * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element} is that the `data` parameters allow you
  * to pass parameters within a single event and `store` within the whole conversion.
  *
  * @member {Object} #store
@@ -783,7 +786,7 @@ function createContextTree( contextDefinition, writer ) {
  */
 
 /**
- * The {@link module:engine/model/writer~Writer} instance used to manipulate data during conversion.
+ * The {@link module:engine/model/writer~Writer} instance used to manipulate the data during conversion.
  *
  * @member {module:engine/model/writer~Writer} #writer
  */
@@ -792,13 +795,13 @@ function createContextTree( contextDefinition, writer ) {
  * Conversion data.
  *
  * **Note:** Keep in mind that this object is shared by reference between all conversion callbacks that will be called.
- * This means that callbacks can override values if needed, and those values will be available in other callbacks.
+ * This means that callbacks can override values if needed, and these values will be available in other callbacks.
  *
  * @typedef {Object} module:engine/conversion/upcastdispatcher~UpcastConversionData
  *
- * @property {module:engine/view/item~Item} viewItem Converted item.
- * @property {module:engine/model/position~Position} modelCursor Position where a converter should start changes.
+ * @property {module:engine/view/item~Item} viewItem The converted item.
+ * @property {module:engine/model/position~Position} modelCursor The position where the converter should start changes.
  * Change this value for the next converter to tell where the conversion should continue.
  * @property {module:engine/model/range~Range} [modelRange] The current state of conversion result. Every change to
- * converted element should be reflected by setting or modifying this property.
+ * the converted element should be reflected by setting or modifying this property.
  */

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

@@ -443,12 +443,11 @@ class Insertion {
 				// At this point the insertion position should be after the node we'll merge. If it isn't,
 				// it should need to be secured as in the left merge case.
 				/**
-				 * An internal error occurred during merging inserted content with its siblings.
-				 * The insertion position should equal to the merge position.
+				 * An internal error occurred when merging inserted content with its siblings.
+				 * The insertion position should equal the merge position.
 				 *
 				 * If you encountered this error, report it back to the CKEditor 5 team
-				 * with as many details regarding the content being inserted and the insertion position
-				 * as possible.
+				 * with as many details as possible regarding the content being inserted and the insertion position.
 				 *
 				 * @error insertcontent-invalid-insertion-position
 				 */

+ 29 - 31
packages/ckeditor5-engine/src/view/downcastwriter.js

@@ -427,7 +427,7 @@ export default class DowncastWriter {
 	}
 
 	/**
-	 * Breaks attribute elements at provided position or at boundaries of a provided range. It breaks attribute elements
+	 * Breaks attribute elements at the provided position or at the boundaries of a provided range. It breaks attribute elements
 	 * up to their first ancestor that is a container element.
 	 *
 	 * In following examples `<p>` is a container, `<b>` and `<u>` are attribute elements:
@@ -439,31 +439,29 @@ export default class DowncastWriter {
 	 *
 	 * **Note:** {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.
 	 *
-	 * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes} and
-	 * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer} is that `breakAttributes` breaks all
-	 * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of given `position`,
+	 * **Note:** The difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes()} and
+	 * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer()} is that `breakAttributes()` breaks all
+	 * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of a given `position`,
 	 * up to the first encountered {@link module:engine/view/containerelement~ContainerElement container element}.
-	 * `breakContainer` assumes that given `position` is directly in container element and breaks that container element.
+	 * `breakContainer()` assumes that a given `position` is directly in the container element and breaks that container element.
 	 *
-	 * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container`
-	 * when {@link module:engine/view/range~Range#start start}
+	 * Throws the `view-writer-invalid-range-container` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}
+	 * when the {@link module:engine/view/range~Range#start start}
 	 * and {@link module:engine/view/range~Range#end end} positions of a passed range are not placed inside same parent container.
 	 *
-	 * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-empty-element`
-	 * when trying to break attributes
-	 * inside {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.
+	 * Throws the `view-writer-cannot-break-empty-element` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}
+	 * when trying to break attributes inside an {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.
 	 *
-	 * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-ui-element`
-	 * when trying to break attributes
-	 * inside {@link module:engine/view/uielement~UIElement UIElement}.
+	 * Throws the `view-writer-cannot-break-ui-element` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}
+	 * when trying to break attributes inside a {@link module:engine/view/uielement~UIElement UIElement}.
 	 *
 	 * @see module:engine/view/attributeelement~AttributeElement
 	 * @see module:engine/view/containerelement~ContainerElement
 	 * @see module:engine/view/downcastwriter~DowncastWriter#breakContainer
-	 * @param {module:engine/view/position~Position|module:engine/view/range~Range} positionOrRange Position where
+	 * @param {module:engine/view/position~Position|module:engine/view/range~Range} positionOrRange The position where
 	 * to break attribute elements.
-	 * @returns {module:engine/view/position~Position|module:engine/view/range~Range} New position or range, after breaking the attribute
-	 * elements.
+	 * @returns {module:engine/view/position~Position|module:engine/view/range~Range} The new position or range, after breaking the
+	 * attribute elements.
 	 */
 	breakAttributes( positionOrRange ) {
 		if ( positionOrRange instanceof Position ) {
@@ -474,27 +472,27 @@ export default class DowncastWriter {
 	}
 
 	/**
-	 * Breaks {@link module:engine/view/containerelement~ContainerElement container view element} into two, at the given position. Position
-	 * has to be directly inside container element and cannot be in root. Does not break if position is at the beginning
-	 * or at the end of it's parent element.
+	 * Breaks a {@link module:engine/view/containerelement~ContainerElement container view element} into two, at the given position.
+	 * The position has to be directly inside the container element and cannot be in the root. It does not break the conrainer view element
+	 * if the position is at the beginning or at the end of its parent element.
 	 *
 	 *		<p>foo^bar</p> -> <p>foo</p><p>bar</p>
 	 *		<div><p>foo</p>^<p>bar</p></div> -> <div><p>foo</p></div><div><p>bar</p></div>
 	 *		<p>^foobar</p> -> ^<p>foobar</p>
 	 *		<p>foobar^</p> -> <p>foobar</p>^
 	 *
-	 * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes} and
-	 * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer} is that `breakAttributes` breaks all
-	 * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of given `position`,
+	 * **Note:** The difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes()} and
+	 * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer()} is that `breakAttributes()` breaks all
+	 * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of a given `position`,
 	 * up to the first encountered {@link module:engine/view/containerelement~ContainerElement container element}.
-	 * `breakContainer` assumes that given `position` is directly in container element and breaks that container element.
+	 * `breakContainer()` assumes that the given `position` is directly in the container element and breaks that container element.
 	 *
 	 * @see module:engine/view/attributeelement~AttributeElement
 	 * @see module:engine/view/containerelement~ContainerElement
 	 * @see module:engine/view/downcastwriter~DowncastWriter#breakAttributes
-	 * @param {module:engine/view/position~Position} position Position where to break element.
-	 * @returns {module:engine/view/position~Position} Position between broken elements. If element has not been broken,
-	 * the returned position is placed either before it or after it.
+	 * @param {module:engine/view/position~Position} position The position where to break the element.
+	 * @returns {module:engine/view/position~Position} The position between broken elements. If an element has not been broken,
+	 * the returned position is placed either before or after it.
 	 */
 	breakContainer( position ) {
 		const element = position.parent;
@@ -517,7 +515,7 @@ export default class DowncastWriter {
 			 *
 			 * @error view-writer-break-root
 			 */
-			throw new CKEditorError( 'view-writer-break-root: Trying to break root element.', this.document );
+			throw new CKEditorError( 'view-writer-break-root: Trying to break a root element.', this.document );
 		}
 
 		if ( position.isAtStart ) {
@@ -653,7 +651,7 @@ export default class DowncastWriter {
 	}
 
 	/**
-	 * Insert node or nodes at specified position. Takes care about breaking attributes before insertion
+	 * Inserts a node or nodes at specified position. Takes care about breaking attributes before insertion
 	 * and merging them afterwards.
 	 *
 	 * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert
@@ -1927,7 +1925,7 @@ function validateNodesToInsert( nodes, errorContext ) {
 	for ( const node of nodes ) {
 		if ( !validNodesToInsert.some( ( validNode => node instanceof validNode ) ) ) { // eslint-disable-line no-use-before-define
 			/**
-			 * One of the nodes to be inserted is of invalid type.
+			 * One of the nodes to be inserted is of an invalid type.
 			 *
 			 * Nodes to be inserted with {@link module:engine/view/downcastwriter~DowncastWriter#insert `DowncastWriter#insert()`} should be
 			 * of the following types:
@@ -1942,7 +1940,7 @@ function validateNodesToInsert( nodes, errorContext ) {
 			 * @error view-writer-insert-invalid-node-type
 			 */
 			throw new CKEditorError(
-				'view-writer-insert-invalid-node-type: One of the nodes to be inserted is of invalid type.',
+				'view-writer-insert-invalid-node-type: One of the nodes to be inserted is of an invalid type.',
 				errorContext
 			);
 		}
@@ -1985,7 +1983,7 @@ function validateRangeContainer( range, errorContext ) {
 		 * {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#clean()`},
 		 * {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#wrap()`},
 		 * {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#unwrap()`} need to be called
-		 * on a range that have its start and end positions located in the same container element. Both positions can be
+		 * on a range that has its start and end positions located in the same container element. Both positions can be
 		 * nested within other elements (e.g. an attribute element) but the closest container ancestor must be the same.
 		 *
 		 * @error view-writer-invalid-range-container

+ 3 - 3
packages/ckeditor5-image/docs/features/image.md

@@ -84,9 +84,9 @@ See the {@link features/image-upload Image upload} guide.
 
 ## Inserting images via source URL
 
-Besides the ability to insert images by uploading them directly from your disk or via CKFinder, you can also configure the editor to allow inserting images via source URL.
+Besides the ability to insert images by uploading them directly from your disk or via CKFinder, you can also configure CKEditor 5 to allow inserting images via source URL.
 
-In order to enable this option configure `image.upload.panel.items` like below:
+In order to enable this option, configure {@link module:image/imageupload~ImageUploadPanelConfig#items `image.upload.panel.items`} like below:
 
 ```js
 ClassicEditor
@@ -103,7 +103,7 @@ ClassicEditor
 	} )
 ```
 
-This will extend the standalone **Insert image** button in the toolbar by adding the dropdown panel with the new feature (click the arrow next to the button). To see how it works, please take a look at the demo below:
+This will extend the standalone **Insert image** button in the toolbar by adding a dropdown panel with the new feature. To open the panel and add the image URL, click the arrow next to the image button. Check the demo below to insert a new image via URL or update an existing image by selecting it, opening the dropdown panel and pasting a new URL.
 
 {@snippet features/image-insert-via-url}
 

+ 21 - 21
packages/ckeditor5-image/lang/contexts.json

@@ -1,24 +1,24 @@
 {
-	"image widget": "Label for the image widget.",
-	"Side image": "Label for the Side image option.",
-	"Full size image": "Label for the Full size image option.",
-	"Left aligned image": "Label for the Left aligned image option",
-	"Centered image": "Label for the Centered image option",
-	"Right aligned image": "Label for the Right aligned image option",
-	"Change image text alternative": "Label for the Change image text alternative button.",
-	"Text alternative": "Label for the image text alternative input.",
-	"Enter image caption": "Placeholder text for image caption displayed when caption is empty.",
-	"Insert image": "Label for the insert image toolbar button.",
-	"Upload failed": "Title of the notification displayed when upload fails.",
+	"image widget": "The label for the image widget.",
+	"Side image": "The label for the Side image option.",
+	"Full size image": "The label for the Full size image option.",
+	"Left aligned image": "The label for the Left aligned image option.",
+	"Centered image": "The label for the Centered image option.",
+	"Right aligned image": "The label for the Right aligned image option.",
+	"Change image text alternative": "The label for the Change image text alternative button.",
+	"Text alternative": "The label for the image text alternative input.",
+	"Enter image caption": "The placeholder text for the image caption displayed when the caption is empty.",
+	"Insert image": "The label for the insert image toolbar button.",
+	"Upload failed": "The title of the notification displayed when upload fails.",
 	"Image toolbar": "The label used by assistive technologies describing an image toolbar attached to an image widget.",
-	"Resize image": "The label used for the dropdown in the image toolbar containing defined resize options",
-	"Resize image to %0": "The label used for the standalone resize options buttons in the image toolbar",
-	"Resize image to the original size": "The accessibility label of the standalone image resize reset option button in the image toolbar for the screen readers",
-	"Original": "Default label for the resize option that resets the size of the image.",
-	"Image resize list": "The accessibility label of the image resize dropdown list for the screen readers.",
-	"Insert": "The label of submit form button if image src URL input has no value",
-	"Update": "The label of submit form button if image src URL input has value",
-	"Insert image via URL": "The input label for the Insert image via URL form",
-	"Update image URL": "The alternative input label for the Insert image via URL form",
-	"Paste the image source URL.": "The tip label below the Insert image via URL form"
+	"Resize image": "The label used for the dropdown in the image toolbar containing defined resize options.",
+	"Resize image to %0": "The label used for the standalone resize options buttons in the image toolbar.",
+	"Resize image to the original size": "The accessibility label of the standalone image resize reset option button in the image toolbar for screen readers.",
+	"Original": "The default label for the resize option that resets the size of the image.",
+	"Image resize list": "The accessibility label of the image resize dropdown for screen readers.",
+	"Insert": "The label of the form submit button if the image source URL input has no value.",
+	"Update": "The label of the form submit button if the image source URL input has a value.",
+	"Insert image via URL": "The input label for the Insert image via URL form.",
+	"Update image URL": "The input label for the Insert image via URL form for a pre-existing image.",
+	"Paste the image source URL.": "The content of the tip below the Insert image via URL form."
 }

+ 0 - 1
packages/ckeditor5-image/src/image/imageediting.js

@@ -113,7 +113,6 @@ export default class ImageEditing extends Plugin {
 			} )
 			.add( viewFigureToModel() );
 
-		// Register imageUpload command.
 		editor.commands.add( 'imageInsert', new ImageInsertCommand( editor ) );
 	}
 }

+ 2 - 2
packages/ckeditor5-image/src/imageinsert/ui/imageinsertformrowview.js

@@ -15,8 +15,8 @@ import '../../../theme/imageinsertformrowview.css';
  * The class representing a single row in a complex form,
  * used by {@link module:image/imageinsert/ui/imageinsertpanelview~ImageUploadPanelView}.
  *
- * **Note**: For now this class is private. When more use cases arrive (beyond ckeditor5-table and ckeditor5-image),
- * it will become a component in ckeditor5-ui.
+ * **Note**: For now this class is private. When more use cases appear (beyond `ckeditor5-table` and `ckeditor5-image`),
+ * it will become a component in `ckeditor5-ui`.
  *
  * @private
  * @extends module:ui/view~View

+ 8 - 8
packages/ckeditor5-image/src/imageinsert/ui/imageinsertpanelview.js

@@ -38,8 +38,8 @@ export default class ImageInsertPanelView extends View {
 	/**
 	 * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsert/ui~ImageInsertUI}.
 	 *
-	 * @param {module:utils/locale~Locale} [locale] The localization services instance..
-	 * @param {Object} [integrations] Integrations object that contain
+	 * @param {module:utils/locale~Locale} [locale] The localization services instance.
+	 * @param {Object} [integrations] An integrations object that contains
 	 * components (or tokens for components) to be shown in the panel view.
 	 */
 	constructor( locale, integrations ) {
@@ -69,7 +69,7 @@ export default class ImageInsertPanelView extends View {
 		this.dropdownView = this._createDropdownView( locale );
 
 		/**
-		 * Value of the URL input.
+		 * The value of the URL input.
 		 *
 		 * @member {String} #imageURLInputValue
 		 * @observable
@@ -122,7 +122,7 @@ export default class ImageInsertPanelView extends View {
 		} );
 
 		/**
-		 * Collection of the defined integrations for inserting the images.
+		 * A collection of the defined integrations for inserting the images.
 		 *
 		 * @private
 		 * @member {module:utils/collection~Collection}
@@ -226,7 +226,7 @@ export default class ImageInsertPanelView extends View {
 	}
 
 	/**
-	 * Creates dropdown view.
+	 * Creates the dropdown view.
 	 *
 	 * @param {module:utils/locale~Locale} locale The localization services instance.
 	 *
@@ -294,7 +294,7 @@ export default class ImageInsertPanelView extends View {
 	}
 
 	/**
-	 * Focuses the fist {@link #_focusables} in the form.
+	 * Focuses the first {@link #_focusables focusable} in the form.
 	 */
 	focus() {
 		this._focusCycler.focusFirst();
@@ -303,13 +303,13 @@ export default class ImageInsertPanelView extends View {
 
 /**
  * Fired when the form view is submitted (when one of the children triggered the submit event),
- * e.g. click on {@link #insertButtonView}.
+ * e.g. by a click on {@link #insertButtonView}.
  *
  * @event submit
  */
 
 /**
- * Fired when the form view is canceled, e.g. click on {@link #cancelButtonView}.
+ * Fired when the form view is canceled, e.g. by a click on {@link #cancelButtonView}.
  *
  * @event cancel
  */

+ 2 - 2
packages/ckeditor5-image/src/imageupload.js

@@ -42,7 +42,7 @@ export default class ImageUpload extends Plugin {
 }
 
 /**
- * Image upload configuration.
+ * The image upload configuration.
  *
  * @member {module:image/imageupload~ImageUploadConfig} module:image/image~ImageConfig#upload
  */
@@ -75,7 +75,7 @@ export default class ImageUpload extends Plugin {
  *		};
  *
  * The type string should match [one of the sub-types](https://www.iana.org/assignments/media-types/media-types.xhtml#image)
- * of the image MIME type. E.g. for the `image/jpeg` MIME type, add `'jpeg'` to your image upload configuration.
+ * of the image MIME type. For example, for the `image/jpeg` MIME type, add `'jpeg'` to your image upload configuration.
  *
  * **Note:** This setting only restricts some image types to be selected and uploaded through the CKEditor UI and commands. Image type
  * recognition and filtering should also be implemented on the server which accepts image uploads.

+ 1 - 1
packages/ckeditor5-image/src/imageupload/imageuploadui.js

@@ -43,7 +43,7 @@ export default class ImageUploadUI extends Plugin {
 	}
 
 	/**
-	 * Creates and sets up file dialog button view.
+	 * Creates and sets up the file dialog button view.
 	 *
 	 * @param {module:utils/locale~Locale} locale The localization services instance.
 	 *

+ 1 - 1
packages/ckeditor5-table/src/converters/upcasttable.js

@@ -85,7 +85,7 @@ export function skipEmptyTableRow() {
 }
 
 /**
- * Converter that ensures empty paragraph is inserted in a table cell if no other content was converted.
+ * A converter that ensures an empty paragraph is inserted in a table cell if no other content was converted.
  *
  * @returns {Function} Conversion helper.
  */

+ 1 - 1
packages/ckeditor5-table/src/tablewalker.js

@@ -532,7 +532,7 @@ class TableSlot {
  */
 
 // @if CK_DEBUG // function throwMissingGetterError( getterName ) {
-// @if CK_DEBUG //		throw new CKEditorError( 'tableslot-getter-removed: This TableSlot getter does not exist any more.', this, {
+// @if CK_DEBUG //		throw new CKEditorError( 'tableslot-getter-removed: This TableSlot getter does not exist anymore.', this, {
 // @if CK_DEBUG //			getterName
 // @if CK_DEBUG //		} );
 // @if CK_DEBUG // }

+ 14 - 14
packages/ckeditor5-utils/src/collection.js

@@ -202,7 +202,7 @@ export default class Collection {
 		} else if ( index > this._items.length || index < 0 ) {
 			/**
 			 * The `index` passed to {@link module:utils/collection~Collection#addMany `Collection#addMany()`}
-			 * is invalid. It must be a number between 0 and the the collection's length.
+			 * is invalid. It must be a number between 0 and the collection's length.
 			 *
 			 * @error collection-add-item-bad-index
 			 */
@@ -230,9 +230,9 @@ export default class Collection {
 	}
 
 	/**
-	 * Gets item by its id or index.
+	 * Gets an item by its ID or index.
 	 *
-	 * @param {String|Number} idOrIndex The item id or index in the collection.
+	 * @param {String|Number} idOrIndex The item ID or index in the collection.
 	 * @returns {Object|null} The requested item or `null` if such item does not exist.
 	 */
 	get( idOrIndex ) {
@@ -244,20 +244,20 @@ export default class Collection {
 			item = this._items[ idOrIndex ];
 		} else {
 			/**
-			 * Index or id must be given.
+			 * An index or ID must be given.
 			 *
 			 * @error collection-get-invalid-arg
 			 */
-			throw new CKEditorError( 'collection-get-invalid-arg: Index or id must be given.', this );
+			throw new CKEditorError( 'collection-get-invalid-arg: An index or ID must be given.', this );
 		}
 
 		return item || null;
 	}
 
 	/**
-	 * Returns a boolean indicating whether the collection contains an item.
+	 * Returns a Boolean indicating whether the collection contains an item.
 	 *
-	 * @param {Object|String} itemOrId The item or its id in the collection.
+	 * @param {Object|String} itemOrId The item or its ID in the collection.
 	 * @returns {Boolean} `true` if the collection contains the item, `false` otherwise.
 	 */
 	has( itemOrId ) {
@@ -272,11 +272,11 @@ export default class Collection {
 	}
 
 	/**
-	 * Gets index of item in the collection.
-	 * When item is not defined in the collection then index will be equal -1.
+	 * Gets an index of an item in the collection.
+	 * When an item is not defined in the collection, the index will equal -1.
 	 *
-	 * @param {Object|String} itemOrId The item or its id in the collection.
-	 * @returns {Number} Index of given item.
+	 * @param {Object|String} itemOrId The item or its ID in the collection.
+	 * @returns {Number} The index of a given item.
 	 */
 	getIndex( itemOrId ) {
 		let item;
@@ -293,7 +293,7 @@ export default class Collection {
 	/**
 	 * Removes an item from the collection.
 	 *
-	 * @param {Object|Number|String} subject The item to remove, its id or index in the collection.
+	 * @param {Object|Number|String} subject The item to remove, its ID or index in the collection.
 	 * @returns {Object} The removed item.
 	 * @fires remove
 	 * @fires change
@@ -642,11 +642,11 @@ export default class Collection {
 
 			if ( typeof itemId != 'string' ) {
 				/**
-				 * This item's id should be a string.
+				 * This item's ID should be a string.
 				 *
 				 * @error collection-add-invalid-id
 				 */
-				throw new CKEditorError( 'collection-add-invalid-id: This item\'s id should be a string.', this );
+				throw new CKEditorError( 'collection-add-invalid-id: This item\'s ID should be a string.', this );
 			}
 
 			if ( this.get( itemId ) ) {