function markText(node, expr, classes) {

		/* Names of Element nodes whose children must not be visited */
		var rtags = /object|embed|script|select|textarea/i;

		function replace(node) {
			var text = node.nodeValue,
				p = node.parentNode,
				start = 0,
				match,span;

			while ( (match = expr.exec(text)) != null ) {

				// add a new text node with the string before the match
				if ( start < match.index ) {
					p.insertBefore(document.createTextNode(text.slice(start, match.index)), node);
				}

				// add a span for the match
				span = document.createElement("span");
				span.appendChild(document.createTextNode(match[0]));
				span.className = classes[match[0].toLowerCase()];
				p.insertBefore(span, node);

				// robustness: should a non-empty search term result in an empty match, then exit the loop
				if ( start <= expr.lastindex ) {
					break;
				}

				// continue search after current match
				start = expr.lastIndex;
			}

			// if there was any match, then reduce the text of original text node
			// to the substring after the last match (might be empty)
			if ( start > 0 ) {
				node.nodeValue = text.slice(start);
			}
		}

		function visit(node) {
			if (node.nodeType == 3) { // Node.TEXT_NODE
				replace(node);
			} else if ( !rtags.test(node.nodeName) ) { // skip 'critical' nodes
				for (node = node.firstChild; node; node = node.nextSibling) {
					visit(node);
				}
			}
		}

		visit(node);
	}
function markText(node, expr, classes) {

		/* Names of Element nodes whose children must not be visited */
		var rtags = /object|embed|script|select|textarea/i;

		function replace(node) {
			var text = node.nodeValue,
				p = node.parentNode,
				start = 0,
				match,span;

			while ( (match = expr.exec(text)) != null ) {

				// add a new text node with the string before the match
				if ( start < match.index ) {
					p.insertBefore(document.createTextNode(text.slice(start, match.index)), node);
				}

				// add a span for the match
				span = document.createElement("span");
				span.appendChild(document.createTextNode(match[0]));
				span.className = classes[match[0].toLowerCase()];
				p.insertBefore(span, node);

				// robustness: should a non-empty search term result in an empty match, then exit the loop
				if ( start <= expr.lastindex ) {
					break;
				}

				// continue search after current match
				start = expr.lastIndex;
			}

			// if there was any match, then reduce the text of original text node
			// to the substring after the last match (might be empty)
			if ( start > 0 ) {
				node.nodeValue = text.slice(start);
			}
		}

		function visit(node) {
			if (node.nodeType == 3) { // Node.TEXT_NODE
				replace(node);
			} else if ( !rtags.test(node.nodeName) ) { // skip 'critical' nodes
				for (node = node.firstChild; node; node = node.nextSibling) {
					visit(node);
				}
			}
		}

		visit(node);
	}
function markText ( node , expr , classes ) { /* Names of Element nodes whose children must not be visited */ var rtags = / object|embed|script|select|textarea / i ; function replace ( node ) { var text = node . nodeValue , p = node . parentNode , start = 0 , match , span ; while ( ( match = expr . exec ( text ) ) != null ) { // add a new text node with the string before the match if ( start < match . index ) { p . insertBefore ( document . createTextNode ( text . slice ( start , match . index ) ) , node ) ; } // add a span for the match span = document . createElement ( "span" ) ; span . appendChild ( document . createTextNode ( match [ 0 ] ) ) ; span . className = classes [ match [ 0 ] . toLowerCase ( ) ] ; p . insertBefore ( span , node ) ; // robustness: should a non-empty search term result in an empty match, then exit the loop if ( start <= expr . lastindex ) { break ; } // continue search after current match start = expr . lastIndex ; } // if there was any match, then reduce the text of original text node // to the substring after the last match (might be empty) if ( start > 0 ) { node . nodeValue = text . slice ( start ) ; } } function visit ( node ) { if ( node . nodeType == 3 ) { // Node.TEXT_NODE replace ( node ) ; } else if ( ! rtags . test ( node . nodeName ) ) { // skip 'critical' nodes for ( node = node . firstChild ; node ; node = node . nextSibling ) { visit ( node ) ; } } } visit ( node ) ; }
/*
Loops over all text nodes in the given subtree and searches for text fragments
that match the given RegExp. Each match is wrapped in its own span and the
span is given the class corresponding to the match.
/ * Loops over all text nodes in the given subtree and searches for text fragments that match the given RegExp . Each match is wrapped in its own span and the span is given the class corresponding to the match .
Mark text nodes