Skip to content

Instantly share code, notes, and snippets.

@gariknyazev
Created July 16, 2018 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gariknyazev/37b5095dc523fb6487c0086a3f0421c4 to your computer and use it in GitHub Desktop.
Save gariknyazev/37b5095dc523fb6487c0086a3f0421c4 to your computer and use it in GitHub Desktop.
Visit all Text nodes in Range (JavaScript)
//Range definition https://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
function visitTextNodesInRange(range, visitor) {
var reachedStartNode = false, reachedEndNode = false,
startContainer = range.startContainer, endContainer = range.endContainer,
startOffset = range.startOffset, endOffset = range.endOffset;
var visitNode = function (node, visitor) {
var isTextNode = node.nodeType === Node.TEXT_NODE;
if (isTextNode) {
if (node === startContainer && node === endContainer) {
visitor(node, startOffset, endOffset);
} else if (node === startContainer) {
visitor(node, startOffset, node.nodeValue.length);
} else if (node === endContainer) {
visitor(node, 0, endOffset);
} else if (reachedStartNode) {
visitor(node, 0, node.nodeValue.length);
}
}
var startIndex = node === startContainer && !isTextNode ? startOffset : 0;
var endIndex = node === endContainer && !isTextNode ? endOffset : node.childNodes.length;
reachedStartNode = reachedStartNode || node === startContainer;
for (var i = startIndex; !reachedEndNode && i < endIndex; ++i) {
visitNode(node.childNodes[i], visitor);
}
reachedEndNode = reachedEndNode || node === endContainer;
};
visitNode(range.commonAncestorContainer, visitor);
}
//Example usage: mask selected text with some placeholder
function maskSelectedText() {
var visitor = function(textNode, startOffset, endOffset) {
var value = textNode.nodeValue;
var result = value.substring(0, startOffset);
result += value.substring(startOffset, endOffset).replace(/[^\x00-\x7F]|\w/gim, '*');
result += value.substring(endOffset);
textNode.nodeValue = result;
};
if(window.getSelection && window.getSelection().rangeCount) {
visitTextNodesInRange(window.getSelection().getRangeAt(0), visitor);
window.getSelection().removeAllRanges();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment