Mount Ain
Mount Ain

Reputation: 406

How to make bold text in content editable div with raw text processing

I am trying to make font bold text with text processing instead of using execute.commands. Because I want make another functionality that not in execute.command.

Here is the code:

var selectedRange;
var selectedText = '';
let editor = document.getElementById('editor')


String.prototype.replaceBetween = function(start, end, what) {
    return this.substring(0, start) + what + this.substring(end);
};


function actionBold(e){


     let input = e.getElementsByTagName('input')[0]

    if(input != null){
        input.checked = !input.checked
    }

 
    if(selectedText.length != 0){

        let edited = editor.innerHTML.replaceBetween(selectedRange.start, selectedRange.end, `<b>${selectedText}</b>`)
        editor.innerHTML = edited
    }
}

function getSelectionCharacterOffsetWithin(element) {
    var start = 0;
    var end = 0;
    var doc = element.ownerDocument || element.document;
    var win = doc.defaultView || doc.parentWindow;
    var sel;
    if (typeof win.getSelection != "undefined") {
        sel = win.getSelection();
        if (sel.rangeCount > 0) {
            var range = win.getSelection().getRangeAt(0);
            var preCaretRange = range.cloneRange();
            preCaretRange.selectNodeContents(element);
            preCaretRange.setEnd(range.startContainer, range.startOffset);
            start = preCaretRange.toString().length;
            preCaretRange.setEnd(range.endContainer, range.endOffset);
            end = preCaretRange.toString().length;
        }
    } else if ( (sel = doc.selection) && sel.type != "Control") {
        var textRange = sel.createRange();
        var preCaretTextRange = doc.body.createTextRange();
        preCaretTextRange.moveToElementText(element);
        preCaretTextRange.setEndPoint("EndToStart", textRange);
        start = preCaretTextRange.text.length;
        preCaretTextRange.setEndPoint("EndToEnd", textRange);
        end = preCaretTextRange.text.length;
    }
    return { start: start, end: end };
}

function onMouseUp() {
 
    const sel = window.getSelection();
    var arr  = []
    for (var i = 0, len = sel.rangeCount; i < len; ++i) {
        arr.push(sel.getRangeAt(i).cloneContents().textContent);
    }
    selectedText = arr.join();

     selectedRange = getSelectionCharacterOffsetWithin(editor)
}
input{

    display: none;
}

input:checked+svg{

    background-color: rgb(194, 10, 10);
    fill: #fff;
}

label{

    cursor: pointer;
}


#editor{

    width: 50%;
    min-height: 40px;
    background-color: antiquewhite;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>


    <label  onclick="actionBold(this); return false">
        <input class="none" type="checkbox" name="0" checked>
         <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
     </label>

    <div onmouseup="onMouseUp()" id="editor" contenteditable>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Enim omnis ea, voluptas maxime perspiciatis praesentium magni repellendus earum suscipit sint. Veritatis fuga adipisci accusantium similique distinctio vero tenetur ipsam fugiat.</p>
    </div>

    <script src="script.js"></script>


</body>
</html>

I am able to get selected range and I replaced the selected string with <b> tag to get bold font. But the problem is with HTML tags are not counted in range either I don't know how to proceed this further.

I am fine with open source libraries and premium libraries but I want to study it how it works. That's why I trying it my own.

Currently I am using raw text processing. Can anyone knows How to proceed this logically to get successful text editor for bold font only? Thanks in advance.

Upvotes: 6

Views: 888

Answers (1)

Pavan Kumar Jorrigala
Pavan Kumar Jorrigala

Reputation: 3085

I used the following method from Range API

extractContents: to extract the selected content, so we can wrap it with bold tag.

insertNode: putting back the modified content in the same position.

let editor = document.getElementById('editor');
var preCaretRange;

function actionBold(e){
    var bold = document.createElement('b'); // created bold tag
    bold.appendChild(preCaretRange.extractContents()); // extracting and wrapping the content with tag
    preCaretRange.insertNode(bold); // insert the modified content back

}

function onMouseUp() {
    var doc = editor.ownerDocument || editor.document;
    var win = doc.defaultView || doc.parentWindow;
    preCaretRange = win.getSelection().getRangeAt(0);
}

Upvotes: 1

Related Questions