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. 4 5(function() { 6var dumpToTextButton = $('dump-to-text'); 7var dataDump = $('data-dump'); 8dumpToTextButton.addEventListener('click', function(event) { 9 // TODO(akalin): Add info like Chrome version, OS, date dumped, etc. 10 11 var data = ''; 12 data += '======\n'; 13 data += 'Status\n'; 14 data += '======\n'; 15 data += JSON.stringify(chrome.sync.aboutInfo, null, 2); 16 data += '\n'; 17 data += '\n'; 18 19 data += '=============\n'; 20 data += 'Notifications\n'; 21 data += '=============\n'; 22 data += JSON.stringify(chrome.sync.notifications, null, 2); 23 data += '\n'; 24 data += '\n'; 25 26 data += '===\n'; 27 data += 'Log\n'; 28 data += '===\n'; 29 data += JSON.stringify(chrome.sync.log.entries, null, 2); 30 data += '\n'; 31 32 dataDump.textContent = data; 33}); 34 35var allFields = [ 36 'ID', 37 'IS_UNSYNCED', 38 'IS_UNAPPLIED_UPDATE', 39 'BASE_VERSION', 40 'BASE_VERSION_TIME', 41 'SERVER_VERSION', 42 'SERVER_VERSION_TIME', 43 'PARENT_ID', 44 'SERVER_PARENT_ID', 45 'IS_DEL', 46 'SERVER_IS_DEL', 47 'serverModelType', 48 'SERVER_SPECIFICS', 49 'SPECIFICS', 50]; 51 52function 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(); 58} 59 60function getFields(node) { 61 return allFields.map(function(field) { 62 var fieldVal; 63 if (field == 'SERVER_VERSION_TIME') { 64 var version = node['SERVER_VERSION']; 65 fieldVal = versionToDateString(version); 66 } if (field == 'BASE_VERSION_TIME') { 67 var version = node['BASE_VERSION']; 68 fieldVal = versionToDateString(version); 69 } else if ((field == 'SERVER_SPECIFICS' || field == 'SPECIFICS') && 70 $('include-specifics').checked) { 71 fieldVal = JSON.stringify(node[field]); 72 } else { 73 fieldVal = node[field]; 74 } 75 return fieldVal; 76 }); 77} 78 79function isSelectedDatatype(node) { 80 var type = node.serverModelType; 81 var typeCheckbox = $(type); 82 // Some types, such as 'Top level folder', appear in the list of nodes 83 // but not in the list of selectable items. 84 if (typeCheckbox == null) { 85 return false; 86 } 87 return typeCheckbox.checked; 88} 89 90function makeBlobUrl(data) { 91 var textBlob = new Blob([data], {type: 'octet/stream'}); 92 var blobUrl = window.webkitURL.createObjectURL(textBlob); 93 return blobUrl; 94} 95 96function makeDownloadName() { 97 // Format is sync-data-dump-$epoch-$year-$month-$day-$OS.csv. 98 var now = new Date(); 99 var friendlyDate = [now.getFullYear(), 100 now.getMonth() + 1, 101 now.getDate()].join('-'); 102 var name = ['sync-data-dump', 103 friendlyDate, 104 Date.now(), 105 navigator.platform].join('-'); 106 return [name, 'csv'].join('.'); 107} 108 109function makeDateUserAgentHeader() { 110 var now = new Date(); 111 var userAgent = window.navigator.userAgent; 112 var dateUaHeader = [now.toISOString(), userAgent].join(','); 113 return dateUaHeader; 114} 115 116function triggerDataDownload(data) { 117 // Prepend a header with ISO date and useragent. 118 var output = [makeDateUserAgentHeader()]; 119 output.push('====='); 120 121 var aboutInfo = JSON.stringify(chrome.sync.aboutInfo, null, 2); 122 output.push(aboutInfo); 123 124 if (data != null && data.length > 0) { 125 output.push('====='); 126 var fieldLabels = allFields.join(','); 127 output.push(fieldLabels); 128 129 var data = data.filter(isSelectedDatatype); 130 data = data.map(getFields); 131 var dataAsString = data.join('\n'); 132 output.push(dataAsString); 133 } 134 output = output.join('\n'); 135 136 var anchor = $('dump-to-file-anchor'); 137 anchor.href = makeBlobUrl(output); 138 anchor.download = makeDownloadName(); 139 anchor.click(); 140} 141 142function createTypesCheckboxes(types) { 143 var containerElt = $('node-type-checkboxes'); 144 145 types.map(function(type) { 146 var div = document.createElement('div'); 147 148 var checkbox = document.createElement('input'); 149 checkbox.id = type; 150 checkbox.type = 'checkbox'; 151 checkbox.checked = 'yes'; 152 div.appendChild(checkbox); 153 154 var label = document.createElement('label'); 155 // Assigning to label.for doesn't work. 156 label.setAttribute('for', type); 157 label.innerText = type; 158 div.appendChild(label); 159 160 containerElt.appendChild(div); 161 }); 162} 163 164function populateDatatypes(childNodeSummaries) { 165 var types = childNodeSummaries.map(function(n) { 166 return n.type; 167 }); 168 types = types.sort(); 169 createTypesCheckboxes(types); 170} 171 172document.addEventListener('DOMContentLoaded', function() { 173 chrome.sync.getRootNodeDetails(function(rootNode) { 174 chrome.sync.getChildNodeIds(rootNode.id, function(childNodeIds) { 175 chrome.sync.getNodeSummariesById(childNodeIds, populateDatatypes); 176 }); 177 }); 178}); 179 180var dumpToFileLink = $('dump-to-file'); 181dumpToFileLink.addEventListener('click', function(event) { 182 chrome.sync.getAllNodes(triggerDataDownload); 183}); 184})(); 185