Woodgnome
Woodgnome

Reputation: 2391

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.

Upvotes: 3

Views: 15871

Answers (3)

Alexandru Pavaloi
Alexandru Pavaloi

Reputation: 29

I just stumbled upon a similar usecase. I want to remove everything after the cursor position.

Here's my solution

// Insert a unique marker so I can easily find the current position in the editor
const UNIQUE_MARKER = "MARKER";
editor.insertContent(UNIQUE_MARKER);

const markerIndex = editor.getContent().indexOf(UNIQUE_MARKER);
const beforeCursorContent = editor.getContent().slice(0, markerIndex);

editor.setContent(beforeCursorContent);

Upvotes: 1

revliscano
revliscano

Reputation: 2272

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.

Upvotes: 1

Thariama
Thariama

Reputation: 50832

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

Upvotes: 10

Related Questions