/* * jquery highlight plugin * * based on highlight v3 by johann burkard * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html * * code a little bit refactored and cleaned (in my humble opinion). * most important changes: * - has an option to highlight only entire words (wordsonly - false by default), * - has an option to be case sensitive (casesensitive - false by default) * - highlight element tag and class names can be specified in options * * usage: * // wrap every occurrance of text 'lorem' in content * // with (default options) * $('#content').highlight('lorem'); * * // search for and highlight more terms at once * // so you can save some time on traversing dom * $('#content').highlight(['lorem', 'ipsum']); * $('#content').highlight('lorem ipsum'); * * // search only for entire word 'lorem' * $('#content').highlight('lorem', { wordsonly: true }); * * // don't ignore case during search of term 'lorem' * $('#content').highlight('lorem', { casesensitive: true }); * * // wrap every occurrance of term 'ipsum' in content * // with * $('#content').highlight('ipsum', { element: 'em', classname: 'important' }); * * // remove default highlight * $('#content').unhighlight(); * * // remove custom highlight * $('#content').unhighlight({ element: 'em', classname: 'important' }); * * * copyright (c) 2009 bartek szopka * * licensed under mit license. * */ jquery.extend({ highlight: function (node, re, nodename, classname) { if (node.nodetype === 3) { var match = node.data.match(re); if (match) { var highlight = document.createelement(nodename || 'span'); highlight.classname = classname || 'highlight'; var wordnode = node.splittext(match.index); wordnode.splittext(match[0].length); var wordclone = wordnode.clonenode(true); highlight.appendchild(wordclone); wordnode.parentnode.replacechild(highlight, wordnode); return 1; //skip added node in parent } } else if ((node.nodetype === 1 && node.childnodes) && // only element nodes that have children !/(script|style)/i.test(node.tagname) && // ignore script and style nodes !(node.tagname === nodename.touppercase() && node.classname === classname)) { // skip if already highlighted for (var i = 0; i < node.childnodes.length; i++) { i += jquery.highlight(node.childnodes[i], re, nodename, classname); } } return 0; } }); jquery.fn.unhighlight = function (options) { var settings = { classname: 'highlight', element: 'span' }; jquery.extend(settings, options); return this.find(settings.element + "." + settings.classname).each(function () { var parent = this.parentnode; parent.replacechild(this.firstchild, this); parent.normalize(); }).end(); }; jquery.fn.highlight = function (words, options) { var settings = { classname: 'highlight', element: 'span', casesensitive: false, wordsonly: false }; jquery.extend(settings, options); if (words.constructor === string) { words = [words]; } words = jquery.grep(words, function(word, i){ return word != ''; }); words = jquery.map(words, function(word, i) { return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); }); if (words.length == 0) { return this; }; var flag = settings.casesensitive ? "" : "i"; var pattern = "(" + words.join("|") + ")"; if (settings.wordsonly) { pattern = "\\b" + pattern + "\\b"; } var re = new regexp(pattern, flag); return this.each(function () { jquery.highlight(this, re, settings.element, settings.classname); }); };