Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / resources / sync_internals / sync_search.js
blobfc9d504ab8d57a5ef2ba6083da157e796b1dbe4d
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // require: cr.js
7 cr.define('chrome.sync', function() {
8   var currSearchId = 0;
10   var setQueryString = function(queryControl, query) {
11     queryControl.value = query;
12   };
14   var createDoQueryFunction = function(queryControl, submitControl, query) {
15     return function() {
16       setQueryString(queryControl, query);
17       submitControl.click();
18     };
19   };
21   /**
22    * Decorates the quick search controls
23    *
24    * @param {Array of DOM elements} quickLinkArray The <a> object which
25    *     will be given a link to a quick filter option.
26    * @param {!HTMLInputElement} queryControl The <input> object of
27    *     type=search where the user types in his query.
28    */
29   var decorateQuickQueryControls = function(quickLinkArray, submitControl,
30                                             queryControl) {
31     for (var index = 0; index < allLinks.length; ++index) {
32       var quickQuery = allLinks[index].getAttribute('data-query');
33       var quickQueryFunction = createDoQueryFunction(queryControl,
34           submitControl, quickQuery);
35       allLinks[index].addEventListener('click', quickQueryFunction);
36     }
37   };
39   /**
40    * Runs a search with the given query.
41    *
42    * @param {string} query The regex to do the search with.
43    * @param {function} callback The callback called with the search results;
44    *     not called if doSearch() is called again while the search is running.
45    */
46   var doSearch = function(query, callback) {
47     var searchId = ++currSearchId;
48     try {
49       var regex = new RegExp(query);
50       chrome.sync.getAllNodes(query, function(allNodes) {
51         if (currSearchId != searchId) {
52           return;
53         }
54         callback(allNodes.filter(function(elem) {
55           return regex.test(JSON.stringify(elem, null, 2));
56         }), null);
57       });
58     } catch (err) {
59       // Sometimes the provided regex is invalid.  This and other errors will
60       // be caught and handled here.
61       callback([], err);
62     }
63   };
65   /**
66    * Decorates the various search controls.
67    *
68    * @param {!HTMLInputElement} queryControl The <input> object of
69    *     type=search where the user types in his query.
70    * @param {!HTMLButtonElement} submitControl The <button> object
71    *     where the user can click to do his query.
72    * @param {!HTMLElement} statusControl The <span> object display the
73    *     search status.
74    * @param {!HTMLElement} listControl The <list> object which holds
75    *     the list of returned results.
76    * @param {!HTMLPreElement} detailsControl The <pre> object which
77    *     holds the details of the selected result.
78    */
79   function decorateSearchControls(queryControl, submitControl, statusControl,
80                                   resultsControl, detailsControl) {
81     var resultsDataModel = new cr.ui.ArrayDataModel([]);
83     var searchFunction = function() {
84       var query = queryControl.value;
85       statusControl.textContent = '';
86       resultsDataModel.splice(0, resultsDataModel.length);
87       if (!query) {
88         return;
89       }
90       statusControl.textContent = 'Searching for ' + query + '...';
91       queryControl.removeAttribute('error');
92       var timer = chrome.sync.makeTimer();
93       doSearch(query, function(nodes, error) {
94         if (error) {
95           statusControl.textContent = 'Error: ' + error;
96           queryControl.setAttribute('error', '');
97         } else {
98           statusControl.textContent =
99             'Found ' + nodes.length + ' nodes in ' +
100             timer.elapsedSeconds + 's';
101           queryControl.removeAttribute('error');
103           // TODO(akalin): Write a nicer list display.
104           for (var i = 0; i < nodes.length; ++i) {
105             nodes[i].toString = function() {
106               return this.NON_UNIQUE_NAME;
107             };
108           }
109           resultsDataModel.push.apply(resultsDataModel, nodes);
110           // Workaround for http://crbug.com/83452 .
111           resultsControl.redraw();
112         }
113       });
114     };
116     submitControl.addEventListener('click', searchFunction);
117     // Decorate search box.
118     queryControl.onsearch = searchFunction;
119     queryControl.value = '';
121     // Decorate results list.
122     cr.ui.List.decorate(resultsControl);
123     resultsControl.dataModel = resultsDataModel;
124     resultsControl.selectionModel.addEventListener('change', function(event) {
125       detailsControl.textContent = '';
126       var selected = resultsControl.selectedItem;
127       if (selected) {
128         detailsControl.textContent = JSON.stringify(selected, null, 2);
129       }
130     });
131   }
133   return {
134     decorateSearchControls: decorateSearchControls,
135     decorateQuickQueryControls: decorateQuickQueryControls
136   };