CKEditor5 & Angular2 - Getting exact position of caret on click inside editor to grab data

社会主义新天地 提交于 2019-12-24 06:27:17

问题


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

On a high level, I'm trying to trigger a method when a user clicks inside a Balloon Editor, and it will store all the text before the cursor in a variable, and then store all the text after a cursor in another variable.

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

Any idea on how to accomplish this? I assume I need to create two instances of Position and then somehow feed that into a Range, but I have no idea on how to feed the Position the correct path.

If anyone has a working method for just a regular old single instance of CKEditor 5, I would appreciate it. Thank you!


回答1:


The full solution will look like this:

const pos = editor.document.selection.getFirstPosition();

// If you want to get the text up to the root's 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's 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 );

You use here the TreeWalker to get all items in a range and stringify text proxies which you find there.

Please note that you get TextProxys instead of normal Text nodes because the tree walker may need to return a part of a text node (if the range ends in the middle of that text node).


EDIT: To stringify the content to the data format, (so – including HTML markup, not just text), you need to use a bit 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 ) );
}


来源:https://stackoverflow.com/questions/47758418/ckeditor5-angular2-getting-exact-position-of-caret-on-click-inside-editor-to

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!