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

Merge branch 'master' into t/ckeditor5-angular/61

Maciej Bukowski 6 лет назад
Родитель
Сommit
cdf2c8881a
74 измененных файлов с 4815 добавлено и 954 удалено
  1. 5 5
      .travis.yml
  2. 248 0
      CHANGELOG.md
  3. 63 5
      README.md
  4. 1 1
      docs/_snippets/examples/classic-editor.html
  5. 1 1
      docs/_snippets/examples/multi-root-editor.js
  6. 0 0
      docs/_snippets/features/build-ui-language-source.html
  7. 12 0
      docs/_snippets/features/build-ui-language-source.js
  8. 5 0
      docs/_snippets/features/mathtype.html
  9. 28 0
      docs/_snippets/features/mathtype.js
  10. 4 0
      docs/_snippets/features/ui-language-content.html
  11. 25 0
      docs/_snippets/features/ui-language-content.js
  12. 4 0
      docs/_snippets/features/ui-language-rtl.html
  13. 23 0
      docs/_snippets/features/ui-language-rtl.js
  14. 1 1
      docs/_snippets/features/ui-language.html
  15. 2 5
      docs/_snippets/features/ui-language.js
  16. 12 0
      docs/_snippets/features/wproofreader.html
  17. 22 0
      docs/_snippets/features/wproofreader.js
  18. 361 0
      docs/_snippets/framework/tutorials/using-react-in-widget.html
  19. 175 0
      docs/_snippets/framework/tutorials/using-react-in-widget.js
  20. BIN
      docs/assets/img/builds-content-styles.png
  21. BIN
      docs/assets/img/fields.jpg
  22. BIN
      docs/assets/img/using-react-in-a-widget-1.png
  23. 54 12
      docs/builds/guides/faq.md
  24. 73 20
      docs/builds/guides/frameworks/angular.md
  25. 18 0
      docs/builds/guides/frameworks/css.md
  26. 288 211
      docs/builds/guides/frameworks/react.md
  27. 105 21
      docs/builds/guides/frameworks/vuejs.md
  28. 48 14
      docs/builds/guides/integration/advanced-setup.md
  29. 2 0
      docs/builds/guides/integration/basic-api.md
  30. 193 0
      docs/builds/guides/integration/content-styles.md
  31. 14 0
      docs/builds/guides/integration/saving-data.md
  32. 12 0
      docs/builds/guides/migrate.md
  33. 1 0
      docs/builds/guides/overview.md
  34. 1 1
      docs/builds/guides/support/browser-compatibility.md
  35. 0 22
      docs/builds/guides/support/getting-support.md
  36. 17 5
      docs/features/image-upload.md
  37. 71 0
      docs/features/math-equations.md
  38. 91 0
      docs/features/spelling-and-grammar-checking.md
  39. 70 21
      docs/features/ui-language.md
  40. 4 4
      docs/framework/guides/architecture/ui-library.md
  41. 2 2
      docs/framework/guides/contributing/contributing.md
  42. 29 18
      docs/framework/guides/contributing/development-environment.md
  43. 25 20
      docs/framework/guides/contributing/testing-environment.md
  44. 10 10
      docs/framework/guides/creating-simple-plugin.md
  45. 1 1
      docs/framework/guides/custom-editor-creator.md
  46. 6 2
      docs/framework/guides/development-tools.md
  47. 29 35
      docs/framework/guides/quick-start.md
  48. 7 7
      docs/framework/guides/tutorials/implementing-a-block-widget.md
  49. 6 6
      docs/framework/guides/tutorials/implementing-an-inline-widget.md
  50. 1306 0
      docs/framework/guides/tutorials/using-react-in-a-widget.md
  51. 21 4
      docs/umberto.json
  52. 9 3
      mrgit.json
  53. 73 61
      package.json
  54. 3 3
      scripts/bump-year.js
  55. 241 0
      scripts/docs/build-content-styles.js
  56. 6 1
      scripts/docs/build-docs.js
  57. 2 2
      scripts/docs/buildapi.js
  58. 76 0
      scripts/docs/content-styles/ckeditor.js
  59. 35 0
      scripts/docs/content-styles/list-content-styles.js
  60. 10 0
      scripts/docs/getrealimportpath.js
  61. 60 5
      scripts/docs/snippetadapter.js
  62. 0 39
      scripts/release/update-mgit-branches.js
  63. 7 19
      scripts/update-stable-branches.sh
  64. 33 0
      tests/manual/article.html
  65. 45 0
      tests/manual/article.js
  66. 3 0
      tests/manual/article.md
  67. 55 0
      tests/manual/mathtype.html
  68. 76 0
      tests/manual/mathtype.js
  69. 5 0
      tests/manual/mathtype.md
  70. BIN
      tests/manual/sample.jpg
  71. 69 0
      tests/manual/wproofreader.html
  72. 75 0
      tests/manual/wproofreader.js
  73. 24 0
      tests/manual/wproofreader.md
  74. 412 367
      yarn.lock

+ 5 - 5
.travis.yml

@@ -1,8 +1,10 @@
 sudo: required
 sudo: required
-dist: trusty
+dist: xenial
 addons:
 addons:
   chrome: stable
   chrome: stable
 language: node_js
 language: node_js
+services:
+- xvfb
 cache:
 cache:
   yarn: true
   yarn: true
 node_js:
 node_js:
@@ -11,12 +13,10 @@ cache:
 - node_modules
 - node_modules
 before_install:
 before_install:
 - export START_TIME=$( date +%s )
 - export START_TIME=$( date +%s )
-- export DISPLAY=:99.0
-- 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

+ 248 - 0
CHANGELOG.md

@@ -1,6 +1,254 @@
 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)).

+ 63 - 5
README.md

@@ -4,11 +4,9 @@ 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)
 
 
-[![Join the chat at https://gitter.im/ckeditor/ckeditor5](https://badges.gitter.im/ckeditor/ckeditor5.svg)](https://gitter.im/ckeditor/ckeditor5?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 [![Join newsletter](https://img.shields.io/badge/join-newsletter-00cc99.svg)](http://eepurl.com/c3zRPr)
 [![Join newsletter](https://img.shields.io/badge/join-newsletter-00cc99.svg)](http://eepurl.com/c3zRPr)
 [![Follow twitter](https://img.shields.io/badge/follow-twitter-00cc99.svg)](https://twitter.com/ckeditor)
 [![Follow twitter](https://img.shields.io/badge/follow-twitter-00cc99.svg)](https://twitter.com/ckeditor)
 
 
@@ -18,7 +16,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 +219,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>
@@ -233,6 +243,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/ckeditor-cloud-services-core"><code>@ckeditor/ckeditor-cloud-services-core</code></a>
+	</td>
+	<td>
+		<a href="https://www.npmjs.com/package/@ckeditor/ckeditor-cloud-services-core"><img src="https://img.shields.io/npm/v/@ckeditor/ckeditor-cloud-services-core.svg" alt="@ckeditor/ckeditor-cloud-services-core npm package badge"></a>
+	</td>
+	<td>
+		CKEditor Cloud Services integration utils.
+	</td>
+</tr>
+
 </tbody>
 </tbody>
 </table>
 </table>
 
 
@@ -479,6 +501,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-horizontal-rule"><code>@ckeditor/ckeditor5-horizontal-rule</code></a>
+	</td>
+	<td>
+		<a href="https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-rule"><img src="https://img.shields.io/npm/v/@ckeditor/ckeditor5-horizontal-rule.svg" alt="@ckeditor/ckeditor5-horizontal-rule npm package badge"></a>
+	</td>
+	<td>
+		The horizontal rule feature.
+	</td>
+</tr>
+
 <tr>
 <tr>
 	<td>
 	<td>
 		<a href="https://github.com/ckeditor/ckeditor5-image"><code>@ckeditor/ckeditor5-image</code></a>
 		<a href="https://github.com/ckeditor/ckeditor5-image"><code>@ckeditor/ckeditor5-image</code></a>
@@ -487,7 +521,19 @@ See CKEditor 5 release blog posts [on the CKEditor blog](https://ckeditor.com/bl
 		<a href="https://www.npmjs.com/package/@ckeditor/ckeditor5-image"><img src="https://img.shields.io/npm/v/@ckeditor/ckeditor5-image.svg" alt="@ckeditor/ckeditor5-image npm package badge"></a>
 		<a href="https://www.npmjs.com/package/@ckeditor/ckeditor5-image"><img src="https://img.shields.io/npm/v/@ckeditor/ckeditor5-image.svg" alt="@ckeditor/ckeditor5-image npm package badge"></a>
 	</td>
 	</td>
 	<td>
 	<td>
-		The image feature. Supports image styles and captioning.
+		The image feature. Supports image styles, captioning, upload, resizing, and more.
+	</td>
+</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>
 	</td>
 </tr>
 </tr>
 
 
@@ -623,6 +669,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 +776,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/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/multi-root-editor.js

@@ -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;

+ 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 );
+	} );

+ 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>

+ 2 - 5
docs/_snippets/features/ui-language.js

@@ -3,16 +3,13 @@
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  * 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 );
+	} );

+ 361 - 0
docs/_snippets/framework/tutorials/using-react-in-widget.html

@@ -0,0 +1,361 @@
+<style>
+/* assets/styles.css */
+
+/* --- General application styles --------------------------------------------------- */
+
+.app {
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+}
+
+.app textarea {
+	width: 100%;
+	height: 300px;
+	font-family: 'Courier New', Courier, monospace;
+	box-sizing: border-box;
+	font-size: 14px;
+}
+
+/* --- Product offer editor styles ----------------------------------------------------- */
+
+.app .app__offer-editor {
+	flex: 1 1 auto;
+}
+
+/* --- Generic product preview styles --------------------------------------------------- */
+
+.app .product-preview {
+	background-repeat: no-repeat;
+	background-position: center;
+	background-image: var(--product-image);
+	background-size: cover;
+	height: 120px;
+	position: relative;
+	overflow: hidden;
+	box-shadow: 1px 1px 3px hsla(0, 0%, 0%, .3);
+	min-width: 120px;
+}
+
+.app .product-preview .product-preview__name {
+	padding: 10px;
+	background: hsl(0, 0%, 100%);
+	font-weight: bold;
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	line-height: 1.5em;
+}
+
+.app .product-preview .product-preview__price {
+	position: absolute;
+	top: 0;
+	right: 0;
+	display: block;
+	background: hsl(346, 100%, 56%);
+	padding: 6px 10px;
+	min-width: 50px;
+	text-align: center;
+	color: hsl(0, 0%, 100%);
+	text-transform: uppercase;
+	font-size: .8em;
+	line-height: 1.5em;
+}
+
+.app .product-preview .product-preview__add {
+	display: none;
+}
+
+/* --- Product list styles --------------------------------------------------- */
+
+.app .app__product-list {
+	margin-left: 20px;
+	padding: 0 20px;
+	border-left: 1px solid hsl(0, 0%, 87%);
+}
+
+.app .app__product-list ul {
+	display: grid;
+	grid-template-columns: 1fr;
+	grid-gap: 10px;
+	list-style-type: none;
+	margin: 1.5em 0;
+	padding: 0;
+}
+
+.app .app__product-list .product-preview {
+	opacity: .7;
+}
+
+.app .app__product-list .product-preview:hover {
+	opacity: 1;
+}
+
+.app .app__product-list .product-preview:hover .product-preview__add {
+	display: block;
+}
+
+.app .app__product-list .product-preview .product-preview__add {
+	display: none;
+	position: absolute;
+	width: 40px;
+	height: 40px;
+	top: 45%;
+	left: 50%;
+
+	border: 0;
+	padding: 0;
+	cursor: pointer;
+	font-weight: bold;
+	text-align: center;
+	border-radius: 100px;
+	background: hsl(0, 0%, 100%);
+	transform: translate(-50%, -50%);
+	box-shadow: 2px 2px 2px hsla(0, 0%, 0%, .3);
+}
+
+.app .app__product-list .product-preview .product-preview__add span {
+	font-size: 25px;
+	vertical-align: middle;
+	color: hsl(0, 0%, 24%);
+	line-height: 40px;
+	display: inline-block;
+}
+
+.app .app__product-list .product-preview .product-preview__name {
+	font-size: 10px;
+}
+
+.app .app__product-list .product-preview .product-preview__price {
+	font-size: 10px;
+}
+
+/* --- In-editor product widget styles --------------------------------------------------- */
+
+.app .ck-content .product {
+	margin: 1em;
+	animation: slideUp 0.3s ease;
+}
+
+.app .ck-content .table td {
+	vertical-align: middle;
+}
+
+@keyframes slideUp {
+	0% {
+		opacity: 0;
+		transform: translateY(1em);
+	}
+	100% {
+		opacity: 1;
+		transform: translateY(0);
+	}
+}
+</style>
+
+<div id="snippet-react-in-widget">
+	<div class="app"></div>
+</div>
+
+<script type="text/babel">
+// react/productpreview.js
+
+class ProductPreview extends React.Component {
+	render() {
+		const style = {
+			'--product-image': `url(${ this.props.image })`
+		};
+
+		return <div
+			className="product-preview"
+			style={style}>
+				<button
+					className="product-preview__add"
+					onClick={() => this.props.onClick( this.props.id )}
+					title="Add to the offer"
+				>
+					<span>+</span>
+				</button>
+				<span className="product-preview__name">{this.props.name}</span>
+				<span className="product-preview__price">from {this.props.price}</span>
+			</div>
+	}
+}
+
+// react/productlist.js
+
+class ProductList extends React.Component {
+	render() {
+		return <div className="app__product-list">
+			<h3>Products</h3>
+			<ul>
+				{this.props.products.map( product => {
+					return <li key={product.id}>
+						<ProductPreview
+							id={product.id}
+							onClick={this.props.onClick}
+							{...product}
+						/>
+					</li>;
+				})}
+			</ul>
+			<p><b>Tip</b>: Clicking the product will add it to the editor.</p>
+		</div>;
+	}
+}
+
+// app.js
+
+// The React application class. It renders the editor and the product list.
+class App extends React.Component {
+	constructor( props ) {
+		super( props );
+
+		// A place to store the reference to the editor instance created by the <CKEditor> component.
+		// The editor instance is created asynchronously and only available when the editor is ready.
+		this.editor = null;
+
+		this.state = {
+			// The initial editor data. It is bound to the editor instance and will change as
+			// the user types and modifies the content of the editor.
+			editorData: '<h2>Check our last minute deals!</h2><p>The capital city of <a href="https://en.wikipedia.org/wiki/Malta">Malta</a> is the top destination this summer. It’s home to a cutting-edge contemporary architecture, baroque masterpieces, delicious local cuisine and at least 8 months of sun.</p><section class="product" data-id="2"></section><p>You’ll definitely love exploring <a href="https://en.wikipedia.org/wiki/Warsaw">Warsaw</a>! Best time to visit the city is July and August, when it’s cool enough to not break a sweat and hot enough to enjoy summer. The city which has quite a combination of both old and modern textures is located by the river of Vistula.</p><section class="product" data-id="1"></section><h3>Other destinations</h3><figure class="table"><table><thead><tr><th>Destination</th><th>Trip details</th></tr></thead><tbody><tr><td><section class="product" data-id="3"></section><p>&nbsp;</p></td><td>Getting used to an entirely different culture can be challenging. While it’s also nice to learn about cultures online or from books, nothing comes close to experiencing cultural diversity in person. You learn to appreciate each and every single one of the differences while you become more culturally fluid. <a href="http://ckeditor.com">Find out more...</a></td></tr><tr><td><section class="product" data-id="4"></section><p>&nbsp;</p></td><td>Tourists frequently admit that Taj Mahal "simply cannot be described with words". And that’s probably true. The more you try the more speechless you become. Words give only a semblance of truth. <a href="http://ckeditor.com">Find out more...</a></td></tr></tbody></table></figure>'
+		};
+
+		// The configuration of the <CKEditor> instance.
+		this.editorConfig = {
+			plugins: [
+				// A set of editor features to be enabled and available to the user.
+				Essentials, Heading, Bold, Italic, Underline,
+				Link, Paragraph, Table, TableToolbar,
+
+				// Our custom plugin implementing the widget is loaded here.
+				ProductPreviewEditing
+			],
+			toolbar: {
+				viewportTopOffset: window.getViewportTopOffsetConfig(),
+				items: [
+					'heading',
+					'|',
+					'bold', 'italic', 'underline',
+					'|',
+					'link', 'insertTable',
+					'|',
+					'undo', 'redo'
+				]
+			},
+			table: {
+				contentToolbar: [
+					'tableColumn',
+					'tableRow',
+					'mergeTableCells'
+				]
+			},
+			// The configuration of the Products plugin. It specifies a function that will allow
+			// the editor to render a React <ProductPreview> component inside a product widget.
+			products: {
+				productRenderer: ( id, domElement ) => {
+					const product = this.props.products.find( product => product.id === id );
+
+					ReactDOM.render(
+						<ProductPreview id={id} {...product} />,
+						domElement
+					);
+				}
+			}
+		};
+
+		this.handleEditorDataChange = this.handleEditorDataChange.bind( this );
+		this.handleEditorInit = this.handleEditorInit.bind( this );
+	}
+
+	// A handler executed when the user types or modifies the editor content.
+	// It updates the state of the application.
+	handleEditorDataChange( evt, editor ) {
+		this.setState( {
+			editorData: editor.getData()
+		} );
+	}
+
+	// A handler executed when the editor has been initialized and is ready.
+	// It synchronizes the initial data state and saves the reference to the editor instance.
+	handleEditorInit( editor ) {
+		this.editor = editor;
+
+		this.setState( {
+			editorData: editor.getData()
+		} );
+	}
+
+	render() {
+		return [
+			// The application renders two columns:
+			// * in the left one, the <CKEditor> is rendered and the textarea displaying
+			//   live editor data.
+			// * in the right column, a <ProductList> is rendered with available <ProductPreviews>
+			//   to choose from.
+			<div className="app__offer-editor" key="offer-editor">
+				<h3>Product offer editor</h3>
+				<CKEditor
+					editor={ClassicEditor}
+					data={this.state.editorData}
+					config={this.editorConfig}
+					onChange={this.handleEditorDataChange}
+					onInit={this.handleEditorInit}
+				/>
+
+				<h4>Editor data</h4>
+				<textarea value={this.state.editorData} readOnly={true}></textarea>
+			</div>,
+			<ProductList
+				key="product-list"
+				products={this.props.products}
+				onClick={( id ) => {
+					this.editor.execute( 'insertProduct', id );
+					this.editor.editing.view.focus();
+				}}
+			/>
+		];
+	}
+}
+
+// Render the <App> in the <div class="app"></div> element found in DOM.
+ReactDOM.render(
+	<App
+		// Feeding the application with pre–defined products.
+		// In a real-life application, this sort of data would be loaded
+		// from a database. To keep this tutorial simple, we're using
+		// a couple of hard–coded product definitions.
+		products={[
+			{
+				id: 1,
+				name: 'Colors of summer in Poland',
+				price: '$1500',
+				image: '../../../assets/img/fields.jpg'
+			},
+			{
+				id: 2,
+				name: 'Mediterranean Sun on Malta',
+				price: '$1899',
+				image: '../../../assets/img/malta.jpg'
+			},
+			{
+				id: 3,
+				name: 'Tastes of Asia',
+				price: '$2599',
+				image: '../../../assets/img/umbrellas.jpg'
+			},
+			{
+				id: 4,
+				name: 'Exotic india',
+				price: '$2200',
+				image: '../../../assets/img/tajmahal.jpg'
+			}
+		]}
+	/>,
+	document.querySelector( '.app' )
+);
+</script>

+ 175 - 0
docs/_snippets/framework/tutorials/using-react-in-widget.js

@@ -0,0 +1,175 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* global window */
+
+import Babel from 'babel-standalone';
+
+// Imports necessary to run a React application.
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+// The official <CKEditor> component for React.
+import CKEditor from '@ckeditor/ckeditor5-react';
+
+// The base editor class and features required to run the editor.
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
+import Heading from '@ckeditor/ckeditor5-heading/src/heading';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
+import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
+import Link from '@ckeditor/ckeditor5-link/src/link';
+import Table from '@ckeditor/ckeditor5-table/src/table';
+import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import Command from '@ckeditor/ckeditor5-core/src/command';
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import { toWidget } from '@ckeditor/ckeditor5-widget/src/utils';
+import Widget from '@ckeditor/ckeditor5-widget/src/widget';
+
+// ckeditor/productpreviewediting.js
+
+class ProductPreviewEditing extends Plugin {
+	static get requires() {
+		return [ Widget ];
+	}
+
+	init() {
+		this._defineSchema();
+		this._defineConverters();
+
+		this.editor.commands.add( 'insertProduct', new InsertProductPreviewCommand( this.editor ) );
+	}
+
+	_defineSchema() {
+		const schema = this.editor.model.schema;
+
+		schema.register( 'productPreview', {
+			// Behaves like a self-contained object (e.g. an image).
+			isObject: true,
+
+			// Allow in places where other blocks are allowed (e.g. directly in the root).
+			allowWhere: '$block',
+
+			// Each product preview has an id. An unique id tells the application which
+			// product it represents and makes it possible to render it inside a widget.
+			allowAttributes: [ 'id' ]
+		} );
+	}
+
+	_defineConverters() {
+		const editor = this.editor;
+		const conversion = editor.conversion;
+		const renderProduct = editor.config.get( 'products' ).productRenderer;
+
+		// <productPreview> converters ((data) view → model)
+		conversion.for( 'upcast' ).elementToElement( {
+			view: {
+				name: 'section',
+				classes: 'product'
+			},
+			model: ( viewElement, modelWriter ) => {
+				// Read the "data-id" attribute from the view and set it as "id" in the model.
+				return modelWriter.createElement( 'productPreview', {
+					id: parseInt( viewElement.getAttribute( 'data-id' ) )
+				} );
+			}
+		} );
+
+		// <productPreview> converters (model → data view)
+		conversion.for( 'dataDowncast' ).elementToElement( {
+			model: 'productPreview',
+			view: ( modelElement, viewWriter ) => {
+				// In the data view, the model <productPreview> corresponds to:
+				//
+				// <section class="product" data-id="..."></section>
+				return viewWriter.createEmptyElement( 'section', {
+					class: 'product',
+					'data-id': modelElement.getAttribute( 'id' )
+				} );
+			}
+		} );
+
+		// <productPreview> converters (model → editing view)
+		conversion.for( 'editingDowncast' ).elementToElement( {
+			model: 'productPreview',
+			view: ( modelElement, viewWriter ) => {
+				// In the editing view, the model <productPreview> corresponds to:
+				//
+				// <section class="product" data-id="...">
+				//     <div class="product__react-wrapper">
+				//         <ProductPreview /> (React component)
+				//     </div>
+				// </section>
+				const id = modelElement.getAttribute( 'id' );
+
+				// The outer-most <section class="product" data-id="..."></section> element.
+				const section = viewWriter.createContainerElement( 'section', {
+					class: 'product',
+					'data-id': id
+				} );
+
+				// The inner <div class="product__react-wrapper"></div> element.
+				// This element will host a React <ProductPreview /> component.
+				const reactWrapper = viewWriter.createUIElement( 'div', {
+					class: 'product__react-wrapper'
+				}, function( domDocument ) {
+					const domElement = this.toDomElement( domDocument );
+
+					// This the place where React renders the actual product preview hosted
+					// by a UIElement in the view. We're using a function (renderer) passed as
+					// editor.config.products#productRenderer.
+					renderProduct( id, domElement );
+
+					return domElement;
+				} );
+
+				viewWriter.insert( viewWriter.createPositionAt( section, 0 ), reactWrapper );
+
+				return toWidget( section, viewWriter, { label: 'product preview widget' } );
+			}
+		} );
+	}
+}
+
+// ckeditor/insertproductpreviewcommand.js
+
+class InsertProductPreviewCommand extends Command {
+	execute( id ) {
+		this.editor.model.change( writer => {
+			// Insert <productPreview id="...">*</productPreview> at the current selection position
+			// in a way which will result in creating a valid model structure.
+			this.editor.model.insertContent( writer.createElement( 'productPreview', { id } ) );
+		} );
+	}
+
+	refresh() {
+		const model = this.editor.model;
+		const selection = model.document.selection;
+		const allowedIn = model.schema.findAllowedParent( selection.getFirstPosition(), 'productPreview' );
+
+		this.isEnabled = allowedIn !== null;
+	}
+}
+
+Object.assign( window, {
+	Babel,
+	React,
+	ReactDOM,
+	CKEditor,
+	ClassicEditor,
+	Essentials,
+	Heading,
+	Bold,
+	Italic,
+	Underline,
+	Link,
+	Table,
+	TableToolbar,
+	Paragraph,
+	ProductPreviewEditing,
+	InsertProductPreviewCommand
+} );

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


BIN
docs/assets/img/fields.jpg


BIN
docs/assets/img/using-react-in-a-widget-1.png


+ 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 );
+} );
+```

+ 73 - 20
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,20 +290,20 @@ 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 */
@@ -260,7 +313,7 @@ First, create a (S)CSS file in the parent component's directory and style the gi
 }
 }
 ```
 ```
 
 
-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 */
@@ -283,7 +336,7 @@ To style the component using a global stylesheet, first, create it:
 }
 }
 ```
 ```
 
 
-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( {
@@ -446,7 +499,7 @@ The `UploadAdapter` class will be instantiated each time when CKEditor 5 needs i
 
 
 ## 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
 
 
@@ -492,4 +545,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.

+ 18 - 0
docs/builds/guides/frameworks/css.md

@@ -82,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:
@@ -123,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

+ 288 - 211
docs/builds/guides/frameworks/react.md

@@ -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
 
 
@@ -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;
@@ -175,14 +175,14 @@ Before you start modifying the webpack configuration, first install some CKEdito
 
 
 ```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
@@ -199,28 +199,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
+			} )
+		}
+	]
 },
 },
 ```
 ```
 
 
@@ -230,12 +230,12 @@ First, find a loader that starts its definition with the following code: `test:
 
 
 ```js
 ```js
 {
 {
-  test: cssRegex,
-  exclude: [
-    cssModuleRegex,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  ],
-  // (...)
+	test: cssRegex,
+	exclude: [
+		cssModuleRegex,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
+	],
+	// (...)
 }
 }
 ```
 ```
 
 
@@ -243,11 +243,11 @@ Below it, you will find another loader that handles CSS files. You need to disab
 
 
 ```js
 ```js
 {
 {
-  test: cssModuleRegex,
-  exclude: [
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  ],
-  // (...)
+	test: cssModuleRegex,
+	exclude: [
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
+	],
+	// (...)
 }
 }
 ```
 ```
 
 
@@ -255,21 +255,21 @@ Finally, exclude CKEditor 5 SVG and CSS files from `file-loader` . Find the last
 
 
 ```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|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]',
+	}
 }
 }
 ```
 ```
 
 
@@ -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;
@@ -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.

+ 105 - 21
docs/builds/guides/frameworks/vuejs.md

@@ -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,6 +249,22 @@ 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
+				} );
+			} );
 	}
 	}
 };
 };
 ```
 ```
@@ -278,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.
@@ -384,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`

+ 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%);
+}
+```

+ 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).

+ 12 - 0
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>

+ 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.

+ 0 - 22
docs/builds/guides/support/getting-support.md

@@ -19,28 +19,6 @@ Refer to {@link builds/guides/support/reporting-issues Reporting issues} guide f
 
 
 Make sure to tag your questions with ["ckeditor"](https://stackoverflow.com/questions/tagged/ckeditor) and ["ckeditor5"](https://stackoverflow.com/questions/tagged/ckeditor5) to reach the widest audience.
 Make sure to tag your questions with ["ckeditor"](https://stackoverflow.com/questions/tagged/ckeditor) and ["ckeditor5"](https://stackoverflow.com/questions/tagged/ckeditor5) to reach the widest audience.
 
 
-## Gitter
-
-[CKEditor 5 Gitter channel](https://gitter.im/ckeditor/ckeditor5) is the place where you can discuss all matters that do not fit GitHub or Stack Overflow.
-
-Gitter is convenient for asking quick questions, however, it is not the best place for more complex topics which might interest other developers (Gitter logs are indexed via Google but rather poorly). Therefore, try to avoid lengthy discussions on topics which would make sense to be reported either on GitHub or Stack Overflow.
-
-DOs:
-
-* Is it a known bug that "..."?
-* Do you plan to tag the new release this week?
-* I can't find XYZ's documentation. Is it available somewhere?
-* I'm in Warsaw. Anyone for a coffee?
-
-DON'Ts:
-
-* How to extend the selection to the end of the block?
-* Could you implement support for XYZ?
-* I can't make X and Y work together in my app. I developed this plugin and...
-* The editor crashes if I press <kbd>Enter</kbd>. Please help.
-
-And most importantly, be kind to everyone.
-
 ## Commercial support
 ## Commercial support
 
 
 CKEditor 5 also comes with commercial licensing benefits, such as direct support from the core CKEditor development team. Commercial licenses are designed with professionals and enterprises in mind.
 CKEditor 5 also comes with commercial licensing benefits, such as direct support from the core CKEditor development team. Commercial licenses are designed with professionals and enterprises in mind.

+ 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/math-equations.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/spelling-and-grammar-checking.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();
 
 

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

@@ -14,7 +14,7 @@ Before you start, here are some things to keep in mind:
 * We expect contributions to follow the high-quality code standards that we follow, including [coding style](#code-style) and [tests](#tests). Lack of attention to this point may either make it slow to adopt a contribution or even force us to reject it altogether.
 * We expect contributions to follow the high-quality code standards that we follow, including [coding style](#code-style) and [tests](#tests). Lack of attention to this point may either make it slow to adopt a contribution or even force us to reject it altogether.
 * There is no guarantee that your contribution will be incorporated into the project code. Still, pull requests make it easy for you to keep them for your own use or for others who may be interested in them.
 * There is no guarantee that your contribution will be incorporated into the project code. Still, pull requests make it easy for you to keep them for your own use or for others who may be interested in them.
 * If you plan to start working on a bigger task, it might be worth asking the core team (beforehand) whether a specific feature or a solution to an issue will be accepted.
 * If you plan to start working on a bigger task, it might be worth asking the core team (beforehand) whether a specific feature or a solution to an issue will be accepted.
-* If you need any assistance when creating a patch or implementing a feature, ping us under the ticket or on [Gitter](https://gitter.im/ckeditor/ckeditor5).
+* If you need any assistance when creating a patch or implementing a feature, ping us under the ticket.
 * [Having a CLA](#contributor-license-agreement-cla) is essential to have your contributions accepted.
 * [Having a CLA](#contributor-license-agreement-cla) is essential to have your contributions accepted.
 
 
 ### Setting up the development environment
 ### Setting up the development environment
@@ -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

+ 29 - 18
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}.
 
 
@@ -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:

+ 25 - 20
docs/framework/guides/contributing/testing-environment.md

@@ -11,46 +11,51 @@ Before reading this article we recommend getting familiar with the CKEditor 5 {@
 
 
 The CKEditor 5 testing environment uses a popular setup with [Karma](https://karma-runner.github.io), [webpack](https://webpack.github.io/), [babel-loader](https://github.com/babel/babel-loader) and [Istanbul](https://github.com/gotwarlost/istanbul). We created some [npm scripts](https://docs.npmjs.com/cli/run-script) which glue all these pieces and special requirements for CKEditor together.
 The CKEditor 5 testing environment uses a popular setup with [Karma](https://karma-runner.github.io), [webpack](https://webpack.github.io/), [babel-loader](https://github.com/babel/babel-loader) and [Istanbul](https://github.com/gotwarlost/istanbul). We created some [npm scripts](https://docs.npmjs.com/cli/run-script) which glue all these pieces and special requirements for CKEditor together.
 
 
-Each CKEditor package has its own tests suite (see for example the [engine's tests](https://github.com/ckeditor/ckeditor5-engine/tree/master/tests)), however, the test runner is available in the [`ckeditor5`](https://github.com/ckeditor/ckeditor5) package which is the central development environment. The actual code of the test runner is implemented in the [`@ckeditor/ckeditor5-dev-tests`](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-tests) package and can be easily reused outside of `ckeditor5`.
+Each CKEditor 5 package has its own tests suite (see for example the [engine's tests](https://github.com/ckeditor/ckeditor5-engine/tree/master/tests)), however, the test runner is available in the [`ckeditor5`](https://github.com/ckeditor/ckeditor5) package which is the central development environment. The actual code of the test runner is implemented in the [`@ckeditor/ckeditor5-dev-tests`](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-tests) package and can be easily reused outside of `ckeditor5`.
 
 
 ## Running automated tests
 ## Running automated tests
 
 
-In order to run the automated tests use the `yarn run test [<args>...]` command.
+In order to run the automated tests, use the `yarn run test [<args>...]` command.
 
 
-It accepts the following arguments (must be passed after the `--` option):
+It accepts the following arguments that must be passed after the `--` option:
 
 
 * `--watch` (alias `-w`) &ndash; Whether to watch the files and execute tests whenever any file changes.
 * `--watch` (alias `-w`) &ndash; Whether to watch the files and execute tests whenever any file changes.
-* `--source-map` (alias `-s`) &ndash; Whether to generate the source maps.
+* `--source-map` (alias `-s`) &ndash; Whether to generate useful source maps for the code.
 * `--coverage` (alias `-c`) &ndash; Whether to generate code coverage.
 * `--coverage` (alias `-c`) &ndash; Whether to generate code coverage.
 * `--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).
-* `--browsers` &ndash; Browsers which will be used to run the tests. Defaults to `Chrome`.
+* `--files` &ndash; Specifies test 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 that 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. Note that by default `--debug` is set to `true` even if you did not specify it. This enables the base set of debug logs (`// @if CK_DEBUG //`) which should always be enabled in the testing environment. You can completely turn off the debug mode by setting the `--debug false` option.
 
 
 ### Examples
 ### Examples
 
 
 Run all tests with the code coverage check of the [`ckeditor5-core`](https://github.com/ckeditor/ckeditor5-core) package:
 Run all tests with the code coverage check of the [`ckeditor5-core`](https://github.com/ckeditor/ckeditor5-core) package:
 
 
-```
+```bash
 yarn run test -c --files=core
 yarn run test -c --files=core
 ```
 ```
 
 
 Run and watch the [engine's `view` namespace tests](https://github.com/ckeditor/ckeditor5-engine/tree/master/tests/view) and all the tests in [`ckeditor5-typing`](https://github.com/ckeditor/ckeditor5-typing):
 Run and watch the [engine's `view` namespace tests](https://github.com/ckeditor/ckeditor5-engine/tree/master/tests/view) and all the tests in [`ckeditor5-typing`](https://github.com/ckeditor/ckeditor5-typing):
 
 
-```
+```bash
 yarn run test -cw --files=engine/view,typing
 yarn run test -cw --files=engine/view,typing
 ```
 ```
 
 
 Run the `bold*.js` tests in the [`ckeditor5-basic-styles`](https://github.com/ckeditor/ckeditor5-basic-styles) package:
 Run the `bold*.js` tests in the [`ckeditor5-basic-styles`](https://github.com/ckeditor/ckeditor5-basic-styles) package:
 
 
-```
+```bash
 yarn run test -cw --files=basic-styles/bold*.js
 yarn run test -cw --files=basic-styles/bold*.js
 ```
 ```
 
 
 ## Running manual tests
 ## Running manual tests
 
 
-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 following options:
 
 
-The task accepts the `--source-map` (alias `-s`) option.
+* `--source-map` (alias `-s`) &ndash; Whether to generate useful source maps for the code.
+* `--additionalLanguages="ar,pl,..."` &ndash; Specifies extra languages to the [CKEditor 5 webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin). Check out the {@link features/ui-language UI language guide} to learn more.
+* `--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. Note that by default `--debug` is set to `true` even if you did not specify it. This enables the base set of debug logs (`// @if CK_DEBUG //`) which should always be enabled in the testing environment. You can completely turn off the debug mode by setting the `--debug false` option.
 
 
 It starts the server available at http://localhost:8125.
 It starts the server available at http://localhost:8125.
 
 
@@ -60,16 +65,16 @@ A manual test consists of 3 files:
 
 
 * A `<name>.md` file with the test description.
 * A `<name>.md` file with the test description.
 * A `<name>.js` file with the JavaScript part of the test (e.g. the code initializing an editor).
 * A `<name>.js` file with the JavaScript part of the test (e.g. the code initializing an editor).
-* A `<name>.html` file with the HTML part of the test. It does not need to be an entire HTML page (with the doctype, etc.), it can be just these HTML elements that you want to define.
+* A `<name>.html` file with the HTML part of the test. It does not need to be an entire HTML page (with the doctype, etc.). It can include just the HTML elements that you want to define.
 
 
 All 3 files are combined together and create a single manual test.
 All 3 files are combined together and create a single manual test.
 
 
-Example Markdown file:
+An example Markdown file:
 
 
 ```md
 ```md
 ## Create a new link
 ## Create a new link
 
 
-1. Select a fragment of regular text.
+1. Select a fragment of the regular text.
 2. Click the toolbar "Link" button.
 2. Click the toolbar "Link" button.
 3. Check if the balloon panel attached to the selection appeared.
 3. Check if the balloon panel attached to the selection appeared.
 4. Fill in the "Link URL" input in the panel.
 4. Fill in the "Link URL" input in the panel.
@@ -77,14 +82,14 @@ Example Markdown file:
 6. Check if the selected text is converted into a link.
 6. Check if the selected text is converted into a link.
 ```
 ```
 
 
-Example HTML file:
+An example HTML file:
 
 
 ```html
 ```html
 <head>
 <head>
     <style>
     <style>
         /*
         /*
           Some additional styles which this test needs.
           Some additional styles which this test needs.
-          And yes – the test builder will merge this tag with the head defined in a template.
+          And yes – the test builder will merge this tag with the head defined in the template.
         */
         */
     </style>
     </style>
 </head>
 </head>
@@ -92,7 +97,7 @@ Example HTML file:
 <div id="editor">...</div>
 <div id="editor">...</div>
 ```
 ```
 
 
-Example JavaScript file:
+An example JavaScript file:
 
 
 ```js
 ```js
 /* globals console, window, document */
 /* globals console, window, document */
@@ -123,10 +128,10 @@ ClassicEditor
 
 
 ## Test suite and CI
 ## Test suite and CI
 
 
-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 September 2019, this means over 11000 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 allows 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.
 
 
-When proposing a pull request make sure to add test(s) which verifies it. Every code change should be accompanied by a test which proves that it is needed. Such a strict approach to testing ensures that we have not only 100% of code coverage (which is quite easy to achieve and gives only illusory safety) but also a high level of coverage for cases which we failed to notice initially (and might do that again in the future).
+When proposing a pull request make sure to add test(s) that verifies it. Every code change should be accompanied by a test which proves that it is needed. Such a strict approach to testing ensures that we have not only 100% of code coverage (which is quite easy to achieve and gives only illusory safety) but also a high level of coverage for cases that we failed to notice initially (and might do that again in the future).

+ 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

+ 6 - 2
docs/framework/guides/development-tools.md

@@ -60,8 +60,8 @@ You can specify the name of the editor when attaching to make working with multi
 
 
 ```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.
@@ -72,6 +72,10 @@ Click the <b>"Inspect editor"</b> button below to attach the inspector to the ed
 
 
 {@snippet framework/development-tools/inspector}
 {@snippet framework/development-tools/inspector}
 
 
+## Compatibility
+
+The inspector works with CKEditor 5 [v12.0.0](https://github.com/ckeditor/ckeditor5/releases/tag/v12.0.0)+.
+
 ### Contributing to the inspector
 ### Contributing to the inspector
 
 
 The source code of CKEditor 5 inspector and its issue tracker is available on GitHub in https://github.com/ckeditor/ckeditor5-inspector.
 The source code of CKEditor 5 inspector and its issue tracker is available on GitHub in https://github.com/ckeditor/ckeditor5-inspector.

+ 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}.

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

@@ -5,7 +5,7 @@ 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. 
+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.
 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.
 
 
@@ -29,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 \
@@ -65,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'
 						}
 						}
 					},
 					},
 					{
 					{

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

@@ -25,9 +25,9 @@ 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 \
@@ -66,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'
 						}
 						}
 					},
 					},
 					{
 					{

+ 1306 - 0
docs/framework/guides/tutorials/using-react-in-a-widget.md

@@ -0,0 +1,1306 @@
+---
+menu-title: Using React component in a widget
+category: framework-tutorials
+order: 10
+---
+
+# Using React component in a block widget
+
+In this tutorial, you will learn how to implement an editor plugin that uses the power of the [React](https://reactjs.org/) library inside the CKEditor 5 widget ecosystem. We will build a "Product preview" feature which renders an actual React component inside the editor to display some useful information about the product.
+
+Later on, we will use the "Product preview" feature to build a simple React application that displays an editor next to the list of available products, allowing the user to insert the product in the editor content by clicking it on the list.
+
+<info-box>
+	If you want to see the final product of this tutorial before you plunge in, check out the [demo](#demo).
+</info-box>
+
+<!-- TODO: dynamic controls in React to change the appearance of the widget https://github.com/ckeditor/ckeditor5-widget/issues/81 -->
+
+## Before you start
+
+There are a couple of things you should know before we start:
+
+* Since you are here, we assume you probably have at least some basic understanding of what React is and how it works. But what you might not know is that CKEditor 5 has an official {@link builds/guides/frameworks/react **Rich text editor component for React**} and it will be one of the key features used in this tutorial. Learning how to {@link builds/guides/frameworks/react#integrating-ckeditor-5-built-from-source use it in your project} is a good place to start.
+* In this tutorial, we are going to implement a block editor widget and that itself could give you an headache. We recommend you at least skim through the {@link framework/guides/tutorials/implementing-a-block-widget Implementing a block widget} tutorial to get a grip on editor widgets, their API and possible use–cases.
+* Also, 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.
+* 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.
+
+## Let's start
+
+This guide assumes that you are familiar with [yarn](https://yarnpkg.com) and your project uses yarn already. If not, see the [yarn documentation](https://yarnpkg.com/en/docs/getting-started). If you are using [npm](https://www.npmjs.com/get-npm) you do not have to worry — you can perform the same installation tasks just as easily using [corresponding npm commands](https://docs.npmjs.com/getting-packages-from-the-registry).
+
+First, install packages needed to build and set up a basic React application with a CKEditor 5 instance.
+
+```
+yarn add --dev \
+	@babel/cli \
+	@babel/core \
+	@babel/preset-react \
+	@ckeditor/ckeditor5-basic-styles \
+	@ckeditor/ckeditor5-build-classic \
+	@ckeditor/ckeditor5-core \
+	@ckeditor/ckeditor5-dev-utils \
+	@ckeditor/ckeditor5-editor-classic \
+	@ckeditor/ckeditor5-essentials \
+	@ckeditor/ckeditor5-heading \
+	@ckeditor/ckeditor5-inspector \
+	@ckeditor/ckeditor5-link \
+	@ckeditor/ckeditor5-paragraph \
+	@ckeditor/ckeditor5-react \
+	@ckeditor/ckeditor5-table \
+	@ckeditor/ckeditor5-theme-lark \
+	@ckeditor/ckeditor5-ui \
+	@ckeditor/ckeditor5-widget \
+	babel-loader \
+	css-loader \
+	postcss-loader@3 \
+	raw-loader@3 \
+	react \
+	react-dom \
+	style-loader@1 \
+	webpack@4 \
+	webpack-cli@3
+```
+
+Create a minimal [webpack](https://webpack.js.org) configuration and save it as `webpack.config.js` in the root of the application. To learn more about using webpack with CKEditor 5 and React, check out the {@link builds/guides/frameworks/react#integrating-ckeditor-5-built-from-source "Integrating CKEditor 5 built from source"} section of the CKEditor 5 React component guide.
+
+```js
+// webpack.config.js
+
+const webpack = require( 'webpack' );
+const path = require( 'path' );
+const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
+
+module.exports = {
+	entry: path.resolve( __dirname, 'app.js' ),
+
+	output: {
+		path: path.resolve( __dirname, 'dist' ),
+		filename: 'bundle.js'
+	},
+
+	module: {
+		rules: [
+			{
+				test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+				use: [ 'raw-loader' ]
+			},
+			{
+				test: /\.js$/,
+				exclude: /node_modules/,
+				loader: 'babel-loader',
+				query: {
+					presets: [ '@babel/react' ]
+				}
+			},
+			{
+				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
+						} )
+					}
+				]
+			}
+		]
+	},
+
+	// Useful for debugging.
+	devtool: 'source-map',
+
+	// By default webpack logs warnings if the bundle is bigger than 200kb.
+	performance: { hints: false }
+};
+```
+
+Create your project's entry point and save it as `app.js`, also in the root of the application:
+
+```js
+// app.js
+
+// Imports necessary to run a React application.
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+// The React application class.
+class App extends React.Component {
+	render() {
+		return 'Hello world!';
+	}
+}
+
+// Render the <App> in the <div class="app"></div> element found in DOM.
+ReactDOM.render(
+	<App />,
+	document.querySelector( '.app' )
+);
+```
+
+And an `index.html` page next to the `app.js` file:
+
+```html
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<title>Using React components in CKEditor 5 widgets</title>
+	</head>
+	<body>
+		<div class="app"></div>
+		<script src="dist/bundle.js"></script>
+	</body>
+</html>
+```
+
+Finally, build your project and see if everything worked well by opening the index page in your browser:
+
+```
+oleq@MBP15 ckeditor5-react-in-widgets> node_modules/.bin/webpack --mode development
+Hash: f46cba995690347de4cf
+Version: webpack 4.29.6
+Time: 896ms
+Built at: 04/11/2019 12:43:26 PM
+        Asset      Size  Chunks                    Chunk Names
+    bundle.js   881 KiB    main  [emitted]  [big]  main
+bundle.js.map  1020 KiB    main  [emitted]         main
+Entrypoint main [big] = bundle.js bundle.js.map
+[./app.js] 391 bytes {main} [built]
+[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
+    + 11 hidden modules
+```
+
+You should see a "Hello world" application in your web browser, which might not be much but it is a good start:
+
+{@img assets/img/using-react-in-a-widget-1.png Screenshot of the "Hello world" application in web browser.}
+
+## Application structure
+
+Nothing warms the heart of a developer like a good "Hello world!". But you probably agree that what we created is not the most useful application and it is time to change that. In the next chapters, we will create a couple of React components and CKEditor 5 classes to bring some real logic to the application.
+
+To keep some order in the project, we will put [CKEditor classes](#ckeditor-classes) in the `/ckeditor` directory and [React components](#react-components) in the `/react` directory. [Images and CSS styles](#styles-and-assets) will land in the `/assets` directory. By the time you are finished with this tutorial, the structure of the project should look as follows:
+
+```
+├── app.js
+├── assets
+│   ├── product1.jpg
+│   ├── product2.jpg
+│   ├── product3.jpg
+│   ├── product4.jpg
+│   └── styles.css
+├── ckeditor
+│   ├── insertproductpreviewcommand.js
+│   └── productpreviewediting.js
+├── dist
+│   ├── bundle.js
+│   └── bundle.js.map
+├── index.html
+├── package.json
+├── react
+│   ├── productlist.js
+│   └── productpreview.js
+├── node_modules
+└── webpack.config.js
+```
+
+## CKEditor classes
+
+Let us create the "CKEditor–side" logic that supports product preview widgets in the editor content:
+
+* The [`ProductPreviewEditing`](#editing-plugin) plugin will extend the editor data–layers to support the new kind of content.
+* The [`InsertProductPreviewCommand`](#command) provides an easy way for the "outside world" to insert product previews into editor content.
+
+<info-box>
+	This guide assumes you are familiar with the {@link framework/guides/tutorials/implementing-a-block-widget Implementing a block widget} guide which explains the basic concepts behind data structures and widgets. If in doubt, please refer to that guide for more information.
+</info-box>
+
+### Editing plugin
+
+The `ProductPreviewEditing` plugin defines the `productPreview` element in the editor {@link framework/guides/architecture/editing-engine#model model} and specifies the way it converts to the editing and data {@link framework/guides/architecture/editing-engine#view views}.
+
+<info-box>
+	Read more about the {@link framework/guides/architecture/editing-engine#overview editing engine architecture}.
+</info-box>
+
+* In the **data view**, the `productPreview` is represented as an empty `<section class="product" data-id="..."></section>` with a `data-id` attribute associating it with a particular product. A semantic representation of the product saved in the database can be then consumed in the front–end by retrieving a fresh preview using the `data-id`. Since it does not carry any formatting or styling, the data representation will never get outdated, even if the layout or styles of the application change in the future.
+* In the **editing view**, on the other hand, the product preview is a {@link framework/guides/tutorials/implementing-a-block-widget block widget}, which acts as a self–contained piece of content the user can insert, copy, and paste as a whole but they cannot change its internal structure. Inside the widget, there is a {@link module:engine/view/uielement~UIElement `UIElement`} with a `.product__react-wrapper` class that hosts a React `<ProductPreview>` component. Each time the model element is upcasted, the rendering function specified in the {@link builds/guides/integration/configuration editor configuration} (`editor.config.products.productRenderer`) mounts a React component inside the `UIElement`.
+
+<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.
+</info-box>
+
+The differences in data representations of the product preview are summarized in the following table:
+
+<table>
+	<tr>
+		<th>Data structure</th>
+		<th>Representation</th>
+	</tr>
+	<tr>
+		<td>Model</td>
+		<td>
+			<pre><code>&lt;productPreview id="..." /></code></pre>
+		</td>
+	</tr>
+	<tr>
+		<td>Editing view</td>
+		<td>
+			<pre><code>&lt;section class="product" data-id="...">
+	&lt;div class="product__react-wrapper">
+		&lt;ProductPreview /> // React component
+	&lt;/div>
+&lt;/section></code></pre>
+		</td>
+	</tr>
+	<tr>
+		<td>Data view (editor output)</td>
+		<td>
+			<pre><code>&lt;section class="product" data-id="...">&lt;/section></code></pre>
+		</td>
+	</tr>
+</table>
+
+Here is the full source code of the `ProductPreviewEditing` editor plugin:
+
+```js
+// ckeditor/productpreviewediting.js
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import { toWidget } from '@ckeditor/ckeditor5-widget/src/utils';
+import Widget from '@ckeditor/ckeditor5-widget/src/widget';
+import InsertProductPreviewCommand from './insertproductpreviewcommand';
+
+export default class ProductPreviewEditing extends Plugin {
+	static get requires() {
+		return [ Widget ];
+	}
+
+	init() {
+		this._defineSchema();
+		this._defineConverters();
+
+		this.editor.commands.add( 'insertProduct', new InsertProductPreviewCommand( this.editor ) );
+	}
+
+	_defineSchema() {
+		const schema = this.editor.model.schema;
+
+		schema.register( 'productPreview', {
+			// Behaves like a self-contained object (e.g. an image).
+			isObject: true,
+
+			// Allow in places where other blocks are allowed (e.g. directly in the root).
+			allowWhere: '$block',
+
+			// Each product preview has an id. An unique id tells the application which
+			// product it represents and makes it possible to render it inside a widget.
+			allowAttributes: [ 'id' ]
+		} );
+	}
+
+	_defineConverters() {
+		const editor = this.editor;
+		const conversion = editor.conversion;
+		const renderProduct = editor.config.get( 'products.productRenderer' );
+
+		// <productPreview> converters ((data) view → model)
+		conversion.for( 'upcast' ).elementToElement( {
+			view: {
+				name: 'section',
+				classes: 'product'
+			},
+			model: ( viewElement, modelWriter ) => {
+				// Read the "data-id" attribute from the view and set it as "id" in the model.
+				return modelWriter.createElement( 'productPreview', {
+					id: parseInt( viewElement.getAttribute( 'data-id' ) )
+				} );
+			}
+		} );
+
+		// <productPreview> converters (model → data view)
+		conversion.for( 'dataDowncast' ).elementToElement( {
+			model: 'productPreview',
+			view: ( modelElement, viewWriter ) => {
+				// In the data view, the model <productPreview> corresponds to:
+				//
+				// <section class="product" data-id="..."></section>
+				return viewWriter.createEmptyElement( 'section', {
+					class: 'product',
+					'data-id': modelElement.getAttribute( 'id' )
+				} );
+			}
+		} );
+
+		// <productPreview> converters (model → editing view)
+		conversion.for( 'editingDowncast' ).elementToElement( {
+			model: 'productPreview',
+			view: ( modelElement, viewWriter ) => {
+				// In the editing view, the model <productPreview> corresponds to:
+				//
+				// <section class="product" data-id="...">
+				//     <div class="product__react-wrapper">
+				//         <ProductPreview /> (React component)
+				//     </div>
+				// </section>
+				const id = modelElement.getAttribute( 'id' );
+
+				// The outer-most <section class="product" data-id="..."></section> element.
+				const section = viewWriter.createContainerElement( 'section', {
+					class: 'product',
+					'data-id': id
+				} );
+
+				// The inner <div class="product__react-wrapper"></div> element.
+				// This element will host a React <ProductPreview /> component.
+				const reactWrapper = viewWriter.createUIElement( 'div', {
+					class: 'product__react-wrapper'
+				}, function( domDocument ) {
+					const domElement = this.toDomElement( domDocument );
+
+					// This the place where React renders the actual product preview hosted
+					// by a UIElement in the view. We're using a function (renderer) passed as
+					// editor.config.products#productRenderer.
+					renderProduct( id, domElement );
+
+					return domElement;
+				} );
+
+				viewWriter.insert( viewWriter.createPositionAt( section, 0 ), reactWrapper );
+
+				return toWidget( section, viewWriter, { label: 'product preview widget' } );
+			}
+		} );
+	}
+}
+```
+
+### Command
+
+The `InsertProductPreviewCommand` inserts the `productPreview` element into the model at the current selection position. It is executed by the `<ProductPreview>` React component in the application sidebar to insert a widget into the editor content.
+
+Learn more about widget commands in the {@link framework/guides/tutorials/implementing-a-block-widget#creating-a-command "Implementing a block widget"} guide. See this command in action in the section about the [main application component](#main-application-component).
+
+```js
+// ckeditor/insertproductpreviewcommand.js
+
+import Command from '@ckeditor/ckeditor5-core/src/command';
+
+export default class InsertProductPreviewCommand extends Command {
+	execute( id ) {
+		this.editor.model.change( writer => {
+			// Insert <productPreview id="...">*</productPreview> at the current selection position
+			// in a way which will result in creating a valid model structure.
+			this.editor.model.insertContent( writer.createElement( 'productPreview', { id } ) );
+		} );
+	}
+
+	refresh() {
+		const model = this.editor.model;
+		const selection = model.document.selection;
+		const allowedIn = model.schema.findAllowedParent( selection.getFirstPosition(), 'productPreview' );
+
+		this.isEnabled = allowedIn !== null;
+	}
+}
+```
+
+## React components
+
+It is time to define the React–side of the application that renders the actual layout:
+
+* The [`<ProductList>`](#product-list) component displays a bunch of `<ProductPreview>` children and allows the user to click them to insert them into the editor.
+* The [`<ProductPreview>`](#product-preview) component represents a single product with its name, price tag and a background image.
+* The [`<App>`](#main-application-component) component glues all the things together.
+
+### Product list
+
+The `<ProductList>` React component renders instances of `<ProductPreview>`. When clicked, the preview executes a callback passed in ["props"](https://reactjs.org/docs/components-and-props.html) that inserts its own copy into the editor content by executing the [`'insertProduct'`](#command) editor command. The list is displayed in the sidebar of the [application](#main-application-component).
+
+```jsx
+// react/productlist.js
+
+import React from 'react';
+import ProductPreview from './productpreview';
+
+export default class ProductList extends React.Component {
+	render() {
+		return <div className="app__product-list">
+			<h3>Products</h3>
+			<ul>
+				{this.props.products.map( product => {
+					return <li key={product.id}>
+						<ProductPreview
+							id={product.id}
+							onClick={this.props.onClick}
+							{...product}
+						/>
+					</li>;
+				})}
+			</ul>
+			<p><b>Tip</b>: Clicking the product will add it to the editor.</p>
+		</div>;
+	}
+}
+```
+
+### Product preview
+
+The actual preview of the product, with its name, price and an image. Instances of the `<ProductPreview>` component populate both the [`<ProductList>`](#product-list) and the [editor widgets](#editing-plugin) in the content.
+
+Clicking a preview in the sidebar executes the [`'insertProduct'`](#command) editor command and inserts the same preview in the editor content.
+
+```jsx
+// react/productpreview.js
+
+import React from 'react';
+
+export default class ProductPreview extends React.Component {
+	render() {
+		const style = {
+			'--product-image': `url(${ this.props.image })`
+		};
+
+		return <div
+			className="product-preview"
+			style={style}>
+				<button
+					className="product-preview__add"
+					onClick={() => this.props.onClick( this.props.id )}
+					title="Add to the offer"
+				>
+					<span>+</span>
+				</button>
+				<span className="product-preview__name">{this.props.name}</span>
+				<span className="product-preview__price">from {this.props.price}</span>
+			</div>
+	}
+}
+```
+
+### Main application component
+
+So far, we have CKEditor classes that bring the product preview in to the content, a list of products and a product component ready. It is time to glue things together in the `App` class.
+
+We are going to extend the [main application file](#lets-start) skeleton that we created earlier in this tutorial so it renders the {@link builds/guides/frameworks/react official `<CKEditor>` React component} on the left side, and the list of available products on the right.
+
+Let us have a look at the full source code of the `App` class:
+
+```jsx
+// app.js
+
+// Imports necessary to run a React application.
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+// The official <CKEditor> component for React.
+import CKEditor from '@ckeditor/ckeditor5-react';
+
+// The official CKEditor 5 instance inspector, helps understand the editor view and model.
+import CKEditorInspector from '@ckeditor/ckeditor5-inspector';
+
+// The base editor class and features required to run the editor.
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
+import Heading from '@ckeditor/ckeditor5-heading/src/heading';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
+import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
+import Link from '@ckeditor/ckeditor5-link/src/link';
+import Table from '@ckeditor/ckeditor5-table/src/table';
+import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+
+// CKEditor plugin implementing a product widget to be used in editor content.
+import ProductPreviewEditing from './ckeditor/productpreviewediting';
+
+// React components to render the list of product and the product preview.
+import ProductList from './react/productlist';
+import ProductPreview from './react/productpreview';
+
+// The React application class. It renders the editor and the product list.
+class App extends React.Component {
+	constructor( props ) {
+		super( props );
+
+		// A place to store the reference to the editor instance created by the <CKEditor> component.
+		// The editor instance is created asynchronously and only available when the editor is ready.
+		this.editor = null;
+
+		this.state = {
+			// The initial editor data. It is bound to the editor instance and will change as
+			// the user types and modifies the content of the editor.
+			editorData: '<h2>Check our last minute deals!</h2><p>The capital city of <a href="https://en.wikipedia.org/wiki/Malta">Malta</a> is the top destination this summer. It’s home to a cutting-edge contemporary architecture, baroque masterpieces, delicious local cuisine and at least 8 months of sun.</p><section class="product" data-id="2"></section><p>You’ll definitely love exploring <a href="https://en.wikipedia.org/wiki/Warsaw">Warsaw</a>! Best time to visit the city is July and August, when it’s cool enough to not break a sweat and hot enough to enjoy summer. The city which has quite a combination of both old and modern textures is located by the river of Vistula.</p><section class="product" data-id="1"></section><h3>Other destinations</h3><figure class="table"><table><thead><tr><th>Destination</th><th>Trip details</th></tr></thead><tbody><tr><td><section class="product" data-id="3"></section><p>&nbsp;</p></td><td>Getting used to an entirely different culture can be challenging. While it’s also nice to learn about cultures online or from books, nothing comes close to experiencing cultural diversity in person. You learn to appreciate each and every single one of the differences while you become more culturally fluid. <a href="http://ckeditor.com">Find out more...</a></td></tr><tr><td><section class="product" data-id="4"></section><p>&nbsp;</p></td><td>Tourists frequently admit that Taj Mahal "simply cannot be described with words". And that’s probably true. The more you try the more speechless you become. Words give only a semblance of truth. <a href="http://ckeditor.com">Find out more...</a></td></tr></tbody></table></figure>'
+		};
+
+		// The configuration of the <CKEditor> instance.
+		this.editorConfig = {
+			plugins: [
+				// A set of editor features to be enabled and available to the user.
+				Essentials, Heading, Bold, Italic, Underline,
+				Link, Paragraph, Table, TableToolbar,
+
+				// Our custom plugin implementing the widget is loaded here.
+				ProductPreviewEditing
+			],
+			toolbar: [
+				'heading',
+				'|',
+				'bold', 'italic', 'underline',
+				'|',
+				'link', 'insertTable',
+				'|',
+				'undo', 'redo'
+			],
+			table: {
+				contentToolbar: [
+					'tableColumn',
+					'tableRow',
+					'mergeTableCells'
+				]
+			},
+			// The configuration of the Products plugin. It specifies a function that will allow
+			// the editor to render a React <ProductPreview> component inside a product widget.
+			products: {
+				productRenderer: ( id, domElement ) => {
+					const product = this.props.products.find( product => product.id === id );
+
+					ReactDOM.render(
+						<ProductPreview id={id} {...product} />,
+						domElement
+					);
+				}
+			}
+		};
+
+		this.handleEditorDataChange = this.handleEditorDataChange.bind( this );
+		this.handleEditorInit = this.handleEditorInit.bind( this );
+	}
+
+	// A handler executed when the user types or modifies the editor content.
+	// It updates the state of the application.
+	handleEditorDataChange( evt, editor ) {
+		this.setState( {
+			editorData: editor.getData()
+		} );
+	}
+
+	// A handler executed when the editor has been initialized and is ready.
+	// It synchronizes the initial data state and saves the reference to the editor instance.
+	handleEditorInit( editor ) {
+		this.editor = editor;
+
+		this.setState( {
+			editorData: editor.getData()
+		} );
+
+		// CKEditor 5 inspector allows you to take a peek into editor's model and view
+		// data layers. Use it to debug the application and learn more about the editor.
+		CKEditorInspector.attach( editor );
+	}
+
+	render() {
+		return [
+			// The application renders two columns:
+			// * in the left one, the <CKEditor> is rendered and the textarea displaying
+			//   live editor data.
+			// * in the right column, a <ProductList> is rendered with available <ProductPreviews>
+			//   to choose from.
+			<div className="app__offer-editor" key="offer-editor">
+				<h3>Product offer editor</h3>
+				<CKEditor
+					editor={ClassicEditor}
+					data={this.state.editorData}
+					config={this.editorConfig}
+					onChange={this.handleEditorDataChange}
+					onInit={this.handleEditorInit}
+				/>
+
+				<h3>Editor data</h3>
+				<textarea value={this.state.editorData} readOnly={true}></textarea>
+			</div>,
+			<ProductList
+				key="product-list"
+				products={this.props.products}
+				onClick={( id ) => {
+					this.editor.execute( 'insertProduct', id );
+					this.editor.editing.view.focus();
+				}}
+			/>
+		];
+	}
+}
+```
+
+The JavaScript code is ready but to run the application we need to specify a couple of product definitions. Let us do that when mounting the `<App>` component:
+
+```js
+// app.js
+
+class App extends React.Component {
+	// ...
+}
+
+// Render the <App> in the <div class="app"></div> element found in DOM.
+ReactDOM.render(
+	<App
+		// Feeding the application with pre–defined products.
+		// In a real-life application, this sort of data would be loaded
+		// from a database. To keep this tutorial simple, we're using
+		// a couple of hard–coded product definitions.
+		products={[
+			{
+				id: 1,
+				name: 'Colors of summer in Poland',
+				price: '$1500',
+				image: 'product1.jpg'
+			},
+			{
+				id: 2,
+				name: 'Mediterranean Sun on Malta',
+				price: '$1899',
+				image: 'product2.jpg'
+			},
+			{
+				id: 3,
+				name: 'Tastes of Asia',
+				price: '$2599',
+				image: 'product3.jpg'
+			},
+			{
+				id: 4,
+				name: 'Exotic india',
+				price: '$2200',
+				image: 'product4.jpg'
+			}
+		]}
+	/>,
+	document.querySelector( '.app' )
+);
+```
+
+Please note that each product comes with its own image (e.g. `product1.jpg`), which should be stored in the `assets/` directory to load correctly via CSS `background-image`. Learn more about styles in the [next chapter](#styles-and-assets).
+
+## Styles and assets
+
+The application needs some styling to look good. We are going to put them in the `assets/styles.css` file imported in our main HTML file (`index.html`):
+
+```css
+/* assets/styles.css */
+
+/* --- General application styles --------------------------------------------------- */
+
+.app {
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+	font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
+	margin: 0 auto;
+}
+
+.app h2 {
+	font-size: 1.3em;
+}
+
+.app textarea {
+	width: 100%;
+	height: 150px;
+	font-family: 'Courier New', Courier, monospace;
+	box-sizing: border-box;
+	font-size: 14px;
+}
+
+/* --- Product offer editor styles ----------------------------------------------------- */
+
+.app .app__offer-editor {
+	flex: 1 1 auto;
+	max-width: 800px;
+}
+
+/* --- Generic product preview styles --------------------------------------------------- */
+
+.app .product-preview {
+	background-repeat: no-repeat;
+	background-position: center;
+	background-image: var(--product-image);
+	background-size: cover;
+	height: 150px;
+	position: relative;
+	overflow: hidden;
+	box-shadow: 1px 1px 3px hsla(0, 0%, 0%, .3);
+	min-width: 160px;
+}
+
+.app .product-preview .product-preview__name {
+	padding: 10px;
+	background: hsl(0, 0%, 100%);
+	font-weight: bold;
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	right: 0;
+}
+
+.app .product-preview .product-preview__price {
+	position: absolute;
+	top: 0;
+	right: 0;
+	display: block;
+	background: hsl(346, 100%, 56%);
+	padding: 6px 10px;
+	min-width: 50px;
+	text-align: center;
+	color: hsl(0, 0%, 100%);
+	text-transform: uppercase;
+	font-size: .8em;
+}
+
+.app .product-preview .product-preview__add {
+	display: none;
+}
+
+/* --- Product list styles --------------------------------------------------- */
+
+.app .app__product-list {
+	margin-left: 20px;
+	padding: 20px;
+	min-width: 400px;
+	border-left: 1px solid hsl(0, 0%, 87%);
+}
+
+.app .app__product-list h2 {
+	margin-top: 10px;
+}
+
+.app .app__product-list ul {
+	display: grid;
+	grid-template-columns: 1fr 1fr;
+	grid-gap: 10px;
+	margin-top: 10px;
+	list-style-type: none;
+	margin: 0;
+	padding: 0;
+}
+
+.app .app__product-list .product-preview {
+	opacity: .7;
+}
+
+.app .app__product-list .product-preview:hover {
+	opacity: 1;
+}
+
+.app .app__product-list .product-preview:hover .product-preview__add {
+	display: block;
+}
+
+.app .app__product-list .product-preview .product-preview__add {
+	display: none;
+	position: absolute;
+	width: 40px;
+	height: 40px;
+	top: 45%;
+	left: 50%;
+
+	border: 0;
+	padding: 0;
+	cursor: pointer;
+	font-weight: bold;
+	text-align: center;
+	border-radius: 100px;
+	background: hsl(0, 0%, 100%);
+	transform: translate(-50%, -50%);
+	box-shadow: 2px 2px 2px hsla(0, 0%, 0%, .3);
+}
+
+.app .app__product-list .product-preview .product-preview__add span {
+	font-size: 25px;
+	vertical-align: middle;
+	color: hsl(0, 0%, 24%);
+	line-height: 40px;
+	display: inline-block;
+}
+
+.app .app__product-list .product-preview .product-preview__name {
+	font-size: 10px;
+}
+
+.app .app__product-list .product-preview .product-preview__price {
+	font-size: 10px;
+}
+
+/* --- In-editor product widget styles --------------------------------------------------- */
+
+.app .ck-content .product {
+	margin: 1em;
+	animation: slideUp 0.3s ease;
+}
+
+@keyframes slideUp {
+	0% {
+		opacity: 0;
+		transform: translateY(1em);
+	}
+	100% {
+		opacity: 1;
+		transform: translateY(0);
+	}
+}
+```
+
+The product preview (`.product-preview` class) uses `background-image: var(--product-image)` to set its background. It means that all images must be stored in the `assets/` directory next to the `styles.css` file in order to load properly.
+
+## Demo
+
+You can see the entire application working below. Click the products in the sidebar to add them to the editor. You can also check out the [full source code](#full-source-code) of this tutorial if you want to extend it further or use it as base for your application.
+
+{@snippet framework/tutorials/using-react-in-widget}
+
+## Full source code
+
+The following code snippets are the complete implementation of the application (and all its dependencies). Follow the [application structure](#application-structure) diagram to re–create the application.
+
+### `app.js`
+
+```jsx
+// app.js
+
+// Imports necessary to run a React application.
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+// The official <CKEditor> component for React.
+import CKEditor from '@ckeditor/ckeditor5-react';
+
+// The official CKEditor 5 instance inspector, helps understand the editor view and model.
+import CKEditorInspector from '@ckeditor/ckeditor5-inspector';
+
+// The base editor class and features required to run the editor.
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
+import Heading from '@ckeditor/ckeditor5-heading/src/heading';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
+import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
+import Link from '@ckeditor/ckeditor5-link/src/link';
+import Table from '@ckeditor/ckeditor5-table/src/table';
+import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+
+// CKEditor plugin implementing a product widget to be used in editor content.
+import ProductPreviewEditing from './ckeditor/productpreviewediting';
+
+// React components to render the list of product and the product preview.
+import ProductList from './react/productlist';
+import ProductPreview from './react/productpreview';
+
+// The React application class. It renders the editor and the product list.
+class App extends React.Component {
+	constructor( props ) {
+		super( props );
+
+		// A place to store the reference to the editor instance created by the <CKEditor> component.
+		// The editor instance is created asynchronously and only available when the editor is ready.
+		this.editor = null;
+
+		this.state = {
+			// The initial editor data. It is bound to the editor instance and will change as
+			// the user types and modifies the content of the editor.
+			editorData: `
+				<h2>Check our last minute deals!</h2>
+
+				<p>Aenean erat conubia pretium libero habitant turpis vivamus dignissim molestie, phasellus libero! Curae; consequat cubilia mattis. Litora non iaculis tincidunt.</p>
+				<section class="product" data-id="2">&nbsp;</section>
+				<p>Mollis gravida parturient ad maecenas euismod consectetur lacus rutrum urna eget ligula. Nisi imperdiet scelerisque natoque scelerisque cubilia nulla gravida. Eleifend malesuada pharetra est commodo venenatis aenean habitasse curae; fusce elit.</p>
+				<section class="product" data-id="1">&nbsp;</section>
+
+				<h3>Other deals</h3>
+				<p>Ultricies dapibus placerat orci natoque fames commodo facilisi sollicitudin. Sed hendrerit mi dis non lacinia ipsum. Luctus fames scelerisque auctor pellentesque mi nunc mattis, amet sapien.</p>
+
+				<figure class="table">
+					<table>
+						<thead>
+							<tr>
+								<th>Our deal</th>
+								<th>Why this one?</th>
+							</tr>
+						</thead>
+						<tbody>
+							<tr>
+								<td>
+									<section class="product" data-id="3">&nbsp;</section>
+								</td>
+								<td>Nascetur, nullam hac nibh curabitur elementum. Est ridiculus turpis adipiscing erat maecenas habitant montes. Curabitur mauris ut luctus semper. Neque orci auctor luctus accumsan quam cursus purus condimentum dis?</td>
+							</tr>
+							<tr>
+								<td>
+									<section class="product" data-id="4">&nbsp;</section>
+								</td>
+								<td>Elementum condimentum convallis porttitor cubilia consectetur cum. In pretium neque accumsan pharetra. Magna in quisque dignissim praesent facilisi diam. Ad habitant ultricies at faucibus. Ultricies auctor sodales massa nisi eget sem porta?</td>
+							</tr>
+						</tbody>
+					</table>
+				</figure>
+			`,
+		};
+
+		// The configuration of the <CKEditor> instance.
+		this.editorConfig = {
+			plugins: [
+				// A set of editor features to be enabled and available to the user.
+				Essentials, Heading, Bold, Italic, Underline,
+				Link, Paragraph, Table, TableToolbar,
+
+				// Our custom plugin implementing the widget is loaded here.
+				ProductPreviewEditing
+			],
+			toolbar: [
+				'heading',
+				'|',
+				'bold', 'italic', 'underline',
+				'|',
+				'link', 'insertTable',
+				'|',
+				'undo', 'redo'
+			],
+			table: {
+				contentToolbar: [
+					'tableColumn',
+					'tableRow',
+					'mergeTableCells'
+				]
+			},
+			// The configuration of the Products plugin. It specifies a function that will allow
+			// the editor to render a React <ProductPreview> component inside a product widget.
+			products: {
+				productRenderer: ( id, domElement ) => {
+					const product = this.props.products.find( product => product.id === id );
+
+					ReactDOM.render(
+						<ProductPreview id={id} {...product} />,
+						domElement
+					);
+				}
+			}
+		};
+
+		this.handleEditorDataChange = this.handleEditorDataChange.bind( this );
+		this.handleEditorInit = this.handleEditorInit.bind( this );
+	}
+
+	// A handler executed when the user types or modifies the editor content.
+	// It updates the state of the application.
+	handleEditorDataChange( evt, editor ) {
+		this.setState( {
+			editorData: editor.getData()
+		} );
+	}
+
+	// A handler executed when the editor has been initialized and is ready.
+	// It synchronizes the initial data state and saves the reference to the editor instance.
+	handleEditorInit( editor ) {
+		this.editor = editor;
+
+		this.setState( {
+			editorData: editor.getData()
+		} );
+
+		// CKEditor 5 inspector allows you to take a peek into editor's model and view
+		// data layers. Use it to debug the application and learn more about the editor.
+		CKEditorInspector.attach( editor );
+	}
+
+	render() {
+		return [
+			// The application renders two columns:
+			// * in the left one, the <CKEditor> is rendered and the textarea displaying
+			//   live editor data.
+			// * in the right column, a <ProductList> is rendered with available <ProductPreviews>
+			//   to choose from.
+			<div className="app__offer-editor" key="offer-editor">
+				<h3>Product offer editor</h3>
+				<CKEditor
+					editor={ClassicEditor}
+					data={this.state.editorData}
+					config={this.editorConfig}
+					onChange={this.handleEditorDataChange}
+					onInit={this.handleEditorInit}
+				/>
+
+				<h3>Editor data</h3>
+				<textarea value={this.state.editorData} readOnly={true}></textarea>
+			</div>,
+			<ProductList
+				key="product-list"
+				products={this.props.products}
+				onClick={( id ) => {
+					this.editor.execute( 'insertProduct', id );
+					this.editor.editing.view.focus();
+				}}
+			/>
+		];
+	}
+}
+
+// Render the <App> in the <div class="app"></div> element found in DOM.
+ReactDOM.render(
+	<App
+		// Feeding the application with pre–defined products.
+		// In a real-life application, this sort of data would be loaded
+		// from a database. To keep this tutorial simple, we're using
+		// a couple of hard–coded product definitions.
+		products={[
+			{
+				id: 1,
+				name: 'Colors of summer in Poland',
+				price: '$1500',
+				image: 'product1.jpg'
+			},
+			{
+				id: 2,
+				name: 'Mediterranean Sun on Malta',
+				price: '$1899',
+				image: 'product2.jpg'
+			},
+			{
+				id: 3,
+				name: 'Tastes of Asia',
+				price: '$2599',
+				image: 'product3.jpg'
+			},
+			{
+				id: 4,
+				name: 'Exotic india',
+				price: '$2200',
+				image: 'product4.jpg'
+			}
+		]}
+	/>,
+	document.querySelector( '.app' )
+);
+```
+
+### `productpreviewediting.js`
+
+```js
+// ckeditor/productpreviewediting.js
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import { toWidget } from '@ckeditor/ckeditor5-widget/src/utils';
+import Widget from '@ckeditor/ckeditor5-widget/src/widget';
+import InsertProductPreviewCommand from './insertproductpreviewcommand';
+
+export default class ProductPreviewEditing extends Plugin {
+	static get requires() {
+		return [ Widget ];
+	}
+
+	init() {
+		this._defineSchema();
+		this._defineConverters();
+
+		this.editor.commands.add( 'insertProduct', new InsertProductPreviewCommand( this.editor ) );
+	}
+
+	_defineSchema() {
+		const schema = this.editor.model.schema;
+
+		schema.register( 'productPreview', {
+			// Behaves like a self-contained object (e.g. an image).
+			isObject: true,
+
+			// Allow in places where other blocks are allowed (e.g. directly in the root).
+			allowWhere: '$block',
+
+			// Each product preview has an id. An unique id tells the application which
+			// product it represents and makes it possible to render it inside a widget.
+			allowAttributes: [ 'id' ]
+		} );
+	}
+
+	_defineConverters() {
+		const editor = this.editor;
+		const conversion = editor.conversion;
+		const renderProduct = editor.config.get( 'products' ).productRenderer;
+
+		// <productPreview> converters ((data) view → model)
+		conversion.for( 'upcast' ).elementToElement( {
+			view: {
+				name: 'section',
+				classes: 'product'
+			},
+			model: ( viewElement, modelWriter ) => {
+				// Read the "data-id" attribute from the view and set it as "id" in the model.
+				return modelWriter.createElement( 'productPreview', {
+					id: parseInt( viewElement.getAttribute( 'data-id' ) )
+				} );
+			}
+		} );
+
+		// <productPreview> converters (model → data view)
+		conversion.for( 'dataDowncast' ).elementToElement( {
+			model: 'productPreview',
+			view: ( modelElement, viewWriter ) => {
+				// In the data view, the model <productPreview> corresponds to:
+				//
+				// <section class="product" data-id="..."></section>
+				return viewWriter.createEmptyElement( 'section', {
+					class: 'product',
+					'data-id': modelElement.getAttribute( 'id' )
+				} );
+			}
+		} );
+
+		// <productPreview> converters (model → editing view)
+		conversion.for( 'editingDowncast' ).elementToElement( {
+			model: 'productPreview',
+			view: ( modelElement, viewWriter ) => {
+				// In the editing view, the model <productPreview> corresponds to:
+				//
+				// <section class="product" data-id="...">
+				//     <div class="product__react-wrapper">
+				//         <ProductPreview /> (React component)
+				//     </div>
+				// </section>
+				const id = modelElement.getAttribute( 'id' );
+
+				// The outer-most <section class="product" data-id="..."></section> element.
+				const section = viewWriter.createContainerElement( 'section', {
+					class: 'product',
+					'data-id': id
+				} );
+
+				// The inner <div class="product__react-wrapper"></div> element.
+				// This element will host a React <ProductPreview /> component.
+				const reactWrapper = viewWriter.createUIElement( 'div', {
+					class: 'product__react-wrapper'
+				}, function( domDocument ) {
+					const domElement = this.toDomElement( domDocument );
+
+					// This the place where React renders the actual product preview hosted
+					// by a UIElement in the view. We're using a function (renderer) passed as
+					// editor.config.products#productRenderer.
+					renderProduct( id, domElement );
+
+					return domElement;
+				} );
+
+				viewWriter.insert( viewWriter.createPositionAt( section, 0 ), reactWrapper );
+
+				return toWidget( section, viewWriter, { label: 'product preview widget' } );
+			}
+		} );
+	}
+}
+```
+
+### `insertproductpreviewcommand.js`
+
+```js
+// ckeditor/insertproductpreviewcommand.js
+
+import Command from '@ckeditor/ckeditor5-core/src/command';
+
+export default class InsertProductPreviewCommand extends Command {
+	execute( id ) {
+		this.editor.model.change( writer => {
+			// Insert <productPreview id="...">*</productPreview> at the current selection position
+			// in a way which will result in creating a valid model structure.
+			this.editor.model.insertContent( writer.createElement( 'productPreview', { id } ) );
+		} );
+	}
+
+	refresh() {
+		const model = this.editor.model;
+		const selection = model.document.selection;
+		const allowedIn = model.schema.findAllowedParent( selection.getFirstPosition(), 'productPreview' );
+
+		this.isEnabled = allowedIn !== null;
+	}
+}
+```
+
+### `productlist.js`
+
+```jsx
+// react/productlist.js
+
+import React from 'react';
+import ProductPreview from './productpreview';
+
+export default class ProductList extends React.Component {
+	render() {
+		return <div className="app__product-list">
+			<h3>Products</h3>
+			<ul>
+				{this.props.products.map( product => {
+					return <li key={product.id}>
+						<ProductPreview
+							id={product.id}
+							onClick={this.props.onClick}
+							{...product}
+						/>
+					</li>;
+				})}
+			</ul>
+			<p><b>Tip</b>: Clicking the product will add it to the editor.</p>
+		</div>;
+	}
+}
+```
+
+### `productpreview.js`
+
+```jsx
+// react/productpreview.js
+
+import React from 'react';
+
+export default class ProductPreview extends React.Component {
+	render() {
+		const style = {
+			'--product-image': `url(${ this.props.image })`
+		};
+
+		return <div
+			className="product-preview"
+			style={style}>
+				<button
+					className="product-preview__add"
+					onClick={() => this.props.onClick( this.props.id )}
+					title="Add to the offer"
+				>
+					<span>+</span>
+				</button>
+				<span className="product-preview__name">{this.props.name}</span>
+				<span className="product-preview__price">from {this.props.price}</span>
+			</div>
+	}
+}
+````
+
+### `index.html`
+
+```html
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<title>Using React components in CKEditor 5 widgets</title>
+		<link rel="stylesheet" href="assets/styles.css">
+	</head>
+	<body>
+		<div class="app"></div>
+		<script src="dist/bundle.js"></script>
+	</body>
+</html>
+```

+ 21 - 4
docs/umberto.json

@@ -15,14 +15,20 @@
 		"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",
+		"features/mathtype.html": "features/math-equations.html",
+		"features/spell-checker.html": "features/spelling-and-grammar-checking.html"
 	},
 	},
 	"scripts": {
 	"scripts": {
 		"snippet-adapter": "../scripts/docs/snippetadapter",
 		"snippet-adapter": "../scripts/docs/snippetadapter",
@@ -138,11 +144,17 @@
 							"slug": "deep-dive",
 							"slug": "deep-dive",
 							"order": 300,
 							"order": 300,
 							"categories": [
 							"categories": [
+								{
+									"name": "Conversion",
+									"id": "framework-deep-dive-conversion",
+									"slug": "ui",
+									"order": 100
+								},
 								{
 								{
 									"name": "User interface",
 									"name": "User interface",
 									"id": "framework-deep-dive-ui",
 									"id": "framework-deep-dive-ui",
 									"slug": "ui",
 									"slug": "ui",
-									"order": 100
+									"order": 110
 								}
 								}
 							]
 							]
 						},
 						},
@@ -213,6 +225,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"
 				}
 				}
 			]
 			]
 		},
 		},

+ 9 - 3
mgit.json → mrgit.json

@@ -1,7 +1,9 @@
 {
 {
   "packages": "packages/",
   "packages": "packages/",
-  "packagesPrefix": "@ckeditor/ckeditor5-",
+  "packagesPrefix": [ "@ckeditor/ckeditor5-", "@ckeditor/ckeditor-" ],
+  "baseBranches": [ "master", "stable" ],
   "dependencies": {
   "dependencies": {
+    "@ckeditor/ckeditor-cloud-services-core": "ckeditor/ckeditor-cloud-services-core",
     "@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",
     "@ckeditor/ckeditor5-autoformat": "ckeditor/ckeditor5-autoformat",
     "@ckeditor/ckeditor5-autoformat": "ckeditor/ckeditor5-autoformat",
@@ -27,8 +29,10 @@
     "@ckeditor/ckeditor5-essentials": "ckeditor/ckeditor5-essentials",
     "@ckeditor/ckeditor5-essentials": "ckeditor/ckeditor5-essentials",
     "@ckeditor/ckeditor5-font": "ckeditor/ckeditor5-font",
     "@ckeditor/ckeditor5-font": "ckeditor/ckeditor5-font",
     "@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-horizontal-rule": "ckeditor/ckeditor5-horizontal-rule",
     "@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 +48,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"
   }
   }
 }
 }

+ 73 - 61
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,77 +21,88 @@
     "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/ckeditor-cloud-services-core": "^5.0.0",
+    "@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-horizontal-rule": "^0.0.1",
+    "@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.3.0",
-    "@ckeditor/ckeditor5-dev-utils": "^12.0.1",
-    "@ckeditor/ckeditor5-dev-webpack-plugin": "^8.0.1",
-    "@ckeditor/ckeditor5-inspector": "^1.2.0",
-    "@ckeditor/ckeditor5-real-time-collaboration": "^12.2.0",
-    "@ckeditor/ckeditor5-track-changes": "^0.2.0",
+    "@ckeditor/ckeditor5-comments": "^4.0.0",
+    "@ckeditor/ckeditor5-dev-docs": "^11.0.9",
+    "@ckeditor/ckeditor5-dev-env": "^16.0.0",
+    "@ckeditor/ckeditor5-dev-tests": "^16.9.0",
+    "@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-real-time-collaboration": "^12.4.0",
+    "@ckeditor/ckeditor5-track-changes": "^1.1.0",
+    "@wiris/mathtype-ckeditor5": "^7.16.1",
+    "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",
     "progress-bar-webpack-plugin": "^1.12.1",
     "progress-bar-webpack-plugin": "^1.12.1",
-    "raw-loader": "^1.0.0",
-    "style-loader": "^0.23.0",
+    "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",
+    "uglifyjs-webpack-plugin": "^1.3.0",
     "umberto": "^1.0.0",
     "umberto": "^1.0.0",
-    "webpack": "^4.15.0"
+    "webpack": "^4.39.1"
   },
   },
   "engines": {
   "engines": {
     "node": ">=8.0.0",
     "node": ">=8.0.0",
@@ -109,14 +120,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",

+ 3 - 3
scripts/bump-year.js

@@ -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
 
 
 */
 */
 
 

+ 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();
+		} );
+	} );
+}

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

@@ -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

+ 2 - 2
scripts/docs/buildapi.js

@@ -16,8 +16,8 @@ module.exports = function buildApiDocs() {
 		.build( {
 		.build( {
 			readmePath: path.join( process.cwd(), 'README.md' ),
 			readmePath: path.join( process.cwd(), 'README.md' ),
 			sourceFiles: [
 			sourceFiles: [
-				process.cwd() + '/packages/ckeditor5-*/src/**/*.@(js|jsdoc)',
-				'!' + process.cwd() + '/packages/ckeditor5-*/src/lib/**/*.js',
+				process.cwd() + '/packages/@(ckeditor|ckeditor5)-*/src/**/*.@(js|jsdoc)',
+				'!' + process.cwd() + '/packages/@(ckeditor|ckeditor5)-*/src/lib/**/*.js',
 				'!' + process.cwd() + '/packages/ckeditor5-build-*/src/**/*.js'
 				'!' + process.cwd() + '/packages/ckeditor5-build-*/src/**/*.js'
 			],
 			],
 			validateOnly: process.argv.includes( '--validate-only' )
 			validateOnly: process.argv.includes( '--validate-only' )

+ 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()
+					} );
+				}
+			} );
+		} );
+	};
+} );

+ 10 - 0
scripts/docs/getrealimportpath.js

@@ -5,6 +5,16 @@
 
 
 /* eslint-env node */
 /* eslint-env node */
 
 
+const NON_CKEDITOR5_PACKAGES = {
+	'cloud-services-core': 'ckeditor-cloud-services-core'
+};
+
 module.exports = function getRealImportPath( modulePath ) {
 module.exports = function getRealImportPath( modulePath ) {
+	for ( const shortPkgName of Object.keys( NON_CKEDITOR5_PACKAGES ) ) {
+		if ( modulePath.startsWith( shortPkgName ) ) {
+			return modulePath.replace( new RegExp( '^' + shortPkgName ), `@ckeditor/${ NON_CKEDITOR5_PACKAGES[ shortPkgName ] }/src` );
+		}
+	}
+
 	return modulePath.replace( /^([^/]+)\//, '@ckeditor/ckeditor5-$1/src/' );
 	return modulePath.replace( /^([^/]+)\//, '@ckeditor/ckeditor5-$1/src/' );
 };
 };

+ 60 - 5
scripts/docs/snippetadapter.js

@@ -16,6 +16,7 @@ const UglifyJsWebpackPlugin = require( 'uglifyjs-webpack-plugin' );
 const ProgressBarPlugin = require( 'progress-bar-webpack-plugin' );
 const ProgressBarPlugin = require( 'progress-bar-webpack-plugin' );
 
 
 const DEFAULT_LANGUAGE = 'en';
 const DEFAULT_LANGUAGE = 'en';
+const MULTI_LANGUAGE = 'multi-language';
 
 
 /**
 /**
  * @param {Set.<Snippet>} snippets Snippet collection extracted from documentation files.
  * @param {Set.<Snippet>} snippets Snippet collection extracted from documentation files.
@@ -91,6 +92,12 @@ module.exports = function snippetAdapter( snippets, options, umbertoHelpers ) {
 	// Group snippets by language. There is no way to build different languages in a single Webpack process.
 	// 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.
 	// Webpack must be called as many times as different languages are being used in snippets.
 	for ( const snippetData of 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 ] ) {
 		if ( !groupedSnippetsByLanguage[ snippetData.snippetConfig.language ] ) {
 			groupedSnippetsByLanguage[ snippetData.snippetConfig.language ] = new Set();
 			groupedSnippetsByLanguage[ snippetData.snippetConfig.language ] = new Set();
 		}
 		}
@@ -163,8 +170,10 @@ module.exports = function snippetAdapter( snippets, options, umbertoHelpers ) {
 
 
 					let snippetHTML = fs.readFileSync( snippetData.snippetSources.html ).toString();
 					let snippetHTML = fs.readFileSync( snippetData.snippetSources.html ).toString();
 
 
-					snippetHTML = snippetHTML.replace( /%BASE_PATH%/g, snippetData.basePath );
-					snippetHTML = `<div class="live-snippet">${ snippetHTML }</div>`;
+					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 );
 					content = content.replace( getSnippetPlaceholder( snippetData.snippetName ), snippetHTML );
 
 
@@ -176,6 +185,13 @@ module.exports = function snippetAdapter( snippets, options, umbertoHelpers ) {
 					if ( wasCSSGenerated ) {
 					if ( wasCSSGenerated ) {
 						cssFiles.unshift( path.join( snippetData.relativeOutputPath, snippetData.snippetName, 'snippet.css' ) );
 						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` ) );
+						} );
+					}
 				}
 				}
 
 
 				const cssImportsHTML = getHTMLImports( cssFiles, importPath => {
 				const cssImportsHTML = getHTMLImports( cssFiles, importPath => {
@@ -259,6 +275,27 @@ function getWebpackConfig( snippets, config ) {
 		definitions[ definitionKey ] = JSON.stringify( config.definitions[ definitionKey ] );
 		definitions[ definitionKey ] = JSON.stringify( config.definitions[ definitionKey ] );
 	}
 	}
 
 
+	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 = {
 	const webpackConfig = {
 		mode: config.production ? 'production' : 'development',
 		mode: config.production ? 'production' : 'development',
 
 
@@ -286,9 +323,7 @@ function getWebpackConfig( snippets, config ) {
 
 
 		plugins: [
 		plugins: [
 			new MiniCssExtractPlugin( { filename: '[name]/snippet.css' } ),
 			new MiniCssExtractPlugin( { filename: '[name]/snippet.css' } ),
-			new CKEditorWebpackPlugin( {
-				language: config.language
-			} ),
+			new CKEditorWebpackPlugin( ckeditorWebpackPluginOptions ),
 			new webpack.BannerPlugin( {
 			new webpack.BannerPlugin( {
 				banner: bundler.getLicenseBanner(),
 				banner: bundler.getLicenseBanner(),
 				raw: true
 				raw: true
@@ -330,6 +365,24 @@ function getWebpackConfig( snippets, 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( '/' )
+					},
 				}
 				}
 			]
 			]
 		}
 		}
@@ -449,4 +502,6 @@ function getHTMLImports( files, mapFunction ) {
  * @property {String} [language] A language that will be used for building the editor.
  * @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>} [dependencies] Names of samples that are required to working.
+ *
+ * @property {Array.<String>} [additionalLanguages] Additional languages that are required by the snippet.
  */
  */

+ 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 or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-/* 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.` );

+ 7 - 19
scripts/update-stable-branches.sh

@@ -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

+ 33 - 0
tests/manual/article.html

@@ -0,0 +1,33 @@
+<head>
+	<style>
+		body {
+			max-width: 800px;
+			margin: 20px auto;
+		}
+	</style>
+</head>
+<div id="editor">
+	<h2>Heading 1</h2>
+	<p>Paragraph</p>
+	<p><strong>Bold</strong> <i>Italic</i> <a href="https://ckeditor.com">Link</a></p>
+	<ul>
+		<li>UL List item 1</li>
+		<li>UL List item 2</li>
+	</ul>
+	<ol>
+		<li>OL List item 1</li>
+		<li>OL List item 2</li>
+	</ol>
+	<figure class="image image-style-side">
+		<img alt="bar" src="sample.jpg">
+		<figcaption>Caption</figcaption>
+	</figure>
+	<blockquote>
+		<p>Quote</p>
+		<ul>
+			<li>Quoted UL List item 1</li>
+			<li>Quoted UL List item 2</li>
+		</ul>
+		<p>Quote</p>
+	</blockquote>
+</div>

+ 45 - 0
tests/manual/article.js

@@ -0,0 +1,45 @@
+/**
+ * @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 console, window, document */
+
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+
+import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
+
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ ArticlePluginSet ],
+		toolbar: [
+			'heading',
+			'|',
+			'bold',
+			'italic',
+			'link',
+			'bulletedList',
+			'numberedList',
+			'blockQuote',
+			'insertTable',
+			'mediaEmbed',
+			'undo',
+			'redo'
+		],
+		image: {
+			toolbar: [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]
+		},
+		table: {
+			contentToolbar: [
+				'tableColumn',
+				'tableRow',
+				'mergeTableCells'
+			]
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 3 - 0
tests/manual/article.md

@@ -0,0 +1,3 @@
+# Article plugin set
+
+Check whether all the available features work together.

+ 55 - 0
tests/manual/mathtype.html

@@ -0,0 +1,55 @@
+<head>
+	<!-- Required to fetch runtime data from https://www.wiris.net. -->
+	<meta http-equiv="Content-Security-Policy"
+		content="connect-src 'self' https://cksource.com http://*.cke-cs.com https://www.wiris.net;">
+</head>
+
+<div id="editor">
+	<h2>Hello world!</h2>
+
+	<figure class="table">
+		<table>
+			<tbody>
+				<tr>
+					<td>
+						<h2>Header 2</h2>
+
+						<p>Sample text with <span class="mention" data-mention="@Lily">@Lily</span> mentioned.</p>
+					</td>
+					<td>
+						<span style="color:hsl(0,75%,60%);"><i>Colors</i></span>
+						<span style="background-color:hsl(270,75%,60%);color:hsl(0,0%,100%);"><strong>are</strong></span>
+						plain
+						<span class="text-big" style="color:hsl(210,75%,60%);">awesome</span>
+						<span class="text-huge"><mark class="marker-yellow">!</mark></span>
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<figure class="image">
+							<img src="sample.jpg" alt="CKEditor logo" />
+							<figcaption>An <u>image</u></figcaption>
+						</figure>
+					</td>
+					<td>
+						<ol>
+							<li>First</li>
+							<li>Second</li>
+							<li>Third</li>
+						</ol>
+
+						<p>Closing paragraph.</p>
+					</td>
+				</tr>
+			</tbody>
+		</table>
+	</figure>
+
+	<blockquote>
+		<p>This is a quote block.</p>
+	</blockquote>
+
+	<p style="text-align:center;">Centered paragraph.</p>
+
+	<p>Sample text</p>
+</div>

+ 76 - 0
tests/manual/mathtype.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
+ */
+
+/* globals console:false, document, window */
+
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
+import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';
+import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
+import Code from '@ckeditor/ckeditor5-basic-styles/src/code';
+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 EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage';
+import Font from '@ckeditor/ckeditor5-font/src/font';
+import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight';
+import Indent from '@ckeditor/ckeditor5-indent/src/indent';
+import Mention from '@ckeditor/ckeditor5-mention/src/mention';
+import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice';
+import RemoveFormat from '@ckeditor/ckeditor5-remove-format/src/removeformat';
+import MathType from '@wiris/mathtype-ckeditor5';
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		cloudServices: CS_CONFIG,
+		plugins: [
+			ArticlePluginSet,
+			Alignment,
+			Underline,
+			Strikethrough,
+			Code,
+			Subscript,
+			Superscript,
+			EasyImage,
+			Font,
+			Highlight,
+			Indent,
+			Mention,
+			PasteFromOffice,
+			RemoveFormat,
+			MathType
+		],
+		toolbar: [
+			'MathType', 'ChemType', '|', 'heading', 'fontFamily', 'fontSize', 'fontColor', 'fontBackgroundColor',
+			'highlight', 'alignment', '|', 'bold', 'italic', 'underline', 'strikethrough', 'code', 'subscript',
+			'superscript', 'removeFormat', '|', 'bulletedList', 'numberedList', 'indent', 'outdent', '|', 'link',
+			'blockQuote', 'imageUpload', 'mediaEmbed', 'insertTable', '|', 'undo', 'redo'
+		],
+		image: {
+			toolbar: [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]
+		},
+		mediaEmbed: {
+			previewsInData: true,
+			toolbar: [ 'blockQuote' ]
+		},
+		mention: {
+			feeds: [ {
+				marker: '@',
+				feed: [ '@Barney', '@Lily', '@Marshall', '@Robin', '@Ted' ]
+			} ]
+		},
+		table: {
+			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ],
+			tableToolbar: [ 'bold', 'italic' ]
+		}
+	} )
+	.then( newEditor => {
+		window.editor = newEditor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 5 - 0
tests/manual/mathtype.md

@@ -0,0 +1,5 @@
+# Mathtype
+
+Use "MathType" and "ChemType" buttons to insert formulas.
+
+Note: There are some 404 HTTP error codes reported in the background until [2043](https://github.com/ckeditor/ckeditor5/issues/2043) is resolved.

BIN
tests/manual/sample.jpg


+ 69 - 0
tests/manual/wproofreader.html

@@ -0,0 +1,69 @@
+<head>
+	<!--
+		Required to fetch runtime data from https://svc.webspellchecker.net.
+		Also both unsafe inline and eval are required for it to work (https://github.com/WebSpellChecker/wproofreader/issues/19).
+	-->
+	<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval' https://cksource.com https://svc.webspellchecker.net;">
+</head>
+
+<script
+	type="text/javascript"
+	src="https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js"
+	data-wsc-serviceid="1:Eebp63-lWHbt2-ASpHy4-AYUpy2-fo3mk4-sKrza1-NsuXy4-I1XZC2-0u2F54-aqYWd1-l3Qf14-umd"
+	data-wsc-autosearch="true"
+	data-wsc-enablegrammar="true"
+></script>
+
+<div id="editor">
+	<h2>Hello world witth an obvious typo</h2>
+
+	<figure class="table">
+		<table>
+			<tbody>
+				<tr>
+					<td>
+						<h2>Header 2</h2>
+
+						<p>
+							<span class="mention" data-mention="@Ted">@Ted</span>
+							very rarely makes a typo. However he occasionally forgets to add a comma after “however”.
+						</p>
+					</td>
+					<td>
+						<span style="color:hsl(0,75%,60%);"><i>Colors</i></span>
+						<span
+							style="background-color:hsl(270,75%,60%);color:hsl(0,0%,100%);"><strong>are</strong></span>
+						plain
+						<span class="text-big" style="color:hsl(210,75%,60%);">awesome</span>
+						<span class="text-huge"><mark class="marker-yellow">!</mark></span>
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<figure class="image">
+							<img src="sample.jpg" alt="CKEditor logo" />
+							<figcaption>An <u>image</u></figcaption>
+						</figure>
+					</td>
+					<td>
+						<ol>
+							<li>First</li>
+							<li>Second</li>
+							<li>Third</li>
+						</ol>
+
+						<p>Closing paragraph.</p>
+					</td>
+				</tr>
+			</tbody>
+		</table>
+	</figure>
+
+	<blockquote>
+		<p>This is a quote block.</p>
+	</blockquote>
+
+	<p style="text-align:center;">Centered paragraph.</p>
+
+	<p>Sample text</p>
+</div>

+ 75 - 0
tests/manual/wproofreader.js

@@ -0,0 +1,75 @@
+/**
+ * @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 console:false, document, window */
+
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
+import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';
+import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
+import Code from '@ckeditor/ckeditor5-basic-styles/src/code';
+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 EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage';
+import Font from '@ckeditor/ckeditor5-font/src/font';
+import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight';
+import Indent from '@ckeditor/ckeditor5-indent/src/indent';
+import Mention from '@ckeditor/ckeditor5-mention/src/mention';
+import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice';
+import RemoveFormat from '@ckeditor/ckeditor5-remove-format/src/removeformat';
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		cloudServices: CS_CONFIG,
+		plugins: [
+			ArticlePluginSet,
+			Alignment,
+			Underline,
+			Strikethrough,
+			Code,
+			Subscript,
+			Superscript,
+			EasyImage,
+			Font,
+			Highlight,
+			Indent,
+			Mention,
+			PasteFromOffice,
+			RemoveFormat,
+		],
+		toolbar: [
+			'heading', 'fontFamily', 'fontSize', 'fontColor', 'fontBackgroundColor', 'highlight', 'alignment', '|',
+			'bold', 'italic', 'underline', 'strikethrough', 'code', 'subscript', 'superscript', 'removeFormat', '|',
+			'link', 'blockQuote', 'imageUpload', 'mediaEmbed', 'insertTable', '|',
+			'bulletedList', 'numberedList', 'indent', 'outdent', '|', 'undo', 'redo',
+			'|'
+		],
+		image: {
+			toolbar: [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]
+		},
+		mediaEmbed: {
+			previewsInData: true,
+			toolbar: [ 'blockQuote' ]
+		},
+		mention: {
+			feeds: [ {
+				marker: '@',
+				feed: [ '@Barney', '@Lily', '@Marshall', '@Robin', '@Ted' ]
+			} ]
+		},
+		table: {
+			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ],
+			tableToolbar: [ 'bold', 'italic' ]
+		}
+	} )
+	.then( newEditor => {
+		window.editor = newEditor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 24 - 0
tests/manual/wproofreader.md

@@ -0,0 +1,24 @@
+# Wproofreader
+
+Note: the plugin starts checking only **after focusing** the editor.
+
+## Inline typo correction
+
+1. Focus the editor.
+1. Wait until typos are indicated.
+1. Hover mouse cursor over "witth".
+1. Pick "with" from appearing context menu.
+
+## Inline grammar correction
+
+1. Focus the editor.
+1. Wait until typos are indicated.
+1. Hover mouse cursor over (the first) "However".
+1. Pick "However," from appearing context menu.
+
+## Dialog checking
+
+1. Focus the editor.
+1. Hover a spell check icon in the bottom-right corner of the editable.
+1. Click "Proofread in dialog" option.
+1. Use it to fix a typo.

Разница между файлами не показана из-за своего большого размера
+ 412 - 367
yarn.lock


Некоторые файлы не были показаны из-за большого количества измененных файлов