about.js revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochcr.define('chrome.sync.about_tab', function() {
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Contains the latest snapshot of sync about info.
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  chrome.sync.aboutInfo = {};
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  function highlightIfChanged(node, oldVal, newVal) {
10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    function clearHighlight() {
11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      this.removeAttribute('highlighted');
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    var oldStr = oldVal.toString();
15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    var newStr = newVal.toString();
16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (oldStr != '' && oldStr != newStr) {
17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      // Note the addListener function does not end up creating duplicate
18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      // listeners.  There can be only one listener per event at a time.
19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      // Reference: https://developer.mozilla.org/en/DOM/element.addEventListener
20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      node.addEventListener('webkitAnimationEnd', clearHighlight, false);
21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      node.setAttribute('highlighted', '');
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  function refreshAboutInfo(aboutInfo) {
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    chrome.sync.aboutInfo = aboutInfo;
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    var aboutInfoDiv = $('about-info');
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    jstProcess(new JsEvalContext(aboutInfo), aboutInfoDiv);
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  function onAboutInfoUpdatedEvent(e) {
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    refreshAboutInfo(e.details);
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  /** Container for accumulated sync protocol events. */
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  var protocolEvents = [];
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  /** We may receive re-delivered events.  Keep a record of ones we've seen. */
39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  var knownEventTimestamps = {};
40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  /**
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   * Callback for incoming protocol events.
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   * @param {Event} e The protocol event.
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   */
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  function onReceivedProtocolEvent(e) {
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    var details = e.details;
47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
48e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Return early if we've seen this event before.  Assumes that timestamps
49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // are sufficiently high resolution to uniquely identify an event.
50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (knownEventTimestamps.hasOwnProperty(details.time)) {
51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      return;
52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    knownEventTimestamps[details.time] = true;
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    protocolEvents.push(details);
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    var context = new JsEvalContext({ events: protocolEvents });
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    jstProcess(context, $('traffic-event-container'));
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  /**
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   * Initializes state and callbacks for the protocol event log UI.
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   */
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  function initProtocolEventLog() {
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    chrome.sync.events.addEventListener(
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        'onProtocolEvent', onReceivedProtocolEvent);
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Make the prototype jscontent element disappear.
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    jstProcess({}, $('traffic-event-container'));
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  /**
73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch   * Initializes listeners for status dump and import UI.
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   */
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  function initStatusDumpButton() {
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    $('status-data').hidden = true;
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    var dumpStatusButton = $('dump-status');
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    dumpStatusButton.addEventListener('click', function(event) {
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      var aboutInfo = chrome.sync.aboutInfo;
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (!$('include-ids').checked) {
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        aboutInfo.details = chrome.sync.aboutInfo.details.filter(function(el) {
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          return !el.is_sensitive;
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        });
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      }
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      var data = '';
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data += new Date().toString() + '\n';
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data += '======\n';
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data += 'Status\n';
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data += '======\n';
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data += JSON.stringify(aboutInfo, null, 2) + '\n';
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      $('status-text').value = data;
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      $('status-data').hidden = false;
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    });
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    var importStatusButton = $('import-status');
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    importStatusButton.addEventListener('click', function(event) {
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      $('status-data').hidden = false;
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if ($('status-text').value.length == 0) {
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        $('status-text').value =
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            'Paste sync status dump here then click import.';
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return;
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      }
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // First remove any characters before the '{'.
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      var data = $('status-text').value;
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      var firstBrace = data.indexOf('{');
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (firstBrace < 0) {
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        $('status-text').value = 'Invalid sync status dump.';
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return;
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      }
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data = data.substr(firstBrace);
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // Remove listeners to prevent sync events from overwriting imported data.
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      chrome.sync.events.removeEventListener(
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          'onAboutInfoUpdated',
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          onAboutInfoUpdatedEvent);
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      var aboutInfo = JSON.parse(data);
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      refreshAboutInfo(aboutInfo);
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    });
123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  /**
126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch   * Toggles the given traffic event entry div's "expanded" state.
127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch   * @param {HTMLElement} element the element to toggle.
128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch   */
129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  function expandListener(element) {
130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    element.target.classList.toggle('traffic-event-entry-expanded');
131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  /**
134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch   * Attaches a listener to the given traffic event entry div.
135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch   * @param {HTMLElement} element the element to attach the listener to.
136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch   */
137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  function addExpandListener(element) {
138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    element.addEventListener('click', expandListener, false);
139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  function onLoad() {
142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    initStatusDumpButton();
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    initProtocolEventLog();
144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    chrome.sync.events.addEventListener(
146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        'onAboutInfoUpdated',
147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        onAboutInfoUpdatedEvent);
148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Register to receive a stream of event notifications.
150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    chrome.sync.registerForEvents();
151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Request an about info update event to initialize the page.
153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    chrome.sync.requestUpdatedAboutInfo();
154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return {
157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    onLoad: onLoad,
158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    addExpandListener: addExpandListener,
159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    highlightIfChanged: highlightIfChanged
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  };
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch});
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochdocument.addEventListener(
164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'DOMContentLoaded', chrome.sync.about_tab.onLoad, false);
165