浏览代码

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

Maciej Bukowski 5 年之前
父节点
当前提交
45c6726ac6
共有 100 个文件被更改,包括 995 次插入435 次删除
  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. 1 1
      packages/ckeditor5-build-balloon-block/build/ckeditor.js
  39. 1 1
      packages/ckeditor5-build-balloon-block/build/ckeditor.js.map
  40. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ar.js
  41. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ast.js
  42. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/az.js
  43. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/bg.js
  44. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/cs.js
  45. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/da.js
  46. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/de.js
  47. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/el.js
  48. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/en-au.js
  49. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/en-gb.js
  50. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/eo.js
  51. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/es.js
  52. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/et.js
  53. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/eu.js
  54. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/fa.js
  55. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/fi.js
  56. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/fr.js
  57. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/gl.js
  58. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/he.js
  59. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/hr.js
  60. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/hu.js
  61. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/id.js
  62. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/it.js
  63. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ja.js
  64. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/km.js
  65. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/kn.js
  66. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ko.js
  67. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ku.js
  68. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/lt.js
  69. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/lv.js
  70. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/nb.js
  71. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ne.js
  72. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/nl.js
  73. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/no.js
  74. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/pl.js
  75. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/pt-br.js
  76. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/pt.js
  77. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ro.js
  78. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ru.js
  79. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/si.js
  80. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/sk.js
  81. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/sq.js
  82. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/sr-latn.js
  83. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/sr.js
  84. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/sv.js
  85. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/th.js
  86. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/tr.js
  87. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/ug.js
  88. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/uk.js
  89. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/vi.js
  90. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/zh-cn.js
  91. 1 1
      packages/ckeditor5-build-balloon-block/build/translations/zh.js
  92. 22 22
      packages/ckeditor5-build-balloon-block/package.json
  93. 1 1
      packages/ckeditor5-build-balloon/build/ckeditor.js
  94. 1 1
      packages/ckeditor5-build-balloon/build/ckeditor.js.map
  95. 1 1
      packages/ckeditor5-build-balloon/build/translations/ar.js
  96. 1 1
      packages/ckeditor5-build-balloon/build/translations/ast.js
  97. 1 1
      packages/ckeditor5-build-balloon/build/translations/az.js
  98. 1 1
      packages/ckeditor5-build-balloon/build/translations/bg.js
  99. 1 1
      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


+ 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


+ 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


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

文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/ckeditor.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/ckeditor.js.map


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ar.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ast.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/az.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/bg.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/cs.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/da.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/de.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/el.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/en-au.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/en-gb.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/eo.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/es.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/et.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/eu.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/fa.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/fi.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/fr.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/gl.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/he.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/hr.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/hu.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/id.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/it.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ja.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/km.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/kn.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ko.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ku.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/lt.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/lv.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/nb.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ne.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/nl.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/no.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/pl.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/pt-br.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/pt.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ro.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ru.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/si.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/sk.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/sq.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/sr-latn.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/sr.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/sv.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/th.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/tr.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/ug.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/uk.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/vi.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon-block/build/translations/zh-cn.js


文件差异内容过多而无法显示
+ 1 - 1
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",

文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon/build/ckeditor.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon/build/ckeditor.js.map


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon/build/translations/ar.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon/build/translations/ast.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon/build/translations/az.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon/build/translations/bg.js


文件差异内容过多而无法显示
+ 1 - 1
packages/ckeditor5-build-balloon/build/translations/cs.js


+ 0 - 0
packages/ckeditor5-build-balloon/build/translations/da.js


部分文件因为文件数量过多而无法显示