Home | History | Annotate | Download | only in sync_internals
      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 
      7 cr.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