Range object with JSON

I am writing a Chrome extension, and I need to pass the value that the user selected on the website for my server. I am using window.getSelection () code that returns a range object. I use JSON to pass the range object back to my server, but it does not work. I am new to this, but I think the problem is that you can only pass text using JSON, and the range object includes both the DOM structure (which is not text) and the actual selection of text (which is text ), I'm right? Is there an alternative?

var selection = window.getSelection(); $.getJSON(url, {data:selection}, function(moot) { alert("done"); }); 
+4
source share
3 answers

A simple workaround is not to serialize and send the entire select object, but to save the start and end points as XPath (along with their offsets). Something like that:

 function makeXPath (node, currentPath) { /* this should suffice in HTML documents for selectable nodes, XML with namespaces needs more code */ currentPath = currentPath || ''; switch (node.nodeType) { case 3: case 4: return makeXPath(node.parentNode, 'text()[' + (document.evaluate('preceding-sibling::text()', node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength + 1) + ']'); case 1: return makeXPath(node.parentNode, node.nodeName + '[' + (document.evaluate('preceding-sibling::' + node.nodeName, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength + 1) + ']' + (currentPath ? '/' + currentPath : '')); case 9: return '/' + currentPath; default: return ''; } } function restoreSelection () { var selection = window.getSelection(); selection.removeAllRanges(); var range = document.createRange(); range.setStart(document.evaluate(selectionDetails[0], document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue, Number(selectionDetails[1])); range.setEnd(document.evaluate(selectionDetails[2], document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue, Number(selectionDetails[3])); selection.addRange(range); } } function getSelection() { var selection = window.getSelection(); var range = selection.getRangeAt(0); var selectObj = { 'startXPath': makeXPath(range.startContainer), 'startOffset': range.startOffset, 'endXPath': makeXPath(range.endContainer), 'endOffset': range.endOffset } return selectObj } 

Not fully verified, but the general idea is here.

Sources: This and That

+4
source

Have you tried window.getSelection().toString() ? This should only get the text value in itself.

MDN is currently unavailable, but you can check the DOMSelection documentation there: https://developer.mozilla.org/En/DOM/Selection

EDIT

You can also try using the anchorNode and focusNode properties to capture the nodes where the selection starts and stops. If you really need raw html, you can do something like focusNode.parentNode.outerHTML to get the whole block (it looks like you cannot do outerHTML on focus or anchorNodes directly).

t

 var selection = window.getSelection(); var payload = { selectedText: selection.toString(), startHTML: selection.anchorNode.parentNode.outerHTML, endHTML: selection.focusNode.parentNode.outerHTML } 

and then analyze it from the other side. You can also clear other information from nodes so that you don’t have to transmit entire html lines for posting.

0
source

If you need to submit a user selection on your page

 var selection = window.getSelection(); for(i=0;i<selection.rangeCount;i++) a[i]=selection.getRangeAt(i); $.getJSON(url, {data:a.toString()}, function(moot) { alert("done"); }); 

Note: instead of toString() you can use join('<separator>') also based on your needs

Using window.getSelection().toString() would combine all selections without a separator

0
source

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


All Articles