apostrophe icon indicating copy to clipboard operation
apostrophe copied to clipboard

Line breaks don't work inside `<pre>` tags in rich text widget

Open tomtuv opened this issue 1 year ago • 8 comments

To Reproduce

Step by step instructions to reproduce the behavior:

  1. Add a new rich text widget
  2. Select a custom <pre> style or create one using the Markdown shortcut ```
  3. Press +
  4. 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 Screenshot of the rich text widget with a `<pre>` element

tomtuv avatar Sep 12 '23 10:09 tomtuv

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 avatar Sep 12 '23 12:09 BoDonkey

@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.

tomtuv avatar Sep 12 '23 19:09 tomtuv

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.

boutell avatar Sep 12 '23 19:09 boutell

@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!

BoDonkey avatar Sep 12 '23 20:09 BoDonkey

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.

sujitmahapatra avatar Oct 05 '23 15:10 sujitmahapatra

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.

boutell avatar Oct 06 '23 15:10 boutell

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);
    }
  }
});

sujitmahapatra avatar Oct 12 '23 05:10 sujitmahapatra

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.

boutell avatar Oct 12 '23 12:10 boutell