CKeditor 5 removes whitespace from within `<pre>` tags
Description of the bug
After switching to CKeditor 5, pages on the documentation site that previously had nicely indented code samples, loose the whitespace after saving with ckeditor5 enabled.
This appears to be a known issue with ckeditor5. There is both an issue and a Pull Request with a potential solution:
- issue: https://github.com/ckeditor/ckeditor5/issues/16124
- PR: https://github.com/ckeditor/ckeditor5/pull/16125
Steps To Reproduce
To reproduce the behavior:
- Create a page in "Raw HTML" mode
- Add some nicely idndened code in a
<pre>tag, something like
h3 {
font-size: 2em;
}
- Save.
- Edit the page, switch to a text format with ckeditor5 enabled.
- Save. See how whitespace has been removed from display
- Edit the page again. See how whitespace has also been removed from the database
Actual behavior
Whitespace deleted.
Expected behavior
Whitespace preserved.
Additional information
Add any other information that could help, such as:
- Backdrop CMS version: 1.27.1
Hello! I noticed that you referred to the issue and pull request I made for CKEditor.
Please note that those are not related to <pre> tags, as those should already work out of the box in CKEditor (but might have to be enabled explicitly, maybe with https://ckeditor.com/docs/ckeditor5/latest/features/code-blocks.html).
Instead, the issue and pull request relate to preformatted text with the white-space CSS property, which will preserve white space similar to how it is preserved in a <pre> tag, but does not involve <pre> tags, code blocks, etc.
This may be an issue with our code formatter that we apply to saved content coming out of CKEditor, rather than a CKEditor 5 specific issue. When switching back and forth from Source mode with the CKEditor 5 toolbar button, the formatting is maintained. But when saving the content, the spaces are lost in the content that is saved to the database.
If I edit ckeditor5.js and comment out this line:
newData = Backdrop.ckeditor5.formatHtml(newData);
Then <pre> tags preserve white-space properly.
Looks like CKEditor 5 made a similar correction to their HTML formatter in this commit: https://github.com/ckeditor/ckeditor5/commit/14c02db1a80562bae455ca8ed7ed900fe18b8798
The Backdrop code formatter is essentially a copy of the internal code formatter used by CKEditor. If we port/adapt this fix into our own formatter it should preserve <pre> tag spacing on save.
I ported https://github.com/ckeditor/ckeditor5/commit/14c02db1a80562bae455ca8ed7ed900fe18b8798 into https://github.com/backdrop/backdrop/pull/4757, using Backdrop code style and writing in JS instead of TypeScript. It seems to fix the problem. I ran into this issue writing documentation on docs.backdropcms.org (which obviously needs a lot of code samples). It would be great to get this fixed.
I have tested this with a demo sandbox (running 1.28.0 as of earlier today) vs. the PR branch sandbox:
- Create a page in "Raw HTML" mode
- Add some nicely idndened code in a
<pre>tag, something like<pre> h3 { font-size: 2em; } </pre> - Save
In both cases, the rendered output is this (4 spaces preserved 👍🏼 ):
h3 { font-size: 2em; } - Edit the page:
The format in both cases retains the whitespace 👍🏼 (4 spaces at the beginning of the
font-size: 2em;line) - switch to a text format with ckeditor5 enabled (the default "Basic" format that we ship OOTB with core) -> warning shown in both cases:
Activating CKEditor 5 will reformat the content of this field. Review content carefully after activating. Click to activate editor.
- Click the link to activate the editor: in both cases, the text switches to this (all rendered in a single line):
h3 { font-size: 2em;} - While still in the WYSIWYG, Select that single-line text and copy it. Then paste is somewhere where formatting is preserved (like in a GitHub comment) -> in both cases, the single line text is converted to multi-line when you paste it - whitespace still retained (not part of what we are testing here, but I found it interesting, so I thought I'd report it):
h3 { font-size: 2em; } - Click the "Source" button in the CKEditor toolbar -> in both cases, this is the result (
<pre>s replaced with<p>s, and 4 spaces replaced withspace+ +space+ ):<p> h3 { font-size: 2em; } </p> - Save the content. In both cases, the rendered output is this (notice: 3 spaces now):
h3 { font-size: 2em; } - Edit the page again. In both cases:
- there is no CKE toolbar 👎🏼
- the
Activating CKEditor 5 will reformat the content of this field. Review content carefully after activating.warning is still shown 👎🏼 - the editor is still "Basic" 👍🏼
- the content in the text area is this (the first
spaceis missing - you now get +space+ ):<p> h3 { font-size: 2em; } </p>
- Clicking the link to activate the editor in both cases results in this (switched to single-line again,
<p>tags instead of<pre>, and now you have 4 spaces again 🤔 ). Switching to source shows this:<p> h3 { font-size: 2em; } </p>
So yeah, in both cases I see many things that do not work as expected, however l don't see any difference between them. Am I missing something?