Merge branch '4.0'

Conflicts:
	chrome/content/zotero/xpcom/zotero.js
	install.rdf
	update.rdf
This commit is contained in:
Simon Kornblith 2013-03-23 17:35:19 -04:00
commit d8e2007da4
18 changed files with 134 additions and 60 deletions

@ -1 +1 @@
Subproject commit 67de2bc8f2d22247463b1b84caf9bf0ab100f2fa
Subproject commit 5b7a687df6464af87eaacc4088bd136ec1039d1b

View file

@ -40,7 +40,6 @@
onunload="Zotero_Preferences.onUnload()"
ondialoghelp="Zotero_Preferences.openHelpLink()"
windowtype="zotero:pref"
width="620"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<prefpane id="zotero-prefpane-general"

View file

@ -32,9 +32,11 @@
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<prefwindow id="zotero-prefs">
<prefpane id="zotero-prefpane-proxies"
label="&zotero.preferences.prefpane.proxies;"
image="chrome://zotero/skin/prefs-proxies.png" position="6"
helpTopic="proxies">
label="&zotero.preferences.prefpane.proxies;"
image="chrome://zotero/skin/prefs-proxies.png"
onpaneload="Zotero_Preferences.Proxies.init()"
position="6"
helpTopic="proxies">
<description width="45em" style="font-size: 12px">
&zotero.preferences.proxies.desc_before_link;
<label class="zotero-text-link" href="http://www.zotero.org/support/proxies"

View file

@ -60,7 +60,8 @@
<separator class="thin"/>
<label id="pdftools-required" hidden="true"/>
<!-- This doesn't wrap without an explicit width -->
<label id="pdftools-required" width="45em" hidden="true"/>
<separator class="thin"/>
@ -70,7 +71,8 @@
<separator class="thin"/>
<label id="pdftools-documentation-link" hidden="true"/>
<!-- This doesn't wrap without an explicit width -->
<label id="pdftools-documentation-link" width="45em" hidden="true"/>
<separator class="thin"/>
@ -110,6 +112,8 @@
</rows>
</grid>
</groupbox>
<separator/>
</prefpane>
<script src="preferences_search.js" type="application/javascript;version=1.8"/>

View file

@ -43,6 +43,21 @@ Zotero.File = new function(){
this.getCharsetFromFile = getCharsetFromFile;
this.addCharsetListener = addCharsetListener;
/**
* Encode special characters in file paths that might cause problems,
* like # (but preserve slashes or colons)
*
* @param {String} path File path
* @return {String} Encoded file path
*/
this.encodeFilePath = function(path) {
var parts = path.split(/([\\\/:]+)/);
// Every other item is the separator
for (var i=0, n=parts.length; i<n; i+=2) {
parts[i] = encodeURIComponent(parts[i]);
}
return parts.join('');
}
function getExtension(file){
var pos = file.leafName.lastIndexOf('.');

View file

@ -41,6 +41,7 @@ Zotero.HTTP = new function() {
* <li>debug - Log response text and status code</li>
* <li>dontCache - If set, specifies that the request should not be fulfilled from the cache</li>
* <li>headers - HTTP headers to include in the request</li>
* <li>requestObserver - Callback to receive XMLHttpRequest after open()</li>
* <li>responseType - The type of the response. See XHR 2 documentation for legal values</li>
* <li>responseCharset - The charset the response should be interpreted as</li>
* <li>successCodes - HTTP status codes that are considered successful</li>
@ -86,12 +87,19 @@ Zotero.HTTP = new function() {
});
}
var deferred = Q.defer();
var xmlhttp = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance();
// Prevent certificate/authentication dialogs from popping up
xmlhttp.mozBackgroundRequest = true;
xmlhttp.open(method, url, true);
// Pass the request to a callback
if (options && options.requestObserver) {
options.requestObserver(xmlhttp);
}
if (method == 'PUT') {
// Some servers (e.g., Jungle Disk DAV) return a 200 response code
// with Content-Length: 0, which triggers a "no element found" error
@ -128,8 +136,6 @@ Zotero.HTTP = new function() {
xmlhttp.setRequestHeader(header, headers[header]);
}
var deferred = Q.defer();
xmlhttp.onloadend = function() {
var status = xmlhttp.status;

View file

@ -104,9 +104,11 @@ Zotero.Sync.Storage.Queue.prototype.__defineSetter__('finishedRequests', functio
var localChanges = this._localChanges;
var remoteChanges = this._remoteChanges;
var conflicts = this._conflicts.concat();
var deferred = this._deferred;
this._localChanges = false;
this._remoteChanges = false;
this._conflicts = [];
this._deferred = null;
if (!this._error) {
Zotero.debug("Resolving promise for queue " + this.name);
@ -114,7 +116,7 @@ Zotero.Sync.Storage.Queue.prototype.__defineSetter__('finishedRequests', functio
Zotero.debug(this._remoteChanges);
Zotero.debug(this._conflicts);
this._deferred.resolve({
deferred.resolve({
libraryID: this.libraryID,
type: this.type,
localChanges: localChanges,
@ -128,7 +130,7 @@ Zotero.Sync.Storage.Queue.prototype.__defineSetter__('finishedRequests', functio
this._error = false;
e.libraryID = this.libraryID;
e.type = this.type;
this._deferred.reject(e);
deferred.reject(e);
}
return;
@ -368,7 +370,12 @@ Zotero.Sync.Storage.Queue.prototype.addConflict = function (requestName, localDa
Zotero.Sync.Storage.Queue.prototype.error = function (e) {
if (!this._error) {
this._error = e;
if (this.isRunning()) {
this._error = e;
}
else {
Zotero.debug("Queue " + this.name + " was no longer running -- not assigning error", 2);
}
}
Zotero.debug(e, 1);
this.stop();

View file

@ -43,6 +43,7 @@ Zotero.Sync.Storage.Request = function (name, callbacks) {
this._deferred = Q.defer();
this._running = false;
this._stopping = false;
this._percentage = 0;
this._remaining = null;
this._maxSize = null;
@ -222,16 +223,16 @@ Zotero.Sync.Storage.Request.prototype.start = function () {
// This promise updates localChanges/remoteChanges on the queue
self._deferred.resolve(results);
})
.fail(function (e) {
.catch(function (e) {
if (self._stopping) {
Zotero.debug("Skipping error for stopping request " + self.name);
return;
}
Zotero.debug(self.queue.Type + " request " + self.name + " failed");
Zotero.debug(self._deferred);
Zotero.debug(self._deferred.promise.isFulfilled());
self._deferred.reject(e);
Zotero.debug(self._deferred.promise.isFulfilled());
Zotero.debug(self._deferred.promise.isRejected());
})
// Finish the request (and in turn the queue, if this is the last request)
.fin(function () {
.finally(function () {
if (!self._finished) {
self._finish();
}
@ -309,6 +310,8 @@ Zotero.Sync.Storage.Request.prototype.onProgress = function (channel, progress,
*/
Zotero.Sync.Storage.Request.prototype.stop = function () {
if (this.channel) {
this._stopping = true;
try {
Zotero.debug("Stopping request '" + this.name + "'");
this.channel.cancel(0x804b0002); // NS_BINDING_ABORTED
@ -343,7 +346,7 @@ Zotero.Sync.Storage.Request.prototype._finish = function () {
this.queue.updateProgress();
}
catch (e) {
Zotero.debug(e);
Zotero.debug(e, 1);
Components.utils.reportError(e);
this._deferred.reject(e);
throw e;

View file

@ -42,14 +42,17 @@ Zotero.Sync.Storage.WebDAV = (function () {
* @param {Zotero.Item} item
* @param {Function} callback Callback f(item, mdate)
*/
function getStorageModificationTime(item) {
var funcName = "Zotero.Sync.Storage.WebDAV.getStorageModificationTime()";
function getStorageModificationTime(item, request) {
var uri = getItemPropertyURI(item);
return Zotero.HTTP.promise(
"GET", uri, { debug: true, successCodes: [200, 300, 404] }
)
return Zotero.HTTP.promise("GET", uri,
{
debug: true,
successCodes: [200, 300, 404],
requestObserver: function (xmlhttp) {
request.setChannel(xmlhttp.channel);
}
})
.then(function (req) {
checkResponse(req);
@ -113,7 +116,8 @@ Zotero.Sync.Storage.WebDAV = (function () {
})
.catch(function (e) {
if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
throw new Error("Unexpected status code " + e.status + " in " + funcName);
throw new Error("HTTP " + e.status + " error from WebDAV "
+ "server for GET request");
}
throw e;
});
@ -141,8 +145,9 @@ Zotero.Sync.Storage.WebDAV = (function () {
.then(function (req) {
return { mtime: mtime, hash: hash };
})
.fail(function (e) {
throw new Error("Unexpected status code " + e.xmlhttp.status);
.catch(function (e) {
throw new Error("HTTP " + e.xmlhttp.status
+ " from WebDAV server for HTTP PUT");
});
};
@ -163,7 +168,7 @@ Zotero.Sync.Storage.WebDAV = (function () {
var request = data.request;
var item = Zotero.Sync.Storage.getItemFromRequestName(request.name);
return getStorageModificationTime(item)
return getStorageModificationTime(item, request)
.then(function (mdate) {
if (!request.isRunning()) {
Zotero.debug("Upload request '" + request.name
@ -320,8 +325,9 @@ Zotero.Sync.Storage.WebDAV = (function () {
default:
Zotero.debug(response);
throw ("Unexpected file upload status " + status +
" in Zotero.Sync.Storage.WebDAV.onUploadComplete()");
throw (Zotero.getString('sync.storage.error.fileUploadFailed') +
" " + Zotero.getString('sync.storage.error.checkFileSyncSettings')
+ "\n\n" + "HTTP " + status);
}
return setStorageModificationTime(item)
@ -812,7 +818,7 @@ Zotero.Sync.Storage.WebDAV = (function () {
}
// Retrieve modification time from server to store locally afterwards
return getStorageModificationTime(item)
return getStorageModificationTime(item, request)
.then(function (mdate) {
if (!request.isRunning()) {
Zotero.debug("Download request '" + request.name
@ -879,9 +885,8 @@ Zotero.Sync.Storage.WebDAV = (function () {
return;
}
else if (status != 200) {
var msg = "Unexpected status code " + status
+ " for request " + data.request.name
+ " in Zotero.Sync.Storage.WebDAV.downloadFile()";
var msg = "HTTP " + status + " from WebDAV server "
+ " while downloading file";
Zotero.debug(msg, 1);
Components.utils.reportError(msg);
deferred.reject(Zotero.Sync.Storage.WebDAV.defaultError);
@ -987,8 +992,8 @@ Zotero.Sync.Storage.WebDAV = (function () {
_cachedCredentials = false;
}
else {
throw("Unexpected status code " + e.status + " getting "
+ "WebDAV last sync time");
throw("HTTP " + e.status + " error from WebDAV server "
+ "for GET request");
}
return Q.reject(e);
@ -1034,8 +1039,9 @@ Zotero.Sync.Storage.WebDAV = (function () {
}
});
})
.fail(function (e) {
var msg = "Unexpected error code " + req.status + " uploading storage success file";
.catch(function (e) {
var msg = "HTTP " + req.status + " error from WebDAV server "
+ "for PUT request";
Zotero.debug(msg, 2);
Components.utils.reportError(msg);
throw Zotero.Sync.Storage.WebDAV.defaultError;
@ -1058,8 +1064,8 @@ Zotero.Sync.Storage.WebDAV = (function () {
})
.fail(function (e) {
if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
var msg = "Unexpected status code " + e.status + " "
+ "for OPTIONS request caching WebDAV credentials";
var msg = "HTTP " + e.status + " error from WebDAV server "
+ "for OPTIONS request";
Zotero.debug(msg, 1);
Components.utils.reportError(msg);
throw new Error(Zotero.Sync.Storage.WebDAV.defaultErrorRestart);

View file

@ -38,10 +38,17 @@ Zotero.Sync.Storage.ZFS = (function () {
* @param {Zotero.Item} item
* @param {Function} callback Callback f(item, etag)
*/
function getStorageFileInfo(item) {
function getStorageFileInfo(item, request) {
var funcName = "Zotero.Sync.Storage.ZFS.getStorageFileInfo()";
return Zotero.HTTP.promise("GET", getItemInfoURI(item), { successCodes: [200, 404], headers: _headers })
return Zotero.HTTP.promise("GET", getItemInfoURI(item),
{
successCodes: [200, 404],
headers: _headers,
requestObserver: function (xmlhttp) {
request.setChannel(xmlhttp.channel);
}
})
.then(function (req) {
if (req.status == 404) {
return false;
@ -72,10 +79,15 @@ Zotero.Sync.Storage.ZFS = (function () {
return info;
})
.fail(function (e) {
.catch(function (e) {
if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
var msg = "Unexpected status code " + e.xmlhttp.status
+ " getting storage file info";
if (e.xmlhttp.status == 0) {
var msg = "Request cancelled getting storage file info";
}
else {
var msg = "Unexpected status code " + e.xmlhttp.status
+ " getting storage file info";
}
Zotero.debug(msg, 1);
Zotero.debug(e.xmlhttp.responseText);
Components.utils.reportError(msg);
@ -102,7 +114,7 @@ Zotero.Sync.Storage.ZFS = (function () {
var request = data.request;
var item = Zotero.Sync.Storage.getItemFromRequestName(request.name);
return getStorageFileInfo(item)
return getStorageFileInfo(item, request)
.then(function (info) {
if (request.isFinished()) {
Zotero.debug("Upload request '" + request.name
@ -694,7 +706,7 @@ Zotero.Sync.Storage.ZFS = (function () {
}
// Retrieve file info from server to store locally afterwards
return getStorageFileInfo(item)
return getStorageFileInfo(item, request)
.then(function (info) {
if (!request.isRunning()) {
Zotero.debug("Download request '" + request.name

View file

@ -978,13 +978,28 @@ Zotero.Sync.Runner = new function () {
box.appendChild(content);
box.appendChild(buttons);
var desc = doc.createElement('description');
// Use of deck and textbox+description here is a hack from
// http://www.blackfishsoftware.com/node/47 to make the text
// selectable while maintaining the proper width and height
var deck = doc.createElement('deck');
var msg = e.message;
/*if (e.fileName) {
msg += '\n\nFile: ' + e.fileName + '\nLine: ' + e.lineNumber;
}*/
var textbox = doc.createElement('textbox');
textbox.className = 'plain';
textbox.setAttribute('multiline', true);
textbox.setAttribute('readonly', true);
textbox.setAttribute('value', msg);
deck.appendChild(textbox);
var desc = doc.createElement('description');
desc.textContent = msg;
content.appendChild(desc);
deck.appendChild(desc);
content.appendChild(deck);
// If not an error and there's no explicit button text, don't show
// button to report errors

View file

@ -291,10 +291,10 @@ Zotero.Translate.ItemSaver.prototype = {
var IOService = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
try {
var uri = IOService.newURI(path, "", this._baseURI);
var uri = IOService.newURI(Zotero.File.encodeFilePath(path), "", this._baseURI);
}
catch (e) {
var msg = "Error parsing attachment path: " + path;
var msg = "Error parsing attachment path: " + path + "\n" + e.message;
Zotero.logError(msg);
Zotero.debug("Translate: " + msg, 2);
return false;
@ -303,14 +303,14 @@ Zotero.Translate.ItemSaver.prototype = {
try {
var file = uri.QueryInterface(Components.interfaces.nsIFileURL).file;
if (file.path == '/') {
var msg = "Error parsing attachment path: " + path;
var msg = "Error parsing attachment path: " + path + "\nRoot path returned.";
Zotero.logError(msg);
Zotero.debug("Translate: " + msg, 2);
return false;
}
}
catch (e) {
var msg = "Error getting file from attachment path: " + path;
var msg = "Error getting file from attachment path: " + path + "\n" + e.message;
Zotero.logError(msg);
Zotero.debug("Translate: " + msg, 2);
return false;

View file

@ -278,4 +278,4 @@
<!ENTITY zotero.downloadManager.label "Save to Zotero">
<!ENTITY zotero.downloadManager.saveToLibrary.description "Attachments cannot be saved to the currently selected library. This item will be saved to your library instead.">
<!ENTITY zotero.downloadManager.noPDFTools.description "To use this feature, you must first install the PDF tools in the Zotero preferences.">
<!ENTITY zotero.downloadManager.noPDFTools.description "To use this feature, you must first install the PDF tools in the Search pane of the Zotero preferences.">

View file

@ -258,7 +258,7 @@ pane.item.attachments.count.singular = %S attachment:
pane.item.attachments.count.plural = %S attachments:
pane.item.attachments.select = Select a File
pane.item.attachments.PDF.installTools.title = PDF Tools Not Installed
pane.item.attachments.PDF.installTools.text = To use this feature, you must first install the PDF tools in the Zotero preferences.
pane.item.attachments.PDF.installTools.text = To use this feature, you must first install the PDF tools in the Search pane of the Zotero preferences.
pane.item.attachments.filename = Filename
pane.item.noteEditor.clickHere = click here
pane.item.tags.count.zero = %S tags:
@ -822,7 +822,7 @@ sync.storage.error.default = A file sync error occurred. Please try syncing
sync.storage.error.defaultRestart = A file sync error occurred. Please restart %S and/or your computer and try syncing again.\n\nIf you receive this message repeatedly, submit an error report and post the Report ID to a new thread in the Zotero Forums.
sync.storage.error.serverCouldNotBeReached = The server %S could not be reached.
sync.storage.error.permissionDeniedAtAddress = You do not have permission to create a Zotero directory at the following address:
sync.storage.error.checkFileSyncSettings = Please check your file sync settings or contact your server administrator.
sync.storage.error.checkFileSyncSettings = Please check your file sync settings or contact your WebDAV server administrator.
sync.storage.error.verificationFailed = %S verification failed. Verify your file sync settings in the Sync pane of the Zotero preferences.
sync.storage.error.fileNotCreated = The file '%S' could not be created in the Zotero 'storage' directory.
sync.storage.error.encryptedFilenames = Error creating file '%S'.\n\nSee http://www.zotero.org/support/kb/encrypted_filenames for more information.

View file

@ -431,6 +431,10 @@
}
/* Sync error panel */
#zotero-sync-error-panel {
margin-right: 0;
}
.zotero-sync-error-panel-library-name {
font-size: 12px;
font-weight: bold;

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
2013-03-20 06:25:00
2013-03-22 05:55:00

@ -1 +1 @@
Subproject commit ed58b9977976ed42cdbaab0f129adb83c287664c
Subproject commit f23d8732c02c256423d4fbd6d85f9bca2d5336c2