/* ======== JQUEY CARET =========== */ (function($) { $.fn.caret = function(pos) { var target = this[0]; var isContentEditable = target.contentEditable === "true"; //get if (arguments.length == 0) { //HTML5 if (window.getSelection) { //contenteditable if (isContentEditable) { target.focus(); var range1 = window.getSelection().getRangeAt(0), range2 = range1.cloneRange(); range2.selectNodeContents(target); range2.setEnd(range1.endContainer, range1.endOffset); return range2.toString().length; } //textarea return target.selectionStart; } //IE<9 if (document.selection) { target.focus(); //contenteditable if (isContentEditable) { var range1 = document.selection.createRange(), range2 = document.body.createTextRange(); range2.moveToElementText(target); range2.setEndPoint("EndToEnd", range1); return range2.text.length; } //textarea var pos = 0, range = target.createTextRange(), range2 = document.selection.createRange().duplicate(), bookmark = range2.getBookmark(); range.moveToBookmark(bookmark); while (range.moveStart("character", -1) !== 0) pos++; return pos; } //not supported return 0; } //set if (pos == -1) pos = this[isContentEditable ? "text" : "val"]().length; //HTML5 if (window.getSelection) { //contenteditable if (isContentEditable) { target.focus(); window.getSelection().collapse(target.firstChild, pos); } else //textarea target.setSelectionRange(pos, pos); } else if (document.body.createTextRange) { //IE<9 var range = document.body.createTextRange(); range.moveToElementText(target); range.moveStart("character", pos); range.collapse(true); range.select(); } if (!isContentEditable) target.focus(); return pos; }; })(jQuery); /* ========= TEXTAREA HELPER =============== */ (function($) { "use strict"; var caretClass = "textarea-helper-caret", dataKey = "textarea-helper", // Styles that could influence size of the mirrored element. mirrorStyles = [ // Box Styles. "box-sizing", "height", "width", "padding-bottom", "padding-left", "padding-right", "padding-top", // Font stuff. "font-family", "font-size", "font-style", "font-variant", "font-weight", // Spacing etc. "word-spacing", "letter-spacing", "line-height", "text-decoration", "text-indent", "text-transform", // The direction. "direction" ]; var TextareaHelper = function(elem) { if (elem.nodeName.toLowerCase() !== "textarea") return; this.$text = $(elem); this.$mirror = $("
") .css({ position: "absolute", overflow: "auto", "white-space": "pre-wrap", "word-wrap": "break-word", top: 0, left: -9999 }) .insertAfter(this.$text); }; (function() { this.update = function() { // Copy styles. var styles = {}; for (var i = 0, style; (style = mirrorStyles[i]); i++) { styles[style] = this.$text.css(style); } this.$mirror.css(styles).empty(); // Update content and insert caret. var caretPos = this.getOriginalCaretPos(), str = this.$text.val(), pre = document.createTextNode(str.substring(0, caretPos)), post = document.createTextNode(str.substring(caretPos)), $car = $("") .addClass(caretClass) .css("position", "absolute") .html(" "); this.$mirror.append(pre, $car, post).scrollTop(this.$text.scrollTop()); }; this.destroy = function() { this.$mirror.remove(); this.$text.removeData(dataKey); return null; }; this.caretPos = function() { this.update(); var $caret = this.$mirror.find("." + caretClass), pos = $caret.position(); if (this.$text.css("direction") === "rtl") { pos.right = this.$mirror.innerWidth() - pos.left - $caret.width(); pos.left = "auto"; } return pos; }; this.height = function() { this.update(); this.$mirror.css("height", ""); return this.$mirror.height(); }; // XBrowser caret position // Adapted from http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea this.getOriginalCaretPos = function() { var text = this.$text[0]; if (text.selectionStart) { return text.selectionStart; } else if (document.selection) { text.focus(); var r = document.selection.createRange(); if (r == null) { return 0; } var re = text.createTextRange(), rc = re.duplicate(); re.moveToBookmark(r.getBookmark()); rc.setEndPoint("EndToStart", re); return rc.text.length; } return 0; }; }.call(TextareaHelper.prototype)); $.fn.textareaHelper = function(method) { this.each(function() { var $this = $(this), instance = $this.data(dataKey); if (!instance) { instance = new TextareaHelper(this); $this.data(dataKey, instance); } }); if (method) { var instance = this.first().data(dataKey); return instance[method](); } else { return this; } }; })(jQuery); /* ========= JQURY ALERTS ================= */ (function($) { $.jPopup = function(message, errorLevel, callback, options, buttons) { var defaults = { message: message, errorLevel: errorLevel, wrapperClass: "jpopup", show: "drop", minHeight: 5 }; options = $.extend(defaults, options); var dialogCSS = "ui-state-error"; var iconCSS = " ui-icon-alert"; switch (options.errorLevel) { case "highlight": dialogCSS = " ui-state-highlight"; iconCSS = " ui-icon-notice"; break; case "error": dialogCSS = " ui-state-error"; iconCSS = " ui-icon-alert"; break; default: dialogCSS = ""; iconCSS = " ui-icon-info"; break; } var dialog = $( '
' + options.message + "
" ); var dialogOptions = { bgiframe: true, dialogClass: options.wrapperClass + dialogCSS, resizable: false, minHeight: options.minHeight, modal: true, buttons: buttons, close: function(event, ui) { dialog.remove(); if (callback) callback(false); } }; options = $.extend(dialogOptions, options); dialog.dialog(options); }; $.jConfirm = function(message, errorLevel, callback, options) { var buttons = { Ok: function() { $(this).dialog("close"); if (callback) { callback(true); } }, Cancel: function() { $(this).dialog("close"); if (callback) { callback(false); } } }; $.jPopup(message, errorLevel, callback, options, buttons); }; $.jAlert = function(message, errorLevel, callback, options) { var buttons = { Ok: function() { $(this).dialog("close"); if (callback) { callback(true); } } }; $.jPopup(message, errorLevel, callback, options, buttons); }; })(jQuery); /* === THEME SWITCHER TOOL ====== */ /* jQuery plugin themeswitcher based on http://blog.rbe.homeip.net/posts/jquery-themeswitcher ---------------------------------------------------------------------*/ var baseUrl = baseUrl || "/"; if (!baseUrl.match(/\/$/)) { baseUrl = baseUrl + "/"; } $.fn.themeswitcher = function(settings) { var options = jQuery.extend( { loadTheme: "cupertino", initialText: "Switch Theme", width: 180, height: 400, buttonPreText: "Theme: ", closeOnSelect: true, buttonHeight: 14, cookieName: "jquery-ui-theme", onOpen: function() {}, onClose: function() {}, onSelect: function() {}, useStandard: true, cssPrefix: "//code.jquery.com/ui/1.12.1/themes/", cssSuffix: "/jquery-ui.css", imgPrefix: baseUrl + "images/Themeroller/theme_90_", imgSuffix: ".png", imageLocation: baseUrl + "images/Themeroller/", themes: {}, useCookie: true }, settings ); if (options.useStandard) $.extend(options.themes, { base: { icon: options.imageLocation + "base.png" }, "black-tie": {}, blitzer: {}, cupertino: {}, "dark-hive": {}, "dot-luv": {}, eggplant: {}, "excite-bike": {}, flick: {}, "hot-sneaks": {}, humanity: {}, "le-frog": {}, "mint-choc": {}, overcast: {}, "pepper-grinder": {}, redmond: {}, smoothness: {}, "south-street": {}, start: {}, sunny: {}, "swanky-purse": {}, trontastic: {}, "ui-darkness": {}, "ui-lightness": {} }); var theme_ul = ""; for (var i in options.themes) { css = options.themes[i].css || options.cssPrefix + i + options.cssSuffix; img = options.themes[i].icon || options.imgPrefix + i.replace("-", "_") + options.imgSuffix; theme_ul += "
  • " +
      img +
      "" + i + "
  • "; } theme_ul = "
      " + theme_ul + "
    "; //markup var button = $( '
    ' + options.initialText + "" ); var switcherpane = $( '
    ' + theme_ul + "
    " ) .find("div") .removeAttr("id"); //button events button.click(function() { if (switcherpane.is(":visible")) switcherpane.spHide(); else switcherpane.spShow(); return false; }); //menu events (mouseout didn't work...) switcherpane.hover( function() {}, function() { if (switcherpane.is(":visible")) { $(this).spHide(); } } ); //show/hide panel functions $.fn.spShow = function() { $(this) .css({ top: button.offset().top + options.buttonHeight + 6, left: button.offset().left }) .slideDown(50); button.css(button_active); options.onOpen(); }; $.fn.spHide = function() { $(this).slideUp(50, function() { options.onClose(); }); button.css(button_default); }; /* Theme Loading ---------------------------------------------------------------------*/ switcherpane.find("a").click(function() { updateCSS($(this).attr("href")); var themeName = $(this) .find("span") .text(); button .find(".jquery-ui-themeswitcher-title") .text(options.buttonPreText + themeName); if (options.useCookie) $.cookie(options.cookieName, themeName, { path: "/" }); options.onSelect(); if (options.closeOnSelect && switcherpane.is(":visible")) { switcherpane.spHide(); } return false; }); //function to rewrite stylesheet link. // if there is not onewith an id='ui-theme', append to function updateCSS(locStr) { if ($("head link#ui-theme").length == 0) $("head").append( $('') ); $("head link#ui-theme").attr("href", locStr); } /* Inline CSS ---------------------------------------------------------------------*/ var button_default = { fontFamily: "Trebuchet MS, Verdana, sans-serif", fontSize: "11px", color: "#666", background: "#eee url(" + options.imageLocation + "buttonbg.png) 50% 50% repeat-x", border: "1px solid #ccc", "-moz-border-radius": "6px", "-webkit-border-radius": "6px", textDecoration: "none", padding: "3px 3px 3px 8px", width: options.width - 11, //minus must match left and right padding display: "block", height: options.buttonHeight, outline: "0" }; var button_hover = { borderColor: "#bbb", background: "#f0f0f0", cursor: "pointer", color: "#444" }; var button_active = { color: "#aaa", background: "#000", border: "1px solid #ccc", borderBottom: 0, "-moz-border-radius-bottomleft": 0, "-webkit-border-bottom-left-radius": 0, "-moz-border-radius-bottomright": 0, "-webkit-border-bottom-right-radius": 0, outline: "0" }; //button css button .css(button_default) .hover( function() { $(this).css(button_hover); }, function() { if (!switcherpane.is(":animated") && switcherpane.is(":hidden")) { $(this).css(button_default); } } ) .find(".jquery-ui-themeswitcher-icon") .css({ float: "right", width: "16px", height: "16px", background: "url(" + options.imageLocation + "icon_color_arrow.gif) 50% 50% no-repeat" }); //pane css switcherpane .css({ position: "absolute", float: "left", fontFamily: "Trebuchet MS, Verdana, sans-serif", fontSize: "12px", background: "#000", color: "#fff", padding: "8px 3px 3px", border: "1px solid #ccc", "-moz-border-radius-bottomleft": "6px", "-webkit-border-bottom-left-radius": "6px", "-moz-border-radius-bottomright": "6px", "-webkit-border-bottom-right-radius": "6px", borderTop: 0, zIndex: 999999, width: options.width - 6 //minus must match left and right padding }) .find("ul") .css({ listStyle: "none", margin: "0", padding: "0", overflow: "auto", height: options.height }) .end() .find("li") .hover( function() { $(this).css({ borderColor: "#555", background: "url(" + options.imageLocation + "menuhoverbg.png) 50% 50% repeat-x", cursor: "pointer" }); }, function() { $(this).css({ borderColor: "#111", background: "#000", cursor: "auto" }); } ) .css({ width: options.width - 30, height: "", padding: "2px", margin: "1px", border: "1px solid #111", "-moz-border-radius": "4px", clear: "left", textAlign: "center", float: "left" }) .end() .find("a") .css({ color: "#aaa", textDecoration: "none", // float: 'left', width: "100%", outline: "0", textAlign: "center" }) .end() .find("img") .css({ // float: 'left', border: "1px solid #333", margin: "0 2px" }) .end() .find(".themeName") .css({ float: "left", margin: "3px 0", display: "block", width: "100%" }) .end(); $(this).append(button); $("body").append(switcherpane); switcherpane.hide(); if ( options.useCookie && ($.cookie(options.cookieName) || options.loadTheme) ) { var themeName = $.cookie(options.cookieName) || options.loadTheme; switcherpane.find("a:contains(" + themeName + ")").trigger("click"); } return this; }; /** * Cookie plugin * * Copyright (c) 2006 Klaus Hartl (stilbuero.de) * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * */ jQuery.cookie = function(name, value, options) { if (typeof value != "undefined") { // name and value given, set cookie options = options || {}; options.expires = 365; if (value === null) { value = ""; options.expires = -1; } var expires = ""; if ( options.expires && (typeof options.expires == "number" || options.expires.toUTCString) ) { var date; if (typeof options.expires == "number") { date = new Date(); date.setTime(date.getTime() + options.expires * 24 * 60 * 60 * 1000); } else { date = options.expires; } expires = "; expires=" + date.toUTCString(); // use expires attribute, max-age is not supported by IE } // CAUTION: Needed to parenthesize options.path and options.domain // in the following expressions, otherwise they evaluate to undefined // in the packed version for some reason... var path = options.path ? "; path=" + options.path : ""; var domain = options.domain ? "; domain=" + options.domain : ""; var secure = options.secure ? "; secure" : ""; document.cookie = [ name, "=", encodeURIComponent(value), expires, path, domain, secure ].join(""); } else { // only name given, get cookie var cookieValue = null; if (document.cookie && document.cookie != "") { var cookies = document.cookie.split(";"); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) == name + "=") { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } }; /* ==== STICKEY TABLE HEADERS ======== */ (function($) { $.StickyTableHeaders = function(el, options) { // To avoid scope issues, use 'base' instead of 'this' // to reference this class from internal events and functions. var base = this; // Access to jQuery and DOM versions of element base.$el = $(el); base.el = el; // Add a reverse reference to the DOM object base.$el.data("StickyTableHeaders", base); base.init = function() { base.options = $.extend({}, $.StickyTableHeaders.defaultOptions, options); base.$el.each(function() { var $this = $(this); $this.wrap( '
    ' ); var originalHeaderRow = $("thead:first", this); originalHeaderRow.before(originalHeaderRow.clone()); var clonedHeaderRow = $("thead:first", this); clonedHeaderRow.addClass("tableFloatingHeader"); clonedHeaderRow.css("position", "fixed"); clonedHeaderRow.css("top", "0px"); clonedHeaderRow.css("left", $this.css("margin-left")); clonedHeaderRow.css("display", "none"); originalHeaderRow.addClass("tableFloatingHeaderOriginal"); // enabling support for jquery.tablesorter plugin $this.bind("sortEnd", function(e) { base.updateCloneFromOriginal(originalHeaderRow, clonedHeaderRow); }); }); base.updateTableHeaders(); $(window).scroll(base.updateTableHeaders); $(window).resize(base.updateTableHeaders); }; base.updateTableHeaders = function() { base.$el.each(function() { var $this = $(this); var $window = $(window); var fixedHeaderHeight = isNaN(base.options.fixedOffset) ? base.options.fixedOffset.height() : base.options.fixedOffset; var originalHeaderRow = $(".tableFloatingHeaderOriginal", this); var floatingHeaderRow = $(".tableFloatingHeader", this); var offset = $this.offset(); var scrollTop = $window.scrollTop() + fixedHeaderHeight; var scrollLeft = $window.scrollLeft(); if (scrollTop > offset.top && scrollTop < offset.top + $this.height()) { floatingHeaderRow.css("top", fixedHeaderHeight + "px"); floatingHeaderRow.css("margin-top", 0); floatingHeaderRow.css("left", offset.left - scrollLeft + "px"); floatingHeaderRow.css("display", "block"); base.updateCloneFromOriginal(originalHeaderRow, floatingHeaderRow); } else { floatingHeaderRow.css("display", "none"); } }); }; base.updateCloneFromOriginal = function( originalHeaderRow, floatingHeaderRow ) { // Copy cell widths and classes from original header $("th", floatingHeaderRow).each(function(index) { $this = $(this); var origCell = $("th", originalHeaderRow).eq(index); $this.removeClass().addClass(origCell.attr("class")); $this.css("width", origCell.width()); }); // Copy row width from whole table floatingHeaderRow.css("width", originalHeaderRow.width()); }; // Run initializer base.init(); }; $.StickyTableHeaders.defaultOptions = { fixedOffset: 0 }; $.fn.stickyTableHeaders = function(options) { return this.each(function() { new $.StickyTableHeaders(this, options); }); }; })(jQuery); /************************************** jQuery Accordion Table ****************************************/ (function($) { $.fn.accordionTable = function(options) { return this.each(function() { var settings = options; // no defaults hideAllAccordionRows(this); hideAllTableOpenIcons(this); $(this) .find("." + settings.accordionClosedImg) .on("click", function(e) { if ( settings.isRowLoaded( $(e.target) .closest("tr") .next("tr") ) ) $.ajax({ url: urlForAccordionRow(e), data: dataAttributes(e), complete: function(data) { var accordion_row = toggleAccordionRow(e); if (settings.formatResponseToHtml) settings.formatResponseToHtml(data, accordion_row); else accordion_row.find("td").html(data.responseText); } }); else toggleAccordionRow(e); }); $(this) .find("." + settings.accordionOpenImg) .on("click", function(e) { toggleAccordionRow(e); }); function dataAttributes(e) { if (settings.dataAttrs) return settings.dataAttrs(e); else return null; } function urlForAccordionRow(e) { if (settings.urlForAccordionRow) return settings.urlForAccordionRow(e); else return ""; } function toggleAccordionRow(e) { var non_accordion_row = $(e.target).parents("tr"), accordion_row = non_accordion_row.next("tr"); accordion_row.toggle(); non_accordion_row.find("." + settings.accordionClosedImg).toggle(); non_accordion_row.find("." + settings.accordionOpenImg).toggle(); return accordion_row; } function hideAllAccordionRows(table) { $(table) .find("tr." + settings.accordionRow) .each(function(index) { $(this).hide(); }); } function hideAllTableOpenIcons(table) { $(table) .find("." + settings.accordionOpenImg) .each(function(index) { $(this).hide(); }); } }); }; })(jQuery); /*====== URL PARSING ========*/ /* https://github.com/websanova/url/tags */ window.url = (function() { function isNumeric(arg) { return !isNaN(parseFloat(arg)) && isFinite(arg); } return function(arg, url) { var _ls = url || window.location.toString(); if (!arg) { return _ls; } else { arg = arg.toString(); } if (_ls.substring(0, 2) === "//") { _ls = "http:" + _ls; } else if (_ls.split("://").length === 1) { _ls = "http://" + _ls; } url = _ls.split("/"); var _l = { auth: "" }, host = url[2].split("@"); if (host.length === 1) { host = host[0].split(":"); } else { _l.auth = host[0]; host = host[1].split(":"); } _l.protocol = url[0]; _l.hostname = host[0]; _l.port = host[1] || (_l.protocol.split(":")[0].toLowerCase() === "https" ? "443" : "80"); _l.pathname = (url.length > 3 ? "/" : "") + url .slice(3, url.length) .join("/") .split("?")[0] .split("#")[0]; var _p = _l.pathname; if (_p.charAt(_p.length - 1) === "/") { _p = _p.substring(0, _p.length - 1); } var _h = _l.hostname, _hs = _h.split("."), _ps = _p.split("/"); if (arg === "hostname") { return _h; } else if (arg === "domain") { if ( /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/.test( _h ) ) { return _h; } return _hs.slice(-2).join("."); } else if (arg === "sub") { //else if (arg === 'tld') { return _hs.slice(-1).join('.'); } return _hs.slice(0, _hs.length - 2).join("."); } else if (arg === "port") { return _l.port; } else if (arg === "protocol") { return _l.protocol.split(":")[0]; } else if (arg === "auth") { return _l.auth; } else if (arg === "user") { return _l.auth.split(":")[0]; } else if (arg === "pass") { return _l.auth.split(":")[1] || ""; } else if (arg === "path") { return _l.pathname; } else if (arg.charAt(0) === ".") { arg = arg.substring(1); if (isNumeric(arg)) { arg = parseInt(arg, 10); return _hs[arg < 0 ? _hs.length + arg : arg - 1] || ""; } } else if (isNumeric(arg)) { arg = parseInt(arg, 10); return _ps[arg < 0 ? _ps.length + arg : arg] || ""; } else if (arg === "file") { return _ps.slice(-1)[0]; } else if (arg === "filename") { return _ps.slice(-1)[0].split(".")[0]; } else if (arg === "fileext") { return _ps.slice(-1)[0].split(".")[1] || ""; } else if (arg.charAt(0) === "?" || arg.charAt(0) === "#") { var params = _ls, param = null; if (arg.charAt(0) === "?") { params = (params.split("?")[1] || "").split("#")[0]; } else if (arg.charAt(0) === "#") { params = params.split("#")[1] || ""; } if (!arg.charAt(1)) { return params; } arg = arg.substring(1); params = params.split("&"); for (var i = 0, ii = params.length; i < ii; i++) { param = params[i].split("="); if (param[0] === arg) { return param[1] || ""; } } return null; } return ""; }; })(); if (typeof jQuery !== "undefined") { jQuery.extend({ url: function(arg, url) { return window.url(arg, url); } }); } /* Highlighter */ /* * 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); }); };