102 lines
2.9 KiB
JavaScript
102 lines
2.9 KiB
JavaScript
/**
|
|
* @package Joomla.JavaScript
|
|
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
|
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
|
*/
|
|
|
|
// Only define the Joomla namespace if not defined.
|
|
if (typeof(Joomla) === 'undefined') {
|
|
var Joomla = {};
|
|
}
|
|
|
|
Joomla.Highlighter = new Class({
|
|
Implements: Options,
|
|
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);
|
|
}
|
|
}
|
|
});
|