typeahead_helper: Add escaping highlighter.

(imported from commit 71c08479763da792b581ff191c04889f0383ccc9)
This commit is contained in:
Waseem Daher 2012-11-18 13:19:52 -05:00
parent f214c2df75
commit 31c4cf96d2
3 changed files with 35 additions and 43 deletions

View File

@ -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 += "<strong>" + Handlebars.Utils.escapeExpression(piece) + "</strong>";
} 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.

View File

@ -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 += "<strong>" + Handlebars.Utils.escapeExpression(piece) + "</strong>";
} 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;

View File

@ -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 += "<strong>" + Handlebars.Utils.escapeExpression(piece) + "</strong>";
} else {
result += Handlebars.Utils.escapeExpression(piece);
}
});
return result;
};
return exports;
}());