1 // Copyright (c) 2011 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.
6 var dumpToTextButton = $('dump-to-text');
7 var dataDump = $('data-dump');
8 dumpToTextButton.addEventListener('click', function(event) {
9 // TODO(akalin): Add info like Chrome version, OS, date dumped, etc.
15 data += JSON.stringify(chrome.sync.aboutInfo, null, 2);
19 data += '=============\n';
20 data += 'Notifications\n';
21 data += '=============\n';
22 data += JSON.stringify(chrome.sync.notifications, null, 2);
29 data += JSON.stringify(chrome.sync.log.entries, null, 2);
32 dataDump.textContent = data;
38 'IS_UNAPPLIED_UPDATE',
42 'SERVER_VERSION_TIME',
52 function versionToDateString(version) {
53 // TODO(mmontgomery): ugly? Hacky? Is there a better way?
54 var epochLength = Date.now().toString().length;
55 var epochTime = parseInt(version.slice(0, epochLength));
56 var date = new Date(epochTime);
57 return date.toString();
61 * @param {!Object} node A JavaScript represenation of a sync entity.
62 * @return {string} A string representation of the sync entity.
64 function serializeNode(node) {
65 return allFields.map(function(field) {
67 if (field == 'SERVER_VERSION_TIME') {
68 var version = node['SERVER_VERSION'];
69 fieldVal = versionToDateString(version);
70 } if (field == 'BASE_VERSION_TIME') {
71 var version = node['BASE_VERSION'];
72 fieldVal = versionToDateString(version);
73 } else if ((field == 'SERVER_SPECIFICS' || field == 'SPECIFICS') &&
74 (!$('include-specifics').checked)) {
75 fieldVal = 'REDACTED';
76 } else if ((field == 'SERVER_SPECIFICS' || field == 'SPECIFICS') &&
77 $('include-specifics').checked) {
78 fieldVal = JSON.stringify(node[field]);
80 fieldVal = node[field];
87 * @param {string} type The name of a sync model type.
88 * @return {boolean} True if the type's checkbox is selected.
90 function isSelectedDatatype(type) {
91 var typeCheckbox = $(type);
92 // Some types, such as 'Top level folder', appear in the list of nodes
93 // but not in the list of selectable items.
94 if (typeCheckbox == null) {
97 return typeCheckbox.checked;
100 function makeBlobUrl(data) {
101 var textBlob = new Blob([data], {type: 'octet/stream'});
102 var blobUrl = window.URL.createObjectURL(textBlob);
106 function makeDownloadName() {
107 // Format is sync-data-dump-$epoch-$year-$month-$day-$OS.csv.
108 var now = new Date();
109 var friendlyDate = [now.getFullYear(),
111 now.getDate()].join('-');
112 var name = ['sync-data-dump',
115 navigator.platform].join('-');
116 return [name, 'csv'].join('.');
119 function makeDateUserAgentHeader() {
120 var now = new Date();
121 var userAgent = window.navigator.userAgent;
122 var dateUaHeader = [now.toISOString(), userAgent].join(',');
127 * Builds a summary of current state and exports it as a downloaded file.
129 * @param {!Array<{type: string, nodes: !Array<!Object>}>} nodesMap
130 * Summary of local state by model type.
132 function triggerDataDownload(nodesMap) {
133 // Prepend a header with ISO date and useragent.
134 var output = [makeDateUserAgentHeader()];
135 output.push('=====');
137 var aboutInfo = JSON.stringify(chrome.sync.aboutInfo, null, 2);
138 output.push(aboutInfo);
140 // Filter out non-selected types.
141 var selectedTypesNodes = nodesMap.filter(function(x) {
142 return isSelectedDatatype(x.type);
145 // Serialize the remaining nodes and add them to the output.
146 selectedTypesNodes.forEach(function(typeNodes) {
147 output.push('=====');
148 output.push(typeNodes.nodes.map(serializeNode).join('\n'));
151 output = output.join('\n');
153 var anchor = $('dump-to-file-anchor');
154 anchor.href = makeBlobUrl(output);
155 anchor.download = makeDownloadName();
159 function createTypesCheckboxes(types) {
160 var containerElt = $('node-type-checkboxes');
162 types.map(function(type) {
163 var div = document.createElement('div');
165 var checkbox = document.createElement('input');
167 checkbox.type = 'checkbox';
168 checkbox.checked = 'yes';
169 div.appendChild(checkbox);
171 var label = document.createElement('label');
172 // Assigning to label.for doesn't work.
173 label.setAttribute('for', type);
174 label.innerText = type;
175 div.appendChild(label);
177 containerElt.appendChild(div);
181 function onReceivedListOfTypes(e) {
182 var types = e.details.types;
184 createTypesCheckboxes(types);
185 chrome.sync.events.removeEventListener(
186 'onReceivedListOfTypes',
187 onReceivedListOfTypes);
190 document.addEventListener('DOMContentLoaded', function() {
191 chrome.sync.events.addEventListener(
192 'onReceivedListOfTypes',
193 onReceivedListOfTypes);
194 chrome.sync.requestListOfTypes();
197 var dumpToFileLink = $('dump-to-file');
198 dumpToFileLink.addEventListener('click', function(event) {
199 chrome.sync.getAllNodes(triggerDataDownload);