diff --git a/chrome/content/zotero/browser.js b/chrome/content/zotero/browser.js
index c6673064d..6627012fb 100644
--- a/chrome/content/zotero/browser.js
+++ b/chrome/content/zotero/browser.js
@@ -50,8 +50,6 @@ var Zotero_Browser = new function() {
this.tabClose = tabClose;
this.resize = resize;
this.updateStatus = updateStatus;
- this.finishScraping = finishScraping;
- this.itemDone = itemDone;
this.tabbrowser = null;
this.appcontent = null;
@@ -447,51 +445,6 @@ var Zotero_Browser = new function() {
}
}
- /*
- * Callback to be executed when scraping is complete
- */
- function finishScraping(obj, returnValue) {
- if(!returnValue) {
- Zotero_Browser.progress.show();
- Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError"));
- // Include link to Known Translator Issues page
- var url = "http://www.zotero.org/documentation/known_translator_issues";
- var linkText = ''
- + Zotero.getString('ingester.scrapeErrorDescription.linkText') + '';
- Zotero_Browser.progress.addDescription(Zotero.getString("ingester.scrapeErrorDescription", linkText));
- Zotero_Browser.progress.startCloseTimer(8000);
- } else {
- Zotero_Browser.progress.startCloseTimer();
- }
- Zotero_Browser.isScraping = false;
- }
-
-
- /*
- * Callback to be executed when an item has been finished
- */
- function itemDone(obj, dbItem, item, collection) {
- var title = item.title;
- var icon = Zotero.ItemTypes.getImageSrc(item.itemType);
- Zotero_Browser.progress.show();
- Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scraping"));
- Zotero_Browser.progress.addLines([title], [icon]);
-
- // add item to collection, if one was specified
- if(collection) {
- collection.addItem(dbItem.id);
- }
-
- if(Zotero_Browser.isScraping) {
- // initialize close timer between item saves in case translator doesn't call done
- Zotero_Browser.progress.startCloseTimer(10000); // is this long enough?
- } else {
- // if we aren't supposed to be scraping now, the translator is broken; assume we're
- // done
- Zotero_Browser.progress.startCloseTimer();
- }
- }
-
/**
* Called when status bar icon is right-clicked
*/
@@ -551,9 +504,9 @@ var Zotero_Browser = new function() {
function _constructLookupFunction(tab, success) {
return function(e) {
tab.page.translate.setTranslator(tab.page.translators[0]);
- tab.page.translate.clearHandlers("itemsDone");
+ tab.page.translate.clearHandlers("done");
tab.page.translate.clearHandlers("itemDone");
- tab.page.translate.setHandler("itemsDone", function(obj, status) {
+ tab.page.translate.setHandler("done", function(obj, status) {
if(status) {
success(e, obj);
Zotero_Browser.progress.close();
@@ -716,6 +669,7 @@ Zotero_Browser.Tab.prototype._attemptLocalFileImport = function(doc) {
Zotero_Browser.Tab.prototype.translate = function(libraryID, collectionID, translator) {
if(this.page.translators && this.page.translators.length) {
Zotero_Browser.progress.show();
+ Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scraping"));
Zotero_Browser.isScraping = true;
if(collectionID) {
@@ -730,11 +684,57 @@ Zotero_Browser.Tab.prototype.translate = function(libraryID, collectionID, trans
// use first translator available
this.page.translate.setTranslator(translator ? translator : this.page.translators[0]);
- this.page.translate.clearHandlers("itemsDone");
+ this.page.translate.clearHandlers("done");
this.page.translate.clearHandlers("itemDone");
- this.page.translate.setHandler("itemsDone", function(obj, item) { Zotero_Browser.finishScraping(obj, item) });
- this.page.translate.setHandler("itemDone", function(obj, dbItem, item) { Zotero_Browser.itemDone(obj, dbItem, item, collection) });
+ this.page.translate.setHandler("done", function(obj, returnValue) {
+ if(!returnValue) {
+ Zotero_Browser.progress.show();
+ Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError"));
+ // Include link to Known Translator Issues page
+ var url = "http://www.zotero.org/documentation/known_translator_issues";
+ var linkText = ''
+ + Zotero.getString('ingester.scrapeErrorDescription.linkText') + '';
+ Zotero_Browser.progress.addDescription(Zotero.getString("ingester.scrapeErrorDescription", linkText));
+ Zotero_Browser.progress.startCloseTimer(8000);
+ } else {
+ Zotero_Browser.progress.startCloseTimer();
+ }
+ Zotero_Browser.isScraping = false;
+ });
+
+ var attachmentsMap = new WeakMap();
+
+ this.page.translate.setHandler("itemDone", function(obj, dbItem, item) {
+ Zotero_Browser.progress.show();
+ var itemProgress = new Zotero_Browser.progress.ItemProgress(Zotero.ItemTypes.getImageSrc(item.itemType),
+ item.title);
+ itemProgress.setProgress(100);
+ for(var i=0; i elements are turned into XUL links
*/
- function addDescription(text) {
- if(_windowLoaded) {
- var newHB = _progressWindow.document.createElement("hbox");
- newHB.setAttribute("class", "zotero-progress-item-hbox");
- var newDescription = _progressWindow.document.createElement("description");
-
- var parts = Zotero.Utilities.parseMarkup(text);
- for each(var part in parts) {
- if (part.type == 'text') {
- var elem = _progressWindow.document.createTextNode(part.text);
+ this.addDescription = _deferUntilWindowLoad(function addDescription(text) {
+ var newHB = _progressWindow.document.createElement("hbox");
+ newHB.setAttribute("class", "zotero-progress-item-hbox");
+ var newDescription = _progressWindow.document.createElement("description");
+
+ var parts = Zotero.Utilities.parseMarkup(text);
+ for each(var part in parts) {
+ if (part.type == 'text') {
+ var elem = _progressWindow.document.createTextNode(part.text);
+ }
+ else if (part.type == 'link') {
+ var elem = _progressWindow.document.createElement('label');
+ elem.setAttribute('value', part.text);
+ elem.setAttribute('class', 'zotero-text-link');
+ for (var i in part.attributes) {
+ elem.setAttribute(i, part.attributes[i]);
}
- else if (part.type == 'link') {
- var elem = _progressWindow.document.createElement('label');
- elem.setAttribute('value', part.text);
- elem.setAttribute('class', 'zotero-text-link');
- for (var i in part.attributes) {
- elem.setAttribute(i, part.attributes[i]);
- }
- }
-
- newDescription.appendChild(elem);
}
- newHB.appendChild(newDescription);
- _progressWindow.document.getElementById("zotero-progress-text-box").appendChild(newHB);
-
- _move();
- } else {
- _loadDescription = text;
+ newDescription.appendChild(elem);
}
- }
+
+ newHB.appendChild(newDescription);
+ _progressWindow.document.getElementById("zotero-progress-text-box").appendChild(newHB);
+
+ _move();
+ });
-
- function startCloseTimer(ms, requireMouseOver) {
+ /**
+ * Sets a timer to close the progress window. If a previous close timer was set,
+ * clears it.
+ * @param {Integer} ms The number of milliseconds to wait before closing the progress
+ * window.
+ * @param {Boolean} [requireMouseOver] If true, wait until the mouse has touched the
+ * window before closing.
+ */
+ this.startCloseTimer = function startCloseTimer(ms, requireMouseOver) {
if (_windowLoaded || _windowLoading) {
if (requireMouseOver && !_mouseWasOver) {
return;
@@ -261,10 +230,14 @@ Zotero.ProgressWindow = function(_window){
}
_timeoutID = _progressWindow.setTimeout(_timeout, ms);
+ _closing = true;
}
}
- function close() {
+ /**
+ * Immediately closes the progress window if it is open.
+ */
+ this.close = function close() {
_disableTimeout();
_windowLoaded = false;
_windowLoading = false;
@@ -275,23 +248,102 @@ Zotero.ProgressWindow = function(_window){
} catch(ex) {}
}
+ /**
+ * Creates a new object representing a line in the progressWindow. This is the OO
+ * version of addLines() above.
+ */
+ this.ItemProgress = _deferUntilWindowLoad(function(iconSrc, title, parentItemProgress) {
+ this._itemText = _progressWindow.document.createElement("description");
+ this._itemText.appendChild(_progressWindow.document.createTextNode(title));
+ this._itemText.setAttribute("class", "zotero-progress-item-label");
+ this._itemText.setAttribute("crop", "end");
+
+ this._image = _progressWindow.document.createElement("hbox");
+ this._image.setAttribute("class", "zotero-progress-item-icon");
+ this._image.setAttribute("flex", 0);
+ this._image.style.width = "16px";
+ this._image.style.backgroundRepeat = "no-repeat";
+ this.setIcon(iconSrc);
+
+ this._hbox = _progressWindow.document.createElement("hbox");
+ this._hbox.setAttribute("class", "zotero-progress-item-hbox");
+ if(parentItemProgress) {
+ this._hbox.style.marginLeft = "16px";
+ this._hbox.zoteroIsChildItem;
+ }
+ this._hbox.style.opacity = "0.5";
+
+ this._hbox.appendChild(this._image);
+ this._hbox.appendChild(this._itemText);
+
+ var container = _progressWindow.document.getElementById("zotero-progress-text-box");
+ if(parentItemProgress) {
+ var nextItem = parentItemProgress._hbox.nextSibling;
+ while(nextItem && nextItem.zoteroIsChildItem) {
+ nextItem = nextItem.nextSibling;
+ }
+ container.insertBefore(this._hbox, nextItem);
+ } else {
+ container.appendChild(this._hbox);
+ }
+
+ _move();
+ });
+
+ /**
+ * Sets the current save progress for this item.
+ * @param {Integer} percent A percentage from 0 to 100.
+ */
+ this.ItemProgress.prototype.setProgress = _deferUntilWindowLoad(function(percent) {
+ if(percent != 0 && percent != 100) {
+ // Indication of partial progress, so we will use the circular indicator
+ this._image.style.backgroundImage = "url('chrome://zotero/skin/progress_arcs.png')";
+ this._image.style.backgroundPosition = "-"+(Math.round(percent/100*nArcs)*16)+"px 0";
+ this._hbox.style.opacity = percent/200+.5;
+ this._hbox.style.filter = "alpha(opacity = "+(percent/2+50)+")";
+ } else if(percent == 100) {
+ this._image.style.backgroundImage = "url('"+this._iconSrc+"')";
+ this._image.style.backgroundPosition = "";
+ this._hbox.style.opacity = "1";
+ this._hbox.style.filter = "";
+ }
+ });
+
+ /**
+ * Sets the icon for this item.
+ * @param {Integer} percent A percentage from 0 to 100.
+ */
+ this.ItemProgress.prototype.setIcon = _deferUntilWindowLoad(function(iconSrc) {
+ this._image.style.backgroundImage = "url('"+iconSrc+"')";
+ this._image.style.backgroundPosition = "";
+ this._iconSrc = iconSrc;
+ });
+
+ /**
+ * Indicates that an error occurred saving this item.
+ */
+ this.ItemProgress.prototype.setError = _deferUntilWindowLoad(function() {
+ this._image.style.backgroundImage = "url('chrome://zotero/skin/cross.png')";
+ this._image.style.backgroundPosition = "";
+ this._itemText.style.color = "red";
+ this._hbox.style.opacity = "1";
+ this._hbox.style.filter = "";
+ });
+
function _onWindowLoaded() {
_windowLoading = false;
_windowLoaded = true;
_move();
- // do things we delayed because the window was loading
- changeHeadline(_loadHeadline);
- addLines(_loadLines, _loadIcons);
- if (_loadDescription) {
- addDescription(_loadDescription);
- }
- // reset parameters
- _loadHeadline = '';
- _loadLines = [];
- _loadIcons = [];
- _loadDescription = null;
+ // do things we delayed because the window was loading
+ for(var i=0; i<_deferredUntilWindowLoad.length; i++) {
+ _deferredUntilWindowLoad[i].apply(_deferredUntilWindowLoadThis[i],
+ _deferredUntilWindowLoadArgs[i]);
+ }
+ _deferredUntilWindowLoad = [];
+ _deferredUntilWindowLoadThis = [];
+ _deferredUntilWindowLoadArgs = [];
}
function _move() {
@@ -303,8 +355,8 @@ Zotero.ProgressWindow = function(_window){
}
function _timeout() {
- close(); // could check to see if we're really supposed to close yet
- // (in case multiple scrapers are operating at once)
+ self.close(); // could check to see if we're really supposed to close yet
+ // (in case multiple scrapers are operating at once)
_timeoutID = false;
}
@@ -319,7 +371,6 @@ Zotero.ProgressWindow = function(_window){
_timeoutID = false;
}
-
/*
* Disable the close timer when the mouse is over the window
*/
@@ -328,8 +379,7 @@ Zotero.ProgressWindow = function(_window){
_disableTimeout();
}
-
- /*
+ /**
* Start the close timer when the mouse leaves the window
*
* Note that this onmouseout doesn't work correctly on popups in Fx2,
@@ -345,11 +395,27 @@ Zotero.ProgressWindow = function(_window){
&& (e.screenY >= top) && e.screenY <= (top + this.outerHeight)) {
return;
}
- startCloseTimer();
+ if(_closing) self.startCloseTimer();
}
-
function _onMouseUp(e) {
- close();
+ self.close();
+ }
+
+ /**
+ * Wraps a function to ensure it isn't called until the window is loaded
+ */
+ function _deferUntilWindowLoad(fn) {
+ return function() {
+ if(_window.closed) return;
+
+ if(_windowLoaded) {
+ fn.apply(this, Array.prototype.slice.call(arguments));
+ } else {
+ _deferredUntilWindowLoad.push(fn);
+ _deferredUntilWindowLoadThis.push(this);
+ _deferredUntilWindowLoadArgs.push(Array.prototype.slice.call(arguments));
+ }
+ }
}
}
diff --git a/chrome/content/zotero/xpcom/server_connector.js b/chrome/content/zotero/xpcom/server_connector.js
index 385388ac9..ca413b405 100755
--- a/chrome/content/zotero/xpcom/server_connector.js
+++ b/chrome/content/zotero/xpcom/server_connector.js
@@ -32,17 +32,21 @@ Zotero.Server.Connector.AttachmentProgressManager = new function() {
attachmentProgress = {},
i = 1;
+ /**
+ * Adds attachments to attachment progress manager
+ */
+ this.add = function(attachments) {
+ for(var i=0; i