www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit f3a8cbd993f116db716fd2a4b9c794b5f405bc39
parent 7ce0e9ee23c68afe0d7d3ec5cab1a77b5428f06e
Author: Dan Stillman <dstillman@zotero.org>
Date:   Wed,  7 Jul 2010 18:34:09 +0000

Switch back to multiple items per Zotero Commons bucket

- Creating buckets not yet supported
- Some now-unused single-item-per-bucket code still needs to be removed
- Child attachments are not displayed in Zotero Commons pane
- Manual refreshing via bucket right-click (or a Firefox restart) is currently necessary after adding items
- Double-clicking bucket takes you to bucket page; double-clicking item takes you to named anchor


Diffstat:
Mchrome/content/zotero/overlay.js | 69+++++++++++++++++++++++++++++++++++++--------------------------------
Mchrome/content/zotero/overlay.xul | 2+-
Mchrome/content/zotero/xpcom/collectionTreeView.js | 100++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mchrome/content/zotero/xpcom/commons.js | 1104++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Mchrome/content/zotero/xpcom/itemTreeView.js | 25+++++++++----------------
Mchrome/content/zotero/xpcom/notifier.js | 2+-
6 files changed, 757 insertions(+), 545 deletions(-)

diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js @@ -1343,7 +1343,7 @@ var ZoteroPane = new function() } var itemGroup = this.itemsView._itemGroup; - if (!itemGroup.isTrash() && !itemGroup.isCommons() && !this.canEdit()) { + if (!itemGroup.isTrash() && !itemGroup.isBucket() && !this.canEdit()) { this.displayCannotEditLibraryMessage(); return; } @@ -1383,7 +1383,7 @@ var ZoteroPane = new function() else if (itemGroup.isShare()) { return; } - else if (itemGroup.isCommons()) { + else if (itemGroup.isBucket()) { var prompt = toDelete; } // Do nothing in trash view if any non-deleted items are selected @@ -1465,22 +1465,24 @@ var ZoteroPane = new function() } } - this.refreshCommons = function() { - if (this.collectionsView - && this.collectionsView.selection - && this.collectionsView.selection.count == 1 - && this.collectionsView.selection.currentIndex != -1) { - var itemGroup = this.collectionsView._getItemAtRow(this.collectionsView.selection.currentIndex); - if (itemGroup && itemGroup.isCommons()) { - var self = this; - Zotero.Commons.syncBucketList(function () { - self.itemsView.refresh(); - self.itemsView.sort(); - - // On a manual refresh, also check for new OCRed files - Zotero.Commons.syncFiles(); - }); - } + this.refreshCommonsBucket = function() { + if (!this.collectionsView + || !this.collectionsView.selection + || this.collectionsView.selection.count != 1 + || this.collectionsView.selection.currentIndex == -1) { + return false; + } + + var itemGroup = this.collectionsView._getItemAtRow(this.collectionsView.selection.currentIndex); + if (itemGroup && itemGroup.isBucket()) { + var self = this; + itemGroup.ref.refreshItems(function () { + self.itemsView.refresh(); + self.itemsView.sort(); + + // On a manual refresh, also check for new OCRed files + //Zotero.Commons.syncFiles(); + }); } } @@ -1783,7 +1785,7 @@ var ZoteroPane = new function() exportFile: 9, loadReport: 10, emptyTrash: 11, - refreshCommons: 12 + refreshCommonsBucket: 12 }; var itemGroup = this.collectionsView._getItemAtRow(this.collectionsView.selection.currentIndex); @@ -1854,8 +1856,8 @@ var ZoteroPane = new function() else if (itemGroup.isHeader()) { // Don't show menu for headers } - else if (itemGroup.isCommons()) { - show = [m.refreshCommons]; + else if (itemGroup.isBucket()) { + show = [m.refreshCommonsBucket]; } // Group else if (itemGroup.isGroup()) { @@ -2156,11 +2158,15 @@ var ZoteroPane = new function() // TODO: implement menu for remote items if (!itemGroup.editable) { for (var i in m) { - switch (i) { - case 'exportItems': - case 'createBib': - case 'loadReport': - continue; + // Still show export/bib/report for non-editable views + // (other than Commons buckets, which aren't real items) + if (!itemGroup.isBucket()) { + switch (i) { + case 'exportItems': + case 'createBib': + case 'loadReport': + continue; + } } disable.push(m[i]); var index = enable.indexOf(m[i]); @@ -2273,9 +2279,8 @@ var ZoteroPane = new function() return; } - if (itemGroup.isCommons()) { - // TODO: take to a search of the user's buckets? - //ZoteroPane.loadURI(itemGroup.ref.uri); + if (itemGroup.isBucket()) { + ZoteroPane.loadURI(itemGroup.ref.uri); event.stopPropagation(); } } @@ -2302,9 +2307,9 @@ var ZoteroPane = new function() ZoteroPane.collectionsView.selection.currentIndex ); - if (itemGroup.isCommons()) { - var bucket = Zotero.Commons.getBucketFromItem(item); - ZoteroPane.loadURI(bucket.uri); + if (itemGroup.isBucket()) { + var uri = itemGroup.ref.getItemURI(item); + ZoteroPane.loadURI(uri); event.stopPropagation(); return; } diff --git a/chrome/content/zotero/overlay.xul b/chrome/content/zotero/overlay.xul @@ -107,7 +107,7 @@ <menuitem label="&zotero.toolbar.export.label;" oncommand="Zotero_File_Interface.exportFile()"/> <menuitem oncommand="Zotero_Report_Interface.loadCollectionReport()"/> <menuitem label="&zotero.toolbar.emptyTrash.label;" oncommand="ZoteroPane.emptyTrash();"/> - <menuitem label="Refresh" oncommand="ZoteroPane.refreshCommons();"/><!--TODO localize --> + <menuitem label="Refresh" oncommand="ZoteroPane.refreshCommonsBucket();"/><!--TODO localize --> </popup> <popup id="zotero-itemmenu" onpopupshowing="ZoteroPane.buildItemContextMenu();"> <menuitem label="&zotero.items.menu.showInLibrary;" oncommand="ZoteroPane.selectItem(this.parentNode.getAttribute('itemID'), true)"/> diff --git a/chrome/content/zotero/xpcom/collectionTreeView.js b/chrome/content/zotero/xpcom/collectionTreeView.js @@ -39,7 +39,7 @@ Zotero.CollectionTreeView = function() this._treebox = null; this.itemToSelect = null; this._highlightedRows = {}; - this._unregisterID = Zotero.Notifier.registerObserver(this, ['collection', 'search', 'share', 'group', 'commons']); + this._unregisterID = Zotero.Notifier.registerObserver(this, ['collection', 'search', 'share', 'group', 'bucket']); this.showDuplicates = false; } @@ -149,6 +149,16 @@ Zotero.CollectionTreeView.prototype.setTree = function(treebox) */ Zotero.CollectionTreeView.prototype.refresh = function() { + // Record open states before refreshing + if (this._dataItems) { + for (var i=0, len=this._dataItems.length; i<len; i++) { + var itemGroup = this._dataItems[i][0] + if (itemGroup.ref && itemGroup.ref.id == 'commons-header') { + var commonsExpand = this.isContainerOpen(i); + } + } + } + this.selection.clearSelection(); var oldCount = this.rowCount; this._dataItems = []; @@ -194,7 +204,7 @@ Zotero.CollectionTreeView.prototype.refresh = function() var groups = Zotero.Groups.getAll(); if (groups.length) { - this._showItem(new Zotero.ItemGroup('separator')); + this._showItem(new Zotero.ItemGroup('separator', false)); var header = { id: "group-libraries-header", label: "Group Libraries", // TODO: localize @@ -234,15 +244,33 @@ Zotero.CollectionTreeView.prototype.refresh = function() var shares = Zotero.Zeroconf.instances; if (shares.length) { - this._showItem(new Zotero.ItemGroup('separator')); + this._showItem(new Zotero.ItemGroup('separator', false)); for each(var share in shares) { this._showItem(new Zotero.ItemGroup('share', share)); } } - + if (Zotero.Commons.enabled) { - this._showItem(new Zotero.ItemGroup('separator')); - this._showItem(new Zotero.ItemGroup('commons'), null, null, true); + this._showItem(new Zotero.ItemGroup('separator', false)); + var header = { + id: "commons-header", + label: "Commons", // TODO: localize + expand: function (buckets) { + if (!buckets) { + var buckets = Zotero.Commons.getBuckets(); + } + + for each(var bucket in buckets) { + self._showItem(new Zotero.ItemGroup('bucket', bucket), 1); + } + } + }; + Zotero.debug('============='); + Zotero.debug(commonsExpand); + this._showItem(new Zotero.ItemGroup('header', header), null, null, commonsExpand); + if (commonsExpand) { + header.expand(); + } } this._refreshHashMap(); @@ -263,11 +291,7 @@ Zotero.CollectionTreeView.prototype.reload = function() for (var i=0; i<this.rowCount; i++) { if (this.isContainer(i) && this.isContainerOpen(i)) { - var itemGroup = this._getItemAtRow(i); - if (!itemGroup.isCollection()) { - continue; - } - openCollections.push(itemGroup.ref.id); + openCollections.push(this._getItemAtRow(i).ref.id); } } @@ -376,7 +400,7 @@ Zotero.CollectionTreeView.prototype.notify = function(action, type, ids) this.rememberSelection(savedSelection); } else if (action == 'modify' || action == 'refresh') { - if (type != 'commons') { + if (type != 'bucket') { this.reload(); } this.rememberSelection(savedSelection); @@ -422,8 +446,10 @@ Zotero.CollectionTreeView.prototype.notify = function(action, type, ids) this.rememberSelection(savedSelection); break; - case 'commons': + case 'bucket': this.reload(); + this.rememberSelection(savedSelection); + break; } } @@ -511,15 +537,14 @@ Zotero.CollectionTreeView.prototype.getImageSrc = function(row, col) if (source.ref.id == 'group-libraries-header') { collectionType = 'groups'; } + else if (source.ref.id == 'commons-header') { + collectionType = 'commons'; + } break; case 'group': collectionType = 'library'; break; - - case 'commons': - collectionType = 'commons'; - break; } return "chrome://zotero/skin/treesource-" + collectionType + ".png"; } @@ -527,7 +552,7 @@ Zotero.CollectionTreeView.prototype.getImageSrc = function(row, col) Zotero.CollectionTreeView.prototype.isContainer = function(row) { var itemGroup = this._getItemAtRow(row); - return itemGroup.isLibrary(true) || itemGroup.isCollection() || itemGroup.isHeader() || itemGroup.isCommons(); + return itemGroup.isLibrary(true) || itemGroup.isCollection() || itemGroup.isHeader() || itemGroup.isBucket(); } Zotero.CollectionTreeView.prototype.isContainerOpen = function(row) @@ -547,6 +572,9 @@ Zotero.CollectionTreeView.prototype.isContainerEmpty = function(row) if (itemGroup.isHeader()) { return false; } + if (itemGroup.isBucket()) { + return true; + } if (itemGroup.isGroup()) { return !itemGroup.ref.hasCollections(); } @@ -604,6 +632,8 @@ Zotero.CollectionTreeView.prototype.toggleOpenState = function(row) if (itemGroup.type == 'header') { itemGroup.ref.expand(); } + else if(itemGroup.type == 'bucket') { + } else { if (itemGroup.isLibrary()) { count = itemGroup.ref.expand(); @@ -1048,17 +1078,15 @@ Zotero.CollectionTreeView.prototype.canDrop = function(row, orient, dragData) { var itemGroup = this._getItemAtRow(row); //the collection we are dragging over - if (!itemGroup.editable - // Commons can be dropped on but not edited - && !itemGroup.isCommons()) { + if (dataType == 'zotero/item' && itemGroup.isBucket()) { + return true; + } + + if (!itemGroup.editable) { return false; } if (dataType == 'zotero/item') { - if(itemGroup.isCommons()) { - return true; - } - var ids = data; var items = Zotero.Items.get(ids); var skip = true; @@ -1223,8 +1251,8 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) var targetLibraryID = null; } - if(itemGroup.isCommons()) { - Zotero.Commons.uploadItems(ids); + if(itemGroup.isBucket()) { + itemGroup.ref.uploadItems(ids); return; } @@ -1625,9 +1653,9 @@ Zotero.ItemGroup.prototype.isShare = function() return this.type == 'share'; } -Zotero.ItemGroup.prototype.isCommons = function() +Zotero.ItemGroup.prototype.isBucket = function() { - return this.type == 'commons'; + return this.type == 'bucket'; } Zotero.ItemGroup.prototype.isTrash = function() @@ -1654,7 +1682,7 @@ Zotero.ItemGroup.prototype.isWithinGroup = function () { } Zotero.ItemGroup.prototype.__defineGetter__('editable', function () { - if (this.isTrash() || this.isShare() || this.isCommons()) { + if (this.isTrash() || this.isShare() || this.isBucket()) { return false; } if (!this.isWithinGroup()) { @@ -1713,6 +1741,9 @@ Zotero.ItemGroup.prototype.getName = function() case 'share': return this.ref.name; + + case 'bucket': + return this.ref.name; case 'trash': return Zotero.getString('pane.collections.trash'); @@ -1723,9 +1754,6 @@ Zotero.ItemGroup.prototype.getName = function() case 'header': return this.ref.label; - case 'commons': - return "Commons"; - default: return ""; } @@ -1738,8 +1766,8 @@ Zotero.ItemGroup.prototype.getChildItems = function() case 'share': return this.ref.getAll(); - case 'commons': - return Zotero.Commons.getItems(); + case 'bucket': + return this.ref.getItems(); case 'header': return []; @@ -1852,7 +1880,7 @@ Zotero.ItemGroup.prototype.getChildTags = function() { case 'share': return false; - case 'commons': + case 'bucket': return false; case 'header': diff --git a/chrome/content/zotero/xpcom/commons.js b/chrome/content/zotero/xpcom/commons.js @@ -45,6 +45,109 @@ Zotero.Commons = new function() { return Zotero.Prefs.get("commons.secretKey"); }); + this.getBuckets = function (callback) { + if (!this.enabled) { + return _buckets; + } + + var accessKey = this.accessKey; + var secretKey = this.secretKey; + + if (_bucketsLoaded) { + return _buckets; + } + + if (_bucketsLoading) { + Zotero.debug("Already loading buckets"); + return _buckets; + } + + _bucketsLoading = true; + + var syncCallback = function (req) { + // Error + if (req.status != 200) { + Zotero.debug(req.status); + Zotero.debug(req.responseText); + + if (req.status == 503) { + alert("Unable to retrieve bucket list from the Internet Archive: server unavailable."); + } + else { + alert("Unable to retrieve bucket list from the Internet Archive: server error " + req.status); + } + + _bucketsLoading = false; + + return; + } + + Zotero.debug(req.responseText); + + var currentBuckets = []; + var IABuckets = []; + + for (var name in _buckets) { + currentBuckets.push(name); + } + currentBuckets.sort(); + + Zotero.debug('=========='); + Zotero.debug("CURRENT BUCKETS"); + Zotero.debug(currentBuckets); + + + var buckets = req.responseXML.getElementsByTagName("Bucket"); + for (var i=0, len=buckets.length; i<len; i++) { + var bucketName = buckets[i].getElementsByTagName('Name')[0].textContent; + IABuckets.push(bucketName); + } + IABuckets.sort(); + + Zotero.debug("IA BUCKETS"); + Zotero.debug(IABuckets); + + var addBuckets = Zotero.Utilities.prototype.arrayDiff(IABuckets, currentBuckets); + var removeBuckets = Zotero.Utilities.prototype.arrayDiff(currentBuckets, IABuckets); + + Zotero.debug("ADD"); + Zotero.debug(addBuckets); + Zotero.debug("REMOVE"); + Zotero.debug(removeBuckets); + + for each(var name in removeBuckets) { + delete _buckets[name]; + } + + var ids = []; + var refresh = false; + for each(var name in addBuckets) { + refresh = true; + var bucket = new Zotero.Commons.Bucket(name); + _buckets[name] = bucket; + ids.push(bucket.id); + } + + _bucketsLoading = false; + _bucketsLoaded = true; + + // refresh left pane if local bucket list changed + if (refresh) { + Zotero.Notifier.trigger('add', 'bucket', ids); + } + + if (callback) { + callback(); + } + }; + + var req = this.createAuthenticatedRequest( + "GET", "/", {}, accessKey, secretKey, syncCallback, null, false, true + ); + + return _buckets; + }; + this.RDF_TRANSLATOR = { 'label': 'Zotero RDF', 'target': 'rdf', @@ -65,14 +168,15 @@ Zotero.Commons = new function() { var _buckets = {}; var _bucketsLoading = false; + var _bucketsLoaded = false; var _requestingItems = false; this.createBucket = function (item, onBucketQueued, onBucketCreated, waitForCreation) { var headers = { "x-archive-auto-make-bucket":"1", - "x-archive-meta01-collection":"scholarworkspaces", - "x-archive-meta02-collection":"zoterocommons", + "x-archive-meta01-collection":"zoterocommons", + "x-archive-meta02-collection":"scholarworkspaces", "x-archive-meta-sponsor":"Andrew W. Mellon Foundation", "x-archive-meta01-language":"eng" }; @@ -118,10 +222,6 @@ Zotero.Commons = new function() { if (waitForCreation) { Zotero.debug('Waiting for bucket creation'); - - Zotero.debug('-------'); - Zotero.debug(setTimeout); - setTimeout(function () { var tries = 15; bucket.exists(function (found) { @@ -190,94 +290,6 @@ Zotero.Commons = new function() { } - this.syncBucketList = function (callback) { - var accessKey = Zotero.Prefs.get("commons.accessKey"); - var secretKey = Zotero.Prefs.get("commons.secretKey"); - - if (_bucketsLoading) { - Zotero.debug("Already loading buckets"); - return; - } - - _bucketsLoading = true; - - var syncCallback = function (req) { - // Error - if (req.status != 200) { - Zotero.debug(req.status); - Zotero.debug(req.responseText); - - if (req.status == 503) { - alert("Unable to retrieve items list from the Internet Archive: server unavailable."); - } - else { - alert("Unable to retrieve items list from the Internet Archive: server error " + req.status); - } - - _bucketsLoading = false; - - return; - } - - Zotero.debug(req.responseText); - - var currentBuckets = []; - var IABuckets = []; - - for (var name in _buckets) { - currentBuckets.push(name); - } - currentBuckets.sort(); - - Zotero.debug('=========='); - Zotero.debug("CURRENT BUCKETS"); - Zotero.debug(currentBuckets); - - - var buckets = req.responseXML.getElementsByTagName("Bucket"); - for (var i=0, len=buckets.length; i<len; i++) { - var bucketName = buckets[i].getElementsByTagName('Name')[0].textContent; - IABuckets.push(bucketName); - } - IABuckets.sort(); - - Zotero.debug("IA BUCKETS"); - Zotero.debug(IABuckets); - - var addBuckets = Zotero.Utilities.prototype.arrayDiff(IABuckets, currentBuckets); - var removeBuckets = Zotero.Utilities.prototype.arrayDiff(currentBuckets, IABuckets); - - Zotero.debug("ADD"); - Zotero.debug(addBuckets); - Zotero.debug("REMOVE"); - Zotero.debug(removeBuckets); - - for each(var name in removeBuckets) { - delete _buckets[name]; - } - - for each(var name in addBuckets) { - _buckets[name] = new Zotero.Commons.Bucket(name); - } - - // refresh left pane if local bucket list changed - //if(prefChanged) { - //Zotero.Notifier.trigger('add', 'bucket', true); - //} - - _bucketsLoading = false; - - if (callback) { - callback(); - } - }; - - var req = this.createAuthenticatedRequest( - "GET", "/", {}, accessKey, secretKey, syncCallback, null, false, true - ); - } - - this.getNewBucketName = function () { return "zc-" + this.accessKey + "-" + Zotero.ID.getBigInt(9999999999); } @@ -296,66 +308,6 @@ Zotero.Commons = new function() { } return false; } - - - /** - * Return an array of items belonging to this user - */ - this.getItems = function() { - Zotero.debug('========'); - Zotero.debug('calling getItems()'); - - if (!this.refreshNeeded) { - Zotero.debug("Commons: Buckets already loaded. Returing existing item set"); - return _getItemsFromBuckets(); - } - - if (_requestingItems) { - Zotero.debug("Commons: Already requesting items in Zotero.Commons.getItem()", 2); - return; - } - - _requestingItems = true; - - // First update the list of buckets - var req = this.syncBucketList(function () { - Zotero.Commons.refreshNeeded = false; - Zotero.Notifier.trigger('refresh', 'commons', []); - _requestingItems = false; - }); - - // Browser offline - if (!req) { - _requestingItems = false; - } - - // List isn't yet available - return []; - } - - - this.syncFiles = function () { - if (Zotero.Commons.refreshNeeded) { - throw ("Buckets must be loaded before syncing files in Zotero.Commons.syncFiles()"); - } - - Zotero.debug("Getting updated files from all buckets"); - - var progressWin = null; - var icon = 'chrome://zotero/skin/treeitem-attachment-pdf.png'; - - for each(var bucket in _buckets) { - bucket.syncFiles(function (attachment) { - if (!progressWin) { - progressWin = new Zotero.ProgressWindow(); - progressWin.changeHeadline("Downloading OCRed PDFs"); // TODO: localize - } - progressWin.addLines([attachment.getField('title')], [icon]); - progressWin.show(); - progressWin.startCloseTimer(8000); - }); - } - } this.uploadItems = function (ids) { @@ -421,113 +373,16 @@ Zotero.Commons = new function() { // TODO: check relations table to see if this item already has a bucket // TODO: localize - progressWin.changeHeadline("Uploading items to IA"); + progressWin.changeHeadline("Uploading Items to IA"); progressWin.addLines([item.getField('title')], [item.getImageSrc()]); progressWin.show(); - Zotero.Commons.createBucket( - item, - // onBucketQueued - function () { - // Start next item while waiting for bucket creation - process(items); - }, - // onBucketCreated - function (bucket) { - // Link item to new bucket - var url1 = Zotero.URI.getItemURI(item); - var predicate = bucket.relationPredicate; - var url2 = bucket.uri; - Zotero.Relations.add(null, url1, predicate, url2); - - // - // Export item and attachments to RDF and files - // - - var key = Zotero.ID.getKey(); - - var outputDir = Zotero.getTempDirectory(); - // TEMP - //outputDir.append(bucket.name); - outputDir.append(key); - - var translation = new Zotero.Translate("export"); - translation.setItems([item]); - translation.setTranslator(Zotero.Commons.RDF_TRANSLATOR.translatorID); - translation.setDisplayOptions(Zotero.Commons.RDF_TRANSLATOR.displayOptions); - translation.setHandler("done", function (translation, success) { - if (!success) { - alert("Commons: Translation failed for " + translation); - return; - } - - try { - // Upload RDF file - var rdfFile = outputDir.clone(); - // TEMP - //rdfFile.append(bucket.name + ".rdf"); - rdfFile.append(key + ".rdf"); - rdfFile.moveTo(null, bucket.name + ".rdf"); - bucket.putFile(rdfFile, "application/rdf+xml", function (uri) { - // TEMP - rdfFile.moveTo(null, key + ".rdf"); - - // Then create ZIP file from item - var zipFile = Zotero.getTempDirectory(); - // TEMP - //zipFile.append(outputDir.leafName + '.zip'); - zipFile.append(key + '.zip'); - - var zw = Components.classes["@mozilla.org/zipwriter;1"] - .createInstance(Components.interfaces.nsIZipWriter); - zw.open(zipFile, 0x04 | 0x08 | 0x20); // open rw, create, truncate - - bucket.zipDirectory(outputDir, outputDir, zw); - - // Upload file after zipping - var observer = new Zotero.Commons.ZipWriterObserver(zw, function () { - bucket.putFile(zipFile, "application/zip", function (uri) { - // TODO: localize - Zotero.debug('-=-=-=-=-='); - Zotero.debug(items.length); - if (!items.length) { - progressWin.startCloseTimer(5000); - } - - Zotero.Commons.refreshNeeded = true; - }); - }); - zw.processQueue(observer, null); - }); - } - catch (e) { - alert("Zotero Commons upload failed:\n\n" + e); - } - }); - translation.setLocation(outputDir); - translation.translate(); // synchronous - }, - true - ); } process(items); } - this.deleteItems = function (ids) { - Zotero.debug("Unimplemented"); - return; - - // TODO: Confirm - - for each(var id in ids) { - var bucket = this.getBucketFromItemID(id); - bucket.erase(); - } - } - - this.createAuthenticatedRequest = function (method, resource, headers, accessKey, secretKey, callback, data, sendAsBinary, noCache) { var url = Zotero.Commons.apiUrl + resource; @@ -603,19 +458,32 @@ Zotero.Commons = new function() { } + // Recursively add files and directories to zipWriter + this.zipDirectory = function (rootDir, dir, zipWriter) { + dir = dir.directoryEntries; + while(dir.hasMoreElements()) { + var file = dir.getNext(); + file.QueryInterface(Components.interfaces.nsILocalFile); + + var fileName = file.getRelativeDescriptor(rootDir); + if(fileName.indexOf('.') == 0) { + Zotero.debug('Skipping file ' + fileName); + continue; + } - function _getItemsFromBuckets() { - var items = []; - for (var name in _buckets) { - Zotero.debug('getting bucket ' + name); - var item = _buckets[name].item; - // Only return available items - if (item) { - Zotero.debug('found'); - items.push(item); + // addEntryFile works for both files and directories + zipWriter.addEntryFile( + fileName, + Components.interfaces.nsIZipWriter.COMPRESSION_DEFAULT, + file, + true + ); + + if (file.isDirectory()) { + Zotero.Commons.zipDirectory(rootDir, file, zipWriter); + continue; } } - return items; } @@ -680,6 +548,7 @@ Zotero.Commons = new function() { Zotero.Commons.Bucket = function (name) { + this.id = Zotero.ID.getBigInt(); // assign a random ID to the bucket for this session this.name = name; this.accessKey = Zotero.Prefs.get("commons.accessKey"); this.secretKey = Zotero.Prefs.get("commons.secretKey"); @@ -687,37 +556,16 @@ Zotero.Commons.Bucket = function (name) { this._requestingItems = false; this._needRefresh = false; - this._item = null; + this._items = {}; + this._itemsLoading = false; + this._itemsLoaded = false; + this._metadataLoading = false; this._itemDataLoaded = false; this._itemDataLoading = false; } -Zotero.Commons.Bucket.prototype.__defineGetter__('item', function () { - Zotero.debug("REQUESTING ITEM FOR " + this.name); - - if (this._item) { - Zotero.debug("RETURNING"); - return this._item; - } - -/* var item = new Zotero.Item('document'); - item.setField('title', this.name); - return item; -*/ - - Zotero.debug("LOADING"); - - this._loadMetadata(function () { - Zotero.debug("LOADED"); - Zotero.Notifier.trigger('refresh', 'commons', []); - }); - - return false; -}); - - Zotero.Commons.Bucket.prototype.__defineGetter__('uri', function () { return 'http://www.archive.org/details/' + this.name; }); @@ -734,10 +582,6 @@ Zotero.Commons.Bucket.prototype.__defineGetter__('apiURI', function() { return Zotero.Commons.apiUrl + '/' + this.name; }); -Zotero.Commons.Bucket.prototype.__defineGetter__('rdfURI', function() { - return Zotero.Commons.apiUrl + '/' + this.name + '/' + this.name + '.rdf'; -}); - Zotero.Commons.Bucket.prototype.relationPredicate = "owl:sameAs"; @@ -768,9 +612,6 @@ Zotero.Commons.Bucket.prototype.exists = function (callback, maxTries, tries) { var seconds = delay / 1000; Zotero.debug("Bucket " + self.name + " doesn't yet exist -- retrying in " + seconds + " seconds"); - Zotero.debug('---------'); - Zotero.debug(setTimeout); - setTimeout(function () { self.exists(callback, maxTries, tries); }, delay); @@ -786,25 +627,262 @@ Zotero.Commons.Bucket.prototype.exists = function (callback, maxTries, tries) { } -/** - * Get OCRed PDFs from files in this bucket - * - * @param {Function} callback Function to run after adding each file -- - * function is passed the new attachment item - * (which due to a Zotero.Attachments.importFromURL() - * limitation will still be downloading) - */ -Zotero.Commons.Bucket.prototype.syncFiles = function (callback) { - // Find local item if it exists - var rels = Zotero.Relations.getByURIs(null, this.relationPredicate, this.uri); - if (!rels.length) { - Zotero.debug("No local items linked to URI " + this.uri); - return; +Zotero.Commons.Bucket.prototype.getItems = function (callback) { + if (this._itemsLoaded || this._itemsLoading) { + return this._getCachedItems(); } - if (rels.length > 1) { - throw ("Commons: More than one local item linked to remote bucket " + this.name); - } - var item = Zotero.URI.getURIItem(rels[0].subject); + + this._itemsLoading = true; + + var method = "GET"; + var uri = this.downloadURI + "/" + this.name + "_files.xml"; + + var self = this; + var progressWin = null; + var progressWinIcon = 'chrome://zotero/skin/treeitem-attachment-pdf.png'; + + var req = Zotero.Utilities.HTTP.doGet(uri, function (xmlhttp) { + if (xmlhttp.status != 200) { + Zotero.debug(xmlhttp.status); + Zotero.debug(xmlhttp.responseText); + alert("Error loading data from the Internet Archive"); + self._itemsLoading = false; + return; + } + + Zotero.debug(xmlhttp.responseText); + + try { + // Strip XML declaration and convert to E4X + var xml = new XML(xmlhttp.responseText.replace(/<\?xml.*\?>/, '')); + } + catch (e) { + alert("Invalid response retrieving file upload parameters"); + return; + } + + var zipsXML = xml.file.(@source == 'original').(format == 'Zotero ZIP Item'); + + Zotero.debug(zipsXML); + + var zips = []; + + // Generate a list of extracted PDFs with OCRed equivalents + var ocrOriginals = {}; + var ocrPDFXML = xml.file.(@source == 'derivative').(format == 'Additional Text PDF').@name; + for each(var pdf in ocrPDFXML) { + var fn = pdf.toString().replace(/_text\.pdf$/, '.pdf'); + ocrOriginals[fn] = true; + } + + for each(var zipXML in zipsXML) { + var key = zipXML.@name.toString(); + var title = zipXML.title.toString(); + + var childrenXML = xml.file.(typeof zipsource != 'undefined').(zipsource == key).(format != 'Zotero RDF'); + var children = []; + for each(var childXML in childrenXML) { + var childKey = childXML.@name.toString(); + children.push({ + key: childKey, + title: childXML.title.toString(), + ocr: ocrOriginals[childKey] ? true : false + }); + } + +/* + // See if we already have this item + if (self._items[key]) { + continue; + } +*/ + zips.push({ + key: key, + title: title, + children: children + }); + } + + self._itemsLoading = false; + self._itemsLoaded = true; + + Zotero.debug(zips); + + Zotero.Notifier.trigger('refresh', 'bucket', self.id); + + // Get RDF for new items, pulling off a stack + var process = function (zips) { + if (!zips.length) { + Zotero.debug("Commons: No more ZIPs to process"); + + if (callback) { + callback(); + } + + return; + } + + let zip = zips.shift(); + + // See if we already have this item + if (self._items[zip.key]) { + process(zips); + return; + } + + var rdfURI = self.downloadURI + '/' + zip.key; + rdfURI = rdfURI.replace(/\.zip$/, "_zotero.rdf"); + + Zotero.Utilities.HTTP.doGet(rdfURI, function (xmlhttp) { + // If RDF not available, skip item + if (xmlhttp.status != 200) { + Zotero.debug("RDF not found at " + xmlhttp.channel.originalURI.spec); + process(zips); + return; + } + + Zotero.debug(xmlhttp.responseText); + + var translate = new Zotero.Translate("import"); + translate.setString(xmlhttp.responseText); + translate.getTranslators() + translate.setTranslator(Zotero.Commons.RDF_IMPORT_TRANSLATOR.translatorID); + translate.setHandler("itemDone", function (translation, item) { + var typeID = Zotero.ItemTypes.getID(item.itemType); + var newItem = new Zotero.Item(typeID); + newItem.id = Zotero.ID.getBigInt(); + + // Add item data to virtual item + for (var field in item) { + // Skip empty fields + if (!item[field]) { + continue; + } + var fieldID = Zotero.ItemFields.getID(field); + if (!fieldID) { + continue; + } + + try { + newItem.setField(fieldID, item[field]); + } + catch (e) { + Zotero.debug(e); + } + } + + // Add creators to virtual item + for (var i=0; i<item.creators.length; i++) { + try { + var creator = new Zotero.Creator; + creator.setFields(item.creators[i]); + newItem.setCreator(i, creator, item.creators[i].creatorType); + } + catch (e) { + Zotero.debug(e); + } + } + + self._items[zip.key] = newItem; + + Zotero.Notifier.trigger('refresh', 'bucket', self.id); + + // If item exists locally, check for OCRed attachments + var localItem = self.getLocalItem(newItem); + if (localItem) { + for each(var child in zip.children) { + if (!child.ocr) { + continue; + } + + var iaFileName = child.key.replace(/\.pdf$/, '_text.pdf'); + var iaFileURI = self.downloadURI + '/' + iaFileName; + + var rels = Zotero.Relations.getByURIs(null, self.relationPredicate, iaFileURI); + if (rels.length) { + Zotero.debug("Commons: " + IAFileName + " has already been downloaded -- skipping"); + continue; + } + + Zotero.debug("Downloading OCRed PDF " + iaFileName); + + var title = Zotero.localeJoin([child.title, '(OCR)']); + var baseName = child.key; + + if (!progressWin) { + progressWin = new Zotero.ProgressWindow(); + progressWin.changeHeadline("Downloading OCRed PDFs"); // TODO: localize + } + progressWin.addLines([child.title], [progressWinIcon]); + progressWin.show(); + progressWin.startCloseTimer(8000); + + var newAttachment = Zotero.Attachments.importFromURL( + iaFileURI, localItem.id, title, baseName, null, 'application/pdf' + ); + if (!(newAttachment instanceof Zotero.Item)) { + throw (newAttachment + " is not a Zotero.Item in Zotero.Commons.Bucket.getItems()"); + } + + // Add a relation linking the new attachment to the IA file + var uri = Zotero.URI.getItemURI(newAttachment); + Zotero.Relations.add(null, uri, self.relationPredicate, iaFileURI); + } + } + + process(zips); + }); + translate.translate(false, false); + }); + } + + process(zips); + }); + + // Browser offline + if (!req) { + this._itemsLoading = false; + } + + // List isn't yet available + return this._getCachedItems(); +} + + +Zotero.Commons.Bucket.prototype.refreshItems = function (callback) { + if (this._itemsLoading) { + Zotero.debug("Items already loading in Zotero.Commons.Bucket.refreshItems()", 2); + if (callback) { + callback() + } + return; + } + + Zotero.debug("Loading items for bucket '" + this.name + "'"); + this._itemsLoaded = false; + this.getItems(callback); +} + + +/** + * Get OCRed PDFs from files in this bucket + * + * @param {Function} callback Function to run after adding each file -- + * function is passed the new attachment item + * (which due to a Zotero.Attachments.importFromURL() + * limitation will still be downloading) + */ +Zotero.Commons.Bucket.prototype.syncFiles = function (callback) { + // Find local item if it exists + var rels = Zotero.Relations.getByURIs(null, this.relationPredicate, this.uri); + if (!rels.length) { + Zotero.debug("No local items linked to URI " + this.uri); + return; + } + if (rels.length > 1) { + throw ("Commons: More than one local item linked to remote bucket " + this.name); + } + var item = Zotero.URI.getURIItem(rels[0].subject); if (!item) { Zotero.debug("Linked local item not found for URI " + this.uri, 2); return; @@ -905,46 +983,233 @@ Zotero.Commons.Bucket.prototype.syncFiles = function (callback) { } -// deletes selected items from IA. -Zotero.Commons.Bucket.prototype.erase = function () { - var method = "DELETE"; - var headers = { - "x-archive-cascade-delete":"1" - }; +Zotero.Commons.Bucket.prototype.uploadItems = function (ids) { + var items = Zotero.Items.get(ids); + if (!items) { + Zotero.debug("No items to upload"); + return; + } - var resource = '/' + this.name; + var itemsToUpload = false; + for (var i=0, len=items.length; i<len; i++) { + if (items[i].isRegularItem()) { + itemsToUpload = true; + break; + } + } + + var pr = Components.classes["@mozilla.org/network/default-prompt;1"] + .getService(Components.interfaces.nsIPrompt); + + if (!itemsToUpload) { + Zotero.debug("No regular items to upload"); + pr.alert("", "Only items with bibliographic metadata can be added to the Zotero Commons."); + return; + } + + var buttonFlags = (pr.BUTTON_POS_0) * (pr.BUTTON_TITLE_IS_STRING) + + (pr.BUTTON_POS_1) * (pr.BUTTON_TITLE_CANCEL); + var index = pr.confirmEx( + "Zotero Commons Upload", + "By uploading items to Zotero Commons you agree to the terms of use at zotero.org and archive.org. " + + "Please make sure metadata for your item(s) is set properly." + + "\n\n " + + "Continue to upload items to the Internet Archive?", + buttonFlags, + "Upload", + null, null, null, {} + ); + + // if user chooses 'cancel', exit + if (index != 0) return; + + var progressWin = new Zotero.ProgressWindow(); + var tmpDir = Zotero.getTempDirectory(); var self = this; - // Delete IA bucket - var callback = function (req) { - if (req.status == 204) { - Zotero.debug("Commons: " + resource + " was deleted successfully."); - this._needRefresh = true; - Zotero.Notifier.trigger('refresh', 'bucket', ids); - - //respecify metadata - self.updateMetadata(item.key,"delete",null); + // Upload items one at a time, pulling items off a stack + var process = function (items) { + if (!items.length) { + Zotero.debug("Commons: No more items to upload"); + return; } - else { - Zotero.debug(req.status); - Zotero.debug(req.responseText); - - if (req.status == 403) { - alert("Failed to delete " + resource + " at IA: authentication failed."); - } - else if (req.status == 503) { - alert("Failed to delete " + resource + " at IA: server unavailable."); - } - else { - alert("Failed to delete " + resource + " at IA."); - Zotero.debug("Commons: delete failed with status code: " + req.status); + + let item = items.shift(); + + // Skip notes and attachments + if (!item.isRegularItem()) { + process(items); + return; + } + + // TODO: check relations table to see if this item already has a bucket + + // TODO: localize + progressWin.changeHeadline("Uploading Items to IA"); + progressWin.addLines([item.getField('title')], [item.getImageSrc()]); + progressWin.show(); + + self.uploadItem( + item, + function () { + Zotero.debug(items.length); + if (items.length) { + // Process next item + process(items); + } + else { + progressWin.startCloseTimer(5000); + } } + ); + } + + process(items); +} + + +/** + * Export item and attachments to RDF and files and upload to IA + */ +Zotero.Commons.Bucket.prototype.uploadItem = function (item, callback) { + var key = item.key; + + var outputDir = Zotero.getTempDirectory(); + outputDir.append(key); + + var bucket = this; + + var translation = new Zotero.Translate("export"); + translation.setItems([item]); + translation.setTranslator(Zotero.Commons.RDF_TRANSLATOR.translatorID); + translation.setDisplayOptions(Zotero.Commons.RDF_TRANSLATOR.displayOptions); + translation.setHandler("done", function (translation, success) { + if (!success) { + alert("Commons: Translation failed for " + translation); + return; } + + try { + // Rename RDF file + var rdfFile = outputDir.clone(); + rdfFile.append(key + ".rdf"); + rdfFile.moveTo(null, "zotero.rdf"); + + // Then create ZIP file from item + var zipFile = Zotero.getTempDirectory(); + zipFile.append(item.getField('title') + '-' + key + '.zip'); + + var zw = Components.classes["@mozilla.org/zipwriter;1"] + .createInstance(Components.interfaces.nsIZipWriter); + zw.open(zipFile, 0x04 | 0x08 | 0x20); // open rw, create, truncate + + Zotero.Commons.zipDirectory(outputDir, outputDir, zw); + + // Upload file after zipping + var observer = new Zotero.Commons.ZipWriterObserver(zw, function () { + bucket.putFile(zipFile, "application/zip", function (uri) { + // Link item to new bucket + var url1 = Zotero.URI.getItemURI(item); + var predicate = bucket.relationPredicate; + var url2 = bucket.getItemURI(item); + + // TEMP? + if (Zotero.Relations.getByURIs(url1, predicate, url2).length == 0) { + Zotero.Relations.add(null, url1, predicate, url2); + } + + if (callback) { + callback(); + } + }); + }); + zw.processQueue(observer, null); + } + catch (e) { + alert("Zotero Commons upload failed:\n\n" + e); + } + }); + translation.setLocation(outputDir); + translation.translate(); // synchronous +} + + +/** + * Delete selected items from IA + */ +Zotero.Commons.Bucket.prototype.deleteItems = function (ids) { + var ids = Zotero.flattenArguments(ids); + + // Get the ZIP filenames from the ids + var keysToDelete = []; + for each(var id in ids) { + var key = this._getIAKeyByItemID(id); + if (key) { + keysToDelete.push(key); + } + } + + if (!keysToDelete.length) { + Zotero.debug("No items to delete"); + return; + } + + var method = "DELETE"; + // Delete extracted files as well + var headers = { + "x-archive-cascade-delete":"1" }; - Zotero.Commons.createAuthenticatedRequest( - method, resource, headers, self.accessKey, self.secretKey, callback - ); + var resource = '/' + this.name; + var bucket = this; + + for each(let key in keysToDelete) { + let path = resource + '/' + key; + + Zotero.Commons.createAuthenticatedRequest( + method, path, headers, this.accessKey, this.secretKey, function (req) { + if (req.status == 204) { + Zotero.debug('---=---------'); + if (!bucket._items[key]) { + Zotero.debug('NO ITEM!'); + Zotero.debug(key); + Zotero.debug(bucket._items); + } + + + // Delete any relations linked to the IA item + var uri = bucket.getItemURI(bucket._items[key]); + var relations = Zotero.Relations.getByURIs( + null, bucket.relationPredicate, uri + ); + if (relations) { + for each(var relation in relations) { + relation.erase(); + } + } + + delete bucket._items[key]; + + Zotero.debug("Commons: " + path + " was deleted successfully."); + Zotero.Notifier.trigger('refresh', 'bucket', bucket.id); + } + else { + Zotero.debug(req.status); + Zotero.debug(req.responseText); + + if (req.status == 403) { + alert("Failed to delete " + path + " at IA: authentication failed."); + } + else if (req.status == 503) { + alert("Failed to delete " + path + " at IA: server unavailable."); + } + else { + alert("Failed to delete " + path + " at IA."); + Zotero.debug("Commons: delete failed with status code: " + req.status); + } + } + }); + } } @@ -956,8 +1221,8 @@ Zotero.Commons.Bucket.prototype.updateMetadata = function(action, item, callback var headers = { "x-archive-ignore-preexisting-bucket":"1", - "x-archive-meta01-collection":"scholarworkspaces", - "x-archive-meta02-collection":"zoterocommons", + "x-archive-meta01-collection":"zoterocommons", + "x-archive-meta02-collection":"scholarworkspaces", "x-archive-meta-mediatype":"texts", "x-archive-meta-sponsor":"Andrew W. Mellon Foundation" }; @@ -1034,23 +1299,11 @@ Zotero.Commons.Bucket.prototype.putFile = function (file, mimeType, callback) { var self = this; var putCallback = function (req) { + Zotero.debug(req.responseText); + // Success if (req.status == 201) { - /*for (var i = 0, len = data.items.length; i < len; i++) { - var url1 = Zotero.URI.getItemURI(data.items[i]); - var predicate = self.relationPredicate; - var url2 = self.getKeyUrl(self.name, keyHyphened); - - if (Zotero.Relations.getByURIs(url1, predicate, url2).length - || Zotero.Relations.getByURIs(url2, predicate, url1).length) { - Zotero.debug(url1 + " and " + url2 + " are already linked"); - continue; - } - Zotero.Relations.add(null, url1, predicate, url2); - }*/ - Zotero.debug("Commons: " + fileName + " was uploaded successfully."); - //this._needRefresh = true; - //Zotero.Notifier.trigger('refresh', 'bucket', null); + Zotero.debug("Commons: " + fileNameHyphened + " was uploaded successfully."); if (callback) { callback(req.channel.URI.spec); @@ -1082,112 +1335,45 @@ Zotero.Commons.Bucket.prototype.putFile = function (file, mimeType, callback) { } -// Recursively add files and directories to zipWriter -Zotero.Commons.Bucket.prototype.zipDirectory = function(rootDir, dir, zipWriter) { - dir = dir.directoryEntries; - while(dir.hasMoreElements()) { - var file = dir.getNext(); - file.QueryInterface(Components.interfaces.nsILocalFile); +Zotero.Commons.Bucket.prototype.getItemURI = function (item) { + return this.uri + '#' + encodeURIComponent(item.getField('title')); +} - var fileName = file.getRelativeDescriptor(rootDir); - if(fileName.indexOf('.') == 0) { - Zotero.debug('Skipping file ' + fileName); - continue; - } - // addEntryFile works for both files and directories - zipWriter.addEntryFile( - fileName, - Components.interfaces.nsIZipWriter.COMPRESSION_DEFAULT, - file, - true - ); - - if(file.isDirectory()) { - this.zipDirectory(rootDir, file, zipWriter); - continue; - } +Zotero.Commons.Bucket.prototype.getLocalItem = function (item) { + var uri = this.getItemURI(item); + var rels = Zotero.Relations.getByURIs(null, this.relationPredicate, uri); + + if (rels.length > 1) { + throw ("Commons: More than one local item linked to remote item " + uri); + } + + var item = Zotero.URI.getURIItem(rels[0].subject); + if (!item) { + Zotero.debug("Linked local item not found for URI " + this.uri, 2); + return false; } + + return item; } -Zotero.Commons.Bucket.prototype._loadMetadata = function (callback) { - if (this._metadataLoading) { - return; +Zotero.Commons.Bucket.prototype._getCachedItems = function () { + var items = []; + for each(var item in this._items) { + items.push(item); } - - this._metadataLoading = true; - var self = this; - - Zotero.Utilities.HTTP.doGet(this.rdfURI, function (xmlhttp) { - // If RDF not available, use the bucket metadata - if (xmlhttp.status != 200) { - Zotero.debug("RDF for bucket " + self.name + " not available"); - - /*Zotero.Utilities.HTTP.doGet(self.metadataURI, function (xmlhttp) { - if (xmlhttp.status != 200) { - Zotero.debug(xmlhttp.status); - Zotero.debug(xmlhttp.responseText); - return; - } - - Zotero.debug(xmlhttp.responseText); - - // Strip XML declaration and convert to E4X - var xml = new XML(xmlhttp.responseText.replace(/<\?xml.*\?>/, '')); - var title = xml.title; - if (!self._item) { - self._item = new Zotero.Item("document"); - self._item.id = Zotero.ID.getBigInt(); - } - self._item.setField('title', title); - - self._metadataLoading = false; - - if (callback) { - callback(); - } - });*/ - return; + return items; +} + + +Zotero.Commons.Bucket.prototype._getIAKeyByItemID = function (id) { + for (var key in this._items) { + if (this._items[key].id == id) { + return key; } - - Zotero.debug(xmlhttp.responseText); - - var translate = new Zotero.Translate("import"); - translate.setString(xmlhttp.responseText); - translate.getTranslators() - translate.setTranslator(Zotero.Commons.RDF_IMPORT_TRANSLATOR.translatorID); - translate.setHandler("itemDone", function (translation, item) { - var typeID = Zotero.ItemTypes.getID(item.itemType); - var newItem = new Zotero.Item(typeID); - newItem.id = Zotero.ID.getBigInt(); - - for (var field in item) { - // Skip empty fields - if (!item[field]) { - continue; - } - var fieldID = Zotero.ItemFields.getID(field); - if (!fieldID) { - continue; - } - Zotero.debug('setting field ' + fieldID + ' to ' + item[field]); - try { - newItem.setField(fieldID, item[field]); - } - catch(e) { Zotero.debug(e); } - } - - self._item = newItem; - self._metadataLoading = false; - - if (callback) { - callback(); - } - return; - }); - translate.translate(false, false); - }); + } + return false; } diff --git a/chrome/content/zotero/xpcom/itemTreeView.js b/chrome/content/zotero/xpcom/itemTreeView.js @@ -52,7 +52,7 @@ Zotero.ItemTreeView = function(itemGroup, sourcesOnly) this._dataItems = []; this.rowCount = 0; - this._unregisterID = Zotero.Notifier.registerObserver(this, ['item', 'collection-item', 'share-items', 'commons']); + this._unregisterID = Zotero.Notifier.registerObserver(this, ['item', 'collection-item', 'share-items', 'bucket']); } @@ -260,7 +260,6 @@ Zotero.ItemTreeView.prototype.refresh = function() */ Zotero.ItemTreeView.prototype.notify = function(action, type, ids, extraData) { - Zotero.debug('============='); if (!this._treebox || !this._treebox.treeBody) { Components.utils.reportError("Treebox didn't exist in itemTreeView.notify()"); return; @@ -270,7 +269,7 @@ Zotero.ItemTreeView.prototype.notify = function(action, type, ids, extraData) Zotero.debug("Item row map didn't exist in itemTreeView.notify()"); return; } - Zotero.debug(1); + var itemGroup = this._itemGroup; var madeChanges = false; @@ -285,10 +284,9 @@ Zotero.ItemTreeView.prototype.notify = function(action, type, ids, extraData) this.refresh(); } } - else if (type == 'commons') { - if (itemGroup.isCommons()) { + else if (type == 'bucket') { + if (itemGroup.isBucket()) { this.refresh(); - this.sort(); } } else if (savedSelection.length == 1 && savedSelection[0] == ids[0]) { @@ -457,7 +455,6 @@ Zotero.ItemTreeView.prototype.notify = function(action, type, ids, extraData) } else if(action == 'add') { - Zotero.debug(2); // If saved search or trash, just re-run search if (itemGroup.isSearch() || itemGroup.isTrash()) { this.refresh(); @@ -502,7 +499,6 @@ Zotero.ItemTreeView.prototype.notify = function(action, type, ids, extraData) if(madeChanges) { - Zotero.debug(3); // If adding and this is the active window, select the item if(action == 'add' && ids.length===1 && activeWindow) { @@ -515,7 +511,7 @@ Zotero.ItemTreeView.prototype.notify = function(action, type, ids, extraData) // Reset to Info tab this._ownerDocument.getElementById('zotero-view-tabbox').selectedIndex = 0; - Zotero.debug(4); + this.selectItem(ids[0]); } // If single item is selected and was modified @@ -544,7 +540,6 @@ Zotero.ItemTreeView.prototype.notify = function(action, type, ids, extraData) } else { - Zotero.debug(4); var previousRow = this._itemRowMap[ids[0]]; if (sort) { @@ -1117,8 +1112,6 @@ Zotero.ItemTreeView.prototype.sort = function(itemID) */ Zotero.ItemTreeView.prototype.selectItem = function(id, expand, noRecurse) { - Zotero.debug('============='); - Zotero.debug(Zotero.suppressUIUpdates); // Don't change selection if UI updates are disabled (e.g., during sync) if (Zotero.suppressUIUpdates) { return; @@ -1262,7 +1255,10 @@ Zotero.ItemTreeView.prototype.deleteSelection = function (force) var itemGroup = this._itemGroup; - if (itemGroup.isTrash()) { + if (itemGroup.isBucket()) { + itemGroup.ref.deleteItems(ids); + } + else if (itemGroup.isTrash()) { Zotero.Items.erase(ids); } else if (itemGroup.isGroup() || (force && itemGroup.isWithinGroup())) { @@ -1274,9 +1270,6 @@ Zotero.ItemTreeView.prototype.deleteSelection = function (force) else if (itemGroup.isCollection()) { itemGroup.ref.removeItems(ids); } - else if (itemGroup.isCommons()) { - Zotero.Commons.deleteItems(ids); - } this._treebox.endUpdateBatch(); } diff --git a/chrome/content/zotero/xpcom/notifier.js b/chrome/content/zotero/xpcom/notifier.js @@ -28,7 +28,7 @@ Zotero.Notifier = new function(){ var _disabled = false; var _types = [ 'collection', 'creator', 'search', 'share', 'share-items', 'item', - 'collection-item', 'item-tag', 'tag', 'group', 'commons' + 'collection-item', 'item-tag', 'tag', 'group', 'bucket' ]; var _inTransaction; var _locked = false;