15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(function() {
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var dumpToTextButton = $('dump-to-text');
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var dataDump = $('data-dump');
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dumpToTextButton.addEventListener('click', function(event) {
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Add info like Chrome version, OS, date dumped, etc.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var data = '';
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '======\n';
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += 'Status\n';
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '======\n';
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += JSON.stringify(chrome.sync.aboutInfo, null, 2);
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '\n';
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '\n';
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '=============\n';
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += 'Notifications\n';
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '=============\n';
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += JSON.stringify(chrome.sync.notifications, null, 2);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '\n';
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '\n';
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '===\n';
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += 'Log\n';
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '===\n';
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += JSON.stringify(chrome.sync.log.entries, null, 2);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data += '\n';
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dataDump.textContent = data;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)});
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var allFields = [
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'ID',
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'IS_UNSYNCED',
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'IS_UNAPPLIED_UPDATE',
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'BASE_VERSION',
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'BASE_VERSION_TIME',
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'SERVER_VERSION',
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'SERVER_VERSION_TIME',
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'PARENT_ID',
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'SERVER_PARENT_ID',
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'IS_DEL',
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'SERVER_IS_DEL',
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'serverModelType',
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  'SERVER_SPECIFICS',
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  'SPECIFICS',
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)];
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function versionToDateString(version) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(mmontgomery): ugly? Hacky? Is there a better way?
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var epochLength = Date.now().toString().length;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var epochTime = parseInt(version.slice(0, epochLength));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var date = new Date(epochTime);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return date.toString();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/**
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * @param {!Object} node A JavaScript represenation of a sync entity.
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * @return {string} A string representation of the sync entity.
63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfunction serializeNode(node) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return allFields.map(function(field) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var fieldVal;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (field == 'SERVER_VERSION_TIME') {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var version = node['SERVER_VERSION'];
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fieldVal = versionToDateString(version);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } if (field == 'BASE_VERSION_TIME') {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var version = node['BASE_VERSION'];
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fieldVal = versionToDateString(version);
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if ((field == 'SERVER_SPECIFICS' || field == 'SPECIFICS') &&
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            (!$('include-specifics').checked)) {
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fieldVal = 'REDACTED';
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if ((field == 'SERVER_SPECIFICS' || field == 'SPECIFICS') &&
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            $('include-specifics').checked) {
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      fieldVal = JSON.stringify(node[field]);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fieldVal = node[field];
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return fieldVal;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  });
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/**
87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * @param {string} type The name of a sync model type.
88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * @return {boolean} True if the type's checkbox is selected.
89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */
90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfunction isSelectedDatatype(type) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var typeCheckbox = $(type);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Some types, such as 'Top level folder', appear in the list of nodes
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but not in the list of selectable items.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (typeCheckbox == null) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return typeCheckbox.checked;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function makeBlobUrl(data) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var textBlob = new Blob([data], {type: 'octet/stream'});
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  var blobUrl = window.URL.createObjectURL(textBlob);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return blobUrl;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function makeDownloadName() {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Format is sync-data-dump-$epoch-$year-$month-$day-$OS.csv.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var now = new Date();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var friendlyDate = [now.getFullYear(),
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      now.getMonth() + 1,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      now.getDate()].join('-');
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var name = ['sync-data-dump',
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              friendlyDate,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              Date.now(),
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              navigator.platform].join('-');
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return [name, 'csv'].join('.');
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function makeDateUserAgentHeader() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var now = new Date();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var userAgent = window.navigator.userAgent;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var dateUaHeader = [now.toISOString(), userAgent].join(',');
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dateUaHeader;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/**
127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Builds a summary of current state and exports it as a downloaded file.
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * @param {!Array.<{type: string, nodes: !Array<!Object>}>} nodesMap
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *     Summary of local state by model type.
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */
132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfunction triggerDataDownload(nodesMap) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prepend a header with ISO date and useragent.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var output = [makeDateUserAgentHeader()];
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output.push('=====');
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var aboutInfo = JSON.stringify(chrome.sync.aboutInfo, null, 2);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output.push(aboutInfo);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Filter out non-selected types.
141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  var selectedTypesNodes = nodesMap.filter(function(x) {
142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return isSelectedDatatype(x.type);
143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  });
144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Serialize the remaining nodes and add them to the output.
146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  selectedTypesNodes.forEach(function(typeNodes) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output.push('=====');
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    output.push(typeNodes.nodes.map(serializeNode).join('\n'));
149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  });
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output = output.join('\n');
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var anchor = $('dump-to-file-anchor');
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor.href = makeBlobUrl(output);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor.download = makeDownloadName();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor.click();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function createTypesCheckboxes(types) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var containerElt = $('node-type-checkboxes');
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  types.map(function(type) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var div = document.createElement('div');
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var checkbox = document.createElement('input');
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    checkbox.id = type;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    checkbox.type = 'checkbox';
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    checkbox.checked = 'yes';
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    div.appendChild(checkbox);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var label = document.createElement('label');
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Assigning to label.for doesn't work.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    label.setAttribute('for', type);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    label.innerText = type;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    div.appendChild(label);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    containerElt.appendChild(div);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  });
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)function onReceivedListOfTypes(e) {
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  var types = e.details.types;
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  types.sort();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  createTypesCheckboxes(types);
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chrome.sync.events.removeEventListener(
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      'onReceivedListOfTypes',
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      onReceivedListOfTypes);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)document.addEventListener('DOMContentLoaded', function() {
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chrome.sync.events.addEventListener(
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      'onReceivedListOfTypes',
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      onReceivedListOfTypes);
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chrome.sync.requestListOfTypes();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)});
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var dumpToFileLink = $('dump-to-file');
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dumpToFileLink.addEventListener('click', function(event) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome.sync.getAllNodes(triggerDataDownload);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)});
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)})();
202