• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4
5// require: cr.js
6
7cr.define('chrome.sync', function() {
8  var currSearchId = 0;
9
10  /**
11   * Runs a search with the given query.
12   *
13   * @param {string} query The regex to do the search with.
14   * @param {function} callback The callback called with the search results;
15   *     not called if doSearch() is called again while the search is running.
16   */
17  var doSearch = function(query, callback) {
18    var searchId = ++currSearchId;
19    try {
20      var regex = new RegExp(query);
21      chrome.sync.getAllNodes(query, function(allNodes) {
22        if (currSearchId != searchId) {
23          return;
24        }
25        callback(allNodes.filter(function(elem) {
26          return regex.test(JSON.stringify(elem, null, 2));
27        }), null);
28      });
29    } catch (err) {
30      // Sometimes the provided regex is invalid.  This and other errors will
31      // be caught and handled here.
32      callback([], err);
33    }
34  };
35
36  /**
37   * Decorates the various search controls.
38   *
39   * @param {!HTMLInputElement} queryControl The <input> object of
40   *     type=search where the user types in his query.
41   * @param {!HTMLElement} statusControl The <span> object display the
42   *     search status.
43   * @param {!HTMLElement} listControl The <list> object which holds
44   *     the list of returned results.
45   * @param {!HTMLPreElement} detailsControl The <pre> object which
46   *     holds the details of the selected result.
47   */
48  function decorateSearchControls(queryControl, statusControl,
49                                  resultsControl, detailsControl) {
50    var resultsDataModel = new cr.ui.ArrayDataModel([]);
51
52    // Decorate search box.
53    queryControl.onsearch = function() {
54      var query = queryControl.value;
55      statusControl.textContent = '';
56      resultsDataModel.splice(0, resultsDataModel.length);
57      if (!query) {
58        return;
59      }
60      statusControl.textContent = 'Searching for ' + query + '...';
61      queryControl.removeAttribute('error');
62      var timer = chrome.sync.makeTimer();
63      doSearch(query, function(nodes, error) {
64        if (error) {
65          statusControl.textContent = 'Error: ' + error;
66          queryControl.setAttribute('error', '');
67        } else {
68          statusControl.textContent =
69            'Found ' + nodes.length + ' nodes in ' +
70            timer.elapsedSeconds + 's';
71          queryControl.removeAttribute('error');
72
73          // TODO(akalin): Write a nicer list display.
74          for (var i = 0; i < nodes.length; ++i) {
75            nodes[i].toString = function() {
76              return this.NON_UNIQUE_NAME;
77            };
78          }
79          resultsDataModel.push.apply(resultsDataModel, nodes);
80          // Workaround for http://crbug.com/83452 .
81          resultsControl.redraw();
82        }
83      });
84    };
85    queryControl.value = '';
86
87    // Decorate results list.
88    cr.ui.List.decorate(resultsControl);
89    resultsControl.dataModel = resultsDataModel;
90    resultsControl.selectionModel.addEventListener('change', function(event) {
91      detailsControl.textContent = '';
92      var selected = resultsControl.selectedItem;
93      if (selected) {
94        detailsControl.textContent = JSON.stringify(selected, null, 2);
95      }
96    });
97  }
98
99  return {
100    decorateSearchControls: decorateSearchControls
101  };
102});
103