Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tinyMCE - get content up to cursor position

I am making a little word prediction plugin for tinyMCE and need to extract a bit of text and later insert text from a list of predicted words. The insertion should be no problem, as I know where the cursor is and can use the mceInsertContent command. Getting the text for the prediction however...

I need to extract a subset of the text ending at the letter immediately before the cursor position and starting at, well, the start of the text. I can strip HTML tags myself if neccessary, but I prefer letting tinyMCE do it if possible.

I was thinking of doing it like this:

  1. Insert bookmark at current cursor positon using mceInsertContent
  2. Create a range from start of text up to my bookmark.
  3. Get the content of the range.
  4. Delete the bookmark.

Now, since I'm not that well versed in tinyMCE that has proved to be a bit of a challenge for me, so how would one go about doing this?

The code needs to work cross-browser.

like image 274
Woodgnome Avatar asked Sep 06 '26 04:09

Woodgnome


2 Answers

You may try this code snippets (ed is the tinymce editor object)

A. Insert bookmark at current cursor positon using mceInsertContent

ed.execCommand('mceInsertContent', false,'<span class="marker">\ufeff</span>');

B. Create a range from start of text up to my bookmark.

var rng = ed.selection.getRng(1);
var rng2 = rng.cloneRange();

// set start of range to begin of forst paragraph
rng2.setStartBefore($(ed.getBody()).find('p:first').get(0));

rng2.setEndBefore($(ed.getBody()).find('span.marker').get(0));
ed.selection.setRng(rng2);

C. Get the content of the range.

// get content of selection (range)
var content = ed.selection.getContent({format: 'text'});

D. Delete the bookmark.

$(ed.getBody()).find('span.marker').remove();

Update: If you are concerned about the selection change you may reset your initial range

ed.selection.setRng(rng);
like image 135
Thariama Avatar answered Sep 07 '26 17:09

Thariama


Here's my solution for this one (when Ctrl is pressed, the word is displayed in console):

function isLetter(chr){
    if(chr.match(/[A-Za-z\u00C0-\u00D6\u00D8-\u00f6\u00f8-\u00ff]/i)){
        return true;
    }
    else{
        return false;
    }
}



var editor = tinymce.activeEditor;
var $edBody = $(editor.getBody());
editor.on('KeyUp', function(e){
    if(e.code == "ControlLeft"){
        var sel = editor.selection.getSel();
        var caretPos = sel.anchorOffset;
        var txtData = sel.anchorNode.data;
        var i = caretPos;
        var word = "";

        while(i > 0){
            if(isLetter(txtData.charAt(i))){
                word += txtData.charAt(i);
                i -= 1;
            }
            else{
                break;
            }
        }

        word = word.split("").reverse().join("");

        i = caretPos + 1;
        while(i < txtData.length){
            if(isLetter(txtData.charAt(i))){
                word += txtData.charAt(i);
                i += 1;
            }
            else{
                break;
            }
        }
        console.log(word);
    }
});

Maybe there is an cleaner or more elegant way to solve this, if so, please comment and let's make this solution better.

like image 31
revliscano Avatar answered Sep 07 '26 19:09

revliscano



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!