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
);