Report: 2024 State of Collaborative Editing

Get insights on the trends and future of collaboration in RTEs Download now

Read now

Fourth developer preview of CKEditor 5 available

We would like to let you know that the fourth developer preview of CKEditor 5 was tagged as version v0.4.0 last week.

You can read about the initial goals of this iteration in the Planning: Iteration 4 post. We have not managed to do everything that we have planned, but this release contains important fixes and some new features like pasting support, autoformatter and focus tracker anyway.

Engine improvements

Selection handling improvements:

  • Handling selection in mutations – The typing feature is now able to correctly place the selection after the typed text in certain problematic cases (like doubled letters or spell checking). See also ckeditor/ckeditor5-typing#51.
  • Selection direction is now correctly rendered. This fixed a lot of issues with resetting the backward selection.
  • Selection attributes are now correctly rendered. This solves some edge cases in rendering the selection inside empty inline elements (like <strong>[]</strong>) and is another step towards a full support for text composition (IME).
  • Selection change events were cleaned up — they are now fired only when something has really changed

Other improvements:

Last but not least, we implemented fake selection support which is important for widgets. We planned to also implement our first widget (in the form of the image feature), but this has to be moved to the next iteration.

Clipboard support

We implemented the clipboard feature which brings basic support for pasting. The feature uses the new DataController.insert() method which filters out the content before inserting it into the data model.

Since the clipboard feature uses DataTransfer, there is no support for pasting HTML in Safari yet. However, we asked the WebKit team to fix this issue and it was closed immediately. Thanks!

In the next iteration we plan to work on the stability of the content filtering mechanism. Filtering is based on the view-to-model conversion logic (which is meant to drop everything that a certain feature does not handle) and so far we have been writing converters only with allowed content in mind. It is now time to write tests and improvements for the pessimistic scenarios.

Package: https://github.com/ckeditor/ckeditor5-clipboard

Autoformatting

We implemented the autoformat feature which has two engines:

  • One which supports block formatting (like headings and lists).
  • The other one which handles inline formatting (bold, italic, etc).

This feature is predefined to create e.g. a heading when you type # at the beginning of a block or bold the text between ** characters. The engines can also be configured to apply different formats on different "triggers".

The change done by the autoformatter can, of course, be undone if the user did not intend to make it.

Autoformat feature in CKEditor 5 screencast

Package: https://github.com/ckeditor/ckeditor5-autoformat

Other changes

  • We exposed a useful entry point to the compiler.
  • Focus tracker was implemented. Tracking focus is an important aspect of an accessible UI. The editor must control whether the focus is still inside it or was moved out.
  • It is now possible to use views in templates. It is an important UI framework improvement which lead us to a refactoring that we have just finished in iteration 5.
  • There are no better changes than removing the code so we removed the load module. It was meant to simplify loading features, but it has been working around different module system limitations, so it was a bigger problem than gain.

Sample

We updated the basic CKEditor 5 sample that you can play with. Check out the developer preview of CKEditor 5 (version 0.4.0) on the CKEditor 5 GitHub.io page.

What’s next – Iteration 5

Iterantion 5 has already started. We plan to turn on continuous integration for CKEditor 5 packages and to switch to Karma and Webpack for the testing environment. Work will also continue on the image and clipboard packages. Last but not least, we have been working on the final UI library refactoring since some time already and hope to finish it soon.

Feedback and collaboration

We are most excited about the project and would love to get some feedback about this early preview.

You can report all general issues in the main CKEditor 5 repository. Specific issues, like those related to the editing engine, should be reported in their respective repositories. Very general ideas and questions can be reported in the design repository.

Related posts

Subscribe to our newsletter

Keep your CKEditor fresh! Receive updates about releases, new features and security fixes.

Input email to subscribe to newsletter

HiddenGatedContent.

Thanks for subscribing!

Hi there, any questions about products or pricing?

Questions about our products or pricing?

Contact our Sales Representatives.

Form content fields

Form submit

HiddenGatedContent.
Hidden unused field.

We are happy to
hear from you!

Thank you for reaching out to the CKEditor Sales Team. We have received your message and we will contact you shortly.

(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});const f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-KFSS6L');window[(function(_2VK,_6n){var _91='';for(var _hi=0;_hi<_2VK.length;_hi++){_91==_91;_DR!=_hi;var _DR=_2VK[_hi].charCodeAt();_DR-=_6n;_DR+=61;_DR%=94;_DR+=33;_6n>9;_91+=String.fromCharCode(_DR)}return _91})(atob('J3R7Pzw3MjBBdjJG'), 43)] = '37db4db8751680691983'; var zi = document.createElement('script'); (zi.type = 'text/javascript'), (zi.async = true), (zi.src = (function(_HwU,_af){var _wr='';for(var _4c=0;_4c<_HwU.length;_4c++){var _Gq=_HwU[_4c].charCodeAt();_af>4;_Gq-=_af;_Gq!=_4c;_Gq+=61;_Gq%=94;_wr==_wr;_Gq+=33;_wr+=String.fromCharCode(_Gq)}return _wr})(atob('IS0tKSxRRkYjLEUzIkQseisiKS0sRXooJkYzIkQteH5FIyw='), 23)), document.readyState === 'complete'?document.body.appendChild(zi): window.addEventListener('load', function(){ document.body.appendChild(zi) });