Home | History | Annotate | Download | only in signin_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 var chrome = chrome || {};
      6 
      7 /**
      8  * Organizes all signin event listeners and asynchronous requests.
      9  * This object has no public constructor.
     10  * @type {Object}
     11  */
     12 chrome.signin = chrome.signin || {};
     13 
     14 (function() {
     15 
     16 // TODO(vishwath): This function is identical to the one in sync_internals.js
     17 // Merge both if possible.
     18 // Accepts a DOM node and sets its highlighted attribute oldVal != newVal
     19 function highlightIfChanged(node, oldVal, newVal) {
     20   var oldStr = oldVal.toString();
     21   var newStr = newVal.toString();
     22   if (oldStr != '' && oldStr != newStr) {
     23     // Note the addListener function does not end up creating duplicate
     24     // listeners.  There can be only one listener per event at a time.
     25     // Reference: https://developer.mozilla.org/en/DOM/element.addEventListener
     26     node.addEventListener('webkitAnimationEnd',
     27                           function() { this.removeAttribute('highlighted'); },
     28                           false);
     29     node.setAttribute('highlighted');
     30   }
     31 }
     32 
     33 // Wraps highlightIfChanged for multiple conditions.
     34 function highlightIfAnyChanged(node, oldToNewValList) {
     35   for (var i = 0; i < oldToNewValList.length; i++)
     36     highlightIfChanged(node, oldToNewValList[i][0], oldToNewValList[i][1]);
     37 }
     38 
     39 function setClassFromValue(value) {
     40   if (value == 0)
     41     return 'zero';
     42   if (value == 'Successful')
     43     return 'ok';
     44 
     45   return '';
     46 }
     47 
     48 // Allow signin_index.html to access the functions above using the
     49 // corresponding chrome.signin.<method> calls.
     50 chrome.signin['highlightIfChanged'] = highlightIfChanged;
     51 chrome.signin['highlightIfAnyChanged'] = highlightIfAnyChanged;
     52 chrome.signin['setClassFromValue'] = setClassFromValue;
     53 
     54 // Simplified Event class, borrowed (ok, stolen) from chrome_sync.js
     55 function Event() {
     56   this.listeners_ = [];
     57 }
     58 
     59 // Add a new listener to the list.
     60 Event.prototype.addListener = function(listener) {
     61   this.listeners_.push(listener);
     62 };
     63 
     64 // Remove a listener from the list.
     65 Event.prototype.removeListener = function(listener) {
     66   var i = this.findListener_(listener);
     67   if (i == -1) {
     68     return;
     69   }
     70   this.listeners_.splice(i, 1);
     71 };
     72 
     73 // Check if the listener has already been registered so we can prevent
     74 // duplicate registrations.
     75 Event.prototype.hasListener = function(listener) {
     76   return this.findListener_(listener) > -1;
     77 };
     78 
     79 // Are there any listeners registered yet?
     80 Event.prototype.hasListeners = function() {
     81   return this.listeners_.length > 0;
     82 };
     83 
     84 // Returns the index of the given listener, or -1 if not found.
     85 Event.prototype.findListener_ = function(listener) {
     86   for (var i = 0; i < this.listeners_.length; i++) {
     87     if (this.listeners_[i] == listener) {
     88       return i;
     89     }
     90   }
     91   return -1;
     92 };
     93 
     94 // Fires the event.  Called by the actual event callback.  Any
     95 // exceptions thrown by a listener are caught and logged.
     96 Event.prototype.fire = function() {
     97   var args = Array.prototype.slice.call(arguments);
     98   for (var i = 0; i < this.listeners_.length; i++) {
     99     try {
    100       this.listeners_[i].apply(null, args);
    101     } catch (e) {
    102       if (e instanceof Error) {
    103         // Non-standard, but useful.
    104         console.error(e.stack);
    105       } else {
    106         console.error(e);
    107       }
    108     }
    109   }
    110 };
    111 
    112 // These are the events that will be registered.
    113 chrome.signin.events = {
    114   'signin_manager': [
    115     'onSigninInfoChanged'
    116  ]
    117 };
    118 
    119 for (var eventType in chrome.signin.events) {
    120   var events = chrome.signin.events[eventType];
    121   for (var i = 0; i < events.length; ++i) {
    122     var event = events[i];
    123     chrome.signin[event] = new Event();
    124   }
    125 }
    126 
    127 // Creates functions that call into SigninInternalsUI.
    128 function makeSigninFunction(name) {
    129   var callbacks = [];
    130 
    131   // Calls the function, assuming the last argument is a callback to be
    132   // called with the return value.
    133   var fn = function() {
    134     var args = Array.prototype.slice.call(arguments);
    135     callbacks.push(args.pop());
    136     chrome.send(name, args);
    137   };
    138 
    139   // Handle a reply, assuming that messages are processed in FIFO order.
    140   // Called by SigninInternalsUI::HandleJsReply().
    141   fn.handleReply = function() {
    142     var args = Array.prototype.slice.call(arguments);
    143     // Remove the callback before we call it since the callback may
    144     // throw.
    145     var callback = callbacks.shift();
    146     callback.apply(null, args);
    147   };
    148 
    149   return fn;
    150 }
    151 
    152 // The list of js functions that call into SigninInternalsUI
    153 var signinFunctions = [
    154   // Signin Summary Info
    155   'getSigninInfo'
    156 ];
    157 
    158 for (var i = 0; i < signinFunctions.length; ++i) {
    159   var signinFunction = signinFunctions[i];
    160   chrome.signin[signinFunction] = makeSigninFunction(signinFunction);
    161 }
    162 
    163 chrome.signin.internalsInfo = {};
    164 
    165 // Replace the displayed values with the latest fetched ones.
    166 function refreshSigninInfo(signinInfo) {
    167   chrome.signin.internalsInfo = signinInfo;
    168   var internalsInfoDiv = $('signin-info');
    169   jstProcess(new JsEvalContext(signinInfo), internalsInfoDiv);
    170   var tokenInfoDiv = $('token-info');
    171   jstProcess(new JsEvalContext(signinInfo), tokenInfoDiv);
    172 }
    173 
    174 // On load, do an initial refresh and register refreshSigninInfo to be invoked
    175 // whenever we get new signin information from SigninInternalsUI.
    176 function onLoad() {
    177   chrome.signin.getSigninInfo(refreshSigninInfo);
    178 
    179   chrome.signin.onSigninInfoChanged.addListener(function(info) {
    180     refreshSigninInfo(info);
    181   });
    182 }
    183 
    184 document.addEventListener('DOMContentLoaded', onLoad, false);
    185 })();
    186