Ported searchbar
This commit is contained in:
parent
2a9fddf7a0
commit
673661b798
8 changed files with 100 additions and 125 deletions
|
|
@ -21,6 +21,7 @@ app.views.Header = app.views.Base.extend({
|
|||
postRenderTemplate: function(){
|
||||
new app.views.Notifications({ el: '#notification_dropdown' });
|
||||
new app.views.NotificationsBadge({ el: '#notification_badge' });
|
||||
new app.views.SearchBar({ el: '#search_people_form' });
|
||||
},
|
||||
|
||||
menuElement: function(){ return this.$("ul.dropdown"); },
|
||||
|
|
|
|||
70
app/assets/javascripts/app/views/searchbar_view.js
Normal file
70
app/assets/javascripts/app/views/searchbar_view.js
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||
app.views.SearchBar = app.views.Base.extend({
|
||||
initialize: function(){
|
||||
this.searchForm = this.$el;
|
||||
this.searchFormAction = this.searchForm.attr('action');
|
||||
this.searchInput = this.searchForm.find('input[type="search"]');
|
||||
this.searchInputName = this.searchForm.find('input[type="search"]').attr('name');
|
||||
this.searchInputHandle = this.searchForm.find('input[type="search"]').attr('handle');
|
||||
this.options = {
|
||||
cacheLength: 15,
|
||||
delay: 800,
|
||||
extraParams: {limit: 4},
|
||||
formatItem: this.formatItem,
|
||||
formatResult: this.formatResult,
|
||||
max: 5,
|
||||
minChars: 2,
|
||||
onSelect: this.selectItemCallback,
|
||||
parse: this.parse,
|
||||
scroll: false,
|
||||
context: this
|
||||
};
|
||||
|
||||
var self = this;
|
||||
this.searchInput.autocomplete(self.searchFormAction + '.json',
|
||||
$.extend(self.options, { element: self.searchInput }));
|
||||
},
|
||||
|
||||
formatItem: function(row){
|
||||
if(typeof row.search !== 'undefined') { return Diaspora.I18n.t('search_for', row); }
|
||||
else {
|
||||
var item = '';
|
||||
if (row.avatar) { item += '<img src="' + row.avatar + '" class="avatar"/>'; }
|
||||
item += row.name;
|
||||
if (row.handle) { item += '<div class="search_handle">' + row.handle + '</div>'; }
|
||||
return item;
|
||||
}
|
||||
},
|
||||
|
||||
formatResult: function(row){ return Handlebars.Utils.escapeExpression(row.name); },
|
||||
|
||||
parse: function(data) {
|
||||
var results = data.map(function(person){
|
||||
person.name = Handlebars.Utils.escapeExpression(person.name);
|
||||
return {data : person, value : person.name};
|
||||
});
|
||||
|
||||
var self = this.context;
|
||||
results.push({
|
||||
data: {
|
||||
name: self.searchInput.val(),
|
||||
url: self.searchFormAction + '?' + self.searchInputName + '=' + self.searchInput.val(),
|
||||
search: true
|
||||
},
|
||||
value: self.searchInput.val()
|
||||
});
|
||||
|
||||
return results;
|
||||
},
|
||||
|
||||
selectItemCallback: function(evt, data, formatted){
|
||||
if(data.search === true){
|
||||
window.location = this.searchFormAction + '?' + this.searchInputName + '=' + data.name;
|
||||
}
|
||||
else{ // The actual result
|
||||
this.options.element.val(formatted);
|
||||
window.location = data.url ? data.url : '/tags/' + data.name.substring(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
// @license-ends
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||
|
||||
(function() {
|
||||
var Header = function() {
|
||||
var self = this;
|
||||
|
||||
this.subscribe("widget/ready", function(evt, header) {
|
||||
self.search = self.instantiate("Search", header.find(".search_form"));
|
||||
});
|
||||
};
|
||||
|
||||
Diaspora.Widgets.Header = Header;
|
||||
})();
|
||||
// @license-end
|
||||
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||
|
||||
(function() {
|
||||
var Search = function() {
|
||||
var self = this;
|
||||
|
||||
this.subscribe("widget/ready", function(evt, searchForm) {
|
||||
$.extend(self, {
|
||||
searchForm: searchForm,
|
||||
searchFormAction: searchForm.attr("action"),
|
||||
searchInput: searchForm.find("input[type='search']"),
|
||||
searchInputName: searchForm.find("input[type='search']").attr("name"),
|
||||
searchInputHandle: searchForm.find("input[type='search']").attr("handle"),
|
||||
options: {
|
||||
cacheLength : 15,
|
||||
delay : 800,
|
||||
extraParams : {limit : 4},
|
||||
formatItem : self.formatItem,
|
||||
formatResult : self.formatResult,
|
||||
max : 5,
|
||||
minChars : 2,
|
||||
onSelect: self.selectItemCallback,
|
||||
parse : self.parse,
|
||||
scroll : false
|
||||
}
|
||||
});
|
||||
|
||||
self.searchInput.autocomplete(self.searchFormAction + ".json", $.extend(self.options, {
|
||||
element: self.searchInput
|
||||
}));
|
||||
});
|
||||
|
||||
this.formatItem = function(row) {
|
||||
if (typeof row.search !== "undefined") {
|
||||
return Diaspora.I18n.t("search_for", row);
|
||||
} else {
|
||||
var item = "";
|
||||
if (row.avatar) {
|
||||
item += "<img src='"+ row.avatar +"' class='avatar'/>";
|
||||
}
|
||||
item += row.name;
|
||||
if (row.handle) {
|
||||
item += "<div class='search_handle'>" + row.handle + "</div>";
|
||||
}
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
this.formatResult = function(row) {
|
||||
return Handlebars.Utils.escapeExpression(row.name);
|
||||
};
|
||||
|
||||
this.parse = function(data) {
|
||||
var results = data.map(function(person){
|
||||
person['name'] = Handlebars.Utils.escapeExpression(person['name']);
|
||||
return {data : person, value : person['name']};
|
||||
});
|
||||
|
||||
results.push({
|
||||
data: {
|
||||
name: self.searchInput.val(),
|
||||
url: self.searchFormAction + "?" + self.searchInputName + "=" + self.searchInput.val(),
|
||||
search: true
|
||||
},
|
||||
value: self.searchInput.val()
|
||||
});
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
this.selectItemCallback = function(evt, data, formatted) {
|
||||
if (data['search'] === true) { // The placeholder "search for" result
|
||||
window.location = self.searchFormAction + '?' + self.searchInputName + '=' + data['name'];
|
||||
} else { // The actual result
|
||||
self.options.element.val(formatted);
|
||||
window.location = data['url'] ? data['url'] : "/tags/" + data['name'].substring(1); // we don't want the #-character
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Diaspora.Widgets.Search = Search;
|
||||
})();
|
||||
// @license-end
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
|
||||
|
||||
<div id="global_search">
|
||||
<form accept-charset="UTF-8" action="/search" class="search_form" method="get">
|
||||
<form id="search_people_form" accept-charset="UTF-8" action="/search" class="search_form" method="get">
|
||||
<input name="utf8" type="hidden" value="✓">
|
||||
<input id="q" name="q" placeholder="{{t "header.search"}}" results="5" type="search" autocomplete="off" class="ac_input">
|
||||
</form>
|
||||
|
|
|
|||
14
spec/javascripts/app/views/search_view_spec.js
Normal file
14
spec/javascripts/app/views/search_view_spec.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
describe("app.views.SearchBar", function() {
|
||||
beforeEach(function(){
|
||||
this.view = new app.views.SearchBar({ el: '#search_people_form' });
|
||||
});
|
||||
describe("parse", function() {
|
||||
it("escapes a persons name", function() {
|
||||
$("#jasmine_content").html('<form action="#" id="searchForm"></form>');
|
||||
|
||||
var person = { 'name': '</script><script>alert("xss");</script' };
|
||||
var result = this.view.search.parse([$.extend({}, person)]);
|
||||
expect(result[0].data.name).not.toEqual(person.name);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
describe("Diaspora.Widgets.Search", function() {
|
||||
describe("parse", function() {
|
||||
it("escapes a persons name", function() {
|
||||
$("#jasmine_content").html('<form action="#" id="searchForm"></form>');
|
||||
|
||||
var search = Diaspora.BaseWidget.instantiate("Search", $("#jasmine_content > #searchForm"));
|
||||
var person = {"name": "</script><script>alert('xss');</script"};
|
||||
var result = search.parse([$.extend({}, person)]);
|
||||
expect(result[0].data.name).not.toEqual(person.name);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue