CKEditor5 & Angular2 - Getting the exact caret position when clicking inside the editor to capture data

In Angular2 +, I try to get the exact caret position when I click inside the CKEditor5 Balloon Editor instance. I will have several instances on the page, each of which is dynamically represented via @ViewChildren and QueryList (each instance is a separate editor).

At a high level, I try to call a method when the user clicks inside the Ball Editor, and he will save all the text before the cursor in a variable, and then save all the text after the cursor in another variable.

i.e. if the user types Hello world this is a test and clicks inside the div after the "world", he will store "Hello world" in one variable and "this is a test" in another variable.

Any idea on how to do this? I assume that I need to create two instances of Position , and then somehow pass this to Range , but I don't know how to feed Position correct path.

If someone has a working method just for a regular old CKEditor 5 instance, I would appreciate it. Thanks!

+1
source share
1 answer

A complete solution would look like this:

 const pos = editor.document.selection.getFirstPosition(); // If you want to get the text up to the root boundary: // const posStart = Position.createAt( pos.root ); // const posEnd = Position.createAt( pos.root, 'end' ); // If you want to get the text up to the current element boundary: const posStart = Position.createAt( pos.parent ); const posEnd = Position.createAt( pos.parent, 'end' ); const rangeBefore = new Range( posStart, pos ); const rangeAfter = new Range( pos, posEnd ); let textBefore = ''; let textAfter = ''; // Range is iterable and uses TreeWalker to return all items in the range. // value is of type TreeWalkerValue. for ( const value of rangeBefore ) { if ( value.item.is( 'textProxy' ) ) { textBefore += value.item.data; } } for ( const value of rangeAfter ) { if ( value.item.is( 'textProxy' ) ) { textAfter += value.item.data; } } console.log( textBefore ); console.log( textAfter ); 

Here you can use TreeWalker to get all the elements in the range and align the text proxies you find there.

Please note that you get TextProxy instead of regular Text , because the walker may need to return part of the node text (if the range ends in the middle of this node text).


EDIT: To reinforce content in a data format (so - including HTML markup, not just text), you need to use several different methods:

 function doStuff( editor ) { const pos = editor.document.selection.getFirstPosition(); const posStart = Position.createAt( pos.root ); const posEnd = Position.createAt( pos.root, 'end' ); const rangeBefore = new Range( posStart, pos ); const rangeAfter = new Range( pos, posEnd ); const fragBefore = editor.data.getSelectedContent( new Selection( [ rangeBefore ] ) ); const fragAfter = editor.data.getSelectedContent( new Selection( [ rangeAfter ] ) ); console.log( editor.data.stringify( fragBefore ) ); console.log( editor.data.stringify( fragAfter ) ); } 
0
source

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


All Articles