From 673661b798f809489cc51a79c8bcd34c7afcc5e0 Mon Sep 17 00:00:00 2001
From: Augier <contact@c-henry.fr>
Date: Thu, 12 Mar 2015 21:23:40 +0100
Subject: [PATCH] Ported searchbar

---
 .../javascripts/app/views/header_view.js      | 17 ++--
 .../app/views/notifications_badge_view.js     | 12 +--
 .../javascripts/app/views/searchbar_view.js   | 70 ++++++++++++++++
 app/assets/javascripts/widgets/header.js      | 15 ----
 app/assets/javascripts/widgets/search.js      | 83 -------------------
 app/assets/templates/header_tpl.jst.hbs       |  2 +-
 .../javascripts/app/views/search_view_spec.js | 14 ++++
 spec/javascripts/widgets/search-spec.js       | 12 ---
 8 files changed, 100 insertions(+), 125 deletions(-)
 create mode 100644 app/assets/javascripts/app/views/searchbar_view.js
 delete mode 100644 app/assets/javascripts/widgets/header.js
 delete mode 100644 app/assets/javascripts/widgets/search.js
 create mode 100644 spec/javascripts/app/views/search_view_spec.js
 delete mode 100644 spec/javascripts/widgets/search-spec.js

diff --git a/app/assets/javascripts/app/views/header_view.js b/app/assets/javascripts/app/views/header_view.js
index a3c9aceeb6..a3a2197aa4 100644
--- a/app/assets/javascripts/app/views/header_view.js
+++ b/app/assets/javascripts/app/views/header_view.js
@@ -2,17 +2,17 @@
 
 app.views.Header = app.views.Base.extend({
 
-  templateName : "header",
+  templateName: "header",
 
-  className : "dark-header",
+  className: "dark-header",
 
-  events :{
-    "click ul.dropdown li:first-child" : "toggleUserDropdown",
+  events: {
+    "click ul.dropdown li:first-child": "toggleUserDropdown",
     "focusin #q": "toggleSearchActive",
     "focusout #q": "toggleSearchActive"
   },
 
-  initialize : function(){
+  initialize: function(){
     $(document.body).click($.proxy(this.hideUserDropdown, this));
 
     return this;
@@ -21,11 +21,12 @@ 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"); },
+  menuElement: function(){ return this.$("ul.dropdown"); },
 
-  toggleUserDropdown : function(evt){
+  toggleUserDropdown: function(evt){
     if(evt){ evt.preventDefault(); }
 
     this.menuElement().toggleClass("active");
@@ -35,7 +36,7 @@ app.views.Header = app.views.Base.extend({
     }
   },
 
-  hideUserDropdown : function(evt){
+  hideUserDropdown: function(evt){
     if(this.menuElement().hasClass("active") && !$(evt.target).parents("#user_menu").length){
       this.menuElement().removeClass("active");
     }
diff --git a/app/assets/javascripts/app/views/notifications_badge_view.js b/app/assets/javascripts/app/views/notifications_badge_view.js
index e16d222c62..2c3bfee4fa 100644
--- a/app/assets/javascripts/app/views/notifications_badge_view.js
+++ b/app/assets/javascripts/app/views/notifications_badge_view.js
@@ -8,12 +8,12 @@ app.views.NotificationsBadge = app.views.Base.extend({
   initialize: function(){
     $(document.body).click($.proxy(this.hideNotifDropdown, this));
 
-      this.currentPage = 2;
-      this.notificationsLoaded = 10;
-      this.badge = this.$el;
-      this.dropdown = $('#notification_dropdown');
-      this.dropdownNotifications = this.dropdown.find(".notifications");
-      this.ajaxLoader = this.dropdown.find(".ajax_loader");
+    this.currentPage = 2;
+    this.notificationsLoaded = 10;
+    this.badge = this.$el;
+    this.dropdown = $('#notification_dropdown');
+    this.dropdownNotifications = this.dropdown.find(".notifications");
+    this.ajaxLoader = this.dropdown.find(".ajax_loader");
   },
 
   toggleNotifDropdown: function(evt){
diff --git a/app/assets/javascripts/app/views/searchbar_view.js b/app/assets/javascripts/app/views/searchbar_view.js
new file mode 100644
index 0000000000..6c16265bfe
--- /dev/null
+++ b/app/assets/javascripts/app/views/searchbar_view.js
@@ -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
diff --git a/app/assets/javascripts/widgets/header.js b/app/assets/javascripts/widgets/header.js
deleted file mode 100644
index e74fb175ac..0000000000
--- a/app/assets/javascripts/widgets/header.js
+++ /dev/null
@@ -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
-
diff --git a/app/assets/javascripts/widgets/search.js b/app/assets/javascripts/widgets/search.js
deleted file mode 100644
index 5540751940..0000000000
--- a/app/assets/javascripts/widgets/search.js
+++ /dev/null
@@ -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
diff --git a/app/assets/templates/header_tpl.jst.hbs b/app/assets/templates/header_tpl.jst.hbs
index 4fa05b10d7..89f81b5637 100644
--- a/app/assets/templates/header_tpl.jst.hbs
+++ b/app/assets/templates/header_tpl.jst.hbs
@@ -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>
diff --git a/spec/javascripts/app/views/search_view_spec.js b/spec/javascripts/app/views/search_view_spec.js
new file mode 100644
index 0000000000..2a1e4fa623
--- /dev/null
+++ b/spec/javascripts/app/views/search_view_spec.js
@@ -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);
+    });
+  });
+});
diff --git a/spec/javascripts/widgets/search-spec.js b/spec/javascripts/widgets/search-spec.js
deleted file mode 100644
index 4f1fb659a5..0000000000
--- a/spec/javascripts/widgets/search-spec.js
+++ /dev/null
@@ -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);
-        });
-    });
-});
-- 
GitLab