// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. var chrome = chrome || {}; /** * Organizes all signin event listeners and asynchronous requests. * This object has no public constructor. * @type {Object} */ chrome.signin = chrome.signin || {}; (function() { // TODO(vishwath): This function is identical to the one in sync_internals.js // Merge both if possible. // Accepts a DOM node and sets its highlighted attribute oldVal != newVal function highlightIfChanged(node, oldVal, newVal) { var oldStr = oldVal.toString(); var newStr = newVal.toString(); if (oldStr != '' && oldStr != newStr) { // Note the addListener function does not end up creating duplicate // listeners. There can be only one listener per event at a time. // Reference: https://developer.mozilla.org/en/DOM/element.addEventListener node.addEventListener('webkitAnimationEnd', function() { this.removeAttribute('highlighted'); }, false); node.setAttribute('highlighted', ''); } } // Wraps highlightIfChanged for multiple conditions. function highlightIfAnyChanged(node, oldToNewValList) { for (var i = 0; i < oldToNewValList.length; i++) highlightIfChanged(node, oldToNewValList[i][0], oldToNewValList[i][1]); } function setClassFromValue(value) { if (value == 0) return 'zero'; if (value == 'Successful') return 'ok'; return ''; } // Allow signin_index.html to access the functions above using the // corresponding chrome.signin. calls. chrome.signin['highlightIfChanged'] = highlightIfChanged; chrome.signin['highlightIfAnyChanged'] = highlightIfAnyChanged; chrome.signin['setClassFromValue'] = setClassFromValue; // Simplified Event class, borrowed (ok, stolen) from chrome_sync.js function Event() { this.listeners_ = []; } // Add a new listener to the list. Event.prototype.addListener = function(listener) { this.listeners_.push(listener); }; // Remove a listener from the list. Event.prototype.removeListener = function(listener) { var i = this.findListener_(listener); if (i == -1) { return; } this.listeners_.splice(i, 1); }; // Check if the listener has already been registered so we can prevent // duplicate registrations. Event.prototype.hasListener = function(listener) { return this.findListener_(listener) > -1; }; // Are there any listeners registered yet? Event.prototype.hasListeners = function() { return this.listeners_.length > 0; }; // Returns the index of the given listener, or -1 if not found. Event.prototype.findListener_ = function(listener) { for (var i = 0; i < this.listeners_.length; i++) { if (this.listeners_[i] == listener) { return i; } } return -1; }; // Fires the event. Called by the actual event callback. Any // exceptions thrown by a listener are caught and logged. Event.prototype.fire = function() { var args = Array.prototype.slice.call(arguments); for (var i = 0; i < this.listeners_.length; i++) { try { this.listeners_[i].apply(null, args); } catch (e) { if (e instanceof Error) { // Non-standard, but useful. console.error(e.stack); } else { console.error(e); } } } }; // These are the events that will be registered. chrome.signin.events = { 'signin_manager': [ 'onSigninInfoChanged' ] }; for (var eventType in chrome.signin.events) { var events = chrome.signin.events[eventType]; for (var i = 0; i < events.length; ++i) { var event = events[i]; chrome.signin[event] = new Event(); } } // Creates functions that call into SigninInternalsUI. function makeSigninFunction(name) { var callbacks = []; // Calls the function, assuming the last argument is a callback to be // called with the return value. var fn = function() { var args = Array.prototype.slice.call(arguments); callbacks.push(args.pop()); chrome.send(name, args); }; // Handle a reply, assuming that messages are processed in FIFO order. // Called by SigninInternalsUI::HandleJsReply(). fn.handleReply = function() { var args = Array.prototype.slice.call(arguments); // Remove the callback before we call it since the callback may // throw. var callback = callbacks.shift(); callback.apply(null, args); }; return fn; } // The list of js functions that call into SigninInternalsUI var signinFunctions = [ // Signin Summary Info 'getSigninInfo' ]; for (var i = 0; i < signinFunctions.length; ++i) { var signinFunction = signinFunctions[i]; chrome.signin[signinFunction] = makeSigninFunction(signinFunction); } chrome.signin.internalsInfo = {}; // Replace the displayed values with the latest fetched ones. function refreshSigninInfo(signinInfo) { chrome.signin.internalsInfo = signinInfo; var internalsInfoDiv = $('signin-info'); jstProcess(new JsEvalContext(signinInfo), internalsInfoDiv); var tokenInfoDiv = $('token-info'); jstProcess(new JsEvalContext(signinInfo), tokenInfoDiv); } // On load, do an initial refresh and register refreshSigninInfo to be invoked // whenever we get new signin information from SigninInternalsUI. function onLoad() { chrome.signin.getSigninInfo(refreshSigninInfo); chrome.signin.onSigninInfoChanged.addListener(function(info) { refreshSigninInfo(info); }); } document.addEventListener('DOMContentLoaded', onLoad, false); })();