Problem/Motivation
https://github.com/ckeditor/ckeditor5/releases/tag/v40.0.0
All major breaking changes in this release are for/due to <img height> support (see point 1 below).
All minor breaking changes are for the comments plugin, which Drupal does not use.
Notable in this release:
- Support for
<img height>, which empty inline elements, which is a big regression for front-end performance for content created in CKEditor 5.That's why it was one of the prioritized upstream blockers in #3340578: [meta] [upstream] Prioritized CKEditor 5 upstream blockers.
- A new "simple list" config option, to disallow markup like
<ul><li>a</li><li><p>paragraph 1</p><p>paragraph 2</p></li></ul>and only allow markup like<ul><li>a</li><li>b</li></ul>. This MR allows configuring that:
- More UI components were introduced, which could be very powerful and enabling for CKEditor 5 plugins in the contrib space! I think
AutocompleteViewmay be valuable for #3317769: Add support for linking to entities in CKEditor 5 for example :) - The
Drag and drop of blocks
functionality requires the use of theBalloonEditor, not theClassicEditorthat we use. I did ask @witeksocha if it'd be possible to just get the drag-and-drop parts without the toolbar, and while it isn't supported out of the box, it "should not be too hard to do". 🤞 Would be a great feature addition! - I tried the AI demo (which we cannot ship in Drupal enabled by default because it requires a paid API key), and it sure does look nice. It's not able to generate images just yet unfortunately (my prompt:
insert an image of a cute llama with a Druplicon on its back
failed, although it generatedhttp://ckeditor.com/docs/images/cute_llama.jpeg😄), but generating 2 paragraphs about Drupal's past and future worked fine:
It requires a CKEditor 5 premium license too, so I imagine that those who are interested will soon be able to use it in https://www.drupal.org/project/ckeditor5_premium_features.
Proposed resolution
- Update
core/package.json yarn --cwd core install && yarn --cwd core build && yarn --cwd core build:ckeditor5-types
Remaining tasks
- Get images working again — see #8.
- Update path test for the modified
ckeditor5_listconfiguration
User interface changes
New config option:

API changes
None.
Data model changes
The configuration for the ckeditor5_list plugin is modified. An update path is (of course) provided.
Release notes snippet
CKEditor 5 has been updated to 40.0.0. This fixes a long-standing front-end performance problem: until now, images linked in CKEditor 5 generated markup that lacked the image height. This would cause layout shifts after the images had loaded, since the browser could not possibly know the height it had to reserve for the images.
NOTE: this was not a problem if you were uploading images thanks to the Track images uploaded via a Text Editor
setting width & height automatically. But that didn't work for linked images (inserted by URL).
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | Screenshot 2023-10-12 at 4.46.38 PM.png | 105.1 KB | wim leers |
| #9 | Screenshot 2023-10-12 at 4.12.34 PM.png | 252.64 KB | wim leers |
Issue fork drupal-3393557
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3393557-cke5-40
changes, plain diff MR !4989
Comments
Comment #2
wim leersFYI: thanks to #3379104: Add a "CKEditor 5 nightly" GitLab CI job, we already know that we'll need to change the
drupalImageplugin, because on September 1, tests still passed, but on September 18, they failed.Expected failures:
CKEditor5Test::testEditorFileReferenceIntegration()CKEditor5Test::testAttributeEncoding()ImageTest::testAlignment()ImageTest::testWidth()ImageUrlTest::testAlignment()ImageUrlTest::testWidth()Comment #3
wim leersIssue summary updated to make this a 2-step process instead of a 5-step process. Will make future updates simpler 👍
Comment #5
wim leersYay, both
::testAlignment()cases now pass 👍Everything else seems centered on the presence of this new
style="aspect-ratio:WIDTH/HEIGHT"in the<img>markup.Seems doable!
Comment #6
wim leers⚠️ upstream
<img heightwas implemented in an incompatible way🤩 1. Drop a lot of overrides from
drupalImage!We actually implemented a lot of overrides to get
widthandheightworking reliably.Looks like we can just
rm -rfthat: https://git.drupalcode.org/project/drupal/-/merge_requests/4989/diffs?co... — 131 lines gone 🥳🤷♂️ 2. Presence of
style="aspect-ratio:3456/2160"https://ckeditor.com/docs/ckeditor5/latest/updating/guides/update-to-40.... says:
That sounds like it'd be
<img aspect-ratio>… but it's actually not an attribute, but aCSS property. 😬 IOW: a value of the
styleattribute:<img style="aspect-ratio:…">.The use of the
styleattribute means that this will not work in Drupal, since Drupal's measures to protect content creators from XSS injection will strip any and allstyleattributes:—
\Drupal\editor\Element::preRenderTextFormat()editor_filter_xss()is smart enough to only run it for text formats that do have XSS filtering, which is why it will not do anything forfull_htmlfor example.Now, this is not even a big deal, because we simply do not need that information! Drupal uniquely never allowed resizing without respecting the aspect ratio.
Unfortunately,
attachDowncastConverter'ssetRatioForInlineImageparameter only applies to inline images, and nothing else in the relevant commit appears us to override this behavior. Still, we can work around this.😱 3. Reliance on
style="aspect-ratio:3456/2160;width:419px;"for actually resizingOh noes … resizing that 3456x2160 image only seems to work in CKEditor 5 itself? It does not work in the final rendered result?
Turns out that
widthandheightare always the original width and height, and not the resized ones! 🫣Fine, this makes sense for certain HTML-centric approaches. But we'll at least need our downcast to behave differently, because otherwise a lot of contrib/custom modules will break.
So we'll have to restore our own downcast and adjust it.
However … it appears that the
Originalbutton then will not work at all.This too seems surmountable:
setImageNaturalSizeAttributes()'s logic should be tweaked. AFAICT just removing a singleif-statement would be enough:👆 That would always get the loaded image width/height as the correct one. The browser will load the image anyway, so there's no extra cost.
Conclusion
It is possible in theory to do all this overriding on our end, but AFAICT a
40.0.1release from the CKEditor 5 team with:setImageNaturalSizeAttributes()resizedHeightavailableI will discuss this in the meeting I have with them in ~30 mins. 👍
Comment #8
wim leersDiscussed in detail with @witeksocha. He recalls there was a reason to remove
resizedHeight, but alas it was not documented. He also recalls there was a good reason to not always set the natural width & height.He'll talk to the engineer who led this upstream change and will get back to me early next week 👍
Comment #9
wim leersNew config option:

From the release notes:
👆 Now available in Drupal.
Comment #10
wim leersThey're working on this upstream at https://github.com/ckeditor/ckeditor5/issues/15185.
Comment #12
wim leersNo comments were posted there, but it looks like 2 days ago @niegowski linked a PR (https://github.com/ckeditor/ckeditor5/pull/15222) that provides the necessary example here.
Comment #13
wim leersComment #14
wim leersI was able to port https://github.com/ckeditor/ckeditor5/pull/15222 by mostly copy/pasting and it works 😄🥳
However, it looks like it does not support %-based
widthvalues.Let's find out what other tests fail…
Comment #15
wim leersOkay, I've got all tests passing now, except for one:
… for both locally hosted (aka uploaded) images and remotely hosted images.
That makes sense: we previously already had to write custom logic (see #3249592: [drupalImage] <img width> upcast assumes HTML5: px unit, but HTML4 allowed % unit) to keep these working, and the code I've copy/pasted from upstream does not handle this.
Comment #16
wim leersAlso, we absolutely need to make sure that that continues to work correctly, because until ~6 months ago, image resizing in CKEditor 5 was using
%, notpx: #3348603: CKEditor 5 resizes images with % width instead of px width (the CKEditor 4 default): breaks image captions *and* is a regression.Comment #17
wim leersJust pushed the missing update path test coverage.
This is now ready for review 😊
Comment #18
wim leersClarify the issue summary.
Comment #19
smustgrave commentedSince the main feature for core seems to be list
Disabled Allow the user to create paragraphs in list items (or other block elements)
Created a page placing
<ul><li>a</li><li><p>paragraph 1</p><p>paragraph 2</p></li></ul>P tags got turned to li
Enabled Allow the user to create paragraphs in list items (or other block elements)
Create a page placing
<ul><li>a</li><li><p>paragraph 1</p><p>paragraph 2</p></li></ul>P tags remained the same.
Comment #20
catchLeft a comment on the MR.
Comment #21
wim leersThe irony — @catch just talked to me about this ~1.5 week ago and I still forgot 😅🙈 Matched the pattern that was used in #3282233: Ability to configure additional languages (e.g. "bash" or "SQL") for CKEditor 5 CodeBlock plugin.
Comment #22
smustgrave commentedDidn't think of that post_update vs presave so that's on me.
But looks to have been addressed and tests are green.
Comment #23
catch@Wim does that mean we're locked on CKEditor 39 on 10.1.x for the forseeable future or would it be possible (and if so, desirable) to backport just the update without the configuration changes - not sure how much it is API change vs. new feature.
Comment #24
wim leersIt is possible to backport without the
ckeditor5_listplugin config changes, and instead just hardcode the default behavior in HEAD (multiBlock: true.I did not propose that because I was under the impression that the policy is to never update JS packages unless for very strong reasons. We did have such very strong reasons for CKEditor 38.1.0 (https://www.drupal.org/project/drupal/issues/3340578#fixed-10.1.1) and 39.0.0 (https://www.drupal.org/project/drupal/issues/3340578#fixed-10.1.3), because each of them fixed data loss issues or upgrade-blocking-missing-functionality problems.
For this one, the impact is far less severe. And the potential risk of unknown/unadvertised breaking changes does not seem to outweigh the presence of
<img height>😅If you want to see this backported nonetheless, I'd be happy to work on a
10.1.x-specific MR 👍Comment #25
catchI don't strongly want to backport it, I just wondered whether it's better to leave 10.1 on 39 or 40. If there's no strong reason to update let's not, given we only have about 1 normal patch release of 10.1 left anyway.
Comment #26
spokjeComment #27
catchThis needs an yarn lock update.
Comment #28
spokjeComment #30
catchCommitted/pushed to 11.x and cherry-picked to 10.2.x, thanks!
Comment #31
longwaveThis made it to 11.x but not 10.2.x.
Comment #33
catchOuch thanks. Pushed now.