// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. (function() { var dumpToTextButton = $('dump-to-text'); var dataDump = $('data-dump'); dumpToTextButton.addEventListener('click', function(event) { // TODO(akalin): Add info like Chrome version, OS, date dumped, etc. var data = ''; data += '======\n'; data += 'Status\n'; data += '======\n'; data += JSON.stringify(chrome.sync.aboutInfo, null, 2); data += '\n'; data += '\n'; data += '=============\n'; data += 'Notifications\n'; data += '=============\n'; data += JSON.stringify(chrome.sync.notifications, null, 2); data += '\n'; data += '\n'; data += '===\n'; data += 'Log\n'; data += '===\n'; data += JSON.stringify(chrome.sync.log.entries, null, 2); data += '\n'; dataDump.textContent = data; }); var allFields = [ 'ID', 'IS_UNSYNCED', 'IS_UNAPPLIED_UPDATE', 'BASE_VERSION', 'BASE_VERSION_TIME', 'SERVER_VERSION', 'SERVER_VERSION_TIME', 'PARENT_ID', 'SERVER_PARENT_ID', 'IS_DEL', 'SERVER_IS_DEL', 'serverModelType', 'SERVER_SPECIFICS', 'SPECIFICS', ]; function versionToDateString(version) { // TODO(mmontgomery): ugly? Hacky? Is there a better way? var epochLength = Date.now().toString().length; var epochTime = parseInt(version.slice(0, epochLength)); var date = new Date(epochTime); return date.toString(); } function getFields(node) { return allFields.map(function(field) { var fieldVal; if (field == 'SERVER_VERSION_TIME') { var version = node['SERVER_VERSION']; fieldVal = versionToDateString(version); } if (field == 'BASE_VERSION_TIME') { var version = node['BASE_VERSION']; fieldVal = versionToDateString(version); } else if ((field == 'SERVER_SPECIFICS' || field == 'SPECIFICS') && (!$('include-specifics').checked)) { fieldVal = 'REDACTED'; } else if ((field == 'SERVER_SPECIFICS' || field == 'SPECIFICS') && $('include-specifics').checked) { fieldVal = JSON.stringify(node[field]); } else { fieldVal = node[field]; } return fieldVal; }); } function isSelectedDatatype(node) { var type = node.serverModelType; var typeCheckbox = $(type); // Some types, such as 'Top level folder', appear in the list of nodes // but not in the list of selectable items. if (typeCheckbox == null) { return false; } return typeCheckbox.checked; } function makeBlobUrl(data) { var textBlob = new Blob([data], {type: 'octet/stream'}); var blobUrl = window.URL.createObjectURL(textBlob); return blobUrl; } function makeDownloadName() { // Format is sync-data-dump-$epoch-$year-$month-$day-$OS.csv. var now = new Date(); var friendlyDate = [now.getFullYear(), now.getMonth() + 1, now.getDate()].join('-'); var name = ['sync-data-dump', friendlyDate, Date.now(), navigator.platform].join('-'); return [name, 'csv'].join('.'); } function makeDateUserAgentHeader() { var now = new Date(); var userAgent = window.navigator.userAgent; var dateUaHeader = [now.toISOString(), userAgent].join(','); return dateUaHeader; } function triggerDataDownload(data) { // Prepend a header with ISO date and useragent. var output = [makeDateUserAgentHeader()]; output.push('====='); var aboutInfo = JSON.stringify(chrome.sync.aboutInfo, null, 2); output.push(aboutInfo); if (data != null && data.length > 0) { output.push('====='); var fieldLabels = allFields.join(','); output.push(fieldLabels); var data = data.filter(isSelectedDatatype); data = data.map(getFields); var dataAsString = data.join('\n'); output.push(dataAsString); } output = output.join('\n'); var anchor = $('dump-to-file-anchor'); anchor.href = makeBlobUrl(output); anchor.download = makeDownloadName(); anchor.click(); } function createTypesCheckboxes(types) { var containerElt = $('node-type-checkboxes'); types.map(function(type) { var div = document.createElement('div'); var checkbox = document.createElement('input'); checkbox.id = type; checkbox.type = 'checkbox'; checkbox.checked = 'yes'; div.appendChild(checkbox); var label = document.createElement('label'); // Assigning to label.for doesn't work. label.setAttribute('for', type); label.innerText = type; div.appendChild(label); containerElt.appendChild(div); }); } document.addEventListener('DOMContentLoaded', function() { chrome.sync.getListOfTypes(function(types) { types.sort(); createTypesCheckboxes(types); }); }); var dumpToFileLink = $('dump-to-file'); dumpToFileLink.addEventListener('click', function(event) { chrome.sync.getAllNodes(triggerDataDownload); }); })();