PageRenderTime 61ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/pancake-web/pancake/web/static/js/controllers/searchresultcontroller.js

https://bitbucket.org/mozillapancake/pancake
JavaScript | 188 lines | 114 code | 34 blank | 40 comment | 7 complexity | 8e93e7bdc40af5b851ef4ed7336fd56b MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, MIT, Apache-2.0
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. define([
  5. 'config',
  6. 'config/searchProviders',
  7. 'underscore',
  8. 'backbone',
  9. 'lib/template',
  10. 'lib/routecontroller',
  11. 'models/searchcollections',
  12. 'views/widgetview',
  13. 'views/searchviews',
  14. 'logger'
  15. ], function(
  16. config,
  17. searchProviders,
  18. util,
  19. Backbone,
  20. template,
  21. RouteController,
  22. searchCollections,
  23. WidgetView,
  24. searchViews,
  25. logger
  26. ) {
  27. // We need to pass an empty array into empty collections that need options
  28. // (null gets interpreted as a value and wrapped). It's a bit fussy, but it
  29. // should be faster to share a single object than create one.
  30. var emptyArray = [];
  31. var SearchResultsController = RouteController.extend({
  32. initialize: function (options) {
  33. // Initialize collections object for storing search collections.
  34. var collections = this.collections = {};
  35. // > Depending on how many providers we end up with, we may want to
  36. // > figure out a way to lazily create collections based on what we
  37. // > actually need. Prototypal objects are fast, though, so it might
  38. // > not actually matter -GB.
  39. collections.bings = new searchCollections.Bing(emptyArray, {
  40. urlTokens: {
  41. base: config.searchRoot,
  42. path: 'bing'
  43. },
  44. urlQuery: {
  45. // `q: query.terms,` should be manually configured in the `enter`
  46. // method using `terms` method.
  47. format: 'json'
  48. }
  49. });
  50. collections.tweets = new searchCollections.Tweets(emptyArray, {
  51. urlTokens: {
  52. base: config.searchRoot,
  53. path: 'twitter'
  54. },
  55. urlQuery: {
  56. // `q: query.terms,` should be manually configured in the `enter`
  57. // method using `terms` method.
  58. format: 'json'
  59. }
  60. });
  61. this.mainView = new searchViews.SearchTabsView();
  62. var bingListView = this.bings(collections.bings);
  63. var tweetListView = this.tweets(collections.tweets);
  64. this.mainView.widgets({
  65. '#bing-results': bingListView,
  66. '#twitter-results': tweetListView
  67. });
  68. this.mainView.bind('activate', function (view) {
  69. var activeView = view.widget(view.active);
  70. var collection = activeView.collection;
  71. if (collection.state() === 'invalid') {
  72. activeView.render();
  73. collection.fetchDebounced();
  74. }
  75. });
  76. this.mainView.activateTab('#bing-results');
  77. },
  78. enter: function (query, options) {
  79. util.extend(this, options || {});
  80. // Set this view as active in the app.
  81. this.appView.widget(
  82. '#main',
  83. this.mainView
  84. );
  85. },
  86. update: function (query, options) {
  87. // Update instance from options.
  88. //
  89. // TODO: I'm not wild about the way this works -- it's too brittle -GB
  90. util.extend(this, options || {});
  91. var terms = this.parseQuery(query).terms;
  92. var collections = this.collections;
  93. // Update terms on all collections.
  94. for(var key in collections) collections[key].terms(terms);
  95. // Fetch active search collection.
  96. this.mainView.widget(this.mainView.active).collection.fetchDebounced();
  97. },
  98. exit: function () {
  99. // Empty collections on exit.
  100. var collections = this.collections;
  101. for (var key in collections) collections[key].reset();
  102. // These memoized collections are available as properties on the
  103. // bings collection.
  104. this.collections.bings.images().reset();
  105. this.collections.bings.suggestions().reset();
  106. },
  107. // Factory function for creating tweet result view with configured
  108. // click handlers. This is all a little bit obtuse, and could probably
  109. // be cleaner, but I want to avoid binding handlers in the view constructor.
  110. tweets: function (collection) {
  111. var searchTweetsView = new searchViews.SearchTweetsView({
  112. collection: collection
  113. });
  114. searchTweetsView.bind('visit', function (placeView, siteModel, e) {
  115. // TODO
  116. }, this);
  117. return searchTweetsView;
  118. },
  119. // Factory function for creating bing result view with configured
  120. // click handlers. This is all a little bit obtuse, and could probably
  121. // be cleaner, but I want to avoid binding handlers in the view constructor.
  122. bings: function (collection) {
  123. var searchBingView = new searchViews.SearchBingView({
  124. collection: collection
  125. });
  126. // Define a handler for `visit` events on the `searchBingView`.
  127. searchBingView.bind('visit', function (placeView, siteModel, e) {
  128. // do nothing, allow the link click to proceed
  129. }, this);
  130. // Define a handler for `suggest` events on the `searchBingView`.
  131. searchBingView.bind('suggest', function (view, model, e) {
  132. // TODO
  133. }, this);
  134. return searchBingView;
  135. },
  136. parseQuery: function (query) {
  137. var // parse out the query - it can be something like twitter/term1/term2
  138. // or just 'term'
  139. terms = query.split('/'),
  140. // a master list of search providers we support, with name: prefix.
  141. // define in config maybe?
  142. providers = searchProviders;
  143. var parsed = {};
  144. // We consider the first term to be a provider if it matches one of the
  145. // providers in our list.
  146. if(terms.length > 1 && providers[terms[0]]) {
  147. parsed.provider = terms.shift();
  148. }
  149. parsed.terms = terms.join(' ');
  150. return parsed;
  151. }
  152. });
  153. return new SearchResultsController();
  154. });