joomla_test/media/com_finder/js/highlighter.js

100 lines
2.9 KiB
JavaScript
Raw Permalink Normal View History

2020-01-02 22:20:31 +07:00
var Highlighter = new Class({
options: {
autoUnhighlight: true,
caseSensitive: false,
startElement: false,
endElement: false,
elements: new Array(),
className: 'highlight',
onlyWords: true,
tag: 'span'
},
initialize: function (options) {
this.setOptions(options);
this.getElements(this.options.startElement, this.options.endElement);
this.words = [];
},
highlight: function (words) {
if (words.constructor === String) {
words = [words];
}
if (this.options.autoUnhighlight) {
this.unhighlight(words);
}
var pattern = this.options.onlyWords ? '\b' + pattern + '\b' : '(' + words.join('\\b|\\b') + ')';
var regex = new RegExp(pattern, this.options.caseSensitive ? '' : 'i');
this.options.elements.each(function (el) {
this.recurse(el, regex, this.options.className);
}, this);
return this;
},
unhighlight: function (words) {
if (words.constructor === String) {
words = [words];
}
words.each(function (word) {
word = (this.options.caseSensitive ? word : word.toUpperCase());
if (this.words[word]) {
var elements = $$(this.words[word]);
elements.setProperty('class', '');
elements.each(function (el) {
var tn = document.createTextNode(el.getText());
el.getParent().replaceChild(tn, el);
});
}
}, this);
return this;
},
recurse: function (node, regex, klass) {
if (node.nodeType === 3) {
var match = node.data.match(regex);
if (match) {
var highlight = new Element(this.options.tag);
highlight.addClass(klass);
var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
highlight.setProperty('rel', highlight.get('text'));
var comparer = highlight.get('text');
if (!this.options.caseSensitive) {
comparer = highlight.get('text').toUpperCase();
}
if (!this.words[comparer]) {
this.words[comparer] = [];
}
this.words[comparer].push(highlight);
return 1;
}
} else if ((node.nodeType === 1 && node.childNodes) && !/(script|style|textarea|iframe)/i.test(node.tagName) && !(node.tagName === this.options.tag.toUpperCase() && node.className === klass)) {
for (var i = 0; i < node.childNodes.length; i++) {
i += this.recurse(node.childNodes[i], regex, klass);
}
}
return 0;
},
getElements: function (start, end) {
var next = start.getNext();
if (next.id != end.id) {
this.options.elements.include(next);
this.getElements(next, end);
}
}
});
Highlighter.implement(new Options);
window.addEvent('domready', function () {
var start = document.id('highlighter-start');
var end = document.id('highlighter-end');
if (!start || !end || !window.highlight) {
return true;
}
highlighter = new Highlighter({
startElement: start,
endElement: end,
autoUnhighlight: true,
onlyWords: false
}).highlight(window.highlight);
start.dispose();
end.dispose();
});