From 31c4cf96d24ec363ef680c3f4d307a0f1f15f7e8 Mon Sep 17 00:00:00 2001 From: Waseem Daher Date: Sun, 18 Nov 2012 13:19:52 -0500 Subject: [PATCH] typeahead_helper: Add escaping highlighter. (imported from commit 71c08479763da792b581ff191c04889f0383ccc9) --- zephyr/static/js/composebox_typeahead.js | 27 +++--------------------- zephyr/static/js/search.js | 24 +++++---------------- zephyr/static/js/typeahead_helper.js | 27 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 43 deletions(-) diff --git a/zephyr/static/js/composebox_typeahead.js b/zephyr/static/js/composebox_typeahead.js index 8b0fa44792..164cb5b7bc 100644 --- a/zephyr/static/js/composebox_typeahead.js +++ b/zephyr/static/js/composebox_typeahead.js @@ -8,8 +8,8 @@ var composebox_typeahead = (function () { // the default highlighter. // // So if you are not using trusted input, you MUST use the a -// highlighter that escapes, such as composebox_typeahead_highlighter -// below. +// highlighter that escapes (i.e. one that calls +// typeahead_helper.highlight_with_escaping). var exports = {}; @@ -60,7 +60,6 @@ function get_last_recipient_in_pm(query_string) { return recipients[recipients.length-1]; } -// Loosely based on Bootstrap's default highlighter, but with escaping added. function composebox_typeahead_highlighter(item) { var query = this.query; if ($(this.$element).attr('id') === 'private_message_recipient') { @@ -69,27 +68,7 @@ function composebox_typeahead_highlighter(item) { // recent one we're entering. query = get_last_recipient_in_pm(this.query); } - query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&'); - var regex = new RegExp('(' + query + ')', 'ig'); - // The result of the split will include the query term, because our regex - // has parens in it. - // (as per https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/split) - // However, "not all browsers support this capability", so this is a place to look - // if we have an issue here in, e.g. IE. - var pieces = item.split(regex); - // We need to assemble this manually (as opposed to doing 'join') because we need to - // (1) escape all the pieces and (2) the regex is case-insensitive, and we need - // to know the case of the content we're replacing (you can't just use a bolded - // version of 'query') - var result = ""; - $.each(pieces, function(idx, piece) { - if (piece.match(regex)) { - result += "" + Handlebars.Utils.escapeExpression(piece) + ""; - } else { - result += Handlebars.Utils.escapeExpression(piece); - } - }); - return result; + return typeahead_helper.highlight_with_escaping(query, item); } // nextFocus is set on a keydown event to indicate where we should focus on keyup. diff --git a/zephyr/static/js/search.js b/zephyr/static/js/search.js index ca6070ae1e..34bcfbcd0a 100644 --- a/zephyr/static/js/search.js +++ b/zephyr/static/js/search.js @@ -39,24 +39,6 @@ function render_object(obj) { return "Error"; } -// Borrowed from composebox_typeahead_highlighter in composebox_typeahead.js. -function searchbox_typeahead_highlighter(item) { - var query = this.query; - var string_item = render_object(mapped[item]); - query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&'); - var regex = new RegExp('(' + query + ')', 'ig'); - var pieces = string_item.split(regex); - var result = ""; - $.each(pieces, function(idx, piece) { - if (piece.match(regex)) { - result += "" + Handlebars.Utils.escapeExpression(piece) + ""; - } else { - result += Handlebars.Utils.escapeExpression(piece); - } - }); - return result; -} - exports.initialize = function () { $( "#search_query" ).typeahead({ source: function (query, process) { @@ -79,7 +61,11 @@ exports.initialize = function () { return labels; }, items: 3, - highlighter: searchbox_typeahead_highlighter, + highlighter: function (item) { + var query = this.query; + var string_item = render_object(mapped[item]); + return typeahead_helper.highlight_with_escaping(query, string_item); + }, matcher: function (item) { var obj = mapped[item]; var actual_search_term = obj.query; diff --git a/zephyr/static/js/typeahead_helper.js b/zephyr/static/js/typeahead_helper.js index bfc9e507a0..d71914623e 100644 --- a/zephyr/static/js/typeahead_helper.js +++ b/zephyr/static/js/typeahead_helper.js @@ -2,6 +2,33 @@ var typeahead_helper = (function () { var exports = {}; +// Loosely based on Bootstrap's default highlighter, but with escaping added. +exports.highlight_with_escaping = function (query, item) { + // query: The text currently in the searchbox + // item: The string we are trying to appropriately highlight + query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&'); + var regex = new RegExp('(' + query + ')', 'ig'); + // The result of the split will include the query term, because our regex + // has parens in it. + // (as per https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/split) + // However, "not all browsers support this capability", so this is a place to look + // if we have an issue here in, e.g. IE. + var pieces = item.split(regex); + // We need to assemble this manually (as opposed to doing 'join') because we need to + // (1) escape all the pieces and (2) the regex is case-insensitive, and we need + // to know the case of the content we're replacing (you can't just use a bolded + // version of 'query') + var result = ""; + $.each(pieces, function(idx, piece) { + if (piece.match(regex)) { + result += "" + Handlebars.Utils.escapeExpression(piece) + ""; + } else { + result += Handlebars.Utils.escapeExpression(piece); + } + }); + return result; +}; + return exports; }());