apostrophe
apostrophe copied to clipboard
Line breaks don't work inside `<pre>` tags in rich text widget
To Reproduce
Step by step instructions to reproduce the behavior:
- Add a new rich text widget
- Select a custom
<pre>
style or create one using the Markdown shortcut```
- Press ⇧ + ⏎
- A new paragraph is created instead of a line break
Expected behavior
A new line break should be created inside the same <pre>
element.
Describe the bug
Line breaks work fine inside <p>
tags using ⇧ + ⏎ but when inside <pre>
tags, it creates a new paragraph.
Details
Version of Node.js: 16.20.1
Server Operating System: Linux
Additional context: The bug is present in all browsers.
Screenshots
Thanks for the bug report. The rich text widget loads the Tiptap codeblock extensions, but for some reason, it doesn't recognize a return inside. Just an FYI - Tiptap kinda implements Markdown. In this case, once you toggle a codeblock on with three backticks or tilde, you should be able to use a plain return and stay in the block. You need to use three returns or a down arrow to get out of the block (if it is working correctly).
@BoDonkey Thank you for the quick response. I've tried with the Markdown way using the three backticks but there is the same problem. Pressing ⏎ creates a space and ⇧ + ⏎ creates a new paragraph.
It's worth checking the official tiptap sandboxes to see if they also have this problem. If not we may have broken something with a custom paragraph tag.
@tomtuv Sorry - should have been clearer in my earlier comment. You are correct, something is broken. When it is fixed, you should only need to hit return to create a new line still within the code fence. @boutell I checked the official sandbox and made sure everything worked as expected before I opened the ticket. I forgot we even had the codeblock extension loaded in addition to the code extension!
To solve the issue where line breaks inside a <pre>
element are creating new paragraphs instead of new line breaks,
Wrap the content inside the <pre>
element with a <div>
or another block-level element.
Here's an example
<div>
<pre>
Your preformatted text here
</pre>
</div>
By wrapping the <pre>
element in a <div>
, line breaks created with Shift + Enter (⇧ + ⏎) will stay within the same block-level container, preventing the creation of new paragraphs.
How strange. I wonder why this is necessary. We might be able to do it just while in the editor, stripping out and restoring the divs as we save and reload the editor.
Please note that this is a simplified, conceptual solution, and the exact implementation will depend on the rich text editor library you're using and its API. In practice, you would need to adapt this to your specific development environment.
const richTextEditor = document.getElementById('myRichTextEditor');
// Add an event listener to the editor for detecting the Shift + Enter keypress
richTextEditor.addEventListener('keydown', (event) => {
if (event.shiftKey && event.key === 'Enter') {
// Prevent the default behavior of creating a new paragraph
event.preventDefault();
// Check if the cursor is inside a <pre> tag
const selection = window.getSelection();
const parentElement = selection.focusNode.parentElement;
if (parentElement && parentElement.tagName === 'PRE') {
// Insert a line break within the <pre> tag
const range = selection.getRangeAt(0);
const br = document.createElement('br');
range.insertNode(br);
range.setStartAfter(br);
range.setEndAfter(br);
selection.removeAllRanges();
selection.addRange(range);
}
}
});
That's actually a pretty long way from how Tiptap does things. Your first observation may be relevant to Tiptap but the second would be difficult to apply.