diff --git a/gulpfile.js b/gulpfile.js
index 5da74aaeeb..f0d105deae 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -109,7 +109,6 @@ var backgroundInclude = [
'cachedTypes.js',
'zotero/date.js',
'zotero/debug.js',
- 'errors_webkit.js',
"zotero/xregexp/xregexp.js",
"zotero/xregexp/addons/build.js",
"zotero/xregexp/addons/matchrecursive.js",
@@ -117,6 +116,7 @@ var backgroundInclude = [
"zotero/xregexp/addons/unicode/unicode-categories.js",
"zotero/xregexp/addons/unicode/unicode-zotero.js",
'zotero/openurl.js',
+ 'reports.js',
'repo.js',
'zotero/translation/tlds.js',
'zotero/translation/translator.js',
diff --git a/src/common/connector.js b/src/common/connector.js
index 1f6f4b3030..525dd669ce 100644
--- a/src/common/connector.js
+++ b/src/common/connector.js
@@ -44,6 +44,25 @@ Zotero.Connector = {
Object.assign(this.selected, data);
Zotero.Connector_Browser._updateExtensionUI();
}.bind(this)});
+ this.addEventListener('reports', {notify: async function(data) {
+ if ('errors' in data && 'get' in data.errors) {
+ let sysInfo = await Zotero.getSystemInfo();
+ let errors = await Zotero.Errors.getErrors();
+ Zotero.Connector.callMethod('reports', {report: `${sysInfo}\n\n${errors.join('\n\n')}`});
+ }
+ else if ('debug' in data) {
+ if ('get' in data.debug) {
+ let debug = await Zotero.Debug.get();
+ Zotero.Connector.callMethod('reports', {report: debug});
+ }
+ else if ('store' in data.debug) {
+ Zotero.Debug.setStore(data.debug.store)
+ }
+ else if ('clear' in data.debug) {
+ Zotero.Debug.clear();
+ }
+ }
+ }});
Zotero.Connector.SSE.init();
},
@@ -311,46 +330,3 @@ Zotero.Connector.SSE = {
};
Zotero.Connector.addEventListener = Zotero.Connector.SSE._addEventListener.bind(Zotero.Connector.SSE);
Zotero.Connector.removeEventListener = Zotero.Connector.SSE._removeEventListener.bind(Zotero.Connector.SSE);
-
-
-// TODO: this does not belong here in the slightest
-Zotero.Connector_Debug = new function() {
- /**
- * Call a callback depending upon whether debug output is being stored
- */
- this.storing = function() {
- return Zotero.Debug.storing;
- }
-
- /**
- * Call a callback with the lines themselves
- */
- this.get = function() {
- return Zotero.Debug.get();
- };
-
- /**
- * Call a callback with the number of lines of output
- */
- this.count = function() {
- return Zotero.Debug.count();
- }
-
- /**
- * Submit data to the server
- */
- this.submitReport = function() {
- return Zotero.Debug.get().then(function(body){
- return Zotero.HTTP.request("POST", ZOTERO_CONFIG.REPOSITORY_URL + "report?debug=1", {body});
- }).then(function(xmlhttp) {
- if (!xmlhttp.responseXML) {
- throw new Error('Invalid response from server');
- }
- var reported = xmlhttp.responseXML.getElementsByTagName('reported');
- if (reported.length != 1) {
- throw new Error('The server returned an error. Please try again.');
- }
- return reported[0].getAttribute('reportID');
- });
- };
-}
diff --git a/src/common/errors_webkit.js b/src/common/errors_webkit.js
deleted file mode 100644
index cd0ca1cdf5..0000000000
--- a/src/common/errors_webkit.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- ***** BEGIN LICENSE BLOCK *****
-
- Copyright © 2009 Center for History and New Media
- George Mason University, Fairfax, Virginia, USA
- http://zotero.org
-
- This file is part of Zotero.
-
- Zotero is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Zotero is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Zotero. If not, see .
-
- ***** END LICENSE BLOCK *****
-*/
-
-Zotero.Errors = new function() {
- var _output = [];
-
- /**
- * Error handler
- * @param {String} string Error string
- * @param {String} url URL of error
- * @param {Number} line Line where error occurred
- */
- this.log = function(string, url, line) {
- var err = ['[JavaScript Error: "', string, '"'];
- if(url || line) {
- var info = [];
- if(url) info.push('file: "'+url+'"');
- if(line) info.push('line: '+line);
- err.push(" {"+info.join(" ")+"}");
- }
- err.push("]");
- err = err.join("");
- _output.push(err);
- }
-
- /**
- * Gets errors as an array of strings
- */
- this.getErrors = Zotero.Promise.method(function() {
- return _output.slice();
- })
-
- /**
- * Sends an error report to the server
- */
- this.sendErrorReport = function() {
- return Zotero.getSystemInfo().then(function(info) {
- var parts = {
- error: "true",
- errorData: _output.join('\n'),
- extraData: '',
- diagnostic: info
- };
-
- var body = '';
- for (var key in parts) {
- body += key + '=' + encodeURIComponent(parts[key]) + '&';
- }
- body = body.substr(0, body.length - 1);
- let options = {body, headers: {'Content-Type': 'application/x-www-form-urlencoded'}};
- return Zotero.HTTP.request("POST", "https://www.zotero.org/repo/report", options).then(function(xmlhttp) {
- var reported = xmlhttp.responseXML.getElementsByTagName('reported');
- if (reported.length != 1) {
- throw new Error('Invalid response from repository');
- }
- return reported[0].getAttribute('reportID');
- });
- });
- }
-}
-
-Zotero.Debug.bgInit = Zotero.Debug.init;
diff --git a/src/common/messages.js b/src/common/messages.js
index c724aa9f6b..37ffdf71dd 100644
--- a/src/common/messages.js
+++ b/src/common/messages.js
@@ -115,7 +115,11 @@ var MESSAGES = {
minArgs: 4
}
},
- setStore: false
+ setStore: false,
+ isStoring: true,
+ get: true,
+ count: true,
+ submitToZotero: true
},
Connector: {
checkIsOnline: true,
@@ -133,16 +137,10 @@ var MESSAGES = {
openConfigEditor: false,
openPreferences: false
},
- Connector_Debug: {
- storing: true,
- get: true,
- count: true,
- submitReport: true
- },
Errors: {
log: false,
getErrors: true,
- sendErrorReport: true
+ submitToZotero: true
},
Messaging: {
sendMessage: true
diff --git a/src/common/preferences/preferences.jsx b/src/common/preferences/preferences.jsx
index cb2dccf061..acd5af5de4 100644
--- a/src/common/preferences/preferences.jsx
+++ b/src/common/preferences/preferences.jsx
@@ -113,7 +113,7 @@ var Zotero_Preferences = {
document.getElementById('advanced-textarea-errors').textContent = errors.join("\n\n");
}
// get debug logging info
- return Zotero.Connector_Debug.count();
+ return Zotero.Debug.count();
}).then(function(count) {
document.getElementById('advanced-span-lines-logged').textContent = count.toString();
toggleDisabled(document.getElementById('advanced-button-view-output'), !count);
@@ -208,7 +208,7 @@ Zotero_Preferences.Advanced = {
init: function() {
document.getElementById("advanced-checkbox-enable-logging").onchange =
- function() { Zotero.Debug.setStore(this.checked); };
+ function() { Zotero.Debug.setStore(this.checked, true); };
document.getElementById("advanced-checkbox-enable-at-startup").onchange =
function() { Zotero.Prefs.set('debug.store', this.checked); };
document.getElementById("advanced-checkbox-show-in-console").onchange = function() {
@@ -245,7 +245,7 @@ Zotero_Preferences.Advanced = {
};
// get preference values
- Zotero.Connector_Debug.storing(function(status) {
+ Zotero.Debug.isStoring().then(function(status) {
document.getElementById('advanced-checkbox-enable-logging').checked = !!status;
});
Zotero.Prefs.getAsync("debug.store").then(function(status) {
@@ -263,7 +263,7 @@ Zotero_Preferences.Advanced = {
* Opens a new window to view debug output.
*/
viewDebugOutput: function() {
- Zotero.Connector_Debug.get(function(log) {
+ Zotero.Debug.get().then(function(log) {
var textarea = document.getElementById("advanced-textarea-debug");
textarea.textContent = log;
textarea.style.display = "";
@@ -274,7 +274,7 @@ Zotero_Preferences.Advanced = {
* Clears stored debug output.
*/
clearDebugOutput: function() {
- Zotero.Debug.clear();
+ Zotero.Debug.clear(true);
Zotero_Preferences.refreshData();
var textarea = document.getElementById("advanced-textarea-debug");
textarea.style.display = 'none';
@@ -287,9 +287,9 @@ Zotero_Preferences.Advanced = {
var submitOutputButton = document.getElementById('advanced-button-submit-output');
toggleDisabled(submitOutputButton, true);
- return Zotero.Connector_Debug.submitReport().then(function(reportID) {
+ return Zotero.Debug.submitToZotero().then(function(reportID) {
alert("Your debug output has been submitted.\n\n"
- + `The Debug ID is D${reportID}.`);
+ + `The Debug ID is ${reportID}.`);
}, function(e) {
alert(`An error occurred submitting your debug output.\n\n${e.message}\n\n`+
'Please check your internet connection. If the problem persists, '+
@@ -304,7 +304,7 @@ Zotero_Preferences.Advanced = {
var reportErrorsButton = document.getElementById('advanced-button-report-errors');
toggleDisabled(reportErrorsButton, true);
- return Zotero.Errors.sendErrorReport().then(function(reportID) {
+ return Zotero.Errors.submitToZotero().then(function(reportID) {
alert(`Your error report has been submitted.\n\nReport ID: ${reportID}\n\n`+
'Please post a message to the Zotero Forums (forums.zotero.org) with this Report '+
'ID, a description of the problem, and any steps necessary to reproduce it.\n\n'+
diff --git a/src/common/reports.js b/src/common/reports.js
new file mode 100644
index 0000000000..df4a1cd207
--- /dev/null
+++ b/src/common/reports.js
@@ -0,0 +1,138 @@
+/*
+ ***** BEGIN LICENSE BLOCK *****
+
+ Copyright © 2017 Center for History and New Media
+ George Mason University, Fairfax, Virginia, USA
+ http://zotero.org
+
+ This file is part of Zotero.
+
+ Zotero is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zotero is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zotero. If not, see .
+
+ ***** END LICENSE BLOCK *****
+*/
+
+(function() {
+
+var setStore = Zotero.Debug.setStore;
+Zotero.Debug.setStore = function(val, fetchFromClient) {
+ if (typeof fetchFromClient != 'boolean') fetchFromClient = false;
+ setStore.apply(this, arguments);
+ if (fetchFromClient) {
+ Zotero.Connector.callMethod('reports', {debug: {store: val}});
+ }
+};
+
+var clear = Zotero.Debug.clear;
+Zotero.Debug.clear = function(fetchFromClient) {
+ if (typeof fetchFromClient != 'boolean') fetchFromClient = false;
+ clear.apply(this, arguments);
+ if (fetchFromClient) {
+ Zotero.Connector.callMethod('reports', {debug: {clear: true}});
+ }
+};
+
+// Only there to expose the pref to injected pages
+Zotero.Debug.isStoring = function() {
+ return Zotero.Debug.storing;
+};
+
+/**
+ * Submit data to the server
+ */
+Zotero.Debug.submitToZotero = async function() {
+ return Zotero.Errors.submitToZotero(true);
+};
+
+Zotero.Errors = new function() {
+ var _output = [];
+
+ /**
+ * Error handler
+ * @param {String} string Error string
+ * @param {String} url URL of error
+ * @param {Number} line Line where error occurred
+ */
+ this.log = function(string, url, line) {
+ var err = ['Error: ', string];
+ if(url || line) {
+ var info = [];
+ if(url) info.push('file: "'+url+'"');
+ if(line) info.push('line: '+line);
+ err.push(" {"+info.join(" ")+"}");
+ }
+ err = err.join("");
+ _output.push(err);
+ };
+
+ /**
+ * Gets errors as an array of strings
+ */
+ this.getErrors = async function() {
+ return _output.slice();
+ };
+
+ this.generateReport = async function() {
+ let sysInfo = await Zotero.getSystemInfo();
+ return sysInfo + "\n\n" + (await this.getErrors()).join('\n\n') + "\n\n"
+ }
+
+ /**
+ * Sends an error report to the server
+ */
+ this.submitToZotero = async function(debug) {
+ var connectorBody, zoteroBody, url;
+ if (debug) {
+ url = ZOTERO_CONFIG.REPOSITORY_URL + "report?debug=1";
+ connectorBody = await Zotero.Debug.get();
+ } else {
+ url = ZOTERO_CONFIG.REPOSITORY_URL + "report?debug=1";
+ connectorBody = await this.generateReport();
+ }
+
+ // If zotero unavailable -- ignore
+ try {
+ if (debug) {
+ zoteroBody = await Zotero.Connector.callMethod('reports', {debug: {get: true}});
+ } else {
+ zoteroBody = await Zotero.Connector.callMethod('reports', {errors: {get: true}});
+ }
+ } catch (e) {}
+
+ let date = (new Date()).toUTCString();
+ let type = debug ? "Debug" : "Report";
+ let body = `----------------------------- Connector ${type}: ${date} --------------------------------\n\n`;
+ body += connectorBody;
+ if (zoteroBody) {
+ body += `\n\n----------------------------- Zotero ${type} --------------------------------\n\n`;
+ body += zoteroBody;
+ }
+ let headers = {'Content-Type': 'text/plain'};
+ let xmlhttp = await Zotero.HTTP.request("POST", url, {body, headers});
+
+ if (!xmlhttp.responseXML) {
+ throw new Error('Invalid response from server');
+ }
+ var reported = xmlhttp.responseXML.getElementsByTagName('reported');
+ if (reported.length != 1) {
+ throw new Error('The server returned an error. Please try again.');
+ }
+ if (debug) {
+ return 'D' + reported[0].getAttribute('reportID');
+ }
+ return 'D' + reported[0].getAttribute('reportID');
+ }
+};
+
+}());
\ No newline at end of file
diff --git a/src/common/test/tests/connectorTest.js b/src/common/test/tests/connectorTest.js
index d4a1f5b338..7681b95509 100644
--- a/src/common/test/tests/connectorTest.js
+++ b/src/common/test/tests/connectorTest.js
@@ -46,18 +46,26 @@ describe('Connector', function() {
}));
it('responds with false when Zotero is offline', Promise.coroutine(function*() {
- let status = yield background(function() {
+ let status = yield background(async function() {
Zotero.HTTP.request.resolves({status: 0});
- return Zotero.Connector.checkIsOnline();
+ let sseStatus = Zotero.Connector.SSE.available;
+ Zotero.Connector.SSE.available = false;
+ let status = await Zotero.Connector.checkIsOnline();
+ Zotero.Connector.SSE.available = sseStatus;
+ return status
});
assert.isNotOk(status);
}));
it('throws when Zotero responds with a non-200 status', Promise.coroutine(function* () {
try {
- yield background(function() {
+ yield background(async function() {
Zotero.HTTP.request.resolves({status: 500, getResponseHeader: () => '', responseText: 'Error'});
- return Zotero.Connector.checkIsOnline();
+ let sseStatus = Zotero.Connector.SSE.available;
+ Zotero.Connector.SSE.available = false;
+ let status = await Zotero.Connector.checkIsOnline();
+ Zotero.Connector.SSE.available = sseStatus;
+ return status
});
} catch (e) {
return
diff --git a/src/common/test/tests/preferencesTest.js b/src/common/test/tests/preferencesTest.js
index 6af85e2fbd..2da17c7333 100644
--- a/src/common/test/tests/preferencesTest.js
+++ b/src/common/test/tests/preferencesTest.js
@@ -113,22 +113,23 @@ describe('Preferences', function() {
}
}));
- it('submits a debug log to Zotero.org', Promise.coroutine(function * () {
+ it('submits a debug log to Zotero.org', async function () {
var debugId = '1234567890';
var testDebugLine = 'testDebugLine';
- yield background(function(debugId) {
+ await background(function(debugId) {
sinon.stub(Zotero.HTTP, 'request').resolves(
{responseXML: {getElementsByTagName: () => [{getAttribute: () => debugId}]}}
);
+ sinon.stub(Zotero.Connector, 'callMethod').resolves(new Zotero.Connector.CommunicationError('stub'));
}, debugId);
try {
- yield tab.run(function(testDebugLine) {
+ await tab.run(function(testDebugLine) {
document.getElementById('advanced-checkbox-enable-logging').click();
Zotero.debug(testDebugLine);
return Zotero_Preferences.refreshData();
}, testDebugLine);
- var message = yield tab.run(function() {
+ var message = await tab.run(function() {
var deferred = Zotero.Promise.defer();
sinon.stub(window, 'alert').callsFake(deferred.resolve);
document.getElementById('advanced-checkbox-enable-logging').click();
@@ -141,13 +142,16 @@ describe('Preferences', function() {
});
assert.include(message, `D${debugId}`);
- var debugLogBody = yield background(function() {
+ var debugLogBody = await background(function() {
return Zotero.HTTP.request.firstCall.args[2].body;
});
assert.include(debugLogBody, testDebugLine);
} finally {
- yield background(() => Zotero.HTTP.request.restore());
- }
- }));
+ await background(function() {
+ Zotero.HTTP.request.restore();
+ Zotero.Connector.callMethod.restore();
+ });
+ }
+ });
});
});
\ No newline at end of file
diff --git a/src/common/zotero.js b/src/common/zotero.js
index bddc9efbad..7612f35fc2 100644
--- a/src/common/zotero.js
+++ b/src/common/zotero.js
@@ -157,7 +157,7 @@ var Zotero = new function() {
/**
* Get versions, platform, etc.
*/
- this.getSystemInfo = function() {
+ this.getSystemInfo = async function() {
var info = {
connector: "true",
version: this.version,
@@ -169,12 +169,7 @@ var Zotero = new function() {
info.appName = Zotero.clientName;
info.zoteroAvailable = Zotero.Connector.isOnline;
- var str = '';
- for (var key in info) {
- str += key + ' => ' + info[key] + ', ';
- }
- str = str.substr(0, str.length - 2);
- return Promise.resolve(str);
+ return JSON.stringify(info, null, ' ');
};
/**