Skip to content

Instantly share code, notes, and snippets.

@HomerJSimpson
Created September 13, 2017 17:40
Show Gist options
  • Save HomerJSimpson/5c290bc0fa05c72855fc46208c371c25 to your computer and use it in GitHub Desktop.
Save HomerJSimpson/5c290bc0fa05c72855fc46208c371c25 to your computer and use it in GitHub Desktop.
Add span to textnodes so can highlight on pdf text layer
function wrapText(container, text) {
// Construct a regular expression that matches text at the start or end of a string or surrounded by non-word characters.
// Escape any special regex characters in text.
var textRE = new RegExp('(^|\\W)' + text.replace(/[\\^$*+.?[\]{}()|]/, '\\$&') + '($|\\W)', 'm');
var nodeText;
var nodeStack = [];
// Remove empty text nodes and combine adjacent text nodes.
container.normalize();
// Iterate through the container's child elements, looking for text nodes.
var curNode = container.firstChild;
while (curNode != null) {
if (curNode.nodeType == Node.TEXT_NODE) {
// Get node text in a cross-browser compatible fashion.
if (typeof curNode.textContent == 'string')
nodeText = curNode.textContent;
else
nodeText = curNode.innerText;
// Use a regular expression to check if this text node contains the target text.
var match = textRE.exec(nodeText);
if (match != null) {
// Create a document fragment to hold the new nodes.
var fragment = document.createDocumentFragment();
// Create a new text node for any preceding text.
if (match.index > 0)
fragment.appendChild(document.createTextNode(match.input.substr(0, match.index)));
// Create the wrapper span and add the matched text to it.
var spanNode = document.createElement('span');
spanNode.className = 'highlighted';
spanNode.appendChild(document.createTextNode(match[0]));
fragment.appendChild(spanNode);
// Create a new text node for any following text.
if (match.index + match[0].length < match.input.length)
fragment.appendChild(document.createTextNode(match.input.substr(match.index + match[0].length)));
// Replace the existing text node with the fragment.
curNode.parentNode.replaceChild(fragment, curNode);
curNode = spanNode;
}
} else if (curNode.nodeType == Node.ELEMENT_NODE && curNode.firstChild != null) {
nodeStack.push(curNode);
curNode = curNode.firstChild;
// Skip the normal node advancement code.
continue;
}
// If there's no more siblings at this level, pop back up the stack until we find one.
while (curNode != null && curNode.nextSibling == null)
curNode = nodeStack.pop();
// If curNode is null, that means we've completed our scan of the DOM tree.
// If not, we need to advance to the next sibling.
if (curNode != null)
curNode = curNode.nextSibling;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment