Jelajahi Sumber

Merge branch 'stable' into i/ckeditor5-react/118

Maciej Bukowski 5 tahun lalu
induk
melakukan
45c6726ac6
100 mengubah file dengan 942 tambahan dan 382 penghapusan
  1. 33 0
      .github/workflows/ckeditor5-integrations.yml
  2. 1 1
      .github/workflows/merge-stable.yml
  3. 158 21
      CHANGELOG.md
  4. 6 1
      docs/_snippets/examples/document-editor.js
  5. 1 1
      docs/_snippets/examples/multi-root-editor.html
  6. 3 3
      docs/_snippets/examples/multi-root-editor.js
  7. 0 14
      docs/_snippets/features/mathtype.html
  8. 62 1
      docs/_snippets/features/mathtype.js
  9. 9 0
      docs/builds/guides/frameworks/angular.md
  10. 24 24
      docs/builds/guides/integration/content-styles.md
  11. 3 3
      docs/builds/guides/migrate.md
  12. 2 0
      docs/features/image-upload.md
  13. 2 2
      docs/features/index.md
  14. 3 2
      docs/framework/guides/contributing/testing-environment.md
  15. 8 6
      docs/framework/guides/support/versioning-policy.md
  16. 1 1
      docs/index.md
  17. 67 65
      package.json
  18. 2 2
      packages/ckeditor-cloud-services-core/package.json
  19. 77 18
      packages/ckeditor-cloud-services-core/src/token/token.js
  20. 5 5
      packages/ckeditor-cloud-services-core/src/uploadgateway/fileuploader.js
  21. 2 2
      packages/ckeditor-cloud-services-core/src/uploadgateway/uploadgateway.js
  22. 202 103
      packages/ckeditor-cloud-services-core/tests/token/token.js
  23. 6 2
      packages/ckeditor-cloud-services-core/tests/uploadgateway/fileuploader.js
  24. 4 1
      packages/ckeditor-cloud-services-core/tests/uploadgateway/uploadgateway.js
  25. 13 13
      packages/ckeditor5-adapter-ckfinder/package.json
  26. 9 0
      packages/ckeditor5-alignment/docs/features/text-alignment.md
  27. 13 13
      packages/ckeditor5-alignment/package.json
  28. 14 14
      packages/ckeditor5-autoformat/package.json
  29. 2 2
      packages/ckeditor5-autoformat/tests/autoformat.js
  30. 5 5
      packages/ckeditor5-autosave/package.json
  31. 10 1
      packages/ckeditor5-basic-styles/docs/features/basic-styles.md
  32. 10 10
      packages/ckeditor5-basic-styles/package.json
  33. 27 0
      packages/ckeditor5-block-quote/docs/_snippets/features/block-quote.html
  34. 38 0
      packages/ckeditor5-block-quote/docs/_snippets/features/block-quote.js
  35. 6 2
      packages/ckeditor5-block-quote/docs/api/block-quote.md
  36. 70 0
      packages/ckeditor5-block-quote/docs/features/block-quote.md
  37. 14 14
      packages/ckeditor5-block-quote/package.json
  38. 0 0
      packages/ckeditor5-build-balloon-block/build/ckeditor.js
  39. 0 0
      packages/ckeditor5-build-balloon-block/build/ckeditor.js.map
  40. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/ar.js
  41. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ast.js
  42. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/az.js
  43. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/bg.js
  44. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/cs.js
  45. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/da.js
  46. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/de.js
  47. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/el.js
  48. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/en-au.js
  49. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/en-gb.js
  50. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/eo.js
  51. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/es.js
  52. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/et.js
  53. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/eu.js
  54. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/fa.js
  55. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/fi.js
  56. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/fr.js
  57. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/gl.js
  58. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/he.js
  59. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/hr.js
  60. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/hu.js
  61. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/id.js
  62. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/it.js
  63. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/ja.js
  64. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/km.js
  65. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/kn.js
  66. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/ko.js
  67. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/ku.js
  68. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/lt.js
  69. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/lv.js
  70. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/nb.js
  71. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/ne.js
  72. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/nl.js
  73. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/no.js
  74. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/pl.js
  75. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/pt-br.js
  76. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/pt.js
  77. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/ro.js
  78. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/ru.js
  79. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/si.js
  80. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/sk.js
  81. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/sq.js
  82. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/sr-latn.js
  83. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/sr.js
  84. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/sv.js
  85. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/th.js
  86. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/tr.js
  87. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/ug.js
  88. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/uk.js
  89. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/vi.js
  90. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/zh-cn.js
  91. 0 0
      packages/ckeditor5-build-balloon-block/build/translations/zh.js
  92. 22 22
      packages/ckeditor5-build-balloon-block/package.json
  93. 0 0
      packages/ckeditor5-build-balloon/build/ckeditor.js
  94. 0 0
      packages/ckeditor5-build-balloon/build/ckeditor.js.map
  95. 0 0
      packages/ckeditor5-build-balloon/build/translations/ar.js
  96. 1 1
      packages/ckeditor5-build-balloon/build/translations/ast.js
  97. 0 0
      packages/ckeditor5-build-balloon/build/translations/az.js
  98. 0 0
      packages/ckeditor5-build-balloon/build/translations/bg.js
  99. 0 0
      packages/ckeditor5-build-balloon/build/translations/cs.js
  100. 0 0
      packages/ckeditor5-build-balloon/build/translations/da.js

+ 33 - 0
.github/workflows/ckeditor5-integrations.yml

@@ -0,0 +1,33 @@
+# This script triggers Travis that verifies whether projects that depend on CKEditor 5 build correctly.
+#
+# In order to integrate the action in a new repository, you need add a few secrets in the new repository.
+#   - INTEGRATION_CI_ORGANIZATION - a name of the organization that keeps the repository where the build should be triggered
+#   - INTEGRATION_CI_REPOSITORY - a name of the repository where the build should be triggered
+#   - INTEGRATION_CI_TRAVIS_TOKEN - an authorization token generated by Travis CLI: `travis --pro token`
+name: CKEditor 5 Integrations
+
+on:
+  push:
+    branches: [ master ]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Trigger CI
+        env:
+          WORKFLOW_TRIGGER_REPOSITORY: ${{ github.repository }}
+          WORKFLOW_TRIGGER_COMMIT: ${{ github.sha }}
+          WORKFLOW_ORGANIZATION: ${{ secrets.INTEGRATION_CI_ORGANIZATION }}
+          WORKFLOW_REPOSITORY: ${{ secrets.INTEGRATION_CI_REPOSITORY }}
+          WORKFLOW_TRAVIS_TOKEN: ${{ secrets.INTEGRATION_CI_TRAVIS_TOKEN }}
+        run: |
+          export BUILD_MESSAGE="Repository: $WORKFLOW_TRIGGER_REPOSITORY\n\nCommit: https://github.com/$WORKFLOW_TRIGGER_REPOSITORY/commit/$WORKFLOW_TRIGGER_COMMIT."
+          export REQUEST_BODY="{\"request\": { \"branch\": \"master\", \"message\": \"$BUILD_MESSAGE\" } }"
+          curl -s -X POST \
+            -H "Content-Type: application/json" \
+            -H "Accept: application/json" \
+            -H "Travis-API-Version: 3" \
+            -H "Authorization: token $WORKFLOW_TRAVIS_TOKEN" \
+            -d "$REQUEST_BODY" \
+            "https://api.travis-ci.com/repo/$WORKFLOW_ORGANIZATION%2F$WORKFLOW_REPOSITORY/requests"

+ 1 - 1
.github/workflows/merge-stable.yml

@@ -22,7 +22,7 @@ jobs:
       - uses: rtCamp/action-slack-notify@v2.0.2
         id: error_message_slack
         name: Slack notification
-        if: (steps.merge_action.outputs.status != 201) && (steps.merge_action.outputs.status != 204)
+        if: ((steps.merge_action.outputs.status != 201) && (steps.merge_action.outputs.status != 204)) || failure()
         env:
           SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
           SLACK_CHANNEL: "cke5-ci"

+ 158 - 21
CHANGELOG.md

@@ -1,6 +1,143 @@
 Changelog
 =========
 
+## [23.0.0](https://github.com/ckeditor/ckeditor5/compare/v22.0.0...v23.0.0) (2020-09-29)
+
+### Release highlights
+
+We are happy to announce the release of CKEditor 5 v23.0.0.
+
+This release brings the new [pagination feature](https://ckeditor.com/blog/How-to-create-ready-to-print-documents-with-page-structure-in-WYSIWYG-editor---CKEditor-5-pagination-feature/).
+
+Other than that, we focused on bug fixes and stability improvements. Some highlights are listed below:
+
+* [Five bug fixes for list and list style plugins](https://github.com/ckeditor/ckeditor5/issues?q=is%3Aissue+milestone%3A%22iteration+36%22+label%3Atype%3Abug+label%3Apackage%3Alist).
+* [The "upload image via URL" feature was extracted into a separate image insert plugin](https://github.com/ckeditor/ckeditor5/issues/7890).
+* [Improvements for pasting as plain text using <kbd>Ctrl/Cmd</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd>](https://github.com/ckeditor/ckeditor5/issues/7799).
+* Fixed [a case where the link balloon toolbar would be mispositioned](https://github.com/ckeditor/ckeditor5/issues/7926) in some rare cases.
+
+Please note that there are some **major breaking changes**. Be sure to review them before upgrading.
+
+Read more in the blog post: https://ckeditor.com/blog/CKEditor-5-v23.0.0-with-pagination-feature-list-styles-and-improved-image-upload/
+
+### Collaboration features
+
+The CKEditor 5 Collaboration features changelog can be found here: https://ckeditor.com/collaboration/changelog.
+
+### MAJOR BREAKING CHANGES [ℹ️](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html#major-and-minor-breaking-changes)
+
+* **[image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image)**: In order to use the "insert image via URL" feature you now need to load the `ImageInsert` plugin and use the `imageInsert` button instead of the `imageUpload` button that implemented this functionality previously.
+
+### MINOR BREAKING CHANGES [ℹ️](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html#major-and-minor-breaking-changes)
+
+* **[clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard)**: When pasting plain text, each double line break is now treated as a paragraph separator, while a single line break is converted into a soft break. Formerly, every single line break was treated as paragraph separation.
+
+### Features
+
+* **[clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard)**: Improved line to paragraph/soft break retention when pasting as plain text. Closes [#7884](https://github.com/ckeditor/ckeditor5/issues/7884). ([commit](https://github.com/ckeditor/ckeditor5/commit/a4b89965e8b156ee4ed67df9d4a634c0e6deac01))
+* **[utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils)**: Added a user-agent check for the Blink engine to the [`env`](https://ckeditor.com/docs/ckeditor5/latest/api/module_utils_env-env.html) module. ([commit](https://github.com/ckeditor/ckeditor5/commit/a5a4b933e8ecef2b25ddbf03d371b89f26490025))
+* Introduced the `PastePlainText` feature that detects pasting with <kbd>Ctrl/cmd</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> keystroke. Closes [#7799](https://github.com/ckeditor/ckeditor5/issues/7799). ([commit](https://github.com/ckeditor/ckeditor5/commit/ab7bce94ebb7b6d59c5f3ea2d9433f71ddd864d2))
+
+### Bug fixes
+
+* **[clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard)**: The editor now properly places soft breaks in the plain text clipboard data representation. Closes [#8045](https://github.com/ckeditor/ckeditor5/issues/8045). ([commit](https://github.com/ckeditor/ckeditor5/commit/92ace8d7f3abe4c8247ca18697984eb538f3f5ec))
+* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: The `model.History#getOperations()` method was returning incorrect values if history had operations with negative version numbers or version numbers differing by more than one. Closes [#8143](https://github.com/ckeditor/ckeditor5/issues/8143). ([commit](https://github.com/ckeditor/ckeditor5/commit/3433e9a8ad64cc971cdfa4658a84585b4e23f19e))
+* **[image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image)**: Aligned and fixed the styling for the split button in the `ImageInsert` dropdown. Closes [#7986](https://github.com/ckeditor/ckeditor5/issues/7986), [#7927](https://github.com/ckeditor/ckeditor5/issues/7927). ([commit](https://github.com/ckeditor/ckeditor5/commit/4671ed10a4af4c507abd594414771b714ff31cf7))
+* **[link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link)**: Manual decorators will no longer be corrupted by the link image plugin. Closes [#7975](https://github.com/ckeditor/ckeditor5/issues/7975). ([commit](https://github.com/ckeditor/ckeditor5/commit/73eacd641f38ee261cd43ddfdf98df5e22eb2fdd))
+* **[link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link)**: Prevented throwing an error when creating a link from a multi-block selection. Closes [#7907](https://github.com/ckeditor/ckeditor5/issues/7907). ([commit](https://github.com/ckeditor/ckeditor5/commit/eb92cfb7377fa066a4cb08163ade33a73639aab1))
+* **[link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link)**: Pressing the <kbd>Enter</kbd> key should not throw an error when a non-collapsed selection ends with a valid URL. Closes [#7983](https://github.com/ckeditor/ckeditor5/issues/7983). ([commit](https://github.com/ckeditor/ckeditor5/commit/bcf3af6bee1edbd3a6d0c6874e0ad0518f73f518))
+* **[link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link)**: The link balloon positioning should be correct when the selection is collapsed in some rare cases. Closes [#7926](https://github.com/ckeditor/ckeditor5/issues/7926). ([commit](https://github.com/ckeditor/ckeditor5/commit/b532a8ec55e1e1506b6f8030f944559b1cf0761d))
+* **[list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list)**: The list style plugin will no longer cause the editor to crash when indenting a list item that is the last element in the editor. Closes [#8072](https://github.com/ckeditor/ckeditor5/issues/8072). ([commit](https://github.com/ckeditor/ckeditor5/commit/3e6ea99fe28225c52092b621c3593748bb1c168e))
+* **[list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list)**: Undo will restore a proper value of the `list-style-type` attribute in the view element after undoing list merge. Closes [#7930](https://github.com/ckeditor/ckeditor5/issues/7930). ([commit](https://github.com/ckeditor/ckeditor5/commit/3e6ea99fe28225c52092b621c3593748bb1c168e))
+* **[list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list)**: Fixed a bug that prevented using the same list style for nested lists. Closes [#8081](https://github.com/ckeditor/ckeditor5/issues/8081). ([commit](https://github.com/ckeditor/ckeditor5/commit/3e6ea99fe28225c52092b621c3593748bb1c168e))
+* **[list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list)**: The `listStyle` attribute should be inherited when inserting or replacing a `listItem` with the same list type (the `listType` attribute for the inserted or modified item is equal to the next or previous sibling list). Closes [#7932](https://github.com/ckeditor/ckeditor5/issues/7932). ([commit](https://github.com/ckeditor/ckeditor5/commit/03bf7211b1efc94ba087750f77006d534fdbaa5d))
+* **[list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list)**: When removing the content between two lists items, these lists will be merged into a single list. The second list should adjust its `listStyle` attribute to the first list. Closes [#7879](https://github.com/ckeditor/ckeditor5/issues/7879). ([commit](https://github.com/ckeditor/ckeditor5/commit/7aa952823a8b182dc41075fa8cf4cc3a452eb78b))
+* **[paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office)**: Fixed pasting a list with an empty item from Google Docs. Closes [#7958](https://github.com/ckeditor/ckeditor5/issues/7958). ([commit](https://github.com/ckeditor/ckeditor5/commit/ebf6bb798cb274c840df86de073cf511c66d876c))
+
+### Other changes
+
+* **[cloud-services-core](https://www.npmjs.com/package/@ckeditor/ckeditor-cloud-services-core)**: Change the token refreshing mechanism to depend on the token expiration time. ([commit](https://github.com/ckeditor/ckeditor5/commit/501490a5729c413ee00311fe3c9a965fab2bb2ad))
+* **[image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image)**: The `config.image.upload.panel.items` option does not need to be set anymore in order to show the "insert image via URL form". It is enough to load the new `ImageInsert` plugin and use the new `imageInsert` button. See [#8034](https://github.com/ckeditor/ckeditor5/issues/8034). ([commit](https://github.com/ckeditor/ckeditor5/commit/48a9e943122e4cdd0e2647f03ebc7b17c402710e))
+* **[image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image)**: Introduced `ImageInsert` as a standalone plugin that contains the `ImageUpload` functionality. Closes [#7890](https://github.com/ckeditor/ckeditor5/issues/7890). ([commit](https://github.com/ckeditor/ckeditor5/commit/4671ed10a4af4c507abd594414771b714ff31cf7))
+* **[image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image)**: The `ImageUploadPanelView` form label should change depending on whether the image is selected or not. Closes [#7878](https://github.com/ckeditor/ckeditor5/issues/7878). ([commit](https://github.com/ckeditor/ckeditor5/commit/288fb97e00181a130dd2833d6e3aa74bdab5b7cc))
+* **[link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link)**: The link plugin now comes with the autolink feature enabled by default. Closes [#7682](https://github.com/ckeditor/ckeditor5/issues/7682). ([commit](https://github.com/ckeditor/ckeditor5/commit/c9533f1752057fd833998a356282f8a625f4e39c))
+* **[theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark)**: Balloon panel arrows pointing down should have realistic shadows. Closes [#7928](https://github.com/ckeditor/ckeditor5/issues/7928). ([commit](https://github.com/ckeditor/ckeditor5/commit/1c0b5c978fc23f3ca5cccba7b89711469838c315))
+* Updated translations. ([commit](https://github.com/ckeditor/ckeditor5/commit/9256cbee9dc2173e1f1756fa566ba92a2d4bd6bc), [commit](https://github.com/ckeditor/ckeditor5/commit/08fc2a54b8953fe6000c900d8f1270b86edc1590))
+
+### Released packages
+
+Check out the [Versioning policy](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html) guide for more information.
+
+<details>
+<summary>Released packages (summary)</summary>
+
+Major releases (contain major breaking changes):
+
+* [@ckeditor/ckeditor5-easy-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-easy-image): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image): v22.0.0 => v23.0.0
+
+Minor releases (contain minor breaking changes):
+
+* [@ckeditor/ckeditor5-clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard): v22.0.0 => v23.0.0
+
+Releases containing new features:
+
+* [@ckeditor/ckeditor5-utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils): v22.0.0 => v23.0.0
+
+Other releases:
+
+* [@ckeditor/ckeditor-cloud-services-core](https://www.npmjs.com/package/@ckeditor/ckeditor-cloud-services-core): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-adapter-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-adapter-ckfinder): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-alignment](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-autoformat](https://www.npmjs.com/package/@ckeditor/ckeditor5-autoformat): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-autosave](https://www.npmjs.com/package/@ckeditor/ckeditor5-autosave): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-block-quote](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-build-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-build-balloon-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-balloon-block): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-build-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-build-decoupled-document](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-decoupled-document): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-build-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-ckfinder](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckfinder): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-cloud-services](https://www.npmjs.com/package/@ckeditor/ckeditor5-cloud-services): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-code-block](https://www.npmjs.com/package/@ckeditor/ckeditor5-code-block): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-core](https://www.npmjs.com/package/@ckeditor/ckeditor5-core): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-editor-balloon](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-balloon): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-editor-classic](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-classic): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-editor-decoupled](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-decoupled): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-editor-inline](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-enter](https://www.npmjs.com/package/@ckeditor/ckeditor5-enter): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-essentials](https://www.npmjs.com/package/@ckeditor/ckeditor5-essentials): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-font](https://www.npmjs.com/package/@ckeditor/ckeditor5-font): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-heading](https://www.npmjs.com/package/@ckeditor/ckeditor5-heading): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-highlight](https://www.npmjs.com/package/@ckeditor/ckeditor5-highlight): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-horizontal-line](https://www.npmjs.com/package/@ckeditor/ckeditor5-horizontal-line): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-media-embed](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-page-break](https://www.npmjs.com/package/@ckeditor/ckeditor5-page-break): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-paragraph](https://www.npmjs.com/package/@ckeditor/ckeditor5-paragraph): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-paste-from-office](https://www.npmjs.com/package/@ckeditor/ckeditor5-paste-from-office): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-restricted-editing](https://www.npmjs.com/package/@ckeditor/ckeditor5-restricted-editing): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-select-all](https://www.npmjs.com/package/@ckeditor/ckeditor5-select-all): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-special-characters](https://www.npmjs.com/package/@ckeditor/ckeditor5-special-characters): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-theme-lark](https://www.npmjs.com/package/@ckeditor/ckeditor5-theme-lark): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-typing](https://www.npmjs.com/package/@ckeditor/ckeditor5-typing): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-undo](https://www.npmjs.com/package/@ckeditor/ckeditor5-undo): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-upload](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-watchdog](https://www.npmjs.com/package/@ckeditor/ckeditor5-watchdog): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget): v22.0.0 => v23.0.0
+* [@ckeditor/ckeditor5-word-count](https://www.npmjs.com/package/@ckeditor/ckeditor5-word-count): v22.0.0 => v23.0.0
+</details>
+
+
 ## [22.0.0](https://github.com/ckeditor/ckeditor5/compare/v21.0.0...v22.0.0) (2020-08-26)
 
 ### Release highlights
@@ -9,24 +146,24 @@ We are happy to announce the release of CKEditor 5 v22.0.0.
 
 This release brings a few new features:
 
-* [List styles plugin](https://github.com/ckeditor/ckeditor5/issues/7801).
-* [Makrdown plugin](https://github.com/ckeditor/ckeditor5/issues/6007).
+* The [list style plugin](https://github.com/ckeditor/ckeditor5/issues/7801).
+* The [Markdown plugin](https://github.com/ckeditor/ckeditor5/issues/6007).
 * [Inserting image with URL](https://github.com/ckeditor/ckeditor5/issues/7794).
-* [New event-based conversion api](https://github.com/ckeditor/ckeditor5/issues/7336).
+* [A new event-based conversion API](https://github.com/ckeditor/ckeditor5/issues/7336).
 
 Please note that there are some **major breaking changes**. Be sure to review them before upgrading.
 
-<!-- TODO: Add a link to the blog post. -->
+Read more in the blog post: https://ckeditor.com/blog/ckeditor-5-v22.0.0-with-inserting-images-via-url-list-styles-and-markdown-plugin/
 
 ### Collaboration features
 
-The CKEditor 5 Collaboration features changelog can be found here: https://ckeditor.com/collaboration/changelog.
+The CKEditor 5 Collaboration Features changelog can be found here: https://ckeditor.com/collaboration/changelog.
 
 ### MAJOR BREAKING CHANGES [ℹ️](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html#major-and-minor-breaking-changes)
 
-* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: The `config.view` callback of `DowncastHelpers` takes a `DowncastConversionApi` instance instead of a `DowncastWriter`. An example migration snippet can be found in a [GitHub comment](https://github.com/ckeditor/ckeditor5/issues/7334#issuecomment-670450941). See [#7334](https://github.com/ckeditor/ckeditor5/issues/7334).
-* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: The `config.model` callback of `UpcastHelpers` takes a `UpcastConversionApi` instance instead of a `ModelWriter`. An example migration snippet can be found in a [GitHub comment](https://github.com/ckeditor/ckeditor5/issues/7334#issuecomment-670450941). See [#7334](https://github.com/ckeditor/ckeditor5/issues/7334).
-* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: The `config.view` parameter for upcast element-to-element conversion helpers configurations is now mandatory. You can retain previous "catch-all" behavior for upcast converter using `config.view = /[\s\S]+/` value.
+* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: The `view` and `model` callbacks of all one-way converter helpers (such as `editor.conversion.for( 'upcast' ).elementToElement()`, `editor.conversion.for( 'downcast' ).attributeToElement()`) now take the `conversionApi` as their second parameter. Previously, the second parameter was the downcast or upcast writer instance. Now, the writer needs to be retrieved from `conversionApi.writer`.<br><br>
+An example migration snippet can be found in a [GitHub comment](https://github.com/ckeditor/ckeditor5/issues/7334#issuecomment-670450941).
+* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: The `config.view` parameter for upcast element-to-element conversion helper configurations is now mandatory. You can retain the previous "catch-all" behavior for the upcast converter using the `config.view = /[\s\S]+/` value.
 
 ### MINOR BREAKING CHANGES [ℹ️](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/versioning-policy.html#major-and-minor-breaking-changes)
 
@@ -36,35 +173,35 @@ The CKEditor 5 Collaboration features changelog can be found here: https://ckedi
 ### Features
 
 * **[clipboard](https://www.npmjs.com/package/@ckeditor/ckeditor5-clipboard)**: Pasting a plain text will inherit selection attributes. Closes [#1006](https://github.com/ckeditor/ckeditor5/issues/1006). ([commit](https://github.com/ckeditor/ckeditor5/commit/2a163e389a6b22b1e5590fe6a2ed8204387d4350))
-* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Options passed to `Editor#getData()` and `DataController#get()` are now available in downcast conversion under `conversionApi.options` object. Closes [#7628](https://github.com/ckeditor/ckeditor5/issues/7628). ([commit](https://github.com/ckeditor/ckeditor5/commit/0a5d07e3c9a5cef51ebfb4a5819b5118ad9ae115))
-* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Added conversion API to upcast and downcast helpers. Closes [#7334](https://github.com/ckeditor/ckeditor5/issues/7334). ([commit](https://github.com/ckeditor/ckeditor5/commit/16c971198971b770d4e7aff4ea8eec7a88a6fcdb))
-* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Introduced `SchemaItemDefinition#isSelectable` and `SchemaItemDefinition#isContent` properties. Closes [#6432](https://github.com/ckeditor/ckeditor5/issues/6432). ([commit](https://github.com/ckeditor/ckeditor5/commit/579c1c851ca33c78de60c98777684f8ee5ceb26e))
-* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Introduced new upcast `ConversionApi` helper methods - `conversionApi.safeInsert()` and `conversionApi.updateConversionResult()`. New methods are intended to simplify writing event based element-to-element converters. Closes [#7336](https://github.com/ckeditor/ckeditor5/issues/7336). ([commit](https://github.com/ckeditor/ckeditor5/commit/8d84af1610089ea7916401ecf6f636c9d330b459))
+* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Options passed to `Editor#getData()` and `DataController#get()` are now available in downcast conversion under the `conversionApi.options` object. Closes [#7628](https://github.com/ckeditor/ckeditor5/issues/7628). ([commit](https://github.com/ckeditor/ckeditor5/commit/0a5d07e3c9a5cef51ebfb4a5819b5118ad9ae115))
+* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Added the conversion API to upcast and downcast helpers. Closes [#7334](https://github.com/ckeditor/ckeditor5/issues/7334). ([commit](https://github.com/ckeditor/ckeditor5/commit/16c971198971b770d4e7aff4ea8eec7a88a6fcdb))
+* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Introduced the `SchemaItemDefinition#isSelectable` and `SchemaItemDefinition#isContent` properties. Closes [#6432](https://github.com/ckeditor/ckeditor5/issues/6432). ([commit](https://github.com/ckeditor/ckeditor5/commit/579c1c851ca33c78de60c98777684f8ee5ceb26e))
+* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Introduced new upcast `ConversionApi` helper methods: `conversionApi.safeInsert()` and `conversionApi.updateConversionResult()`. The new methods are intended to simplify writing event-based element-to-element converters. Closes [#7336](https://github.com/ckeditor/ckeditor5/issues/7336). ([commit](https://github.com/ckeditor/ckeditor5/commit/8d84af1610089ea7916401ecf6f636c9d330b459))
 * **[image](https://www.npmjs.com/package/@ckeditor/ckeditor5-image)**: Introduced the insert image via URL feature. Closes [#7794](https://github.com/ckeditor/ckeditor5/issues/7794). ([commit](https://github.com/ckeditor/ckeditor5/commit/bb00c23f6234751666e859e6e5d7e909f194e375))
 * **[indent](https://www.npmjs.com/package/@ckeditor/ckeditor5-indent)**: Block indentation is now recognized as a formatting attribute. Closes [#2358](https://github.com/ckeditor/ckeditor5/issues/2358). ([commit](https://github.com/ckeditor/ckeditor5/commit/6b2cc25dd717eb22caf7189d8cf33511397179c0))
-* **[list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list)**: Introduced the list styles feature that allows customizing the list marker. Closes [#7801](https://github.com/ckeditor/ckeditor5/issues/7801). ([commit](https://github.com/ckeditor/ckeditor5/commit/137dd2856aecaa8f9c023e6ca9d01592707137a0))
+* **[list](https://www.npmjs.com/package/@ckeditor/ckeditor5-list)**: Introduced the list style feature that allows customizing the list marker. Closes [#7801](https://github.com/ckeditor/ckeditor5/issues/7801). ([commit](https://github.com/ckeditor/ckeditor5/commit/137dd2856aecaa8f9c023e6ca9d01592707137a0))
 * **[markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm)**: Introduced the `Markdown` plugin. Closes [#6007](https://github.com/ckeditor/ckeditor5/issues/6007). ([commit](https://github.com/ckeditor/ckeditor5/commit/7cd5fc198e1977ecefbf0e455f4b514b467e7775))
-* **[markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm)**: The markdown data processor has been revamped and got the dependencies updated. Closes [#5988](https://github.com/ckeditor/ckeditor5/issues/5988). ([commit](https://github.com/ckeditor/ckeditor5/commit/3881349eae0c9a862e76487f8eb117d6ca3e38b0))
-* **[utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils)**: Introduced the `Rect#getBoundingRect()` method that returns a `Rect` instance containing all the rectangles passed as argument. Closes [#7858](https://github.com/ckeditor/ckeditor5/issues/7858). ([commit](https://github.com/ckeditor/ckeditor5/commit/ccfaf5e54854cc8a62ebbc005e35676f77be37c4))
+* **[markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm)**: The Markdown data processor was revamped and got the dependencies updated. Closes [#5988](https://github.com/ckeditor/ckeditor5/issues/5988). ([commit](https://github.com/ckeditor/ckeditor5/commit/3881349eae0c9a862e76487f8eb117d6ca3e38b0))
+* **[utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils)**: Introduced the `Rect#getBoundingRect()` method that returns a `Rect` instance containing all the rectangles passed as an argument. Closes [#7858](https://github.com/ckeditor/ckeditor5/issues/7858). ([commit](https://github.com/ckeditor/ckeditor5/commit/ccfaf5e54854cc8a62ebbc005e35676f77be37c4))
 * **[utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils)**: Introduced the `passive` option support in the `DomEmitterMixin#listenTo()` method. Closes [#7828](https://github.com/ckeditor/ckeditor5/issues/7828). ([commit](https://github.com/ckeditor/ckeditor5/commit/a7ef65c8246b9591a9a2081cfb19266de0c6194b))
-* **[widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget)**: Keyboard vertical navigation in the text lines next to objects should move the caret to the position closest to the object. Closes [#7630](https://github.com/ckeditor/ckeditor5/issues/7630). ([commit](https://github.com/ckeditor/ckeditor5/commit/7984a14a411416634d64d405da2d6d18a314e947))
+* **[widget](https://www.npmjs.com/package/@ckeditor/ckeditor5-widget)**: Keyboard vertical navigation in text lines next to objects should move the caret to the position closest to the object. Closes [#7630](https://github.com/ckeditor/ckeditor5/issues/7630). ([commit](https://github.com/ckeditor/ckeditor5/commit/7984a14a411416634d64d405da2d6d18a314e947))
 
 ### Bug fixes
 
-* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Upcast conversion will now try to wrap text or inline elements in a paragraph in a place where is not allowed but a paragraph is allowed. Closes [#7753](https://github.com/ckeditor/ckeditor5/issues/7753), [#6698](https://github.com/ckeditor/ckeditor5/issues/6698). ([commit](https://github.com/ckeditor/ckeditor5/commit/5e857fd0ec6f4dc9e86dec0bf9c5b87289eedf8b))
+* **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: Upcast conversion will now try to wrap text or inline elements in a paragraph in a place where they are not allowed but a paragraph is allowed. Closes [#7753](https://github.com/ckeditor/ckeditor5/issues/7753), [#6698](https://github.com/ckeditor/ckeditor5/issues/6698). ([commit](https://github.com/ckeditor/ckeditor5/commit/5e857fd0ec6f4dc9e86dec0bf9c5b87289eedf8b))
 * **[engine](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)**: The selection will no longer inherit attributes from an empty inline element. Closes [#7459](https://github.com/ckeditor/ckeditor5/issues/7459). ([commit](https://github.com/ckeditor/ckeditor5/commit/1ddb955cc667ad16b41521762f77b95382f467da))
-* **[link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link)**: Fixed a case where the link balloon would point invalid place after browser scroll or resize. Closes [#7705](https://github.com/ckeditor/ckeditor5/issues/7705). ([commit](https://github.com/ckeditor/ckeditor5/commit/5158209e2a39884a3015e317f17f33a340e2502d))
+* **[link](https://www.npmjs.com/package/@ckeditor/ckeditor5-link)**: Fixed a case where the link balloon would point to an invalid place after the browser scroll or resize. Closes [#7705](https://github.com/ckeditor/ckeditor5/issues/7705). ([commit](https://github.com/ckeditor/ckeditor5/commit/5158209e2a39884a3015e317f17f33a340e2502d))
 * **[ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui)**: Dropdown panels from the editor's main toolbar should always float above the contextual balloons from the editor's content. Closes [#7874](https://github.com/ckeditor/ckeditor5/issues/7874). ([commit](https://github.com/ckeditor/ckeditor5/commit/57d3f02958ad32b8c774dbdc38e1a1210e75af1f))
 * **[ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui)**: Balloon toolbar should reposition and ungroup items correctly when the window resizes. Closes [#6444](https://github.com/ckeditor/ckeditor5/issues/6444). ([commit](https://github.com/ckeditor/ckeditor5/commit/32523780fa27146d4f74b538af4831d8b9683bd9))
-* **[utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils)**: `Rect` utility returns wrong sizes in case of a sequenced range. Closes [#7838](https://github.com/ckeditor/ckeditor5/issues/7838). ([commit](https://github.com/ckeditor/ckeditor5/commit/ccfaf5e54854cc8a62ebbc005e35676f77be37c4))
+* **[utils](https://www.npmjs.com/package/@ckeditor/ckeditor5-utils)**: The `Rect` utility returns wrong sizes in case of a sequenced range. Closes [#7838](https://github.com/ckeditor/ckeditor5/issues/7838). ([commit](https://github.com/ckeditor/ckeditor5/commit/ccfaf5e54854cc8a62ebbc005e35676f77be37c4))
 
 ### Other changes
 
 * **[markdown-gfm](https://www.npmjs.com/package/@ckeditor/ckeditor5-markdown-gfm)**: Upgraded to Marked v1.1.1. Closes [#7850](https://github.com/ckeditor/ckeditor5/issues/7850). ([commit](https://github.com/ckeditor/ckeditor5/commit/d6c8731a33f3402b8bd71b987b762116efd3898a))
-* **[mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention)**: The <kbd>space</kbd> key will not confirm a mention selection from the list. Closes [#6394](https://github.com/ckeditor/ckeditor5/issues/6394). ([commit](https://github.com/ckeditor/ckeditor5/commit/a8d41ecbbeb5d36694ba74d0391805cfaa5214e7))
+* **[mention](https://www.npmjs.com/package/@ckeditor/ckeditor5-mention)**: The <kbd>Space</kbd> key will not confirm a mention selection from the list. Closes [#6394](https://github.com/ckeditor/ckeditor5/issues/6394). ([commit](https://github.com/ckeditor/ckeditor5/commit/a8d41ecbbeb5d36694ba74d0391805cfaa5214e7))
 * **[remove-format](https://www.npmjs.com/package/@ckeditor/ckeditor5-remove-format)**: Block formatting should be removed if the selection is inside that block. ([commit](https://github.com/ckeditor/ckeditor5/commit/6b2cc25dd717eb22caf7189d8cf33511397179c0))
 * **[table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table)**: The `tableCell` model element brought by the `TableEditing` plugin is no longer an object (`SchemaItemDefinition#isObject`) in the `Schema` but a selectable (`SchemaItemDefinition#isSelectable`) (see [#6432](https://github.com/ckeditor/ckeditor5/issues/6432)). ([commit](https://github.com/ckeditor/ckeditor5/commit/579c1c851ca33c78de60c98777684f8ee5ceb26e))
-* **[table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table)**: Pressing <kbd>Shift</kbd>+<kbd>Tab</kbd> in the first table cell now selects entire table. Closes [#7535](https://github.com/ckeditor/ckeditor5/issues/7535). ([commit](https://github.com/ckeditor/ckeditor5/commit/3064c64733145b40290480f3299e168b74380d04))
+* **[table](https://www.npmjs.com/package/@ckeditor/ckeditor5-table)**: Pressing <kbd>Shift</kbd>+<kbd>Tab</kbd> in the first table cell now selects the entire table. Closes [#7535](https://github.com/ckeditor/ckeditor5/issues/7535). ([commit](https://github.com/ckeditor/ckeditor5/commit/3064c64733145b40290480f3299e168b74380d04))
 * **[ui](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui)**: The `clickOutsideHandler()` function will take into consideration that the editor can be placed in a shadow root while detecting a click. Closes [#7743](https://github.com/ckeditor/ckeditor5/issues/7743). ([commit](https://github.com/ckeditor/ckeditor5/commit/2dc026409051828618c274ae62ce331fe05681fe))
 
   Thanks to [@ywsang](https://github.com/ywsang).

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

@@ -6,11 +6,16 @@
 /* globals console, window, document */
 
 import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document/src/ckeditor';
+import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize';
 import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
 
 DecoupledEditor
 	.create( document.querySelector( '.document-editor__editable' ), {
-		cloudServices: CS_CONFIG
+		extraPlugins: [ ImageResize ],
+		cloudServices: CS_CONFIG,
+		image: {
+			toolbar: [ 'imageTextAlternative', '|', 'imageStyle:alignLeft', 'imageStyle:full', 'imageStyle:alignRight' ]
+		}
 	} )
 	.then( editor => {
 		const toolbarContainer = document.querySelector( '.document-editor__toolbar' );

+ 1 - 1
docs/_snippets/examples/multi-root-editor.html

@@ -11,7 +11,7 @@
 
 		<h4>Valletta</h4>
 
-		<figure class="image image-style-align-right">
+		<figure class="image image-style-side">
 			<img alt="Picture of a sunlit facade of a Maltan building." src="%BASE_PATH%/assets/img/malta.jpg">
 			<figcaption>It's siesta time in Valletta.</figcaption>
 		</figure>

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

@@ -404,8 +404,9 @@ MultirootEditor
 		toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'imageUpload', 'blockQuote',
 			'insertTable', 'mediaEmbed', 'undo', 'redo' ],
 		image: {
-			toolbar: [ 'imageTextAlternative', '|', 'imageStyle:alignLeft', 'imageStyle:full', 'imageStyle:alignRight' ],
-			styles: [ 'full', 'alignLeft', 'alignRight' ]
+			toolbar: [ 'imageTextAlternative', '|', 'imageStyle:full',
+				'imageStyle:side' ],
+			styles: [ 'full', 'side' ]
 		},
 		table: {
 			contentToolbar: [
@@ -430,4 +431,3 @@ MultirootEditor
 	.catch( err => {
 		console.error( err.stack );
 	} );
-

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

@@ -3,17 +3,3 @@
 
 	<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>
-
-<script>
-	(() => {
-		const linkElement = document.createElement( 'link' );
-		linkElement.href = 'https://ckeditor.com/docs/ckeditor5/21.0.0/snippets/features/mathtype/snippet.css';
-		linkElement.type = 'text/css';
-		linkElement.rel = 'stylesheet';
-		linkElement.dataset[ 'cke' ] = 'true';
-
-		document.head.appendChild( linkElement );
-	})()
-</script>
-<script src="https://ckeditor.com/docs/ckeditor5/21.0.0/assets/snippet.js"></script>
-<script src="https://ckeditor.com/docs/ckeditor5/21.0.0/snippets/features/mathtype/snippet.js"></script>

+ 62 - 1
docs/_snippets/features/mathtype.js

@@ -3,4 +3,65 @@
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
 
-/* Content removed as a workaround in #7944. Should be restored once the upstream is fixed. */
+/* globals window, document, console */
+
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
+import EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage';
+import MathType from '@wiris/mathtype-ckeditor5';
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#mathtype-editor' ), {
+		plugins: [
+			ArticlePluginSet,
+			EasyImage,
+			MathType
+		],
+		toolbar: {
+			items: [
+				'heading',
+				'|',
+				'bold',
+				'italic',
+				'bulletedList',
+				'numberedList',
+				'|',
+				'outdent',
+				'indent',
+				'|',
+				'MathType',
+				'ChemType',
+				'|',
+				'blockQuote',
+				'link',
+				'mediaEmbed',
+				'insertTable',
+				'|',
+				'undo',
+				'redo'
+			],
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		},
+		image: {
+			styles: [
+				'full',
+				'alignLeft',
+				'alignRight'
+			],
+			toolbar: [
+				'imageStyle:alignLeft',
+				'imageStyle:full',
+				'imageStyle:alignRight',
+				'|',
+				'imageTextAlternative'
+			]
+		},
+		table: {
+			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
+		},
+		cloudServices: CS_CONFIG
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 9 - 0
docs/builds/guides/frameworks/angular.md

@@ -16,6 +16,15 @@ Currently, the CKEditor 5 component for Angular supports integrating CKEditor 5
 	While there is no support to integrate CKEditor 5 from source yet, you can still {@link builds/guides/development/custom-builds create a custom build of CKEditor 5} and include it in your Angular application.
 </info-box>
 
+## Supported Angular versions
+
+Because of the breaking changes in the Angular library output format, the `ckeditor5-angular` package is released in the following versions to support various Angular ecosystems:
+
+* Versions `1.x.x` &ndash; For **Angular 5-8** applications. Support for this version will end when the official support for Angular 8 is dropped (planned date: November 2020),
+* Versions `2.x.x` &ndash; For **Angular 9.1+** applications. This version is currently actively supported.
+
+All available versions are [listed on npm](https://www.npmjs.com/package/@ckeditor/ckeditor5-angular), where they can be pulled from.
+
 ## Quick start
 
 In your existing Angular project, install the [CKEditor 5 WYSIWYG editor component for Angular](https://www.npmjs.com/package/@ckeditor/ckeditor5-angular):

+ 24 - 24
docs/builds/guides/integration/content-styles.md

@@ -48,8 +48,8 @@ Below there is a full list of content styles used by the editor features. You ca
 
 ```css
 /*
- * CKEditor 5 (v22.0.0) content styles.
- * Generated on Thu, 27 Aug 2020 12:13:06 GMT.
+ * CKEditor 5 (v23.0.0) content styles.
+ * Generated on Wed, 30 Sep 2020 10:17:57 GMT.
  * For more information, check out https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/content-styles.html
  */
 
@@ -113,6 +113,28 @@ Below there is a full list of content styles used by the editor features. You ca
 	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%);
+}
+/* ckeditor5-horizontal-line/theme/horizontalline.css */
+.ck-content hr {
+	margin: 15px 0;
+	height: 4px;
+	background: hsl(0, 0%, 87%);
+	border: 0;
+}
 /* ckeditor5-image/theme/image.css */
 .ck-content .image {
 	display: table;
@@ -174,21 +196,6 @@ Below there is a full list of content styles used by the editor features. You ca
 .ck-content .text-huge {
 	font-size: 1.8em;
 }
-/* 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%);
-}
 /* ckeditor5-table/theme/table.css */
 .ck-content .table {
 	margin: 1em auto;
@@ -332,13 +339,6 @@ Below there is a full list of content styles used by the editor features. You ca
 .ck-content .todo-list .todo-list__label .todo-list__label__description {
 	vertical-align: middle;
 }
-/* ckeditor5-horizontal-line/theme/horizontalline.css */
-.ck-content hr {
-	margin: 15px 0;
-	height: 4px;
-	background: hsl(0, 0%, 87%);
-	border: 0;
-}
 /* ckeditor5-code-block/theme/codeblock.css */
 .ck-content pre {
 	padding: 1em;

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

@@ -175,7 +175,7 @@ Note: The number of options was reduced on purpose. We understood that configuri
 			</td>
 		</tr>
 		<tr>
-			<td><a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_backStyle">colorButton_backStyle</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_colors">colorButton_colors</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_colorsPerRow">colorButton_colorsPerRow</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_enableAutomatic">colorButton_enableAutomatic</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_enableMore">colorButton_enableMore</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_foreStyle">colorButton_foreStyle</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_historyRowLimit">colorButton_historyRowLimit</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_normalizeBackground">colorButton_normalizeBackground</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-config.colorButton_renderContentColors">config.colorButton_renderContentColors</a></td>
+			<td><a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_backStyle">colorButton_backStyle</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_colors">colorButton_colors</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_colorsPerRow">colorButton_colorsPerRow</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_enableAutomatic">colorButton_enableAutomatic</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_enableMore">colorButton_enableMore</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_foreStyle">colorButton_foreStyle</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_historyRowLimit">colorButton_historyRowLimit</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_normalizeBackground">colorButton_normalizeBackground</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-colorButton_renderContentColors">config.colorButton_renderContentColors</a></td>
 			<td>
 				<p>Refer to the {@link features/font#configuring-the-font-color-and-font-background-color-features Font feature} guide to learn more about configuring font and background color in CKEditor 5.</p>
 				<p>At the same time, we also provide a new highlight plugin which allows for highlighting parts of the text with the <code>&lt;mark&gt;</code> element with different CSS classes that can be easily styled. See the {@link features/highlight Highlight feature guide} for more information .</p>
@@ -298,7 +298,7 @@ Note: The number of options was reduced on purpose. We understood that configuri
 			<td>Refer to the {@link features/easy-image Easy Image} and {@link features/image Images} feature guides to learn more about image-related features and Easy Image integration in CKEditor 5.</td>
 		</tr>
 		<tr>
-			<td><a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html##cfg-editorplaceholder">editorplaceholder</a></td>
+			<td><a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-editorplaceholder">editorplaceholder</a></td>
 			<td>Refer to the {@link features/editor-placeholder Editor placeholder} feature guide to learn more about configuring this feature in CKEditor 5.</td>
 		</tr>
 		<tr>
@@ -337,7 +337,7 @@ Note: The number of options was reduced on purpose. We understood that configuri
 			<a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-exportPdf_fileName">exportPdf_fileName</a> <br><a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-exportPdf_options">exportPdf_options</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-exportPdf_service">exportPdf_service</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-exportPdf_stylesheets">exportPdf_stylesheets</a> <br> <a href="../../../../ckeditor4/latest/api/CKEDITOR_config.html#cfg-exportPdf_tokenUrl">exportPdf_tokenUrl</a> <br>
 			</td>
 			<td>
-				Refer to the {@link features/export-pdf Export to PDF feature} guide to learn more about about configuring the HTML to PDF converter in CKEditor 5.
+				Refer to the [Export to PDF feature](https://ckeditor.com/docs/ckeditor5/latest/features/export-pdf.html) guide to learn more about about configuring the HTML to PDF converter in CKEditor 5.
 			</td>
 		</tr>
 		<tr>

+ 2 - 0
docs/features/image-upload.md

@@ -22,6 +22,8 @@ The software that makes the image upload possible is called an **upload adapter*
 * [**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.
 
+Read our comprehensive blog post about [Managing images with CKEditor 5](https://ckeditor.com/blog/managing-images-with-ckeditor-5/) to find out more details about image upload and management and to compare the available options.
+
 <info-box>
 	If you want to get a better look under the hood and learn more about the upload process, you can check out the {@link framework/guides/deep-dive/upload-adapter "Custom image upload adapter" deep dive guide} covering that topic.
 </info-box>

+ 2 - 2
docs/features/index.md

@@ -20,8 +20,8 @@ The number of features available for CKEditor 5 is constantly growing. Plenty of
 Each rich-text editor feature is presented on a separate page, with one or more working demos showcasing a feature along with some customization ideas that you can use in your implementation.
 
 <info-box>
-	**In most demos the number of features enabled is limited** to make the currently highlighted piece of functionality stand out more. However, in your CKEditor 5 WYSIWYG editor implementation you are free to choose and combine any features you like from those available.
-</info-box> 
+	**In most demos the number of features enabled is limited** to make the currently highlighted piece of functionality stand out more. However, in your CKEditor 5 WYSIWYG editor implementation you are free to choose and combine any features you like from those available. This can be easily and conveniently done in the [CKEditor 5 online builder](https://ckeditor.com/ckeditor-5/online-builder/).
+</info-box>
 
 ## Looking for more?
 

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

@@ -54,11 +54,12 @@ In order to start the manual tests server, use the `yarn run manual` task.
 
 The task accepts the following options:
 
-* `--source-map` (alias `-s`) &ndash; Whether to generate useful source maps for the code.
 * `--files` &ndash; Specifies test files to run. Accepts a package name or a glob. For example `--files=ckeditor5` will only run tests from the CKEditor 5 main package. Read more about the [rules for converting the `--files` option to a glob pattern](https://github.com/ckeditor/ckeditor5-dev/tree/master/packages/ckeditor5-dev-tests#rules-for-converting---files-option-to-glob-pattern).
-* `--additionalLanguages="ar,pl,..."` &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.
+* `--language="pl"` &ndash; The main language build in into all test editors, passed to the [CKEditor 5 webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin).  Check out the {@link features/ui-language UI language guide} to learn more. When unspecified, `'en'` is passed to the test runner.
+* `--additionalLanguages="ar,pl,..."` &ndash; Specifies extra languages passed to the [CKEditor 5 webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin). Check out the {@link features/ui-language UI language guide} to learn more.
 * `--debug` (alias `-d`) &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.
 * `--port` &ndash; Specifies the port for the server to use. Defaults to `8125`.
+* `--identityFile="/path/to/file.js"` &ndash; Path to the file containing the license key(s) for closed–source features.
 
 It starts the server available at http://localhost:8125.
 

+ 8 - 6
docs/framework/guides/support/versioning-policy.md

@@ -5,26 +5,28 @@ order: 50
 
 # Versioning policy
 
-CKEditor 5 consists of multiple npm packages (over 40, at the moment of writing this guide). When releasing them, we use the following rules:
+CKEditor 5 consists of multiple npm packages (over 50, at the moment of writing this guide). When releasing them, we use the following rules:
 
 * We use the `MAJOR.MINOR.PATCH` version identifiers.
-* Each package is versioned independently, with one exception &mdash; all packages are always in the same `MAJOR` version.
-* A major release of CKEditor 5 (i.e. of all its packages) is published when at least one of its packages must have a major release. This is to ensure the previous rule.
+* All packages are always in the same version.
+* A major release of CKEditor 5 (i.e. of all its packages) is published when at least one of its packages must have a major release.
+* A minor version of CKEditor 5 (i.e. of all its packages) is published when at least one of its packages must have a minor release and none of them require a major release.
 * A package must have a major release when it contains a *major breaking change*.
 * If none of the packages contain any *major breaking change*, the following rules are used to determine the new version of each package:
 	* If a package contains a *minor breaking change*, a `MINOR` version is increased.
 	* If a package contains a new feature, a `MINOR` version is increased.
 	* If a package contains only bug fixes, unrelated changes (e.g. updated translations), documentation or other internal changes, a `PATCH` version is increased.
+* In order to ensure that all packages are in the same version, some releases of certain packages may be empty (no changes).
 
 ## Major and minor breaking changes
 
 The ecosystem of CKEditor 5 consists of multiple layers. Our approach to breaking changes and their effect depends on which layer is affected.
 
-* **The integration layer.** This is the most commonly used API which is used to integrate and customize existing builds or editors built from source. It also includes their setup (which features are included and their default configuration).
+* **The integration layer.** This is the most commonly used API which is used to integrate and customize existing builds or editors built from source. It also includes their setup (whose features are included and their default configuration).
 	* Breaking changes frequency: as rarely as possible. Therefore, changes to this layer are usually done in a backward compatible way.
 	* A breaking change in this layer is understood as a **major breaking change**.
 * **The plugin development API layer.** This is the API exposed by packages such as {@link api/engine `@ckeditor/ckeditor5-engine`} or {@link api/core `@ckeditor/ckeditor5-core`}, which is commonly used by plugin developers.
-	* Breaking changes frequency: rarely. This layer is still frequently used by developers, therefore, we try to limit breaking changes. However, to avoid increasing the technical debt, from time to time we will introduce breaking changes to one or more packages. We also try to "batch" them in order to have as many breaking changes done in one release, to reduce the frequency of major releases.
+	* Breaking changes frequency: rarely. This layer is still frequently used by developers, therefore, we try to limit breaking changes. However, to avoid increasing the technical debt, from time to time we will introduce breaking changes to one or more packages. We also try to "batch" them in order to have as many breaking changes done in one release as possible, to reduce the frequency of major releases.
 	* A breaking change in this layer is understood as a **major breaking change**.
 * **The low-level customizability API layer.** This is the part of package APIs that allows tweaking the behavior of existing features, their UI, etc. and building other features on top of the existing ones or by using their helpers.
 	* Breaking changes frequency: frequent. This layer, while exposed by CKEditor 5 Framework, is often closely connected to the architecture of a certain feature and may expose some implementation details. We want this layer to be public as it increases the ability to reuse the code, however, we cannot guarantee its stability on the same level as in the two previous layers.
@@ -34,4 +36,4 @@ The ecosystem of CKEditor 5 consists of multiple layers. Our approach to breakin
 
 Prior to version 15.0.0 each package was versioned independently and followed the [semantic versioning (semver)](https://semver.org/). Following semver as close as possible was useful as it allowed to quickly identify what changed in each release of a certain package. However, it lead to [problems with building old versions of the editor](https://github.com/ckeditor/ckeditor5/issues/1746).
 
-Therefore, we switched to a more commonly used practice for an ecosystem of packages, which is to treat a single breaking change as a major release of all packages. It automatically fixed the aforementioned problem in all projects that use caret ranges in their `package.json` files.
+Therefore, we switched to a more commonly used practice for an ecosystem of packages, which is to treat a single breaking change as a major release of all packages. It automatically fixed the aforementioned problem in all projects that use caret ranges in their `package.json` files. Later on, we decided that it will be even more convenient for integrators if all packages are in the exact same version, which is also not uncommon (e.g. [Angular](https://github.com/angular/angular) follows this practice).

+ 1 - 1
docs/index.md

@@ -11,7 +11,7 @@ meta-description: Learn how to install, integrate, configure and develop CKEdito
 <dl><dt>{@link builds/guides/overview CKEditor 5 Builds documentation}</dt><dd>Learn how to install, integrate and configure CKEditor 5 Builds. More complex aspects, like creating custom builds, are explained here, too.</dd>
 <dt>{@link framework/guides/overview CKEditor 5 Framework documentation}</dt><dd>Learn how to work with CKEditor 5 Framework, customize it, create your own plugins and custom editors, change the UI or even bring your own UI to the editor.</dd>
 <dt>{@link examples/index CKEditor 5 Examples}</dt><dd>Try out all CKEditor 5 Builds. See some of the possible customizations of CKEditor.</dd>
-<dt>{@link features/index CKEditor 5 Features}</dt><dd>Learn about selected features included in CKEditor 5 Builds.</dd>
+<dt>{@link features/index CKEditor 5 Features}</dt><dd>Learn about the features available for CKEditor 5 &mdash; both the ones included in Builds and a plethora of others.</dd>
 <dt>{@link api/index CKEditor 5 API Reference}</dt><dd>A complete API documentation.</dd></dl>
 
 ## Contribute

+ 67 - 65
package.json

@@ -1,6 +1,6 @@
 {
   "name": "ckeditor5",
-  "version": "22.0.0",
+  "version": "23.0.0",
   "description": "The development environment of CKEditor 5 – the best browser-based rich text editor.",
   "private": true,
   "keywords": [
@@ -21,76 +21,76 @@
     "framework"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor-cloud-services-core": "^22.0.0",
-    "@ckeditor/ckeditor5-adapter-ckfinder": "^22.0.0",
-    "@ckeditor/ckeditor5-alignment": "^22.0.0",
-    "@ckeditor/ckeditor5-autoformat": "^22.0.0",
-    "@ckeditor/ckeditor5-autosave": "^22.0.0",
-    "@ckeditor/ckeditor5-basic-styles": "^22.0.0",
-    "@ckeditor/ckeditor5-block-quote": "^22.0.0",
-    "@ckeditor/ckeditor5-build-balloon": "^22.0.0",
-    "@ckeditor/ckeditor5-build-balloon-block": "^22.0.0",
-    "@ckeditor/ckeditor5-build-classic": "^22.0.0",
-    "@ckeditor/ckeditor5-build-decoupled-document": "^22.0.0",
-    "@ckeditor/ckeditor5-build-inline": "^22.0.0",
-    "@ckeditor/ckeditor5-ckfinder": "^22.0.0",
-    "@ckeditor/ckeditor5-clipboard": "^22.0.0",
-    "@ckeditor/ckeditor5-cloud-services": "^22.0.0",
-    "@ckeditor/ckeditor5-code-block": "^22.0.0",
-    "@ckeditor/ckeditor5-core": "^22.0.0",
-    "@ckeditor/ckeditor5-easy-image": "^22.0.0",
-    "@ckeditor/ckeditor5-editor-balloon": "^22.0.0",
-    "@ckeditor/ckeditor5-editor-classic": "^22.0.0",
-    "@ckeditor/ckeditor5-editor-decoupled": "^22.0.0",
-    "@ckeditor/ckeditor5-editor-inline": "^22.0.0",
-    "@ckeditor/ckeditor5-engine": "^22.0.0",
-    "@ckeditor/ckeditor5-enter": "^22.0.0",
-    "@ckeditor/ckeditor5-essentials": "^22.0.0",
-    "@ckeditor/ckeditor5-font": "^22.0.0",
-    "@ckeditor/ckeditor5-heading": "^22.0.0",
-    "@ckeditor/ckeditor5-highlight": "^22.0.0",
-    "@ckeditor/ckeditor5-horizontal-line": "^22.0.0",
-    "@ckeditor/ckeditor5-image": "^22.0.0",
-    "@ckeditor/ckeditor5-indent": "^22.0.0",
-    "@ckeditor/ckeditor5-link": "^22.0.0",
-    "@ckeditor/ckeditor5-list": "^22.0.0",
-    "@ckeditor/ckeditor5-markdown-gfm": "^22.0.0",
-    "@ckeditor/ckeditor5-media-embed": "^22.0.0",
-    "@ckeditor/ckeditor5-mention": "^22.0.0",
-    "@ckeditor/ckeditor5-page-break": "^22.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^22.0.0",
-    "@ckeditor/ckeditor5-paste-from-office": "^22.0.0",
-    "@ckeditor/ckeditor5-remove-format": "^22.0.0",
-    "@ckeditor/ckeditor5-restricted-editing": "^22.0.0",
-    "@ckeditor/ckeditor5-select-all": "^22.0.0",
-    "@ckeditor/ckeditor5-special-characters": "^22.0.0",
-    "@ckeditor/ckeditor5-table": "^22.0.0",
-    "@ckeditor/ckeditor5-theme-lark": "^22.0.0",
-    "@ckeditor/ckeditor5-typing": "^22.0.0",
-    "@ckeditor/ckeditor5-ui": "^22.0.0",
-    "@ckeditor/ckeditor5-undo": "^22.0.0",
-    "@ckeditor/ckeditor5-upload": "^22.0.0",
-    "@ckeditor/ckeditor5-utils": "^22.0.0",
-    "@ckeditor/ckeditor5-watchdog": "^22.0.0",
-    "@ckeditor/ckeditor5-widget": "^22.0.0",
-    "@ckeditor/ckeditor5-word-count": "^22.0.0"
+    "@ckeditor/ckeditor-cloud-services-core": "^23.0.0",
+    "@ckeditor/ckeditor5-adapter-ckfinder": "^23.0.0",
+    "@ckeditor/ckeditor5-alignment": "^23.0.0",
+    "@ckeditor/ckeditor5-autoformat": "^23.0.0",
+    "@ckeditor/ckeditor5-autosave": "^23.0.0",
+    "@ckeditor/ckeditor5-basic-styles": "^23.0.0",
+    "@ckeditor/ckeditor5-block-quote": "^23.0.0",
+    "@ckeditor/ckeditor5-build-balloon": "^23.0.0",
+    "@ckeditor/ckeditor5-build-balloon-block": "^23.0.0",
+    "@ckeditor/ckeditor5-build-classic": "^23.0.0",
+    "@ckeditor/ckeditor5-build-decoupled-document": "^23.0.0",
+    "@ckeditor/ckeditor5-build-inline": "^23.0.0",
+    "@ckeditor/ckeditor5-ckfinder": "^23.0.0",
+    "@ckeditor/ckeditor5-clipboard": "^23.0.0",
+    "@ckeditor/ckeditor5-cloud-services": "^23.0.0",
+    "@ckeditor/ckeditor5-code-block": "^23.0.0",
+    "@ckeditor/ckeditor5-core": "^23.0.0",
+    "@ckeditor/ckeditor5-easy-image": "^23.0.0",
+    "@ckeditor/ckeditor5-editor-balloon": "^23.0.0",
+    "@ckeditor/ckeditor5-editor-classic": "^23.0.0",
+    "@ckeditor/ckeditor5-editor-decoupled": "^23.0.0",
+    "@ckeditor/ckeditor5-editor-inline": "^23.0.0",
+    "@ckeditor/ckeditor5-engine": "^23.0.0",
+    "@ckeditor/ckeditor5-enter": "^23.0.0",
+    "@ckeditor/ckeditor5-essentials": "^23.0.0",
+    "@ckeditor/ckeditor5-font": "^23.0.0",
+    "@ckeditor/ckeditor5-heading": "^23.0.0",
+    "@ckeditor/ckeditor5-highlight": "^23.0.0",
+    "@ckeditor/ckeditor5-horizontal-line": "^23.0.0",
+    "@ckeditor/ckeditor5-image": "^23.0.0",
+    "@ckeditor/ckeditor5-indent": "^23.0.0",
+    "@ckeditor/ckeditor5-link": "^23.0.0",
+    "@ckeditor/ckeditor5-list": "^23.0.0",
+    "@ckeditor/ckeditor5-markdown-gfm": "^23.0.0",
+    "@ckeditor/ckeditor5-media-embed": "^23.0.0",
+    "@ckeditor/ckeditor5-mention": "^23.0.0",
+    "@ckeditor/ckeditor5-page-break": "^23.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^23.0.0",
+    "@ckeditor/ckeditor5-paste-from-office": "^23.0.0",
+    "@ckeditor/ckeditor5-remove-format": "^23.0.0",
+    "@ckeditor/ckeditor5-restricted-editing": "^23.0.0",
+    "@ckeditor/ckeditor5-select-all": "^23.0.0",
+    "@ckeditor/ckeditor5-special-characters": "^23.0.0",
+    "@ckeditor/ckeditor5-table": "^23.0.0",
+    "@ckeditor/ckeditor5-theme-lark": "^23.0.0",
+    "@ckeditor/ckeditor5-typing": "^23.0.0",
+    "@ckeditor/ckeditor5-ui": "^23.0.0",
+    "@ckeditor/ckeditor5-undo": "^23.0.0",
+    "@ckeditor/ckeditor5-upload": "^23.0.0",
+    "@ckeditor/ckeditor5-utils": "^23.0.0",
+    "@ckeditor/ckeditor5-watchdog": "^23.0.0",
+    "@ckeditor/ckeditor5-widget": "^23.0.0",
+    "@ckeditor/ckeditor5-word-count": "^23.0.0"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-comments": "^22.0.0",
+    "@ckeditor/ckeditor5-comments": "^23.0.0",
     "@ckeditor/ckeditor5-dev-docs": "^23.2.0",
     "@ckeditor/ckeditor5-dev-env": "^23.2.0",
-    "@ckeditor/ckeditor5-dev-tests": "^23.2.0",
+    "@ckeditor/ckeditor5-dev-tests": "^23.3.0",
     "@ckeditor/ckeditor5-dev-utils": "^23.2.0",
     "@ckeditor/ckeditor5-dev-webpack-plugin": "^23.2.0",
-    "@ckeditor/ckeditor5-export-pdf": "^1.0.1",
-    "@ckeditor/ckeditor5-export-word": "^1.0.0",
+    "@ckeditor/ckeditor5-export-pdf": ">=1.0.0",
+    "@ckeditor/ckeditor5-export-word": ">=1.0.0",
     "@ckeditor/ckeditor5-inspector": "^2.2.0",
-    "@ckeditor/ckeditor5-pagination": "^0.0.3",
+    "@ckeditor/ckeditor5-pagination": ">=1.0.0",
     "@ckeditor/ckeditor5-react": "^2.1.0",
-    "@ckeditor/ckeditor5-real-time-collaboration": "^22.0.0",
-    "@ckeditor/ckeditor5-track-changes": "^22.0.0",
+    "@ckeditor/ckeditor5-real-time-collaboration": "^23.0.0",
+    "@ckeditor/ckeditor5-track-changes": "^23.0.0",
     "@webspellchecker/wproofreader-ckeditor5": "^1.0.5",
-    "@wiris/mathtype-ckeditor5": "7.20.0",
+    "@wiris/mathtype-ckeditor5": "^7.24.0",
     "babel-standalone": "^6.26.0",
     "coveralls": "^3.1.0",
     "css-loader": "^3.5.3",
@@ -132,7 +132,7 @@
   },
   "scripts": {
     "lint": "eslint --quiet '**/*.js'",
-    "stylelint": "stylelint --quiet --allow-empty-input 'packages/**/*.css' 'external/*/packages/**/*.css' 'docs/**/*.css'",
+    "stylelint": "stylelint --quiet --allow-empty-input 'packages/**/*.css' 'docs/**/*.css'",
     "test": "node --max_old_space_size=8192 node_modules/@ckeditor/ckeditor5-dev-tests/bin/test.js",
     "manual": "node --max_old_space_size=8192 node_modules/@ckeditor/ckeditor5-dev-tests/bin/test-manual.js",
     "bootstrap": "yarn install",
@@ -176,8 +176,10 @@
       "packages/*",
       "external/*",
       "external/*/packages/*",
-      "external/*/packages/**/ckeditor5",
-      "external/*/packages/**/frontend",
+      "external/*/external/*",
+      "external/*/external/*/packages/*",
+      "external/*/external/*/packages/**/ckeditor5",
+      "external/*/external/*/packages/**/frontend",
       "."
     ],
     "nohoist": [

+ 2 - 2
packages/ckeditor-cloud-services-core/package.json

@@ -1,13 +1,13 @@
 {
   "name": "@ckeditor/ckeditor-cloud-services-core",
-  "version": "22.0.0",
+  "version": "23.0.0",
   "description": "CKEditor Cloud Services Core API.",
   "keywords": [
     "ckeditor5",
     "ckeditor5-lib"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-utils": "^22.0.0"
+    "@ckeditor/ckeditor5-utils": "^23.0.0"
   },
   "engines": {
     "node": ">=12.0.0",

+ 77 - 18
packages/ckeditor-cloud-services-core/src/token/token.js

@@ -7,13 +7,14 @@
  * @module cloud-services-core/token
  */
 
-/* globals XMLHttpRequest, setInterval, clearInterval */
+/* globals XMLHttpRequest, setTimeout, clearTimeout, atob */
 
 import mix from '@ckeditor/ckeditor5-utils/src/mix';
 import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
-const DEFAULT_OPTIONS = { refreshInterval: 3600000, autoRefresh: true };
+const DEFAULT_OPTIONS = { autoRefresh: true };
+const DEFAULT_TOKEN_REFRESH_TIMEOUT_TIME = 3600000;
 
 /**
  * Class representing the token used for communication with CKEditor Cloud Services.
@@ -30,7 +31,6 @@ class Token {
 	 * value is a function it has to match the {@link module:cloud-services-core/token~refreshToken} interface.
 	 * @param {Object} options
 	 * @param {String} [options.initValue] Initial value of the token.
-	 * @param {Number} [options.refreshInterval=3600000] Delay between refreshes. Default 1 hour.
 	 * @param {Boolean} [options.autoRefresh=true] Specifies whether to start the refresh automatically.
 	 */
 	constructor( tokenUrlOrRefreshToken, options = DEFAULT_OPTIONS ) {
@@ -41,11 +41,15 @@ class Token {
 			 * @error token-missing-token-url
 			 */
 			throw new CKEditorError(
-				'token-missing-token-url: A `tokenUrl` must be provided as the first constructor argument.',
+				'token-missing-token-url',
 				this
 			);
 		}
 
+		if ( options.initValue ) {
+			this._validateTokenValue( options.initValue );
+		}
+
 		/**
 		 * Value of the token.
 		 * The value of the token is null if `initValue` is not provided or `init` method was not called.
@@ -84,10 +88,6 @@ class Token {
 	 */
 	init() {
 		return new Promise( ( resolve, reject ) => {
-			if ( this._options.autoRefresh ) {
-				this._startRefreshing();
-			}
-
 			if ( !this.value ) {
 				this.refreshToken()
 					.then( resolve )
@@ -96,6 +96,10 @@ class Token {
 				return;
 			}
 
+			if ( this._options.autoRefresh ) {
+				this._registerRefreshTokenTimeout();
+			}
+
 			resolve( this );
 		} );
 	}
@@ -106,7 +110,14 @@ class Token {
 	 */
 	refreshToken() {
 		return this._refresh()
-			.then( value => this.set( 'value', value ) )
+			.then( value => {
+				this._validateTokenValue( value );
+				this.set( 'value', value );
+
+				if ( this._options.autoRefresh ) {
+					this._registerRefreshTokenTimeout();
+				}
+			} )
 			.then( () => this );
 	}
 
@@ -114,25 +125,74 @@ class Token {
 	 * Destroys token instance. Stops refreshing.
 	 */
 	destroy() {
-		this._stopRefreshing();
+		clearTimeout( this._tokenRefreshTimeout );
+	}
+
+	/**
+	 * Checks whether the provided token follows the JSON Web Tokens (JWT) format.
+	 *
+	 * @protected
+	 * @param {String} tokenValue The token to validate.
+	 */
+	_validateTokenValue( tokenValue ) {
+		// The token must be a string.
+		const isString = typeof tokenValue === 'string';
+
+		// The token must be a plain string without quotes ("").
+		const isPlainString = !/^".*"$/.test( tokenValue );
+
+		// JWT token contains 3 parts: header, payload, and signature.
+		// Each part is separated by a dot.
+		const isJWTFormat = isString && tokenValue.split( '.' ).length === 3;
+
+		if ( !( isPlainString && isJWTFormat ) ) {
+			/**
+			 * The provided token must follow the [JSON Web Tokens](https://jwt.io/introduction/) format.
+			 *
+			 * @error token-not-in-jwt-format
+			 */
+			throw new CKEditorError( 'token-not-in-jwt-format', this );
+		}
 	}
 
 	/**
-	 * Starts value refreshing every `refreshInterval` time.
+	 * Registers a refresh token timeout for the time taken from token.
 	 *
 	 * @protected
 	 */
-	_startRefreshing() {
-		this._refreshInterval = setInterval( () => this.refreshToken(), this._options.refreshInterval );
+	_registerRefreshTokenTimeout() {
+		const tokenRefreshTimeoutTime = this._getTokenRefreshTimeoutTime();
+
+		clearTimeout( this._tokenRefreshTimeout );
+
+		this._tokenRefreshTimeout = setTimeout( () => {
+			this.refreshToken();
+		}, tokenRefreshTimeoutTime );
 	}
 
 	/**
-	 * Stops value refreshing.
+	 * Returns token refresh timeout time calculated from expire time in the token payload.
+	 *
+	 * If the token parse fails or the token payload doesn't contain, the default DEFAULT_TOKEN_REFRESH_TIMEOUT_TIME is returned.
 	 *
 	 * @protected
+	 * @returns {Number}
 	 */
-	_stopRefreshing() {
-		clearInterval( this._refreshInterval );
+	_getTokenRefreshTimeoutTime() {
+		try {
+			const [ , binaryTokenPayload ] = this.value.split( '.' );
+			const { exp: tokenExpireTime } = JSON.parse( atob( binaryTokenPayload ) );
+
+			if ( !tokenExpireTime ) {
+				return DEFAULT_TOKEN_REFRESH_TIMEOUT_TIME;
+			}
+
+			const tokenRefreshTimeoutTime = Math.floor( ( ( tokenExpireTime * 1000 ) - Date.now() ) / 2 );
+
+			return tokenRefreshTimeoutTime;
+		} catch ( err ) {
+			return DEFAULT_TOKEN_REFRESH_TIMEOUT_TIME;
+		}
 	}
 
 	/**
@@ -142,7 +202,6 @@ class Token {
 	 * value is a function it has to match the {@link module:cloud-services-core/token~refreshToken} interface.
 	 * @param {Object} options
 	 * @param {String} [options.initValue] Initial value of the token.
-	 * @param {Number} [options.refreshInterval=3600000] Delay between refreshes. Default 1 hour.
 	 * @param {Boolean} [options.autoRefresh=true] Specifies whether to start the refresh automatically.
 	 * @returns {Promise.<module:cloud-services-core/token~Token>}
 	 */
@@ -185,7 +244,7 @@ function defaultRefreshToken( tokenUrl ) {
 				 * @error token-cannot-download-new-token
 				 */
 				return reject(
-					new CKEditorError( 'token-cannot-download-new-token: Cannot download new token from the provided url.', null )
+					new CKEditorError( 'token-cannot-download-new-token', null )
 				);
 			}
 

+ 5 - 5
packages/ckeditor-cloud-services-core/src/uploadgateway/fileuploader.js

@@ -33,7 +33,7 @@ export default class FileUploader {
 			 *
 			 * @error fileuploader-missing-file
 			 */
-			throw new CKEditorError( 'fileuploader-missing-file: File must be provided as the first argument', null );
+			throw new CKEditorError( 'fileuploader-missing-file', null );
 		}
 
 		if ( !token ) {
@@ -42,7 +42,7 @@ export default class FileUploader {
 			 *
 			 * @error fileuploader-missing-token
 			 */
-			throw new CKEditorError( 'fileuploader-missing-token: Token must be provided as the second argument.', null );
+			throw new CKEditorError( 'fileuploader-missing-token', null );
 		}
 
 		if ( !apiAddress ) {
@@ -51,7 +51,7 @@ export default class FileUploader {
 			 *
 			 * @error fileuploader-missing-api-address
 			 */
-			throw new CKEditorError( 'fileuploader-missing-api-address: Api address must be provided as the third argument.', null );
+			throw new CKEditorError( 'fileuploader-missing-api-address', null );
 		}
 
 		/**
@@ -201,7 +201,7 @@ export default class FileUploader {
 						 * @error fileuploader-uploading-data-failed
 						 */
 						return reject( new CKEditorError(
-							'fileuploader-uploading-data-failed: Uploading file failed.',
+							'fileuploader-uploading-data-failed',
 							this,
 							{ message: xhrResponse.message }
 						) );
@@ -270,7 +270,7 @@ function _base64ToBlob( base64, sliceSize = 512 ) {
 		 *
 		 * @error fileuploader-decoding-image-data-error
 		 */
-		throw new CKEditorError( 'fileuploader-decoding-image-data-error: Problem with decoding Base64 image data.', null );
+		throw new CKEditorError( 'fileuploader-decoding-image-data-error', null );
 	}
 }
 

+ 2 - 2
packages/ckeditor-cloud-services-core/src/uploadgateway/uploadgateway.js

@@ -27,7 +27,7 @@ export default class UploadGateway {
 			 *
 			 * @error uploadgateway-missing-token
 			 */
-			throw new CKEditorError( 'uploadgateway-missing-token: Token must be provided.', null );
+			throw new CKEditorError( 'uploadgateway-missing-token', null );
 		}
 
 		if ( !apiAddress ) {
@@ -36,7 +36,7 @@ export default class UploadGateway {
 			 *
 			 * @error uploadgateway-missing-api-address
 			 */
-			throw new CKEditorError( 'uploadgateway-missing-api-address: Api address must be provided.', null );
+			throw new CKEditorError( 'uploadgateway-missing-api-address', null );
 		}
 
 		/**

+ 202 - 103
packages/ckeditor-cloud-services-core/tests/token/token.js

@@ -26,31 +26,56 @@ describe( 'Token', () => {
 	} );
 
 	describe( 'constructor()', () => {
-		it( 'should throw error when no tokenUrl provided', () => {
+		it( 'should throw an error when no tokenUrl provided', () => {
 			expect( () => new Token() ).to.throw(
 				CKEditorError,
 				'token-missing-token-url'
 			);
 		} );
 
-		it( 'should set a init token value', () => {
-			const token = new Token( 'http://token-endpoint', { initValue: 'initValue', autoRefresh: false } );
+		it( 'should throw an error if the token passed in options is not a string', () => {
+			expect( () => new Token( 'http://token-endpoint', { initValue: 123456 } ) ).to.throw(
+				CKEditorError,
+				'token-not-in-jwt-format'
+			);
+		} );
+
+		it( 'should throw an error if the token passed in options is wrapped in additional quotes', () => {
+			const tokenInitValue = getTestTokenValue();
+
+			expect( () => new Token( 'http://token-endpoint', { initValue: `"${ tokenInitValue }"` } ) ).to.throw(
+				CKEditorError,
+				'token-not-in-jwt-format'
+			);
+		} );
 
-			expect( token.value ).to.equal( 'initValue' );
+		it( 'should throw an error if the token passed in options is not a valid JWT token', () => {
+			expect( () => new Token( 'http://token-endpoint', { initValue: 'token' } ) ).to.throw(
+				CKEditorError,
+				'token-not-in-jwt-format'
+			);
+		} );
+
+		it( 'should set token value if the token passed in options is valid', () => {
+			const tokenInitValue = getTestTokenValue();
+			const token = new Token( 'http://token-endpoint', { initValue: tokenInitValue } );
+
+			expect( token.value ).to.equal( tokenInitValue );
 		} );
 
 		it( 'should fire `change:value` event if the value of the token has changed', done => {
+			const tokenValue = getTestTokenValue();
 			const token = new Token( 'http://token-endpoint', { autoRefresh: false } );
 
 			token.on( 'change:value', ( event, name, newValue ) => {
-				expect( newValue ).to.equal( 'token-value' );
+				expect( newValue ).to.equal( tokenValue );
 
 				done();
 			} );
 
 			token.init();
 
-			requests[ 0 ].respond( 200, '', 'token-value' );
+			requests[ 0 ].respond( 200, '', tokenValue );
 		} );
 
 		it( 'should accept the callback in the constructor', () => {
@@ -62,98 +87,205 @@ describe( 'Token', () => {
 	} );
 
 	describe( 'init()', () => {
-		it( 'should get a token value from endpoint', done => {
+		it( 'should get a token value from the endpoint', done => {
+			const tokenValue = getTestTokenValue();
 			const token = new Token( 'http://token-endpoint', { autoRefresh: false } );
 
 			token.init()
 				.then( () => {
-					expect( token.value ).to.equal( 'token-value' );
+					expect( token.value ).to.equal( tokenValue );
 
 					done();
 				} );
 
-			requests[ 0 ].respond( 200, '', 'token-value' );
+			requests[ 0 ].respond( 200, '', tokenValue );
 		} );
 
 		it( 'should get a token from the refreshToken function when is provided', () => {
-			const token = new Token( () => Promise.resolve( 'token-value' ), { autoRefresh: false } );
+			const tokenValue = getTestTokenValue();
+			const token = new Token( () => Promise.resolve( tokenValue ), { autoRefresh: false } );
 
 			return token.init()
 				.then( () => {
-					expect( token.value ).to.equal( 'token-value' );
+					expect( token.value ).to.equal( tokenValue );
 				} );
 		} );
 
-		it( 'should start token refresh every 1 hour', done => {
-			const clock = sinon.useFakeTimers( { toFake: [ 'setInterval' ] } );
+		it( 'should not refresh token if autoRefresh is disabled in options', async () => {
+			const clock = sinon.useFakeTimers( { toFake: [ 'setTimeout' ] } );
+			const tokenInitValue = getTestTokenValue();
 
-			const token = new Token( 'http://token-endpoint', { initValue: 'initValue' } );
+			const token = new Token( 'http://token-endpoint', { initValue: tokenInitValue, autoRefresh: false } );
 
-			token.init()
-				.then( () => {
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
+			await token.init();
 
-					expect( requests.length ).to.equal( 5 );
+			await clock.tickAsync( 3600000 );
 
-					clock.restore();
+			expect( requests ).to.be.empty;
 
-					done();
-				} );
+			clock.restore();
+		} );
+
+		it( 'should refresh token with the time specified in token `exp` payload property', async () => {
+			const clock = sinon.useFakeTimers( { toFake: [ 'setTimeout' ] } );
+			const tokenInitValue = getTestTokenValue();
+
+			const token = new Token( 'http://token-endpoint', { initValue: tokenInitValue } );
+
+			await token.init();
+
+			await clock.tickAsync( 1800000 );
+			requests[ 0 ].respond( 200, '', getTestTokenValue( 1500 ) );
+
+			await clock.tickAsync( 750000 );
+			requests[ 1 ].respond( 200, '', getTestTokenValue( 900 ) );
+
+			await clock.tickAsync( 450000 );
+			requests[ 2 ].respond( 200, '', getTestTokenValue( 450 ) );
+
+			await clock.tickAsync( 225000 );
+			requests[ 3 ].respond( 200, '', getTestTokenValue( 20 ) );
+
+			await clock.tickAsync( 10000 );
+			requests[ 4 ].respond( 200, '', getTestTokenValue( 20 ) );
+
+			expect( requests.length ).to.equal( 5 );
+
+			clock.restore();
+		} );
+
+		it( 'should refresh the token with the default time if getting token expiration time failed', async () => {
+			const clock = sinon.useFakeTimers( { toFake: [ 'setTimeout' ] } );
+			const tokenValue = 'header.test.signature';
+
+			const token = new Token( 'http://token-endpoint', { initValue: tokenValue } );
+
+			await token.init();
+
+			await clock.tickAsync( 3600000 );
+			requests[ 0 ].respond( 200, '', tokenValue );
+
+			await clock.tickAsync( 3600000 );
+			requests[ 1 ].respond( 200, '', tokenValue );
+
+			expect( requests.length ).to.equal( 2 );
+
+			clock.restore();
+		} );
+
+		it( 'should refresh the token with the default time if the token payload does not contain `exp` property', async () => {
+			const clock = sinon.useFakeTimers( { toFake: [ 'setTimeout' ] } );
+			const tokenValue = `header.${ btoa( JSON.stringify( {} ) ) }.signature`;
+
+			const token = new Token( 'http://token-endpoint', { initValue: tokenValue } );
+
+			await token.init();
+
+			await clock.tickAsync( 3600000 );
+			requests[ 0 ].respond( 200, '', tokenValue );
+
+			await clock.tickAsync( 3600000 );
+			requests[ 1 ].respond( 200, '', tokenValue );
+
+			await clock.tickAsync( 3600000 );
+			requests[ 2 ].respond( 200, '', tokenValue );
+
+			expect( requests.length ).to.equal( 3 );
+
+			clock.restore();
 		} );
 	} );
 
 	describe( 'destroy', () => {
-		it( 'should stop refreshing the token', () => {
-			const clock = sinon.useFakeTimers( { toFake: [ 'setInterval', 'clearInterval' ] } );
-			const token = new Token( 'http://token-endpoint', { initValue: 'initValue' } );
+		it( 'should stop refreshing the token', async () => {
+			const clock = sinon.useFakeTimers( { toFake: [ 'setTimeout', 'clearTimeout' ] } );
+			const tokenInitValue = getTestTokenValue();
 
-			return token.init()
-				.then( () => {
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
+			const token = new Token( 'http://token-endpoint', { initValue: tokenInitValue } );
 
-					expect( requests.length ).to.equal( 2 );
+			await token.init();
 
-					token.destroy();
+			await clock.tickAsync( 1800000 );
+			requests[ 0 ].respond( 200, '', getTestTokenValue( 1500 ) );
+			await clock.tickAsync( 100 );
 
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
+			await clock.tickAsync( 750000 );
+			requests[ 1 ].respond( 200, '', getTestTokenValue( 900 ) );
+			await clock.tickAsync( 100 );
 
-					expect( requests.length ).to.equal( 2 );
-				} );
+			token.destroy();
+
+			await clock.tickAsync( 3600000 );
+			await clock.tickAsync( 3600000 );
+			await clock.tickAsync( 3600000 );
+
+			expect( requests.length ).to.equal( 2 );
+
+			clock.restore();
 		} );
 	} );
 
 	describe( 'refreshToken()', () => {
 		it( 'should get a token from the specified address', done => {
-			const token = new Token( 'http://token-endpoint', { initValue: 'initValue', autoRefresh: false } );
+			const tokenValue = getTestTokenValue();
+			const token = new Token( 'http://token-endpoint', { autoRefresh: false } );
 
 			token.refreshToken()
 				.then( newToken => {
-					expect( newToken.value ).to.equal( 'token-value' );
+					expect( newToken.value ).to.equal( tokenValue );
 
 					done();
 				} );
 
-			requests[ 0 ].respond( 200, '', 'token-value' );
+			requests[ 0 ].respond( 200, '', tokenValue );
+		} );
+
+		it( 'should throw an error if the returned token is wrapped in additional quotes', done => {
+			const tokenValue = getTestTokenValue();
+			const token = new Token( 'http://token-endpoint', { autoRefresh: false } );
+
+			token.refreshToken()
+				.then( () => {
+					done( new Error( 'Promise should be rejected' ) );
+				} )
+				.catch( error => {
+					expect( error.constructor ).to.equal( CKEditorError );
+					expect( error ).to.match( /token-not-in-jwt-format/ );
+					done();
+				} );
+
+			requests[ 0 ].respond( 200, '', `"${ tokenValue }"` );
+		} );
+
+		it( 'should throw an error if the returned token is not a valid JWT token', done => {
+			const token = new Token( 'http://token-endpoint', { autoRefresh: false } );
+
+			token.refreshToken()
+				.then( () => {
+					done( new Error( 'Promise should be rejected' ) );
+				} )
+				.catch( error => {
+					expect( error.constructor ).to.equal( CKEditorError );
+					expect( error ).to.match( /token-not-in-jwt-format/ );
+					done();
+				} );
+
+			requests[ 0 ].respond( 200, '', 'token' );
 		} );
 
 		it( 'should get a token from the specified callback function', () => {
-			const token = new Token( () => Promise.resolve( 'token-value' ), { initValue: 'initValue', autoRefresh: false } );
+			const tokenValue = getTestTokenValue();
+			const token = new Token( () => Promise.resolve( tokenValue ), { autoRefresh: false } );
 
 			return token.refreshToken()
 				.then( newToken => {
-					expect( newToken.value ).to.equal( 'token-value' );
+					expect( newToken.value ).to.equal( tokenValue );
 				} );
 		} );
 
-		it( 'should throw an error when cannot download new token', () => {
-			const token = new Token( 'http://token-endpoint', { initValue: 'initValue', autoRefresh: false } );
+		it( 'should throw an error when cannot download a new token', () => {
+			const tokenInitValue = getTestTokenValue();
+			const token = new Token( 'http://token-endpoint', { initValue: tokenInitValue, autoRefresh: false } );
 			const promise = token._refresh();
 
 			requests[ 0 ].respond( 401 );
@@ -167,7 +299,8 @@ describe( 'Token', () => {
 		} );
 
 		it( 'should throw an error when the response is aborted', () => {
-			const token = new Token( 'http://token-endpoint', { initValue: 'initValue', autoRefresh: false } );
+			const tokenInitValue = getTestTokenValue();
+			const token = new Token( 'http://token-endpoint', { initValue: tokenInitValue, autoRefresh: false } );
 			const promise = token._refresh();
 
 			requests[ 0 ].abort();
@@ -180,7 +313,8 @@ describe( 'Token', () => {
 		} );
 
 		it( 'should throw an error when network error occurs', () => {
-			const token = new Token( 'http://token-endpoint', { initValue: 'initValue', autoRefresh: false } );
+			const tokenInitValue = getTestTokenValue();
+			const token = new Token( 'http://token-endpoint', { initValue: tokenInitValue, autoRefresh: false } );
 			const promise = token._refresh();
 
 			requests[ 0 ].error();
@@ -192,8 +326,9 @@ describe( 'Token', () => {
 			} );
 		} );
 
-		it( 'should throw an error when the callback throws error', () => {
-			const token = new Token( () => Promise.reject( 'Custom error occurred' ), { initValue: 'initValue', autoRefresh: false } );
+		it( 'should throw an error when the callback throws an error', () => {
+			const tokenInitValue = getTestTokenValue();
+			const token = new Token( () => Promise.reject( 'Custom error occurred' ), { initValue: tokenInitValue, autoRefresh: false } );
 
 			token.refreshToken()
 				.catch( error => {
@@ -202,75 +337,39 @@ describe( 'Token', () => {
 		} );
 	} );
 
-	describe( '_startRefreshing()', () => {
-		it( 'should start refreshing', () => {
-			const clock = sinon.useFakeTimers( { toFake: [ 'setInterval' ] } );
-
-			const token = new Token( 'http://token-endpoint', { initValue: 'initValue', autoRefresh: false } );
-
-			token._startRefreshing();
-
-			clock.tick( 3600000 );
-			clock.tick( 3600000 );
-			clock.tick( 3600000 );
-			clock.tick( 3600000 );
-			clock.tick( 3600000 );
-
-			expect( requests.length ).to.equal( 5 );
-
-			clock.restore();
-		} );
-	} );
-
-	describe( '_stopRefreshing()', () => {
-		it( 'should stop refreshing', done => {
-			const clock = sinon.useFakeTimers( { toFake: [ 'setInterval', 'clearInterval' ] } );
-
-			const token = new Token( 'http://token-endpoint', { initValue: 'initValue' } );
-
-			token.init()
-				.then( () => {
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
-
-					token._stopRefreshing();
-
-					clock.tick( 3600000 );
-					clock.tick( 3600000 );
-
-					expect( requests.length ).to.equal( 3 );
-
-					clock.restore();
-
-					done();
-				} );
-		} );
-	} );
-
 	describe( 'static create()', () => {
-		it( 'should return a initialized token', done => {
+		it( 'should return an initialized token', done => {
+			const tokenValue = getTestTokenValue();
+
 			Token.create( 'http://token-endpoint', { autoRefresh: false } )
 				.then( token => {
-					expect( token.value ).to.equal( 'token-value' );
+					expect( token.value ).to.equal( tokenValue );
 
 					done();
 				} );
 
-			requests[ 0 ].respond( 200, '', 'token-value' );
+			requests[ 0 ].respond( 200, '', tokenValue );
 		} );
 
 		it( 'should use default options when none passed', done => {
-			const intervalSpy = sinon.spy( window, 'setInterval' );
+			const tokenValue = getTestTokenValue();
 
 			Token.create( 'http://token-endpoint' )
-				.then( () => {
-					expect( intervalSpy.args[ 0 ][ 1 ] ).to.equal( 3600000 );
+				.then( token => {
+					expect( token._options ).to.eql( { autoRefresh: true } );
 
 					done();
 				} );
 
-			requests[ 0 ].respond( 200, '', 'token-value' );
+			requests[ 0 ].respond( 200, '', tokenValue );
 		} );
 	} );
 } );
+
+// Returns valid token for tests with given expiration time offset.
+//
+// @param {Number} [timeOffset=3600000]
+// @returns {String}
+function getTestTokenValue( timeOffset = 3600 ) {
+	return `header.${ btoa( JSON.stringify( { exp: ( Math.floor( Date.now() / 1000 ) ) + timeOffset } ) ) }.signature`;
+}

+ 6 - 2
packages/ckeditor-cloud-services-core/tests/uploadgateway/fileuploader.js

@@ -14,7 +14,8 @@ const BASE_64_FILE = 'data:image/gif;base64,R0lGODlhCQAJAPIAAGFhYZXK/1FRUf///' +
 	'9ra2gD/AAAAAAAAACH5BAEAAAUALAAAAAAJAAkAAAMYWFqwru2xERcYJLSNNWNBVimC5wjfaTkJADs=';
 
 describe( 'FileUploader', () => {
-	const token = new Token( 'url', { initValue: 'token', autoRefresh: false } );
+	const tokenInitValue = `header.${ btoa( JSON.stringify( { exp: Date.now() + 3600000 } ) ) }.signature`;
+	const token = new Token( 'url', { initValue: tokenInitValue, autoRefresh: false } );
 
 	let fileUploader;
 
@@ -116,9 +117,12 @@ describe( 'FileUploader', () => {
 					expect( request.url ).to.equal( API_ADDRESS );
 					expect( request.method ).to.equal( 'POST' );
 					expect( request.responseType ).to.equal( 'json' );
-					expect( request.requestHeaders ).to.be.deep.equal( { Authorization: 'token' } );
+					expect( request.requestHeaders ).to.be.deep.equal( { Authorization: tokenInitValue } );
 
 					done();
+				} )
+				.catch( err => {
+					console.log( err );
 				} );
 
 			request.respond( 200, { 'Content-Type': 'application/json' },

+ 4 - 1
packages/ckeditor-cloud-services-core/tests/uploadgateway/uploadgateway.js

@@ -3,13 +3,16 @@
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
 
+/* eslint-env browser */
+
 import FileUploader from '../../src/uploadgateway/fileuploader';
 import UploadGateway from '../../src/uploadgateway/uploadgateway';
 import Token from '../../src/token/token';
 import { expectToThrowCKEditorError } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
 describe( 'UploadGateway', () => {
-	const token = new Token( 'url', { initValue: 'token', autoRefresh: false } );
+	const tokenInitValue = `header.${ btoa( JSON.stringify( { exp: Date.now() + 3600000 } ) ) }.signature`;
+	const token = new Token( 'url', { initValue: tokenInitValue, autoRefresh: false } );
 
 	describe( 'constructor()', () => {
 		it( 'should throw error when no token provided', () => {

+ 13 - 13
packages/ckeditor5-adapter-ckfinder/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@ckeditor/ckeditor5-adapter-ckfinder",
-  "version": "22.0.0",
+  "version": "23.0.0",
   "description": "CKFinder adapter for CKEditor 5.",
   "keywords": [
     "ckeditor",
@@ -10,20 +10,20 @@
     "ckeditor5-plugin"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^22.0.0",
-    "@ckeditor/ckeditor5-upload": "^22.0.0"
+    "@ckeditor/ckeditor5-core": "^23.0.0",
+    "@ckeditor/ckeditor5-upload": "^23.0.0"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-basic-styles": "^22.0.0",
-    "@ckeditor/ckeditor5-clipboard": "^22.0.0",
-    "@ckeditor/ckeditor5-editor-classic": "^22.0.0",
-    "@ckeditor/ckeditor5-enter": "^22.0.0",
-    "@ckeditor/ckeditor5-heading": "^22.0.0",
-    "@ckeditor/ckeditor5-image": "^22.0.0",
-    "@ckeditor/ckeditor5-list": "^22.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^22.0.0",
-    "@ckeditor/ckeditor5-typing": "^22.0.0",
-    "@ckeditor/ckeditor5-undo": "^22.0.0"
+    "@ckeditor/ckeditor5-basic-styles": "^23.0.0",
+    "@ckeditor/ckeditor5-clipboard": "^23.0.0",
+    "@ckeditor/ckeditor5-editor-classic": "^23.0.0",
+    "@ckeditor/ckeditor5-enter": "^23.0.0",
+    "@ckeditor/ckeditor5-heading": "^23.0.0",
+    "@ckeditor/ckeditor5-image": "^23.0.0",
+    "@ckeditor/ckeditor5-list": "^23.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^23.0.0",
+    "@ckeditor/ckeditor5-typing": "^23.0.0",
+    "@ckeditor/ckeditor5-undo": "^23.0.0"
   },
   "engines": {
     "node": ">=12.0.0",

+ 9 - 0
packages/ckeditor5-alignment/docs/features/text-alignment.md

@@ -11,6 +11,15 @@ The {@link module:alignment/alignment~Alignment} feature enables support for tex
 
 {@snippet features/text-alignment}
 
+## Related features
+
+There are more CKEditor 5 features that can help you organize your content:
+* {@link features/title Document title} &ndash; Clearly divide your content into a title and body.
+* {@link features/headings Headings} &ndash; Split your content into logical sections.
+* {@link features/indent Block indentation} &ndash; Organize your content into visually separated blocks, indent crucial paragraphs, etc.
+* {@link features/block-quote Block quote} &ndash; Include block quotations or pull quotes in the rich-text content.
+* {@link features/remove-format Remove format} &ndash; Easily clean basic text formatting.
+
 ## Configuring alignment options
 
 It is possible to configure which alignment options are available in the editor by setting the {@link module:alignment/alignment~AlignmentConfig#options `alignment.options`} configuration option. You can choose from `'left'`, `'right'`, `'center'` and `'justify'`.

+ 13 - 13
packages/ckeditor5-alignment/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@ckeditor/ckeditor5-alignment",
-  "version": "22.0.0",
+  "version": "23.0.0",
   "description": "Text alignment feature for CKEditor 5.",
   "keywords": [
     "ckeditor",
@@ -10,20 +10,20 @@
     "ckeditor5-plugin"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^22.0.0",
-    "@ckeditor/ckeditor5-ui": "^22.0.0"
+    "@ckeditor/ckeditor5-core": "^23.0.0",
+    "@ckeditor/ckeditor5-ui": "^23.0.0"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-block-quote": "^22.0.0",
-    "@ckeditor/ckeditor5-editor-classic": "^22.0.0",
-    "@ckeditor/ckeditor5-engine": "^22.0.0",
-    "@ckeditor/ckeditor5-enter": "^22.0.0",
-    "@ckeditor/ckeditor5-heading": "^22.0.0",
-    "@ckeditor/ckeditor5-image": "^22.0.0",
-    "@ckeditor/ckeditor5-list": "^22.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^22.0.0",
-    "@ckeditor/ckeditor5-typing": "^22.0.0",
-    "@ckeditor/ckeditor5-utils": "^22.0.0"
+    "@ckeditor/ckeditor5-block-quote": "^23.0.0",
+    "@ckeditor/ckeditor5-editor-classic": "^23.0.0",
+    "@ckeditor/ckeditor5-engine": "^23.0.0",
+    "@ckeditor/ckeditor5-enter": "^23.0.0",
+    "@ckeditor/ckeditor5-heading": "^23.0.0",
+    "@ckeditor/ckeditor5-image": "^23.0.0",
+    "@ckeditor/ckeditor5-list": "^23.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^23.0.0",
+    "@ckeditor/ckeditor5-typing": "^23.0.0",
+    "@ckeditor/ckeditor5-utils": "^23.0.0"
   },
   "engines": {
     "node": ">=12.0.0",

+ 14 - 14
packages/ckeditor5-autoformat/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@ckeditor/ckeditor5-autoformat",
-  "version": "22.0.0",
+  "version": "23.0.0",
   "description": "Autoformatting feature for CKEditor 5.",
   "keywords": [
     "ckeditor",
@@ -10,21 +10,21 @@
     "ckeditor5-plugin"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^22.0.0",
-    "@ckeditor/ckeditor5-typing": "^22.0.0"
+    "@ckeditor/ckeditor5-core": "^23.0.0",
+    "@ckeditor/ckeditor5-typing": "^23.0.0"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-basic-styles": "^22.0.0",
-    "@ckeditor/ckeditor5-block-quote": "^22.0.0",
-    "@ckeditor/ckeditor5-code-block": "^22.0.0",
-    "@ckeditor/ckeditor5-editor-classic": "^22.0.0",
-    "@ckeditor/ckeditor5-engine": "^22.0.0",
-    "@ckeditor/ckeditor5-enter": "^22.0.0",
-    "@ckeditor/ckeditor5-heading": "^22.0.0",
-    "@ckeditor/ckeditor5-list": "^22.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^22.0.0",
-    "@ckeditor/ckeditor5-undo": "^22.0.0",
-    "@ckeditor/ckeditor5-utils": "^22.0.0"
+    "@ckeditor/ckeditor5-basic-styles": "^23.0.0",
+    "@ckeditor/ckeditor5-block-quote": "^23.0.0",
+    "@ckeditor/ckeditor5-code-block": "^23.0.0",
+    "@ckeditor/ckeditor5-editor-classic": "^23.0.0",
+    "@ckeditor/ckeditor5-engine": "^23.0.0",
+    "@ckeditor/ckeditor5-enter": "^23.0.0",
+    "@ckeditor/ckeditor5-heading": "^23.0.0",
+    "@ckeditor/ckeditor5-list": "^23.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^23.0.0",
+    "@ckeditor/ckeditor5-undo": "^23.0.0",
+    "@ckeditor/ckeditor5-utils": "^23.0.0"
   },
   "engines": {
     "node": ">=12.0.0",

+ 2 - 2
packages/ckeditor5-autoformat/tests/autoformat.js

@@ -486,7 +486,7 @@ describe( 'Autoformat', () => {
 		} );
 
 		describe( 'with code element', () => {
-			describe( 'should not format', () => {
+			describe( 'should not format (inside)', () => {
 				it( '* inside', () => {
 					setData( model, '<paragraph><$text code="true">fo*obar[]</$text></paragraph>' );
 
@@ -532,7 +532,7 @@ describe( 'Autoformat', () => {
 				} );
 			} );
 
-			describe( 'should not format', () => {
+			describe( 'should not format (across)', () => {
 				it( '* across', () => {
 					setData( model, '<paragraph><$text code="true">fo*o</$text>bar[]</paragraph>' );
 

+ 5 - 5
packages/ckeditor5-autosave/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@ckeditor/ckeditor5-autosave",
-  "version": "22.0.0",
+  "version": "23.0.0",
   "description": "Autosave feature for CKEditor 5.",
   "keywords": [
     "ckeditor",
@@ -10,13 +10,13 @@
     "ckeditor5-plugin"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^22.0.0",
-    "@ckeditor/ckeditor5-utils": "^22.0.0",
+    "@ckeditor/ckeditor5-core": "^23.0.0",
+    "@ckeditor/ckeditor5-utils": "^23.0.0",
     "lodash-es": "^4.17.15"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-editor-classic": "^22.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^22.0.0"
+    "@ckeditor/ckeditor5-editor-classic": "^23.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^23.0.0"
   },
   "engines": {
     "node": ">=12.0.0",

+ 10 - 1
packages/ckeditor5-basic-styles/docs/features/basic-styles.md

@@ -5,7 +5,7 @@ category: features
 
 {@snippet features/build-basic-styles-source}
 
-The {@link api/basic-styles basic styles} package provides text formatting features such as bold, italic, underline, strikethrough, subscript, superscript, and code.
+The {@link api/basic-styles basic styles} feature allows you to apply the most frequently used formatting indispensable for content creation. This package provides essential text styling features such as bold, italic, underline, strikethrough, subscript, superscript, and code. Coupled with more [formatting features](#related-features), these serve as a base for any WYSIWYG editor toolset.
 
 <info-box info>
 	All basic text styles can be removed with the {@link features/remove-format remove format} feature.
@@ -15,6 +15,15 @@ The {@link api/basic-styles basic styles} package provides text formatting featu
 
 {@snippet features/basic-styles}
 
+## Related features
+
+Check out also these CKEditor 5 features to gain better control over your content style and format:
+* {@link features/font Font styles} &ndash; Easily and efficiently control the font {@link features/font#configuring-the-font-family-feature family}, {@link features/font#configuring-the-font-size-feature size}, {@link features/font#configuring-the-font-color-and-font-background-color-features text or background color}.
+* {@link features/text-alignment Text alignment} &ndash; Because it does matter whether the content is left, right, centered or justified.
+* {@link features/code-blocks Code blocks}  &ndash; Insert longer, multiline code listings, expanding the inline code style greatly.
+* {@link features/highlight Highlight} &ndash; Mark important words and passages, aiding a review or drawing attention to specific parts of content.
+* {@link features/remove-format Remove format} &ndash; Easily clean basic text formatting.
+
 ## Available text styles
 
 | Style feature | {@link framework/guides/architecture/core-editor-architecture#commands Command} name | {@link builds/guides/integration/configuration#toolbar-setup Toolbar} component name | Output element |

+ 10 - 10
packages/ckeditor5-basic-styles/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@ckeditor/ckeditor5-basic-styles",
-  "version": "22.0.0",
+  "version": "23.0.0",
   "description": "Basic styles feature for CKEditor 5.",
   "keywords": [
     "ckeditor",
@@ -10,17 +10,17 @@
     "ckeditor5-plugin"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^22.0.0",
-    "@ckeditor/ckeditor5-typing": "^22.0.0",
-    "@ckeditor/ckeditor5-ui": "^22.0.0"
+    "@ckeditor/ckeditor5-core": "^23.0.0",
+    "@ckeditor/ckeditor5-typing": "^23.0.0",
+    "@ckeditor/ckeditor5-ui": "^23.0.0"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-editor-classic": "^22.0.0",
-    "@ckeditor/ckeditor5-engine": "^22.0.0",
-    "@ckeditor/ckeditor5-essentials": "^22.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^22.0.0",
-    "@ckeditor/ckeditor5-remove-format": "^22.0.0",
-    "@ckeditor/ckeditor5-utils": "^22.0.0"
+    "@ckeditor/ckeditor5-editor-classic": "^23.0.0",
+    "@ckeditor/ckeditor5-engine": "^23.0.0",
+    "@ckeditor/ckeditor5-essentials": "^23.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^23.0.0",
+    "@ckeditor/ckeditor5-remove-format": "^23.0.0",
+    "@ckeditor/ckeditor5-utils": "^23.0.0"
   },
   "engines": {
     "node": ">=12.0.0",

+ 27 - 0
packages/ckeditor5-block-quote/docs/_snippets/features/block-quote.html

@@ -0,0 +1,27 @@
+<div id="snippet-block-quote">
+	<h3>The Famous Einstein Quote that never was</h3>
+
+	<p>All of us &mdash; well, maybe most of us &mdash; have encountered the following quote in the past few years:</p>
+
+	<blockquote>
+		<p>Everybody is a genius. But if you judge a fish by its ability to climb a tree, it will live its whole life believing that it is stupid.</p>
+
+		<p>Albert Einstein</p>
+	</blockquote>
+
+	<p>It is mostly popular on Facebook and other social networks, where people share it aplenty. No wonder, as it sounds great, it sounds smart, it is neat and, well, let&rsquo;s be frank &mdash; Albert is one hell of a figure!</p>
+
+	<p>The truth, however, is not as neat, not as great and people who mindlessly forward the quote are not as smart. Because, in fact, Einstein has never said that. It comes from a 2004 book &ldquo;The Rhythm of Life: Living Every Day with Passion and Purpose&rdquo; by Mathew Kelly, published almost 50 years after Albert&rsquo;s death in 1955.</p>
+
+	<p>He was, most probably, inspired by an essay by Amos E. Dolbear of Tufts titled &ldquo;An Educational Allegory&rdquo;, describing animals educated to work on their weakest features instead of their strongest ones. So an eagle was made to run, a penguin was forced to fly and so on. There is also the 1903 &ldquo;Jungle School Boards&rdquo; fable from an Illinois newspaper in which a monkey, a kangaroo and an elephant cannot agree on the curriculum for their animal school &mdash; should little animals be taught tree-climbing, jumping or looking wise?&nbsp;</p>
+
+	<p>In the late 1940s, something that appears to be an amalgam of the two was published and later reprinted with various changes in the 1960s. The idea evolved for decades and got mixed up with a few other quotes about being a genius originating back to the 1970s. Finally, Kelly wrote in his 2004 book:</p>
+
+	<blockquote>
+		<p>Albert Einstein wrote, &ldquo;Everybody is a genius. But if you judge a fish by its ability to climb a tree, it will live its whole life believing that it is stupid.&rdquo; The question I have for you at this point of our journey together is, &ldquo;What is your genius?&rdquo;</p>
+	</blockquote>
+
+	<p>Why he attributed this to Albert Einstein remains unclear. The fact is, the quote got popular. But apparently not everybody is a genius when it comes to fact-checking and sources...</p>
+
+</div>
+

+ 38 - 0
packages/ckeditor5-block-quote/docs/_snippets/features/block-quote.js

@@ -0,0 +1,38 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals window, document, console */
+
+import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-block-quote' ), {
+		toolbar: {
+			items: [
+				'heading',
+				'|',
+				'bold',
+				'italic',
+				'link',
+				'|',
+				'bulletedList',
+				'numberedList',
+				'|',
+				'blockQuote',
+				'outdent',
+				'indent',
+				'|',
+				'undo',
+				'redo'
+			],
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err );
+	} );

+ 6 - 2
packages/ckeditor5-block-quote/docs/api/block-quote.md

@@ -8,13 +8,17 @@ category: api-reference
 
 This package implements block quote support for CKEditor 5.
 
+## Demo
+
+Check out the {@link features/block-quote#demo demo in the Block quote feature} guide.
+
 ## Documentation
 
-See the {@link module:block-quote/blockquote~BlockQuote} plugin documentation.
+See the {@link features/block-quote Block quote feature} guide and the {@link module:block-quote/blockquote~BlockQuote} plugin documentation.
 
 ## Installation
 
-```bash
+```
 npm install --save @ckeditor/ckeditor5-block-quote
 ```
 

+ 70 - 0
packages/ckeditor5-block-quote/docs/features/block-quote.md

@@ -0,0 +1,70 @@
+---
+category: features
+menu-title: Block quote
+---
+
+# Block quote
+
+The {@link module:block-quote/blockquote~BlockQuote} feature allows you to easily include block quotations or pull quotes in the rich-text content. This provides an attractive way to draw the readers' attention to selected parts of text. It also helps organize the content in a structured, elegant way and to manage the flow better.
+
+## Demo
+
+Use the editor below to see the block quote plugin in action.
+
+{@snippet features/block-quote}
+
+## Related features
+
+Here are some other CKEditor 5 features that you can use similarly to the block quote plugin to structure your text better:
+
+* {@link features/indent Block indentation}  &ndash; Set indentation for text blocks such as paragraphs or lists.
+* {@link features/code-blocks Code block}  &ndash; Insert longer, multiline code listings.
+* {@link features/text-alignment Text alignment} &ndash; Align your content left, right, center it or justify.
+
+## Installation
+
+To add this feature to your rich-text editor, install the [`@ckeditor/ckeditor5-block-quote`](https://www.npmjs.com/package/@ckeditor/ckeditor5-block-quote) package:
+
+```plaintext
+npm install --save @ckeditor/ckeditor5-block-quote
+```
+
+And add it to your plugin list configuration:
+
+```js
+import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote';
+
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ BlockQuote, ... ],
+		toolbar: [ 'blockQuote', ... ]
+	} )
+	.then( ... )
+	.catch( ... );
+```
+
+<info-box info>
+	Read more about {@link builds/guides/integration/installing-plugins installing plugins}.
+</info-box>
+
+## Common API
+
+The {@link module:block-quote/blockquote~BlockQuote} plugin registers:
+
+* the `'blockQuote'` UI button component implemented by the {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature},
+* the `'blockQuote'` command implemented by the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}.
+
+The command can be executed using the {@link module:core/editor/editor~Editor#execute `editor.execute()`} method:
+
+```js
+// Applies block quote to the selected content.
+editor.execute( 'blockQuote' );
+```
+
+<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>
+
+## Contribute
+
+The source code of the feature is available on GitHub in https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-block-quote.

+ 14 - 14
packages/ckeditor5-block-quote/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@ckeditor/ckeditor5-block-quote",
-  "version": "22.0.0",
+  "version": "23.0.0",
   "description": "Block quote feature for CKEditor 5.",
   "keywords": [
     "ckeditor",
@@ -10,21 +10,21 @@
     "ckeditor5-plugin"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^22.0.0",
-    "@ckeditor/ckeditor5-ui": "^22.0.0",
-    "@ckeditor/ckeditor5-utils": "^22.0.0"
+    "@ckeditor/ckeditor5-core": "^23.0.0",
+    "@ckeditor/ckeditor5-ui": "^23.0.0",
+    "@ckeditor/ckeditor5-utils": "^23.0.0"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-basic-styles": "^22.0.0",
-    "@ckeditor/ckeditor5-editor-classic": "^22.0.0",
-    "@ckeditor/ckeditor5-engine": "^22.0.0",
-    "@ckeditor/ckeditor5-enter": "^22.0.0",
-    "@ckeditor/ckeditor5-heading": "^22.0.0",
-    "@ckeditor/ckeditor5-image": "^22.0.0",
-    "@ckeditor/ckeditor5-list": "^22.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^22.0.0",
-    "@ckeditor/ckeditor5-table": "^22.0.0",
-    "@ckeditor/ckeditor5-typing": "^22.0.0"
+    "@ckeditor/ckeditor5-basic-styles": "^23.0.0",
+    "@ckeditor/ckeditor5-editor-classic": "^23.0.0",
+    "@ckeditor/ckeditor5-engine": "^23.0.0",
+    "@ckeditor/ckeditor5-enter": "^23.0.0",
+    "@ckeditor/ckeditor5-heading": "^23.0.0",
+    "@ckeditor/ckeditor5-image": "^23.0.0",
+    "@ckeditor/ckeditor5-list": "^23.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^23.0.0",
+    "@ckeditor/ckeditor5-table": "^23.0.0",
+    "@ckeditor/ckeditor5-typing": "^23.0.0"
   },
   "engines": {
     "node": ">=12.0.0",

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/ckeditor.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/ckeditor.js.map


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/ar.js


+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ast.js

@@ -1 +1 @@
-!function(e){const a=e.ast=e.ast||{};a.dictionary=Object.assign(a.dictionary||{},{"%0 of %1":"",Bold:"Negrina","Bulleted List":"Llista con viñetes",Cancel:"Encaboxar","Centered image":"","Change image text alternative":"",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"","Full size image":"Imaxen a tamañu completu","Image toolbar":"","image widget":"complementu d'imaxen",Insert:"","Insert image":"","Insert image via URL":"",Italic:"Cursiva","Left aligned image":"",Link:"Enllazar","Link URL":"URL del enllaz",Next:"","Numbered List":"Llista numberada","Open in a new tab":"","Open link in new tab":"","Paste the image source URL.":"",Previous:"",Redo:"Refacer","Rich Text Editor, %0":"Editor de testu arriquecíu, %0","Right aligned image":"",Save:"Guardar","Show more items":"","Side image":"Imaxen llateral","Text alternative":"","This link has no URL":"",Undo:"Desfacer",Unlink:"Desenllazar",Update:"","Upload failed":""}),a.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
+!function(e){const a=e.ast=e.ast||{};a.dictionary=Object.assign(a.dictionary||{},{"%0 of %1":"",Bold:"Negrina","Bulleted List":"Llista con viñetes",Cancel:"Encaboxar","Centered image":"","Change image text alternative":"",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"","Full size image":"Imaxen a tamañu completu","Image toolbar":"","image widget":"complementu d'imaxen","Insert image":"",Italic:"Cursiva","Left aligned image":"",Link:"Enllazar","Link URL":"URL del enllaz",Next:"","Numbered List":"Llista numberada","Open in a new tab":"","Open link in new tab":"",Previous:"",Redo:"Refacer","Rich Text Editor, %0":"Editor de testu arriquecíu, %0","Right aligned image":"",Save:"Guardar","Show more items":"","Side image":"Imaxen llateral","Text alternative":"","This link has no URL":"",Undo:"Desfacer",Unlink:"Desenllazar","Upload failed":""}),a.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/az.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/bg.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/cs.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/da.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/de.js


+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/el.js

@@ -1 +1 @@
-!function(e){const i=e.el=e.el||{};i.dictionary=Object.assign(i.dictionary||{},{"%0 of %1":"","Block quote":"Περιοχή παράθεσης",Bold:"Έντονη","Bulleted List":"Λίστα κουκκίδων",Cancel:"Ακύρωση","Centered image":"","Change image text alternative":"Αλλαγή εναλλακτικού κείμενου","Choose heading":"Επιλέξτε κεφαλίδα",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"Λεζάντα","Full size image":"Εικόνα πλήρης μεγέθους",Heading:"Κεφαλίδα","Heading 1":"Κεφαλίδα 1","Heading 2":"Κεφαλίδα 2","Heading 3":"Κεφαλίδα 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"",Insert:"","Insert image":"Εισαγωγή εικόνας","Insert image via URL":"",Italic:"Πλάγια","Left aligned image":"",Link:"Σύνδεσμος","Link URL":"Διεύθυνση συνδέσμου",Next:"","Numbered List":"Αριθμημένη λίστα","Open in a new tab":"","Open link in new tab":"",Paragraph:"Παράγραφος","Paste the image source URL.":"",Previous:"",Redo:"Επανάληψη","Rich Text Editor, %0":"Επεξεργαστής Πλούσιου Κειμένου, 0%","Right aligned image":"",Save:"Αποθήκευση","Show more items":"","Side image":"","Text alternative":"Εναλλακτικό κείμενο","This link has no URL":"",Undo:"Αναίρεση",Unlink:"Αφαίρεση συνδέσμου",Update:"","Upload failed":""}),i.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
+!function(e){const i=e.el=e.el||{};i.dictionary=Object.assign(i.dictionary||{},{"%0 of %1":"","Block quote":"Περιοχή παράθεσης",Bold:"Έντονη","Bulleted List":"Λίστα κουκκίδων",Cancel:"Ακύρωση","Centered image":"","Change image text alternative":"Αλλαγή εναλλακτικού κείμενου","Choose heading":"Επιλέξτε κεφαλίδα",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"Λεζάντα","Full size image":"Εικόνα πλήρης μεγέθους",Heading:"Κεφαλίδα","Heading 1":"Κεφαλίδα 1","Heading 2":"Κεφαλίδα 2","Heading 3":"Κεφαλίδα 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"","Insert image":"Εισαγωγή εικόνας",Italic:"Πλάγια","Left aligned image":"",Link:"Σύνδεσμος","Link URL":"Διεύθυνση συνδέσμου",Next:"","Numbered List":"Αριθμημένη λίστα","Open in a new tab":"","Open link in new tab":"",Paragraph:"Παράγραφος",Previous:"",Redo:"Επανάληψη","Rich Text Editor, %0":"Επεξεργαστής Πλούσιου Κειμένου, 0%","Right aligned image":"",Save:"Αποθήκευση","Show more items":"","Side image":"","Text alternative":"Εναλλακτικό κείμενο","This link has no URL":"",Undo:"Αναίρεση",Unlink:"Αφαίρεση συνδέσμου","Upload failed":""}),i.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/en-au.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/en-gb.js


+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/eo.js

@@ -1 +1 @@
-!function(i){const a=i.eo=i.eo||{};a.dictionary=Object.assign(a.dictionary||{},{"%0 of %1":"",Bold:"grasa","Bulleted List":"Bula Listo",Cancel:"Nuligi","Centered image":"","Change image text alternative":"Ŝanĝu la alternativan tekston de la bildo","Choose heading":"Elektu ĉapon",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"Skribu klarigon pri la bildo","Full size image":"Bildo kun reala dimensio",Heading:"Ĉapo","Heading 1":"Ĉapo 1","Heading 2":"Ĉapo 2","Heading 3":"Ĉapo 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"bilda fenestraĵo",Insert:"","Insert image":"Enmetu bildon","Insert image via URL":"",Italic:"kursiva","Left aligned image":"",Link:"Ligilo","Link URL":"URL de la ligilo",Next:"","Numbered List":"Numerita Listo","Open in a new tab":"","Open link in new tab":"",Paragraph:"Paragrafo","Paste the image source URL.":"",Previous:"",Redo:"Refari","Rich Text Editor, %0":"Redaktilo de Riĉa Teksto, %0","Right aligned image":"",Save:"Konservi","Show more items":"","Side image":"Flanka biildo","Text alternative":"Alternativa teksto","This link has no URL":"",Undo:"Malfari",Unlink:"Malligi",Update:"","Upload failed":""}),a.getPluralForm=function(i){return 1!=i}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
+!function(i){const a=i.eo=i.eo||{};a.dictionary=Object.assign(a.dictionary||{},{"%0 of %1":"",Bold:"grasa","Bulleted List":"Bula Listo",Cancel:"Nuligi","Centered image":"","Change image text alternative":"Ŝanĝu la alternativan tekston de la bildo","Choose heading":"Elektu ĉapon",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"Skribu klarigon pri la bildo","Full size image":"Bildo kun reala dimensio",Heading:"Ĉapo","Heading 1":"Ĉapo 1","Heading 2":"Ĉapo 2","Heading 3":"Ĉapo 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"bilda fenestraĵo","Insert image":"Enmetu bildon",Italic:"kursiva","Left aligned image":"",Link:"Ligilo","Link URL":"URL de la ligilo",Next:"","Numbered List":"Numerita Listo","Open in a new tab":"","Open link in new tab":"",Paragraph:"Paragrafo",Previous:"",Redo:"Refari","Rich Text Editor, %0":"Redaktilo de Riĉa Teksto, %0","Right aligned image":"",Save:"Konservi","Show more items":"","Side image":"Flanka biildo","Text alternative":"Alternativa teksto","This link has no URL":"",Undo:"Malfari",Unlink:"Malligi","Upload failed":""}),a.getPluralForm=function(i){return 1!=i}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/es.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/et.js


+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/eu.js

@@ -1 +1 @@
-!function(e){const a=e.eu=e.eu||{};a.dictionary=Object.assign(a.dictionary||{},{"%0 of %1":"","Block quote":"Aipua",Bold:"Lodia","Bulleted List":"Buletdun zerrenda",Cancel:"Utzi","Cannot upload file:":"Ezin da fitxategia kargatu:","Centered image":"Zentratutako irudia","Change image text alternative":"Aldatu irudiaren ordezko testua","Choose heading":"Aukeratu izenburua",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"Sartu irudiaren epigrafea","Full size image":"Tamaina osoko irudia",Heading:"Izenburua","Heading 1":"Izenburua 1","Heading 2":"Izenburua 2","Heading 3":"Izenburua 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"irudi widgeta",Insert:"","Insert image":"Txertatu irudia","Insert image via URL":"",Italic:"Etzana","Left aligned image":"Ezkerrean lerrokatutako irudia",Link:"Esteka","Link URL":"Estekaren URLa",Next:"","Numbered List":"Zenbakidun zerrenda","Open in a new tab":"","Open link in new tab":"",Paragraph:"Paragrafoa","Paste the image source URL.":"",Previous:"",Redo:"Berregin","Rich Text Editor, %0":"Testu aberastuaren editorea, %0","Right aligned image":"Eskuinean lerrokatutako irudia",Save:"Gorde","Show more items":"","Side image":"Alboko irudia","Text alternative":"Ordezko testua","This link has no URL":"",Undo:"Desegin",Unlink:"Desestekatu",Update:"","Upload failed":"Kargatzeak huts egin du"}),a.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
+!function(a){const e=a.eu=a.eu||{};e.dictionary=Object.assign(e.dictionary||{},{"%0 of %1":"","Block quote":"Aipua",Bold:"Lodia","Bulleted List":"Buletdun zerrenda",Cancel:"Utzi","Cannot upload file:":"Ezin da fitxategia kargatu:","Centered image":"Zentratutako irudia","Change image text alternative":"Aldatu irudiaren ordezko testua","Choose heading":"Aukeratu izenburua",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"Sartu irudiaren epigrafea","Full size image":"Tamaina osoko irudia",Heading:"Izenburua","Heading 1":"Izenburua 1","Heading 2":"Izenburua 2","Heading 3":"Izenburua 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"irudi widgeta","Insert image":"Txertatu irudia",Italic:"Etzana","Left aligned image":"Ezkerrean lerrokatutako irudia",Link:"Esteka","Link URL":"Estekaren URLa",Next:"","Numbered List":"Zenbakidun zerrenda","Open in a new tab":"","Open link in new tab":"",Paragraph:"Paragrafoa",Previous:"",Redo:"Berregin","Rich Text Editor, %0":"Testu aberastuaren editorea, %0","Right aligned image":"Eskuinean lerrokatutako irudia",Save:"Gorde","Show more items":"","Side image":"Alboko irudia","Text alternative":"Ordezko testua","This link has no URL":"",Undo:"Desegin",Unlink:"Desestekatu","Upload failed":"Kargatzeak huts egin du"}),e.getPluralForm=function(a){return 1!=a}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/fa.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/fi.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/fr.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/gl.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/he.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/hr.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/hu.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/id.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/it.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/ja.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/km.js


+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/kn.js

@@ -1 +1 @@
-!function(e){const i=e.kn=e.kn||{};i.dictionary=Object.assign(i.dictionary||{},{"%0 of %1":"","Block quote":"‍‍‍‍ಗುರುತಿಸಲಾದ ‍‍ಉಲ್ಲೇಖ",Bold:"‍‍ದಪ್ಪ","Bulleted List":"‍‍ಬುಲೆಟ್ ಪಟ್ಟಿ",Cancel:"ರದ್ದುಮಾಡು","Centered image":"","Change image text alternative":"‍ಚಿತ್ರದ ಬದಲಿ ಪಠ್ಯ ಬದಲಾಯಿಸು","Choose heading":"ಶೀರ್ಷಿಕೆ ಆಯ್ಕೆಮಾಡು",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"‍ಚಿತ್ರದ ಶೀರ್ಷಿಕೆ ಸೇರಿಸು","Full size image":"‍ಪೂರ್ಣ ‍‍ಅಳತೆಯ ಚಿತ್ರ",Heading:"ಶೀರ್ಷಿಕೆ","Heading 1":"ಶೀರ್ಷಿಕೆ 1","Heading 2":"ಶೀರ್ಷಿಕೆ 2","Heading 3":"ಶೀರ್ಷಿಕೆ 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"‍ಚಿತ್ರ ವಿಜೆಟ್",Insert:"","Insert image":"","Insert image via URL":"",Italic:"‍ಇಟಾಲಿಕ್","Left aligned image":"",Link:"‍ಕೊಂಡಿ","Link URL":"‍ಕೊಂಡಿ ಸಂಪರ್ಕಿಸು",Next:"","Numbered List":"‍ಸಂಖ್ಯೆಯ ಪಟ್ಟಿ‍","Open in a new tab":"","Open link in new tab":"",Paragraph:"ಪ್ಯಾರಾಗ್ರಾಫ್","Paste the image source URL.":"",Previous:"",Redo:"‍ಮತ್ತೆ ಮಾಡು","Rich Text Editor, %0":"‍ಸಮೃದ್ಧ ಪಠ್ಯ ಸಂಪಾದಕ‍, %0","Right aligned image":"",Save:"ಉಳಿಸು","Show more items":"","Side image":"‍ಪಕ್ಕದ ಚಿತ್ರ","Text alternative":"‍ಪಠ್ಯದ ಬದಲಿ","This link has no URL":"",Undo:"‍‍ರದ್ದು",Unlink:"‍ಕೊಂಡಿ ತೆಗೆ",Update:"","Upload failed":""}),i.getPluralForm=function(e){return e>1}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
+!function(e){const i=e.kn=e.kn||{};i.dictionary=Object.assign(i.dictionary||{},{"%0 of %1":"","Block quote":"‍‍‍‍ಗುರುತಿಸಲಾದ ‍‍ಉಲ್ಲೇಖ",Bold:"‍‍ದಪ್ಪ","Bulleted List":"‍‍ಬುಲೆಟ್ ಪಟ್ಟಿ",Cancel:"ರದ್ದುಮಾಡು","Centered image":"","Change image text alternative":"‍ಚಿತ್ರದ ಬದಲಿ ಪಠ್ಯ ಬದಲಾಯಿಸು","Choose heading":"ಶೀರ್ಷಿಕೆ ಆಯ್ಕೆಮಾಡು",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"‍ಚಿತ್ರದ ಶೀರ್ಷಿಕೆ ಸೇರಿಸು","Full size image":"‍ಪೂರ್ಣ ‍‍ಅಳತೆಯ ಚಿತ್ರ",Heading:"ಶೀರ್ಷಿಕೆ","Heading 1":"ಶೀರ್ಷಿಕೆ 1","Heading 2":"ಶೀರ್ಷಿಕೆ 2","Heading 3":"ಶೀರ್ಷಿಕೆ 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"‍ಚಿತ್ರ ವಿಜೆಟ್","Insert image":"",Italic:"‍ಇಟಾಲಿಕ್","Left aligned image":"",Link:"‍ಕೊಂಡಿ","Link URL":"‍ಕೊಂಡಿ ಸಂಪರ್ಕಿಸು",Next:"","Numbered List":"‍ಸಂಖ್ಯೆಯ ಪಟ್ಟಿ‍","Open in a new tab":"","Open link in new tab":"",Paragraph:"ಪ್ಯಾರಾಗ್ರಾಫ್",Previous:"",Redo:"‍ಮತ್ತೆ ಮಾಡು","Rich Text Editor, %0":"‍ಸಮೃದ್ಧ ಪಠ್ಯ ಸಂಪಾದಕ‍, %0","Right aligned image":"",Save:"ಉಳಿಸು","Show more items":"","Side image":"‍ಪಕ್ಕದ ಚಿತ್ರ","Text alternative":"‍ಪಠ್ಯದ ಬದಲಿ","This link has no URL":"",Undo:"‍‍ರದ್ದು",Unlink:"‍ಕೊಂಡಿ ತೆಗೆ","Upload failed":""}),i.getPluralForm=function(e){return e>1}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/ko.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/ku.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/lt.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/lv.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/nb.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/ne.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/nl.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/no.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/pl.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/pt-br.js


+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/pt.js

@@ -1 +1 @@
-!function(a){const e=a.pt=a.pt||{};e.dictionary=Object.assign(e.dictionary||{},{"%0 of %1":"",Bold:"Negrito","Bulleted List":"Lista não ordenada",Cancel:"Cancelar","Cannot upload file:":"Não foi possível carregar o ficheiro:","Centered image":"Imagem centrada","Change image text alternative":"","Choose heading":"",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"Indicar legenda da imagem","Full size image":"Imagem em tamanho completo",Heading:"Cabeçalho","Heading 1":"Cabeçalho 1","Heading 2":"Cabeçalho 2","Heading 3":"Cabeçalho 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"módulo de imagem",Insert:"","Insert image":"Inserir imagem","Insert image via URL":"",Italic:"Itálico","Left aligned image":"",Link:"Hiperligação","Link URL":"URL da ligação",Next:"","Numbered List":"Lista ordenada","Open in a new tab":"","Open link in new tab":"",Paragraph:"Parágrafo","Paste the image source URL.":"",Previous:"",Redo:"Refazer","Rich Text Editor, %0":"Editor de texto avançado, %0","Right aligned image":"",Save:"Guardar","Show more items":"","Side image":"Imagem lateral","Text alternative":"Texto alternativo","This link has no URL":"",Undo:"Desfazer",Unlink:"Desligar",Update:"","Upload failed":"Falha ao carregar"}),e.getPluralForm=function(a){return 1!=a}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
+!function(a){const e=a.pt=a.pt||{};e.dictionary=Object.assign(e.dictionary||{},{"%0 of %1":"",Bold:"Negrito","Bulleted List":"Lista não ordenada",Cancel:"Cancelar","Cannot upload file:":"Não foi possível carregar o ficheiro:","Centered image":"Imagem centrada","Change image text alternative":"","Choose heading":"",Downloadable:"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor toolbar":"","Enter image caption":"Indicar legenda da imagem","Full size image":"Imagem em tamanho completo",Heading:"Cabeçalho","Heading 1":"Cabeçalho 1","Heading 2":"Cabeçalho 2","Heading 3":"Cabeçalho 3","Heading 4":"","Heading 5":"","Heading 6":"","Image toolbar":"","image widget":"módulo de imagem","Insert image":"Inserir imagem",Italic:"Itálico","Left aligned image":"",Link:"Hiperligação","Link URL":"URL da ligação",Next:"","Numbered List":"Lista ordenada","Open in a new tab":"","Open link in new tab":"",Paragraph:"Parágrafo",Previous:"",Redo:"Refazer","Rich Text Editor, %0":"Editor de texto avançado, %0","Right aligned image":"",Save:"Guardar","Show more items":"","Side image":"Imagem lateral","Text alternative":"Texto alternativo","This link has no URL":"",Undo:"Desfazer",Unlink:"Desligar","Upload failed":"Falha ao carregar"}),e.getPluralForm=function(a){return 1!=a}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/ro.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/ru.js


+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/si.js

@@ -1 +1 @@
-!function(e){const i=e.si=e.si||{};i.dictionary=Object.assign(i.dictionary||{},{Bold:"තදකුරු","Bulleted List":"බුලටිත ලැයිස්තුව","Cannot upload file:":"ගොනුව යාවත්කාලීන කළ නොහැක:","Centered image":"","Change image text alternative":"","Enter image caption":"","Full size image":"","Image toolbar":"","image widget":"",Insert:"","Insert image":"පින්තූරය ඇතුල් කරන්න","Insert image via URL":"",Italic:"ඇලකුරු","Left aligned image":"","Numbered List":"අංකිත ලැයිස්තුව","Paste the image source URL.":"",Redo:"නැවත කරන්න","Right aligned image":"","Side image":"","Text alternative":"",Undo:"අහෝසි කරන්න",Update:"","Upload failed":"උඩුගත කිරීම අසාර්ථක විය"}),i.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
+!function(e){const i=e.si=e.si||{};i.dictionary=Object.assign(i.dictionary||{},{Bold:"තදකුරු","Bulleted List":"බුලටිත ලැයිස්තුව","Cannot upload file:":"ගොනුව යාවත්කාලීන කළ නොහැක:","Centered image":"","Change image text alternative":"","Enter image caption":"","Full size image":"","Image toolbar":"","image widget":"","Insert image":"පින්තූරය ඇතුල් කරන්න",Italic:"ඇලකුරු","Left aligned image":"","Numbered List":"අංකිත ලැයිස්තුව",Redo:"නැවත කරන්න","Right aligned image":"","Side image":"","Text alternative":"",Undo:"අහෝසි කරන්න","Upload failed":"උඩුගත කිරීම අසාර්ථක විය"}),i.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/sk.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/sq.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/sr-latn.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/sr.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/sv.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/th.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/tr.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/ug.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/uk.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/vi.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/zh-cn.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon-block/build/translations/zh.js


+ 22 - 22
packages/ckeditor5-build-balloon-block/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@ckeditor/ckeditor5-build-balloon-block",
-  "version": "22.0.0",
+  "version": "23.0.0",
   "description": "The balloon editor build of CKEditor 5 with a block toolbar – the best browser-based rich text editor.",
   "keywords": [
     "wysiwyg",
@@ -25,29 +25,29 @@
     "build"
   ],
   "devDependencies": {
-    "@ckeditor/ckeditor5-adapter-ckfinder": "^22.0.0",
-    "@ckeditor/ckeditor5-autoformat": "^22.0.0",
-    "@ckeditor/ckeditor5-basic-styles": "^22.0.0",
-    "@ckeditor/ckeditor5-block-quote": "^22.0.0",
-    "@ckeditor/ckeditor5-ckfinder": "^22.0.0",
-    "@ckeditor/ckeditor5-core": "^22.0.0",
+    "@ckeditor/ckeditor5-adapter-ckfinder": "^23.0.0",
+    "@ckeditor/ckeditor5-autoformat": "^23.0.0",
+    "@ckeditor/ckeditor5-basic-styles": "^23.0.0",
+    "@ckeditor/ckeditor5-block-quote": "^23.0.0",
+    "@ckeditor/ckeditor5-ckfinder": "^23.0.0",
+    "@ckeditor/ckeditor5-core": "^23.0.0",
     "@ckeditor/ckeditor5-dev-utils": "^20.0.0",
     "@ckeditor/ckeditor5-dev-webpack-plugin": "^20.0.0",
-    "@ckeditor/ckeditor5-easy-image": "^22.0.0",
-    "@ckeditor/ckeditor5-editor-balloon": "^22.0.0",
-    "@ckeditor/ckeditor5-essentials": "^22.0.0",
-    "@ckeditor/ckeditor5-heading": "^22.0.0",
-    "@ckeditor/ckeditor5-image": "^22.0.0",
-    "@ckeditor/ckeditor5-indent": "^22.0.0",
-    "@ckeditor/ckeditor5-link": "^22.0.0",
-    "@ckeditor/ckeditor5-list": "^22.0.0",
-    "@ckeditor/ckeditor5-media-embed": "^22.0.0",
-    "@ckeditor/ckeditor5-paragraph": "^22.0.0",
-    "@ckeditor/ckeditor5-paste-from-office": "^22.0.0",
-    "@ckeditor/ckeditor5-table": "^22.0.0",
-    "@ckeditor/ckeditor5-typing": "^22.0.0",
-    "@ckeditor/ckeditor5-theme-lark": "^22.0.0",
-    "@ckeditor/ckeditor5-ui": "^22.0.0",
+    "@ckeditor/ckeditor5-easy-image": "^23.0.0",
+    "@ckeditor/ckeditor5-editor-balloon": "^23.0.0",
+    "@ckeditor/ckeditor5-essentials": "^23.0.0",
+    "@ckeditor/ckeditor5-heading": "^23.0.0",
+    "@ckeditor/ckeditor5-image": "^23.0.0",
+    "@ckeditor/ckeditor5-indent": "^23.0.0",
+    "@ckeditor/ckeditor5-link": "^23.0.0",
+    "@ckeditor/ckeditor5-list": "^23.0.0",
+    "@ckeditor/ckeditor5-media-embed": "^23.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^23.0.0",
+    "@ckeditor/ckeditor5-paste-from-office": "^23.0.0",
+    "@ckeditor/ckeditor5-table": "^23.0.0",
+    "@ckeditor/ckeditor5-typing": "^23.0.0",
+    "@ckeditor/ckeditor5-theme-lark": "^23.0.0",
+    "@ckeditor/ckeditor5-ui": "^23.0.0",
     "postcss-loader": "^3.0.0",
     "raw-loader": "^4.0.1",
     "style-loader": "^1.2.1",

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon/build/ckeditor.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon/build/ckeditor.js.map


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon/build/translations/ar.js


+ 1 - 1
packages/ckeditor5-build-balloon/build/translations/ast.js

@@ -1 +1 @@
-!function(e){const a=e.ast=e.ast||{};a.dictionary=Object.assign(a.dictionary||{},{"%0 of %1":"",Bold:"Negrina","Bulleted List":"Llista con viñetes",Cancel:"Encaboxar","Centered image":"","Change image text alternative":"",Downloadable:"","Dropdown toolbar":"","Edit link":"","Editor toolbar":"","Enter image caption":"","Full size image":"Imaxen a tamañu completu","Image toolbar":"","image widget":"complementu d'imaxen",Insert:"","Insert image":"","Insert image via URL":"",Italic:"Cursiva","Left aligned image":"",Link:"Enllazar","Link URL":"URL del enllaz",Next:"","Numbered List":"Llista numberada","Open in a new tab":"","Open link in new tab":"","Paste the image source URL.":"",Previous:"",Redo:"Refacer","Rich Text Editor, %0":"Editor de testu arriquecíu, %0","Right aligned image":"",Save:"Guardar","Show more items":"","Side image":"Imaxen llateral","Text alternative":"","This link has no URL":"",Undo:"Desfacer",Unlink:"Desenllazar",Update:"","Upload failed":""}),a.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
+!function(e){const a=e.ast=e.ast||{};a.dictionary=Object.assign(a.dictionary||{},{"%0 of %1":"",Bold:"Negrina","Bulleted List":"Llista con viñetes",Cancel:"Encaboxar","Centered image":"","Change image text alternative":"",Downloadable:"","Dropdown toolbar":"","Edit link":"","Editor toolbar":"","Enter image caption":"","Full size image":"Imaxen a tamañu completu","Image toolbar":"","image widget":"complementu d'imaxen","Insert image":"",Italic:"Cursiva","Left aligned image":"",Link:"Enllazar","Link URL":"URL del enllaz",Next:"","Numbered List":"Llista numberada","Open in a new tab":"","Open link in new tab":"",Previous:"",Redo:"Refacer","Rich Text Editor, %0":"Editor de testu arriquecíu, %0","Right aligned image":"",Save:"Guardar","Show more items":"","Side image":"Imaxen llateral","Text alternative":"","This link has no URL":"",Undo:"Desfacer",Unlink:"Desenllazar","Upload failed":""}),a.getPluralForm=function(e){return 1!=e}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon/build/translations/az.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon/build/translations/bg.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon/build/translations/cs.js


File diff ditekan karena terlalu besar
+ 0 - 0
packages/ckeditor5-build-balloon/build/translations/da.js


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini