I want to mirror the text selection in a contenteditable div in one browser in another browser. The simplified and relevant section of the code is:
In the source browser:
function someFunc() {
if (window.getSelection().isCollapsed)
return;
var range = window.getSelection().getRangeAt(0);
//Send range over websockets to another browser
sendToAnotherBrowser(...) //Send range
}
In the remote browser, I execute the following code:
var sel = window.getSelection();
sel.addRange(range); //Where range is the range transmitted over webSockets
I get the following error:
"Failed to execute 'addRange' on 'Selection': parameter 1 is not of type 'Range'
QUESTION: How to transmit the "Range" object over websockets? It is not a JSON object to be stringified and sent. Can I serialize it somehow, change it to base64 and then reverse the process on the receiving end?
You can't serialize the object itself, buy you can create an object that contains the data of the Range
object, send it to the socket and build a new Range
object from there.
const sendRange = range => {
const {
startContainer,
endContainer,
startOffset,
endOffset,
collapsed
} = range;
const package = JSON.stringify({
startNodeId: startContainer.id,
endNodeId: endContainer.id,
startOffset,
endOffset
collapsed
});
sendToAnotherBrowser(package);
}
const range = window.getSelection().getRangeAt(0);
sendRange(range);
And receive it somewhere else where you build a new object.
const buildRange = package => {
const {
startNodeId,
endNodeId,
startOffset,
endOffset,
collapsed
} = JSON.parse(package);
const selection = window.getSelection();
const range = document.createRange();
const startNode = document.getElementById(startNodeId);
const endNode = document.getElementById(endNodeId);
range.setStart(startNode, startOffset);
range.setEnd(endNode, endOffset);
if (collapsed) {
range.collapse();
}
selection.addRange(range);
}