in asdoc/library/closure/goog/dom/annotate.js [238:339]
goog.dom.annotate.helpAnnotateText_ = function(
text, terms, annotateFn, ignoreCase) {
var hit = false;
var textToSearch = ignoreCase ? text.toLowerCase() : text;
var textLen = textToSearch.length;
var numTerms = terms.length;
// Each element will be an array of hit positions for the term.
var termHits = new Array(numTerms);
// First collect all the hits into allHits.
for (var i = 0; i < numTerms; i++) {
var term = terms[i];
var hits = [];
var termText = term[0];
if (termText != '') {
var matchWholeWordOnly = term[1];
var termLen = termText.length;
var pos = 0;
// Find each hit for term t and append to termHits.
while (pos < textLen) {
var hitPos = textToSearch.indexOf(termText, pos);
if (hitPos == -1) {
break;
} else {
var prevCharPos = hitPos - 1;
var nextCharPos = hitPos + termLen;
if (!matchWholeWordOnly ||
((prevCharPos < 0 ||
goog.dom.annotate.NONWORD_RE_.test(
textToSearch.charAt(prevCharPos))) &&
(nextCharPos >= textLen ||
goog.dom.annotate.NONWORD_RE_.test(
textToSearch.charAt(nextCharPos))))) {
hits.push(hitPos);
hit = true;
}
pos = hitPos + termLen;
}
}
}
termHits[i] = hits;
}
if (hit) {
var html = [];
var pos = 0;
while (true) {
// First determine which of the n terms is the next hit.
var termIndexOfNextHit;
var posOfNextHit = -1;
for (var i = 0; i < numTerms; i++) {
var hits = termHits[i];
// pull off the position of the next hit of term t
// (it's always the first in the array because we're shifting
// hits off the front of the array as we process them)
// this is the next candidate to consider for the next overall hit
if (!goog.array.isEmpty(hits)) {
var hitPos = hits[0];
// Discard any hits embedded in the previous hit.
while (hitPos >= 0 && hitPos < pos) {
hits.shift();
hitPos = goog.array.isEmpty(hits) ? -1 : hits[0];
}
if (hitPos >= 0 && (posOfNextHit < 0 || hitPos < posOfNextHit)) {
termIndexOfNextHit = i;
posOfNextHit = hitPos;
}
}
}
// Quit if there are no more hits.
if (posOfNextHit < 0) break;
goog.asserts.assertNumber(termIndexOfNextHit);
// Remove the next hit from our hit list.
termHits[termIndexOfNextHit].shift();
// Append everything from the end of the last hit up to this one.
html.push(text.substr(pos, posOfNextHit - pos));
// Append the annotated term.
var termLen = terms[termIndexOfNextHit][0].length;
var termHtml =
goog.html.SafeHtml.htmlEscape(text.substr(posOfNextHit, termLen));
html.push(
annotateFn(goog.asserts.assertNumber(termIndexOfNextHit), termHtml));
pos = posOfNextHit + termLen;
}
// Append everything after the last hit.
html.push(text.substr(pos));
return goog.html.SafeHtml.concat(html);
} else {
return null;
}
};