/media/com_finder/js/highlighter.js

https://bitbucket.org/eternaware/joomus · JavaScript · 100 lines · 100 code · 0 blank · 0 comment · 20 complexity · 4d9f99ad1bf0e5ef032d5c70aeb57657 MD5 · raw file

  1. var Highlighter = new Class({
  2. options: {
  3. autoUnhighlight: true,
  4. caseSensitive: false,
  5. startElement: false,
  6. endElement: false,
  7. elements: new Array(),
  8. className: 'highlight',
  9. onlyWords: true,
  10. tag: 'span'
  11. },
  12. initialize: function (options) {
  13. this.setOptions(options);
  14. this.getElements(this.options.startElement, this.options.endElement);
  15. this.words = [];
  16. },
  17. highlight: function (words) {
  18. if (words.constructor === String) {
  19. words = [words];
  20. }
  21. if (this.options.autoUnhighlight) {
  22. this.unhighlight(words);
  23. }
  24. var pattern = this.options.onlyWords ? '\b' + pattern + '\b' : '(' + words.join('\\b|\\b') + ')';
  25. var regex = new RegExp(pattern, this.options.caseSensitive ? '' : 'i');
  26. this.options.elements.each(function (el) {
  27. this.recurse(el, regex, this.options.className);
  28. }, this);
  29. return this;
  30. },
  31. unhighlight: function (words) {
  32. if (words.constructor === String) {
  33. words = [words];
  34. }
  35. words.each(function (word) {
  36. word = (this.options.caseSensitive ? word : word.toUpperCase());
  37. if (this.words[word]) {
  38. var elements = $$(this.words[word]);
  39. elements.setProperty('class', '');
  40. elements.each(function (el) {
  41. var tn = document.createTextNode(el.getText());
  42. el.getParent().replaceChild(tn, el);
  43. });
  44. }
  45. }, this);
  46. return this;
  47. },
  48. recurse: function (node, regex, klass) {
  49. if (node.nodeType === 3) {
  50. var match = node.data.match(regex);
  51. if (match) {
  52. var highlight = new Element(this.options.tag);
  53. highlight.addClass(klass);
  54. var wordNode = node.splitText(match.index);
  55. wordNode.splitText(match[0].length);
  56. var wordClone = wordNode.cloneNode(true);
  57. highlight.appendChild(wordClone);
  58. wordNode.parentNode.replaceChild(highlight, wordNode);
  59. highlight.setProperty('rel', highlight.get('text'));
  60. var comparer = highlight.get('text');
  61. if (!this.options.caseSensitive) {
  62. comparer = highlight.get('text').toUpperCase();
  63. }
  64. if (!this.words[comparer]) {
  65. this.words[comparer] = [];
  66. }
  67. this.words[comparer].push(highlight);
  68. return 1;
  69. }
  70. } else if ((node.nodeType === 1 && node.childNodes) && !/(script|style|textarea|iframe)/i.test(node.tagName) && !(node.tagName === this.options.tag.toUpperCase() && node.className === klass)) {
  71. for (var i = 0; i < node.childNodes.length; i++) {
  72. i += this.recurse(node.childNodes[i], regex, klass);
  73. }
  74. }
  75. return 0;
  76. },
  77. getElements: function (start, end) {
  78. var next = start.getNext();
  79. if (next.id != end.id) {
  80. this.options.elements.include(next);
  81. this.getElements(next, end);
  82. }
  83. }
  84. });
  85. Highlighter.implement(new Options);
  86. window.addEvent('domready', function () {
  87. var start = document.id('highlighter-start');
  88. var end = document.id('highlighter-end');
  89. if (!start || !end || !window.highlight) {
  90. return true;
  91. }
  92. highlighter = new Highlighter({
  93. startElement: start,
  94. endElement: end,
  95. autoUnhighlight: true,
  96. onlyWords: false
  97. }).highlight(window.highlight);
  98. start.dispose();
  99. end.dispose();
  100. });