Przeglądaj źródła

Merge branch 'master' into t/1509

Aleksander Nowodzinski 6 lat temu
rodzic
commit
d8f18dc58b
90 zmienionych plików z 2957 dodań i 1361 usunięć
  1. 1 1
      .eslintrc.js
  2. 4 9
      .travis.yml
  3. 249 1
      CHANGELOG.md
  4. 38 3
      README.md
  5. 1 1
      docs/_snippets/build-classic-source.js
  6. 1 1
      docs/_snippets/builds/saving-data/autosave.js
  7. 1 1
      docs/_snippets/builds/saving-data/build-autosave-source.js
  8. 1 1
      docs/_snippets/builds/saving-data/manualsave.js
  9. 1 1
      docs/_snippets/examples/balloon-block-editor.js
  10. 1 1
      docs/_snippets/examples/balloon-editor.js
  11. 1 1
      docs/_snippets/examples/classic-editor-short.js
  12. 1 1
      docs/_snippets/examples/classic-editor.html
  13. 1 1
      docs/_snippets/examples/classic-editor.js
  14. 1 1
      docs/_snippets/examples/custom-build.js
  15. 1 1
      docs/_snippets/examples/document-editor.js
  16. 1 1
      docs/_snippets/examples/inline-editor.js
  17. 2 2
      docs/_snippets/examples/multi-root-editor.js
  18. 0 0
      docs/_snippets/features/build-ui-language-source.html
  19. 12 0
      docs/_snippets/features/build-ui-language-source.js
  20. 1 1
      docs/_snippets/features/image-upload.js
  21. 5 0
      docs/_snippets/features/mathtype.html
  22. 28 0
      docs/_snippets/features/mathtype.js
  23. 1 1
      docs/_snippets/features/placeholder-custom.js
  24. 1 1
      docs/_snippets/features/placeholder.js
  25. 1 1
      docs/_snippets/features/read-only.js
  26. 4 0
      docs/_snippets/features/ui-language-content.html
  27. 25 0
      docs/_snippets/features/ui-language-content.js
  28. 4 0
      docs/_snippets/features/ui-language-rtl.html
  29. 23 0
      docs/_snippets/features/ui-language-rtl.js
  30. 1 1
      docs/_snippets/features/ui-language.html
  31. 3 6
      docs/_snippets/features/ui-language.js
  32. 12 0
      docs/_snippets/features/wproofreader.html
  33. 22 0
      docs/_snippets/features/wproofreader.js
  34. 1 1
      docs/_snippets/framework/development-tools/inspector.html
  35. 1 1
      docs/_snippets/framework/development-tools/inspector.js
  36. 5 5
      docs/_snippets/framework/tutorials/block-widget.js
  37. 8 8
      docs/_snippets/framework/tutorials/inline-widget.js
  38. BIN
      docs/assets/img/builds-content-styles.png
  39. BIN
      docs/assets/img/fields.jpg
  40. 1 1
      docs/assets/snippet.js
  41. 54 12
      docs/builds/guides/faq.md
  42. 75 22
      docs/builds/guides/frameworks/angular.md
  43. 22 2
      docs/builds/guides/frameworks/css.md
  44. 304 227
      docs/builds/guides/frameworks/react.md
  45. 111 23
      docs/builds/guides/frameworks/vuejs.md
  46. 48 14
      docs/builds/guides/integration/advanced-setup.md
  47. 2 0
      docs/builds/guides/integration/basic-api.md
  48. 193 0
      docs/builds/guides/integration/content-styles.md
  49. 20 20
      docs/builds/guides/integration/csp.md
  50. 14 0
      docs/builds/guides/integration/saving-data.md
  51. 15 3
      docs/builds/guides/migrate.md
  52. 1 0
      docs/builds/guides/overview.md
  53. 1 1
      docs/builds/guides/support/browser-compatibility.md
  54. 17 5
      docs/features/image-upload.md
  55. 71 0
      docs/features/mathtype.md
  56. 91 0
      docs/features/spell-checker.md
  57. 70 21
      docs/features/ui-language.md
  58. 4 4
      docs/framework/guides/architecture/ui-library.md
  59. 1 1
      docs/framework/guides/contributing/contributing.md
  60. 30 19
      docs/framework/guides/contributing/development-environment.md
  61. 6 2
      docs/framework/guides/contributing/testing-environment.md
  62. 10 10
      docs/framework/guides/creating-simple-plugin.md
  63. 1 1
      docs/framework/guides/custom-editor-creator.md
  64. 10 10
      docs/framework/guides/development-tools.md
  65. 29 35
      docs/framework/guides/quick-start.md
  66. 79 77
      docs/framework/guides/tutorials/implementing-a-block-widget.md
  67. 53 51
      docs/framework/guides/tutorials/implementing-an-inline-widget.md
  68. 12 3
      docs/umberto.json
  69. 5 1
      mrgit.json
  70. 71 64
      package.json
  71. 4 4
      scripts/bump-year.js
  72. 1 1
      scripts/clean-up-svg-icons.sh
  73. 1 1
      scripts/docs/build-and-publish-nightly.js
  74. 1 1
      scripts/docs/build-and-publish.js
  75. 1 1
      scripts/docs/build-api-docs.js
  76. 241 0
      scripts/docs/build-content-styles.js
  77. 11 6
      scripts/docs/build-docs.js
  78. 1 1
      scripts/docs/buildapi.js
  79. 76 0
      scripts/docs/content-styles/ckeditor.js
  80. 35 0
      scripts/docs/content-styles/list-content-styles.js
  81. 1 1
      scripts/docs/getrealimportpath.js
  82. 367 61
      scripts/docs/snippetadapter.js
  83. 0 139
      scripts/notify-travis-status.js
  84. 1 1
      scripts/release/bump-versions.js
  85. 1 1
      scripts/release/changelog.js
  86. 1 1
      scripts/release/publish.js
  87. 0 39
      scripts/release/update-mgit-branches.js
  88. 1 1
      scripts/switch-to-dev-dev.sh
  89. 8 20
      scripts/update-stable-branches.sh
  90. 320 399
      yarn.lock

+ 1 - 1
.eslintrc.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */

+ 4 - 9
.travis.yml

@@ -1,11 +1,7 @@
 sudo: required
 sudo: required
 dist: trusty
 dist: trusty
 addons:
 addons:
-  apt:
-    sources:
-    - google-chrome
-    packages:
-    - google-chrome-stable
+  chrome: stable
 language: node_js
 language: node_js
 cache:
 cache:
   yarn: true
   yarn: true
@@ -19,8 +15,8 @@ before_install:
 - sh -e /etc/init.d/xvfb start
 - sh -e /etc/init.d/xvfb start
 - npm i -g yarn
 - npm i -g yarn
 install:
 install:
-- yarn add mgit2 --ignore-workspace-root-check
-- mgit sync --resolver-url-template="https://github.com/\${ path }.git"
+- yarn add mrgit --ignore-workspace-root-check
+- mrgit sync --resolver-url-template="https://github.com/\${ path }.git"
 - git checkout package.json yarn.lock
 - git checkout package.json yarn.lock
 - rm -rf node_modules
 - rm -rf node_modules
 - yarn install
 - yarn install
@@ -32,8 +28,7 @@ script:
   fi'
   fi'
 after_script:
 after_script:
 - export END_TIME=$( date +%s )
 - export END_TIME=$( date +%s )
-- yarn add slack-notify --ignore-workspace-root-check
-- node ./scripts/notify-travis-status.js
+- ckeditor5-dev-tests-notify-travis-status
 env:
 env:
   global:
   global:
   - secure: RO140EQDHmEOPJPikk8eCY5IdHpnEKGm41p5U1ewAbeZv1DpCG+rSumR2JdYl75kFAaZvCSm1NuVMM+kmYd+/z+LQbKj7QH5G/UHNho3H89blIU6WlJhT0YR5vclm9rvnEvOtxnfODca1Qrw+CaCoJks2o4VYbJB7mOBVNsh7Bc=
   - secure: RO140EQDHmEOPJPikk8eCY5IdHpnEKGm41p5U1ewAbeZv1DpCG+rSumR2JdYl75kFAaZvCSm1NuVMM+kmYd+/z+LQbKj7QH5G/UHNho3H89blIU6WlJhT0YR5vclm9rvnEvOtxnfODca1Qrw+CaCoJks2o4VYbJB7mOBVNsh7Bc=

+ 249 - 1
CHANGELOG.md

@@ -1,11 +1,259 @@
 Changelog
 Changelog
 =========
 =========
 
 
+## [12.4.0](https://github.com/ckeditor/ckeditor5/compare/v12.3.1...v12.4.0) (2019-08-26)
+
+This release brings a huge set of new features: [image resizing](https://ckeditor.com/ckeditor5/build/docs/ckeditor5/latest/features/image.html#resizing-images), [to-do lists](https://ckeditor.com/ckeditor5/build/docs/ckeditor5/latest/features/todo-lists.html), [support for RTL languages](https://ckeditor.com/ckeditor5/build/docs/ckeditor5/latest/features/ui-language.html), [simple upload adapter](https://ckeditor.com/ckeditor5/build/docs/ckeditor5/latest/features/image-upload/simple-upload-adapter.html), [support for pasting from Google Docs](https://ckeditor.com/ckeditor5/build/docs/ckeditor5/latest/features/paste-from-office/paste-from-google-docs.html), [mathematic formulas](https://ckeditor.com/ckeditor5/build/docs/ckeditor5/latest/features/mathtype.html), and [spelling and grammar checking](https://ckeditor.com/ckeditor5/build/docs/ckeditor5/latest/features/spell-checker.html). In addition to that, as always, it contains many improvements and bug fixes.
+
+Blog post comming soon...
+
+### Dependencies
+
+Major releases (contain breaking changes):
+
+* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine): v13.2.1 => [v14.0.0](https://github.com/ckeditor/ckeditor5-engine/releases/tag/v14.0.0)
+* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image): v13.1.2 => [v14.0.0](https://github.com/ckeditor/ckeditor5-image/releases/tag/v14.0.0)
+* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention): v12.0.1 => [v13.0.0](https://github.com/ckeditor/ckeditor5-mention/releases/tag/v13.0.0)
+* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table): v13.0.2 => [v14.0.0](https://github.com/ckeditor/ckeditor5-table/releases/tag/v14.0.0)
+* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui): v13.0.2 => [v14.0.0](https://github.com/ckeditor/ckeditor5-ui/releases/tag/v14.0.0)
+* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload): v11.1.1 => [v12.0.0](https://github.com/ckeditor/ckeditor5-upload/releases/tag/v12.0.0)
+* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils): v13.0.1 => [v14.0.0](https://github.com/ckeditor/ckeditor5-utils/releases/tag/v14.0.0)
+* [@ckeditor/ckeditor5-watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog): v10.0.1 => [v11.0.0](https://github.com/ckeditor/ckeditor5-watchdog/releases/tag/v11.0.0)
+
+Minor releases:
+
+* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment): v11.1.3 => [v11.2.0](https://github.com/ckeditor/ckeditor5-alignment/releases/tag/v11.2.0)
+* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon): v12.3.1 => [v12.4.0](https://github.com/ckeditor/ckeditor5-build-balloon/releases/tag/v12.4.0)
+* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block): v12.3.1 => [v12.4.0](https://github.com/ckeditor/ckeditor5-build-balloon-block/releases/tag/v12.4.0)
+* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic): v12.3.1 => [v12.4.0](https://github.com/ckeditor/ckeditor5-build-classic/releases/tag/v12.4.0)
+* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document): v12.3.1 => [v12.4.0](https://github.com/ckeditor/ckeditor5-build-decoupled-document/releases/tag/v12.4.0)
+* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline): v12.3.1 => [v12.4.0](https://github.com/ckeditor/ckeditor5-build-inline/releases/tag/v12.4.0)
+* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core): v12.2.1 => [v12.3.0](https://github.com/ckeditor/ckeditor5-core/releases/tag/v12.3.0)
+* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline): v12.2.1 => [v12.3.0](https://github.com/ckeditor/ckeditor5-editor-inline/releases/tag/v12.3.0)
+* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter): v11.0.4 => [v11.1.0](https://github.com/ckeditor/ckeditor5-enter/releases/tag/v11.1.0)
+* [@ckeditor/ckeditor5-indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent): v10.0.1 => [v10.1.0](https://github.com/ckeditor/ckeditor5-indent/releases/tag/v10.1.0)
+* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list): v12.0.4 => [v12.1.0](https://github.com/ckeditor/ckeditor5-list/releases/tag/v12.1.0)
+* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office): v11.0.4 => [v11.1.0](https://github.com/ckeditor/ckeditor5-paste-from-office/releases/tag/v11.1.0)
+* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark): v14.1.1 => [v14.2.0](https://github.com/ckeditor/ckeditor5-theme-lark/releases/tag/v14.2.0)
+* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing): v12.1.1 => [v12.2.0](https://github.com/ckeditor/ckeditor5-typing/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget): v11.0.4 => [v11.1.0](https://github.com/ckeditor/ckeditor5-widget/releases/tag/v11.1.0)
+
+Patch releases (bug fixes, internal changes):
+
+* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-adapter-ckfinder/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-autoformat/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-autosave/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles): v11.1.3 => [v11.1.4](https://github.com/ckeditor/ckeditor5-basic-styles/releases/tag/v11.1.4)
+* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote): v11.1.2 => [v11.1.3](https://github.com/ckeditor/ckeditor5-block-quote/releases/tag/v11.1.3)
+* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-ckfinder/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard): v12.0.1 => [v12.0.2](https://github.com/ckeditor/ckeditor5-clipboard/releases/tag/v12.0.2)
+* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-cloud-services/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-easy-image/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon): v12.2.1 => [v12.2.2](https://github.com/ckeditor/ckeditor5-editor-balloon/releases/tag/v12.2.2)
+* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic): v12.1.3 => [v12.1.4](https://github.com/ckeditor/ckeditor5-editor-classic/releases/tag/v12.1.4)
+* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled): v12.2.1 => [v12.2.2](https://github.com/ckeditor/ckeditor5-editor-decoupled/releases/tag/v12.2.2)
+* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-essentials/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font): v11.2.1 => [v11.2.2](https://github.com/ckeditor/ckeditor5-font/releases/tag/v11.2.2)
+* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-heading/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-highlight/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link): v11.1.1 => [v11.1.2](https://github.com/ckeditor/ckeditor5-link/releases/tag/v11.1.2)
+* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-markdown-gfm/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed): v11.1.3 => [v11.1.4](https://github.com/ckeditor/ckeditor5-media-embed/releases/tag/v11.1.4)
+* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-paragraph/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format): v10.0.3 => [v10.0.4](https://github.com/ckeditor/ckeditor5-remove-format/releases/tag/v10.0.4)
+* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo): v11.0.4 => [v11.0.5](https://github.com/ckeditor/ckeditor5-undo/releases/tag/v11.0.5)
+* [@ckeditor/ckeditor5-word-count](https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count): v10.0.1 => [v10.0.2](https://github.com/ckeditor/ckeditor5-word-count/releases/tag/v10.0.2)
+
+
+## [12.3.1](https://github.com/ckeditor/ckeditor5/compare/v12.3.0...v12.3.1) (2019-07-10)
+
+We are happy to report the release of CKEditor 5 v12.3.0 (and v12.3.1 with a [small fix](https://github.com/ckeditor/ckeditor5-typing/pull/209)). This release introduces several new features ([word count](https://ckeditor.com/docs/ckeditor5/latest/features/word-count.html), [automatic text transformations](https://ckeditor.com/docs/ckeditor5/latest/features/text-transformation.html), [ability to control link attributes such as `target`](https://ckeditor.com/docs/ckeditor5/latest/features/link.html#custom-link-attributes-decorators) and [block indentation](https://ckeditor.com/docs/ckeditor5/latest/features/indent.html)). It also brings improvements to existing features (e.g. the ["document colors" section](https://ckeditor.com/docs/ckeditor5/latest/features/font.html#documents-colors) in the font color picker dropdowns) and many bug fixes.
+
+Read more in the blog post: https://ckeditor.com/blog/CKEditor-5-v12.3.0-with-word-count-autocorrect-link-attributes-and-new-upload-adapter-released/
+
+### Dependencies
+
+Patch releases (bug fixes, internal changes):
+
+* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-adapter-ckfinder/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment): v11.1.2 => [v11.1.3](https://github.com/ckeditor/ckeditor5-alignment/releases/tag/v11.1.3)
+* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-autoformat/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-autosave/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles): v11.1.2 => [v11.1.3](https://github.com/ckeditor/ckeditor5-basic-styles/releases/tag/v11.1.3)
+* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote): v11.1.1 => [v11.1.2](https://github.com/ckeditor/ckeditor5-block-quote/releases/tag/v11.1.2)
+* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon): v12.3.0 => [v12.3.1](https://github.com/ckeditor/ckeditor5-build-balloon/releases/tag/v12.3.1)
+* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block): v12.3.0 => [v12.3.1](https://github.com/ckeditor/ckeditor5-build-balloon-block/releases/tag/v12.3.1)
+* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic): v12.3.0 => [v12.3.1](https://github.com/ckeditor/ckeditor5-build-classic/releases/tag/v12.3.1)
+* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document): v12.3.0 => [v12.3.1](https://github.com/ckeditor/ckeditor5-build-decoupled-document/releases/tag/v12.3.1)
+* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline): v12.3.0 => [v12.3.1](https://github.com/ckeditor/ckeditor5-build-inline/releases/tag/v12.3.1)
+* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-ckfinder/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard): v12.0.0 => [v12.0.1](https://github.com/ckeditor/ckeditor5-clipboard/releases/tag/v12.0.1)
+* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-cloud-services/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core): v12.2.0 => [v12.2.1](https://github.com/ckeditor/ckeditor5-core/releases/tag/v12.2.1)
+* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-easy-image/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon): v12.2.0 => [v12.2.1](https://github.com/ckeditor/ckeditor5-editor-balloon/releases/tag/v12.2.1)
+* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic): v12.1.2 => [v12.1.3](https://github.com/ckeditor/ckeditor5-editor-classic/releases/tag/v12.1.3)
+* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled): v12.2.0 => [v12.2.1](https://github.com/ckeditor/ckeditor5-editor-decoupled/releases/tag/v12.2.1)
+* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline): v12.2.0 => [v12.2.1](https://github.com/ckeditor/ckeditor5-editor-inline/releases/tag/v12.2.1)
+* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine): v13.2.0 => [v13.2.1](https://github.com/ckeditor/ckeditor5-engine/releases/tag/v13.2.1)
+* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-enter/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-essentials/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font): v11.2.0 => [v11.2.1](https://github.com/ckeditor/ckeditor5-font/releases/tag/v11.2.1)
+* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-heading/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-highlight/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image): v13.1.1 => [v13.1.2](https://github.com/ckeditor/ckeditor5-image/releases/tag/v13.1.2)
+* [@ckeditor/ckeditor5-indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent): v10.0.0 => [v10.0.1](https://github.com/ckeditor/ckeditor5-indent/releases/tag/v10.0.1)
+* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link): v11.1.0 => [v11.1.1](https://github.com/ckeditor/ckeditor5-link/releases/tag/v11.1.1)
+* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list): v12.0.3 => [v12.0.4](https://github.com/ckeditor/ckeditor5-list/releases/tag/v12.0.4)
+* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-markdown-gfm/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed): v11.1.2 => [v11.1.3](https://github.com/ckeditor/ckeditor5-media-embed/releases/tag/v11.1.3)
+* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention): v12.0.0 => [v12.0.1](https://github.com/ckeditor/ckeditor5-mention/releases/tag/v12.0.1)
+* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-paragraph/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-paste-from-office/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format): v10.0.2 => [v10.0.3](https://github.com/ckeditor/ckeditor5-remove-format/releases/tag/v10.0.3)
+* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table): v13.0.1 => [v13.0.2](https://github.com/ckeditor/ckeditor5-table/releases/tag/v13.0.2)
+* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark): v14.1.0 => [v14.1.1](https://github.com/ckeditor/ckeditor5-theme-lark/releases/tag/v14.1.1)
+* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing): v12.1.0 => [v12.1.1](https://github.com/ckeditor/ckeditor5-typing/releases/tag/v12.1.1)
+* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui): v13.0.1 => [v13.0.2](https://github.com/ckeditor/ckeditor5-ui/releases/tag/v13.0.2)
+* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-undo/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload): v11.1.0 => [v11.1.1](https://github.com/ckeditor/ckeditor5-upload/releases/tag/v11.1.1)
+* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils): v13.0.0 => [v13.0.1](https://github.com/ckeditor/ckeditor5-utils/releases/tag/v13.0.1)
+* [@ckeditor/ckeditor5-watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog): v10.0.0 => [v10.0.1](https://github.com/ckeditor/ckeditor5-watchdog/releases/tag/v10.0.1)
+* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget): v11.0.3 => [v11.0.4](https://github.com/ckeditor/ckeditor5-widget/releases/tag/v11.0.4)
+* [@ckeditor/ckeditor5-word-count](https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count): v10.0.0 => [v10.0.1](https://github.com/ckeditor/ckeditor5-word-count/releases/tag/v10.0.1)
+
+
+## [12.3.0](https://github.com/ckeditor/ckeditor5/compare/v12.2.0...v12.3.0) (2019-07-04)
+
+### Dependencies
+
+New packages:
+
+* [@ckeditor/ckeditor5-indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent): [v10.0.0](https://github.com/ckeditor/ckeditor5-indent/releases/tag/v10.0.0)
+* [@ckeditor/ckeditor5-watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog): [v10.0.0](https://github.com/ckeditor/ckeditor5-watchdog/releases/tag/v10.0.0)
+* [@ckeditor/ckeditor5-word-count](https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count): [v10.0.0](https://github.com/ckeditor/ckeditor5-word-count/releases/tag/v10.0.0)
+
+Major releases (contain breaking changes):
+
+* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard): v11.0.2 => [v12.0.0](https://github.com/ckeditor/ckeditor5-clipboard/releases/tag/v12.0.0)
+* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention): v11.0.0 => [v12.0.0](https://github.com/ckeditor/ckeditor5-mention/releases/tag/v12.0.0)
+* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils): v12.1.1 => [v13.0.0](https://github.com/ckeditor/ckeditor5-utils/releases/tag/v13.0.0)
+
+Minor releases:
+
+* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon): v12.2.0 => [v12.3.0](https://github.com/ckeditor/ckeditor5-build-balloon/releases/tag/v12.3.0)
+* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block): v12.2.0 => [v12.3.0](https://github.com/ckeditor/ckeditor5-build-balloon-block/releases/tag/v12.3.0)
+* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic): v12.2.0 => [v12.3.0](https://github.com/ckeditor/ckeditor5-build-classic/releases/tag/v12.3.0)
+* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document): v12.2.0 => [v12.3.0](https://github.com/ckeditor/ckeditor5-build-decoupled-document/releases/tag/v12.3.0)
+* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline): v12.2.0 => [v12.3.0](https://github.com/ckeditor/ckeditor5-build-inline/releases/tag/v12.3.0)
+* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core): v12.1.1 => [v12.2.0](https://github.com/ckeditor/ckeditor5-core/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon): v12.1.1 => [v12.2.0](https://github.com/ckeditor/ckeditor5-editor-balloon/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled): v12.1.1 => [v12.2.0](https://github.com/ckeditor/ckeditor5-editor-decoupled/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline): v12.1.1 => [v12.2.0](https://github.com/ckeditor/ckeditor5-editor-inline/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine): v13.1.1 => [v13.2.0](https://github.com/ckeditor/ckeditor5-engine/releases/tag/v13.2.0)
+* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link): v11.0.2 => [v11.1.0](https://github.com/ckeditor/ckeditor5-link/releases/tag/v11.1.0)
+* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark): v14.0.0 => [v14.1.0](https://github.com/ckeditor/ckeditor5-theme-lark/releases/tag/v14.1.0)
+* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing): v12.0.2 => [v12.1.0](https://github.com/ckeditor/ckeditor5-typing/releases/tag/v12.1.0)
+* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload): v11.0.2 => [v11.1.0](https://github.com/ckeditor/ckeditor5-upload/releases/tag/v11.1.0)
+
+Patch releases (bug fixes, internal changes):
+
+* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-adapter-ckfinder/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment): v11.1.1 => [v11.1.2](https://github.com/ckeditor/ckeditor5-alignment/releases/tag/v11.1.2)
+* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-autoformat/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-autosave/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles): v11.1.1 => [v11.1.2](https://github.com/ckeditor/ckeditor5-basic-styles/releases/tag/v11.1.2)
+* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote): v11.1.0 => [v11.1.1](https://github.com/ckeditor/ckeditor5-block-quote/releases/tag/v11.1.1)
+* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-ckfinder/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-cloud-services/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-easy-image/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic): v12.1.1 => [v12.1.2](https://github.com/ckeditor/ckeditor5-editor-classic/releases/tag/v12.1.2)
+* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-enter/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-essentials/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font): v11.1.1 => [v11.1.2](https://github.com/ckeditor/ckeditor5-font/releases/tag/v11.1.2)
+* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-heading/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-highlight/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image): v13.1.0 => [v13.1.1](https://github.com/ckeditor/ckeditor5-image/releases/tag/v13.1.1)
+* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list): v12.0.2 => [v12.0.3](https://github.com/ckeditor/ckeditor5-list/releases/tag/v12.0.3)
+* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-markdown-gfm/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed): v11.1.1 => [v11.1.2](https://github.com/ckeditor/ckeditor5-media-embed/releases/tag/v11.1.2)
+* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-paragraph/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-paste-from-office/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format): v10.0.1 => [v10.0.2](https://github.com/ckeditor/ckeditor5-remove-format/releases/tag/v10.0.2)
+* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table): v13.0.0 => [v13.0.1](https://github.com/ckeditor/ckeditor5-table/releases/tag/v13.0.1)
+* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui): v13.0.0 => [v13.0.1](https://github.com/ckeditor/ckeditor5-ui/releases/tag/v13.0.1)
+* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-undo/releases/tag/v11.0.3)
+* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget): v11.0.2 => [v11.0.3](https://github.com/ckeditor/ckeditor5-widget/releases/tag/v11.0.3)
+
+
+## [12.2.0](https://github.com/ckeditor/ckeditor5/compare/v12.1.0...v12.2.0) (2019-06-05)
+
+We are happy to report the release of CKEditor 5 v12.2.0. This is a minor release with many bug fixes and a new UI feature which allows to navigating between multiple balloons.
+
+**Note:** The `config.table.toolbar` property that had been deprecated last year has now been completely removed. Use [`config.table.contentToolbar`](https://ckeditor.com/docs/ckeditor5/latest/api/module_table_table-TableConfig.html#member-contentToolbar) instead.
+
+Read more in the blog post: https://ckeditor.com/blog/CKEditor-5-v12.2.0-with-mobile-friendly-comments-mode/
+
+### Dependencies
+
+Major releases (contain breaking changes):
+
+* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention): v10.0.0 => [v11.0.0](https://github.com/ckeditor/ckeditor5-mention/releases/tag/v11.0.0)
+* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table): v12.0.1 => [v13.0.0](https://github.com/ckeditor/ckeditor5-table/releases/tag/v13.0.0)
+* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark): v13.0.1 => [v14.0.0](https://github.com/ckeditor/ckeditor5-theme-lark/releases/tag/v14.0.0)
+* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui): v12.1.0 => [v13.0.0](https://github.com/ckeditor/ckeditor5-ui/releases/tag/v13.0.0)
+
+Minor releases:
+
+* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote): v11.0.1 => [v11.1.0](https://github.com/ckeditor/ckeditor5-block-quote/releases/tag/v11.1.0)
+* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon): v12.1.0 => [v12.2.0](https://github.com/ckeditor/ckeditor5-build-balloon/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block): v12.1.0 => [v12.2.0](https://github.com/ckeditor/ckeditor5-build-balloon-block/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic): v12.1.0 => [v12.2.0](https://github.com/ckeditor/ckeditor5-build-classic/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document): v12.1.0 => [v12.2.0](https://github.com/ckeditor/ckeditor5-build-decoupled-document/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline): v12.1.0 => [v12.2.0](https://github.com/ckeditor/ckeditor5-build-inline/releases/tag/v12.2.0)
+* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image): v13.0.1 => [v13.1.0](https://github.com/ckeditor/ckeditor5-image/releases/tag/v13.1.0)
+
+Patch releases (bug fixes, internal changes):
+
+* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-adapter-ckfinder/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment): v11.1.0 => [v11.1.1](https://github.com/ckeditor/ckeditor5-alignment/releases/tag/v11.1.1)
+* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-autoformat/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-autosave/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles): v11.1.0 => [v11.1.1](https://github.com/ckeditor/ckeditor5-basic-styles/releases/tag/v11.1.1)
+* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-ckfinder/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-clipboard/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-cloud-services/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core): v12.1.0 => [v12.1.1](https://github.com/ckeditor/ckeditor5-core/releases/tag/v12.1.1)
+* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-easy-image/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon): v12.1.0 => [v12.1.1](https://github.com/ckeditor/ckeditor5-editor-balloon/releases/tag/v12.1.1)
+* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic): v12.1.0 => [v12.1.1](https://github.com/ckeditor/ckeditor5-editor-classic/releases/tag/v12.1.1)
+* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled): v12.1.0 => [v12.1.1](https://github.com/ckeditor/ckeditor5-editor-decoupled/releases/tag/v12.1.1)
+* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline): v12.1.0 => [v12.1.1](https://github.com/ckeditor/ckeditor5-editor-inline/releases/tag/v12.1.1)
+* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine): v13.1.0 => [v13.1.1](https://github.com/ckeditor/ckeditor5-engine/releases/tag/v13.1.1)
+* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-enter/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-essentials/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font): v11.1.0 => [v11.1.1](https://github.com/ckeditor/ckeditor5-font/releases/tag/v11.1.1)
+* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-heading/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-highlight/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-link/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list): v12.0.1 => [v12.0.2](https://github.com/ckeditor/ckeditor5-list/releases/tag/v12.0.2)
+* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-markdown-gfm/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed): v11.1.0 => [v11.1.1](https://github.com/ckeditor/ckeditor5-media-embed/releases/tag/v11.1.1)
+* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-paragraph/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-paste-from-office/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format): v10.0.0 => [v10.0.1](https://github.com/ckeditor/ckeditor5-remove-format/releases/tag/v10.0.1)
+* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing): v12.0.1 => [v12.0.2](https://github.com/ckeditor/ckeditor5-typing/releases/tag/v12.0.2)
+* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-undo/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-upload/releases/tag/v11.0.2)
+* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils): v12.1.0 => [v12.1.1](https://github.com/ckeditor/ckeditor5-utils/releases/tag/v12.1.1)
+* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget): v11.0.1 => [v11.0.2](https://github.com/ckeditor/ckeditor5-widget/releases/tag/v11.0.2)
+
+
 ## [12.1.0](https://github.com/ckeditor/ckeditor5/compare/v12.0.0...v12.1.0) (2019-04-10)
 ## [12.1.0](https://github.com/ckeditor/ckeditor5/compare/v12.0.0...v12.1.0) (2019-04-10)
 
 
 We are happy to report the release of CKEditor 5 v12.1.0. This release introduces 3 new features ([mentions](https://ckeditor.com/docs/ckeditor5/latest/features/mentions.html), [font color and background color](https://ckeditor.com/docs/ckeditor5/latest/features/font.html) and [remove format](https://ckeditor.com/docs/ckeditor5/latest/features/remove-format.html)).
 We are happy to report the release of CKEditor 5 v12.1.0. This release introduces 3 new features ([mentions](https://ckeditor.com/docs/ckeditor5/latest/features/mentions.html), [font color and background color](https://ckeditor.com/docs/ckeditor5/latest/features/font.html) and [remove format](https://ckeditor.com/docs/ckeditor5/latest/features/remove-format.html)).
 
 
-Blog post comming soon...
+Read more in the blog post: https://ckeditor.com/blog/CKEditor-5-v12.1.0-with-mentions-font-color-and-remove-formatting-released/
 
 
 ### Dependencies
 ### Dependencies
 
 

+ 38 - 3
README.md

@@ -4,7 +4,6 @@ CKEditor 5 [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?styl
 [![npm version](https://badge.fury.io/js/ckeditor5.svg)](https://www.npmjs.com/package/ckeditor5)
 [![npm version](https://badge.fury.io/js/ckeditor5.svg)](https://www.npmjs.com/package/ckeditor5)
 
 
 [![Build Status](https://travis-ci.org/ckeditor/ckeditor5.svg?branch=master)](https://travis-ci.org/ckeditor/ckeditor5)
 [![Build Status](https://travis-ci.org/ckeditor/ckeditor5.svg?branch=master)](https://travis-ci.org/ckeditor/ckeditor5)
-[![BrowserStack Status](https://automate.browserstack.com/automate/badge.svg?badge_key=d3hvenZqQVZERFQ5d09FWXdyT0ozVXhLaVltRFRjTTUyZGpvQWNmWVhUUT0tLUZqNlJ1YWRUd0RvdEVOaEptM1B2Q0E9PQ==--c9d3dee40b9b4471ff3fb516d9ecf8d09292c7e0)](https://automate.browserstack.com/public-build/d3hvenZqQVZERFQ5d09FWXdyT0ozVXhLaVltRFRjTTUyZGpvQWNmWVhUUT0tLUZqNlJ1YWRUd0RvdEVOaEptM1B2Q0E9PQ==--c9d3dee40b9b4471ff3fb516d9ecf8d09292c7e0)
 [![Dependency Status](https://img.shields.io/david/ckeditor/ckeditor5.svg)](https://david-dm.org/ckeditor/ckeditor5)
 [![Dependency Status](https://img.shields.io/david/ckeditor/ckeditor5.svg)](https://david-dm.org/ckeditor/ckeditor5)
 [![devDependency Status](https://img.shields.io/david/dev/ckeditor/ckeditor5.svg)](https://david-dm.org/ckeditor/ckeditor5?type=dev)
 [![devDependency Status](https://img.shields.io/david/dev/ckeditor/ckeditor5.svg)](https://david-dm.org/ckeditor/ckeditor5?type=dev)
 
 
@@ -18,7 +17,7 @@ A set of ready-to-use rich text editors created with a powerful framework. Made
 
 
 ## ⚠ This package does not contain any source code
 ## ⚠ This package does not contain any source code
 
 
-CKEditor 5 is distributed as [four ready-to-use rich text editor builds](https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#available-builds) which you can [install from npm](https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/installation.html#npm).
+CKEditor 5 is distributed as [several ready-to-use rich text editor builds](https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#available-builds) which you can [install from npm](https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/installation.html#npm).
 
 
 You can also [customize the existing builds](https://ckeditor.com/docs/ckeditor5/latest/builds/guides/development/custom-builds.html) or build your own editors and features by using the [CKEditor 5 Framework](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/overview.html).
 You can also [customize the existing builds](https://ckeditor.com/docs/ckeditor5/latest/builds/guides/development/custom-builds.html) or build your own editors and features by using the [CKEditor 5 Framework](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/overview.html).
 
 
@@ -221,6 +220,18 @@ See CKEditor 5 release blog posts [on the CKEditor blog](https://ckeditor.com/bl
 	</td>
 	</td>
 </tr>
 </tr>
 
 
+<tr>
+	<td>
+		<a href="https://github.com/ckeditor/ckeditor5-watchdog"><code>@ckeditor/ckeditor5-watchdog</code></a>
+	</td>
+	<td>
+		<a href="https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog"><img src="https://img.shields.io/npm/v/@ckeditor/ckeditor5-watchdog.svg" alt="@ckeditor/ckeditor5-watchdog npm package badge"></a>
+	</td>
+	<td>
+		The watchdog feature, which keeps CKEditor 5 editors running.
+	</td>
+</tr>
+
 <tr>
 <tr>
 	<td>
 	<td>
 		<a href="https://github.com/ckeditor/ckeditor5-cloud-services"><code>@ckeditor/ckeditor5-cloud-services</code></a>
 		<a href="https://github.com/ckeditor/ckeditor5-cloud-services"><code>@ckeditor/ckeditor5-cloud-services</code></a>
@@ -491,6 +502,18 @@ See CKEditor 5 release blog posts [on the CKEditor blog](https://ckeditor.com/bl
 	</td>
 	</td>
 </tr>
 </tr>
 
 
+<tr>
+	<td>
+		<a href="https://github.com/ckeditor/ckeditor5-indent"><code>@ckeditor/ckeditor5-indent</code></a>
+	</td>
+	<td>
+		<a href="https://www.npmjs.com/package/@ckeditor/ckeditor5-indent"><img src="https://img.shields.io/npm/v/@ckeditor/ckeditor5-indent.svg" alt="@ckeditor/ckeditor5-indent npm package badge"></a>
+	</td>
+	<td>
+		The indentation (of lists and blocks) feature.
+	</td>
+</tr>
+
 <tr>
 <tr>
 	<td>
 	<td>
 		<a href="https://github.com/ckeditor/ckeditor5-link"><code>@ckeditor/ckeditor5-link</code></a>
 		<a href="https://github.com/ckeditor/ckeditor5-link"><code>@ckeditor/ckeditor5-link</code></a>
@@ -623,6 +646,18 @@ See CKEditor 5 release blog posts [on the CKEditor blog](https://ckeditor.com/bl
 	</td>
 	</td>
 </tr>
 </tr>
 
 
+<tr>
+	<td>
+		<a href="https://github.com/ckeditor/ckeditor5-word-count"><code>@ckeditor/ckeditor5-word-count</code></a>
+	</td>
+	<td>
+		<a href="https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count"><img src="https://img.shields.io/npm/v/@ckeditor/ckeditor5-word-count.svg" alt="@ckeditor/ckeditor5-word-count npm package badge"></a>
+	</td>
+	<td>
+		The word count feature.
+	</td>
+</tr>
+
 </tbody>
 </tbody>
 </table>
 </table>
 
 
@@ -718,4 +753,4 @@ See CKEditor 5 release blog posts [on the CKEditor blog](https://ckeditor.com/bl
 
 
 ## License
 ## License
 
 
-Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the LICENSE.md file.
+Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the `LICENSE.md` file or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license).

+ 1 - 1
docs/_snippets/build-classic-source.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals window */
 /* globals window */

+ 1 - 1
docs/_snippets/builds/saving-data/autosave.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals ClassicEditor, console, window, document, setTimeout */
 /* globals ClassicEditor, console, window, document, setTimeout */

+ 1 - 1
docs/_snippets/builds/saving-data/build-autosave-source.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals window */
 /* globals window */

+ 1 - 1
docs/_snippets/builds/saving-data/manualsave.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals ClassicEditor, console, window, document, setTimeout */
 /* globals ClassicEditor, console, window, document, setTimeout */

+ 1 - 1
docs/_snippets/examples/balloon-block-editor.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console, window, document */
 /* globals console, window, document */

+ 1 - 1
docs/_snippets/examples/balloon-editor.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console, window, document */
 /* globals console, window, document */

+ 1 - 1
docs/_snippets/examples/classic-editor-short.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals ClassicEditor, console, window, document */
 /* globals ClassicEditor, console, window, document */

+ 1 - 1
docs/_snippets/examples/classic-editor.html

@@ -4,7 +4,7 @@
 	<p>Like all the great things on earth traveling teaches us by example. Here are some of the most precious lessons I’ve learned over the years of traveling.</p>
 	<p>Like all the great things on earth traveling teaches us by example. Here are some of the most precious lessons I’ve learned over the years of traveling.</p>
 
 
 	<figure class="media">
 	<figure class="media">
-		<oembed url="https://www.youtube.com/watch?v=BLJ4GKKaiXw"></oembed>
+		<oembed url="https://www.youtube.com/watch?v=CB70skVw3nU"></oembed>
 	</figure>
 	</figure>
 
 
 	<h3>Appreciation of diversity</h3>
 	<h3>Appreciation of diversity</h3>

+ 1 - 1
docs/_snippets/examples/classic-editor.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals ClassicEditor, console, window, document */
 /* globals ClassicEditor, console, window, document */

+ 1 - 1
docs/_snippets/examples/custom-build.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console, window, document */
 /* globals console, window, document */

+ 1 - 1
docs/_snippets/examples/document-editor.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console, window, document */
 /* globals console, window, document */

+ 1 - 1
docs/_snippets/examples/inline-editor.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console, window, document */
 /* globals console, window, document */

+ 2 - 2
docs/_snippets/examples/multi-root-editor.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console:false, document, window */
 /* globals console:false, document, window */
@@ -211,7 +211,7 @@ class MultirootEditorUI extends EditorUI {
 
 
 			// Register the editable UI view in the editor. A single editor instance can aggregate multiple
 			// Register the editable UI view in the editor. A single editor instance can aggregate multiple
 			// editable areas (roots) but the decoupled editor has only one.
 			// editable areas (roots) but the decoupled editor has only one.
-			this._editableElements.set( editable.name, editableElement );
+			this.setEditableElement( editable.name, editableElement );
 
 
 			// Let the global focus tracker know that the editable UI element is focusable and
 			// Let the global focus tracker know that the editable UI element is focusable and
 			// belongs to the editor. From now on, the focus tracker will sustain the editor focus
 			// belongs to the editor. From now on, the focus tracker will sustain the editor focus

+ 0 - 0
docs/_snippets/features/build-ui-language-source.html


+ 12 - 0
docs/_snippets/features/build-ui-language-source.js

@@ -0,0 +1,12 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals window */
+
+/* config { "additionalLanguages": [ "ar", "es" ] } */
+
+import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
+
+window.ClassicEditor = ClassicEditor;

+ 1 - 1
docs/_snippets/features/image-upload.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals ClassicEditor, console, window, document */
 /* globals ClassicEditor, console, window, document */

+ 5 - 0
docs/_snippets/features/mathtype.html

@@ -0,0 +1,5 @@
+<div id="mathtype-editor">
+	<p>In elementary algebra, the <strong>quadratic formula</strong> is the solution of the quadratic equation.</p>
+
+	<p><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi><mo>=</mo><mfrac><mrow><mo>-</mo><mi>b</mi><mo>&#177;</mo><msqrt><msup><mi>b</mi><mn>2</mn></msup><mo>-</mo><mn>4</mn><mi>a</mi><mi>c</mi></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></math></p>
+</div>

+ 28 - 0
docs/_snippets/features/mathtype.js

@@ -0,0 +1,28 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals document, console */
+
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
+import Heading from '@ckeditor/ckeditor5-heading/src/heading';
+import MathType from '@wiris/mathtype-ckeditor5';
+
+ClassicEditor
+	.create( document.querySelector( '#mathtype-editor' ), {
+		plugins: [
+			Essentials,
+			Bold,
+			Italic,
+			Heading,
+			MathType
+		],
+		toolbar: [ 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo', '|', 'MathType', 'ChemType' ]
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 1 - 1
docs/_snippets/features/placeholder-custom.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console, window, document, ClassicEditor */
 /* globals console, window, document, ClassicEditor */

+ 1 - 1
docs/_snippets/features/placeholder.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console, window, document, ClassicEditor */
 /* globals console, window, document, ClassicEditor */

+ 1 - 1
docs/_snippets/features/read-only.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals ClassicEditor, console, window, document */
 /* globals ClassicEditor, console, window, document */

+ 4 - 0
docs/_snippets/features/ui-language-content.html

@@ -0,0 +1,4 @@
+<div id="snippet-ui-language-content">
+	<h2>لغة</h2>
+	<p>اللغة نسق من الإشارات والرموز، يشكل أداة من أدوات المعرفة، وتعتبر اللغة أهم وسائل التفاهم والاحتكاك بين أفراد المجتمع في جميع ميادين الحياة. وبدون اللغة يتعذر نشاط الناس المعرفي. وترتبط اللغة بالتفكير ارتباطًا وثيقًا؛ فأفكار الإنسان تصاغ دومًا في قالب لغوي، حتى في حال تفكيره الباطني. ومن خلال اللغة فقط تحصل الفكرة على وجودها الواقعي. كما ترمز اللغة إلى الأشياء المنعكسة فيها.</p>
+</div>

+ 25 - 0
docs/_snippets/features/ui-language-content.js

@@ -0,0 +1,25 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals ClassicEditor, console, window, document */
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-ui-language-content' ), {
+		language: {
+			content: 'ar'
+		},
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 4 - 0
docs/_snippets/features/ui-language-rtl.html

@@ -0,0 +1,4 @@
+<div id="snippet-ui-language-rtl">
+	<h2>لغة</h2>
+	<p>اللغة نسق من الإشارات والرموز، يشكل أداة من أدوات المعرفة، وتعتبر اللغة أهم وسائل التفاهم والاحتكاك بين أفراد المجتمع في جميع ميادين الحياة. وبدون اللغة يتعذر نشاط الناس المعرفي. وترتبط اللغة بالتفكير ارتباطًا وثيقًا؛ فأفكار الإنسان تصاغ دومًا في قالب لغوي، حتى في حال تفكيره الباطني. ومن خلال اللغة فقط تحصل الفكرة على وجودها الواقعي. كما ترمز اللغة إلى الأشياء المنعكسة فيها.</p>
+</div>

+ 23 - 0
docs/_snippets/features/ui-language-rtl.js

@@ -0,0 +1,23 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals ClassicEditor, console, window, document */
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-ui-language-rtl' ), {
+		language: 'ar',
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 1 - 1
docs/_snippets/features/ui-language.html

@@ -1,3 +1,3 @@
 <div id="snippet-ui-language">
 <div id="snippet-ui-language">
-	<p>This is <a href="https://ckeditor.com">CKEditor&nbsp;5</a>.</p>
+	<p>Un <strong>lenguaje</strong> (del <a href="http://es.wikipedia.org/wiki/Idioma_occitano">provenzal</a> <em>lenguatge</em> y este del <a href="http://es.wikipedia.org/wiki/Lat%C3%ADn">lat&iacute;n</a> <em>lingua</em>) es un sistema de <a href="http://es.wikipedia.org/wiki/Comunicaci%C3%B3n">comunicaci&oacute;n</a> estructurado para el que existe un <a href="http://es.wikipedia.org/wiki/Significado">contexto</a> de uso y ciertos principios combinatorios formales. Existen contextos tanto naturales como artificiales.</p>
 </div>
 </div>

+ 3 - 6
docs/_snippets/features/ui-language.js

@@ -1,18 +1,15 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
-/* globals console, window, document */
-
-/* config { "language": "de" } */
-
-import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
+/* globals ClassicEditor, console, window, document */
 
 
 import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
 import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
 
 
 ClassicEditor
 ClassicEditor
 	.create( document.querySelector( '#snippet-ui-language' ), {
 	.create( document.querySelector( '#snippet-ui-language' ), {
+		language: 'es',
 		cloudServices: CS_CONFIG,
 		cloudServices: CS_CONFIG,
 		toolbar: {
 		toolbar: {
 			viewportTopOffset: window.getViewportTopOffsetConfig()
 			viewportTopOffset: window.getViewportTopOffsetConfig()

+ 12 - 0
docs/_snippets/features/wproofreader.html

@@ -0,0 +1,12 @@
+<script type="text/javascript" src="https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js"></script>
+<script>
+	window.WEBSPELLCHECKER_CONFIG = {
+		autoSearch: true,
+		enableGrammar: true,
+		serviceId: '1:Eebp63-lWHbt2-ASpHy4-AYUpy2-fo3mk4-sKrza1-NsuXy4-I1XZC2-0u2F54-aqYWd1-l3Qf14-umd'
+	};
+</script>
+<div id="snippet-wproofreader">
+	<p>Typos hapen. We striving to correct them. Hover on the marked words for instant correction suggestions or click the dialog icon in the bottom right corner to have the whole text proofread at once.</p>
+	<p>You can also paste your own text here to have its spelling and grammar checked.</p>
+</div>

+ 22 - 0
docs/_snippets/features/wproofreader.js

@@ -0,0 +1,22 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals ClassicEditor, console, window, document */
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-wproofreader' ), {
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 1 - 1
docs/_snippets/framework/development-tools/inspector.html

@@ -9,7 +9,7 @@
 		<li>Browse and inspect the model and view structures.</li>
 		<li>Browse and inspect the model and view structures.</li>
 		<li>Observe the selection position.</li>
 		<li>Observe the selection position.</li>
 		<li>Check the list of commands and their state.</li>
 		<li>Check the list of commands and their state.</li>
-		<li>More features comming soon!</li>
+		<li>More features coming soon!</li>
 	</ul>
 	</ul>
 </div>
 </div>
 
 

+ 1 - 1
docs/_snippets/framework/development-tools/inspector.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console, window, document */
 /* globals console, window, document */

+ 5 - 5
docs/_snippets/framework/tutorials/block-widget.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals console, window, document */
 /* globals console, window, document */
@@ -31,7 +31,7 @@ class SimpleBoxUI extends Plugin {
 		const editor = this.editor;
 		const editor = this.editor;
 		const t = editor.t;
 		const t = editor.t;
 
 
-		// The "simpleBox" button must be registered among UI components of the editor
+		// The "simpleBox" button must be registered among the UI components of the editor
 		// to be displayed in the toolbar.
 		// to be displayed in the toolbar.
 		editor.ui.componentFactory.add( 'simpleBox', locale => {
 		editor.ui.componentFactory.add( 'simpleBox', locale => {
 			// The state of the button will be bound to the widget command.
 			// The state of the button will be bound to the widget command.
@@ -156,7 +156,7 @@ class SimpleBoxEditing extends Plugin {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 			model: 'simpleBoxTitle',
 			model: 'simpleBoxTitle',
 			view: ( modelElement, viewWriter ) => {
 			view: ( modelElement, viewWriter ) => {
-				// Note: we use a more specialized createEditableElement() method here.
+				// Note: You use a more specialized createEditableElement() method here.
 				const h1 = viewWriter.createEditableElement( 'h1', { class: 'simple-box-title' } );
 				const h1 = viewWriter.createEditableElement( 'h1', { class: 'simple-box-title' } );
 
 
 				return toWidgetEditable( h1, viewWriter );
 				return toWidgetEditable( h1, viewWriter );
@@ -181,7 +181,7 @@ class SimpleBoxEditing extends Plugin {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 			model: 'simpleBoxDescription',
 			model: 'simpleBoxDescription',
 			view: ( modelElement, viewWriter ) => {
 			view: ( modelElement, viewWriter ) => {
-				// Note: we use a more specialized createEditableElement() method here.
+				// Note: You use a more specialized createEditableElement() method here.
 				const div = viewWriter.createEditableElement( 'div', { class: 'simple-box-description' } );
 				const div = viewWriter.createEditableElement( 'div', { class: 'simple-box-description' } );
 
 
 				return toWidgetEditable( div, viewWriter );
 				return toWidgetEditable( div, viewWriter );
@@ -194,7 +194,7 @@ class InsertSimpleBoxCommand extends Command {
 	execute() {
 	execute() {
 		this.editor.model.change( writer => {
 		this.editor.model.change( writer => {
 			// Insert <simpleBox>*</simpleBox> at the current selection position
 			// Insert <simpleBox>*</simpleBox> at the current selection position
-			// in a way which will result in creating a valid model structure.
+			// in a way that will result in creating a valid model structure.
 			this.editor.model.insertContent( createSimpleBox( writer ) );
 			this.editor.model.insertContent( createSimpleBox( writer ) );
 		} );
 		} );
 	}
 	}

+ 8 - 8
docs/_snippets/framework/tutorials/inline-widget.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 /* globals console, window, document */
 /* globals console, window, document */
 
 
@@ -26,13 +26,13 @@ class PlaceholderCommand extends Command {
 		const editor = this.editor;
 		const editor = this.editor;
 
 
 		editor.model.change( writer => {
 		editor.model.change( writer => {
-			// Create <placeholder> elment with name attribute...
+			// Create a <placeholder> elment with the "name" attribute...
 			const placeholder = writer.createElement( 'placeholder', { name: value } );
 			const placeholder = writer.createElement( 'placeholder', { name: value } );
 
 
 			// ... and insert it into the document.
 			// ... and insert it into the document.
 			editor.model.insertContent( placeholder );
 			editor.model.insertContent( placeholder );
 
 
-			// Put the selection on inserted element.
+			// Put the selection on the inserted element.
 			writer.setSelection( placeholder, 'on' );
 			writer.setSelection( placeholder, 'on' );
 		} );
 		} );
 	}
 	}
@@ -59,7 +59,7 @@ class PlaceholderUI extends Plugin {
 		const t = editor.t;
 		const t = editor.t;
 		const placeholderNames = editor.config.get( 'placeholderConfig.types' );
 		const placeholderNames = editor.config.get( 'placeholderConfig.types' );
 
 
-		// The "placeholder" dropdown must be registered among UI components of the editor
+		// The "placeholder" dropdown must be registered among the UI components of the editor
 		// to be displayed in the toolbar.
 		// to be displayed in the toolbar.
 		editor.ui.componentFactory.add( 'placeholder', locale => {
 		editor.ui.componentFactory.add( 'placeholder', locale => {
 			const dropdownView = createDropdown( locale );
 			const dropdownView = createDropdown( locale );
@@ -75,7 +75,7 @@ class PlaceholderUI extends Plugin {
 				withText: true
 				withText: true
 			} );
 			} );
 
 
-			// Execute the command when the dropdown items is clicked (executed).
+			// Execute the command when the dropdown item is clicked (executed).
 			this.listenTo( dropdownView, 'execute', evt => {
 			this.listenTo( dropdownView, 'execute', evt => {
 				editor.execute( 'placeholder', { value: evt.source.commandParam } );
 				editor.execute( 'placeholder', { value: evt.source.commandParam } );
 				editor.editing.view.focus();
 				editor.editing.view.focus();
@@ -135,10 +135,10 @@ class PlaceholderEditing extends Plugin {
 			// Allow wherever text is allowed:
 			// Allow wherever text is allowed:
 			allowWhere: '$text',
 			allowWhere: '$text',
 
 
-			// The placeholder will acts as an inline node:
+			// The placeholder will act as an inline node:
 			isInline: true,
 			isInline: true,
 
 
-			// The inline-widget is self-contained so cannot be split by the caret and can be selected:
+			// The inline widget is self-contained so it cannot be split by the caret and it can be selected:
 			isObject: true,
 			isObject: true,
 
 
 			// The placeholder can have many types, like date, name, surname, etc:
 			// The placeholder can have many types, like date, name, surname, etc:
@@ -167,7 +167,7 @@ class PlaceholderEditing extends Plugin {
 			view: ( modelItem, viewWriter ) => {
 			view: ( modelItem, viewWriter ) => {
 				const widgetElement = createPlaceholderView( modelItem, viewWriter );
 				const widgetElement = createPlaceholderView( modelItem, viewWriter );
 
 
-				// Enable widget handling on placeholder element inside editing view.
+				// Enable widget handling on a placeholder element inside the editing view.
 				return toWidget( widgetElement, viewWriter );
 				return toWidget( widgetElement, viewWriter );
 			}
 			}
 		} );
 		} );

BIN
docs/assets/img/builds-content-styles.png


BIN
docs/assets/img/fields.jpg


+ 1 - 1
docs/assets/snippet.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* globals window, document */
 /* globals window, document */

+ 54 - 12
docs/builds/guides/faq.md

@@ -10,7 +10,7 @@ order: 40
 
 
 Unlike [CKEditor 4](https://ckeditor.com/ckeditor-4/), CKEditor 5 implements a custom {@link framework/guides/architecture/editing-engine data model}. This means that every piece of content that is loaded into the editor needs to be converted to that model and then rendered back to the view.
 Unlike [CKEditor 4](https://ckeditor.com/ckeditor-4/), CKEditor 5 implements a custom {@link framework/guides/architecture/editing-engine data model}. This means that every piece of content that is loaded into the editor needs to be converted to that model and then rendered back to the view.
 
 
-Each kind of content must be handled by some feature. For instance the [ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles) package handles HTML elements such as `<b>`, `<i>`, `<u>`, etc. along with their representation in the model. The feature defines the two–way conversion between the HTML (view) and the editor model.
+Each kind of content must be handled by some feature. For instance the [`ckeditor5-basic-styles`](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles) package handles HTML elements such as `<b>`, `<i>`, `<u>`, etc. along with their representation in the model. The feature defines the two–way conversion between the HTML (view) and the editor model.
 
 
 If you load some content unknown to any editor feature, it will be dropped. If you want all the HTML5 elements to be supported, you need to write plugins to support them. Once you do that, CKEditor 5 will not filter anything out.
 If you load some content unknown to any editor feature, it will be dropped. If you want all the HTML5 elements to be supported, you need to write plugins to support them. Once you do that, CKEditor 5 will not filter anything out.
 
 
@@ -22,15 +22,9 @@ See the [relevant issue](https://github.com/ckeditor/ckeditor5/issues/592) on Gi
 
 
 ## What happened to the `contents.css` file? How do I style the content of the editor?
 ## What happened to the `contents.css` file? How do I style the content of the editor?
 
 
-There is no such thing as the `contents.css` file because in CKEditor 5 features bring their own content styles, which are by default included in the JavaScript build and {@link framework/guides/theme-customization#styles-processing-and-bundling loaded by the style–loader} (they can be {@link builds/guides/integration/advanced-setup#option-extracting-css extracted}, too). It optimizes the size of the builds as the styles of unused features are simply excluded.
+There is no such thing as the `contents.css` file because in CKEditor 5 features bring their own content styles, which are by default included in the JavaScript build and {@link framework/guides/theme-customization#styles-processing-and-bundling loaded by the style loader}. It optimizes the size of the builds as the styles of unused features are simply excluded.
 
 
-Although some styles are provided by the features, it is up to the developers to make sure the content created by CKEditor 5 is properly styled, both in the front–end and in the back–end. To style the content in the editor (back–end), use the `.ck-content` CSS class:
-
-```css
-.ck-content a {
-	color: teal;
-}
-```
+You can get the full list of editor content styles in a {@link builds/guides/integration/content-styles dedicated guide}. You can also {@link builds/guides/integration/advanced-setup#option-extracting-css extract all CSS} brought by CKEditor 5 (content and UI) to a separate file when creating a custom editor build.
 
 
 ## The build I downloaded is missing some features. How do I add them?
 ## The build I downloaded is missing some features. How do I add them?
 
 
@@ -40,7 +34,7 @@ You can learn which editor features are available in the {@link features/index f
 
 
 ## Where are the `editor.insertHtml()` and `editor.insertText()` methods? How to insert some content?
 ## Where are the `editor.insertHtml()` and `editor.insertText()` methods? How to insert some content?
 
 
-Because CKEditor 5 uses a custom {@link framework/guides/architecture/editing-engine data model}, whenever you want to insert anything, you should modify the model first, which is then converted back to the view where the users input their content (called editable). In CKEditor 5, HTML is just one of many possible output formats. You can learn more about the ways of changing the model in the {@link framework/guides/architecture/editing-engine#changing-the-model dedicated guide}.
+Because CKEditor 5 uses a custom {@link framework/guides/architecture/editing-engine data model}, whenever you want to insert anything, you should modify the model first, which is then converted back to the view where the users input their content (called "editable"). In CKEditor 5, HTML is just one of many possible output formats. You can learn more about the ways of changing the model in the {@link framework/guides/architecture/editing-engine#changing-the-model dedicated guide}.
 
 
 To insert a new link at the current position, use the following snippet:
 To insert a new link at the current position, use the following snippet:
 
 
@@ -80,11 +74,11 @@ By default, CKEditor 5 has no global registry of editor instances. But if necess
 
 
 The {@link features/image Image} and {@link features/image-upload Image upload} features are enabled by default in all editor builds. However, to fully enable image upload when installing CKEditor 5 you need to configure one of the available upload adapters. Check out the {@link features/image-upload comprehensive "Image upload" guide} to find out the best image upload strategy for your project.
 The {@link features/image Image} and {@link features/image-upload Image upload} features are enabled by default in all editor builds. However, to fully enable image upload when installing CKEditor 5 you need to configure one of the available upload adapters. Check out the {@link features/image-upload comprehensive "Image upload" guide} to find out the best image upload strategy for your project.
 
 
-## How to use CKEditor 5 with frameworks (Angular, React, etc.)?
+## How to use CKEditor 5 with frameworks (Angular, React, Vue, etc.)?
 
 
 For the full list of official integrations see the {@link builds/guides/frameworks/overview#official-wysiwyg-editor-integrations "Official integrations"} section.
 For the full list of official integrations see the {@link builds/guides/frameworks/overview#official-wysiwyg-editor-integrations "Official integrations"} section.
 
 
-If an official integration for the framework of your choice does not exist yet, make sure to read the {@link builds/guides/frameworks/overview "Integrating CKEditor 5 with JavaScript frameworks"} guide. CKEditor 5 offers a rich JavaScript API and ready to use builds which make it possible to use CKEditor 5 with whichever framework you need.
+If an official integration for the framework of your choice does not exist yet, make sure to read the {@link builds/guides/frameworks/overview "Integrating CKEditor 5 with JavaScript frameworks"} guide. CKEditor 5 offers a rich JavaScript API and ready-to-use builds that make it possible to use CKEditor 5 with whichever framework you need.
 
 
 We plan to provide more official integrations with time. [Your feedback on what should we work on next](https://github.com/ckeditor/ckeditor5/issues/1002) will be most welcome!
 We plan to provide more official integrations with time. [Your feedback on what should we work on next](https://github.com/ckeditor/ckeditor5/issues/1002) will be most welcome!
 
 
@@ -111,3 +105,51 @@ plugins: [
 You can also use the relative path which is resolved relative to the resource that imports `bold.svg` (the {@link module:basic-styles/bold/boldui~BoldUI `BoldUI`} class file in this scenario).
 You can also use the relative path which is resolved relative to the resource that imports `bold.svg` (the {@link module:basic-styles/bold/boldui~BoldUI `BoldUI`} class file in this scenario).
 
 
 Learn more about {@link builds/guides/integration/advanced-setup#webpack-configuration building CKEditor 5 using webpack}.
 Learn more about {@link builds/guides/integration/advanced-setup#webpack-configuration building CKEditor 5 using webpack}.
+
+## How to get the editor instance object from the DOM element?
+
+If you have a reference to the editor editable's DOM element (the one with the `.ck-editor__editable` class and the `contenteditable` attribute), you can access the editor instance this editable element belongs to using the `ckeditorInstance` property:
+
+```html
+<!-- The editable element in the editor's DOM structure. -->
+<div class="... ck-editor__editable ..." contenteditable="true">
+	<!-- Editable content. -->
+</div>
+```
+
+```js
+// A reference to the editor editable element in the DOM.
+const domEditableElement = document.querySelector( '.ck-editor__editable' );
+
+// Get the editor instance from the editable element.
+const editorInstance = domEditableElement.ckeditorInstance;
+
+// Use the editor instance API.
+editorInstance.setData( '<p>Hello world!<p>' );
+```
+
+## How to add an attribute to the editor editable in DOM?
+
+If you have a reference to the editor instance, simply use the {@link framework/guides/architecture/editing-engine#changing-the-view `change()`} method of the view and set the new attribute via the {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer}:
+
+```js
+editor.editing.view.change( writer => {
+	const viewEditableRoot = editor.editing.view.document.getRoot();
+
+	writer.setAttribute( 'myAttribute', 'value', viewEditableRoot );
+} );
+```
+
+If you do not have the reference to the editor instance but you have access to the editable element in the DOM, you can [access it using the `ckeditorInstance` property](#how-to-get-the-editor-instance-object-from-the-dom-element) and then use the same API to set the attribute:
+
+```js
+const domEditableElement = document.querySelector( '.ck-editor__editable' );
+const editorInstance = domEditableElement.ckeditorInstance;
+
+editorInstance.editing.view.change( writer => {
+	// Map the editable element in the DOM to the editable element in the editor's view.
+	const viewEditableRoot = editorInstance.editing.view.domConverter.mapDomToView( domEditableElement );
+
+	writer.setAttribute( 'myAttribute', 'value', viewEditableRoot );
+} );
+```

+ 75 - 22
docs/builds/guides/frameworks/angular.md

@@ -1,10 +1,10 @@
 ---
 ---
-menu-title: Angular 2+ component
+menu-title: Angular component
 category: builds-integration-frameworks
 category: builds-integration-frameworks
 order: 20
 order: 20
 ---
 ---
 
 
-# Rich text editor component for Angular 2+
+# Rich text editor component for Angular
 
 
 [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-angular.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-angular)
 [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-angular.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-angular)
 
 
@@ -18,13 +18,13 @@ Currently, the CKEditor 5 component for Angular supports integrating CKEditor 5
 
 
 ## Quick start
 ## Quick start
 
 
-In your existing Angular project, install the [CKEditor 5 WYSIWYG editor component for Angular 2+](https://www.npmjs.com/package/@ckeditor/ckeditor5-angular):
+In your existing Angular project, install the [CKEditor 5 WYSIWYG editor component for Angular](https://www.npmjs.com/package/@ckeditor/ckeditor5-angular):
 
 
 ```bash
 ```bash
 npm install --save @ckeditor/ckeditor5-angular
 npm install --save @ckeditor/ckeditor5-angular
 ```
 ```
 
 
-Install one of the {@link builds/guides/overview#available-builds official editor builds} or {@link builds/guides/development/custom-builds create a custom one} (e.g. if you want to install more plugins or customize something that cannot be controlled with the {@link builds/guides/integration/configuration editor configuration}).
+Install one of the {@link builds/guides/overview#available-builds official editor builds} or [create a custom one](#using-a-custom-ckeditor-5-build).
 
 
 Assuming that you picked [`@ckeditor/ckeditor5-build-classic`](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic):
 Assuming that you picked [`@ckeditor/ckeditor5-build-classic`](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic):
 
 
@@ -68,15 +68,16 @@ Finally, use the `<ckeditor>` tag in the template to run the rich text editor:
 
 
 Rebuild your application and CKEditor 5 should greet you with "Hello, world!".
 Rebuild your application and CKEditor 5 should greet you with "Hello, world!".
 
 
-### Note: Using the Document editor build
+### Using the Document editor build
 
 
-If you want to use the {@link framework/guides/document-editor Document editor build}, you need to {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create add the toolbar to the DOM manually}.
+If you want to use the {@link framework/guides/document-editor document editor build}, you need to {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create add the toolbar to the DOM manually}.
 
 
 ```ts
 ```ts
 import * as DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
 import * as DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
 
 
 @Component( {
 @Component( {
 	// ...
 	// ...
+} )
 export class MyComponent {
 export class MyComponent {
 	public Editor = DecoupledEditor;
 	public Editor = DecoupledEditor;
 
 
@@ -95,6 +96,57 @@ And then, in the template:
 <ckeditor [editor]="Editor" data="<p>Hello, world!</p>" (ready)="onReady($event)"></ckeditor>
 <ckeditor [editor]="Editor" data="<p>Hello, world!</p>" (ready)="onReady($event)"></ckeditor>
 ```
 ```
 
 
+### Using a custom CKEditor 5 build
+
+If you want to add more plugins to the existing build or customize something that cannot be controlled with the {@link builds/guides/integration/configuration editor configuration} you should create a custom build first, using the {@link builds/guides/development/custom-builds create a custom build guide}.
+
+You should finish the above tutorial with the generated `ckeditor.js` file (and corresponding translation files). In the next step you should copy it to the `src` directory and import it to the component file.
+
+```ts
+import * as Editor from 'path/to/the/ckeditor';
+
+@Component( {
+	// ...
+} )
+export class MyComponent {
+	public Editor = Editor;
+	// ...
+}
+```
+
+Note that to allow importing JavaScript files without providing their corresponding types you need to set `allowJs` to `true` in the `tsconfig.json` file. Also, make sure that you target `ES6` or higher, otherwise you are likely to end up with [a weird transpilation error](https://github.com/ckeditor/ckeditor5-angular/issues/20) in the production build.
+
+```json
+"compilerOptions": {
+	"allowJs": true,
+	"target": "es2015"
+	// other options
+}
+```
+
+<info-box>
+	If you cannot set the target higher than `es5`, try to set `"buildOptimizer": false` which will produce a bigger, but correct production build.
+</info-box>
+
+### Strict mode project tips
+
+If you have the strict mode set in your project, you need to specify types for CKEditor 5 packages. Otherwise you will get the `Could not find a declaration file for module` error.
+
+To fix that you need to create a TypeScript declaration file and declare modules that miss their types:
+
+```ts
+// typings.d.ts
+
+// You should specify the CKEditor 5 build you use here:
+declare module '@ckeditor/ckeditor5-build-classic' {
+	const ClassicEditorBuild: any;
+
+	export = ClassicEditorBuild;
+}
+```
+
+Unfortunately, CKEditor 5 builds do not ship with corresponding TypeScript typings yet. If you are interested in this topic you can add your vote or a comment [here](https://github.com/ckeditor/ckeditor5/issues/504).
+
 ## Integration with `ngModel`
 ## Integration with `ngModel`
 
 
 The component implements the [`ControlValueAccessor`](https://angular.io/api/forms/ControlValueAccessor) interface and works with the `ngModel`. Here is how to use it:
 The component implements the [`ControlValueAccessor`](https://angular.io/api/forms/ControlValueAccessor) interface and works with the `ngModel`. Here is how to use it:
@@ -121,7 +173,7 @@ The component implements the [`ControlValueAccessor`](https://angular.io/api/for
 
 
 ## Supported `@Input` properties
 ## Supported `@Input` properties
 
 
-The following `@Input` properties are supported by the CKEditor 5 component for Angular 2+:
+The following `@Input` properties are supported by the CKEditor 5 rich text editor component for Angular:
 
 
 ### `editor` (required)
 ### `editor` (required)
 
 
@@ -165,7 +217,7 @@ export class MyComponent {
 
 
 ### `tagName`
 ### `tagName`
 
 
-Specifies the tag name of the HTML element on which the editor will be created.
+The tag name of the HTML element on which the rich text editor will be created.
 
 
 The default tag is `<div>`.
 The default tag is `<div>`.
 
 
@@ -200,16 +252,17 @@ export class MyComponent {
 
 
 ## Supported `@Output` properties
 ## Supported `@Output` properties
 
 
-The following `@Output` properties are supported by the CKEditor 5 component for Angular 2+:
+The following `@Output` properties are supported by the CKEditor 5 rich text editor component for Angular:
 
 
 ### `ready`
 ### `ready`
 
 
-Fired when the editor is ready. It corresponds with the [`editor#ready`](https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html#event-ready) event. Fired with the editor instance.
+Fired when the editor is ready. It corresponds with the [`editor#ready`](https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html#event-ready) event.
+It is fired with the editor instance.
 
 
 ### `change`
 ### `change`
 
 
 Fired when the content of the editor has changed. It corresponds with the {@link module:engine/model/document~Document#event:change:data `editor.model.document#change:data`} event.
 Fired when the content of the editor has changed. It corresponds with the {@link module:engine/model/document~Document#event:change:data `editor.model.document#change:data`} event.
-Fired with an object containing the editor and the CKEditor 5 `change:data` event object.
+It is fired with an object containing the editor and the CKEditor 5 `change:data` event object.
 
 
 ```html
 ```html
 <ckeditor [editor]="Editor" (change)="onChange($event)"></ckeditor>
 <ckeditor [editor]="Editor" (change)="onChange($event)"></ckeditor>
@@ -237,30 +290,30 @@ export class MyComponent {
 ### `blur`
 ### `blur`
 
 
 Fired when the editing view of the editor is blurred. It corresponds with the {@link module:engine/view/document~Document#event:blur `editor.editing.view.document#blur`} event.
 Fired when the editing view of the editor is blurred. It corresponds with the {@link module:engine/view/document~Document#event:blur `editor.editing.view.document#blur`} event.
-Fired with an object containing the editor and the CKEditor 5 `blur` event data.
+It is fired with an object containing the editor and the CKEditor 5 `blur` event data.
 
 
 ### `focus`
 ### `focus`
 
 
 Fired when the editing view of the editor is focused. It corresponds with the {@link module:engine/view/document~Document#event:focus `editor.editing.view.document#focus`} event.
 Fired when the editing view of the editor is focused. It corresponds with the {@link module:engine/view/document~Document#event:focus `editor.editing.view.document#focus`} event.
-Fired with an object containing the editor and the CKEditor 5 `focus` event data.
+It is fired with an object containing the editor and the CKEditor 5 `focus` event data.
 
 
 ## Styling
 ## Styling
 
 
-The CKEditor 5 component for Angular can be styled using the component stylesheet or using a global stylesheet. Let's see how to set the CKEditor 5 component's height using these two approaches.
+The CKEditor 5 rich text editor component for Angular can be styled using the component stylesheet or using a global stylesheet. See how to set the CKEditor 5 component's height using these two approaches.
 
 
 ### Setting the height via the component stylesheet
 ### Setting the height via the component stylesheet
 
 
-First, create a (S)CSS file in the parent component's directory and style the given editor's part preceded by the `:host` and `::ng-deep` pseudo selectors.
+First, create a (S)CSS file in the parent component's directory and style the given editor's part preceded by the `:host` and `::ng-deep` pseudo selectors:
 
 
 ```css
 ```css
 /* src/app/app.component.css */
 /* src/app/app.component.css */
 
 
-:host ::ng-deep .ck-editor__editable {
+:host ::ng-deep .ck-editor__editable_inline {
 	min-height: 500px;
 	min-height: 500px;
 }
 }
 ```
 ```
 
 
-Then in the parent component add the relative path to the above stylesheet.
+Then in the parent component add the relative path to the above stylesheet:
 
 
 ```ts
 ```ts
 /* src/app/app.component.ts */
 /* src/app/app.component.ts */
@@ -278,12 +331,12 @@ To style the component using a global stylesheet, first, create it:
 ```css
 ```css
 /* src/styles.css */
 /* src/styles.css */
 
 
-.ck-editor__editable {
+.ck-editor__editable_inline {
 	min-height: 500px;
 	min-height: 500px;
 }
 }
 ```
 ```
 
 
-Then, add it in the `angular.json` configuration file.
+Then, add it in the `angular.json` configuration file:
 
 
 ```json
 ```json
 "architect": {
 "architect": {
@@ -299,7 +352,7 @@ Then, add it in the `angular.json` configuration file.
 
 
 ### Setting the placeholder
 ### Setting the placeholder
 
 
-To display {@link features/editor-placeholder the placeholder} in the main editable element simply set the `placeholder` field in the CKEditor 5 component configuration:
+To display {@link features/editor-placeholder the placeholder} in the main editable element, set the `placeholder` field in the CKEditor 5 rich text editor component configuration:
 
 
 ```ts
 ```ts
 @Component( {
 @Component( {
@@ -314,7 +367,7 @@ export class MyComponent {
 
 
 ## Localization
 ## Localization
 
 
-The CKEditor 5 component can be localized in two steps.
+The CKEditor 5 rich text editor component can be localized in two steps.
 
 
 ### 1. Loading translation files
 ### 1. Loading translation files
 
 
@@ -360,4 +413,4 @@ For advanced usage see the {@link features/ui-language Setting UI language} guid
 
 
 ## Contributing and reporting issues
 ## Contributing and reporting issues
 
 
-The source code of the rich text editor component for Angular 2+ is available on GitHub in https://github.com/ckeditor/ckeditor5-angular.
+The source code of the CKEditor 5 rich text editor component for Angular is available on GitHub in https://github.com/ckeditor/ckeditor5-angular.

+ 22 - 2
docs/builds/guides/frameworks/css.md

@@ -15,6 +15,8 @@ In this guide, you will learn how to address these integration issues and use th
 
 
 ## Compatibility with Bootstrap
 ## Compatibility with Bootstrap
 
 
+### Bootstrap modals
+
 We noticed that [Bootstrap](https://getbootstrap.com) modals cover the UI of the rich-text editor and break the input fields. Knowing that, you will need to take the following steps to get CKEditor 5 working in the Bootstrap environment:
 We noticed that [Bootstrap](https://getbootstrap.com) modals cover the UI of the rich-text editor and break the input fields. Knowing that, you will need to take the following steps to get CKEditor 5 working in the Bootstrap environment:
 
 
 * Configure the `z-index` of the floating editor UI (e.g. balloons) so it is displayed over the Bootstrap overlay.
 * Configure the `z-index` of the floating editor UI (e.g. balloons) so it is displayed over the Bootstrap overlay.
@@ -45,11 +47,11 @@ $( '#modal-container' ).modal( {
 
 
 ### Bootstrap table styles
 ### Bootstrap table styles
 
 
-There is also a known [issue](https://github.com/ckeditor/ckeditor5-table/issues/154) concerning table styles brought by Bootstrap breaking the table (widget) layout during editing. If you do not want additional space around edited tables when using Bootstrap, add the following styles to your application:
+There is also a known [issue](https://github.com/ckeditor/ckeditor5-table/issues/154) concerning table styles brought by Bootstrap breaking the table (widget) layout during editing. If you do not want any additional space around edited tables when using Bootstrap, add the following styles to your application:
 
 
 ```css
 ```css
 /*
 /*
- * Override the width of table set by Bootstrap content styles.
+ * Override the width of the table set by Bootstrap content styles.
  * See: https://github.com/ckeditor/ckeditor5-table/issues/154.
  * See: https://github.com/ckeditor/ckeditor5-table/issues/154.
  */
  */
 .ck-content .table {
 .ck-content .table {
@@ -80,6 +82,7 @@ If you want to use CKEditor 5 with [Materialize.css](https://materializecss.com/
 
 
 * Configure the base `z-index` of the floating editor UI so it is displayed over the Materialize modals.
 * Configure the base `z-index` of the floating editor UI so it is displayed over the Materialize modals.
 * Bring back the default `.ck-input` class appearance (because Materialize overrides it with a higher specificity).
 * Bring back the default `.ck-input` class appearance (because Materialize overrides it with a higher specificity).
+* Bring back the default `<ul>` and `<li>` appearance (because Materialize overrides it).
 * Configure modals so they stop "stealing" the focus from the rich-text editor input fields.
 * Configure modals so they stop "stealing" the focus from the rich-text editor input fields.
 
 
 Use the following CSS to address the issues with the `z-index` and selector specificity:
 Use the following CSS to address the issues with the `z-index` and selector specificity:
@@ -121,6 +124,23 @@ Use the following CSS to address the issues with the `z-index` and selector spec
 }
 }
 ```
 ```
 
 
+```css
+/*
+ * Bring back the default <ul> and <li> appearance.
+ *
+ * See: https://github.com/Dogfalo/materialize/blob/v1-dev/sass/components/_global.scss#L28-L37
+ */
+.ck.ck-content ul,
+.ck.ck-content ul li {
+  list-style-type: inherit;
+}
+
+.ck.ck-content ul {
+  /* Default user agent stylesheet, you can change it to your needs. */
+  padding-left: 40px;
+}
+```
+
 To change the behavior of the modals and prevent them from "stealing" the focus, use the [`dismissible: false`](https://materializecss.com/modals.html#options) option.
 To change the behavior of the modals and prevent them from "stealing" the focus, use the [`dismissible: false`](https://materializecss.com/modals.html#options) option.
 
 
 ```js
 ```js

+ 304 - 227
docs/builds/guides/frameworks/react.md

@@ -14,7 +14,7 @@ The easiest way to use CKEditor 5 in your React application is by choosing one o
 
 
 ## Quick start
 ## Quick start
 
 
-Install the [CKEditor 5 WYSIWYG editor component for React](https://www.npmjs.com/package/@ckeditor/ckeditor5-react) and the editor build of your choice.
+Install the [CKEditor 5 WYSIWYG editor component for React](https://www.npmjs.com/package/@ckeditor/ckeditor5-react) and the {@link builds/guides/overview#available-builds editor build of your choice}.
 
 
 Assuming that you picked [`@ckeditor/ckeditor5-build-classic`](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic):
 Assuming that you picked [`@ckeditor/ckeditor5-build-classic`](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic):
 
 
@@ -30,31 +30,31 @@ import CKEditor from '@ckeditor/ckeditor5-react';
 import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
 import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
 
 
 class App extends Component {
 class App extends Component {
-    render() {
-        return (
-            <div className="App">
-                <h2>Using CKEditor 5 build in React</h2>
-                <CKEditor
-                    editor={ ClassicEditor }
-                    data="<p>Hello from CKEditor 5!</p>"
-                    onInit={ editor => {
-                        // You can store the "editor" and use when it is needed.
-                        console.log( 'Editor is ready to use!', editor );
-                    } }
-                    onChange={ ( event, editor ) => {
-                        const data = editor.getData();
-                        console.log( { event, editor, data } );
-                    } }
-                    onBlur={ editor => {
-                        console.log( 'Blur.', editor );
-                    } }
-                    onFocus={ editor => {
-                        console.log( 'Focus.', editor );
-                    } }
-                />
-            </div>
-        );
-    }
+	render() {
+		return (
+			<div className="App">
+				<h2>Using CKEditor 5 build in React</h2>
+				<CKEditor
+					editor={ ClassicEditor }
+					data="<p>Hello from CKEditor 5!</p>"
+					onInit={ editor => {
+						// You can store the "editor" and use when it is needed.
+						console.log( 'Editor is ready to use!', editor );
+					} }
+					onChange={ ( event, editor ) => {
+						const data = editor.getData();
+						console.log( { event, editor, data } );
+					} }
+					onBlur={ ( event, editor ) => {
+						console.log( 'Blur.', editor );
+					} }
+					onFocus={ ( event, editor ) => {
+						console.log( 'Focus.', editor );
+					} }
+				/>
+			</div>
+		);
+	}
 }
 }
 
 
 export default App;
 export default App;
@@ -67,16 +67,16 @@ The `<CKEditor>` component supports the following properties:
 * `editor` (required) &ndash; The {@link module:core/editor/editor~Editor `Editor`} constructor to use.
 * `editor` (required) &ndash; The {@link module:core/editor/editor~Editor `Editor`} constructor to use.
 * `data` &ndash; The initial data for the created editor. See the {@link builds/guides/integration/basic-api#interacting-with-the-editor Basic API} guide.
 * `data` &ndash; The initial data for the created editor. See the {@link builds/guides/integration/basic-api#interacting-with-the-editor Basic API} guide.
 * `config` &ndash; The editor configuration. See the {@link builds/guides/integration/configuration Configuration} guide.
 * `config` &ndash; The editor configuration. See the {@link builds/guides/integration/configuration Configuration} guide.
-* `onChange` &ndash; A function called when the editor's data has changed. See the {@link module:engine/model/document~Document#event:change:data `editor.model.document#change:data`} event.
+* `onInit` &ndash; A function called when the editor was initialized. It receives the initialized {@link module:core/editor/editor~Editor `editor`} as a parameter.
+* `disabled` &ndash; A Boolean value. The {@link module:core/editor/editor~Editor `editor`} is being switched to read-only mode if the property is set to `true`.
+* `onChange` &ndash; A function called when the editor data has changed. See the {@link module:engine/model/document~Document#event:change:data `editor.model.document#change:data`} event.
+* `onBlur` &ndash; A function called when the editor was blurred. See the {@link module:engine/view/document~Document#event:blur `editor.editing.view.document#blur`} event.
+* `onFocus` &ndash; A function called when the editor was focused. See the {@link module:engine/view/document~Document#event:focus `editor.editing.view.document#focus`} event.
 
 
-	The callback receives two parameters:
+The editor events callbacks (`onChange`, `onBlur`, `onFocus`) receive two parameters:
 
 
-	1. An {@link module:utils/eventinfo~EventInfo `EventInfo`} object,
-	2. An {@link module:core/editor/editor~Editor `Editor`} instance.
-* `onInit` &ndash; A function called when the editor was initialized. It receives the initialized {@link module:core/editor/editor~Editor `editor`} as a parameter.
-* `onBlur` &ndash; A function called when the editor was blurred. It receives the blurred {@link module:core/editor/editor~Editor `editor`} as a parameter.
-* `onFocus` &ndash; A function called when the editor was focused. It receives the focused {@link module:core/editor/editor~Editor `editor`} as a parameter.
-* `disabled` &ndash; A boolean. The {@link module:core/editor/editor~Editor `editor`} is being switched to read-only mode if the property is set to `true`.
+1. An {@link module:utils/eventinfo~EventInfo `EventInfo`} object.
+2. An {@link module:core/editor/editor~Editor `Editor`} instance.
 
 
 ### Customizing the builds
 ### Customizing the builds
 
 
@@ -95,7 +95,7 @@ There are two main ways to do that.
 
 
 ### Note: Building for production
 ### Note: Building for production
 
 
-If you still work with `create-react-app@1` or use a custom configuration for you application which still uses `webpack@3`, you will need to adjust the `UglifyJsPlugin` option to make CKEditor 5 compatible with this setup. CKEditor 5 builds use ES6 so the default JavaScript minifier of `webpack@3` and `create-react-app@1` is not able to digest them.
+If you still work with `create-react-app@1` or use a custom configuration for you application that still uses `webpack@3`, you will need to adjust the `UglifyJsPlugin` option to make CKEditor 5 compatible with this setup. CKEditor 5 builds use ES6 so the default JavaScript minifier of `webpack@3` and `create-react-app@1` is not able to digest them.
 
 
 To do that, you need to first [eject the configuration](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-eject) from the setup created via `create-react-app` (assuming that you use it):
 To do that, you need to first [eject the configuration](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-eject) from the setup created via `create-react-app` (assuming that you use it):
 
 
@@ -113,27 +113,27 @@ If you use the {@link framework/guides/document-editor Document editor}, you nee
 import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
 import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
 
 
 class App extends Component {
 class App extends Component {
-    render() {
-        return (
-            <div className="App">
-                <h2>CKEditor 5 using a custom build - DecoupledEditor</h2>
-                <CKEditor
-                    onInit={ editor => {
-                        console.log( 'Editor is ready to use!', editor );
-
-                        // Insert the toolbar before the editable area.
-                        editor.ui.getEditableElement().parentElement.insertBefore(
-                            editor.ui.view.toolbar.element,
-                            editor.ui.getEditableElement()
-                        );
-                    } }
-                    onChange={ ( event, editor ) => console.log( { event, editor } ) }
-                    editor={ DecoupledEditor }
-                    data="<p>Hello from CKEditor 5's DecoupledEditor!</p>"
-                    config={ /* the editor configuration */ }
-                />
-        );
-    }
+	render() {
+		return (
+			<div className="App">
+				<h2>CKEditor 5 using a custom build - DecoupledEditor</h2>
+				<CKEditor
+					onInit={ editor => {
+						console.log( 'Editor is ready to use!', editor );
+
+						// Insert the toolbar before the editable area.
+						editor.ui.getEditableElement().parentElement.insertBefore(
+							editor.ui.view.toolbar.element,
+							editor.ui.getEditableElement()
+						);
+					} }
+					onChange={ ( event, editor ) => console.log( { event, editor } ) }
+					editor={ DecoupledEditor }
+					data="<p>Hello from CKEditor 5's DecoupledEditor!</p>"
+					config={ /* the editor configuration */ }
+				/>
+		);
+	}
 }
 }
 
 
 export default App;
 export default App;
@@ -147,47 +147,47 @@ This guide assumes that you are using [Create React App CLI](https://github.com/
 
 
 ### Using `create-react-app@2`
 ### Using `create-react-app@2`
 
 
-The configuration needs to be ejected so you are able to customize the webpack configuration. In order to be able to build CKEditor 5 from source you need to tell webpack how to handle CKEditor 5's SVG and CSS files (by adding loaders configuration). Additionally, you need to exclude CKEditor 5's source from existing loaders.
+The configuration needs to be ejected to make it possible to customize the webpack configuration. In order to be able to build CKEditor 5 from source, you need to tell webpack how to handle CKEditor 5's SVG and CSS files (by adding loaders configuration). Additionally, you need to exclude the CKEditor 5 source from existing loaders.
 
 
 <info-box>
 <info-box>
   You can see all the changes described below in this example project: https://github.com/ckeditor/ckeditor5-react-example/commits/master.
   You can see all the changes described below in this example project: https://github.com/ckeditor/ckeditor5-react-example/commits/master.
 </info-box>
 </info-box>
 
 
-Let's create a sample application using `create-react-app@2` first:
+Create a sample application using `create-react-app@2` first:
 
 
 ```bash
 ```bash
 npx create-react-app ckeditor5-react-example && cd ckeditor5-react-example
 npx create-react-app ckeditor5-react-example && cd ckeditor5-react-example
 ```
 ```
 
 
-Now, you can eject the configuration (you can find more information about ejecting [here](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-eject)):
+Now you can eject the configuration (you can find more information about ejecting [here](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-eject)):
 
 
 ```bash
 ```bash
 yarn eject
 yarn eject
 
 
-# For some strange reasons this is needed too
-# (https://github.com/facebook/create-react-app/issues/6099)
+# For some strange reasons this is needed, too
+# (https://github.com/facebook/create-react-app/issues/6099).
 yarn add @babel/plugin-transform-react-jsx @babel/plugin-transform-react-jsx-self
 yarn add @babel/plugin-transform-react-jsx @babel/plugin-transform-react-jsx-self
 ```
 ```
 
 
 #### Installing missing dependencies
 #### Installing missing dependencies
 
 
-Before we will start modifying the webpack configuration, let's first install a couple of CKEditor 5 dependencies that you will need:
+Before you start modifying the webpack configuration, first install some CKEditor 5 dependencies that you will need:
 
 
 ```bash
 ```bash
 yarn add \
 yarn add \
-  raw-loader \
-  @ckeditor/ckeditor5-dev-utils \
-  @ckeditor/ckeditor5-theme-lark \
-  @ckeditor/ckeditor5-react \
-  @ckeditor/ckeditor5-editor-classic \
-  @ckeditor/ckeditor5-essentials \
-  @ckeditor/ckeditor5-paragraph \
-  @ckeditor/ckeditor5-basic-styles
+	raw-loader@3 \
+	@ckeditor/ckeditor5-dev-utils \
+	@ckeditor/ckeditor5-theme-lark \
+	@ckeditor/ckeditor5-react \
+	@ckeditor/ckeditor5-editor-classic \
+	@ckeditor/ckeditor5-essentials \
+	@ckeditor/ckeditor5-paragraph \
+	@ckeditor/ckeditor5-basic-styles
 ```
 ```
 
 
 #### Modifying webpack configuration
 #### Modifying webpack configuration
 
 
-Once you ejected the configuration and installed dependencies, you can now edit the webpack config (`config/webpack.config.js`).
+Once you ejected the configuration and installed dependencies, you can now edit the webpack configuration (`config/webpack.config.js`).
 
 
 First, import an object that creates the configuration for PostCSS:
 First, import an object that creates the configuration for PostCSS:
 
 
@@ -195,94 +195,94 @@ First, import an object that creates the configuration for PostCSS:
 const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
 const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
 ```
 ```
 
 
-Then, add two new elements to the exported object under the `module.rules` array (as new items of the `oneOf` array). These are SVG and CSS loaders required to handle CKEditor 5 source:
+Then, add two new elements to the exported object under the `module.rules` array (as new items of the `oneOf` array). These are SVG and CSS loaders required to handle the CKEditor 5 source:
 
 
 ```js
 ```js
 {
 {
-  test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
-  use: [ 'raw-loader' ]
+	test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+	use: [ 'raw-loader' ]
 },
 },
 {
 {
-  test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  use: [
-    {
-      loader: 'style-loader',
-      options: {
-        singleton: true
-      }
-    },
-    {
-      loader: 'postcss-loader',
-      options: styles.getPostCssConfig( {
-        themeImporter: {
-          themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
-        },
-        minify: true
-      } )
-    }
-  ]
+	test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
+	use: [
+		{
+			loader: 'style-loader',
+			options: {
+				injectType: 'singletonStyleTag'
+			}
+		},
+		{
+			loader: 'postcss-loader',
+			options: styles.getPostCssConfig( {
+				themeImporter: {
+					themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
+				},
+				minify: true
+			} )
+		}
+	]
 },
 },
 ```
 ```
 
 
-Now, you need to exclude CSS files used by CKEditor 5 from project's CSS loader.
+Now you need to exclude CSS files used by CKEditor 5 from the project's CSS loader.
 
 
 First, find a loader that starts its definition with the following code: `test: cssRegex` and modify it:
 First, find a loader that starts its definition with the following code: `test: cssRegex` and modify it:
 
 
 ```js
 ```js
 {
 {
-  test: cssRegex,
-  exclude: [
-    cssModuleRegex,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  ],
-  // (...)
+	test: cssRegex,
+	exclude: [
+		cssModuleRegex,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
+	],
+	// (...)
 }
 }
 ```
 ```
 
 
-Below it, you will find another loader that handles CSS files. We need to disable it for CKEditor 5 CSS as well. Its definition starts with `test: cssModuleRegex`:
+Below it, you will find another loader that handles CSS files. You need to disable it for CKEditor 5 CSS as well. Its definition starts with `test: cssModuleRegex`:
 
 
 ```js
 ```js
 {
 {
-  test: cssModuleRegex,
-  exclude: [
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  ],
-  // (...)
+	test: cssModuleRegex,
+	exclude: [
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
+	],
+	// (...)
 }
 }
 ```
 ```
 
 
-Finally, exclude CKEditor 5 SVG and CSS files from `file-loader` . Find the last item in the `module.rules` array which should be the `file-loader` configuration and modify it so it looks like this:
+Finally, exclude CKEditor 5 SVG and CSS files from `file-loader` . Find the last item in the `module.rules` array which should be the `file-loader` configuration, and modify it so it looks like this:
 
 
 ```js
 ```js
 {
 {
-  loader: require.resolve('file-loader'),
-  // Exclude `js` files to keep "css" loader working as it injects
-  // its runtime that would otherwise be processed through "file" loader.
-  // Also exclude `html` and `json` extensions so they get processed
-  // by webpacks internal loaders.
-  exclude: [
-    /\.(js|mjs|jsx|ts|tsx)$/,
-    /\.html$/,
-    /\.json$/,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/
-  ],
-  options: {
-    name: 'static/media/[name].[hash:8].[ext]',
-  }
+	loader: require.resolve( 'file-loader' ),
+	// Exclude `js` files to keep the "css" loader working as it injects
+	// its runtime that would otherwise be processed through the "file" loader.
+	// Also exclude `html` and `json` extensions so they get processed
+	// by webpack's internal loaders.
+	exclude: [
+		/\.(js|mjs|jsx|ts|tsx)$/,
+		/\.html$/,
+		/\.json$/,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/
+	],
+	options: {
+		name: 'static/media/[name].[hash:8].[ext]',
+	}
 }
 }
 ```
 ```
 
 
 #### Using CKEditor 5 source
 #### Using CKEditor 5 source
 
 
-Once your configuration is updated, you can now use CKEditor 5 directly from source. Let's test it by editing `src/App.js`:
+Once your configuration is updated, you can now use CKEditor 5 directly from source. Test it by editing `src/App.js`:
 
 
 ```jsx
 ```jsx
 import React, { Component } from 'react';
 import React, { Component } from 'react';
 
 
 import CKEditor from '@ckeditor/ckeditor5-react';
 import CKEditor from '@ckeditor/ckeditor5-react';
 
 
-// NOTE: We use editor from source (not a build)!
+// NOTE: Use the editor from source (not a build)!
 import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 
 
 import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
 import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
@@ -291,37 +291,37 @@ import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 
 
 const editorConfiguration = {
 const editorConfiguration = {
-  plugins: [ Essentials, Bold, Italic, Paragraph ],
-  toolbar: [ 'bold', 'italic' ]
+	plugins: [ Essentials, Bold, Italic, Paragraph ],
+	toolbar: [ 'bold', 'italic' ]
 };
 };
 
 
 class App extends Component {
 class App extends Component {
-  render() {
-    return (
-      <div className="App">
-        <h2>Using CKEditor 5 from source in React</h2>
-        <CKEditor
-          editor={ ClassicEditor }
-          config={ editorConfiguration }
-          data="<p>Hello from CKEditor 5!</p>"
-          onInit={ editor => {
-            // You can store the "editor" and use when it is needed.
-            console.log( 'Editor is ready to use!', editor );
-          } }
-          onChange={ ( event, editor ) => {
-            const data = editor.getData();
-            console.log( { event, editor, data } );
-          } }
-          onBlur={ editor => {
-            console.log( 'Blur.', editor );
-          } }
-          onFocus={ editor => {
-            console.log( 'Focus.', editor );
-          } }
-        />
-      </div>
-    );
-  }
+	render() {
+		return (
+			<div className="App">
+				<h2>Using CKEditor 5 from source in React</h2>
+				<CKEditor
+					editor={ ClassicEditor }
+					config={ editorConfiguration }
+					data="<p>Hello from CKEditor 5!</p>"
+					onInit={ editor => {
+						// You can store the "editor" and use when it is needed.
+						console.log( 'Editor is ready to use!', editor );
+					} }
+					onChange={ ( event, editor ) => {
+						const data = editor.getData();
+						console.log( { event, editor, data } );
+					} }
+					onBlur={ ( event, editor ) => {
+						console.log( 'Blur.', editor );
+					} }
+					onFocus={ ( event, editor ) => {
+						console.log( 'Focus.', editor );
+					} }
+				/>
+			</div>
+		);
+	}
 }
 }
 
 
 export default App;
 export default App;
@@ -355,7 +355,7 @@ Now you can eject the configuration:
 npm run eject
 npm run eject
 ```
 ```
 
 
-The configuration needs to be ejected in order for you to be able to customize webpack configuration. To be able to build CKEditor 5 from source you must load inline SVG images and handle CKEditor 5's CSS as well as correctly minify the ES6 source.
+The configuration needs to be ejected to make it possible to customize the webpack configuration. To be able to build CKEditor 5 from source you must load inline SVG images and handle CKEditor 5's CSS as well as correctly minify the ES6 source.
 
 
 <info-box>
 <info-box>
 	You can find more information about ejecting [here](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-eject).
 	You can find more information about ejecting [here](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-eject).
@@ -400,26 +400,26 @@ In the end, the entire plugin definition should look as follows:
 ```js
 ```js
 // Minify the code.
 // Minify the code.
 new UglifyJsWebpackPlugin( {
 new UglifyJsWebpackPlugin( {
-  uglifyOptions: {
-    compress: {
-      warnings: false,
-      // Disabled because of an issue with Uglify breaking seemingly valid code:
-      // https://github.com/facebookincubator/create-react-app/issues/2376
-      // Pending further investigation:
-      // https://github.com/mishoo/UglifyJS2/issues/2011
-      comparisons: false,
-    },
-    mangle: {
-        safari10: true,
-    },
-    output: {
-        comments: false,
-        // Turned on because emoji and regex is not minified properly using default
-        // https://github.com/facebookincubator/create-react-app/issues/2488
-        ascii_only: true,
-    },
-  },
-  sourceMap: shouldUseSourceMap,
+	uglifyOptions: {
+		compress: {
+			warnings: false,
+			// Disabled because of an issue with Uglify breaking seemingly valid code:
+			// https://github.com/facebookincubator/create-react-app/issues/2376
+			// Pending further investigation:
+			// https://github.com/mishoo/UglifyJS2/issues/2011
+			comparisons: false,
+		},
+		mangle: {
+			safari10: true,
+		},
+		output: {
+			comments: false,
+			// Turned on because emoji and regex is not minified properly using default
+			// https://github.com/facebookincubator/create-react-app/issues/2488
+			ascii_only: true,
+		},
+	},
+	sourceMap: shouldUseSourceMap,
 } )
 } )
 ```
 ```
 
 
@@ -444,28 +444,28 @@ Then add two new elements to the exported object under the `module.rules` array
 
 
 ```js
 ```js
 {
 {
-  test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
-  use: [ 'raw-loader' ]
+	test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+	use: [ 'raw-loader' ]
 },
 },
 {
 {
-  test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  use: [
-    {
-      loader: 'style-loader',
-      options: {
-        singleton: true
-      }
-    },
-    {
-      loader: 'postcss-loader',
-      options: styles.getPostCssConfig( {
-        themeImporter: {
-          themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
-        },
-        minify: true
-      } )
-    }
-  ]
+	test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
+	use: [
+		{
+			loader: 'style-loader',
+			options: {
+				injectType: 'singletonStyleTag'
+			}
+		},
+		{
+			loader: 'postcss-loader',
+			options: styles.getPostCssConfig( {
+				themeImporter: {
+					themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
+				},
+				minify: true
+			} )
+		}
+	]
 },
 },
 ```
 ```
 
 
@@ -473,9 +473,9 @@ Exclude CSS files used by CKEditor 5 from project's CSS loader:
 
 
 ```js
 ```js
 {
 {
-  test: /\.css$/,
-  exclude: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  // (...)
+	test: /\.css$/,
+	exclude: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
+	// (...)
 }
 }
 ```
 ```
 
 
@@ -483,21 +483,21 @@ And exclude CKEditor 5 SVG and CSS files from `file-loader` because these files
 
 
 ```js
 ```js
 {
 {
-  loader: require.resolve('file-loader'),
-  // Exclude `js` files to keep the "css" loader working as it injects
-  // its runtime that would otherwise be processed through the "file" loader.
-  // Also exclude `html` and `json` extensions so they get processed
-  // by webpack's internal loaders.
-  exclude: [
-    /\.(js|jsx|mjs)$/,
-    /\.html$/,
-    /\.json$/,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/
-  ],
-  options: {
-    name: 'static/media/[name].[hash:8].[ext]'
-  }
+	loader: require.resolve( 'file-loader' ),
+	// Exclude `js` files to keep the "css" loader working as it injects
+	// its runtime that would otherwise be processed through the "file" loader.
+	// Also exclude `html` and `json` extensions so they get processed
+	// by webpack's internal loaders.
+	exclude: [
+		/\.(js|jsx|mjs)$/,
+		/\.html$/,
+		/\.json$/,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/
+	],
+	options: {
+		name: 'static/media/[name].[hash:8].[ext]'
+	}
 }
 }
 ```
 ```
 
 
@@ -537,28 +537,105 @@ import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 import Heading from '@ckeditor/ckeditor5-heading/src/heading';
 import Heading from '@ckeditor/ckeditor5-heading/src/heading';
 
 
 class App extends Component {
 class App extends Component {
-    render() {
-        return (
-            <div className="App">
-                <h2>Using CKEditor 5 Framework in React</h2>
-                <CKEditor
-                    onInit={ editor => console.log( 'Editor is ready to use!', editor ) }
-                    onChange={ ( event, editor ) => console.log( { event, editor } ) }
-                    config={ {
-                        plugins: [ Essentials, Paragraph, Bold, Italic, Heading ],
-                        toolbar: [ 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo', ]
-                    } }
-                    editor={ ClassicEditor }
-                    data="<p>Hello from CKEditor 5!</p>"
-                />
-            </div>
-        );
-    }
+	render() {
+		return (
+			<div className="App">
+				<h2>Using CKEditor 5 Framework in React</h2>
+				<CKEditor
+					onInit={ editor => console.log( 'Editor is ready to use!', editor ) }
+					onChange={ ( event, editor ) => console.log( { event, editor } ) }
+					config={ {
+						plugins: [ Essentials, Paragraph, Bold, Italic, Heading ],
+						toolbar: [ 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo', ]
+					} }
+					editor={ ClassicEditor }
+					data="<p>Hello from CKEditor 5!</p>"
+				/>
+			</div>
+		);
+	}
 }
 }
 
 
 export default App;
 export default App;
 ```
 ```
 
 
+## Localization
+
+CKEditor 5 supports {@link features/ui-language multiple UI languages}, and so does the official React component. Follow the instructions below to translate CKEditor 5 in your React application.
+
+### Ready-to-use builds
+
+When using one of the {@link builds/guides/overview#available-builds official editor builds}, you need to import the translations first:
+
+```js
+import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
+
+// Import translations for the German language.
+import '@ckeditor/ckeditor5-build-classic/build/translations/de';
+
+// ...
+```
+
+Then, {@link builds/guides/integration/configuration configure} the language of the editor in the component:
+
+```jsx
+<CKEditor
+	config={ {
+		// Use the German language for this editor.
+		language: 'de',
+
+		// ...
+	} }
+	editor={ ClassicEditor }
+	data="<p>Hello from CKEditor 5!</p>"
+/>
+```
+
+For more information, please refer to the {@link features/ui-language "Setting UI language"} guide.
+
+### CKEditor 5 built from source
+
+Using the editor [built from source](#integrating-ckeditor-5-built-from-source) requires you to modify the webpack configuration. First, install the [official webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin) that allows localizing editor builds:
+
+```bash
+npm install @ckeditor/ckeditor5-dev-webpack-plugin --save-dev
+```
+
+Then, add the installed plugin to the webpack configuration:
+
+<info-box>
+	We assume that you use `create-react-app@2`. For earlier versions, make sure to modify [both webpack configuration files](#changes-required-in-webpacks-production-configuration).
+</info-box>
+
+```js
+// webpack.config.js
+'use strict';
+
+// ...
+const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
+
+module.exports = {
+	// ...
+
+	plugins: [
+		// ....
+
+		new CKEditorWebpackPlugin( {
+			// The UI language. Language codes follow the https://en.wikipedia.org/wiki/ISO_639-1 format.
+			language: 'de'
+		} ),
+
+		// ....
+	],
+
+	// ...
+};
+```
+
+After building the application, CKEditor 5 will run with the UI translated to the specified language.
+
+For more information, please refer to the {@link features/ui-language "Setting UI language"} guide.
+
 ## Contributing and reporting issues
 ## Contributing and reporting issues
 
 
 The source code of rich text editor component for React is available on GitHub in https://github.com/ckeditor/ckeditor5-react.
 The source code of rich text editor component for React is available on GitHub in https://github.com/ckeditor/ckeditor5-react.

+ 111 - 23
docs/builds/guides/frameworks/vuejs.md

@@ -21,7 +21,7 @@ Additionally, you can [integrate CKEditor 5 from source](#using-ckeditor-from-so
 
 
 ## Quick start
 ## Quick start
 
 
-Install the [CKEditor 5 WYSIWYG editor component for Vue.js](https://www.npmjs.com/package/@ckeditor/ckeditor5-vue) and the {@link builds/guides/overview#available-builds build of your choice}.
+Install the [CKEditor 5 WYSIWYG editor component for Vue.js](https://www.npmjs.com/package/@ckeditor/ckeditor5-vue) and the {@link builds/guides/overview#available-builds editor build of your choice}.
 
 
 Assuming that you picked [`@ckeditor/ckeditor5-build-classic`](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic):
 Assuming that you picked [`@ckeditor/ckeditor5-build-classic`](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic):
 
 
@@ -192,13 +192,14 @@ npm install --save \
     @ckeditor/ckeditor5-vue \
     @ckeditor/ckeditor5-vue \
     @ckeditor/ckeditor5-dev-webpack-plugin \
     @ckeditor/ckeditor5-dev-webpack-plugin \
     @ckeditor/ckeditor5-dev-utils \
     @ckeditor/ckeditor5-dev-utils \
-    postcss-loader \
+    postcss-loader@3 \
     raw-loader@0.5.1
     raw-loader@0.5.1
 ```
 ```
 
 
 Edit the `vue.config.js` file and use the following configuration. If the file is not present, create it in the root of the application (i.e. next to `package.json`):
 Edit the `vue.config.js` file and use the following configuration. If the file is not present, create it in the root of the application (i.e. next to `package.json`):
 
 
 ```js
 ```js
+const path = require( 'path' );
 const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
 const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
 const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
 const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
 
 
@@ -220,24 +221,11 @@ module.exports = {
 		]
 		]
 	},
 	},
 
 
-	css: {
-		loaderOptions: {
-			// Various modules in the CKEditor source code import .css files.
-			// These files must be transpiled using PostCSS in order to load properly.
-			postcss: styles.getPostCssConfig( {
-				themeImporter: {
-					themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
-				},
-				minify: true
-			} )
-		}
-	},
-
+	// Vue CLI would normally use its own loader to load .svg and .css files, however:
+	//	1. The icons used by CKEditor must be loaded using raw-loader,
+	//	2. The CSS used by CKEditor must be transpiled using PostCSS to load properly.
 	chainWebpack: config => {
 	chainWebpack: config => {
-		// Vue CLI would normally use its own loader to load .svg files. The icons used by
-		// CKEditor should be loaded using raw-loader instead.
-
-		// Get the default rule for *.svg files.
+		// (1.) To handle editor icons, get the default rule for *.svg files first:
 		const svgRule = config.module.rule( 'svg' );
 		const svgRule = config.module.rule( 'svg' );
 
 
 		// Then you can either:
 		// Then you can either:
@@ -247,7 +235,7 @@ module.exports = {
 		//		svgRule.uses.clear();
 		//		svgRule.uses.clear();
 		//
 		//
 		// * or exclude ckeditor directory from node_modules:
 		// * or exclude ckeditor directory from node_modules:
-		svgRule.exclude.add( __dirname + '/node_modules/@ckeditor' );
+		svgRule.exclude.add( path.join( __dirname, 'node_modules', '@ckeditor' ) );
 
 
 		// Add an entry for *.svg files belonging to CKEditor. You can either:
 		// Add an entry for *.svg files belonging to CKEditor. You can either:
 		//
 		//
@@ -261,10 +249,30 @@ module.exports = {
 			.test( /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/ )
 			.test( /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/ )
 			.use( 'raw-loader' )
 			.use( 'raw-loader' )
 			.loader( 'raw-loader' );
 			.loader( 'raw-loader' );
+
+		// (2.) Transpile the .css files imported by the editor using PostCSS.
+		// Make sure only the CSS belonging to ckeditor5-* packages is processed this way.
+		config.module
+			.rule( 'cke-css' )
+			.test( /ckeditor5-[^/\\]+[/\\].+\.css$/ )
+			.use( 'postcss-loader' )
+			.loader( 'postcss-loader' )
+			.tap( () => {
+				return styles.getPostCssConfig( {
+					themeImporter: {
+						themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' ),
+					},
+					minify: true
+				} );
+			} );
 	}
 	}
 };
 };
 ```
 ```
 
 
+<info-box>
+    By default, the Vue CLI uses [`file-loader`](https://webpack.js.org/loaders/file-loader/) for all SVG files. The `file-loader` copies the file to the output directory and resolves imports into URLs. The CKEditor's UI components use SVG {@link module:ui/icon/iconview~IconView#content source directly} so the theme icons must be loaded using [`raw-loader`](https://webpack.js.org/loaders/raw-loader). If your project uses different approach then CKEditor's UI library you must create different webpack loader rules for your project SVG files and CKEditor's ones.
+</info-box>
+
 ### Using the editor from source
 ### Using the editor from source
 
 
 Having configured `vue.config.js`, you can choose the building blocks of your editor. Install the packages necessary for your integration:
 Having configured `vue.config.js`, you can choose the building blocks of your editor. Install the packages necessary for your integration:
@@ -274,9 +282,9 @@ npm install --save \
 	@ckeditor/ckeditor5-editor-classic \
 	@ckeditor/ckeditor5-editor-classic \
 	@ckeditor/ckeditor5-essentials \
 	@ckeditor/ckeditor5-essentials \
 	@ckeditor/ckeditor5-basic-styles \
 	@ckeditor/ckeditor5-basic-styles \
-	@ckeditor/ckeditor5-basic-styles \
 	@ckeditor/ckeditor5-link \
 	@ckeditor/ckeditor5-link \
-	@ckeditor/ckeditor5-paragraph
+	@ckeditor/ckeditor5-paragraph \
+	@ckeditor/ckeditor5-theme-lark
 ```
 ```
 
 
 You can use more packages, depending on which features are needed in your application.
 You can use more packages, depending on which features are needed in your application.
@@ -380,6 +388,86 @@ Since accessing the editor toolbar is not possible until after the editor instan
 </script>
 </script>
 ```
 ```
 
 
+## Localization
+
+CKEditor 5 supports {@link features/ui-language multiple UI languages}, and so does the official Vue.js component. Follow the instructions below to translate CKEditor 5 in your Vue.js application.
+
+### Ready-to-use builds
+
+When using one of the {@link builds/guides/overview#available-builds official editor builds}, you need to import the translations first.
+
+* When using a [direct script include](#direct-script-include):
+	```html
+	<!-- Import translations for the German language. -->
+	<script src="../node_modules/@ckeditor/ckeditor5-build-classic/build/translations/de.js"></script>
+	<script src="../node_modules/@ckeditor/ckeditor5-build-classic/build/ckeditor.js"></script>
+	<script src="../node_modules/@ckeditor/ckeditor5-vue/dist/ckeditor.js"></script>
+	```
+* When using [ES6 modules](#using-es6-modules):
+	```js
+	import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
+
+	// Import translations for the German language.
+	import '@ckeditor/ckeditor5-build-classic/build/translations/de';
+	```
+
+Then, {@link builds/guides/integration/configuration configure} the language of the editor in the component:
+
+```html
+<ckeditor :editor="editor" v-model="editorData" :config="editorConfig"></ckeditor>
+```
+
+```js
+export default {
+	name: 'app',
+	data() {
+		return {
+			editor: ClassicEditor,
+			editorData: '<p>Content of the editor.</p>',
+			editorConfig: {
+				// Run the editor with the German UI.
+				language: 'de'
+			}
+		};
+	}
+}
+```
+
+For more information, please refer to the {@link features/ui-language "Setting UI language"} guide.
+
+### CKEditor 5 built from source
+
+Using the editor [built from source](#using-ckeditor-from-source) requires you to modify the webpack configuration. Pass the `language` (also `additionalLanguages`) to the constructor of  [`CKEditorWebpackPlugin`](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin) to localize your editor:
+
+```js
+// vue.config.js
+// ...
+
+const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
+
+// ...
+
+module.exports = {
+	// ...
+
+	configureWebpack: {
+		plugins: [
+			// CKEditor needs its own plugin to be built using webpack.
+			new CKEditorWebpackPlugin( {
+				// The UI language. Language codes follow the https://en.wikipedia.org/wiki/ISO_639-1 format.
+				language: 'de'
+			} )
+		]
+	},
+
+	// ...
+}
+```
+
+After building the application, CKEditor 5 will run with the UI translated to the specified language.
+
+For more information, please refer to the {@link features/ui-language "Setting UI language"} guide.
+
 ## Component directives
 ## Component directives
 
 
 ### `editor`
 ### `editor`
@@ -512,7 +600,7 @@ Specifies the {@link module:core/editor/editorconfig~EditorConfig configuration}
 			return {
 			return {
 				editor: ClassicEditor,
 				editor: ClassicEditor,
 				editorConfig: {
 				editorConfig: {
-					toolbar: [ 'bold', 'italic', '|' 'link' ]
+					toolbar: [ 'bold', 'italic', '|', 'link' ]
 				}
 				}
 			};
 			};
 		}
 		}

+ 48 - 14
docs/builds/guides/integration/advanced-setup.md

@@ -99,9 +99,9 @@ The second step is to install dependencies needed to build the editor. The list
 npm install --save \
 npm install --save \
 	@ckeditor/ckeditor5-dev-webpack-plugin \
 	@ckeditor/ckeditor5-dev-webpack-plugin \
 	@ckeditor/ckeditor5-dev-utils \
 	@ckeditor/ckeditor5-dev-utils \
-	postcss-loader \
-	raw-loader \
-	style-loader \
+	postcss-loader@3 \
+	raw-loader@3 \
+	style-loader@1 \
 	webpack@4 \
 	webpack@4 \
 	webpack-cli@3 \
 	webpack-cli@3 \
 ```
 ```
@@ -133,21 +133,16 @@ module.exports = {
 	module: {
 	module: {
 		rules: [
 		rules: [
 			{
 			{
-				// Or /ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/ if you want to limit this loader
-				// to CKEditor 5 icons only.
-				test: /\.svg$/,
-
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
 				use: [ 'raw-loader' ]
 				use: [ 'raw-loader' ]
 			},
 			},
 			{
 			{
-				// Or /ckeditor5-[^/]+\/theme\/[\w-/]+\.css$/ if you want to limit this loader
-				// to CKEditor 5 theme only.
-				test: /\.css$/,
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
 				use: [
 				use: [
 					{
 					{
 						loader: 'style-loader',
 						loader: 'style-loader',
 						options: {
 						options: {
-							singleton: true
+							injectType: 'singletonStyleTag'
 						}
 						}
 					},
 					},
 					{
 					{
@@ -166,6 +161,45 @@ module.exports = {
 };
 };
 ```
 ```
 
 
+#### Webpack Encore
+
+If you use [Webpack Encore](https://github.com/symfony/webpack-encore), you can use the following configuration:
+
+```js
+const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
+const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
+
+Encore.
+	// ... your configuration ...
+
+	.addPlugin( new CKEditorWebpackPlugin( {
+		// See https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html
+		language: 'pl'
+	} ) )
+
+	// Use raw-loader for CKEditor 5 SVG files.
+	.addRule( {
+		test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+		loader: 'raw-loader'
+	} )
+
+	// Configure other image loaders to exclude CKEditor 5 SVG files.
+	.configureLoaderRule( 'images', loader => {
+		loader.exclude = /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/;
+	} )
+
+	// Configure PostCSS loader.
+	.addLoader({
+		test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
+		loader: 'postcss-loader',
+		options: styles.getPostCssConfig( {
+			themeImporter: {
+				themePath: require.resolve('@ckeditor/ckeditor5-theme-lark')
+			}
+		} )
+	} )
+```
+
 ### Running the editor – method 1
 ### Running the editor – method 1
 
 
 You can now import all the needed plugins and the creator directly into your code and use it there. The easiest way to do so is to copy it from the `src/ckeditor.js` file available in every build repository.
 You can now import all the needed plugins and the creator directly into your code and use it there. The easiest way to do so is to copy it from the `src/ckeditor.js` file available in every build repository.
@@ -370,11 +404,11 @@ module.exports = {
 	module: {
 	module: {
 		rules: [
 		rules: [
 			{
 			{
-				test: /\.svg$/,
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
 				use: [ 'raw-loader' ]
 				use: [ 'raw-loader' ]
 			},
 			},
 			{
 			{
-				test: /\.css$/,
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
 				use: [
 				use: [
 					MiniCssExtractPlugin.loader,
 					MiniCssExtractPlugin.loader,
 					'css-loader',
 					'css-loader',
@@ -420,7 +454,7 @@ Then, add this item to webpack [`module.rules`](https://webpack.js.org/configura
 module: {
 module: {
 	rules: [
 	rules: [
 		{
 		{
-			test: /ckeditor5-[^\/\\]+[\/\\].*\.js$/,
+			test: /ckeditor5-[^\/\\]+[\/\\].+\.js$/,
 			use: [
 			use: [
 				{
 				{
 					loader: 'babel-loader',
 					loader: 'babel-loader',

+ 2 - 0
docs/builds/guides/integration/basic-api.md

@@ -170,9 +170,11 @@ Once destroyed, resources used by the editor instance are released and the origi
 
 
 {@link module:engine/model/document~Document#change:data `Document#change:data`}.
 {@link module:engine/model/document~Document#change:data `Document#change:data`}.
 
 
+```js
 editor.model.document.on( 'change:data', () => {
 editor.model.document.on( 'change:data', () => {
     console.log( 'The data has changed!' );
     console.log( 'The data has changed!' );
 } );
 } );
+```
 
 
 This event is fired when the document changes in such a way which is "visible" in the editor data. There is also a group of changes, like selection position changes, marker changes which do not affect the result of `editor.getData()`. To listen to all these changes, you can use a wider {@link module:engine/model/document~Document#change `Document#change`} event.
 This event is fired when the document changes in such a way which is "visible" in the editor data. There is also a group of changes, like selection position changes, marker changes which do not affect the result of `editor.getData()`. To listen to all these changes, you can use a wider {@link module:engine/model/document~Document#change `Document#change`} event.
 
 

+ 193 - 0
docs/builds/guides/integration/content-styles.md

@@ -0,0 +1,193 @@
+---
+# Scope:
+# * Explain what content styles are and how to use them.
+# * Offer developers a way to obtain the editor content styles.
+
+category: builds-integration
+order: 80
+---
+
+# Content styles
+
+Some of the {@link features/index core editor features} bring additional CSS to control the look of the content they produce. Take, for example, the {@link features/image image feature} that needs special content styles to render images and their captions in the content. Or the {@link module:block-quote/blockquote~BlockQuote block quote} feature that displays quotes in italic with a subtle border on the side.
+
+{@img assets/img/builds-content-styles.png 823 Editor content styles.}
+
+Content styles are bundled along with editor UI styles and, together with the JavaScript code of CKEditor 5, they create a monolithic structure called an {@link builds/guides/overview#available-builds editor build}. By default, content styles are inseparable from the rest of the editor which means there is no CSS file containing them you could take straight from the editor and use in your application (as opposed to the CKEditor 4 `contents.css` file). To get the editor content styles, for instance, for the front–end of your application, you will have to take additional steps described in this guide.
+
+## Sharing content styles between front–end and back–end
+
+By default, content styles are loaded by the editor JavaScript which makes them only present when users edit their content and this, in turn, usually takes place in the back–end of an application. If you want to use the same styles in the front–end, you may find yourself in a situation that requires you to load CKEditor just for that purpose, which is (performance–wise) not the best idea.
+
+To avoid unnecessary dependencies in your front–end, use a stylesheet with a complete list of CKEditor 5 content styles used by all editor features. There are two ways to obtain it:
+
+* By taking it directly from [this guide](#the-full-list-of-content-styles) and saving it as a static resource in your application (e.g. `content-styles.css`) (**recommended**).
+* By generating it using a dedicated script. Learn more in the {@link framework/guides/contributing/development-environment#generating-content-styles Development environment} guide.
+
+Load the `content-styles.css` file in your application by adding the following code to the template:
+
+```html
+<link rel="stylesheet" href="path/to/assets/content-styles.css" type="text/css">
+```
+
+The content in the front–end of your application should now look the same as when edited by the users.
+
+<info-box warning>
+	**Important!**
+
+	If you take a closer look at the content styles, you may notice they are prefixed with the `.ck-content` class selector. This narrows their scope when used in CKEditor 5 so they do not affect the rest of the application. To use them in the front–end, **you will have to** add the `ck-content` CSS class to the container of your content. Otherwise the styles will not be applied.
+</info-box>
+
+<info-box>
+	If you are not afraid to get your hands dirty, you can always create a custom CKEditor 5 build from the source code with **all** the CSS (both UI and the content) extracted to a separate file. See how to do that in a {@link builds/guides/integration/advanced-setup#option-extracting-css dedicated guide}.
+</info-box>
+
+## The full list of content styles
+
+Below there is a full list of content styles used by the editor features. You can copy it and use straight in your project. **Make sure to add the `ck-content` class to your content container for the styles to work** ([see above](#sharing-content-styles-between-frontend-and-backend)).
+
+```css
+/*
+ * CKEditor 5 (v12.3.1) content styles.
+ * Generated on Mon, 19 Aug 2019 12:01:17 GMT.
+ * For more information, check out https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/content-styles.html
+ */
+
+:root {
+	--ck-image-style-spacing: 1.5em;
+}
+
+/* ckeditor5-image/theme/image.css */
+.ck-content .image {
+	display: table;
+	clear: both;
+	text-align: center;
+	margin: 1em auto
+}
+/* ckeditor5-image/theme/image.css */
+.ck-content .image > img {
+	display: block;
+	margin: 0 auto;
+	max-width: 100%;
+	min-width: 50px;
+}
+/* ckeditor5-image/theme/imagecaption.css */
+.ck-content .image > figcaption {
+	display: table-caption;
+	caption-side: bottom;
+	word-break: break-word;
+	color: hsl(0, 0%, 20%);
+	background-color: hsl(0, 0%, 97%);
+	padding: .6em;
+	font-size: .75em;
+	outline-offset: -1px;
+}
+/* ckeditor5-image/theme/imageresize.css */
+.ck-content .image.image_resized {
+	max-width: 100%;
+	display: block;
+	box-sizing: border-box
+}
+/* ckeditor5-image/theme/imageresize.css */
+.ck-content .image.image_resized img {
+	width: 100%;
+}
+/* ckeditor5-image/theme/imageresize.css */
+.ck-content .image.image_resized > figcaption {
+	display: block;
+}
+/* ckeditor5-media-embed/theme/mediaembed.css */
+.ck-content .media {
+	clear: both;
+	margin: 1em 0;
+	display: block;
+	min-width: 15em;
+}
+/* ckeditor5-table/theme/table.css */
+.ck-content .table {
+	margin: 1em auto;
+	display: table
+}
+/* ckeditor5-table/theme/table.css */
+.ck-content .table table {
+	border-collapse: collapse;
+	border-spacing: 0;
+	border: 1px double hsl(0, 0%, 70%)
+}
+/* ckeditor5-table/theme/table.css */
+.ck-content .table table td,
+.ck-content .table table th {
+	min-width: 2em;
+	padding: .4em;
+	border-color: hsl(0, 0%, 85%);
+}
+/* ckeditor5-table/theme/table.css */
+.ck-content .table table td,
+.ck-content .table table th {
+	min-width: 2em;
+	padding: .4em;
+	border-color: hsl(0, 0%, 85%);
+}
+/* ckeditor5-table/theme/table.css */
+.ck-content .table table th {
+	font-weight: bold;
+	background: hsl(0, 0%, 98%);
+}
+/* ckeditor5-basic-styles/theme/code.css */
+.ck-content code {
+	background-color: hsla(0, 0%, 78%, 0.3);
+	padding: .15em;
+	border-radius: 2px;
+}
+/* ckeditor5-image/theme/imagestyle.css */
+.ck-content .image-style-side:not(.image_resized), .ck-content .image-style-align-left:not(.image_resized), .ck-content .image-style-align-center:not(.image_resized), .ck-content .image-style-align-right:not(.image_resized) {
+	max-width: 50%;
+}
+/* ckeditor5-image/theme/imagestyle.css */
+.ck-content .image-style-side:not(.image_resized), .ck-content .image-style-align-left:not(.image_resized), .ck-content .image-style-align-center:not(.image_resized), .ck-content .image-style-align-right:not(.image_resized) {
+	max-width: 50%;
+}
+/* ckeditor5-image/theme/imagestyle.css */
+.ck-content .image-style-side:not(.image_resized), .ck-content .image-style-align-left:not(.image_resized), .ck-content .image-style-align-center:not(.image_resized), .ck-content .image-style-align-right:not(.image_resized) {
+	max-width: 50%;
+}
+/* ckeditor5-image/theme/imagestyle.css */
+.ck-content .image-style-side:not(.image_resized), .ck-content .image-style-align-left:not(.image_resized), .ck-content .image-style-align-center:not(.image_resized), .ck-content .image-style-align-right:not(.image_resized) {
+	max-width: 50%;
+}
+/* ckeditor5-image/theme/imagestyle.css */
+.ck-content .image-style-side {
+	float: right;
+	margin-left: var(--ck-image-style-spacing);
+}
+/* ckeditor5-image/theme/imagestyle.css */
+.ck-content .image-style-align-left {
+	float: left;
+	margin-right: var(--ck-image-style-spacing);
+}
+/* ckeditor5-image/theme/imagestyle.css */
+.ck-content .image-style-align-center {
+	margin-left: auto;
+	margin-right: auto;
+}
+/* ckeditor5-image/theme/imagestyle.css */
+.ck-content .image-style-align-right {
+	float: right;
+	margin-left: var(--ck-image-style-spacing);
+}
+/* ckeditor5-block-quote/theme/blockquote.css */
+.ck-content blockquote {
+	overflow: hidden;
+	padding-right: 1.5em;
+	padding-left: 1.5em;
+	margin-left: 0;
+	margin-right: 0;
+	font-style: italic;
+	border-left: solid 5px hsl(0, 0%, 80%);
+}
+/* ckeditor5-block-quote/theme/blockquote.css */
+.ck-content[dir="rtl"] blockquote {
+	border-left: 0;
+	border-right: solid 5px hsl(0, 0%, 80%);
+}
+```

+ 20 - 20
docs/builds/guides/integration/csp.md

@@ -10,11 +10,11 @@ order: 70
 
 
 # Content Security Policy
 # Content Security Policy
 
 
-CKEditor 5 is compatible with applications that use [<abbr title="Content Security Policy">CSP</abbr> rules](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) and helps developers build secure web.
+CKEditor 5 is compatible with applications that use [<abbr title="Content Security Policy">CSP</abbr> rules](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) and helps developers build a secure web.
 
 
 ## Recommended CSP configuration
 ## Recommended CSP configuration
 
 
-The recommended CSP configuration that allows the rich text editor to run out–of–the–box with all standard features using the content like images or media from external hosts looks as follows:
+The recommended CSP configuration that allows the rich-text editor to run out–of–the–box with all standard features using the content like images or media from external hosts looks as follows:
 
 
 ```
 ```
 default-src 'none'; connect-src 'self'; script-src 'self'; img-src * data:; style-src 'self' 'unsafe-inline'; frame-src *
 default-src 'none'; connect-src 'self'; script-src 'self'; img-src * data:; style-src 'self' 'unsafe-inline'; frame-src *
@@ -22,30 +22,30 @@ default-src 'none'; connect-src 'self'; script-src 'self'; img-src * data:; styl
 
 
 ## Impact of CSP on editor features
 ## Impact of CSP on editor features
 
 
-Some CSP directives have an impact on certain rich text editor features. Here is the round-up of directives and their specific roles in the editor:
+Some CSP directives have an impact on certain rich-text editor features. Here is the round-up of directives and their specific roles in the editor:
 
 
-* `default-src 'none'`: resets the policy and blocks everything. All successive directives work as a whitelist. By itself, as long as followed by other directives, it has no impact on the editor.
+* `default-src 'none'`: Resets the policy and blocks everything. All successive directives work as a whitelist. By itself, as long as it is followed by other directives, it has no impact on the editor.
 * `connect-src 'self'`
 * `connect-src 'self'`
-	* Allows the {@link features/image-upload editor upload features} to use [`XMLHttpReqests`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) (AJAX) to upload files to the server, for instance, when an image is pasted or dropped into the editor content. The `'self`' value ensures the requests remain within the same host.
+	* Allows the {@link features/image-upload editor upload features} to use [`XMLHttpReqests`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) (Ajax) to upload files to the server, for instance, when an image is pasted or dropped into the editor content. The `'self`' value ensures the requests remain within the same host.
 	* Allows {@link builds/guides/integration/saving-data#autosave-feature auto–saving editor data} using `XMLHttpRequest`.
 	* Allows {@link builds/guides/integration/saving-data#autosave-feature auto–saving editor data} using `XMLHttpRequest`.
 
 
-	**Note**: To use [CKEditor Cloud Services](https://ckeditor.com/ckeditor-cloud-services/), include the `http://*.cke-cs.com` domain in the `connect-src` directive, for instance, `connect-src 'self' http://*.cke-cs.com`.
-* `script-src 'self'`: allows the execution of JavaScript from the current host only and can be applied only if the CKEditor 5 script file (`<script src="[ckeditor-build-path]/ckeditor.js"></script>`) is also served from that host.
+	**Note**: To use [CKEditor Cloud Services](https://ckeditor.com/ckeditor-cloud-services/), include the `http://*.cke-cs.com` domain in the `connect-src` directive, for instance: `connect-src 'self' http://*.cke-cs.com`.
+* `script-src 'self'`: Allows the execution of JavaScript from the current host only and can be applied only if the CKEditor 5 script file (`<script src="[ckeditor-build-path]/ckeditor.js"></script>`) is also served from that host.
 
 
-	**Note**: If CKEditor 5 is served from another host, for instance, the {@link builds/guides/integration/installation#cdn official CDN}, make sure the value of `script-src` includes that host (`script-src 'self' https://cdn.ckeditor.com`).
+	**Note**: If CKEditor 5 is served from another host, for example the {@link builds/guides/integration/installation#cdn official CDN}, make sure the value of `script-src` includes that host (`script-src 'self' https://cdn.ckeditor.com`).
 * `img-src * data:`
 * `img-src * data:`
 	* The `*` directive value allows images in the editor content to come from any hosts.
 	* The `*` directive value allows images in the editor content to come from any hosts.
 	* The `data:` value allows:
 	* The `data:` value allows:
-		* pasting {@link features/image-upload images from the clipboard} and {@link features/paste-from-word from Word} into editor content. Pasted images are usually represented as Base64–encoded strings (`<img src="data:..." />`) and without `data:` they cannot be displayed and uploaded.
-		* displaying the {@link features/media-embed Media embed} feature placeholders for the inserted media.
+		* Pasting {@link features/image-upload images from the clipboard} and {@link features/paste-from-word from Microsoft Word} into the editor content. Pasted images are usually represented as Base64–encoded strings (`<img src="data:..." />`) and without `data:` they cannot be displayed and uploaded.
+		* Displaying the {@link features/media-embed media embed} feature placeholders for the inserted media.
 
 
-	**Note**: Use the more strict `img-src 'self'` if all images in the editor content are hosted from the same domain and you do **not** want to enable the {@link features/media-embed Media embed} and {@link features/paste-from-word Paste from Word} features.
+	**Note**: Use the more strict `img-src 'self'` if all images in the editor content are hosted from the same domain and you do **not** want to enable the {@link features/media-embed media embed} and {@link features/paste-from-word paste from Word} features.
 * `style-src 'self' 'unsafe-inline'`: `'unsafe-inline'` is necessary for:
 * `style-src 'self' 'unsafe-inline'`: `'unsafe-inline'` is necessary for:
-	* webpack's [style-loader](https://github.com/webpack-contrib/style-loader) to load {@link framework/guides/theme-customization#styles-processing-and-bundling editor UI styles}.
+	* webpack's [style-loader](https://github.com/webpack-contrib/style-loader) to load the {@link framework/guides/theme-customization#styles-processing-and-bundling editor UI styles}.
 
 
 	**Note**: You can {@link builds/guides/integration/advanced-setup#option-extracting-css extract styles to a separate `.css` file} during the editor building process and remove this directive.
 	**Note**: You can {@link builds/guides/integration/advanced-setup#option-extracting-css extract styles to a separate `.css` file} during the editor building process and remove this directive.
-	* certain editor content styles to work properly. For instance, you are going to need it if you want to enable editor features like {@link features/font Font} or {@link features/text-alignment Text alignment} or any other feature that uses inline `style="..."` attributes in the content.
-* `frame-src *`: Necessary for the {@link features/media-embed Media embed} feature to load media with previews (containing `<iframe>`).
+	* Certain editor content styles to work properly. For instance, you are going to need it if you want to enable such editor features as {@link features/font font} or {@link features/text-alignment text alignment} or any other feature that uses inline `style="..."` attributes in the content.
+* `frame-src *`: Necessary for the {@link features/media-embed media embed} feature to load media with previews (containing `<iframe>`).
 
 
 	**Note**: Use the more strict `frame-src 'self'` if all the media in the edited content come from the same domain as your application.
 	**Note**: Use the more strict `frame-src 'self'` if all the media in the edited content come from the same domain as your application.
 
 
@@ -61,10 +61,10 @@ Knowing the role of each directive, the strictest set of rules that allows CKEdi
 default-src 'none'; connect-src 'self'; script-src 'self'; img-src 'self'; style-src 'self'; frame-src 'self'
 default-src 'none'; connect-src 'self'; script-src 'self'; img-src 'self'; style-src 'self'; frame-src 'self'
 ```
 ```
 
 
-but it comes with some trade–offs, for instance, it requires you to:
+This comes with some trade–offs, though. For example, it requires you to:
 
 
-* use an editor build with the {@link builds/guides/integration/advanced-setup#option-extracting-css styles extracted to a separate `.css` file} (no style-loader),
-* load images in the content from the same host,
-* load previewable media in the content from the same host,
-* give up certain features that use inline styles like {@link features/font Font} or {@link features/text-alignment Text alignment},
-* give up pasting images from the clipboard or {@link features/paste-from-word from Word},
+* Use an editor build with the {@link builds/guides/integration/advanced-setup#option-extracting-css styles extracted to a separate `.css` file} (no style-loader).
+* Load images in the content from the same host.
+* Load previewable media in the content from the same host.
+* Give up certain features that use inline styles like {@link features/font font} or {@link features/text-alignment text alignment}.
+* Give up pasting images from the clipboard or {@link features/paste-from-word from Word}.

+ 14 - 0
docs/builds/guides/integration/saving-data.md

@@ -154,6 +154,20 @@ It also listens to the native [`window#beforeunload`](https://developer.mozilla.
 
 
 This automatically secures you from the user leaving the page before the content is saved or some ongoing actions like image upload did not finish.
 This automatically secures you from the user leaving the page before the content is saved or some ongoing actions like image upload did not finish.
 
 
+The minimum time period between two save actions can be configured using the {@link module:autosave/autosave~AutosaveConfig#waitingTime `config.waitingTime`} property to not overload the backend. 1 second is the default waiting time before the next save action if nothing has changed in the meantime after the editor data has changed.
+
+```js
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		autosave: {
+			waitingTime: 5000, // in ms
+			save( editor ) {}
+		},
+
+		// ... other configuration options
+	} );
+```
+
 ### Demo
 ### Demo
 
 
 This demo shows a simple integration of the editor with a fake HTTP server (which needs 1000ms to save the content).
 This demo shows a simple integration of the editor with a fake HTTP server (which needs 1000ms to save the content).

+ 15 - 3
docs/builds/guides/migrate.md

@@ -68,6 +68,18 @@ The following table presents configuration options available in CKEditor 4 and t
 
 
 Note: The number of options was reduced on purpose. We understood that configuring CKEditor 4 was a bit too troublesome due to the number of configuration options available (over 240). Sometimes they were definitely too low-level, also many times they were so infrequently used that it did not justify the increased level of the application complexity. This is why when designing CKEditor 5 from scratch, we decided to come with a simplified editor, with well-thought default behavior, based on the results of the [Editor Recommendations](http://ckeditor.github.io/editor-recommendations/) project.
 Note: The number of options was reduced on purpose. We understood that configuring CKEditor 4 was a bit too troublesome due to the number of configuration options available (over 240). Sometimes they were definitely too low-level, also many times they were so infrequently used that it did not justify the increased level of the application complexity. This is why when designing CKEditor 5 from scratch, we decided to come with a simplified editor, with well-thought default behavior, based on the results of the [Editor Recommendations](http://ckeditor.github.io/editor-recommendations/) project.
 
 
+<style>
+/* See: https://github.com/ckeditor/ckeditor5/issues/1718. */
+.docsearch-txt {
+	table-layout: fixed;
+}
+
+.docsearch-txt tr th:nth-child( 1 ),
+.docsearch-txt tr td:nth-child( 1 ) {
+	width: 250px;
+}
+</style>
+
 <table class="docsearch-txt">
 <table class="docsearch-txt">
 	<thead>
 	<thead>
 		<tr>
 		<tr>
@@ -90,7 +102,7 @@ Note: The number of options was reduced on purpose. We understood that configuri
 		<tr>
 		<tr>
 			<td><a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-autoGrow_bottomSpace">autoGrow_bottomSpace</a> <br> <a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-autoGrow_maxHeight">autoGrow_maxHeight</a> <br> <a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-autoGrow_minHeight">autoGrow_minHeight</a> <br> <a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-autoGrow_onStartup">autoGrow_onStartup</a></td>
 			<td><a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-autoGrow_bottomSpace">autoGrow_bottomSpace</a> <br> <a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-autoGrow_maxHeight">autoGrow_maxHeight</a> <br> <a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-autoGrow_minHeight">autoGrow_minHeight</a> <br> <a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-autoGrow_onStartup">autoGrow_onStartup</a></td>
 			<td>
 			<td>
-				<p>Classic editor (CKEditor 5) no longer encapsulates the editing area in an <code>&lt;iframe&gt;</code>, which means that the height (and similar options) of the editing area can be easily controlled with CSS. For example the <code>minHeight</code> and <code>maxHeight</code> settings can be achieved with <code>.ck-content { min-height:200px; max-height:400px; }</code>.</p>
+				<p>Classic editor (CKEditor 5) no longer encapsulates the editing area in an <code>&lt;iframe&gt;</code>, which means that the height (and similar options) of the editing area can be easily controlled with CSS. For example the <code>minHeight</code> and <code>maxHeight</code> settings can be achieved with <code>.ck-editor__editable_inline { min-height:200px; max-height:400px; }</code>.</p>
 				<p> See also <a href="https://stackoverflow.com/questions/46559354/how-to-set-the-height-of-ckeditor-5-classic-editor" target="_blank" rel="noopener">How to set the height of CKEditor 5 (Classic editor)</a>.</p>
 				<p> See also <a href="https://stackoverflow.com/questions/46559354/how-to-set-the-height-of-ckeditor-5-classic-editor" target="_blank" rel="noopener">How to set the height of CKEditor 5 (Classic editor)</a>.</p>
 			</td>
 			</td>
 		</tr>
 		</tr>
@@ -336,7 +348,7 @@ Note: The number of options was reduced on purpose. We understood that configuri
 		<tr>
 		<tr>
 			<td><a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-height">height</a></td>
 			<td><a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-height">height</a></td>
 			<td>
 			<td>
-				<p>Classic editor (CKEditor 5) no longer encapsulates the editing area in an <code>&lt;iframe&gt;</code>, which means that the height (and similar options) of the editing area can be easily controlled with CSS. For example the height setting can be achieved with <code>.ck-content { height:400px; }</code>.</p>
+				<p>Classic editor (CKEditor 5) no longer encapsulates the editing area in an <code>&lt;iframe&gt;</code>, which means that the height (and similar options) of the editing area can be easily controlled with CSS. For example the height setting can be achieved with <code>.ck-editor__editable_inline { height:400px; }</code>.</p>
 				<p>See also <a href="https://stackoverflow.com/questions/46559354/how-to-set-the-height-of-ckeditor-5-classic-editor" target="_blank" rel="noopener">How to set the height of CKEditor 5 (Classic editor)</a>.</p>
 				<p>See also <a href="https://stackoverflow.com/questions/46559354/how-to-set-the-height-of-ckeditor-5-classic-editor" target="_blank" rel="noopener">How to set the height of CKEditor 5 (Classic editor)</a>.</p>
 			</td>
 			</td>
 		</tr>
 		</tr>
@@ -578,7 +590,7 @@ Note: The number of options was reduced on purpose. We understood that configuri
 		<tr>
 		<tr>
 			<td><a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-width">width</a></td>
 			<td><a href="/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-width">width</a></td>
 			<td>
 			<td>
-				<p>Classic editor (CKEditor 5) no longer encapsulates the editing area in an <code>&lt;iframe&gt;</code>, which means that the height (and similar options) of the editing area can be easily controlled with CSS. For example, the width setting can be achieved with <code>.ck-content { width:400px; }</code>.</p>
+				<p>Classic editor (CKEditor 5) no longer encapsulates the editing area in an <code>&lt;iframe&gt;</code>, which means that the height (and similar options) of the editing area can be easily controlled with CSS. For instance, to set the width of the Classic editor, use <code>.ck-editor { width:400px; }</code>. Setting the width of other editors which do not enclose the toolbar and the editable in a box (Inline editor, Balloon editor, etc.) can be achieved using <code>.ck-editor__editable_inline { width:400px; }</code>.</p>
 				<p>See also <a href="https://stackoverflow.com/questions/46559354/how-to-set-the-height-of-ckeditor-5-classic-editor" target="_blank" rel="noopener">How to set the height of CKEditor 5 (Classic editor)</a>.</p>
 				<p>See also <a href="https://stackoverflow.com/questions/46559354/how-to-set-the-height-of-ckeditor-5-classic-editor" target="_blank" rel="noopener">How to set the height of CKEditor 5 (Classic editor)</a>.</p>
 			</td>
 			</td>
 		</tr>
 		</tr>

+ 1 - 0
docs/builds/guides/overview.md

@@ -20,6 +20,7 @@ The following CKEditor 5 Builds are currently available:
  * [Classic editor](#classic-editor)
  * [Classic editor](#classic-editor)
  * [Inline editor](#inline-editor)
  * [Inline editor](#inline-editor)
  * [Balloon editor](#balloon-editor)
  * [Balloon editor](#balloon-editor)
+ * [Balloon block editor](#balloon-block-editor)
  * [Document editor](#document-editor)
  * [Document editor](#document-editor)
 
 
 ### Classic editor
 ### Classic editor

+ 1 - 1
docs/builds/guides/support/browser-compatibility.md

@@ -42,4 +42,4 @@ CKEditor 5 is currently supported in the following mobile environments:
 
 
 To ensure the highest quality, we maintain a complete test suite with a stable 100% of code coverage for each of the packages. As of October 2018, this means over 9600 tests and the number is growing.
 To ensure the highest quality, we maintain a complete test suite with a stable 100% of code coverage for each of the packages. As of October 2018, this means over 9600 tests and the number is growing.
 
 
-Such an extensive test suite requires a proper continuous integration service. We use [Travis CI](https://travis-ci.com/) as a build platform and [BrowserStack](https://www.browserstack.com/) to be able to run tests on all browsers. These services ensure seamless and fast developer experience and allow us to focus on the job.
+Such an extensive test suite requires a proper continuous integration service. We use [Travis CI](https://travis-ci.com/) as a build platform. This service ensures seamless and fast developer experience and allow us to focus on the job.

+ 17 - 5
docs/features/image-upload.md

@@ -8,16 +8,16 @@ order: 10
 
 
 Inserting images into content created with CKEditor 5 is a very common task. In a properly configured rich-text editor, there are several ways for the end user to insert images:
 Inserting images into content created with CKEditor 5 is a very common task. In a properly configured rich-text editor, there are several ways for the end user to insert images:
 
 
-* **Pasting** it from the clipboard.
+* **Pasting** an image from the clipboard.
 * **Dragging** a file from the file system.
 * **Dragging** a file from the file system.
-* Selecting it through a **file system dialog**.
-* Selecting it from a **media management tool** in your application.
+* Selecting an image through a **file system dialog**.
+* Selecting an image from a **media management tool** in your application.
 
 
 Excluding the last option, all other ways require the image to be uploaded to a server. The server will then be responsible for providing the image URL used by CKEditor 5 to display the image in the document.
 Excluding the last option, all other ways require the image to be uploaded to a server. The server will then be responsible for providing the image URL used by CKEditor 5 to display the image in the document.
 
 
 {@img assets/img/image-upload-animation.svg 650 The visualization of the image upload process in a WYSIWYG editor.}
 {@img assets/img/image-upload-animation.svg 650 The visualization of the image upload process in a WYSIWYG editor.}
 
 
-The software that makes the image upload possible is called an **upload adapter**. It is a callback which tells the editor how to send the file to the server. There are two main strategies of getting the image upload work you can adopt in your project:
+The software that makes the image upload possible is called an **upload adapter**. It is a callback that tells the WYSIWYG editor how to send the file to the server. There are two main strategies of getting the image upload to work that you can adopt in your project:
 
 
 * [**Official upload adapters**](#official-upload-adapters) &ndash; There are several features providing upload adapters developed and maintained by the CKEditor team. Pick the best one for your integration and let it handle the image upload in your project.
 * [**Official upload adapters**](#official-upload-adapters) &ndash; There are several features providing upload adapters developed and maintained by the CKEditor team. Pick the best one for your integration and let it handle the image upload in your project.
 * [**Custom upload adapters**](#implementing-your-own-upload-adapter) &ndash; Create your own upload adapter from scratch using the open API architecture of CKEditor 5.
 * [**Custom upload adapters**](#implementing-your-own-upload-adapter) &ndash; Create your own upload adapter from scratch using the open API architecture of CKEditor 5.
@@ -40,7 +40,7 @@ The demo below uses the {@link builds/guides/overview#classic-editor Classic edi
 
 
 CKEditor 5 introduces a new way of handling images, with a strong focus on the end–user experience. This feature is called {@link features/easy-image Easy Image} and its goal is to make the image upload as effortless and intuitive as possible.
 CKEditor 5 introduces a new way of handling images, with a strong focus on the end–user experience. This feature is called {@link features/easy-image Easy Image} and its goal is to make the image upload as effortless and intuitive as possible.
 
 
-Easy Image is part of the [CKEditor Cloud Services](https://ckeditor.com/ckeditor-cloud-services/) offer. It is a <abbr title="Software as a service">SaaS</abbr> product which:
+Easy Image is part of the [CKEditor Cloud Services](https://ckeditor.com/ckeditor-cloud-services/) offer. It is a <abbr title="Software as a service">SaaS</abbr> product that:
 
 
 * securely uploads images,
 * securely uploads images,
 * takes care of rescaling and optimizing them as well as providing various image sizes (responsive images),
 * takes care of rescaling and optimizing them as well as providing various image sizes (responsive images),
@@ -68,6 +68,18 @@ There are two ways you can integrate CKEditor 5 with the CKFinder file manager:
 
 
 {@link features/ckfinder **Learn how to integrate CKEditor 5 with CKFinder in your project**}.
 {@link features/ckfinder **Learn how to integrate CKEditor 5 with CKFinder in your project**}.
 
 
+### Simple adapter
+
+The {@link features/simple-upload-adapter Simple upload adapter} allows uploading images to your server using the [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) API with a minimal editor configuration.
+
+{@link features/simple-upload-adapter **Learn how to use the Simple upload adapter in CKEditor 5**}.
+
+### Base64 adapter
+
+The {@link features/base64-upload-adapter Base64 upload feature} converts images inserted into the editor into [Base64 strings](https://en.wikipedia.org/wiki/Base64) in the {@link builds/guides/integration/saving-data editor output}.
+
+{@link features/base64-upload-adapter **Learn how to use Base64–encoded images in CKEditor 5**}.
+
 ## Implementing your own upload adapter
 ## Implementing your own upload adapter
 
 
 CKEditor 5 provides an open API that allows you to develop your own upload adapters. Tailored to your project, a custom adapter will allow you to take the **full control** over the process of sending the files to the server as well as passing the response from the server (e.g. the URL to the saved file) back to the WYSIWYG editor.
 CKEditor 5 provides an open API that allows you to develop your own upload adapters. Tailored to your project, a custom adapter will allow you to take the **full control** over the process of sending the files to the server as well as passing the response from the server (e.g. the URL to the saved file) back to the WYSIWYG editor.

+ 71 - 0
docs/features/mathtype.md

@@ -0,0 +1,71 @@
+---
+category: features
+menu-title: Math and chemical formulas
+---
+
+# Math equations and chemical formulas
+
+<info-box>
+	This feature is provided as a commercial solution called MathType delivered by our partner, [Wiris](http://www.wiris.com).
+	You can report any issues in the official CKEditor 5 [GitHub repository](https://github.com/ckeditor/ckeditor5/issues). A license can be purchased [here](https://ckeditor.com/contact/).
+</info-box>
+
+[MathType](http://www.wiris.com/en/mathtype) is a popular mathematical and science formula editor with classical and handwriting input modes. You can use it to create math equations or chemical formulas right inside the CKEditor 5 content.
+
+MathType is based upon standards like MathML for internal representation and the PNG image format for displaying formulas. It can also handle other formats like LaTeX, Flash, SVG and EPS.
+
+Additionally, MathType offers a special tool designed to help you work with chemical notation. When enabled, ChemType adds a specialized toolbar with the common chemical symbols as well as changes the notation to make it more intuitive to work with chemical formulas.
+
+## Demo
+
+In order to start creating math or chemical formulas in the WYSIWYG editor below, click the MathType or ChemType buttons in the toolbar. This will open the relevant dialog on the screen.
+
+Use the toolbar to write your equation or formula. At any time you can also click the "Go to handwritten mode" button on the right side of the MathType editor to switch to handwriting.
+
+When you are done creating your scientific content, click the "OK" button to insert your formula into CKEditor 5. You can also edit any existing formulas by double-clicking them in your document.
+
+{@snippet features/mathtype}
+
+## Usage
+
+The MathType window is split into two main areas: a [tabbed toolbar](https://docs.wiris.com/en/mathtype/mathtype_web/toolbar) that contains a large number of icons that are useful for creating math equations and chemical formulas, and an editing area where you can see your current formula, the location of the cursor, and the text currently selected (if any).
+
+The following resources can come in handy if you want to become proficient at working with this tool:
+* [Using MathType Web](https://docs.wiris.com/en/mathtype/mathtype_web/using_mathtype) covers the basics of creating formulas, using your keyboard, moving the cursor in templates, formatting your content or writing on mobile devices.
+* [Introductory tutorials](https://docs.wiris.com/en/mathtype/mathtype_web/intro_tutorials) are intended to get you started using MathType.
+* [ChemType](https://docs.wiris.com/en/mathtype/mathtype_web/chemistry) explains the features of the dedicated chemistry toolbar.
+* [MathType documentation](https://docs.wiris.com/en/mathtype/mathtype_web/start) is a complete reference to all MathType features and settings.
+
+## Editing modes
+
+MathType lets you choose between two editing modes:
+* **Classic input mode** provides options to choose symbols and templates from the MathType or ChemType toolbars and combine them to build the equation.
+* **Handwritten input mode** lets you write the equation in your own handwriting. After checking the equation preview to ensure its accuracy, you can insert the equation or switch to classic input for further editing. [Read more here](https://docs.wiris.com/en/mathtype/mathtype_web/handwritten-input).
+
+If you visit a page using MathType with your mobile device, the handwriting interface will appear by default. However, if you visit the same page with a laptop or desktop computer, the classic input will be displayed. The user is always free to change between the two interfaces.
+
+## Installation
+
+To add MathType features to your editor, install the [`@wiris/mathtype-ckeditor5`](https://www.npmjs.com/package/@wiris/mathtype-ckeditor5) package:
+
+```bash
+npm install --save @wiris/mathtype-ckeditor5
+```
+
+Then add it to your plugin list and the toolbar configuration:
+
+```js
+import MathType from '@wiris/mathtype-ckeditor5';
+
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ MathType, ... ],
+		toolbar: [ 'MathType', 'ChemType', ... ]
+	} )
+	.then( ... )
+	.catch( ... );
+```
+
+<info-box info>
+	Read more about {@link builds/guides/integration/installing-plugins installing plugins}.
+</info-box>

+ 91 - 0
docs/features/spell-checker.md

@@ -0,0 +1,91 @@
+---
+category: features
+menu-title: Spelling and grammar checking
+---
+
+# Proofreading, spelling and grammar checking
+
+{@snippet build-classic-source}
+
+<info-box>
+	The spell checker for CKEditor 5 is a commercial solution provided by our partner, [WebSpellChecker](https://webspellchecker.com/). You can report any issues in its [GitHub repository](https://github.com/WebSpellChecker/wproofreader). The license can be purchased [here](https://ckeditor.com/contact/).
+</info-box>
+
+[WProofreader](https://webspellchecker.com/wsc-proofreader) is an innovative proofreading tool that combines the functionality of "spell check as you type" and "spell check in a dialog" in a modern, distraction-free UI. Spelling and grammar suggestions are available on hover with no clicking needed.
+
+## Demo
+
+Click in the editor below to enable the spelling and grammar checking. Hover an underlined word to display the proofreader suggestions for any of the spelling and grammar mistakes found.
+
+The proofreader badge in the bottom right-hand corner shows you the number of mistakes detected. It also gives you access to proofreader settings. If you want to see an overview of all spelling and grammar mistakes, click the "Proofread in dialog" icon in the badge.
+
+{@snippet features/wproofreader}
+
+## Supported languages
+
+By default the spell checker supports 17 languages: American English, British English, Brazilian Portuguese, Canadian English, Canadian French, Danish, Dutch, Finnish, French, German, Greek, Italian, Norwegian Bokmal, Portuguese, Spanish, Swedish and Ukrainian. Grammar checking is available for 15 of them &mdash; there is no grammar checking for Finnish and Norwegian.
+
+There are also over 150 additional languages and specialized dictionaries such as medical and legal available for an additional fee. You can check the full list [here](https://webspellchecker.com/additional-dictionaries/).
+
+## Installation
+
+WProofreader is installed separately from CKEditor 5 and does not need to be combined into an editor build as other features. To use this tool, it is necessary to load the WProofreader script on your page and provide the configuration.
+
+The proofreader can be used either as a [cloud solution](#wproofreader-cloud) or [hosted on your own server](#wproofreader-server).
+
+### WProofreader Cloud
+
+After signing up for a [trial or paid version](https://ckeditor.com/contact/), you will receive your service ID which is used to activate the service.
+
+Add the following configuration to your page:
+
+```html
+<script>
+	window.WEBSPELLCHECKER_CONFIG = {
+		autoSearch: true,
+		enableGrammar: true,
+		serviceId: 'your-service-ID'
+	};
+</script>
+```
+
+And then load the proofreader script:
+
+```html
+<script src="https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js"></script>
+```
+
+Refer to the [official documentation](https://github.com/WebSpellChecker/wproofreader#wproofreader-cloud) for more details about the cloud setup and available configuration options.
+
+### WProofreader Server
+
+After signing up for a [trial or paid version](https://ckeditor.com/contact/), you will receive access to the WebSpellChecker Server package to install on your own server.
+
+You will need to add the following configuration to your page:
+
+```html
+<script>
+	window.WEBSPELLCHECKER_CONFIG = {
+		autoSearch: true,
+		enableGrammar: true,
+		servicePort: '2880',
+		servicePath: '/'
+	};
+</script>
+```
+
+Then specify the path to the service on your page:
+
+```html
+<script src="http(s)://your_host_name/spellcheck/wscbundle/wscbundle.js"></script>
+```
+
+Refer to the [official documentation](https://github.com/WebSpellChecker/wproofreader#wproofreader-server) for more details about the server setup and available configuration options.
+
+## Configuration
+
+WProofreader configuration is set outside the CKEditor 5 configuration. Refer to the [WProofreader API](http://dev.webspellchecker.net/api/wscbundle/) for further information.
+
+## Contribute
+
+You can report issues and request features in the [official WProofreader repository](https://github.com/WebSpellChecker/wproofreader/issues).

+ 70 - 21
docs/features/ui-language.md

@@ -2,16 +2,34 @@
 category: features
 category: features
 ---
 ---
 
 
+{@snippet features/build-ui-language-source}
+
 # Setting the UI language
 # Setting the UI language
 
 
-The UI of the editor can be localized. CKEditor 5 currently supports around 20 languages and the number is growing.
+The UI of the editor can be localized. CKEditor 5 currently supports around 50 languages and the number is growing.
 
 
-If you want to help translate CKEditor 5 into your native language, join the [CKEditor 5 project on Transifex](https://www.transifex.com/ckeditor/ckeditor5/). Your help will be much appreciated!
+<info-box>
+	If you want to help translate CKEditor 5 into your native language, join the [CKEditor 5 project on Transifex](https://www.transifex.com/ckeditor/ckeditor5/). Your help will be much appreciated!
+</info-box>
 
 
-See the demo of the editor in German:
+See the demo of the editor in Spanish:
 
 
 {@snippet features/ui-language}
 {@snippet features/ui-language}
 
 
+## Right–to–left (RTL) languages support
+
+CKEditor 5 supports right–to–left languages out–of–the–box. When one of <abbr title="right–to–left">RTL</abbr> languages is used, the WYSIWYG editor adapts its UI for the best editing experience, for instance, mirroring various elements like toolbars, dropdowns, buttons, etc.
+
+See the demo of the editor in Arabic:
+
+{@snippet features/ui-language-rtl}
+
+<info-box>
+	If you want to change the language of the content only (different languages for the UI and the content), check out the [Setting the language of the content](#setting-the-language-of-the-content) section to learn more.
+</info-box>
+
+We are doing our best to deliver the best RTL support to our users and we constantly improve the editor. Check out the [RTL support](https://github.com/ckeditor/ckeditor5/issues/1151) issue on GitHub to learn more and stay up–to–date. Your feedback is much appreciated!
+
 ## Loading additional languages from CDN, npm and zip file
 ## Loading additional languages from CDN, npm and zip file
 
 
  By default, the editor will display in English. This is the language built into the `ckeditor.js` files. In order to change the language of the editor UI, you need to load additional language file(s). Check out the following sections to see how to do that:
  By default, the editor will display in English. This is the language built into the `ckeditor.js` files. In order to change the language of the editor UI, you need to load additional language file(s). Check out the following sections to see how to do that:
@@ -26,7 +44,7 @@ Next, you can configure the editor to use the chosen language:
 ClassicEditor
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
 	.create( document.querySelector( '#editor' ), {
 		// The language code is defined in the https://en.wikipedia.org/wiki/ISO_639-1 standard.
 		// The language code is defined in the https://en.wikipedia.org/wiki/ISO_639-1 standard.
-		language: 'de'
+		language: 'es'
 	} )
 	} )
 	.then( editor => {
 	.then( editor => {
 		console.log( editor );
 		console.log( editor );
@@ -38,7 +56,7 @@ ClassicEditor
 
 
 ### CDN
 ### CDN
 
 
-To use different language than default one (English), you need to load the editor together with the preferred language:
+To use a different language than the default one (English), you need to load the editor together with the preferred language:
 
 
 ```html
 ```html
 <script src="https://cdn.ckeditor.com/ckeditor5/[version.number]/[distribution]/ckeditor.js"></script>
 <script src="https://cdn.ckeditor.com/ckeditor5/[version.number]/[distribution]/ckeditor.js"></script>
@@ -52,34 +70,34 @@ For example:
 <script src="https://cdn.ckeditor.com/ckeditor5/{@var ckeditor5-version}/classic/translations/de.js"></script>
 <script src="https://cdn.ckeditor.com/ckeditor5/{@var ckeditor5-version}/classic/translations/de.js"></script>
 ```
 ```
 
 
-See {@link builds/guides/integration/installation#cdn CDN installation guides} for more information.
+See the {@link builds/guides/integration/installation#cdn CDN installation guide} for more information.
 
 
 ### npm
 ### npm
 
 
-After installing the build from npm, languages will be available at `node_modules/@ckeditor/ckeditor5-build-[name]/build/translations/[lang].js`.
+After installing the build from npm, languages will be available in `node_modules/@ckeditor/ckeditor5-build-[name]/build/translations/[lang].js`.
 
 
-Single language can be loaded directly to your code by importing e.g. `'@ckeditor/ckeditor5-build-classic/build/translations/de.js'`.
+A single language can be loaded directly to your code by importing e.g. `'@ckeditor/ckeditor5-build-classic/build/translations/de.js'`.
 
 
-See {@link builds/guides/integration/installation#npm npm installation guides} for more information.
+See the {@link builds/guides/integration/installation#npm npm installation guide} for more information.
 
 
 ### Zip
 ### Zip
 
 
-All additional languages are included in the `.zip` file. You need to include `ckeditor.js` file together with the chosen language file:
+All additional languages are included in the `.zip` file. You need to include the `ckeditor.js` file together with the chosen language file:
 
 
 ```html
 ```html
 <script src="[ckeditor-path]/ckeditor.js"></script>
 <script src="[ckeditor-path]/ckeditor.js"></script>
 <script src="[ckeditor-path]/translations/de.js"></script>
 <script src="[ckeditor-path]/translations/de.js"></script>
 ```
 ```
 
 
-See {@link builds/guides/integration/installation#zip-download zip installation guides} for more information.
+See the {@link builds/guides/integration/installation#zip-download zip installation guide} for more information.
 
 
 ## Building the editor using a specific language
 ## Building the editor using a specific language
 
 
-Currently, it is possible to change the UI language at the build stage and after the build. A single build of the editor supports the language which was defined in the [CKEditor 5 webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin)'s configuration. See the whole translation process to see how you can change the language later.
+Currently, it is possible to change the UI language at the build stage and after the build. A single build of the editor supports the language which was defined in the [CKEditor 5 webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin)'s configuration. Check the whole translation process to see how you can change the language later.
 
 
 If you use one of the {@link builds/index predefined editor builds}, refer to {@link builds/guides/development/custom-builds Creating custom builds} to learn how to change the language of your build.
 If you use one of the {@link builds/index predefined editor builds}, refer to {@link builds/guides/development/custom-builds Creating custom builds} to learn how to change the language of your build.
 
 
-If you build CKEditor from scratch or integrate it directly into your application, then all you need to do is to:
+If you build CKEditor 5 from scratch or integrate it directly into your application, then all you need to do is to:
 
 
 1. Install the [`@ckeditor/ckeditor5-dev-webpack-plugin`](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin) package:
 1. Install the [`@ckeditor/ckeditor5-dev-webpack-plugin`](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin) package:
 
 
@@ -94,10 +112,10 @@ If you build CKEditor from scratch or integrate it directly into your applicatio
 	```js
 	```js
 	const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
 	const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
 
 
-	// Define webpack plugins ...
+	// Define webpack plugins...
 		plugins: [
 		plugins: [
 			new CKEditorWebpackPlugin( {
 			new CKEditorWebpackPlugin( {
-				// Main language that will be built into the main bundle.
+				// The main language that will be built into the main bundle.
 				language: 'en',
 				language: 'en',
 
 
 				// Additional languages that will be emitted to the `outputDirectory`.
 				// Additional languages that will be emitted to the `outputDirectory`.
@@ -105,7 +123,7 @@ If you build CKEditor from scratch or integrate it directly into your applicatio
 				// The bundle is optimized for one language when this option is omitted.
 				// The bundle is optimized for one language when this option is omitted.
 				additionalLanguages: 'all',
 				additionalLanguages: 'all',
 
 
-				// Optional directory for emitted translations. Relative to the webpack's output.
+				// An optional directory for emitted translations. Relative to the webpack's output.
 				// Defaults to `'translations'`.
 				// Defaults to `'translations'`.
 				// outputDirectory: 'ckeditor5-translations',
 				// outputDirectory: 'ckeditor5-translations',
 
 
@@ -123,17 +141,17 @@ If you build CKEditor from scratch or integrate it directly into your applicatio
 	// ...
 	// ...
 	```
 	```
 
 
-3. Run webpack. If the `additionalLanguages` option is not set, the CKEditor plugin for webpack will replace the {@link module:utils/locale~Locale#t `t()`} function call parameters used in the source code with localized language strings. Otherwise the CKEditor plugin for webpack will replace the {@link module:utils/locale~Locale#t `t()`} function call parameters with short ids and emit the translation files that should land in the `'translations'` directory (or different, if the `outputDirectory` option is specified).
+3. Run webpack. If the `additionalLanguages` option is not set, the CKEditor 5 plugin for webpack will replace the {@link module:utils/locale~Locale#t `t()`} function call parameters used in the source code with localized language strings. Otherwise the CKEditor 5 plugin for webpack will replace the {@link module:utils/locale~Locale#t `t()`} function call parameters with short IDs and emit the translation files that should land in the `'translations'` directory (or different, if the `outputDirectory` option is specified).
 
 
-4. If you want to change the language after the build ends, you will need to edit the `index.html` file, add the translation file and set the UI language to the target one.
+4. If you want to change the language after the build ends, you will need to edit the `index.html` file, add the translation file, and set the UI language to the target one.
 
 
 	```html
 	```html
 	<script src="../build/ckeditor.js"></script>
 	<script src="../build/ckeditor.js"></script>
-	<script src="../build/translations/pl.js"></script>
+	<script src="../build/translations/de.js"></script>
 	<script>
 	<script>
 		ClassicEditor
 		ClassicEditor
 			.create( document.querySelector( '#editor' ), {
 			.create( document.querySelector( '#editor' ), {
-				language: 'pl'
+				language: 'de'
 			} )
 			} )
 			.then( editor => {
 			.then( editor => {
 				window.editor = editor;
 				window.editor = editor;
@@ -147,5 +165,36 @@ If you build CKEditor from scratch or integrate it directly into your applicatio
 <info-box>
 <info-box>
 	We are aware that the current localization method is not sufficient for some needs. It does not support different bundlers (e.g. Rollup or Browserify). We will be extending the localization possibilities in the future.
 	We are aware that the current localization method is not sufficient for some needs. It does not support different bundlers (e.g. Rollup or Browserify). We will be extending the localization possibilities in the future.
 
 
-	You can read more about the used techniques in the ["Implement translation services" issue](https://github.com/ckeditor/ckeditor5/issues/387) and ["Implement translation services v2" issue](https://github.com/ckeditor/ckeditor5/issues/624).
+	You can read more about the used techniques in the [Implement translation services](https://github.com/ckeditor/ckeditor5/issues/387) and [Implement translation services v2](https://github.com/ckeditor/ckeditor5/issues/624) issues.
+</info-box>
+
+## Setting the language of the content
+
+In CKEditor 5 you can separately configure the language of the UI and the language of the content. This means you can use the English UI of the editor but type your content in Arabic or Hebrew. The language of the content has an impact on the editing experience, for instance it affects screen readers and spell checkers. It is also particularly useful for typing in certain languages (e.g. [right–to–left](#righttoleft-rtl-languages-support) ones) because it changes the default alignment of the text.
+
+Configure {@link module:core/editor/editorconfig~EditorConfig#language `config.language`} to change the language of the content. In this example, the UI of the editor will be English but the content will be Arabic:
+
+```js
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		language: {
+			// The UI will be English.
+			ui: 'en',
+
+			// But the content will be edited in Arabic.
+			content: 'ar'
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );
+```
+
+{@snippet features/ui-language-content}
+
+<info-box>
+	If you are unsure about the language that the content will be typed in, do not set it. The language of the content will then be inherited from the {@link module:core/editor/editorconfig~EditorConfig#language language of the UI}.
 </info-box>
 </info-box>

+ 4 - 4
docs/framework/guides/architecture/ui-library.md

@@ -16,7 +16,7 @@ Views use [templates](#templates) to build the UI. They also provide observable
 A simple input view class can be defined as follows:
 A simple input view class can be defined as follows:
 
 
 ```js
 ```js
-class SampleInputView extends View {
+class SimpleInputView extends View {
 	constructor( locale ) {
 	constructor( locale ) {
 		super( locale );
 		super( locale );
 
 
@@ -66,8 +66,8 @@ class ParentView extends View {
 	constructor( locale ) {
 	constructor( locale ) {
 		super( locale );
 		super( locale );
 
 
-		const childA = new SampleInputView( locale );
-		const childB = new SampleInputView( locale );
+		const childA = new SimpleInputView( locale );
+		const childB = new SimpleInputView( locale );
 
 
 		this.setTemplate( {
 		this.setTemplate( {
 			tag: 'div',
 			tag: 'div',
@@ -90,7 +90,7 @@ document.body.appendChild( parent.element );
 It is also possible to create standalone views that do not belong to any collection. They must be {@link module:ui/view~View#render rendered} before injection into the DOM:
 It is also possible to create standalone views that do not belong to any collection. They must be {@link module:ui/view~View#render rendered} before injection into the DOM:
 
 
 ```js
 ```js
-const view = new SampleInputView( locale );
+const view = new SimpleInputView( locale );
 
 
 view.render();
 view.render();
 
 

+ 1 - 1
docs/framework/guides/contributing/contributing.md

@@ -87,7 +87,7 @@ Some additional things you should keep in mind:
 * Make sure you signed the [Contributor License Agreement (CLA)](#contributor-license-agreement-cla) and that tests pass. Test your changes!
 * Make sure you signed the [Contributor License Agreement (CLA)](#contributor-license-agreement-cla) and that tests pass. Test your changes!
 
 
 <info-box>
 <info-box>
-	If want your changes to be permanent in your development environment, make sure your `mgit.json` file {@link framework/guides/contributing/development-environment#using-mgit-for-custom-packages points to your forked version of the repository} so next time you execute `mgit sync` to refresh the project, the utility will use your fork.
+	If want your changes to be permanent in your development environment, make sure your `mrgit.json` file {@link framework/guides/contributing/development-environment#using-mrgit-for-custom-packages points to your forked version of the repository} so next time you execute `mrgit sync` to refresh the project, the utility will use your fork.
 </info-box>
 </info-box>
 
 
 ## Translating
 ## Translating

+ 30 - 19
docs/framework/guides/contributing/development-environment.md

@@ -8,7 +8,7 @@ order: 10
 The CKEditor 5 codebase is divided into multiple [npm](http://npmjs.com/) packages, each developed in a separate Git repository. The main package is [`ckeditor5`](https://github.com/ckeditor/ckeditor5) which installs all project dependencies and various development-related resources such as:
 The CKEditor 5 codebase is divided into multiple [npm](http://npmjs.com/) packages, each developed in a separate Git repository. The main package is [`ckeditor5`](https://github.com/ckeditor/ckeditor5) which installs all project dependencies and various development-related resources such as:
 
 
 * the testing environment setup,
 * the testing environment setup,
-* configuration for [mgit](https://www.npmjs.com/package/mgit2) (a multi-repo management tool) and [Yarn](https://yarnpkg.com/) (a dependency management tool),
+* configuration for [Mr. Git](https://www.npmjs.com/package/mrgit) (a multi-repo management tool) and [Yarn](https://yarnpkg.com/) (a dependency management tool),
 * translation management tools,
 * translation management tools,
 * documentation generator,
 * documentation generator,
 * and release tools.
 * and release tools.
@@ -26,13 +26,13 @@ In order to start developing CKEditor 5 you will require:
 
 
 First, you need to install a couple of tools which you will be using later:
 First, you need to install a couple of tools which you will be using later:
 
 
-* [mgit2](https://www.npmjs.com/package/mgit2) &mdash; A multi-repo management tool,
+* [mrgit](https://www.npmjs.com/package/mrgit) &mdash; A multi-repo management tool,
 * [Yarn](https://yarnpkg.com/) &mdash; A dependency management tool.
 * [Yarn](https://yarnpkg.com/) &mdash; A dependency management tool.
 
 
 It is best to install them globally in your system for an easier use later on:
 It is best to install them globally in your system for an easier use later on:
 
 
 ```bash
 ```bash
-npm install -g yarn mgit2
+npm install -g yarn mrgit
 ```
 ```
 
 
 **Note:** [Read how to avoid using `sudo` to install packages globally](https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md) or use [nvm](https://github.com/creationix/nvm).
 **Note:** [Read how to avoid using `sudo` to install packages globally](https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md) or use [nvm](https://github.com/creationix/nvm).
@@ -56,12 +56,12 @@ yarn install
 
 
 The steps above should install all the packages from npm, which means that you will have the latest releases of all of them. They are available in `node_modules/@ckeditor/` (we are using [scoped packages](https://docs.npmjs.com/misc/scope), hence the unusual directory).
 The steps above should install all the packages from npm, which means that you will have the latest releases of all of them. They are available in `node_modules/@ckeditor/` (we are using [scoped packages](https://docs.npmjs.com/misc/scope), hence the unusual directory).
 
 
-In order to work with development versions of all the official packages, it is recommended to use mgit. This tool will clone all package repositories to the `packages/` directory. Then, those packages need to be installed in a way understandable by Node.js-compliant tools (like webpack or Browserify). In order to achieve that we use Yarn's feature called [workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) which creates symlinks to these packages.
+In order to work with development versions of all the official packages, it is recommended to use `mrgit`. This tool will clone all package repositories to the `packages/` directory. Then, those packages need to be installed in a way understandable by Node.js-compliant tools (like webpack or Browserify). In order to achieve that we use Yarn's feature called [workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) which creates symlinks to these packages.
 
 
 First, clone all the repositories:
 First, clone all the repositories:
 
 
 ```bash
 ```bash
-mgit sync
+mrgit sync
 ```
 ```
 
 
 Expected result:
 Expected result:
@@ -138,7 +138,7 @@ Whenever you want to update all packages to their latest versions call:
 git pull
 git pull
 
 
 # To update pull changes to all the packages:
 # To update pull changes to all the packages:
-mgit sync
+mrgit sync
 
 
 # To install missing dependencies:
 # To install missing dependencies:
 yarn install
 yarn install
@@ -151,23 +151,23 @@ git pull
 yarn run reinstall
 yarn run reinstall
 ```
 ```
 
 
-The `reinstall` script first calls `yarn run clean` to remove `node_modules/` directories from all packages (including `ckeditor5`) and then `yarn run bootstrap` which is a shorthand for `mgit sync && yarn install`.
+The `reinstall` script first calls `yarn run clean` to remove `node_modules/` directories from all packages (including `ckeditor5`) and then `yarn run bootstrap` which is a shorthand for `mrgit sync && yarn install`.
 
 
 ### Working with multiple repositories
 ### Working with multiple repositories
 
 
-Mgit implements many useful commands, such as:
+Mr. Git implements many useful commands, such as:
 
 
-* `mgit exec 'command'` – executing a shell command in all repositories,
-* `mgit checkout <branch>` – checking all repositories to given branch (or hash),
-* `mgit status` – displaying information about all repositories.
+* `mrgit exec 'command'` – executing a shell command in all repositories,
+* `mrgit checkout <branch>` – checking all repositories to given branch (or hash),
+* `mrgit status` – displaying information about all repositories.
 
 
-Read more about those commands in [mgit's documentation](https://github.com/cksource/mgit2).
+Read more about those commands in [mrgit's documentation](https://github.com/cksource/mrgit).
 
 
-Mgit has been developed by the [CKSource team](https://cksource.com/) and we are relying on it heavily, hence you can expect more features and improvements to come. However, it is not a CKEditor-specific tool and should be suitable for any multi-repository project (though it best fits JavaScript projects).
+Mr. Git has been developed by the [CKSource team](https://cksource.com/) and we are relying on it heavily, hence you can expect more features and improvements to come. However, it is not a CKEditor-specific tool and should be suitable for any multi-repository project (though it best fits JavaScript projects).
 
 
-### Using mgit for custom packages
+### Using `mrgit` for custom packages
 
 
-If you are developing custom packages or forked any of the official packages and want mgit to work with it, change the dependencies configuration in [`mgit.json`](https://github.com/ckeditor/ckeditor5/blob/master/mgit.json). Note that mgit is able to clone the package from any Git URL. Refer to [its documentation](https://github.com/cksource/mgit2) for more details.
+If you are developing custom packages or forked any of the official packages and want `mrgit` to work with it, change the dependencies configuration in [`mrgit.json`](https://github.com/ckeditor/ckeditor5/blob/master/mrgit.json). Note that `mrgit` is able to clone the package from any Git URL. Refer to [its documentation](https://github.com/cksource/mrgit) for more details.
 
 
 ## Running tests
 ## Running tests
 
 
@@ -193,7 +193,7 @@ To create a server for manual tests use the `manual` task:
 yarn run manual
 yarn run manual
 ```
 ```
 
 
-It accepts the `--source-map` (`-s`) option. Note that it watches for changes in the JavaScript files only (see the [bug](https://github.com/ckeditor/ckeditor5-dev/issues/52)).
+It accepts the `--source-map` (`-s`) and `--additionalLanguages="ar,pl,..."` options. Note that it watches for changes in the JavaScript files only (see the [bug](https://github.com/ckeditor/ckeditor5-dev/issues/52)).
 
 
 You can read more about the {@link framework/guides/contributing/testing-environment Testing environment}.
 You can read more about the {@link framework/guides/contributing/testing-environment Testing environment}.
 
 
@@ -211,7 +211,7 @@ This task accepts the following arguments:
 
 
 * `--skip-api` &mdash; Skips building the API documentation (which takes the majority of the total time).
 * `--skip-api` &mdash; Skips building the API documentation (which takes the majority of the total time).
 * `--skip-snippets` &mdash; Skips building live snippets.
 * `--skip-snippets` &mdash; Skips building live snippets.
-* `--whitelisted-snippet=snippet-name` &mdash; Builds a single snippet (`snippet-name.js`) only.
+* `--snippets=snippet-name` &mdash; Whitelist snippets to build (accepts glob patterns).
 * `--skip-validation` &mdash; Skips the final link validation.
 * `--skip-validation` &mdash; Skips the final link validation.
 * `--watch` &mdash; Runs the documentation generator in a watch mode. It covers guides (it does not cover API docs).
 * `--watch` &mdash; Runs the documentation generator in a watch mode. It covers guides (it does not cover API docs).
 * `--production` &mdash; Minifies the assets and performs other actions which are unnecessary during CKEditor 5 development.
 * `--production` &mdash; Minifies the assets and performs other actions which are unnecessary during CKEditor 5 development.
@@ -223,11 +223,22 @@ Note: These arguments must be passed after additional `--`:
 yarn run docs --skip-api
 yarn run docs --skip-api
 ```
 ```
 
 
+## Generating content styles
+
+It is possible to generate a stylesheet containing content styles brought by all CKEditor 5 features. In order to do that, execute:
+
+```bash
+yarn docs:content-styles
+```
+The stylesheet will be saved in the `build/content-styles` folder.
+
+To learn more, refer to the {@link builds/guides/integration/content-styles Content styles} guide.
+
 ## Bisecting through a multi-repository
 ## Bisecting through a multi-repository
 
 
 CKEditor 5 is a multi-repository project. It means that [`git bisect`](https://git-scm.com/docs/git-bisect) (which is super handy when tracking which commit introduced a bug) will not work out of the box.
 CKEditor 5 is a multi-repository project. It means that [`git bisect`](https://git-scm.com/docs/git-bisect) (which is super handy when tracking which commit introduced a bug) will not work out of the box.
 
 
-Fortunately, every commit made to any of the `master` branches of all CKEditor 5 subpackages will update this subpackage's hash in `mgit.json` in the [`master-revisions`](https://github.com/ckeditor/ckeditor5/commits/master-revisions) branch.
+Fortunately, every commit made to any of the `master` branches of all CKEditor 5 subpackages will update this subpackage's hash in `mrgit.json` in the [`master-revisions`](https://github.com/ckeditor/ckeditor5/commits/master-revisions) branch.
 
 
 Thanks to that, `master-revisions` contains an ordered history of all changes which makes it possible to go back to any point in history:
 Thanks to that, `master-revisions` contains an ordered history of all changes which makes it possible to go back to any point in history:
 
 
@@ -240,7 +251,7 @@ git pull
 git co master-revisions~30
 git co master-revisions~30
 
 
 # Check out subpackages to correct hashes.
 # Check out subpackages to correct hashes.
-mgit co
+mrgit co
 ```
 ```
 
 
 Once you found the point in history which interests you, you can go straight to a commit in a subpackage and PR. For example:
 Once you found the point in history which interests you, you can go straight to a commit in a subpackage and PR. For example:

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

@@ -25,6 +25,7 @@ It accepts the following arguments (must be passed after the `--` option):
 * `--verbose` (alias `-v`) &ndash; Allows switching on webpack logs.
 * `--verbose` (alias `-v`) &ndash; Allows switching on webpack logs.
 * `--files` &ndash; Specifies tests files to run. Accepts a package name or a glob. 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).
 * `--files` &ndash; Specifies tests files to run. Accepts a package name or a glob. 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).
 * `--browsers` &ndash; Browsers which will be used to run the tests. Defaults to `Chrome`.
 * `--browsers` &ndash; Browsers which will be used to run the tests. Defaults to `Chrome`.
+* `--debug` (alias `-d`) &ndash; Allows specifying custom debug flags. For example, the `--debug engine` option uncomments the `// @if CK_DEBUG_ENGINE //` lines in the code. The `--debug false` option turns the debugging mechanism off and leaves the lines starting with `// @if CK_DEBUG //` untouched.
 
 
 ### Examples
 ### Examples
 
 
@@ -50,7 +51,10 @@ yarn run test -cw --files=basic-styles/bold*.js
 
 
 In order to start the manual tests server use the `yarn run manual` task.
 In order to start the manual tests server use the `yarn run manual` task.
 
 
-The task accepts the `--source-map` (alias `-s`) option.
+The task accepts the following options:
+
+* `--source-map` (alias `-s`) that generates useful source maps for the code.
+* `--additionalLanguages="ar,pl,..."` that passes 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.
 
 
 It starts the server available at http://localhost:8125.
 It starts the server available at http://localhost:8125.
 
 
@@ -125,7 +129,7 @@ ClassicEditor
 
 
 To ensure the highest quality, we maintain a complete test suite with a stable 100% of code coverage for each of the packages. As of May 2018, this means over 8000 tests and the number is growing. Since every package is tested separately, we implement lower-level tests for libraries and higher-level tests for end-user features.
 To ensure the highest quality, we maintain a complete test suite with a stable 100% of code coverage for each of the packages. As of May 2018, this means over 8000 tests and the number is growing. Since every package is tested separately, we implement lower-level tests for libraries and higher-level tests for end-user features.
 
 
-Such an extensive test suite requires a proper continuous integration service. We use [Travis CI](https://travis-ci.com/) as a build platform and [BrowserStack](https://www.browserstack.com/) to be able to run tests on all browsers. These services ensure seamless and fast developer experience and allow us to focus on the job.
+Such an extensive test suite requires a proper continuous integration service. We use [Travis CI](https://travis-ci.com/) as a build platform. This service ensures seamless and fast developer experience and allow us to focus on the job.
 
 
 Besides automated tests, we also maintain a smaller set of manual tests. They help us verify whether something unexpected happens that might have been missed by the automated tests.
 Besides automated tests, we also maintain a smaller set of manual tests. They help us verify whether something unexpected happens that might have been missed by the automated tests.
 
 

+ 10 - 10
docs/framework/guides/creating-simple-plugin.md

@@ -5,13 +5,13 @@ order: 30
 
 
 # Creating a simple plugin
 # Creating a simple plugin
 
 
-This guide will show you how to create a simple editor plugin.
+This guide will show you how to create a simple rich-text editor plugin for CKEditor 5.
 
 
 <info-box>
 <info-box>
-	Before you get to work, you should check out the {@link framework/guides/quick-start "Quick start"} guide first and set up the framework and building tools.
+	Before you get to work, you should check out the {@link framework/guides/quick-start Quick start} guide first to set up the framework and building tools.
 </info-box>
 </info-box>
 
 
-CKEditor plugins need to implement the {@link module:core/plugin~PluginInterface}. The easiest way to do that is to inherit from the {@link module:core/plugin~Plugin base `Plugin` class}, however, you can also write simple constructor functions. This guide uses the former method.
+CKEditor plugins need to implement the {@link module:core/plugin~PluginInterface}. The easiest way to do that is to inherit from the {@link module:core/plugin~Plugin base `Plugin` class}. However, you can also write simple constructor functions. This guide uses the former method.
 
 
 The plugin that you will write will use a part of the {@link features/image image feature} and will add a simple UI to it &mdash; an "Insert image" button that will open a prompt window asking for the image URL when clicked. Submitting the URL will result in inserting the image into the content and selecting it.
 The plugin that you will write will use a part of the {@link features/image image feature} and will add a simple UI to it &mdash; an "Insert image" button that will open a prompt window asking for the image URL when clicked. Submitting the URL will result in inserting the image into the content and selecting it.
 
 
@@ -21,7 +21,7 @@ The plugin that you will write will use a part of the {@link features/image imag
 
 
 ## Step 1. Installing dependencies
 ## Step 1. Installing dependencies
 
 
-Start from installing necessary dependencies:
+Start from installing the necessary dependencies:
 
 
 * The [`@ckeditor/ckeditor5-image`](https://www.npmjs.com/package/@ckeditor/ckeditor5-image) package that contains the image feature (on which the plugin will rely).
 * The [`@ckeditor/ckeditor5-image`](https://www.npmjs.com/package/@ckeditor/ckeditor5-image) package that contains the image feature (on which the plugin will rely).
 * The [`@ckeditor/ckeditor5-core`](https://www.npmjs.com/package/@ckeditor/ckeditor5-core) package which contains the {@link module:core/plugin~Plugin} and {@link module:core/command~Command} classes.
 * The [`@ckeditor/ckeditor5-core`](https://www.npmjs.com/package/@ckeditor/ckeditor5-core) package which contains the {@link module:core/plugin~Plugin} and {@link module:core/command~Command} classes.
@@ -39,7 +39,7 @@ npm install --save @ckeditor/ckeditor5-image \
 
 
 Now, open the `app.js` file and start adding code there. Usually, when implementing more complex features you will want to split the code into multiple files (modules). However, to make this guide simpler the entire code will be kept in `app.js`.
 Now, open the `app.js` file and start adding code there. Usually, when implementing more complex features you will want to split the code into multiple files (modules). However, to make this guide simpler the entire code will be kept in `app.js`.
 
 
-First thing to do will be to load the core of the image feature:
+The first thing to do will be to load the core of the image feature:
 
 
 ```js
 ```js
 import Image from '@ckeditor/ckeditor5-image/src/image';
 import Image from '@ckeditor/ckeditor5-image/src/image';
@@ -147,7 +147,7 @@ Rebuild the application and refresh the page. You should see a new button in the
 
 
 ## Step 4. Inserting a new image
 ## Step 4. Inserting a new image
 
 
-Now, expand the button's `#execute` event listener, so it will actually insert a new image into the content:
+Now, expand the button's `#execute` event listener, so it will actually insert the new image into the content:
 
 
 ```js
 ```js
 class InsertImage extends Plugin {
 class InsertImage extends Plugin {
@@ -187,7 +187,7 @@ If you refresh the page, you should now be able to insert new images into the co
 
 
 {@img assets/img/framework-quick-start-classic-editor-insert-image.gif 640 Screencast of inserting a new image.}
 {@img assets/img/framework-quick-start-classic-editor-insert-image.gif 640 Screencast of inserting a new image.}
 
 
-The image is fully functional, you can undo inserting by pressing <kbd>Ctrl</kbd>+<kbd>Z</kbd> and the image is always inserted as a block element (the paragraph that contains the selection is automatically split). This is all handled by the CKEditor 5 engine.
+The image is fully functional. You can undo inserting by pressing <kbd>Ctrl</kbd>+<kbd>Z</kbd> and the image is always inserted as a block element (the paragraph that contains the selection is automatically split). This is all handled by the CKEditor 5 engine.
 
 
 <info-box>
 <info-box>
 	As you can see, by clicking the button you are inserting an `<image src="...">` element into the model. The image feature is represented in the model as `<image>`, while in the view (i.e. the virtual DOM) and in the real DOM it is rendered as `<figure class="image"><img src="..."></figure>`.
 	As you can see, by clicking the button you are inserting an `<image src="...">` element into the model. The image feature is represented in the model as `<image>`, while in the view (i.e. the virtual DOM) and in the real DOM it is rendered as `<figure class="image"><img src="..."></figure>`.
@@ -199,7 +199,7 @@ Congratulations! You have just created your first CKEditor 5 plugin!
 
 
 ## Bonus. Enabling image captions
 ## Bonus. Enabling image captions
 
 
-Thanks to the fact that all plugins operate on the model and on the view and know as little about themselves as possible, you can easily enable image captions by simply loading the {@link module:image/imagecaption~ImageCaption} plugin:
+Thanks to the fact that all plugins operate on the model and on the view, and know as little about themselves as possible, you can easily enable image captions by simply loading the {@link module:image/imagecaption~ImageCaption} plugin:
 
 
 ```js
 ```js
 import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
 import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
@@ -286,9 +286,9 @@ ClassicEditor
 
 
 ## What's next?
 ## What's next?
 
 
-If you would like to read more tutorials check out the following one:
+If you would like to read more tutorials, check out the following one:
 
 
 * {@link framework/guides/tutorials/implementing-a-block-widget Implementing a block widget}
 * {@link framework/guides/tutorials/implementing-a-block-widget Implementing a block widget}
 * {@link framework/guides/tutorials/implementing-an-inline-widget Implementing an inline widget}
 * {@link framework/guides/tutorials/implementing-an-inline-widget Implementing an inline widget}
 
 
-If you are more into reading about CKEditor 5's architecture, check out the {@link framework/guides/architecture/intro Introduction to CKEditor 5 architecture}.
+If you are more into reading about the CKEditor 5 architecture, check out the {@link framework/guides/architecture/intro Introduction to CKEditor 5 architecture}.

+ 1 - 1
docs/framework/guides/custom-editor-creator.md

@@ -203,7 +203,7 @@ class MultirootEditorUI extends EditorUI {
 
 
 			// Register the editable UI view in the editor. A single editor instance can aggregate multiple
 			// Register the editable UI view in the editor. A single editor instance can aggregate multiple
 			// editable areas (roots) but the decoupled editor has only one.
 			// editable areas (roots) but the decoupled editor has only one.
-			this._editableElements.set( editable.name, editableElement );
+			this.setEditableElement( editable.name, editableElement );
 
 
 			// Let the global focus tracker know that the editable UI element is focusable and
 			// Let the global focus tracker know that the editable UI element is focusable and
 			// belongs to the editor. From now on, the focus tracker will sustain the editor focus
 			// belongs to the editor. From now on, the focus tracker will sustain the editor focus

+ 10 - 10
docs/framework/guides/development-tools.md

@@ -5,21 +5,21 @@ order: 40
 
 
 # Development tools
 # Development tools
 
 
-In this guide you will learn about developer tools that will help you develop and debug editor plugins and features.
+In this guide you will learn about developer tools that will help you develop and debug CKEditor 5 plugins and features.
 
 
 ## CKEditor 5 inspector
 ## CKEditor 5 inspector
 
 
-The official [CKEditor 5 inspector](https://github.com/ckeditor/ckeditor5-inspector) provides rich debugging tools for editor internals like {@link framework/guides/architecture/editing-engine#model model}, {@link framework/guides/architecture/editing-engine#view view}, and  {@link framework/guides/architecture/core-editor-architecture#commands commands}.
+The official [CKEditor 5 inspector](https://github.com/ckeditor/ckeditor5-inspector) provides rich debugging tools for editor internals like {@link framework/guides/architecture/editing-engine#model model}, {@link framework/guides/architecture/editing-engine#view view}, and {@link framework/guides/architecture/core-editor-architecture#commands commands}.
 
 
-It allows observing changes to the data structures and the selection live in the editor which is particularly helpful when developing new editor features or getting to understand the existing ones.
+It allows you to observe changes to the data structures and the selection live in the editor, which is particularly helpful when developing new rich-text editor features or getting to understand the existing ones.
 
 
-{@img assets/img/framework-development-tools-inspector.jpg Screenshot of a CKEditor 5 inspector attached to an editor instance.}
+{@img assets/img/framework-development-tools-inspector.jpg Screenshot of the CKEditor 5 inspector attached to a WYSIWYG editor instance.}
 
 
 ### Importing the inspector
 ### Importing the inspector
 
 
 You can import the inspector as an [`@ckeditor/ckeditor5-inspector`](https://www.npmjs.com/package/@ckeditor/ckeditor5-inspector) package into your project:
 You can import the inspector as an [`@ckeditor/ckeditor5-inspector`](https://www.npmjs.com/package/@ckeditor/ckeditor5-inspector) package into your project:
 
 
-```
+```bash
 npm install --save-dev @ckeditor/ckeditor5-inspector
 npm install --save-dev @ckeditor/ckeditor5-inspector
 ```
 ```
 
 
@@ -54,14 +54,14 @@ The inspector will show up at the bottom of the screen.
 
 
 ### Inspecting multiple editors
 ### Inspecting multiple editors
 
 
-You can inspect multiple editor instances at a time by calling `CKEditorInspector.attach()` for each one of them. Then you can switch the inspector context to inspect different editors.
+You can inspect multiple CKEditor 5 instances at a time by calling `CKEditorInspector.attach()` for each one of them. Then you can switch the inspector context to inspect different editor instances.
 
 
 You can specify the name of the editor when attaching to make working with multiple instances easier:
 You can specify the name of the editor when attaching to make working with multiple instances easier:
 
 
 ```js
 ```js
 // Inspecting two editor instances at the same time.
 // Inspecting two editor instances at the same time.
-CKEditorInspector.attach( 'header-editor' editor );
-CKEditorInspector.attach( 'body-editor' editor );
+CKEditorInspector.attach( 'header-editor', editor );
+CKEditorInspector.attach( 'body-editor', editor );
 ```
 ```
 
 
 The editor switcher is in the upper–right corner of the inspector panel.
 The editor switcher is in the upper–right corner of the inspector panel.
@@ -78,9 +78,9 @@ The source code of CKEditor 5 inspector and its issue tracker is available on Gi
 
 
 ## Testing helpers
 ## Testing helpers
 
 
-The `getData()` and `setData()` functions exposed by {@link module:engine/dev-utils/model model dev utils} and {@link module:engine/dev-utils/view view dev utils} are useful development helpers.
+The `getData()` and `setData()` functions exposed by {@link module:engine/dev-utils/model model developer utilities} and {@link module:engine/dev-utils/view view developer utilities} are useful development helpers.
 
 
-They allow "stringifying" {@link framework/guides/architecture/editing-engine#model model} and {@link framework/guides/architecture/editing-engine#view view} structures, selections, ranges, and positions as well as loading them from a string. They are often used when writing tests.
+They allow for "stringifying" the {@link framework/guides/architecture/editing-engine#model model} and {@link framework/guides/architecture/editing-engine#view view} structures, selections, ranges, and positions as well as for loading them from a string. They are often used when writing tests.
 
 
 <info-box>
 <info-box>
 	Both tools are designed for prototyping, debugging, and testing purposes. Do not use them in production-grade code.
 	Both tools are designed for prototyping, debugging, and testing purposes. Do not use them in production-grade code.

+ 29 - 35
docs/framework/guides/quick-start.md

@@ -5,11 +5,11 @@ order: 20
 
 
 # Quick start
 # Quick start
 
 
-This guide will show you how to initialize the editor from source.
+This guide will show you how to initialize CKEditor 5 rich-text editor from source.
 
 
 ## How to install the framework?
 ## How to install the framework?
 
 
-The framework is made of several [npm packages](https://npmjs.com). To install it you need:
+The CKEditor 5 Framework is made of several [npm packages](https://npmjs.com). To install it you need:
 
 
 * [Node.js](https://nodejs.org/en/) 6.9.0+
 * [Node.js](https://nodejs.org/en/) 6.9.0+
 * npm 4+ (**note:** some npm 5+ versions were known to cause [problems](https://github.com/npm/npm/issues/16991), especially with deduplicating packages; upgrade npm when in doubt)
 * npm 4+ (**note:** some npm 5+ versions were known to cause [problems](https://github.com/npm/npm/issues/16991), especially with deduplicating packages; upgrade npm when in doubt)
@@ -22,13 +22,13 @@ Besides Node.js and npm you also need [webpack@4](https://webpack.js.org) with a
 
 
 This guide assumes that you are familiar with npm and your project uses npm already. If not, see the [npm documentation](https://docs.npmjs.com/getting-started/what-is-npm) or call `npm init` in an empty directory and keep your fingers crossed.
 This guide assumes that you are familiar with npm and your project uses npm already. If not, see the [npm documentation](https://docs.npmjs.com/getting-started/what-is-npm) or call `npm init` in an empty directory and keep your fingers crossed.
 
 
-First, install packages needed to build CKEditor 5.
+First, install packages needed to build CKEditor 5:
 
 
 ```bash
 ```bash
 npm install --save \
 npm install --save \
-	postcss-loader \
-	raw-loader \
-	style-loader \
+	postcss-loader@3 \
+	raw-loader@3 \
+	style-loader@1 \
 	webpack@4 \
 	webpack@4 \
 	webpack-cli@3
 	webpack-cli@3
 ```
 ```
@@ -56,22 +56,18 @@ module.exports = {
 	module: {
 	module: {
 		rules: [
 		rules: [
 			{
 			{
-				// Or /ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/ if you want to limit this loader
-				// to CKEditor 5 icons only.
-				test: /\.svg$/,
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
 
 
 				use: [ 'raw-loader' ]
 				use: [ 'raw-loader' ]
 			},
 			},
 			{
 			{
-				// Or /ckeditor5-[^/]+\/theme\/[^/]+\.css$/ if you want to limit this loader
-				// to CKEditor 5 theme only.
-				test: /\.css$/,
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
 
 
 				use: [
 				use: [
 					{
 					{
 						loader: 'style-loader',
 						loader: 'style-loader',
 						options: {
 						options: {
-							singleton: true
+							injectType: 'singletonStyleTag'
 						}
 						}
 					},
 					},
 					{
 					{
@@ -98,7 +94,7 @@ module.exports = {
 
 
 ## Creating an editor
 ## Creating an editor
 
 
-You can now install some of the CKEditor 5 Framework packages which will allow you to initialize a simple editor. You can start with the {@link examples/builds/classic-editor classic editor} with a small set of features.
+You can now install some of the CKEditor 5 Framework packages which will allow you to initialize a simple rich-text editor. You can start with the {@link examples/builds/classic-editor classic editor} with a small set of features.
 
 
 ```bash
 ```bash
 npm install --save \
 npm install --save \
@@ -119,7 +115,7 @@ Based on these packages you can create a simple application.
 <info-box warning>
 <info-box warning>
 	Note that in this guide the editor class is used directly (i.e. we use `@ckeditor/ckeditor5-editor-classic` instead of `@ckeditor/ckeditor5-build-classic`).
 	Note that in this guide the editor class is used directly (i.e. we use `@ckeditor/ckeditor5-editor-classic` instead of `@ckeditor/ckeditor5-build-classic`).
 
 
-	We do not use any of the {@link builds/guides/overview builds} because adding new plugins to them requires rebuilding them anyway. This can be done by {@link builds/guides/integration/installing-plugins customizing a build} or by including CKEditor 5 source into your application (like in this guide).
+	No {@link builds/guides/overview editor builds} are used because adding new plugins to them requires rebuilding them anyway. This can be done by {@link builds/guides/integration/installing-plugins customizing a build} or by including CKEditor 5 source into your application (like in this guide).
 </info-box>
 </info-box>
 
 
 ```js
 ```js
@@ -150,30 +146,28 @@ You can now run webpack to build the application. To do that, call the `webpack`
 ./node_modules/.bin/webpack --mode development
 ./node_modules/.bin/webpack --mode development
 ```
 ```
 
 
-<info-box>
-	You can also install `webpack-cli` globally (using `npm install -g`) and run it via a globally available `webpack`.
+You can also install `webpack-cli` globally (using `npm install -g`) and run it via a globally available `webpack`.
 
 
-	Alternatively, you can add it as an [npm script](https://docs.npmjs.com/misc/scripts):
+Alternatively, you can add it as an [npm script](https://docs.npmjs.com/misc/scripts):
 
 
-	```js
-	"scripts": {
-		"build": "webpack --mode development"
-	}
-	```
+```js
+"scripts": {
+	"build": "webpack --mode development"
+}
+```
 
 
-	And use it via:
+And use it with:
 
 
-	```bash
-	yarn run build
-	```
+```bash
+yarn run build
+```
 
 
-	npm adds `./node_modules/.bin/` to the `PATH` automatically, so in this case you do not need to install `webpack-cli` globally.
-</info-box>
+npm adds `./node_modules/.bin/` to the `PATH` automatically, so in this case you do not need to install `webpack-cli` globally.
 
 
 <info-box>
 <info-box>
-	Use `webpack --mode production` if you want to build a minified and optimized application. See more at https://webpack.js.org/concepts/mode/.
+	Use `webpack --mode production` if you want to build a minified and optimized application. See more in the [webpack documentation](https://webpack.js.org/concepts/mode/).
 
 
-	**Note:** Prior to version 1.2.7 `uglifyjs-webpack-plugin` (the default minifier used by webpack) had a bug which caused webpack to crash with the following error: `TypeError: Assignment to constant variable.`. If you experienced this error, make sure that your `node_modules` contains an up to date version of this package (and that webpack uses this version).
+	**Note:** Prior to version 1.2.7, `uglifyjs-webpack-plugin` (the default minifier used by webpack) had a bug which caused webpack to crash with the following error: `TypeError: Assignment to constant variable.`. If you experienced this error, make sure that your `node_modules` contains an up-to-date version of this package (and that webpack uses this version).
 </info-box>
 </info-box>
 
 
 If everything worked correctly, you should see:
 If everything worked correctly, you should see:
@@ -214,9 +208,9 @@ Finally, it is time to create an HTML page:
 </html>
 </html>
 ```
 ```
 
 
-Open this page in your browser and you should see the editor up and running. Make sure to check the browser console in case anything seems wrong.
+Open this page in your browser and you should see the simple WYSIWYG editor up and running. Make sure to check the browser console in case anything seems wrong.
 
 
-{@img assets/img/framework-quick-start-classic-editor.png 976 Screenshot of a classic editor with bold and italic features.}
+{@img assets/img/framework-quick-start-classic-editor.png 976 Screenshot of CKEditor 5 classic editor with bold and italic features.}
 
 
 <info-box>
 <info-box>
 	We recommend using the official {@link framework/guides/development-tools#ckeditor-5-inspector CKEditor 5 inspector} for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more.
 	We recommend using the official {@link framework/guides/development-tools#ckeditor-5-inspector CKEditor 5 inspector} for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more.
@@ -224,6 +218,6 @@ Open this page in your browser and you should see the editor up and running. Mak
 
 
 ## What's next?
 ## What's next?
 
 
-If you finished this guide, you should definitely check out the {@link framework/guides/creating-simple-plugin "Creating a simple plugin"} guide that will teach you some basics of developing features in the CKEditor 5 ecosystem.
+If you finished this guide, you should definitely check out the {@link framework/guides/creating-simple-plugin Creating a simple plugin} guide that will teach you some basics of developing features in the CKEditor 5 ecosystem.
 
 
-If you are more into reading about CKEditor 5's architecture, check out the {@link framework/guides/architecture/intro Introduction to CKEditor 5 architecture}.
+If you are more into reading about the CKEditor 5 architecture, check out the {@link framework/guides/architecture/intro Introduction to CKEditor 5 architecture}.

+ 79 - 77
docs/framework/guides/tutorials/implementing-a-block-widget.md

@@ -5,7 +5,9 @@ order: 10
 
 
 # Implementing a block widget
 # Implementing a block widget
 
 
-In this tutorial, you will learn how to implement a more complex CKEditor 5 plugin. We will build a "Simple box" feature which will allow the user to insert a custom box with a title and body fields into the document. We will use the widget utils and work with the model-view conversion in order to properly set up the behavior of this feature. Later on, we will create a UI which will allow inserting new simple boxes into the document via the toolbar button.
+In this tutorial, you will learn how to implement a more complex CKEditor 5 plugin.
+
+You will build a "Simple box" feature which will allow the user to insert a custom box with a title and body fields into the document. You will use the widget utilities and work with the model-view conversion in order to properly set up the behavior of this feature. Later on, you will create a UI which will allow for inserting new simple boxes into the document with the toolbar button.
 
 
 <info-box>
 <info-box>
 	If you want to see the final product of this tutorial before you plunge in, check out the [demo](#demo).
 	If you want to see the final product of this tutorial before you plunge in, check out the [demo](#demo).
@@ -15,9 +17,9 @@ In this tutorial, you will learn how to implement a more complex CKEditor 5 plug
 
 
 ## Before you start
 ## Before you start
 
 
-While it is not strictly necessary to read the {@link framework/guides/quick-start Quick start} guide before going through this tutorial, it may help you to get more comfortable with CKEditor 5 framework before you will dive into this tutorial.
+While it is not strictly necessary to read the {@link framework/guides/quick-start Quick start} guide before going through this tutorial, it may help you to get more comfortable with CKEditor 5 Framework before you dive into this tutorial.
 
 
-We will also reference various parts of the {@link framework/guides/architecture/intro CKEditor 5 architecture} section as we go. While reading them is not necessary to finish this tutorial, we recommend reading those guides at some point to get a better understanding of the mechanisms used in this tutorial.
+The tutorial will also reference various parts of the {@link framework/guides/architecture/intro CKEditor 5 architecture} section as you go. While reading them is not necessary to finish this tutorial, it is recommended to read these guides at some point to get a better understanding of the mechanisms used in this tutorial.
 
 
 ## Let's start
 ## Let's start
 
 
@@ -27,9 +29,9 @@ First, install packages needed to build and set up a basic CKEditor 5 instance.
 
 
 ```bash
 ```bash
 npm install --save \
 npm install --save \
-	postcss-loader \
-	raw-loader \
-	style-loader \
+	postcss-loader@3 \
+	raw-loader@3 \
+	style-loader@1 \
 	webpack@4 \
 	webpack@4 \
 	webpack-cli@3 \
 	webpack-cli@3 \
 	@ckeditor/ckeditor5-dev-utils \
 	@ckeditor/ckeditor5-dev-utils \
@@ -42,7 +44,7 @@ npm install --save \
 	@ckeditor/ckeditor5-theme-lark
 	@ckeditor/ckeditor5-theme-lark
 ```
 ```
 
 
-Create minimal webpack configuration:
+Create a minimal webpack configuration:
 
 
 ```js
 ```js
 // webpack.config.js
 // webpack.config.js
@@ -63,16 +65,16 @@ module.exports = {
 	module: {
 	module: {
 		rules: [
 		rules: [
 			{
 			{
-				test: /\.svg$/,
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
 				use: [ 'raw-loader' ]
 				use: [ 'raw-loader' ]
 			},
 			},
 			{
 			{
-				test: /\.css$/,
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
 				use: [
 				use: [
 					{
 					{
 						loader: 'style-loader',
 						loader: 'style-loader',
 						options: {
 						options: {
-							singleton: true
+							injectType: 'singletonStyleTag'
 						}
 						}
 					},
 					},
 					{
 					{
@@ -145,9 +147,9 @@ And an `index.html` page:
 </html>
 </html>
 ```
 ```
 
 
-Finally, let's build your project and see if everything worked well by opening the index page in your browser:
+Finally, build your project:
 
 
-```
+```bash
 p@m /workspace/creating-a-plugin> ./node_modules/.bin/webpack --mode development
 p@m /workspace/creating-a-plugin> ./node_modules/.bin/webpack --mode development
 Hash: a4a7cf092b8d69199848
 Hash: a4a7cf092b8d69199848
 Version: webpack 4.28.4
 Version: webpack 4.28.4
@@ -163,15 +165,15 @@ Entrypoint main [big] = bundle.js bundle.js.map
     + 904 hidden modules
     + 904 hidden modules
 ```
 ```
 
 
-You should see a CKEditor 5 instance like this:
+And now see if everything worked well by opening the index page in your browser. You should see a CKEditor 5 instance like this:
 
 
 {@img assets/img/tutorial-implementing-a-widget-1.png Screenshot of a classic editor initialized from source.}
 {@img assets/img/tutorial-implementing-a-widget-1.png Screenshot of a classic editor initialized from source.}
 
 
 ## Plugin structure
 ## Plugin structure
 
 
-Once the editor is up and running we can start implementing the plugin. All the code of a plugin can be kept in a single file, however, we recommend splitting its "editing" and "UI" layers and creating a master plugin which loads both. This way, we ensure better separation of concerns and allow recomposing the features (e.g. picking the editing part of an existing feature but writing your own UI for it). All official CKEditor 5 plugins follow this pattern.
+Once the editor is up and running you can start implementing the plugin. The entire plugin code can be kept in a single file, however, it is recommended to split its "editing" and "UI" layers and create a master plugin which loads both. This way, you ensure better separation of concerns and allow for recomposing the features (e.g. picking the editing part of an existing feature but writing your own UI for it). All official CKEditor 5 plugins follow this pattern.
 
 
-Additionally, we will split code of commands, buttons and other "self-contained" components to separate files as well. In order to not mix up these files with your project's `app.js` and `webpack.config.js` files, let's create this directory structure:
+Additionally, you will split the code of commands, buttons and other "self-contained" components to separate files, too. In order not to mix up these files with your project's `app.js` and `webpack.config.js` files, create this directory structure:
 
 
 ```
 ```
 ├── app.js
 ├── app.js
@@ -186,12 +188,12 @@ Additionally, we will split code of commands, buttons and other "self-contained"
 │   ├── simpleboxediting.js
 │   ├── simpleboxediting.js
 │   └── simpleboxui.js
 │   └── simpleboxui.js
-│   ... the rest of plugin files go here as well
+│   ... the rest of plugin files goes here as well
 └── webpack.config.js
 └── webpack.config.js
 ```
 ```
 
 
-Let's now define the 3 plugins.
+Now define the 3 plugins.
 
 
 First, the master (glue) plugin. Its role is to simply load the "editing" and "UI" parts.
 First, the master (glue) plugin. Its role is to simply load the "editing" and "UI" parts.
 
 
@@ -235,7 +237,7 @@ export default class SimpleBoxEditing extends Plugin {
 }
 }
 ```
 ```
 
 
-Finally, we need to load the `SimpleBox` plugin in our `app.js` file:
+Finally, you need to load the `SimpleBox` plugin in your `app.js` file:
 
 
 ```js
 ```js
 // app.js
 // app.js
@@ -269,9 +271,9 @@ ClassicEditor
 	} );
 	} );
 ```
 ```
 
 
-Rebuild your project, refresh the browser and you should see that the `SimpleBoxEditing` and `SmpleBoxUI` plugins were loaded:
+Rebuild your project, refresh the browser and you should see that the the `SimpleBoxEditing` and `SmpleBoxUI` plugins were loaded:
 
 
-{@img assets/img/tutorial-implementing-a-widget-2.png Screenshot of a classic editor initialized from source with the SimpleBoxEditing#init() got called and SimpleBoxUI#init() got called messages on the console.}
+{@img assets/img/tutorial-implementing-a-widget-2.png Screenshot of a classic editor initialized from source with the "SimpleBoxEditing#init() got called" and "SimpleBoxUI#init() got called" messages on the console.}
 
 
 ## The model and the view layers
 ## The model and the view layers
 
 
@@ -281,7 +283,7 @@ CKEditor 5 implements an MVC architecture and its custom data model, while still
 	Read more about the {@link framework/guides/architecture/editing-engine#overview editing engine architecture}.
 	Read more about the {@link framework/guides/architecture/editing-engine#overview editing engine architecture}.
 </info-box>
 </info-box>
 
 
-Since our simple box feature is meant to be a box with a title and description fields, let's define its model representation like this:
+Since your simple box feature is meant to be a box with a title and description fields, define its model representation like this:
 
 
 ```html
 ```html
 <simpleBox>
 <simpleBox>
@@ -292,13 +294,13 @@ Since our simple box feature is meant to be a box with a title and description f
 
 
 ### Defining the schema
 ### Defining the schema
 
 
-We need to start with defining the model's schema. We need to define there 3 elements and their types and allowed parent/children.
+You need to start with defining the model's schema. You need to define 3 elements and their types as well as allowed parent/children.
 
 
 <info-box>
 <info-box>
 	Read more about the {@link framework/guides/architecture/editing-engine#schema schema}.
 	Read more about the {@link framework/guides/architecture/editing-engine#schema schema}.
 </info-box>
 </info-box>
 
 
-Let's update the `SimpleBoxEditing` plugin with this definition.
+Update the `SimpleBoxEditing` plugin with this definition.
 
 
 ```js
 ```js
 // simplebox/simpleboxediting.js
 // simplebox/simpleboxediting.js
@@ -348,19 +350,19 @@ export default class SimpleBoxEditing extends Plugin {
 
 
 Defining the schema will not have any effect on the editor just yet. It is information which can be used by plugins and the editor engine to understand how actions like pressing the <kbd>Enter</kbd> key, clicking on an element, typing text, inserting an image, etc. should behave.
 Defining the schema will not have any effect on the editor just yet. It is information which can be used by plugins and the editor engine to understand how actions like pressing the <kbd>Enter</kbd> key, clicking on an element, typing text, inserting an image, etc. should behave.
 
 
-For the simple box plugin to start doing anything we need to define model-view converters. Let's do that!
+For the simple box plugin to start doing anything you need to define model-view converters. Do that now!
 
 
 ### Defining converters
 ### Defining converters
 
 
-Converters tell the editor how to convert the view to the model (e.g. when loading the data to the editor or handling pasted content) and how to render the model to the view (for editing purposes, or when retrieving editor data).
+Converters tell the editor how to convert the view to the model (e.g. when loading the data to the editor or handling pasted content) and how to render the model to the view (for editing purposes, or when retrieving the editor data).
 
 
 <info-box>
 <info-box>
 	Read more about the {@link framework/guides/architecture/editing-engine#conversion model-view conversion}.
 	Read more about the {@link framework/guides/architecture/editing-engine#conversion model-view conversion}.
 </info-box>
 </info-box>
 
 
-This is the moment when we need to think about how we want to render the `<simpleBox>` element and its children to the DOM (what user will see) and to the data. CKEditor 5 allows converting the model to a different structure for editing purposes and a different one to be stored as "data" or exchanged with other applications when copy-pasting the content. However, for simplicity, let's use the same representation in both pipelines for now.
+This is the moment when you need to think about how you want to render the `<simpleBox>` element and its children to the DOM (what the user will see) and to the data. CKEditor 5 allows converting the model to a different structure for editing purposes and a different one to be stored as "data" or exchanged with other applications when copy-pasting the content. However, for simplicity, use the same representation in both pipelines for now.
 
 
-The structure in the view that we want to achieve:
+The structure in the view that you want to achieve:
 
 
 ```html
 ```html
 <section class="simple-box">
 <section class="simple-box">
@@ -369,15 +371,15 @@ The structure in the view that we want to achieve:
 </section>
 </section>
 ```
 ```
 
 
-Let's use the {@link module:engine/conversion/conversion~Conversion#elementToElement `conversion.elementToElement()`} method to define all the converters.
+Use the {@link module:engine/conversion/conversion~Conversion#elementToElement `conversion.elementToElement()`} method to define all the converters.
 
 
 <info-box>
 <info-box>
-	We can use this high-level two-way converters definition because we define the same converters for the {@link framework/guides/architecture/editing-engine#data-pipeline data} and {@link framework/guides/architecture/editing-engine#editing-pipeline editing} pipelines.
+	You can use this high-level two-way converters definition because you define the same converters for the {@link framework/guides/architecture/editing-engine#data-pipeline data} and {@link framework/guides/architecture/editing-engine#editing-pipeline editing} pipelines.
 
 
-	Later on we will switch to more fine-grained converters to get more control over the conversion.
+	Later on you will switch to more fine-grained converters to get more control over the conversion.
 </info-box>
 </info-box>
 
 
-We need to define converters for 3 model elements. Let's update the `SimpleBoxEditing` plugin with this code:
+You need to define converters for 3 model elements. Update the `SimpleBoxEditing` plugin with this code:
 
 
 ```js
 ```js
 // simplebox/simpleboxediting.js
 // simplebox/simpleboxediting.js
@@ -426,7 +428,7 @@ export default class SimpleBoxEditing extends Plugin {
 }
 }
 ```
 ```
 
 
-Once we have converters, we can try to see the simple box in action. We did not define yet a way to insert a new simple box into the document, so let's load it via the editor data. In order to do that, we need to modify the `index.html` file:
+Once you have converters, you can try to see the simple box in action. You have not defined a way to insert a new simple box into the document yet, so load it via the editor data. In order to do that, you need to modify the `index.html` file:
 
 
 ```html
 ```html
 <!DOCTYPE html>
 <!DOCTYPE html>
@@ -485,13 +487,13 @@ Rebuild your project and voila &mdash; that's your first simple box instance:
 
 
 ### What's in the model?
 ### What's in the model?
 
 
-The HTML that you have added to the `index.html` file is your editor's data. This is what `editor.getData()` would return. Also, for now, this also the DOM structure which is rendered by CKEditor 5's engine in the editable region:
+The HTML that you added to the `index.html` file is your editor's data. This is what `editor.getData()` would return. Also, for now, this also the DOM structure which is rendered by the CKEditor 5 engine in the editable region:
 
 
 {@img assets/img/tutorial-implementing-a-widget-4.png Screenshot of a DOM structure of the simple box instance – it looks exactly like the data loaded into the editor.}
 {@img assets/img/tutorial-implementing-a-widget-4.png Screenshot of a DOM structure of the simple box instance – it looks exactly like the data loaded into the editor.}
 
 
 However, what's in the model?
 However, what's in the model?
 
 
-To learn that, we recommend using the official {@link framework/guides/development-tools#ckeditor-5-inspector CKEditor 5 inspector}. Once {@link framework/guides/development-tools#ckeditor-5-inspector#installing-the-inspector installed}, you need to load it in the `app.js` file:
+To learn that, use the official {@link framework/guides/development-tools#ckeditor-5-inspector CKEditor 5 inspector}. Once {@link framework/guides/development-tools#ckeditor-5-inspector#installing-the-inspector installed}, you need to load it in the `app.js` file:
 
 
 ```js
 ```js
 // app.js
 // app.js
@@ -546,9 +548,9 @@ You will see the following HTML-like string:
 </simpleBox>
 </simpleBox>
 ```
 ```
 
 
-As you can see, this structure is quite different than the HTML input/output. If you look closely, you will also notice the `[]` characters in the first paragraph &mdash; that's selection position.
+As you can see, this structure is quite different than the HTML input/output. If you look closely, you will also notice the `[]` characters in the first paragraph &mdash; this is the selection position.
 
 
-Play a bit with editor features (bold, italic, headings, lists, selection) to see how the model structure changes.
+Play a bit with the editor features (bold, italic, headings, lists, selection) to see how the model structure changes.
 
 
 <info-box>
 <info-box>
 	You can also use some {@link framework/guides/development-tools#testing-helpers useful helpers like `getData()` and `setData()`} to learn more about the state of the editor model or write assertions in tests.
 	You can also use some {@link framework/guides/development-tools#testing-helpers useful helpers like `getData()` and `setData()`} to learn more about the state of the editor model or write assertions in tests.
@@ -556,45 +558,45 @@ Play a bit with editor features (bold, italic, headings, lists, selection) to se
 
 
 ### Behavior before "widgetizing" simple box
 ### Behavior before "widgetizing" simple box
 
 
-It is time to check if the simple box behaves like we would like it to. You can observe the following:
+It is time to check if the simple box behaves like you would like it to. You can observe the following:
 
 
-* You can type text in the title, but pressing <kbd>Enter</kbd> will not split it and <kbd>Backspace</kbd> will not delete it entirely. That is because it was marked as an `isLimit` element in the schema.
-* You cannot apply a list in the title and cannot turn it into a heading (other than `<h1 class="simple-box-title">` which it is already). That is because it allows only the content that is allowed in other block elements (like paragraphs). You can, however, apply italic inside a title (because italic is allowed in other blocks).
+* You can type text in the title, but pressing <kbd>Enter</kbd> will not split it and <kbd>Backspace</kbd> will not delete it entirely. This is because it was marked as an `isLimit` element in the schema.
+* You cannot apply a list in the title and cannot turn it into a heading (other than `<h1 class="simple-box-title">` which it is already). This is because it allows only the content that is allowed in other block elements (like paragraphs). You can, however, apply italic inside the title (because italic is allowed in other blocks).
 * The description behaves like the title, but it allows more content inside &mdash; lists and other headings.
 * The description behaves like the title, but it allows more content inside &mdash; lists and other headings.
-* If you try to select the entire simple box instance and press <kbd>Delete</kbd>, it will be deleted as a whole. The same when you copy and paste it. That is because it was marked as an `isObject` element in the schema.
-* You cannot easily select the entire simple box instance by clicking on it. Also, the cursor pointer does not change when you hover it. In other words, it seems a bit "dead". That is because we have not yet defined the view behavior yet.
+* If you try to select the entire simple box instance and press <kbd>Delete</kbd>, it will be deleted as a whole. The same when you copy and paste it. This is because it was marked as an `isObject` element in the schema.
+* You cannot easily select the entire simple box instance by clicking on it. Also, the cursor pointer does not change when you hover it. In other words, it seems a bit "dead". This is because you have not defined the view behavior yet.
 
 
-Pretty cool so far, right? With a very little code, you were able to define a behavior of your simple box plugin which maintains the integrity of those elements. The engine ensures that the user does not break those instances.
+Pretty cool so far, right? With a very little code, you were able to define the behavior of your simple box plugin which maintains the integrity of these elements. The engine ensures that the user does not break these instances.
 
 
-Let's see what else we can improve.
+See what else you can improve.
 
 
 ### Making simple box a widget
 ### Making simple box a widget
 
 
 <info-box>
 <info-box>
-	If you are familiar with the {@link @ckeditor4 guide/dev_widgets Widget System of CKEditor 4} you will notice significant differences in how widgets are implemented in CKEditor 5.
+	If you are familiar with the {@link @ckeditor4 guide/dev/deep_dive/widgets/README Widget System of CKEditor 4} you will notice significant differences in how widgets are implemented in CKEditor 5.
 
 
-	CKEditor 4's implementation exposes a declarative API which controls the entire behavior of a widget (from its schema and internal model to the styles, clicking behavior, context menu and the dialog).
+	CKEditor 4 implementation exposes a declarative API that controls the entire behavior of a widget (from its schema and internal model to the styles, clicking behavior, context menu and the dialog).
 
 
-	In CKEditor 5 the widget system was redesigned. Most of its responsibilities were taken over by the engine, some were extracted to a separate package ({@link api/widget `@ckeditor/ckeditor5-widget`}) and some have to be handled by other utils provided by CKEditor 5 framework.
+	In CKEditor 5 the widget system was redesigned. Most of its responsibilities were taken over by the engine, some were extracted to a separate package ({@link api/widget `@ckeditor/ckeditor5-widget`}) and some have to be handled by other utilities provided by CKEditor 5 Framework.
 
 
-	CKEditor 5's implementation is, therefore, open for extensions and recomposition. You can choose those behaviors that you want (just like we did so far in this tutorial by defining a schema) and skip others or implement them by yourself.
+	CKEditor 5 implementation is, therefore, open for extensions and recomposition. You can choose the behaviors that you want (just like you did so far in this tutorial by defining a schema) and skip others or implement them by yourself.
 </info-box>
 </info-box>
 
 
-The converters that we defined convert the model `<simpleBox*>` elements to plain {@link module:engine/view/containerelement~ContainerElement `ContainerElement`}s in the view (and back during upcasting).
+The converters that you defined convert the model `<simpleBox*>` elements to plain {@link module:engine/view/containerelement~ContainerElement `ContainerElement`}s in the view (and back during upcasting).
 
 
-We want to change this behavior a bit so the structure created in the editing view is enhanced with the {@link module:widget/utils~toWidget `toWidget()`} and {@link module:widget/utils~toWidgetEditable `toWidgetEditable()`} utils. We do not want to affect the data view, though. Therefore, we will need to define converters for the editing and data downcasting separately.
+You want to change this behavior a bit so the structure created in the editing view is enhanced with the {@link module:widget/utils~toWidget `toWidget()`} and {@link module:widget/utils~toWidgetEditable `toWidgetEditable()`} utilities. You do not want to affect the data view, though. Therefore, you will need to define converters for the editing and data downcasting separately.
 
 
 If you find the concept of downcasting and upcasting confusing, read the {@link framework/guides/architecture/editing-engine#conversion introduction to conversion}.
 If you find the concept of downcasting and upcasting confusing, read the {@link framework/guides/architecture/editing-engine#conversion introduction to conversion}.
 
 
-Before we start coding, we need to install the {@link api/widget `@ckeditor/ckeditor5-widget`} package:
+Before you start coding, you need to install the {@link api/widget `@ckeditor/ckeditor5-widget`} package:
 
 
-```
+```bash
 npm install --save @ckeditor/ckeditor5-widget
 npm install --save @ckeditor/ckeditor5-widget
 ```
 ```
 
 
-Now, let's revisit the `_defineConverters()` method that we defined earlier. We will use {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToElement `elementToElement()` upcast helper} and {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()` downcast helper} instead of the two-way `elementToElement()` converter helper.
+Now it is time to revisit the `_defineConverters()` method that you defined earlier. You will use the {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToElement `elementToElement()` upcast helper} and the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()` downcast helper} instead of the two-way `elementToElement()` converter helper.
 
 
-Additionally, we need to ensure that the {@link module:widget/widget~Widget `Widget`} plugin is loaded. If you omit it, the elements in the view will have all the classes (e.g. `ck-widget`) but there will be no "behaviors" loaded (e.g. clicking a widget will not select it).
+Additionally, you need to ensure that the {@link module:widget/widget~Widget `Widget`} plugin is loaded. If you omit it, the elements in the view will have all the classes (e.g. `ck-widget`) but there will be no "behaviors" loaded (e.g. clicking a widget will not select it).
 
 
 ```js
 ```js
 // simplebox/simpleboxediting.js
 // simplebox/simpleboxediting.js
@@ -666,7 +668,7 @@ export default class SimpleBoxEditing extends Plugin {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 			model: 'simpleBoxTitle',
 			model: 'simpleBoxTitle',
 			view: ( modelElement, viewWriter ) => {
 			view: ( modelElement, viewWriter ) => {
-				// Note: we use a more specialized createEditableElement() method here.
+				// Note: You use a more specialized createEditableElement() method here.
 				const h1 = viewWriter.createEditableElement( 'h1', { class: 'simple-box-title' } );
 				const h1 = viewWriter.createEditableElement( 'h1', { class: 'simple-box-title' } );
 
 
 				return toWidgetEditable( h1, viewWriter );
 				return toWidgetEditable( h1, viewWriter );
@@ -691,7 +693,7 @@ export default class SimpleBoxEditing extends Plugin {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 			model: 'simpleBoxDescription',
 			model: 'simpleBoxDescription',
 			view: ( modelElement, viewWriter ) => {
 			view: ( modelElement, viewWriter ) => {
-				// Note: we use a more specialized createEditableElement() method here.
+				// Note: You use a more specialized createEditableElement() method here.
 				const div = viewWriter.createEditableElement( 'div', { class: 'simple-box-description' } );
 				const div = viewWriter.createEditableElement( 'div', { class: 'simple-box-description' } );
 
 
 				return toWidgetEditable( div, viewWriter );
 				return toWidgetEditable( div, viewWriter );
@@ -702,37 +704,37 @@ export default class SimpleBoxEditing extends Plugin {
 ```
 ```
 
 
 <info-box>
 <info-box>
-	As you can see, the code became much more verbose and far longer. This is because we used lower-level converters. We plan to provide more handy widget conversion utils in the future. Read more (and 👍) in [this ticket](https://github.com/ckeditor/ckeditor5/issues/1228).
+	As you can see, the code became much more verbose and far longer. This is because you used lower-level converters. We plan to provide more handy widget conversion utilities in the future. Read more (and 👍) in [this ticket](https://github.com/ckeditor/ckeditor5/issues/1228).
 </info-box>
 </info-box>
 
 
 ### Behavior after "widgetizing" simple box
 ### Behavior after "widgetizing" simple box
 
 
 You can rebuild your project now and see how your simple box plugin has changed.
 You can rebuild your project now and see how your simple box plugin has changed.
 
 
-{@img assets/img/tutorial-implementing-a-widget-5.png Screenshot of a widget's focus outline.}
+{@img assets/img/tutorial-implementing-a-widget-5.png Screenshot of the widget's focus outline.}
 
 
 You should observe that:
 You should observe that:
 
 
-* The `<section>`, `<h1>`, and `<div>` elements have the `contentEditable` attribute on them (plus some classes). This attribute tells the browser whether an element is considered "editable". Passing element through `toWidget()` will make its content non-editable. Conversely, passing it through `toWidgetEditable()` will make its content editable again.
-* You can now click on the widget (the gray area) to select it. Once it is selected, it is easier to copy-paste it.
+* The `<section>`, `<h1>`, and `<div>` elements have the `contentEditable` attribute on them (plus some classes). This attribute tells the browser whether an element is considered "editable". Passing the element through `toWidget()` will make its content non-editable. Conversely, passing it through `toWidgetEditable()` will make its content editable again.
+* You can now click the widget (the gray area) to select it. Once it is selected, it is easier to copy-paste it.
 * The widget and its nested editable regions react to hovering, selection, and focus (outline).
 * The widget and its nested editable regions react to hovering, selection, and focus (outline).
 
 
 In other words, the simple box instance became much more responsive.
 In other words, the simple box instance became much more responsive.
 
 
-Additionally, if you call `editor.getData()` you will get the same HTML as before "widgetizing" simple box. That's thanks to using `toWidget()` and `toNestedEditable()` only in the `editingDowncast` pipeline.
+Additionally, if you call `editor.getData()` you will get the same HTML as before "widgetizing" the simple box. This is thanks to using `toWidget()` and `toNestedEditable()` only in the `editingDowncast` pipeline.
 
 
-This is all that we need from the model and the view layers for now. In terms of "editability" and data input/output its fully functional. Let's now find a way to insert new simple boxes into the document!
+This is all that you need from the model and the view layers for now. In terms of "editability" and data input/output it is fully functional. Now find a way to insert new simple boxes into the document!
 
 
 ## Creating a command
 ## Creating a command
 
 
-A {@link framework/guides/architecture/core-editor-architecture#commands command} is a combination of an action and a state. You can interact with most of the editor features by commands that they expose. This allows not only executing those features (e.g. bolding a fragment of text) but also checking if this action can be executed in the selection's current location as well as observing other state properties (such as whether the currently selected text is bolded).
+A {@link framework/guides/architecture/core-editor-architecture#commands command} is a combination of an action and a state. You can interact with most of the editor features by commands that they expose. This allows not only executing these features (e.g. bolding a fragment of text) but also checking if this action can be executed in the selection's current location as well as observing other state properties (such as whether the currently selected text is bolded).
 
 
 In case of the simple box the situation is simple:
 In case of the simple box the situation is simple:
 
 
-* we need an "insert new simple box" action,
-* and "can we insert a new simple box here (at the current selection position)".
+* you need an "insert a new simple box" action,
+* and "can you insert a new simple box here (at the current selection position)".
 
 
-Let's create a new file `insertsimpleboxcommand.js` in the `simplebox/` directory. We will use the {@link module:engine/model/model~Model#insertContent `model.insertContent()`} method which will be able to e.g. split a paragraph if you try to insert a simple box in the middle of it (which is not allowed by the schema.
+Create a new file `insertsimpleboxcommand.js` in the `simplebox/` directory. You will use the {@link module:engine/model/model~Model#insertContent `model.insertContent()`} method which will be able to, for example, split a paragraph if you try to insert a simple box in the middle of it (which is not allowed by the schema).
 
 
 ```js
 ```js
 // simplebox/insertsimpleboxcommand.js
 // simplebox/insertsimpleboxcommand.js
@@ -743,7 +745,7 @@ export default class InsertSimpleBoxCommand extends Command {
 	execute() {
 	execute() {
 		this.editor.model.change( writer => {
 		this.editor.model.change( writer => {
 			// Insert <simpleBox>*</simpleBox> at the current selection position
 			// Insert <simpleBox>*</simpleBox> at the current selection position
-			// in a way which will result in creating a valid model structure.
+			// in a way that will result in creating a valid model structure.
 			this.editor.model.insertContent( createSimpleBox( writer ) );
 			this.editor.model.insertContent( createSimpleBox( writer ) );
 		} );
 		} );
 	}
 	}
@@ -828,7 +830,7 @@ console.log( editor.commands.get( 'insertSimpleBox' ).isEnabled );
 
 
 It is always `true` except when the selection is in one place &mdash; in other simple box's title. You can also observe that executing the command when the selection is in that place takes no effect.
 It is always `true` except when the selection is in one place &mdash; in other simple box's title. You can also observe that executing the command when the selection is in that place takes no effect.
 
 
-Let's change one more thing before we will move forward &mdash; let's disallow `simpleBox` inside `simpleBoxDescription` too. This can be done by {@link module:engine/model/schema~Schema#addChildCheck defining a custom child check}:
+Change one more thing before you move forward &mdash; disallow `simpleBox` inside `simpleBoxDescription`, too. This can be done by {@link module:engine/model/schema~Schema#addChildCheck defining a custom child check}:
 
 
 ```js
 ```js
 // simplebox/simpleboxediting.js
 // simplebox/simpleboxediting.js
@@ -894,15 +896,15 @@ export default class SimpleBoxEditing extends Plugin {
 }
 }
 ```
 ```
 
 
-Now, the command should be disabled also when the selection is inside the description of another simple box instance.
+Now the command should be disabled also when the selection is inside the description of another simple box instance.
 
 
 ## Creating a button
 ## Creating a button
 
 
-It is time to allow editor users to insert the widget into the content. The best way to do that is through a UI button in the toolbar. You can quickly create one using the {@link module:ui/button/buttonview~ButtonView `ButtonView`} class brought by the {@link framework/guides/architecture/ui-library UI framework} of CKEditor 5.
+It is time to allow the editor users to insert the widget into the content. The best way to do that is through a UI button in the toolbar. You can quickly create one using the {@link module:ui/button/buttonview~ButtonView `ButtonView`} class brought by the {@link framework/guides/architecture/ui-library UI framework} of CKEditor 5.
 
 
-The button should execute the [command](#creating-a-command) when clicked and become inactive if the widget cannot be inserted in some particular position of the selection ([as defined in the schema](#defining-the-schema)).
+The button should execute the [command](#creating-a-command) when clicked and become inactive if the widget cannot be inserted into some particular position of the selection ([as defined in the schema](#defining-the-schema)).
 
 
-Let us see what it looks like in practice and extend the `SimpleBoxUI` plugin [created earlier](#plugin-structure):
+See what it looks like in practice and extend the `SimpleBoxUI` plugin [created earlier](#plugin-structure):
 
 
 ```js
 ```js
 // simplebox/simpleboxui.js
 // simplebox/simpleboxui.js
@@ -917,7 +919,7 @@ export default class SimpleBoxUI extends Plugin {
 		const editor = this.editor;
 		const editor = this.editor;
 		const t = editor.t;
 		const t = editor.t;
 
 
-		// The "simpleBox" button must be registered among UI components of the editor
+		// The "simpleBox" button must be registered among the UI components of the editor
 		// to be displayed in the toolbar.
 		// to be displayed in the toolbar.
 		editor.ui.componentFactory.add( 'simpleBox', locale => {
 		editor.ui.componentFactory.add( 'simpleBox', locale => {
 			// The state of the button will be bound to the widget command.
 			// The state of the button will be bound to the widget command.
@@ -952,7 +954,7 @@ The last thing you need to do is tell the editor to display the button in the to
 ClassicEditor
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
 	.create( document.querySelector( '#editor' ), {
 		plugins: [ Essentials, Paragraph, Heading, List, Bold, Italic, SimpleBox ],
 		plugins: [ Essentials, Paragraph, Heading, List, Bold, Italic, SimpleBox ],
-		// Insert the "simpleBox" to the editor toolbar.
+		// Insert the "simpleBox" button into the editor toolbar.
 		toolbar: [ 'heading', 'bold', 'italic', 'numberedList', 'bulletedList', 'simpleBox' ]
 		toolbar: [ 'heading', 'bold', 'italic', 'numberedList', 'bulletedList', 'simpleBox' ]
 	} )
 	} )
 	.then( editor => {
 	.then( editor => {
@@ -1006,7 +1008,7 @@ class SimpleBoxUI extends Plugin {
 		const editor = this.editor;
 		const editor = this.editor;
 		const t = editor.t;
 		const t = editor.t;
 
 
-		// The "simpleBox" button must be registered among UI components of the editor
+		// The "simpleBox" button must be registered among the UI components of the editor
 		// to be displayed in the toolbar.
 		// to be displayed in the toolbar.
 		editor.ui.componentFactory.add( 'simpleBox', locale => {
 		editor.ui.componentFactory.add( 'simpleBox', locale => {
 			// The state of the button will be bound to the widget command.
 			// The state of the button will be bound to the widget command.
@@ -1131,7 +1133,7 @@ class SimpleBoxEditing extends Plugin {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 			model: 'simpleBoxTitle',
 			model: 'simpleBoxTitle',
 			view: ( modelElement, viewWriter ) => {
 			view: ( modelElement, viewWriter ) => {
-				// Note: we use a more specialized createEditableElement() method here.
+				// Note: You use a more specialized createEditableElement() method here.
 				const h1 = viewWriter.createEditableElement( 'h1', { class: 'simple-box-title' } );
 				const h1 = viewWriter.createEditableElement( 'h1', { class: 'simple-box-title' } );
 
 
 				return toWidgetEditable( h1, viewWriter );
 				return toWidgetEditable( h1, viewWriter );
@@ -1156,7 +1158,7 @@ class SimpleBoxEditing extends Plugin {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 		conversion.for( 'editingDowncast' ).elementToElement( {
 			model: 'simpleBoxDescription',
 			model: 'simpleBoxDescription',
 			view: ( modelElement, viewWriter ) => {
 			view: ( modelElement, viewWriter ) => {
-				// Note: we use a more specialized createEditableElement() method here.
+				// Note: You use a more specialized createEditableElement() method here.
 				const div = viewWriter.createEditableElement( 'div', { class: 'simple-box-description' } );
 				const div = viewWriter.createEditableElement( 'div', { class: 'simple-box-description' } );
 
 
 				return toWidgetEditable( div, viewWriter );
 				return toWidgetEditable( div, viewWriter );
@@ -1169,7 +1171,7 @@ class InsertSimpleBoxCommand extends Command {
 	execute() {
 	execute() {
 		this.editor.model.change( writer => {
 		this.editor.model.change( writer => {
 			// Insert <simpleBox>*</simpleBox> at the current selection position
 			// Insert <simpleBox>*</simpleBox> at the current selection position
-			// in a way which will result in creating a valid model structure.
+			// in a way that will result in creating a valid model structure.
 			this.editor.model.insertContent( createSimpleBox( writer ) );
 			this.editor.model.insertContent( createSimpleBox( writer ) );
 		} );
 		} );
 	}
 	}

+ 53 - 51
docs/framework/guides/tutorials/implementing-an-inline-widget.md

@@ -5,7 +5,9 @@ order: 10
 
 
 # Implementing an inline widget
 # Implementing an inline widget
 
 
-In this tutorial, you will learn how to implement an inline widget. We will build a "Placeholder" feature which allow the user to insert predefined placeholders, like a date or a surname, into the document. We will use widget utils and conversion in order to define the behavior of this feature. Later on, we will use dropdown utils to create a dropdown which will allow inserting new placeholders. We will also learn how to use the editor configuration to define allowed placeholder names.
+In this tutorial, you will learn how to implement an inline widget.
+
+You will build a "placeholder" feature that allows the users to insert predefined placeholders, like a date or a surname, into the document. You will use widget utilities and conversion in order to define the behavior of this feature. Later on, you will use dropdown utilities to create a dropdown that will allow for inserting new placeholders. You will also learn how to use the editor configuration to define allowed placeholder names.
 
 
 <info-box>
 <info-box>
 	If you want to see the final product of this tutorial before you plunge in, check out the [demo](#demo).
 	If you want to see the final product of this tutorial before you plunge in, check out the [demo](#demo).
@@ -13,19 +15,19 @@ In this tutorial, you will learn how to implement an inline widget. We will buil
 
 
 ## Before you start ⚠️
 ## Before you start ⚠️
 
 
-This guide assumes that you are familiar with widgets concept introduced in the {@link framework/guides/tutorials/implementing-a-block-widget Implementing a block widget} tutorial. We will also reference various concepts from {@link framework/guides/architecture/intro CKEditor 5 architecture}.
+This guide assumes that you are familiar with the widgets concept introduced in the {@link framework/guides/tutorials/implementing-a-block-widget Implementing a block widget} tutorial. The tutorial will also reference various concepts from the {@link framework/guides/architecture/intro CKEditor 5 architecture}.
 
 
 ## Bootstrapping the project
 ## Bootstrapping the project
 
 
-The overall project structure will be similar to this described in {@link framework/guides/tutorials/implementing-a-block-widget#lets-start Let's start} and {@link framework/guides/tutorials/implementing-a-block-widget#plugin-structure Plugin structure} sections.
+The overall project structure will be similar to one described in {@link framework/guides/tutorials/implementing-a-block-widget#lets-start Let's start} and {@link framework/guides/tutorials/implementing-a-block-widget#plugin-structure Plugin structure} sections of the "Implementing a block widget" tutorial.
 
 
 First, install required dependencies:
 First, install required dependencies:
 
 
 ```bash
 ```bash
 npm install --save \
 npm install --save \
-	postcss-loader \
-	raw-loader \
-	style-loader \
+	postcss-loader@3 \
+	raw-loader@3 \
+	style-loader@1 \
 	webpack@4 \
 	webpack@4 \
 	webpack-cli@3 \
 	webpack-cli@3 \
 	@ckeditor/ckeditor5-basic-styles \
 	@ckeditor/ckeditor5-basic-styles \
@@ -64,16 +66,16 @@ module.exports = {
 	module: {
 	module: {
 		rules: [
 		rules: [
 			{
 			{
-				test: /\.svg$/,
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
 				use: [ 'raw-loader' ]
 				use: [ 'raw-loader' ]
 			},
 			},
 			{
 			{
-				test: /\.css$/,
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
 				use: [
 				use: [
 					{
 					{
 						loader: 'style-loader',
 						loader: 'style-loader',
 						options: {
 						options: {
-							singleton: true
+							injectType: 'singletonStyleTag'
 						}
 						}
 					},
 					},
 					{
 					{
@@ -152,7 +154,7 @@ ClassicEditor
 	} );
 	} );
 ```
 ```
 
 
-Before building the project we still need to define `Placeholder` plugin. The project will have a structure as below:
+Before building the project you still need to define the `Placeholder` plugin. The project will have a structure as below:
 
 
 ```
 ```
 ├── app.js
 ├── app.js
@@ -170,12 +172,12 @@ Before building the project we still need to define `Placeholder` plugin. The pr
 │   └── theme
 │   └── theme
 │       └── placeholder.css
 │       └── placeholder.css
-│   ... the rest of plugin files go here as well
+│   ... the rest of the plugin files go here as well.
 └── webpack.config.js
 └── webpack.config.js
 ```
 ```
 
 
-You can see that the placeholder feature has an established plugin structure: the master (glue) plugin (`placeholder/placeholder.js`), the "editing" (`placeholder/placeholderediting.js`) and the "ui" (`placeholder/placeholderui.js`) parts.
+You can see that the placeholder feature has an established plugin structure: the master (glue) plugin (`placeholder/placeholder.js`), the "editing" (`placeholder/placeholderediting.js`) and the "UI" (`placeholder/placeholderui.js`) parts.
 
 
 The master (glue) plugin:
 The master (glue) plugin:
 
 
@@ -222,11 +224,11 @@ export default class PlaceholderEditing extends Plugin {
 }
 }
 ```
 ```
 
 
-At this stage we can build the project and open it in the browser to verify if it is building correctly.
+At this stage you can build the project and open it in the browser to verify if it is building correctly.
 
 
 ## The model and the view layers
 ## The model and the view layers
 
 
-The placeholder feature will be {@link module:engine/model/schema~SchemaItemDefinition defined as  an inline} (text-like) element so it will be inserted in other editor blocks, like `<paragraph>`, that allow text. The placeholder will have a `name` attribute. This means that the model containing some text and a placeholder will look like this:
+The placeholder feature will be {@link module:engine/model/schema~SchemaItemDefinition defined as an inline} (text-like) element so it will be inserted into other editor blocks, like `<paragraph>`, that allow text. The placeholder will have a `name` attribute. This means that the model containing some text and a placeholder will look like this:
 
 
 ```html
 ```html
 <paragraph>
 <paragraph>
@@ -236,9 +238,9 @@ The placeholder feature will be {@link module:engine/model/schema~SchemaItemDefi
 
 
 ### Defining the schema
 ### Defining the schema
 
 
-The `<placeholder>` element should be treated as `$text` so it must be defined with `isInline: true`. We want to allow it wherever the `$text` is allowed so we add `allowWhere: '$text'`. Finally, we will also need the `name` attribute.
+The `<placeholder>` element should be treated as `$text` so it must be defined with `isInline: true`. You want to allow it wherever the `$text` is allowed so you add `allowWhere: '$text'`. Finally, you will also need the `name` attribute.
 
 
-We will also use this occasion to import the theme file (`theme/placeholder.css`).
+You will also use this opportunity to import the theme file (`theme/placeholder.css`).
 
 
 ```js
 ```js
 // placeholder/placeholderediting.js
 // placeholder/placeholderediting.js
@@ -261,10 +263,10 @@ export default class PlaceholderEditing extends Plugin {
 			// Allow wherever text is allowed:
 			// Allow wherever text is allowed:
 			allowWhere: '$text',
 			allowWhere: '$text',
 
 
-			// The placeholder will acts as an inline node:
+			// The placeholder will act as an inline node:
 			isInline: true,
 			isInline: true,
 
 
-			// The inline-widget is self-contained so cannot be split by the caret and can be selected:
+			// The inline widget is self-contained so it cannot be split by the caret and can be selected:
 			isObject: true,
 			isObject: true,
 
 
 			// The placeholder can have many types, like date, name, surname, etc:
 			// The placeholder can have many types, like date, name, surname, etc:
@@ -274,18 +276,18 @@ export default class PlaceholderEditing extends Plugin {
 }
 }
 ```
 ```
 
 
-The schema is defined so now we can define the model-view converters.
+The schema is defined so now you can define the model-view converters.
 
 
 ### Defining converters
 ### Defining converters
 
 
-The HTML structure (data output) of the converter will be a `<span>` with a `placeholder` class. The text inside the `<span>` will the placeholder's name.
+The HTML structure (data output) of the converter will be a `<span>` with a `placeholder` class. The text inside the `<span>` will be the placeholder's name.
 
 
 ```html
 ```html
 <span class="placeholder">{name}</span>
 <span class="placeholder">{name}</span>
 ```
 ```
 
 
-* **Upcast conversion**. This view-to-model converter will look for `<span>`s with class `placeholder`, read the `<span>`'s text and create a model `<placeholder>` elements with the `name` attribute set accordingly.
-* **Downcast conversion**. The model-to-view conversion will be slightly different for "editing" and "data" pipelines as the "editing downcast" pipeline will use widget utilities to enable widget specific behavior in the editing view. In both pipelines, the element will be rendered using the same structure.
+* **Upcast conversion**. This view-to-model converter will look for `<span>`s with the `placeholder` class, read the `<span>`'s text and create model `<placeholder>` elements with the `name` attribute set accordingly.
+* **Downcast conversion**. The model-to-view conversion will be slightly different for "editing" and "data" pipelines as the "editing downcast" pipeline will use widget utilities to enable widget-specific behavior in the editing view. In both pipelines, the element will be rendered using the same structure.
 
 
 ```js
 ```js
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
@@ -333,7 +335,7 @@ export default class PlaceholderEditing extends Plugin {
 			view: ( modelItem, viewWriter ) => {
 			view: ( modelItem, viewWriter ) => {
 				const widgetElement = createPlaceholderView( modelItem, viewWriter );
 				const widgetElement = createPlaceholderView( modelItem, viewWriter );
 
 
-				// Enable widget handling on placeholder element inside editing view.
+				// Enable widget handling on a placeholder element inside the editing view.
 				return toWidget( widgetElement, viewWriter );
 				return toWidget( widgetElement, viewWriter );
 			}
 			}
 		} );
 		} );
@@ -363,7 +365,7 @@ export default class PlaceholderEditing extends Plugin {
 
 
 ### Feature styles
 ### Feature styles
 
 
-As you could notice the editing part imports the `./theme/placeholder.css` CSS file which describes how the placeholder is displayed in th editing view:
+As you could notice, the editing part imports the `./theme/placeholder.css` CSS file which describes how the placeholder is displayed in th editing view:
 
 
 ```css
 ```css
 /* placeholder/theme/placeholder.css */
 /* placeholder/theme/placeholder.css */
@@ -383,7 +385,7 @@ As you could notice the editing part imports the `./theme/placeholder.css` CSS f
 
 
 ### Command
 ### Command
 
 
-A {@link framework/guides/architecture/core-editor-architecture#commands command} for placeholder feature will insert a `<placeholder>` element (if allowed by the schema) at the selection. The command will accept `options.value` parameter (other CKEditor 5's commands also uses this pattern) to set the placeholder's name.
+The {@link framework/guides/architecture/core-editor-architecture#commands command} for the placeholder feature will insert a `<placeholder>` element (if allowed by the schema) at the selection. The command will accept the `options.value` parameter (other CKEditor 5 commands also use this pattern) to set the placeholder name.
 
 
 ```js
 ```js
 // placeholder/placeholdercommand.js
 // placeholder/placeholdercommand.js
@@ -395,13 +397,13 @@ export default class PlaceholderCommand extends Command {
 		const editor = this.editor;
 		const editor = this.editor;
 
 
 		editor.model.change( writer => {
 		editor.model.change( writer => {
-			// Create <placeholder> elment with name attribute...
+			// Create a <placeholder> elment with the "name" attribute...
 			const placeholder = writer.createElement( 'placeholder', { name: value } );
 			const placeholder = writer.createElement( 'placeholder', { name: value } );
 
 
 			// ... and insert it into the document.
 			// ... and insert it into the document.
 			editor.model.insertContent( placeholder );
 			editor.model.insertContent( placeholder );
 
 
-			// Put the selection on inserted element.
+			// Put the selection on the inserted element.
 			writer.setSelection( placeholder, 'on' );
 			writer.setSelection( placeholder, 'on' );
 		} );
 		} );
 	}
 	}
@@ -417,7 +419,7 @@ export default class PlaceholderCommand extends Command {
 }
 }
 ```
 ```
 
 
-Import the created command and add it to editor's commands:
+Import the created command and add it to the editor commands:
 
 
 ```js
 ```js
 // placeholder/placeholderediting.js
 // placeholder/placeholderediting.js
@@ -457,7 +459,7 @@ export default class PlaceholderEditing extends Plugin {
 
 
 ### Let's see it!
 ### Let's see it!
 
 
-You can rebuild the project now and you should be able to execute the `placeholder` command to insert a new placeholder:
+You can rebuild the project now. You should be able to execute the `placeholder` command to insert a new placeholder:
 
 
 ```js
 ```js
 editor.execute( 'placeholder', { value: 'time' } );
 editor.execute( 'placeholder', { value: 'time' } );
@@ -465,11 +467,11 @@ editor.execute( 'placeholder', { value: 'time' } );
 
 
 This should result in:
 This should result in:
 
 
-{@img assets/img/tutorial-implementing-an-inline-widget-1.png Screenshot of a placeholder widget in action.}
+{@img assets/img/tutorial-implementing-an-inline-widget-1.png Screenshot of a placeholder widget in action in CKEditor 5 WYSIWYG editor.}
 
 
 ### Fixing position mapping
 ### Fixing position mapping
 
 
-If you play now more with the widget (e.g. try to select it by dragging the mouse from its right to the left edge) you will see the following error logged on the console:
+If you play more with the widget (e.g. try to select it by dragging the mouse from its right to the left edge) you will see the following error logged to the console:
 
 
 ```
 ```
 Uncaught CKEditorError: model-nodelist-offset-out-of-bounds: Given offset cannot be found in the node list.
 Uncaught CKEditorError: model-nodelist-offset-out-of-bounds: Given offset cannot be found in the node list.
@@ -487,9 +489,9 @@ view:
 foo<span class="placeholder">{name}</span>bar
 foo<span class="placeholder">{name}</span>bar
 ```
 ```
 
 
-You can say that in the view there is "more" text than in the model. This means that some positions in the view cannot automatically map to positions in the model. Namely &mdash; those are positions inside the `<span>` element.
+You could say that in the view there is "more" text than in the model. This means that some positions in the view cannot automatically map to positions in the model. Namely &mdash; those are positions inside the `<span>` element.
 
 
-Fortunately, CKEditor 5 {@link module:engine/conversion/mapper~Mapper#viewToModelPosition allows customizing the mapping logic}. Also, since mapping to an empty model element is a pretty common scenario, there is a ready-to-use util {@link module:widget/utils~viewToModelPositionOutsideModelElement `viewToModelPositionOutsideModelElement()`} which we can use here like that:
+Fortunately, CKEditor 5 {@link module:engine/conversion/mapper~Mapper#viewToModelPosition allows customizing the mapping logic}. Also, since mapping to an empty model element is a pretty common scenario, there is a ready-to-use utility {@link module:widget/utils~viewToModelPositionOutsideModelElement `viewToModelPositionOutsideModelElement()`} that you can use here like that:
 
 
 ```js
 ```js
 // placeholder/placeholderediting.js
 // placeholder/placeholderediting.js
@@ -537,15 +539,15 @@ export default class PlaceholderEditing extends Plugin {
 }
 }
 ```
 ```
 
 
-After adding the custom mapping, the mapping will work perfectly. Every position inside the view `<span>` element will be mapped to a position outside `<placeholder>` in the model.
+After adding the custom mapping, the mapping will work perfectly. Every position inside the view `<span>` element will be mapped to a position outside the `<placeholder>` in the model.
 
 
 ## Creating the UI
 ## Creating the UI
 
 
 The UI part will provide a dropdown button from which the user can select a placeholder to insert into the editor.
 The UI part will provide a dropdown button from which the user can select a placeholder to insert into the editor.
 
 
-The CKEditor 5 framework features helpers to create different {@link framework/guides/architecture/ui-library#dropdowns dropdowns} like toolbar or list dropdowns.
+CKEditor 5 Framework includes helpers to create different {@link framework/guides/architecture/ui-library#dropdowns dropdowns} like toolbar or list dropdowns.
 
 
-In this tutorial, we will create a dropdown with a list of available placeholders.
+In this tutorial, you will create a dropdown with a list of available placeholders.
 
 
 ```js
 ```js
 // placeholder/placeholderui.js
 // placeholder/placeholderui.js
@@ -563,7 +565,7 @@ export default class PlaceholderUI extends Plugin {
 		const t = editor.t;
 		const t = editor.t;
 		const placeholderNames = [ 'date', 'first name', 'surname' ];
 		const placeholderNames = [ 'date', 'first name', 'surname' ];
 
 
-		// The "placeholder" dropdown must be registered among UI components of the editor
+		// The "placeholder" dropdown must be registered among the UI components of the editor
 		// to be displayed in the toolbar.
 		// to be displayed in the toolbar.
 		editor.ui.componentFactory.add( 'placeholder', locale => {
 		editor.ui.componentFactory.add( 'placeholder', locale => {
 			const dropdownView = createDropdown( locale );
 			const dropdownView = createDropdown( locale );
@@ -579,7 +581,7 @@ export default class PlaceholderUI extends Plugin {
 				withText: true
 				withText: true
 			} );
 			} );
 
 
-			// Execute the command when the dropdown items is clicked (executed).
+			// Execute the command when the dropdown item is clicked (executed).
 			this.listenTo( dropdownView, 'execute', evt => {
 			this.listenTo( dropdownView, 'execute', evt => {
 				editor.execute( 'placeholder', { value: evt.source.commandParam } );
 				editor.execute( 'placeholder', { value: evt.source.commandParam } );
 				editor.editing.view.focus();
 				editor.editing.view.focus();
@@ -632,7 +634,7 @@ ClassicEditor
 	.create( document.querySelector( '#editor' ), {
 	.create( document.querySelector( '#editor' ), {
 		plugins: [ Essentials, Paragraph, Heading, List, Bold, Italic, Placeholder ],
 		plugins: [ Essentials, Paragraph, Heading, List, Bold, Italic, Placeholder ],
 
 
-		// Insert the "placeholder" dropdown to the editor toolbar.
+		// Insert the "placeholder" dropdown into the editor toolbar.
 		toolbar: [ 'heading', 'bold', 'italic', 'numberedList', 'bulletedList', '|', 'placeholder' ]
 		toolbar: [ 'heading', 'bold', 'italic', 'numberedList', 'bulletedList', '|', 'placeholder' ]
 	} )
 	} )
 	.then( editor => {
 	.then( editor => {
@@ -643,7 +645,7 @@ ClassicEditor
 	} );
 	} );
 ```
 ```
 
 
-To make this plugin extensible, the types of placeholders will be read from editor configuration.
+To make this plugin extensible, placeholder types will be read from the editor configuration.
 
 
 The first step is to define the placeholder configuration in the editing plugin:
 The first step is to define the placeholder configuration in the editing plugin:
 
 
@@ -683,7 +685,7 @@ export default class PlaceholderEditing extends Plugin {
 }
 }
 ```
 ```
 
 
-Now let's modify the UI plugin so it will read placeholder types from the configuration:
+Now modify the UI plugin so it will read placeholder types from the configuration:
 
 
 ```js
 ```js
 // placeholder/placeholderui.js
 // placeholder/placeholderui.js
@@ -701,7 +703,7 @@ export default class PlaceholderUI extends Plugin {
 }
 }
 ```
 ```
 
 
-Now the plugins is ready to accept configuration. Let's check how this works by adding `placeholderConfig` configuration in editor's create method:
+The plugin is now ready to accept the configuration. Check how this works by adding the `placeholderConfig` configuration in the editor's `create()` method:
 
 
 ```js
 ```js
 // ... imports
 // ... imports
@@ -717,9 +719,9 @@ ClassicEditor
 	// ...
 	// ...
 ```
 ```
 
 
-Now if you open the dropdown in the toolbar you'll see the new list of placeholders to insert.
+If you open the dropdown in the toolbar, you will see a new list of placeholders to insert.
 
 
-{@img assets/img/tutorial-implementing-an-inline-widget-2.png Screenshot of the placeholder widgets being inserted using the dropdown.}
+{@img assets/img/tutorial-implementing-an-inline-widget-2.png Screenshot of the placeholder widgets being inserted using the dropdown in CKEditor 5 WYSIWYG editor.}
 
 
 ## Demo
 ## Demo
 
 
@@ -760,13 +762,13 @@ class PlaceholderCommand extends Command {
 		const editor = this.editor;
 		const editor = this.editor;
 
 
 		editor.model.change( writer => {
 		editor.model.change( writer => {
-			// Create <placeholder> elment with name attribute...
+			// Create a <placeholder> elment with the "name" attribute...
 			const placeholder = writer.createElement( 'placeholder', { name: value } );
 			const placeholder = writer.createElement( 'placeholder', { name: value } );
 
 
 			// ... and insert it into the document.
 			// ... and insert it into the document.
 			editor.model.insertContent( placeholder );
 			editor.model.insertContent( placeholder );
 
 
-			// Put the selection on inserted element.
+			// Put the selection on the inserted element.
 			writer.setSelection( placeholder, 'on' );
 			writer.setSelection( placeholder, 'on' );
 		} );
 		} );
 	}
 	}
@@ -787,7 +789,7 @@ class PlaceholderUI extends Plugin {
 		const t = editor.t;
 		const t = editor.t;
 		const placeholderNames = editor.config.get( 'placeholderConfig.types' );
 		const placeholderNames = editor.config.get( 'placeholderConfig.types' );
 
 
-		// The "placeholder" dropdown must be registered among UI components of the editor
+		// The "placeholder" dropdown must be registered among the UI components of the editor
 		// to be displayed in the toolbar.
 		// to be displayed in the toolbar.
 		editor.ui.componentFactory.add( 'placeholder', locale => {
 		editor.ui.componentFactory.add( 'placeholder', locale => {
 			const dropdownView = createDropdown( locale );
 			const dropdownView = createDropdown( locale );
@@ -803,7 +805,7 @@ class PlaceholderUI extends Plugin {
 				withText: true
 				withText: true
 			} );
 			} );
 
 
-			// Execute the command when the dropdown items is clicked (executed).
+			// Execute the command when the dropdown item is clicked (executed).
 			this.listenTo( dropdownView, 'execute', evt => {
 			this.listenTo( dropdownView, 'execute', evt => {
 				editor.execute( 'placeholder', { value: evt.source.commandParam } );
 				editor.execute( 'placeholder', { value: evt.source.commandParam } );
 				editor.editing.view.focus();
 				editor.editing.view.focus();
@@ -863,10 +865,10 @@ class PlaceholderEditing extends Plugin {
 			// Allow wherever text is allowed:
 			// Allow wherever text is allowed:
 			allowWhere: '$text',
 			allowWhere: '$text',
 
 
-			// The placeholder will acts as an inline node:
+			// The placeholder will act as an inline node:
 			isInline: true,
 			isInline: true,
 
 
-			// The inline-widget is self-contained so cannot be split by the caret and can be selected:
+			// The inline widget is self-contained so it cannot be split by the caret and it can be selected:
 			isObject: true,
 			isObject: true,
 
 
 			// The placeholder can have many types, like date, name, surname, etc:
 			// The placeholder can have many types, like date, name, surname, etc:
@@ -895,7 +897,7 @@ class PlaceholderEditing extends Plugin {
 			view: ( modelItem, viewWriter ) => {
 			view: ( modelItem, viewWriter ) => {
 				const widgetElement = createPlaceholderView( modelItem, viewWriter );
 				const widgetElement = createPlaceholderView( modelItem, viewWriter );
 
 
-				// Enable widget handling on placeholder element inside editing view.
+				// Enable widget handling on a placeholder element inside the editing view.
 				return toWidget( widgetElement, viewWriter );
 				return toWidget( widgetElement, viewWriter );
 			}
 			}
 		} );
 		} );

+ 12 - 3
docs/umberto.json

@@ -15,14 +15,18 @@
 		"framework/guides/ui/external-ui.html": "framework/guides/deep-dive/ui/external-ui.html",
 		"framework/guides/ui/external-ui.html": "framework/guides/deep-dive/ui/external-ui.html",
 		"framework/guides/ui/document-editor.html": "framework/guides/deep-dive/ui/document-editor.html",
 		"framework/guides/ui/document-editor.html": "framework/guides/deep-dive/ui/document-editor.html",
 		"features/collaboration/overview.html": "features/collaboration/real-time-collaboration/real-time-collaboration.html",
 		"features/collaboration/overview.html": "features/collaboration/real-time-collaboration/real-time-collaboration.html",
-		"features/collaboration/collaborative-editing.html": "features/collaboration/real-time-collaboration/real-time-collaborative-editing.html",
-		"features/collaboration/collaborative-comments.html": "features/collaboration/real-time-collaboration/real-time-collaborative-comments.html",
+		"features/collaboration/collaborative-editing.html": "features/collaboration/real-time-collaboration/real-time-collaboration-integration.html",
+		"features/collaboration/collaborative-comments.html": "features/collaboration/real-time-collaboration/real-time-collaboration-integration.html",
 		"features/collaboration/presence-list.html": "features/collaboration/real-time-collaboration/users-in-real-time-collaboration.html",
 		"features/collaboration/presence-list.html": "features/collaboration/real-time-collaboration/users-in-real-time-collaboration.html",
 		"features/collaboration/comment-only-mode.html": "features/collaboration/comments/comment-only-mode.html",
 		"features/collaboration/comment-only-mode.html": "features/collaboration/comments/comment-only-mode.html",
+		"features/collaboration/real-time-collaboration/real-time-collaborative-comments.html": "features/collaboration/real-time-collaboration/real-time-collaboration-integration.html",
+		"features/collaboration/real-time-collaboration/real-time-collaborative-editing.html": "features/collaboration/real-time-collaboration/real-time-collaboration-integration.html",
 		"features/image-upload.html": "features/image-upload/image-upload.html",
 		"features/image-upload.html": "features/image-upload/image-upload.html",
 		"features/ckfinder.html": "features/image-upload/ckfinder.html",
 		"features/ckfinder.html": "features/image-upload/ckfinder.html",
 		"features/easy-image.html": "features/image-upload/easy-image.html",
 		"features/easy-image.html": "features/image-upload/easy-image.html",
-		"features/collaboration/comments/integrate-comments-with-application.html": "features/collaboration/comments/comments-integration.html"
+		"features/collaboration/comments/integrate-comments-with-application.html": "features/collaboration/comments/comments-integration.html",
+		"features/collaboration/track-changes.html": "features/collaboration/track-changes/track-changes.html",
+		"features/paste-from-word.html": "features/pasting/paste-from-word.html"
 	},
 	},
 	"scripts": {
 	"scripts": {
 		"snippet-adapter": "../scripts/docs/snippetadapter",
 		"snippet-adapter": "../scripts/docs/snippetadapter",
@@ -213,6 +217,11 @@
 					"name": "Image upload",
 					"name": "Image upload",
 					"id": "features-image-upload",
 					"id": "features-image-upload",
 					"slug": "image-upload"
 					"slug": "image-upload"
+				},
+				{
+					"name": "Pasting",
+					"id": "features-pasting",
+					"slug": "pasting"
 				}
 				}
 			]
 			]
 		},
 		},

+ 5 - 1
mgit.json → mrgit.json

@@ -1,6 +1,7 @@
 {
 {
   "packages": "packages/",
   "packages": "packages/",
   "packagesPrefix": "@ckeditor/ckeditor5-",
   "packagesPrefix": "@ckeditor/ckeditor5-",
+  "baseBranches": [ "master", "stable" ],
   "dependencies": {
   "dependencies": {
     "@ckeditor/ckeditor5-adapter-ckfinder": "ckeditor/ckeditor5-adapter-ckfinder",
     "@ckeditor/ckeditor5-adapter-ckfinder": "ckeditor/ckeditor5-adapter-ckfinder",
     "@ckeditor/ckeditor5-alignment": "ckeditor/ckeditor5-alignment",
     "@ckeditor/ckeditor5-alignment": "ckeditor/ckeditor5-alignment",
@@ -29,6 +30,7 @@
     "@ckeditor/ckeditor5-heading": "ckeditor/ckeditor5-heading",
     "@ckeditor/ckeditor5-heading": "ckeditor/ckeditor5-heading",
     "@ckeditor/ckeditor5-highlight": "ckeditor/ckeditor5-highlight",
     "@ckeditor/ckeditor5-highlight": "ckeditor/ckeditor5-highlight",
     "@ckeditor/ckeditor5-image": "ckeditor/ckeditor5-image",
     "@ckeditor/ckeditor5-image": "ckeditor/ckeditor5-image",
+    "@ckeditor/ckeditor5-indent": "ckeditor/ckeditor5-indent",
     "@ckeditor/ckeditor5-link": "ckeditor/ckeditor5-link",
     "@ckeditor/ckeditor5-link": "ckeditor/ckeditor5-link",
     "@ckeditor/ckeditor5-list": "ckeditor/ckeditor5-list",
     "@ckeditor/ckeditor5-list": "ckeditor/ckeditor5-list",
     "@ckeditor/ckeditor5-markdown-gfm": "ckeditor/ckeditor5-markdown-gfm",
     "@ckeditor/ckeditor5-markdown-gfm": "ckeditor/ckeditor5-markdown-gfm",
@@ -44,6 +46,8 @@
     "@ckeditor/ckeditor5-undo": "ckeditor/ckeditor5-undo",
     "@ckeditor/ckeditor5-undo": "ckeditor/ckeditor5-undo",
     "@ckeditor/ckeditor5-upload": "ckeditor/ckeditor5-upload",
     "@ckeditor/ckeditor5-upload": "ckeditor/ckeditor5-upload",
     "@ckeditor/ckeditor5-utils": "ckeditor/ckeditor5-utils",
     "@ckeditor/ckeditor5-utils": "ckeditor/ckeditor5-utils",
-    "@ckeditor/ckeditor5-widget": "ckeditor/ckeditor5-widget"
+    "@ckeditor/ckeditor5-widget": "ckeditor/ckeditor5-widget",
+    "@ckeditor/ckeditor5-watchdog": "ckeditor/ckeditor5-watchdog",
+    "@ckeditor/ckeditor5-word-count": "ckeditor/ckeditor5-word-count"
   }
   }
 }
 }

+ 71 - 64
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "ckeditor5",
   "name": "ckeditor5",
-  "version": "12.1.0",
+  "version": "12.4.0",
   "description": "The development environment of CKEditor 5 – the best browser-based rich text editor.",
   "description": "The development environment of CKEditor 5 – the best browser-based rich text editor.",
   "private": true,
   "private": true,
   "keywords": [
   "keywords": [
@@ -21,80 +21,86 @@
     "framework"
     "framework"
   ],
   ],
   "dependencies": {
   "dependencies": {
-    "@ckeditor/ckeditor5-adapter-ckfinder": "^11.0.1",
-    "@ckeditor/ckeditor5-alignment": "^11.1.0",
-    "@ckeditor/ckeditor5-autoformat": "^11.0.1",
-    "@ckeditor/ckeditor5-autosave": "^11.0.1",
-    "@ckeditor/ckeditor5-basic-styles": "^11.1.0",
-    "@ckeditor/ckeditor5-block-quote": "^11.0.1",
-    "@ckeditor/ckeditor5-build-balloon": "^12.1.0",
-    "@ckeditor/ckeditor5-build-balloon-block": "^12.1.0",
-    "@ckeditor/ckeditor5-build-classic": "^12.1.0",
-    "@ckeditor/ckeditor5-build-decoupled-document": "^12.1.0",
-    "@ckeditor/ckeditor5-build-inline": "^12.1.0",
-    "@ckeditor/ckeditor5-ckfinder": "^11.0.1",
-    "@ckeditor/ckeditor5-clipboard": "^11.0.1",
-    "@ckeditor/ckeditor5-cloud-services": "^11.0.1",
-    "@ckeditor/ckeditor5-core": "^12.1.0",
-    "@ckeditor/ckeditor5-easy-image": "^11.0.1",
-    "@ckeditor/ckeditor5-editor-balloon": "^12.1.0",
-    "@ckeditor/ckeditor5-editor-classic": "^12.1.0",
-    "@ckeditor/ckeditor5-editor-decoupled": "^12.1.0",
-    "@ckeditor/ckeditor5-editor-inline": "^12.1.0",
-    "@ckeditor/ckeditor5-engine": "^13.1.0",
-    "@ckeditor/ckeditor5-enter": "^11.0.1",
-    "@ckeditor/ckeditor5-essentials": "^11.0.1",
-    "@ckeditor/ckeditor5-font": "^11.1.0",
-    "@ckeditor/ckeditor5-heading": "^11.0.1",
-    "@ckeditor/ckeditor5-highlight": "^11.0.1",
-    "@ckeditor/ckeditor5-image": "^13.0.1",
-    "@ckeditor/ckeditor5-link": "^11.0.1",
-    "@ckeditor/ckeditor5-list": "^12.0.1",
-    "@ckeditor/ckeditor5-markdown-gfm": "^11.0.1",
-    "@ckeditor/ckeditor5-media-embed": "^11.1.0",
-    "@ckeditor/ckeditor5-mention": "^10.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^11.0.1",
-    "@ckeditor/ckeditor5-paste-from-office": "^11.0.1",
-    "@ckeditor/ckeditor5-remove-format": "^10.0.0",
-    "@ckeditor/ckeditor5-table": "^12.0.1",
-    "@ckeditor/ckeditor5-theme-lark": "^13.0.1",
-    "@ckeditor/ckeditor5-typing": "^12.0.1",
-    "@ckeditor/ckeditor5-ui": "^12.1.0",
-    "@ckeditor/ckeditor5-undo": "^11.0.1",
-    "@ckeditor/ckeditor5-upload": "^11.0.1",
-    "@ckeditor/ckeditor5-utils": "^12.1.0",
-    "@ckeditor/ckeditor5-widget": "^11.0.1"
+    "@ckeditor/ckeditor5-adapter-ckfinder": "^11.0.5",
+    "@ckeditor/ckeditor5-alignment": "^11.2.0",
+    "@ckeditor/ckeditor5-autoformat": "^11.0.5",
+    "@ckeditor/ckeditor5-autosave": "^11.0.5",
+    "@ckeditor/ckeditor5-basic-styles": "^11.1.4",
+    "@ckeditor/ckeditor5-block-quote": "^11.1.3",
+    "@ckeditor/ckeditor5-build-balloon": "^12.4.0",
+    "@ckeditor/ckeditor5-build-balloon-block": "^12.4.0",
+    "@ckeditor/ckeditor5-build-classic": "^12.4.0",
+    "@ckeditor/ckeditor5-build-decoupled-document": "^12.4.0",
+    "@ckeditor/ckeditor5-build-inline": "^12.4.0",
+    "@ckeditor/ckeditor5-ckfinder": "^11.0.5",
+    "@ckeditor/ckeditor5-clipboard": "^12.0.2",
+    "@ckeditor/ckeditor5-cloud-services": "^11.0.5",
+    "@ckeditor/ckeditor5-core": "^12.3.0",
+    "@ckeditor/ckeditor5-easy-image": "^11.0.5",
+    "@ckeditor/ckeditor5-editor-balloon": "^12.2.2",
+    "@ckeditor/ckeditor5-editor-classic": "^12.1.4",
+    "@ckeditor/ckeditor5-editor-decoupled": "^12.2.2",
+    "@ckeditor/ckeditor5-editor-inline": "^12.3.0",
+    "@ckeditor/ckeditor5-engine": "^14.0.0",
+    "@ckeditor/ckeditor5-enter": "^11.1.0",
+    "@ckeditor/ckeditor5-essentials": "^11.0.5",
+    "@ckeditor/ckeditor5-font": "^11.2.2",
+    "@ckeditor/ckeditor5-heading": "^11.0.5",
+    "@ckeditor/ckeditor5-highlight": "^11.0.5",
+    "@ckeditor/ckeditor5-image": "^14.0.0",
+    "@ckeditor/ckeditor5-indent": "^10.1.0",
+    "@ckeditor/ckeditor5-link": "^11.1.2",
+    "@ckeditor/ckeditor5-list": "^12.1.0",
+    "@ckeditor/ckeditor5-markdown-gfm": "^11.0.5",
+    "@ckeditor/ckeditor5-media-embed": "^11.1.4",
+    "@ckeditor/ckeditor5-mention": "^13.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^11.0.5",
+    "@ckeditor/ckeditor5-paste-from-office": "^11.1.0",
+    "@ckeditor/ckeditor5-remove-format": "^10.0.4",
+    "@ckeditor/ckeditor5-table": "^14.0.0",
+    "@ckeditor/ckeditor5-theme-lark": "^14.2.0",
+    "@ckeditor/ckeditor5-typing": "^12.2.0",
+    "@ckeditor/ckeditor5-ui": "^14.0.0",
+    "@ckeditor/ckeditor5-undo": "^11.0.5",
+    "@ckeditor/ckeditor5-upload": "^12.0.0",
+    "@ckeditor/ckeditor5-utils": "^14.0.0",
+    "@ckeditor/ckeditor5-watchdog": "^11.0.0",
+    "@ckeditor/ckeditor5-widget": "^11.1.0",
+    "@ckeditor/ckeditor5-word-count": "^10.0.2"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@ckeditor/ckeditor5-comments": "^3.0.0",
-    "@ckeditor/ckeditor5-dev-docs": "^11.0.1",
-    "@ckeditor/ckeditor5-dev-env": "^14.1.1",
-    "@ckeditor/ckeditor5-dev-tests": "^16.2.3",
-    "@ckeditor/ckeditor5-dev-utils": "^12.0.1",
-    "@ckeditor/ckeditor5-dev-webpack-plugin": "^8.0.1",
-    "@ckeditor/ckeditor5-inspector": "^1.2.0",
+    "@ckeditor/ckeditor5-comments": "^4.0.0",
+    "@ckeditor/ckeditor5-dev-docs": "^11.0.8",
+    "@ckeditor/ckeditor5-dev-env": "^16.0.0",
+    "@ckeditor/ckeditor5-dev-tests": "^16.7.1",
+    "@ckeditor/ckeditor5-dev-utils": "^12.0.3",
+    "@ckeditor/ckeditor5-dev-webpack-plugin": "^8.0.3",
+    "@ckeditor/ckeditor5-inspector": "^1.3.0",
     "@ckeditor/ckeditor5-react": "^1.1.3",
     "@ckeditor/ckeditor5-react": "^1.1.3",
-    "@ckeditor/ckeditor5-real-time-collaboration": "^12.2.0",
-    "@ckeditor/ckeditor5-track-changes": "^0.2.0",
+    "@ckeditor/ckeditor5-real-time-collaboration": "^12.4.0",
+    "@ckeditor/ckeditor5-track-changes": "^1.1.0",
+    "@wiris/mathtype-ckeditor5": "^7.16.1",
     "babel-standalone": "^6.26.0",
     "babel-standalone": "^6.26.0",
     "css-loader": "^1.0.0",
     "css-loader": "^1.0.0",
     "eslint": "^5.5.0",
     "eslint": "^5.5.0",
-    "eslint-config-ckeditor5": "^1.0.11",
+    "eslint-config-ckeditor5": "^2.0.0",
+    "file-loader": "^4.1.0",
     "glob": "^7.1.2",
     "glob": "^7.1.2",
     "husky": "^1.3.1",
     "husky": "^1.3.1",
     "lint-staged": "^7.0.0",
     "lint-staged": "^7.0.0",
-    "mgit2": "^0.10.0",
     "mini-css-extract-plugin": "^0.4.0",
     "mini-css-extract-plugin": "^0.4.0",
     "minimatch": "^3.0.4",
     "minimatch": "^3.0.4",
+    "mrgit": "^1.0.0",
     "postcss-loader": "^3.0.0",
     "postcss-loader": "^3.0.0",
-    "raw-loader": "^1.0.0",
-    "react": "^16.8.6",
-    "react-dom": "^16.8.6",
-    "style-loader": "^0.23.0",
+    "progress-bar-webpack-plugin": "^1.12.1",
+    "raw-loader": "^3.1.0",
+    "react": "^16.9.0",
+    "react-dom": "^16.9.0",
+    "style-loader": "^1.0.0",
     "svgo": "^1.1.0",
     "svgo": "^1.1.0",
-    "uglifyjs-webpack-plugin": "^1.2.7",
-    "umberto": "^0.22.0",
-    "webpack": "^4.15.0"
+    "uglifyjs-webpack-plugin": "^1.3.0",
+    "umberto": "^1.0.0",
+    "webpack": "^4.39.1"
   },
   },
   "engines": {
   "engines": {
     "node": ">=8.0.0",
     "node": ">=8.0.0",
@@ -112,14 +118,15 @@
     "lint": "eslint --quiet '**/*.js'",
     "lint": "eslint --quiet '**/*.js'",
     "test": "node --max_old_space_size=4096 node_modules/@ckeditor/ckeditor5-dev-tests/bin/test.js",
     "test": "node --max_old_space_size=4096 node_modules/@ckeditor/ckeditor5-dev-tests/bin/test.js",
     "manual": "node --max_old_space_size=4096 node_modules/@ckeditor/ckeditor5-dev-tests/bin/test-manual.js",
     "manual": "node --max_old_space_size=4096 node_modules/@ckeditor/ckeditor5-dev-tests/bin/test-manual.js",
-    "bootstrap": "mgit sync && yarn install",
-    "clean": "rm -rf node_modules && mgit exec 'rm -rf node_modules'",
+    "bootstrap": "mrgit sync && yarn install",
+    "clean": "rm -rf node_modules && mrgit exec 'rm -rf node_modules'",
     "reset": "rm -rf ./packages ./node_modules && yarn run bootstrap",
     "reset": "rm -rf ./packages ./node_modules && yarn run bootstrap",
     "reinstall": "yarn run clean && yarn run bootstrap",
     "reinstall": "yarn run clean && yarn run bootstrap",
     "docs": "node --max-old-space-size=4096 ./scripts/docs/build-docs.js",
     "docs": "node --max-old-space-size=4096 ./scripts/docs/build-docs.js",
     "docs:api": "node ./scripts/docs/build-api-docs.js",
     "docs:api": "node ./scripts/docs/build-api-docs.js",
     "docs:build-and-publish": "node ./scripts/docs/build-and-publish.js",
     "docs:build-and-publish": "node ./scripts/docs/build-and-publish.js",
     "docs:build-and-publish-nightly": "node ./scripts/docs/build-and-publish-nightly.js",
     "docs:build-and-publish-nightly": "node ./scripts/docs/build-and-publish-nightly.js",
+    "docs:content-styles": "node ./scripts/docs/build-content-styles.js",
     "translations:collect": "ckeditor5-dev-env-translations collect",
     "translations:collect": "ckeditor5-dev-env-translations collect",
     "translations:download": "ckeditor5-dev-env-translations download",
     "translations:download": "ckeditor5-dev-env-translations download",
     "translations:upload": "ckeditor5-dev-env-translations upload",
     "translations:upload": "ckeditor5-dev-env-translations upload",

+ 4 - 4
scripts/bump-year.js

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */
@@ -10,14 +10,14 @@
 /*
 /*
 
 
 Usage:
 Usage:
-mgit exec 'node ../../scripts/bump-year.js'
+mrgit exec 'node ../../scripts/bump-year.js'
 node scripts/bump-year.js
 node scripts/bump-year.js
 
 
 Full command to update the entire project:
 Full command to update the entire project:
-git pull && mgit sync && mgit exec 'node ../../scripts/bump-year.js' && node scripts/bump-year.js
+git pull && mrgit sync && mrgit exec 'node ../../scripts/bump-year.js' && node scripts/bump-year.js
 
 
 And after reviewing the changes:
 And after reviewing the changes:
-mgit commit -m "Internal: Bumped the year. [skip ci]" && mgit push git commit -am "Internal: Bumped the year." && git push
+mrgit commit -m "Internal: Bumped the year. [skip ci]" && mrgit push git commit -am "Internal: Bumped the year." && git push
 
 
 */
 */
 
 

+ 1 - 1
scripts/clean-up-svg-icons.sh

@@ -1,7 +1,7 @@
 #!/bin/bash
 #!/bin/bash
 
 
 # @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
 # @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
-# For licensing, see LICENSE.md.
+# For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 
 
 # Cleans up and optimizes SVG files using the SVGO utility.
 # Cleans up and optimizes SVG files using the SVGO utility.
 # The configuration file is located in svgo.config.json.
 # The configuration file is located in svgo.config.json.

+ 1 - 1
scripts/docs/build-and-publish-nightly.js

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */

+ 1 - 1
scripts/docs/build-and-publish.js

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */

+ 1 - 1
scripts/docs/build-api-docs.js

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */

+ 241 - 0
scripts/docs/build-content-styles.js

@@ -0,0 +1,241 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* eslint-env node */
+
+const path = require( 'path' );
+const fs = require( 'fs' );
+const webpack = require( 'webpack' );
+const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
+const { version } = require( '../../package.json' );
+
+const DESTINATION_DIRECTORY = path.join( __dirname, '..', '..', 'build', 'content-styles' );
+const DOCUMENTATION_URL = 'https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/content-styles.html';
+const VARIABLE_DEFINITION_REGEXP = /(--[\w-]+):\s+(.*);/g;
+const VARIABLE_USAGE_REGEXP = /var\((--[\w-]+)\)/g;
+
+const contentRules = {
+	selector: [],
+	variables: []
+};
+
+const webpackConfig = getWebpackConfig();
+const packagesPath = path.join( process.cwd(), 'packages' );
+
+runWebpack( webpackConfig )
+	.then( () => {
+		// All variables are placed inside the `:root` selector. Let's extract their names and values as a map.
+		const cssVariables = new Map( contentRules.variables
+			.map( rule => {
+				// Let's extract all of them as an array of pairs: [ name, value ].
+				const allRules = [];
+				let match;
+
+				while ( ( match = VARIABLE_DEFINITION_REGEXP.exec( rule.css ) ) ) {
+					allRules.push( [ match[ 1 ], match[ 2 ] ] );
+				}
+
+				return allRules;
+			} )
+			.reduce( ( previousValue, currentValue ) => {
+				// And simplify nested arrays as a flattened array.
+				previousValue.push( ...currentValue );
+
+				return previousValue;
+			}, [] ) );
+
+		// CSS variables that are used by the `.ck-content` selector.
+		const usedVariables = new Set();
+
+		const selectorCss = contentRules.selector
+			.map( rule => {
+				// Removes all comments from the rule definition.
+				const cssAsArray = rule.css.replace( /\/\*[^*]+\*\//g, '' ).split( '\n' );
+
+				// We want to fix invalid indentations. We need to find a number of how many indentations we want to remove.
+				// Because the last line ends the block, we can use this value.
+				const lastLineIndent = cssAsArray[ cssAsArray.length - 1 ].length - 1;
+
+				const css = cssAsArray
+					.filter( line => line.trim().length > 0 )
+					.map( ( line, index ) => {
+						// Do not touch the first line. It is always correct.
+						if ( index === 0 ) {
+							return line;
+						}
+
+						return line.slice( lastLineIndent );
+					} )
+					.join( '\n' );
+
+				return `/* ${ rule.file.replace( packagesPath + path.sep, '' ) } */\n${ css }`;
+			} )
+			.filter( rule => {
+				// 1st: path to the CSS file, 2nd: selector definition - start block, 3rd: end block
+				// If the rule contains only 3 lines, it means that it does not define any rules.
+				return rule.split( '\n' ).length > 3;
+			} )
+			.join( '\n' );
+
+		// Find all CSS variables inside the `.ck-content` selector.
+		let match;
+
+		while ( ( match = VARIABLE_USAGE_REGEXP.exec( selectorCss ) ) ) {
+			usedVariables.add( match[ 1 ] );
+		}
+
+		// We need to also look at whether any of the used variables requires the value of other variables.
+		let clearRun = false;
+
+		// We need to process all variables as long as the entire collection won't be changed.
+		while ( !clearRun ) {
+			clearRun = true;
+
+			// For every used variable...
+			for ( const variable of usedVariables ) {
+				const value = cssVariables.get( variable );
+
+				let match;
+
+				// ...find its value and check whether it requires another variable.
+				while ( ( match = VARIABLE_USAGE_REGEXP.exec( value ) ) ) {
+					// If so, mark the entire `while()` block as it should be checked once again.
+					// Also, add the new variable to the used variables collection.
+					if ( !usedVariables.has( match[ 1 ] ) ) {
+						clearRun = false;
+						usedVariables.add( match[ 1 ] );
+					}
+				}
+			}
+		}
+
+		// Build the final content of the CSS file.
+		let data = [
+			'/*',
+			` * CKEditor 5 (v${ version }) content styles.`,
+			` * Generated on ${ new Date().toUTCString() }.`,
+			` * For more information, check out ${ DOCUMENTATION_URL }`,
+			' */\n\n',
+		].join( '\n' );
+
+		data += ':root {\n';
+
+		for ( const variable of [ ...usedVariables ].sort() ) {
+			data += `\t${ variable }: ${ cssVariables.get( variable ) };\n`;
+		}
+
+		data += '}\n\n';
+		data += selectorCss;
+
+		return writeFile( path.join( DESTINATION_DIRECTORY, 'content-styles.css' ), data );
+	} )
+	.then( () => {
+		console.log( `Content styles have been extracted to ${ path.join( DESTINATION_DIRECTORY, 'content-styles.css' ) }` );
+	} )
+	.catch( err => {
+		console.log( err );
+	} );
+
+/**
+ * Prepares the configuration for webpack.
+ *
+ * @returns {Object}
+ */
+function getWebpackConfig() {
+	const postCssConfig = styles.getPostCssConfig( {
+		themeImporter: {
+			themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
+		},
+		minify: false
+	} );
+
+	const contentStylesPlugin = require( './content-styles/list-content-styles' )( { contentRules } );
+
+	postCssConfig.plugins.push( contentStylesPlugin );
+
+	return {
+		mode: 'development',
+
+		devtool: 'source-map',
+
+		entry: {
+			ckeditor5: path.join( __dirname, 'content-styles', 'ckeditor.js' )
+		},
+
+		output: {
+			path: DESTINATION_DIRECTORY,
+			filename: '[name].js'
+		},
+
+		// Configure the paths so building CKEditor 5 snippets work even if the script
+		// is triggered from a directory outside `ckeditor5` (e.g. in a multi-project case).
+		resolve: {
+			modules: getModuleResolvePaths()
+		},
+
+		resolveLoader: {
+			modules: getModuleResolvePaths()
+		},
+
+		module: {
+			rules: [
+				{
+					test: /\.svg$/,
+					use: [ 'raw-loader' ]
+				},
+				{
+					test: /\.css$/,
+					use: [
+						'style-loader',
+						{
+							loader: 'postcss-loader',
+							options: postCssConfig
+						}
+					]
+				}
+			]
+		}
+	};
+}
+
+/**
+ * @param {Object} webpackConfig
+ * @returns {Promise}
+ */
+function runWebpack( webpackConfig ) {
+	return new Promise( ( resolve, reject ) => {
+		webpack( webpackConfig, ( err, stats ) => {
+			if ( err ) {
+				reject( err );
+			} else if ( stats.hasErrors() ) {
+				reject( new Error( stats.toString() ) );
+			} else {
+				resolve();
+			}
+		} );
+	} );
+}
+
+/**
+ * @returns {Array.<String>}
+ */
+function getModuleResolvePaths() {
+	return [
+		path.resolve( __dirname, '..', '..', 'node_modules' ),
+		'node_modules'
+	];
+}
+
+function writeFile( file, data ) {
+	return new Promise( ( resolve, reject ) => {
+		fs.writeFile( file, data, err => {
+			if ( err ) {
+				return reject( err );
+			}
+
+			return resolve();
+		} );
+	} );
+}

+ 11 - 6
scripts/docs/build-docs.js

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */
@@ -17,7 +17,7 @@ const skipValidation = process.argv.includes( '--skip-validation' );
 const production = process.argv.includes( '--production' );
 const production = process.argv.includes( '--production' );
 const watch = process.argv.includes( '--watch' );
 const watch = process.argv.includes( '--watch' );
 const verbose = process.argv.includes( '--verbose' );
 const verbose = process.argv.includes( '--verbose' );
-const whitelistedSnippets = process.argv.find( item => item.startsWith( '--whitelisted-snippet=' ) );
+const whitelistedSnippets = process.argv.find( item => item.startsWith( '--snippets=' ) );
 
 
 buildDocs();
 buildDocs();
 
 
@@ -27,7 +27,12 @@ function buildDocs() {
 	if ( skipApi ) {
 	if ( skipApi ) {
 		promise = Promise.resolve();
 		promise = Promise.resolve();
 	} else {
 	} else {
-		promise = buildApiDocs();
+		promise = buildApiDocs()
+			.catch( err => {
+				console.error( err );
+
+				process.exitCode = 1;
+			} );
 	}
 	}
 
 
 	promise
 	promise
@@ -53,11 +58,11 @@ function runUmberto( options ) {
 		skipLiveSnippets: options.skipLiveSnippets,
 		skipLiveSnippets: options.skipLiveSnippets,
 		skipValidation: options.skipValidation,
 		skipValidation: options.skipValidation,
 		snippetOptions: {
 		snippetOptions: {
-			production: options.production
+			production: options.production,
+			whitelistedSnippets: whitelistedSnippets ? whitelistedSnippets.replace( '--snippets=', '' ).split( ',' ) : []
 		},
 		},
 		skipApi: options.skipApi,
 		skipApi: options.skipApi,
 		verbose: options.verbose,
 		verbose: options.verbose,
-		watch: options.watch,
-		whitelistedSnippets: whitelistedSnippets ? whitelistedSnippets.replace( '--whitelisted-snippet=', '' ) : undefined
+		watch: options.watch
 	} );
 	} );
 }
 }

+ 1 - 1
scripts/docs/buildapi.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */

+ 76 - 0
scripts/docs/content-styles/ckeditor.js

@@ -0,0 +1,76 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+// The editor creator to use.
+import ClassicEditorBase from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+
+import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
+import UploadAdapter from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
+import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Code from '@ckeditor/ckeditor5-basic-styles/src/code';
+import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
+import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough';
+import Subscript from '@ckeditor/ckeditor5-basic-styles/src/subscript';
+import Superscript from '@ckeditor/ckeditor5-basic-styles/src/superscript';
+import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
+import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote';
+import CKFinder from '@ckeditor/ckeditor5-ckfinder/src/ckfinder';
+import EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage';
+import Heading from '@ckeditor/ckeditor5-heading/src/heading';
+import Image from '@ckeditor/ckeditor5-image/src/image';
+import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
+import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize';
+import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle';
+import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar';
+import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload';
+import Link from '@ckeditor/ckeditor5-link/src/link';
+import List from '@ckeditor/ckeditor5-list/src/list';
+import TodoList from '@ckeditor/ckeditor5-list/src/todolist';
+import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice';
+import Table from '@ckeditor/ckeditor5-table/src/table';
+import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
+import Font from '@ckeditor/ckeditor5-font/src/font';
+import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight';
+import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';
+
+export default class ClassicEditor extends ClassicEditorBase {}
+
+// Plugins to include in the build.
+ClassicEditor.builtinPlugins = [
+	Essentials,
+	UploadAdapter,
+	Autoformat,
+	Bold,
+	Code,
+	Italic,
+	Strikethrough,
+	Subscript,
+	Superscript,
+	Underline,
+	BlockQuote,
+	CKFinder,
+	EasyImage,
+	Heading,
+	Image,
+	ImageCaption,
+	ImageResize,
+	ImageStyle,
+	ImageToolbar,
+	ImageUpload,
+	Link,
+	List,
+	TodoList,
+	MediaEmbed,
+	Paragraph,
+	PasteFromOffice,
+	Table,
+	TableToolbar,
+	Font,
+	Highlight,
+	Alignment
+];

+ 35 - 0
scripts/docs/content-styles/list-content-styles.js

@@ -0,0 +1,35 @@
+#!/usr/bin/env node
+
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* eslint-env node */
+
+const postcss = require( 'postcss' );
+
+module.exports = postcss.plugin( 'list-content-styles', function( options ) {
+	const selectorStyles = options.contentRules.selector;
+	const variables = options.contentRules.variables;
+
+	return root => {
+		root.walkRules( rule => {
+			rule.selectors.forEach( selector => {
+				if ( selector.match( ':root' ) ) {
+					variables.push( {
+						file: root.source.input.file,
+						css: rule.toString()
+					} );
+				}
+
+				if ( selector.match( '.ck-content' ) ) {
+					selectorStyles.push( {
+						file: root.source.input.file,
+						css: rule.toString()
+					} );
+				}
+			} );
+		} );
+	};
+} );

+ 1 - 1
scripts/docs/getrealimportpath.js

@@ -1,6 +1,6 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */

+ 367 - 61
scripts/docs/snippetadapter.js

@@ -1,89 +1,272 @@
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */
 
 
 const path = require( 'path' );
 const path = require( 'path' );
 const fs = require( 'fs' );
 const fs = require( 'fs' );
+const minimatch = require( 'minimatch' );
 const webpack = require( 'webpack' );
 const webpack = require( 'webpack' );
 const { bundler, styles } = require( '@ckeditor/ckeditor5-dev-utils' );
 const { bundler, styles } = require( '@ckeditor/ckeditor5-dev-utils' );
 const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
 const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
 const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' );
 const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' );
 const UglifyJsWebpackPlugin = require( 'uglifyjs-webpack-plugin' );
 const UglifyJsWebpackPlugin = require( 'uglifyjs-webpack-plugin' );
+const ProgressBarPlugin = require( 'progress-bar-webpack-plugin' );
 
 
-const webpackProcesses = new Map();
+const DEFAULT_LANGUAGE = 'en';
+const MULTI_LANGUAGE = 'multi-language';
 
 
-module.exports = function snippetAdapter( data ) {
-	if ( !data.snippetSource.js ) {
-		throw new Error( `Missing snippet source for "${ data.snippetPath }".` );
+/**
+ * @param {Set.<Snippet>} snippets Snippet collection extracted from documentation files.
+ * @param {Object} options
+ * @param {Boolean} options.production Whether to build snippets in production mode.
+ * @param {Array.<String>|undefined} options.whitelistedSnippets An array that contains glob patterns.
+ * @param {Object.<String, Function>} umbertoHelpers
+ * @returns {Promise}
+ */
+module.exports = function snippetAdapter( snippets, options, umbertoHelpers ) {
+	const { getSnippetPlaceholder, getSnippetSourcePaths } = umbertoHelpers;
+	const snippetsDependencies = new Map();
+
+	// For each snippet, load its config. If the snippet has defined dependencies, load those as well.
+	for ( const snippetData of snippets ) {
+		if ( !snippetData.snippetSources.js ) {
+			throw new Error( `Missing snippet source for "${ snippetData.snippetName }".` );
+		}
+
+		snippetData.snippetConfig = readSnippetConfig( snippetData.snippetSources.js );
+		snippetData.snippetConfig.language = snippetData.snippetConfig.language || DEFAULT_LANGUAGE;
+
+		// If, in order to work, a snippet requires another snippet to be built, and the other snippet
+		// isn't included in any guide via `{@snippet ...}`, then that other snippet need to be marked
+		// as a dependency of the first one. Example – bootstrap UI uses an iframe, and inside that iframe we
+		// need a JS file. That JS file needs to be built, even though it's not a real snippet (and it's not used
+		// via {@snippet}).
+		if ( snippetData.snippetConfig.dependencies ) {
+			for ( const dependencyName of snippetData.snippetConfig.dependencies ) {
+				// Do not load the same dependency more than once.
+				if ( snippetsDependencies.has( dependencyName ) ) {
+					continue;
+				}
+
+				// Find a root path where to look for the snippet's sources. We just want to pass it through Webpack.
+				const snippetBasePathRegExp = new RegExp( snippetData.snippetName.replace( /\//g, '\\/' ) + '.*$' );
+				const snippetBasePath = snippetData.snippetSources.js.replace( snippetBasePathRegExp, '' );
+
+				const dependencySnippet = {
+					snippetSources: getSnippetSourcePaths( snippetBasePath, dependencyName ),
+					snippetName: dependencyName,
+					outputPath: snippetData.outputPath,
+					destinationPath: snippetData.destinationPath,
+					requiredFor: snippetData
+				};
+
+				if ( !dependencySnippet.snippetSources.js ) {
+					throw new Error( `Missing snippet source for "${ dependencySnippet.snippetName }".` );
+				}
+
+				dependencySnippet.snippetConfig = readSnippetConfig( dependencySnippet.snippetSources.js );
+				dependencySnippet.snippetConfig.language = dependencySnippet.snippetConfig.language || DEFAULT_LANGUAGE;
+
+				snippetsDependencies.set( dependencyName, dependencySnippet );
+			}
+		}
 	}
 	}
 
 
-	const snippetConfig = readSnippetConfig( data.snippetSource.js );
-	const outputPath = path.join( data.outputPath, data.snippetPath );
+	// Add all dependencies to the snippet collection.
+	for ( const snippetData of snippetsDependencies.values() ) {
+		snippets.add( snippetData );
+	}
 
 
-	const webpackConfig = getWebpackConfig( {
-		entry: data.snippetSource.js,
-		outputPath,
-		language: snippetConfig.language,
-		production: data.options.production,
-		definitions: data.options.definitions || {}
-	} );
+	// Remove snippets that do not match to patterns specified in `options.whitelistedSnippets`.
+	if ( options.whitelistedSnippets ) {
+		filterWhitelistedSnippets( snippets, options.whitelistedSnippets );
+	}
 
 
-	let promise;
+	console.log( `Building ${ snippets.size } snippets...` );
 
 
-	// See #530.
-	if ( webpackProcesses.has( outputPath ) ) {
-		promise = webpackProcesses.get( outputPath );
-	} else {
-		promise = runWebpack( webpackConfig );
-		webpackProcesses.set( outputPath, promise );
+	const groupedSnippetsByLanguage = {};
+
+	// Group snippets by language. There is no way to build different languages in a single Webpack process.
+	// Webpack must be called as many times as different languages are being used in snippets.
+	for ( const snippetData of snippets ) {
+		// Multi-languages editors must be built separately.
+		if ( snippetData.snippetConfig.additionalLanguages ) {
+			snippetData.snippetConfig.additionalLanguages.push( snippetData.snippetConfig.language );
+			snippetData.snippetConfig.language = MULTI_LANGUAGE;
+		}
+
+		if ( !groupedSnippetsByLanguage[ snippetData.snippetConfig.language ] ) {
+			groupedSnippetsByLanguage[ snippetData.snippetConfig.language ] = new Set();
+		}
+
+		groupedSnippetsByLanguage[ snippetData.snippetConfig.language ].add( snippetData );
+	}
+
+	// For each language prepare own Webpack configuration.
+	const webpackConfigs = Object.keys( groupedSnippetsByLanguage )
+		.map( language => {
+			return getWebpackConfig( groupedSnippetsByLanguage[ language ], {
+				language,
+				production: options.production,
+				definitions: options.definitions || {}
+			} );
+		} );
+
+	let promise = Promise.resolve();
+
+	// Nothing to build.
+	if ( !webpackConfigs.length ) {
+		return promise;
+	}
+
+	for ( const config of webpackConfigs ) {
+		promise = promise.then( () => runWebpack( config ) );
 	}
 	}
 
 
 	return promise
 	return promise
 		.then( () => {
 		.then( () => {
-			const wasCSSGenerated = fs.existsSync( path.join( outputPath, 'snippet.css' ) );
-			const cssFiles = [
-				path.join( data.basePath, 'assets', 'snippet-styles.css' )
-			];
-
-			// CSS may not be generated by Webpack if a snippet's JS file didn't import any SCSS files.
-			if ( wasCSSGenerated ) {
-				cssFiles.unshift( path.join( data.relativeOutputPath, data.snippetPath, 'snippet.css' ) );
+			// Group snippets by destination path in order to attach required HTML code and assets (CSS and JS).
+			const groupedSnippetsByDestinationPath = {};
+
+			for ( const snippetData of snippets ) {
+				if ( !groupedSnippetsByDestinationPath[ snippetData.destinationPath ] ) {
+					groupedSnippetsByDestinationPath[ snippetData.destinationPath ] = new Set();
+				}
+
+				groupedSnippetsByDestinationPath[ snippetData.destinationPath ].add( snippetData );
 			}
 			}
 
 
-			// If the snippet is a dependency of a parent snippet, append JS and CSS to HTML and save to disk.
-			if ( data.isDependency ) {
-				let htmlFile = fs.readFileSync( data.snippetSource.html ).toString();
+			// For every page that contains at least one snippet, we need to replace Umberto comments with HTML code.
+			for ( const destinationPath of Object.keys( groupedSnippetsByDestinationPath ) ) {
+				const snippetsOnPage = groupedSnippetsByDestinationPath[ destinationPath ];
+
+				// Assets required for the all snippets.
+				const cssFiles = [];
+				const jsFiles = [];
 
 
-				if ( wasCSSGenerated ) {
-					htmlFile += '<link rel="stylesheet" href="snippet.css" type="text/css">';
+				let content = fs.readFileSync( destinationPath ).toString();
+
+				for ( const snippetData of snippetsOnPage ) {
+					// CSS may not be generated by Webpack if a snippet's JS file didn't import any CSS files.
+					const wasCSSGenerated = fs.existsSync( path.join( snippetData.outputPath, snippetData.snippetName, 'snippet.css' ) );
+
+					// If the snippet is a dependency, append JS and CSS to HTML, save to disk and continue.
+					if ( snippetData.requiredFor ) {
+						let htmlFile = fs.readFileSync( snippetData.snippetSources.html ).toString();
+
+						if ( wasCSSGenerated ) {
+							htmlFile += '<link rel="stylesheet" href="snippet.css" type="text/css">';
+						}
+
+						htmlFile += '<script src="snippet.js"></script>';
+
+						fs.writeFileSync( path.join( snippetData.outputPath, snippetData.snippetName, 'snippet.html' ), htmlFile );
+
+						continue;
+					}
+
+					let snippetHTML = fs.readFileSync( snippetData.snippetSources.html ).toString();
+
+					if ( snippetHTML.trim() ) {
+						snippetHTML = snippetHTML.replace( /%BASE_PATH%/g, snippetData.basePath );
+						snippetHTML = `<div class="live-snippet">${ snippetHTML }</div>`;
+					}
+
+					content = content.replace( getSnippetPlaceholder( snippetData.snippetName ), snippetHTML );
+
+					jsFiles.push( path.join( snippetData.basePath, 'assets', 'snippet.js' ) );
+					jsFiles.push( path.join( snippetData.relativeOutputPath, snippetData.snippetName, 'snippet.js' ) );
+
+					cssFiles.push( path.join( snippetData.basePath, 'assets', 'snippet-styles.css' ) );
+
+					if ( wasCSSGenerated ) {
+						cssFiles.unshift( path.join( snippetData.relativeOutputPath, snippetData.snippetName, 'snippet.css' ) );
+					}
+
+					// Additional languages must be imported by the HTML code.
+					if ( snippetData.snippetConfig.additionalLanguages ) {
+						snippetData.snippetConfig.additionalLanguages.forEach( language => {
+							jsFiles.push( path.join( snippetData.relativeOutputPath, 'translations', `${ language }.js` ) );
+						} );
+					}
 				}
 				}
 
 
-				htmlFile += '<script src="snippet.js"></script>';
+				const cssImportsHTML = getHTMLImports( cssFiles, importPath => {
+					return `    <link rel="stylesheet" href="${ importPath }" type="text/css">`;
+				} );
 
 
-				fs.writeFileSync( path.join( outputPath, 'snippet.html' ), htmlFile );
-			}
+				const jsImportsHTML = getHTMLImports( jsFiles, importPath => {
+					return `    <script src="${ importPath }"></script>`;
+				} );
 
 
-			return {
-				html: fs.readFileSync( data.snippetSource.html ),
-				assets: {
-					js: [
-						// Load snippet helpers first.
-						path.join( data.basePath, 'assets', 'snippet.js' ),
-
-						// Then load the actual snippet code.
-						path.join( data.relativeOutputPath, data.snippetPath, 'snippet.js' )
-					],
-					css: cssFiles
-				},
-				dependencies: snippetConfig.dependencies
-			};
+				content = content.replace( '<!--UMBERTO: SNIPPET: CSS-->', cssImportsHTML );
+				content = content.replace( '<!--UMBERTO: SNIPPET: JS-->', jsImportsHTML );
+
+				fs.writeFileSync( destinationPath, content );
+			}
+		} )
+		.then( () => {
+			console.log( `Finished building ${ snippets.size } snippets.` );
 		} );
 		} );
 };
 };
 
 
-function getWebpackConfig( config ) {
+/**
+ * Removes snippets that names do not match to patterns specified in `whitelistedSnippets` array.
+ *
+ * @param {Set.<Snippet>} snippets Snippet collection extracted from documentation files.
+ * @param {Array.<String>|undefined} whitelistedSnippets Snippet patterns that should be built.
+ */
+function filterWhitelistedSnippets( snippets, whitelistedSnippets ) {
+	if ( !whitelistedSnippets.length ) {
+		return;
+	}
+
+	const snippetsToBuild = new Set();
+
+	// Find all snippets that matched to specified criteria.
+	for ( const snippetData of snippets ) {
+		const shouldBeBuilt = whitelistedSnippets.some( pattern => {
+			return minimatch( snippetData.snippetName, pattern ) || snippetData.snippetName.includes( pattern );
+		} );
+
+		if ( shouldBeBuilt ) {
+			snippetsToBuild.add( snippetData );
+		}
+	}
+
+	// Find all dependencies that are required for whitelisted snippets.
+	for ( const snippetData of snippets ) {
+		if ( snippetsToBuild.has( snippetData ) ) {
+			continue;
+		}
+
+		if ( snippetData.requiredFor && snippetsToBuild.has( snippetData.requiredFor ) ) {
+			snippetsToBuild.add( snippetData );
+		}
+	}
+
+	// Remove snippets that won't be built and aren't dependencies of other snippets.
+	for ( const snippetData of snippets ) {
+		if ( !snippetsToBuild.has( snippetData ) ) {
+			snippets.delete( snippetData );
+		}
+	}
+}
+
+/**
+ * Prepares configuration for Webpack.
+ *
+ * @param {Set.<Snippet>} snippets Snippet collection extracted from documentation files.
+ * @param {Object} config
+ * @param {String} config.language Language for the build.
+ * @param {Boolean} config.production Whether to build for production.
+ * @param {Object} config.definitions
+ * @returns {Object}
+ */
+function getWebpackConfig( snippets, config ) {
 	// Stringify all definitions values. The `DefinePlugin` injects definition values as they are so we need to stringify them,
 	// Stringify all definitions values. The `DefinePlugin` injects definition values as they are so we need to stringify them,
 	// so they will become real strings in the generated code. See https://webpack.js.org/plugins/define-plugin/ for more information.
 	// so they will become real strings in the generated code. See https://webpack.js.org/plugins/define-plugin/ for more information.
 	const definitions = {};
 	const definitions = {};
@@ -92,16 +275,36 @@ function getWebpackConfig( config ) {
 		definitions[ definitionKey ] = JSON.stringify( config.definitions[ definitionKey ] );
 		definitions[ definitionKey ] = JSON.stringify( config.definitions[ definitionKey ] );
 	}
 	}
 
 
-	return {
+	const ckeditorWebpackPluginOptions = {};
+
+	if ( config.language === MULTI_LANGUAGE ) {
+		const additionalLanguages = new Set();
+
+		// Find all additional languages that must be built.
+		for ( const snippetData of snippets ) {
+			for ( const language of snippetData.snippetConfig.additionalLanguages ) {
+				additionalLanguages.add( language );
+			}
+		}
+
+		// Pass unique values of `additionalLanguages` to `CKEditorWebpackPlugin`.
+		ckeditorWebpackPluginOptions.additionalLanguages = [ ...additionalLanguages ];
+
+		// Also, set the default language because of the warning that comes from the plugin.
+		ckeditorWebpackPluginOptions.language = DEFAULT_LANGUAGE;
+	} else {
+		ckeditorWebpackPluginOptions.language = config.language;
+	}
+
+	const webpackConfig = {
 		mode: config.production ? 'production' : 'development',
 		mode: config.production ? 'production' : 'development',
 
 
 		devtool: 'source-map',
 		devtool: 'source-map',
 
 
-		entry: config.entry,
+		entry: {},
 
 
 		output: {
 		output: {
-			path: config.outputPath,
-			filename: 'snippet.js'
+			filename: '[name]/snippet.js'
 		},
 		},
 
 
 		optimization: {
 		optimization: {
@@ -119,15 +322,16 @@ function getWebpackConfig( config ) {
 		},
 		},
 
 
 		plugins: [
 		plugins: [
-			new MiniCssExtractPlugin( { filename: 'snippet.css' } ),
-			new CKEditorWebpackPlugin( {
-				language: config.language || 'en'
-			} ),
+			new MiniCssExtractPlugin( { filename: '[name]/snippet.css' } ),
+			new CKEditorWebpackPlugin( ckeditorWebpackPluginOptions ),
 			new webpack.BannerPlugin( {
 			new webpack.BannerPlugin( {
 				banner: bundler.getLicenseBanner(),
 				banner: bundler.getLicenseBanner(),
 				raw: true
 				raw: true
 			} ),
 			} ),
-			new webpack.DefinePlugin( definitions )
+			new webpack.DefinePlugin( definitions ),
+			new ProgressBarPlugin( {
+				format: `Building snippets for language "${ config.language }": :percent (:msg)`,
+			} )
 		],
 		],
 
 
 		// Configure the paths so building CKEditor 5 snippets work even if the script
 		// Configure the paths so building CKEditor 5 snippets work even if the script
@@ -161,12 +365,50 @@ function getWebpackConfig( config ) {
 							} )
 							} )
 						}
 						}
 					]
 					]
+				},
+				// `file-loader` is used to handle assets introduced by 3rd party plugins.
+				// All guides in the documentation that could use images should be named as follow: `guide-type/guide-name`
+				//
+				// NOTE: You cannot use more than single slash `/` in the guide name.
+				// All images will be saved in the `snippets/` directory as `assets/images/[file]`.
+				// Unfortunately, compiled JS/CSS file that requires images will be looking for those assets in:
+				// `snippets/[guide-type/guide-name]/assets/images/` so we need to manually go up twice.
+				// ATM there is no easy way to find the number how many directories we need to go up so the assumption about names of
+				// the guides seems to be a safer solution.
+				{
+					test: /\.(png|jpe?g|gif)$/,
+					loader: 'file-loader',
+					options: {
+						name: config.production ? '[sha512:hash:base64:7].[ext]' : '[name].[ext]',
+						outputPath: path.join( 'assets', 'images' ),
+						publicPath: [ '..', '..', 'assets', 'images' ].join( '/' )
+					},
 				}
 				}
 			]
 			]
 		}
 		}
 	};
 	};
+
+	for ( const snippetData of snippets ) {
+		if ( !webpackConfig.output.path ) {
+			webpackConfig.output.path = snippetData.outputPath;
+		}
+
+		if ( webpackConfig.entry[ snippetData.snippetName ] ) {
+			continue;
+		}
+
+		webpackConfig.entry[ snippetData.snippetName ] = snippetData.snippetSources.js;
+	}
+
+	return webpackConfig;
 }
 }
 
 
+/**
+ * Builds snippets.
+ *
+ * @param {Object} webpackConfig
+ * @returns {Promise}
+ */
 function runWebpack( webpackConfig ) {
 function runWebpack( webpackConfig ) {
 	return new Promise( ( resolve, reject ) => {
 	return new Promise( ( resolve, reject ) => {
 		webpack( webpackConfig, ( err, stats ) => {
 		webpack( webpackConfig, ( err, stats ) => {
@@ -181,6 +423,9 @@ function runWebpack( webpackConfig ) {
 	} );
 	} );
 }
 }
 
 
+/**
+ * @returns {Array.<String>}
+ */
 function getModuleResolvePaths() {
 function getModuleResolvePaths() {
 	return [
 	return [
 		path.resolve( __dirname, '..', '..', 'node_modules' ),
 		path.resolve( __dirname, '..', '..', 'node_modules' ),
@@ -188,6 +433,12 @@ function getModuleResolvePaths() {
 	];
 	];
 }
 }
 
 
+/**
+ * Reads the snippet's configuration.
+ *
+ * @param {String} snippetSourcePath An absolute path to the file.
+ * @returns {Object}
+ */
 function readSnippetConfig( snippetSourcePath ) {
 function readSnippetConfig( snippetSourcePath ) {
 	const snippetSource = fs.readFileSync( snippetSourcePath ).toString();
 	const snippetSource = fs.readFileSync( snippetSourcePath ).toString();
 
 
@@ -199,3 +450,58 @@ function readSnippetConfig( snippetSourcePath ) {
 
 
 	return JSON.parse( configSourceMatch[ 1 ] );
 	return JSON.parse( configSourceMatch[ 1 ] );
 }
 }
+
+/**
+ * Removes duplicated entries specified in `files` array and map those entires using `mapFunction`.
+ *
+ * @param {Array.<String>} files Paths collection.
+ * @param {Function} mapFunction Function that should return a string.
+ * @returns {String}
+ */
+function getHTMLImports( files, mapFunction ) {
+	return [ ...new Set( files ) ]
+		.map( mapFunction )
+		.join( '\n' )
+		.replace( /^\s+/, '' );
+}
+
+/**
+ * @typedef {Object} Snippet
+ *
+ * @property {SnippetSource} snippetSources Sources of the snippet.
+ *
+ * @property {String} snippetName Name of the snippet. Defined directly after `@snippet` tag.
+ *
+ * @property {String} outputPath An absolute path where to write file produced by the `snippetAdapter`.
+ *
+ * @property {String} destinationPath An absolute path to the file where the snippet is being used.
+ *
+ * @property {SnippetConfiguration} snippetConfig={} Additional configuration of the snippet. It's being read from the snippet's source.
+ *
+ * @property {String} [basePath] Relative path from the processed file to the root of the documentation.
+ *
+ * @property {String} [relativeOutputPath] The same like `basePath` but for the output path (where processed file will be saved).
+ *
+ * @property {Snippet|undefined} [requiredFor] If the value is instance of `Snippet`, current snippet requires
+ * the snippet defined as `requiredFor` to work.
+ */
+
+/**
+ * @typedef {Object} SnippetSource
+ *
+ * @property {String} html An absolute path to the HTML sample.
+ *
+ * @property {String} css An absolute path to the CSS sample.
+ *
+ * @property {String} js An absolute path to the JS sample.
+ */
+
+/**
+ * @typedef {Object} SnippetConfiguration
+ *
+ * @property {String} [language] A language that will be used for building the editor.
+ *
+ * @property {Array.<String>} [dependencies] Names of samples that are required to working.
+ *
+ * @property {Array.<String>} [additionalLanguages] Additional languages that are required by the snippet.
+ */

+ 0 - 139
scripts/notify-travis-status.js

@@ -1,139 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* eslint-env node */
-
-/*
-
-This script assumes that is being executed on Travis CI. It requires three environment variables:
-- SLACK_WEBHOOK_URL - a URL where the notification should be sent
-- START_TIME - POSIX time (when the script has begun the job)
-- END_TIME - POSIX time (when the script has finished the job)
-
-It also has some dependencies:
-- "slack-notify"
-
- */
-
-const buildBranch = process.env.TRAVIS_BRANCH;
-
-const acceptedBranches = [
-	'master',
-	'master-revisions'
-];
-
-const acceptedEvents = [
-	'push',
-	'cron'
-];
-
-// Send a notification only for main branches...
-if ( !acceptedBranches.includes( buildBranch ) ) {
-	process.exit();
-}
-
-// ...and an event that triggered the build is correct...
-if ( !acceptedEvents.includes( process.env.TRAVIS_EVENT_TYPE ) ) {
-	process.exit();
-}
-
-// ...and for builds that failed.
-if ( process.env.TRAVIS_TEST_RESULT == 0 ) {
-	process.exit();
-}
-
-const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL;
-
-const slack = require( 'slack-notify' )( SLACK_WEBHOOK_URL );
-
-const buildId = process.env.TRAVIS_JOB_NUMBER.split( '.' )[ 0 ];
-const buildUrl = process.env.TRAVIS_JOB_WEB_URL;
-const buildCommit = process.env.TRAVIS_COMMIT;
-const [ owner, repo ] = process.env.TRAVIS_REPO_SLUG.split( '/' );
-const commitUrl = `https://github.com/${ owner }/${ repo }/commit/${ buildCommit }`;
-const shortCommit = buildCommit.substring( 0, 7 );
-const execTime = getExecutionTime( parseInt( process.env.END_TIME ), parseInt( process.env.START_TIME ) );
-
-slack.onError = err => {
-	console.log( 'API error occurred:', err );
-};
-
-slack.send( {
-	icon_url: 'https://a.slack-edge.com/66f9/img/services/travis_36.png',
-	unfurl_links: 1,
-	username: 'Travis CI',
-	attachments: [
-		{
-			color: 'danger',
-			fields: [
-				{
-					title: 'Branch',
-					value: `<https://github.com/${ owner }/${ repo }/tree/${ buildBranch }|#${ buildBranch }>`,
-					short: true
-				},
-				{
-					title: 'Commit',
-					value: `<${ commitUrl }|${ shortCommit }>`,
-					short: true
-				},
-				{
-					title: 'Build',
-					value: `<${ buildUrl }|#${ buildId }>`,
-					short: true
-				},
-				{
-					title: 'Testing time',
-					value: `${ execTime.mins } min ${ execTime.secs } sec`,
-					short: true
-				},
-				{
-					title: 'Commit message',
-					value: getFormattedMessage( process.env.TRAVIS_COMMIT_MESSAGE, owner, repo ),
-					short: false
-				},
-			]
-		},
-	]
-} );
-
-/**
- * Returns an object that compares two dates.
- *
- * @param {Number} endTime
- * @param {Number} startTime
- * @returns {Object}
- */
-function getExecutionTime( endTime, startTime ) {
-	const execTime = {
-		ms: endTime - startTime
-	};
-
-	execTime.days = Math.floor( execTime.ms / 86400 );
-	execTime.hours = Math.floor( ( execTime.ms - 86400 * execTime.days ) / 3600 );
-	execTime.mins = Math.floor( ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) / 60 );
-	execTime.secs = ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) - 60 * execTime.mins;
-
-	return execTime;
-}
-
-/**
- * Replaces `#Id` and `Repo/Owner#Id` with URls to Github Issues.
- *
- * @param {String} message
- * @param {String} repoOwner
- * @param {String} repoName
- * @returns {string}
- */
-function getFormattedMessage( message, repoOwner, repoName ) {
-	return message
-		.replace( / #(\d+)/g, ( _, issueId ) => {
-			return ` <https://github.com/${ repoOwner }/${ repoName }/issues/${ issueId }|#${ issueId }>`;
-		} )
-		.replace( /([\w-]+\/[\w-]+)#(\d+)/g, ( _, repoSlug, issueId ) => {
-			return `<https://github.com/${ repoSlug }/issues/${ issueId }|${ repoSlug }#${ issueId }>`;
-		} );
-}

+ 1 - 1
scripts/release/bump-versions.js

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */

+ 1 - 1
scripts/release/changelog.js

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */

+ 1 - 1
scripts/release/publish.js

@@ -2,7 +2,7 @@
 
 
 /**
 /**
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
 /* eslint-env node */
 /* eslint-env node */

+ 0 - 39
scripts/release/update-mgit-branches.js

@@ -1,39 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* eslint-env node */
-
-'use strict';
-
-const branchName = process.argv[ 2 ];
-
-if ( !branchName ) {
-	throw new Error( 'Missing branch name.' );
-}
-
-const path = require( 'path' );
-const { tools, logger } = require( '@ckeditor/ckeditor5-dev-utils' );
-const log = logger();
-const mgitJsonPath = path.resolve( __dirname, '..', '..', 'mgit.json' );
-
-log.info( 'Updating the "mgit.json"...' );
-
-tools.updateJSONFile( mgitJsonPath, mgitJson => {
-	const dependencies = mgitJson.dependencies;
-
-	for ( const packageName of Object.keys( dependencies ) ) {
-		dependencies[ packageName ] = dependencies[ packageName ].split( '#' )[ 0 ];
-
-		if ( branchName !== 'master' ) {
-			dependencies[ packageName ] += '#' + branchName;
-		}
-	}
-
-	return mgitJson;
-} );
-
-log.info( `Done. "mgit.json" uses the "${ branchName }" branch now.` );

+ 1 - 1
scripts/switch-to-dev-dev.sh

@@ -1,7 +1,7 @@
 #!/bin/bash
 #!/bin/bash
 
 
 # @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
 # @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
-# For licensing, see LICENSE.md.
+# For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 
 
 # Symlinks packages from https://github.com/ckeditor/ckeditor5-dev in ckeditor5's node_modules.
 # Symlinks packages from https://github.com/ckeditor/ckeditor5-dev in ckeditor5's node_modules.
 # This allows easily switching to dev versions of ckeditor5-dev-* packages.
 # This allows easily switching to dev versions of ckeditor5-dev-* packages.

+ 8 - 20
scripts/update-stable-branches.sh

@@ -1,7 +1,7 @@
 #!/bin/bash
 #!/bin/bash
 
 
 # @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
 # @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
-# For licensing, see LICENSE.md.
+# For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 
 
 set -e
 set -e
 
 
@@ -10,30 +10,18 @@ echo ""
 
 
 if [[ $REPLY =~ ^[Yy]$ ]]
 if [[ $REPLY =~ ^[Yy]$ ]]
 then
 then
-	# Update the `stable` branch in the ckeditor5 repository.
+	# Update the `stable` branch in the `ckeditor5` repository.
 	git checkout stable && git merge master && git checkout master
 	git checkout stable && git merge master && git checkout master
 
 
-	# Add `stable` branches in all repos which don't have them yet.
-	mgit exec 'git checkout -b stable 2> /dev/null && git push origin stable && git checkout master'
+	# Add `#stable` branches in all repos which don't have them yet.
+	mrgit exec 'git checkout -b stable 2> /dev/null && git push origin stable && git checkout master'
 
 
-	# Update all `stable` branches in all packages.
-	mgit exec 'git checkout stable && git pull origin stable && git merge master && git checkout master'
+	# Update all `#stable` branches in all packages.
+	mrgit exec 'git checkout stable && git pull origin stable && git merge master && git checkout master'
 
 
-	# Make sure that `mgit.json` for `stable` and `master` branches is correct.
-	# `stable` branch.
-	git checkout stable && \
-	node ./scripts/release/update-mgit-branches stable && \
-	git commit -a -m "Internal: Use stable branches. [skip ci]"
-
-	# `master` branch.
-	git checkout master && \
-	git merge stable && \
-	node ./scripts/release/update-mgit-branches master && \
-	git commit -a -m "Internal: Use master branches. [skip ci]"
-
-	# Push the `stable` branches.
+	# Push the `#stable` branches.
 	git push origin stable master && \
 	git push origin stable master && \
-	mgit exec 'git push origin stable'
+	mrgit exec 'git push origin stable'
 
 
 	echo "Success! 🎂"
 	echo "Success! 🎂"
 fi
 fi

Plik diff jest za duży
+ 320 - 399
yarn.lock


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików