The solution for fixing contenteditable is as follows:

I am currently working on a script to clean up pasted text within a contenteditable div.

While the script is functioning well for most part, I have noticed that in Firefox, line breaks get removed when the text is copied within or between the divs.

Does anyone have a solution for this issue?
If I paste text from a different source, the line breaks remain intact.
I am also open to exploring alternative solutions apart from the one provided below.

// Here's a fix for pasting within contenteditable
$(document).on('paste', '[contenteditable]', function (e) {
    e.preventDefault();

    if (window.clipboardData) {
        content = window.clipboardData.getData('Text');        
        if (window.getSelection) {
            var selObj = window.getSelection();
            var selRange = selObj.getRangeAt(0);
            selRange.deleteContents();                
            selRange.insertNode(document.createTextNode(content));
        }
    } else if (e.originalEvent.clipboardData) {
        content = (e.originalEvent || e).clipboardData.getData('text/plain');
        document.execCommand('insertText', false, content);
    }        
});
div {
  white-space: pre-wrap;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true">Copy
and
paste
this
back in the same box or the one below. Where do the line breaks go in FF?</div>
<div contenteditable="true">Copy
and
paste
this
back in the same box or the one above. Where do the line breaks go FF?</div>

Answer №1

After conducting thorough research, I have successfully developed a solution based on the discussions in the comments section of the question.

While experimenting with the Selection and Range API (https://developer.mozilla.org/en-US/docs/Web/API/Range), it came to my attention that the Range object possesses a toString() method. Curious to see if newlines were altered during this process, I decided to put it to the test.

To my relief, I discovered that the toString() method within the FF Range object does not remove newlines.

As a result, I have provided my code snippet and a fiddle to customize the default copy function by modifying the content stored in the clipboard upon copying.

$(document).on('copy', '[contenteditable]', function (e) {
  e = e.originalEvent;
  var selectedText = window.getSelection();
  console.log("original copied text\n--------\n", selectedText.toString());
  var range = selectedText.getRangeAt(0);
  var selectedTextReplacement = range.toString()
  console.log("replacement in clipboard\n--------\n", selectedTextReplacement);
  e.clipboardData.setData('text/plain', selectedTextReplacement);
  e.preventDefault(); // default behaviour is to copy any selected text
});
...
div {
  white-space: pre-wrap;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true">Copy
and
paste
this
back in the same box or the one below. Where do they line-breaks go in FF?</div>
<div contenteditable="true">Copy
and
paste
this
back in the same box or the one above. Where do they line-breaks go FF?</div>

In addition, I conducted a basic test on Edge and Chrome to ensure that the override feature does not cause any issues. It appears to be working well across different browsers, allowing for more control over copied content.

However, one lingering question remains in my mind: Why opt for a contenteditable div instead of a textarea if HTML elements are not required in the frontend?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When capturing photos using h5 on iOS devices, the browser may experience a flash back issue

I have been searching Baidu and Google for a while now, but I still haven't found a solution. Here is the specific issue: When using h5 to take photos on iOS systems, the browser flashes back. HTML Code <img src="xxx" onclick="sta ...

How can I gather information from members who have already signed up?

I have a form that submits data to the Angular Firebase database. Once the form is submitted, I want to display the previously submitted data in the form if the user signs in again. Below is my .ts file: import { Component, OnInit } from '@angular/c ...

How to populate an ExtJS 3.4 combobox with local JSON data in a few simple steps

I am utilizing ExtJS 3.4 and in need of populating a combobox with specific data obtained from a previous XMLHttpRequest, stored in a variable as follows: my_variable = "[{"cod_domini":"1","nom_domini":"Sant Esteve de Palautordera"},{"cod_domini":"2","no ...

How can I force a variable width font to behave like a fixed width font in HTML?

Is there a method to emulate the appearance of a fixed-width font using a variable width font in HTML? For instance, if I were to display the phrase "The quick grey fox jumped over the lazy dog" in "Courier New," a fixed-width font, it would appear wider ...

Show the information obtained from the dropdown menu selection

Upon selecting a different item from the drop-down list, I want the specific data related to that field from the MySQL database to be displayed. Currently, I am able to retrieve the value of the selected item in the dropdown menu but encountering difficul ...

Encountering an undefined json array when making an AJAX request

There have been numerous questions on this topic, but none of the specific solutions seemed to apply to my situation. So, I apologize if this is a duplicate query. I am currently working on fetching data from an SQL database using a PHP file that passes t ...

When the ngFor data reaches a count of four, it will be shown in a separate container div

I am struggling to find a way to display my ngFor data in a new container div once the length reaches four. It's easier to hard code the data into separate divs, but using ngFor results in the data being displayed in a single container div. In the co ...

You can easily dismiss the modal by clicking on any part of the screen, not just the button

I have a problem with my current code where I can only close a modal by clicking on a specific button. I want to modify it so that the modal can be closed by clicking anywhere on the screen. Unfortunately, as a JavaScript beginner, integrating new code sni ...

Error: The Gravatar service is unable to retrieve the property 'get' from an undefined source

I have a basic app with just one controller. I'm trying to debug the output of the Gravatar.get() function in the console. However, I encounter an error saying: "TypeError: Cannot read property 'get' of undefined". I'm confused because ...

How can I extract text from a website without retaining number, dot, and alphabet bullets in the list?

I am currently using Python 2.7.8 for a project involving a website with text displayed in an ordered list format using ol tags. I need to extract the specific text items listed below: Coffee Tea Milk This is an example of the HTML code used on my websit ...

What is the method for swapping out the <button> element with the enter key?

I have a webpage where users can post status updates, and other users can comment on these statuses by typing in the textbox and clicking the 'Reply' button. However, I would prefer to remove the button so users can simply press the enter key to ...

Using CSS to style the footer with a body height set to 100%

I am currently working on an angularJS web app with a basic template structure: <html> <head> <link rel="stylesheet" href="style.css" /> </head> <body id="top"> <!-- Templates with vi ...

Having Trouble Scooting Down the Page on Mobile?

Hello there! I'm having a bit of trouble trying to figure out why the scrolling functionality isn't working on my small web app when it reaches the media breakpoint for mobile devices. If you'd like to take a look, here's the link to ...

What is the best way to recycle Vue and Vuetify code?

<script> export default { data () { return { my_alert: false, text: '', color: 'success' } }, methods: { openAlt (text, color) { this.text = text this.color = color this.my_ale ...

Ensuring Uniqueness of Usernames through Client-Side Validation in

Looking to implement client-side validation for a username field during user registration to check if it is available before form submission. Using jQuery validate for basic client-side validations: http://jqueryvalidation.org/ Seeking advice on how to a ...

Every time I attempt to build a React application, I encounter the same error message. I even checked the log file, but it keeps showing the proxy error

An error occurred in the command prompt while installing packages. This process may take a few minutes. Installing react, react-dom, and react-scripts with cra-template... Error: ERR_SOCKET_TIMEOUT The network encountered a socket timeout while trying to ...

Looking to update the background color of a div every 3 seconds?

Every 3 seconds, I need to change the background color of each div. To do this, I attempted to modify the values in the color array every 3 seconds. For example, the value at index 0 (which is "red") would move to index 1, then the value at index 1 would ...

Make a copy of an array and modify the original in a different way

Apologies for my poor English, I will do my best to be clear. :) I am working with a 3-dimensional array which is basically an array of 2-dimensional arrays. My task is to take one of these 2-dimensional arrays and rotate it 90° counterclockwise. Here is ...

Create an eye-catching hexagon shape in CSS/SCSS with rounded corners, a transparent backdrop, and a

I've been working on recreating a design using HTML, CSS/SCSS in Angular. The design can be viewed here: NFT Landing Page Design Here is a snippet of the code I have implemented so far (Typescript, SCSS, HTML): [Code here] [CSS styles here] [H ...

The useEffect hook is not successfully fetching data from the local db.json file

I'm attempting to emulate a Plant API by utilizing a db.json file (with relative path: src\plant-api\db.json), and passing it from the parent component (ItemList) to its child (Item) but I am facing an issue where no data is being displayed ...