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. // the default highlighter.
// //
// So if you are not using trusted input, you MUST use the a // So if you are not using trusted input, you MUST use the a
// highlighter that escapes, such as composebox_typeahead_highlighter // highlighter that escapes (i.e. one that calls
// below. // typeahead_helper.highlight_with_escaping).
var exports = {}; var exports = {};
@ -60,7 +60,6 @@ function get_last_recipient_in_pm(query_string) {
return recipients[recipients.length-1]; return recipients[recipients.length-1];
} }
// Loosely based on Bootstrap's default highlighter, but with escaping added.
function composebox_typeahead_highlighter(item) { function composebox_typeahead_highlighter(item) {
var query = this.query; var query = this.query;
if ($(this.$element).attr('id') === 'private_message_recipient') { if ($(this.$element).attr('id') === 'private_message_recipient') {
@ -69,27 +68,7 @@ function composebox_typeahead_highlighter(item) {
// recent one we're entering. // recent one we're entering.
query = get_last_recipient_in_pm(this.query); query = get_last_recipient_in_pm(this.query);
} }
query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&'); return typeahead_helper.highlight_with_escaping(query, item);
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;
} }
// nextFocus is set on a keydown event to indicate where we should focus on keyup. // 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"; 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 () { exports.initialize = function () {
$( "#search_query" ).typeahead({ $( "#search_query" ).typeahead({
source: function (query, process) { source: function (query, process) {
@ -79,7 +61,11 @@ exports.initialize = function () {
return labels; return labels;
}, },
items: 3, 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) { matcher: function (item) {
var obj = mapped[item]; var obj = mapped[item];
var actual_search_term = obj.query; var actual_search_term = obj.query;

View File

@ -2,6 +2,33 @@ var typeahead_helper = (function () {
var exports = {}; 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; return exports;
}()); }());