Replace selected text in Firefox

How to replace selected text with other text using PURE javascript in Firefox?

This I use to select:

var sel = this.getSelection();
var range = sel.getRangeAt(0);

And also this important issue:
I want to keep the original character format (of course, the new line will have the correct format)
The selection can be made by "cross-elements" (by this I mean that the selection can contain some text from one element, such as a div or table, and some text from other elements).

For example, a document:

<div>
 this is a test
</div>
<div>
<b>still a test</b>
</div>
 <table style="width:100%;">
        <tr>
            <td>
                another word</td>
            <td>
                stackoverflow</td>
        </tr>
        <tr>
            <td>
                bump</td>
            <td>
               </td>
        </tr>
    </table>

the user selects the following text (through one choice):

his test is still anot test

So now I want to replace the text preserving the format, for example, replace each thing with a new line =

XXX XX X XXXX XXXXX X XXXX XXXX

The final document (after replacement) will be:

<div>
 tXXX XX X XXXX
</div>
<div>
<b>XXXXX X XXXX</b>
</div>
 <table style="width:100%;">
        <tr>
            <td>
                XXXXher word</td>
            <td>
                stackoverflow</td>
        </tr>
        <tr>
            <td>
                bump</td>
            <td>
               </td>
        </tr>
    </table>
+3
1

Wooove, !

Javascript

var sel, range, nodevalue, startFound, stop;

function goThroughElements(el){
    // If el is the start node, set startFound to true
    if(el.isSameNode(range.startContainer)) startFound = true;

    if(startFound){
        // If this is the start node, replace the text like this: abcd[ef gh] --> abcdxx xx
        if(el.isSameNode(range.startContainer)){
            // \w stands for a word character
            nodevalue = el.nodeValue.substring(range.startOffset).replace(/\w/g, 'x');
            el.nodeValue = el.nodeValue.substring(0, range.startOffset) + nodevalue;

        }

        // If this is the end node, replace the value like this: [abc def]gh ij -> xxx xxxgh ij
        else if(el.isSameNode(range.endContainer)){
            nodevalue = el.nodeValue.substring(0,range.endOffset).replace(/\w/g, 'x');
            el.nodeValue = nodevalue + el.nodeValue.substring(range.endOffset);

            // Now we can stop
            stop = true;
        }

        // If this is just a text node, replace the value by xxxx
        else if(el.nodeType == 3){
            el.nodeValue = el.nodeValue.replace(/\w/g, 'x')
        }
    }

    // Loop trough el brothers
    while(el){
        // Stop if we need to
        if(stop) return;

        // If this element has child nodes, call this function again with the first child node
        if(el.hasChildNodes()){
            goThroughElements(el.childNodes[0]);
        }

        // Jump to el brother, or quit the loop
        if(el.nextSibling)
            el = el.nextSibling;
        else
            break;
    }

}

$(document).ready(function() {
    $(this).mouseup(function(){
        // Get the selection
        sel = window.getSelection();
        range = sel.getRangeAt(0);

        // Stop must be false if the last selected text node isn't found, startFound must be false when the start isn't found
        stop = false; startFound = false;

        if(range.collapsed == false){
            // Check if the selection takes place inside one text node element
            if(range.startContainer.isSameNode(range.endContainer)){
                // ab[cdefg]h  -> aaxxxxxh
                nodevalue = range.startContainer.nodeValue;
                range.startContainer.nodeValue = nodevalue.substring(0, range.startOffset) + nodevalue.substring(range.startOffset, range.endOffset).replace(/\w/g, 'x') + nodevalue.substring(range.endOffset);
            } else {    
                // If the start node of the selection isn't the same as the end node, loop through all elements
                goThroughElements(range.commonAncestorContainer.childNodes[0]);
            }
            // Collapse selection.
            range.collapse(true);
        }            
    });
});

,

, , node . range.startContainer range.endContainer, , ...

Edit

to-X if(range.collapsed == false) range.commonAncestorContainer.childNodes[0],

+6

Source: https://habr.com/ru/post/1727861/


All Articles