ShadowRoot getSelection (). GetRangeAt (0) returns invalid Range object in Google Chrome 35

We are working on an application for our client that uses dart lang with polymer components. One of our custom components, namely datagrid, uses a datagrid <div contenteditable></div>to enter values ​​into cells. I also want to provide custom formatting capabilities, so I had to override the keystroke event. The problem occurs when I want to create new HTML nodes at the caret position in the content-editable div element in Chrome 35 (perhaps all webkit browsers that support the Shadow DOM natively, and not through polyfills).

When I use window.getSelection().getRangeAt(0)to get the current caret position, new nodes are added to the beginning of the body element instead of the div. In Firefox and IE 11, it works fine (using polyfill).

When I tried this.shadowRoot.getSelection().getRangeAt(0), as suggested here , it did not work because it returns the wrong Range object (error or function?). However, when I registered the Selection object, it seems that all the offsets are correct, so this means that it can be processed in some way, but the guy who asked a similar question on SO did not publish how he did it.

So, I don’t know how to create a Range object from a given offset when the editable content div contains several HTML nodes, because the browser likes to create several nodes when you put a line break in the middle of a word and delete it immediately (as a side question, this is normal, anyway, is there a memory leak?). Then it looks like this on the Chrome console (# cell-input has 4 nodes here, although it just contains the continuous line "Marek"):

<div contenteditable="true" id="cell-input">
    "M"
    "ar"
    "ek"
    <br>
</div>

I tried using something like (this is just pseudo code):

offset = shadowRoot.getSelection().extentOffset;
element = document.querySelector('cell-input');

range = document.createRange();
range.setStart(element.children.first, offset );
range.setEnd(element.children.first, offset);
range.collapse(false);

... but that didn't work. Any ideas?

+4
source share
2 answers

, .

+3

, , shadowRoot , . , this.shadowRoot.getSelection(). GetRangeAt (0) , this.shadowRoot.getSelection() getSelection(). SetStart, getSelection(). SetEnd. . plunk

shadowRoot.getSelection.getRangeAt(0) instead use  
var selRange=document.createRange();
var shadowRootSelection = this.shadowRoot.getSelection();
selRange.setStart(shadowRootSelection.anchorNode, shadowRootSelection.anchorOffset);
        selRange.setEnd(shadowRootSelection.focusNode, shadowRootSelection.focusOffset);
0

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


All Articles