12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var chrome = chrome || {};
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Organizes all signin event listeners and asynchronous requests.
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This object has no public constructor.
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {Object}
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)chrome.signin = chrome.signin || {};
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)(function() {
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(vishwath): This function is identical to the one in sync_internals.js
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Merge both if possible.
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Accepts a DOM node and sets its highlighted attribute oldVal != newVal
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function highlightIfChanged(node, oldVal, newVal) {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var oldStr = oldVal.toString();
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var newStr = newVal.toString();
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (oldStr != '' && oldStr != newStr) {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Note the addListener function does not end up creating duplicate
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // listeners.  There can be only one listener per event at a time.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Reference: https://developer.mozilla.org/en/DOM/element.addEventListener
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    node.addEventListener('webkitAnimationEnd',
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          function() { this.removeAttribute('highlighted'); },
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          false);
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    node.setAttribute('highlighted', '');
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Wraps highlightIfChanged for multiple conditions.
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function highlightIfAnyChanged(node, oldToNewValList) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (var i = 0; i < oldToNewValList.length; i++)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    highlightIfChanged(node, oldToNewValList[i][0], oldToNewValList[i][1]);
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function setClassFromValue(value) {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value == 0)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 'zero';
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value == 'Successful')
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 'ok';
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return '';
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Allow signin_index.html to access the functions above using the
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// corresponding chrome.signin.<method> calls.
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)chrome.signin['highlightIfChanged'] = highlightIfChanged;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)chrome.signin['highlightIfAnyChanged'] = highlightIfAnyChanged;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)chrome.signin['setClassFromValue'] = setClassFromValue;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Simplified Event class, borrowed (ok, stolen) from chrome_sync.js
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function Event() {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  this.listeners_ = [];
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Add a new listener to the list.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Event.prototype.addListener = function(listener) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  this.listeners_.push(listener);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Remove a listener from the list.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Event.prototype.removeListener = function(listener) {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var i = this.findListener_(listener);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (i == -1) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  this.listeners_.splice(i, 1);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Check if the listener has already been registered so we can prevent
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// duplicate registrations.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Event.prototype.hasListener = function(listener) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return this.findListener_(listener) > -1;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Are there any listeners registered yet?
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Event.prototype.hasListeners = function() {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return this.listeners_.length > 0;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns the index of the given listener, or -1 if not found.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Event.prototype.findListener_ = function(listener) {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (var i = 0; i < this.listeners_.length; i++) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (this.listeners_[i] == listener) {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return i;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return -1;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Fires the event.  Called by the actual event callback.  Any
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// exceptions thrown by a listener are caught and logged.
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Event.prototype.fire = function() {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var args = Array.prototype.slice.call(arguments);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (var i = 0; i < this.listeners_.length; i++) {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    try {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this.listeners_[i].apply(null, args);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } catch (e) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (e instanceof Error) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Non-standard, but useful.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        console.error(e.stack);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        console.error(e);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// These are the events that will be registered.
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)chrome.signin.events = {
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  'signin_manager': [
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'onSigninInfoChanged'
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ]
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)for (var eventType in chrome.signin.events) {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var events = chrome.signin.events[eventType];
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (var i = 0; i < events.length; ++i) {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var event = events[i];
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome.signin[event] = new Event();
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Creates functions that call into SigninInternalsUI.
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function makeSigninFunction(name) {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var callbacks = [];
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Calls the function, assuming the last argument is a callback to be
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // called with the return value.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var fn = function() {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var args = Array.prototype.slice.call(arguments);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callbacks.push(args.pop());
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome.send(name, args);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Handle a reply, assuming that messages are processed in FIFO order.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called by SigninInternalsUI::HandleJsReply().
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fn.handleReply = function() {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var args = Array.prototype.slice.call(arguments);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Remove the callback before we call it since the callback may
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // throw.
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var callback = callbacks.shift();
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.apply(null, args);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return fn;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The list of js functions that call into SigninInternalsUI
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var signinFunctions = [
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Signin Summary Info
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  'getSigninInfo'
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)];
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)for (var i = 0; i < signinFunctions.length; ++i) {
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var signinFunction = signinFunctions[i];
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome.signin[signinFunction] = makeSigninFunction(signinFunction);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)chrome.signin.internalsInfo = {};
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Replace the displayed values with the latest fetched ones.
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function refreshSigninInfo(signinInfo) {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome.signin.internalsInfo = signinInfo;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var internalsInfoDiv = $('signin-info');
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  jstProcess(new JsEvalContext(signinInfo), internalsInfoDiv);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var tokenInfoDiv = $('token-info');
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  jstProcess(new JsEvalContext(signinInfo), tokenInfoDiv);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// On load, do an initial refresh and register refreshSigninInfo to be invoked
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// whenever we get new signin information from SigninInternalsUI.
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function onLoad() {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome.signin.getSigninInfo(refreshSigninInfo);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome.signin.onSigninInfoChanged.addListener(function(info) {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    refreshSigninInfo(info);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  });
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)document.addEventListener('DOMContentLoaded', onLoad, false);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)})();
186