Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / sync_driver / resources / about.js
blob47c1ab9392aa340da1810351a8a6ece4dc367342
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.
5 cr.define('chrome.sync.about_tab', function() {
6   // Contains the latest snapshot of sync about info.
7   chrome.sync.aboutInfo = {};
9   function highlightIfChanged(node, oldVal, newVal) {
10     function clearHighlight() {
11       this.removeAttribute('highlighted');
12     }
14     var oldStr = oldVal.toString();
15     var newStr = newVal.toString();
16     if (oldStr != '' && oldStr != newStr) {
17       // Note the addListener function does not end up creating duplicate
18       // listeners.  There can be only one listener per event at a time.
19       // Reference: https://developer.mozilla.org/en/DOM/element.addEventListener
20       node.addEventListener('webkitAnimationEnd', clearHighlight, false);
21       node.setAttribute('highlighted', '');
22     }
23   }
25   function refreshAboutInfo(aboutInfo) {
26     chrome.sync.aboutInfo = aboutInfo;
27     var aboutInfoDiv = $('about-info');
28     jstProcess(new JsEvalContext(aboutInfo), aboutInfoDiv);
29   }
31   function onAboutInfoUpdatedEvent(e) {
32     refreshAboutInfo(e.details);
33   }
35   /**
36    * Helper to determine if an element is scrolled to its bottom limit.
37    * @param {Element} elem element to check
38    * @return {boolean} true if the element is scrolled to the bottom
39    */
40   function isScrolledToBottom(elem) {
41     return elem.scrollHeight - elem.scrollTop == elem.clientHeight;
42   }
44   /**
45    * Helper to scroll an element to its bottom limit.
46    * @param {Element} elem element to be scrolled
47    */
48   function scrollToBottom(elem) {
49     elem.scrollTop = elem.scrollHeight - elem.clientHeight;
50   }
52   /** Container for accumulated sync protocol events. */
53   var protocolEvents = [];
55   /** We may receive re-delivered events.  Keep a record of ones we've seen. */
56   var knownEventTimestamps = {};
58   /**
59    * Callback for incoming protocol events.
60    * @param {Event} e The protocol event.
61    */
62   function onReceivedProtocolEvent(e) {
63     var details = e.details;
65     // Return early if we've seen this event before.  Assumes that timestamps
66     // are sufficiently high resolution to uniquely identify an event.
67     if (knownEventTimestamps.hasOwnProperty(details.time)) {
68       return;
69     }
71     knownEventTimestamps[details.time] = true;
72     protocolEvents.push(details);
74     var trafficContainer = $('traffic-event-container');
76     // Scroll to the bottom if we were already at the bottom.  Otherwise, leave
77     // the scrollbar alone.
78     var shouldScrollDown = isScrolledToBottom(trafficContainer);
80     var context = new JsEvalContext({ events: protocolEvents });
81     jstProcess(context, trafficContainer);
83     if (shouldScrollDown)
84       scrollToBottom(trafficContainer);
85   }
87   /**
88    * Initializes state and callbacks for the protocol event log UI.
89    */
90   function initProtocolEventLog() {
91     chrome.sync.events.addEventListener(
92         'onProtocolEvent', onReceivedProtocolEvent);
94     // Make the prototype jscontent element disappear.
95     jstProcess({}, $('traffic-event-container'));
96   }
98   /**
99    * Initializes listeners for status dump and import UI.
100    */
101   function initStatusDumpButton() {
102     $('status-data').hidden = true;
104     var dumpStatusButton = $('dump-status');
105     dumpStatusButton.addEventListener('click', function(event) {
106       var aboutInfo = chrome.sync.aboutInfo;
107       if (!$('include-ids').checked) {
108         aboutInfo.details = chrome.sync.aboutInfo.details.filter(function(el) {
109           return !el.is_sensitive;
110         });
111       }
112       var data = '';
113       data += new Date().toString() + '\n';
114       data += '======\n';
115       data += 'Status\n';
116       data += '======\n';
117       data += JSON.stringify(aboutInfo, null, 2) + '\n';
119       $('status-text').value = data;
120       $('status-data').hidden = false;
121     });
123     var importStatusButton = $('import-status');
124     importStatusButton.addEventListener('click', function(event) {
125       $('status-data').hidden = false;
126       if ($('status-text').value.length == 0) {
127         $('status-text').value =
128             'Paste sync status dump here then click import.';
129         return;
130       }
132       // First remove any characters before the '{'.
133       var data = $('status-text').value;
134       var firstBrace = data.indexOf('{');
135       if (firstBrace < 0) {
136         $('status-text').value = 'Invalid sync status dump.';
137         return;
138       }
139       data = data.substr(firstBrace);
141       // Remove listeners to prevent sync events from overwriting imported data.
142       chrome.sync.events.removeEventListener(
143           'onAboutInfoUpdated',
144           onAboutInfoUpdatedEvent);
146       var aboutInfo = JSON.parse(data);
147       refreshAboutInfo(aboutInfo);
148     });
149   }
151   /**
152    * Toggles the given traffic event entry div's "expanded" state.
153    * @param {MouseEvent} e the click event that triggered the toggle.
154    */
155   function expandListener(e) {
156     e.target.classList.toggle('traffic-event-entry-expanded');
157   }
159   /**
160    * Attaches a listener to the given traffic event entry div.
161    * @param {HTMLElement} element the element to attach the listener to.
162    */
163   function addExpandListener(element) {
164     element.addEventListener('click', expandListener, false);
165   }
167   function onLoad() {
168     initStatusDumpButton();
169     initProtocolEventLog();
171     chrome.sync.events.addEventListener(
172         'onAboutInfoUpdated',
173         onAboutInfoUpdatedEvent);
175     // Register to receive a stream of event notifications.
176     chrome.sync.registerForEvents();
178     // Request an about info update event to initialize the page.
179     chrome.sync.requestUpdatedAboutInfo();
180   }
182   return {
183     onLoad: onLoad,
184     addExpandListener: addExpandListener,
185     highlightIfChanged: highlightIfChanged
186   };
189 document.addEventListener(
190     'DOMContentLoaded', chrome.sync.about_tab.onLoad, false);