Permalink
Browse files

Add highlight behavior

  • Loading branch information...
1 parent 73b3bcf commit 694fc32d128f6ef1ac325d12d5c22c585583dda3 @mbabker mbabker committed with realityking Sep 18, 2011
Showing with 137 additions and 0 deletions.
  1. +26 −0 libraries/joomla/html/html/string.php
  2. +106 −0 media/system/js/highlighter-uncompressed.js
  3. +5 −0 media/system/js/highlighter.js
@@ -151,4 +151,30 @@ public static function abridge($text, $length = 50, $intro = 30)
return $text;
}
+
+ /**
+ * Method to setup the JavaScript highlight behavior.
+ *
+ * @param array $terms An array of terms to highlight.
+ *
+ * @return void
+ *
+ * @since 11.4
+ */
+ public static function highlighter($terms)
+ {
+ // Get the document object.
+ $doc = JFactory::getDocument();
+
+ // We only want to highlight text on regular html pages.
+ if ($doc->getType() == 'html' && JFactory::getApplication()->input->get('tmpl', null, 'cmd') !== 'component')
+ {
+ // Add the highlighter media.
+ $uncompressed = JFactory::getConfig()->get('debug') ? '-uncompressed' : '';
+ JHtml::_('script', 'system/highlighter' . $uncompressed . '.js', true, true);
+
+ // Add the terms to highlight.
+ $doc->addScriptDeclaration("window.highlight = [\"" . implode('","', $terms) . "\"];");
+ }
+ }
}
@@ -0,0 +1,106 @@
+/**
+ * @package Joomla.JavaScript
+ * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+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('highlight-start');
+ var end = document.id('highlight-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();
+});

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

0 comments on commit 694fc32

Please sign in to comment.