Initial My Publications support
Adds a "My Publications" source after "My Library", implemented as a separate library. Top-level items can be dragged in and removed. (This doesn't currently work without disabling Quick Copy.) Also: - Make "Group Libraries" an unselectable header instead of a container, and don't indent group libraries - Fix relation purging, which maybe never worked - Pass only libraryID/key on deletes (which should speed them up) - Fix async item cloning/copying - Fix miscellaneous other bugs To-do: - Confirmation dialog on drag - API support
This commit is contained in:
parent
a9f010d547
commit
bf36a988e4
24 changed files with 405 additions and 223 deletions
|
@ -101,6 +101,9 @@ var ZoteroOverlay = new function()
|
||||||
|
|
||||||
observerService.addObserver(zoteroObserver, "browser-delayed-startup-finished", false);
|
observerService.addObserver(zoteroObserver, "browser-delayed-startup-finished", false);
|
||||||
|
|
||||||
|
// Set a flag for hi-res displays
|
||||||
|
Zotero.hiDPI = window.devicePixelRatio > 1;
|
||||||
|
|
||||||
// Add a listener for toolbar change events
|
// Add a listener for toolbar change events
|
||||||
window.addEventListener("customizationchange", onToolbarChange, false);
|
window.addEventListener("customizationchange", onToolbarChange, false);
|
||||||
|
|
||||||
|
|
|
@ -1064,7 +1064,8 @@ Zotero.Attachments = new function(){
|
||||||
throw ("Attachment is already in library " + libraryID);
|
throw ("Attachment is already in library " + libraryID);
|
||||||
}
|
}
|
||||||
|
|
||||||
var newAttachment = attachment.clone(libraryID);
|
attachment.loadItemData();
|
||||||
|
var newAttachment = yield attachment.clone(libraryID);
|
||||||
if (attachment.isImportedAttachment()) {
|
if (attachment.isImportedAttachment()) {
|
||||||
// Attachment path isn't copied over by clone() if libraryID is different
|
// Attachment path isn't copied over by clone() if libraryID is different
|
||||||
newAttachment.attachmentPath = attachment.attachmentPath;
|
newAttachment.attachmentPath = attachment.attachmentPath;
|
||||||
|
|
|
@ -42,8 +42,21 @@ Zotero.CollectionTreeView = function()
|
||||||
this.hideSources = [];
|
this.hideSources = [];
|
||||||
|
|
||||||
this._highlightedRows = {};
|
this._highlightedRows = {};
|
||||||
this._unregisterID = Zotero.Notifier.registerObserver(this, ['collection', 'search', 'share', 'group', 'trash', 'bucket'], 'collectionTreeView');
|
this._unregisterID = Zotero.Notifier.registerObserver(
|
||||||
|
this,
|
||||||
|
[
|
||||||
|
'collection',
|
||||||
|
'search',
|
||||||
|
'publications',
|
||||||
|
'share',
|
||||||
|
'group',
|
||||||
|
'trash',
|
||||||
|
'bucket'
|
||||||
|
],
|
||||||
|
'collectionTreeView'
|
||||||
|
);
|
||||||
this._containerState = {};
|
this._containerState = {};
|
||||||
|
this._publicationsRow;
|
||||||
this._duplicateLibraries = [];
|
this._duplicateLibraries = [];
|
||||||
this._unfiledLibraries = [];
|
this._unfiledLibraries = [];
|
||||||
this._trashNotEmpty = {};
|
this._trashNotEmpty = {};
|
||||||
|
@ -164,37 +177,34 @@ Zotero.CollectionTreeView.prototype.refresh = Zotero.Promise.coroutine(function*
|
||||||
libraryID: Zotero.Libraries.userLibraryID
|
libraryID: Zotero.Libraries.userLibraryID
|
||||||
};
|
};
|
||||||
|
|
||||||
// treeRow, level, beforeRow, startOpen
|
//
|
||||||
|
// Add "My Library"
|
||||||
|
//
|
||||||
|
// addRow(treeRow, level, beforeRow, startOpen)
|
||||||
this._addRow(newRows, new Zotero.CollectionTreeRow('library', library), 0, 1);
|
this._addRow(newRows, new Zotero.CollectionTreeRow('library', library), 0, 1);
|
||||||
yield this._expandRow(newRows, 0);
|
yield this._expandRow(newRows, 0);
|
||||||
|
|
||||||
|
// Add "My Publications"
|
||||||
|
this._addRow(newRows, new Zotero.CollectionTreeRow('separator', false));
|
||||||
|
this._addRow(newRows, new Zotero.CollectionTreeRow('publications', {
|
||||||
|
libraryID: Zotero.Libraries.publicationsLibraryID
|
||||||
|
}));
|
||||||
|
this._publicationsRow = newRows.length - 1;
|
||||||
|
|
||||||
|
// Add groups
|
||||||
var groups = yield Zotero.Groups.getAll();
|
var groups = yield Zotero.Groups.getAll();
|
||||||
if (groups.length) {
|
if (groups.length) {
|
||||||
this._addRow(newRows, new Zotero.CollectionTreeRow('separator', false));
|
this._addRow(newRows, new Zotero.CollectionTreeRow('separator', false));
|
||||||
var header = {
|
var row = this._addRow(newRows, new Zotero.CollectionTreeRow('header', {
|
||||||
id: "group-libraries-header",
|
id: "group-libraries-header",
|
||||||
label: Zotero.getString('pane.collections.groupLibraries'),
|
label: Zotero.getString('pane.collections.groupLibraries'),
|
||||||
libraryID: -1,
|
libraryID: -1
|
||||||
expand: Zotero.Promise.coroutine(function* (rows, beforeRow, groups) {
|
}, 0));
|
||||||
if (!groups) {
|
for (let i = 0, len = groups.length; i < len; i++) {
|
||||||
groups = yield Zotero.Groups.getAll();
|
var row = this._addRow(
|
||||||
}
|
newRows,
|
||||||
var newRows = 0;
|
new Zotero.CollectionTreeRow('group', groups[i])
|
||||||
for (var i = 0, len = groups.length; i < len; i++) {
|
|
||||||
var row = self._addRow(
|
|
||||||
rows,
|
|
||||||
new Zotero.CollectionTreeRow('group', groups[i]),
|
|
||||||
1,
|
|
||||||
beforeRow ? beforeRow + newRows : null
|
|
||||||
);
|
);
|
||||||
newRows += 1 + ( yield self._expandRow(rows, row) );
|
|
||||||
}
|
|
||||||
return newRows;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
var row = this._addRow(newRows, new Zotero.CollectionTreeRow('header', header));
|
|
||||||
if (this._containerState.HG) {
|
|
||||||
newRows[row][1] = true;
|
|
||||||
yield header.expand(newRows, null, groups);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +335,8 @@ Zotero.CollectionTreeView.prototype.notify = Zotero.Promise.coroutine(function*
|
||||||
this.rememberSelection(savedSelection);
|
this.rememberSelection(savedSelection);
|
||||||
}
|
}
|
||||||
else if (action == 'modify' || action == 'refresh') {
|
else if (action == 'modify' || action == 'refresh') {
|
||||||
if (type != 'bucket') {
|
if (type != 'bucket'
|
||||||
|
&& (type != 'publications' || this.selectedTreeRow.isPublications())) {
|
||||||
yield this.reload();
|
yield this.reload();
|
||||||
}
|
}
|
||||||
this.rememberSelection(savedSelection);
|
this.rememberSelection(savedSelection);
|
||||||
|
@ -392,10 +403,21 @@ Zotero.CollectionTreeView.prototype.setHighlightedRows = Zotero.Promise.coroutin
|
||||||
this._highlightedRows = {};
|
this._highlightedRows = {};
|
||||||
this._treebox.invalidate();
|
this._treebox.invalidate();
|
||||||
|
|
||||||
for each(var id in ids) {
|
if (!ids) return;
|
||||||
|
for (let id of ids) {
|
||||||
|
var row = null;
|
||||||
|
if (id[0] == 'C') {
|
||||||
|
id = id.substr(1);
|
||||||
yield this.expandToCollection(id);
|
yield this.expandToCollection(id);
|
||||||
this._highlightedRows[this._collectionRowMap[id]] = true;
|
row = this._collectionRowMap[id];
|
||||||
this._treebox.invalidateRow(this._collectionRowMap[id]);
|
}
|
||||||
|
else if (id == 'P') {
|
||||||
|
row = this._publicationsRow;
|
||||||
|
}
|
||||||
|
if (row) {
|
||||||
|
this._highlightedRows[row] = true;
|
||||||
|
this._treebox.invalidateRow(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -429,6 +451,8 @@ Zotero.CollectionTreeView.prototype.getCellText = function(row, column)
|
||||||
|
|
||||||
Zotero.CollectionTreeView.prototype.getImageSrc = function(row, col)
|
Zotero.CollectionTreeView.prototype.getImageSrc = function(row, col)
|
||||||
{
|
{
|
||||||
|
var suffix = Zotero.hiDPI ? "@2x" : "";
|
||||||
|
|
||||||
var treeRow = this.getRow(row);
|
var treeRow = this.getRow(row);
|
||||||
var collectionType = treeRow.type;
|
var collectionType = treeRow.type;
|
||||||
|
|
||||||
|
@ -467,6 +491,9 @@ Zotero.CollectionTreeView.prototype.getImageSrc = function(row, col)
|
||||||
case 'collection':
|
case 'collection':
|
||||||
case 'search':
|
case 'search':
|
||||||
return "chrome://zotero-platform/content/treesource-" + collectionType + ".png";
|
return "chrome://zotero-platform/content/treesource-" + collectionType + ".png";
|
||||||
|
|
||||||
|
case 'publications':
|
||||||
|
return "chrome://zotero/skin/treeitem-journalArticle" + suffix + ".png";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "chrome://zotero/skin/treesource-" + collectionType + ".png";
|
return "chrome://zotero/skin/treesource-" + collectionType + ".png";
|
||||||
|
@ -475,7 +502,7 @@ Zotero.CollectionTreeView.prototype.getImageSrc = function(row, col)
|
||||||
Zotero.CollectionTreeView.prototype.isContainer = function(row)
|
Zotero.CollectionTreeView.prototype.isContainer = function(row)
|
||||||
{
|
{
|
||||||
var treeRow = this.getRow(row);
|
var treeRow = this.getRow(row);
|
||||||
return treeRow.isLibrary(true) || treeRow.isCollection() || treeRow.isHeader() || treeRow.isBucket();
|
return treeRow.isLibrary(true) || treeRow.isCollection() || treeRow.isPublications() || treeRow.isBucket();
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.CollectionTreeView.prototype.isContainerOpen = function(row)
|
Zotero.CollectionTreeView.prototype.isContainerOpen = function(row)
|
||||||
|
@ -492,9 +519,6 @@ Zotero.CollectionTreeView.prototype.isContainerEmpty = function(row)
|
||||||
if (treeRow.isLibrary()) {
|
if (treeRow.isLibrary()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (treeRow.isHeader()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (treeRow.isBucket()) {
|
if (treeRow.isBucket()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -559,10 +583,7 @@ Zotero.CollectionTreeView.prototype.toggleOpenState = Zotero.Promise.coroutine(f
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var treeRow = this.getRow(row);
|
var treeRow = this.getRow(row);
|
||||||
if (treeRow.type == 'header') {
|
if (treeRow.isLibrary(true) || treeRow.isCollection()) {
|
||||||
count = yield treeRow.ref.expand(this._rows, row + 1);
|
|
||||||
}
|
|
||||||
else if (treeRow.isLibrary(true) || treeRow.isCollection()) {
|
|
||||||
count = yield this._expandRow(this._rows, row, true);
|
count = yield this._expandRow(this._rows, row, true);
|
||||||
}
|
}
|
||||||
this.rowCount += count;
|
this.rowCount += count;
|
||||||
|
@ -582,6 +603,7 @@ Zotero.CollectionTreeView.prototype.isSelectable = function (row, col) {
|
||||||
var treeRow = this.getRow(row);
|
var treeRow = this.getRow(row);
|
||||||
switch (treeRow.type) {
|
switch (treeRow.type) {
|
||||||
case 'separator':
|
case 'separator':
|
||||||
|
case 'header':
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -741,14 +763,6 @@ Zotero.CollectionTreeView.prototype.selectLibrary = Zotero.Promise.coroutine(fun
|
||||||
// Find library
|
// Find library
|
||||||
for (var i = 0; i < this.rowCount; i++) {
|
for (var i = 0; i < this.rowCount; i++) {
|
||||||
var treeRow = this.getRow(i);
|
var treeRow = this.getRow(i);
|
||||||
|
|
||||||
// If group header is closed, open it
|
|
||||||
if (treeRow.isHeader() && treeRow.ref.id == 'group-libraries-header'
|
|
||||||
&& !this.isContainerOpen(i)) {
|
|
||||||
yield this.toggleOpenState(i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (treeRow.ref && treeRow.ref.libraryID == libraryID) {
|
if (treeRow.ref && treeRow.ref.libraryID == libraryID) {
|
||||||
this._treebox.ensureRowIsVisible(i);
|
this._treebox.ensureRowIsVisible(i);
|
||||||
this.selection.select(i);
|
this.selection.select(i);
|
||||||
|
@ -900,6 +914,10 @@ Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(functi
|
||||||
var isCollection = treeRow.isCollection();
|
var isCollection = treeRow.isCollection();
|
||||||
var libraryID = treeRow.ref.libraryID;
|
var libraryID = treeRow.ref.libraryID;
|
||||||
|
|
||||||
|
if (treeRow.isPublications()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isGroup) {
|
if (isGroup) {
|
||||||
var group = yield Zotero.Groups.getByLibraryID(libraryID);
|
var group = yield Zotero.Groups.getByLibraryID(libraryID);
|
||||||
var collections = yield group.getCollections();
|
var collections = yield group.getCollections();
|
||||||
|
@ -1259,7 +1277,6 @@ Zotero.CollectionTreeView.prototype.canDropCheck = function (row, orient, dataTr
|
||||||
var ids = data;
|
var ids = data;
|
||||||
var items = Zotero.Items.get(ids);
|
var items = Zotero.Items.get(ids);
|
||||||
var skip = true;
|
var skip = true;
|
||||||
Zotero.debug(ids);
|
|
||||||
for each(var item in items) {
|
for each(var item in items) {
|
||||||
// Can only drag top-level items
|
// Can only drag top-level items
|
||||||
if (!item.isTopLevelItem()) {
|
if (!item.isTopLevelItem()) {
|
||||||
|
@ -1281,6 +1298,15 @@ Zotero.CollectionTreeView.prototype.canDropCheck = function (row, orient, dataTr
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (treeRow.isPublications() && treeRow.ref.libraryID != item.libraryID) {
|
||||||
|
if (item.isAttachment() || item.isNote()) {
|
||||||
|
Zotero.debug("Standalone attachments and notes cannot be added to My Publications");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
skip = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Cross-library drag
|
// Cross-library drag
|
||||||
if (treeRow.ref.libraryID != item.libraryID) {
|
if (treeRow.ref.libraryID != item.libraryID) {
|
||||||
// Only allow cross-library drag to root library and collections
|
// Only allow cross-library drag to root library and collections
|
||||||
|
@ -1313,7 +1339,7 @@ Zotero.CollectionTreeView.prototype.canDropCheck = function (row, orient, dataTr
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (dataType == 'text/x-moz-url' || dataType == 'application/x-moz-file') {
|
else if (dataType == 'text/x-moz-url' || dataType == 'application/x-moz-file') {
|
||||||
if (treeRow.isSearch()) {
|
if (treeRow.isSearch() || treeRow.isPublications()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (dataType == 'application/x-moz-file') {
|
if (dataType == 'application/x-moz-file') {
|
||||||
|
@ -1330,6 +1356,10 @@ Zotero.CollectionTreeView.prototype.canDropCheck = function (row, orient, dataTr
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (dataType == 'zotero/collection') {
|
else if (dataType == 'zotero/collection') {
|
||||||
|
if (treeRow.isPublications()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let draggedCollectionID = data[0];
|
let draggedCollectionID = data[0];
|
||||||
let draggedCollection = Zotero.Collections.get(draggedCollectionID);
|
let draggedCollection = Zotero.Collections.get(draggedCollectionID);
|
||||||
|
|
||||||
|
@ -1400,16 +1430,22 @@ Zotero.CollectionTreeView.prototype.canDropCheckAsync = Zotero.Promise.coroutine
|
||||||
if (linkedItem && !linkedItem.deleted) {
|
if (linkedItem && !linkedItem.deleted) {
|
||||||
// For drag to root, skip if linked item exists
|
// For drag to root, skip if linked item exists
|
||||||
if (treeRow.isLibrary(true)) {
|
if (treeRow.isLibrary(true)) {
|
||||||
|
Zotero.debug("Linked item " + linkedItem.key + " already exists "
|
||||||
|
+ "in library " + treeRow.ref.libraryID);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// For drag to collection
|
// For drag to collection
|
||||||
else if (treeRow.isCollection()) {
|
else if (treeRow.isCollection()) {
|
||||||
// skip if linked item is already in it
|
// skip if linked item is already in it
|
||||||
if (treeRow.ref.hasItem(linkedItem.id)) {
|
if (treeRow.ref.hasItem(linkedItem.id)) {
|
||||||
|
Zotero.debug("Linked item " + linkedItem.key + " already exists "
|
||||||
|
+ "in collection");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// or if linked item is a child item
|
// or if linked item is a child item
|
||||||
else if (!linkedItem.isTopLevelItem()) {
|
else if (!linkedItem.isTopLevelItem()) {
|
||||||
|
Zotero.debug("Linked item " + linkedItem.key + " already exists "
|
||||||
|
+ "as child item");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1420,8 +1456,7 @@ Zotero.CollectionTreeView.prototype.canDropCheckAsync = Zotero.Promise.coroutine
|
||||||
|
|
||||||
// Intra-library drag
|
// Intra-library drag
|
||||||
|
|
||||||
// Make sure there's at least one item that's not already
|
// Make sure there's at least one item that's not already in this destination
|
||||||
// in this collection
|
|
||||||
if (treeRow.isCollection()) {
|
if (treeRow.isCollection()) {
|
||||||
if (treeRow.ref.hasItem(item.id)) {
|
if (treeRow.ref.hasItem(item.id)) {
|
||||||
Zotero.debug("Item " + item.id + " already exists in collection");
|
Zotero.debug("Item " + item.id + " already exists in collection");
|
||||||
|
@ -1563,7 +1598,7 @@ Zotero.CollectionTreeView.prototype.drop = Zotero.Promise.coroutine(function* (r
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new clone item in target library
|
// Create new clone item in target library
|
||||||
var newItem = item.clone(targetLibraryID, false, !Zotero.Prefs.get('groups.copyTags'));
|
var newItem = yield item.clone(targetLibraryID, false, !Zotero.Prefs.get('groups.copyTags'));
|
||||||
var newItemID = yield newItem.save();
|
var newItemID = yield newItem.save();
|
||||||
|
|
||||||
// Record link
|
// Record link
|
||||||
|
@ -1577,10 +1612,11 @@ Zotero.CollectionTreeView.prototype.drop = Zotero.Promise.coroutine(function* (r
|
||||||
|
|
||||||
// Child notes
|
// Child notes
|
||||||
if (Zotero.Prefs.get('groups.copyChildNotes')) {
|
if (Zotero.Prefs.get('groups.copyChildNotes')) {
|
||||||
|
yield item.loadChildItems();
|
||||||
var noteIDs = item.getNotes();
|
var noteIDs = item.getNotes();
|
||||||
var notes = yield Zotero.Items.getAsync(noteIDs);
|
var notes = yield Zotero.Items.getAsync(noteIDs);
|
||||||
for each(var note in notes) {
|
for each(var note in notes) {
|
||||||
let newNote = note.clone(targetLibraryID);
|
let newNote = yield note.clone(targetLibraryID);
|
||||||
newNote.parentID = newItemID;
|
newNote.parentID = newItemID;
|
||||||
yield newNote.save()
|
yield newNote.save()
|
||||||
|
|
||||||
|
@ -1617,11 +1653,11 @@ Zotero.CollectionTreeView.prototype.drop = Zotero.Promise.coroutine(function* (r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.Attachments.copyAttachmentToLibrary(attachment, targetLibraryID, newItem.id);
|
Zotero.Attachments.copyAttachmentToLibrary(attachment, targetLibraryID, newItemID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newID;
|
return newItemID;
|
||||||
});
|
});
|
||||||
|
|
||||||
var targetLibraryID = targetTreeRow.ref.libraryID;
|
var targetLibraryID = targetTreeRow.ref.libraryID;
|
||||||
|
@ -1791,9 +1827,7 @@ Zotero.CollectionTreeView.prototype.drop = Zotero.Promise.coroutine(function* (r
|
||||||
// Add items to target collection
|
// Add items to target collection
|
||||||
if (targetCollectionID) {
|
if (targetCollectionID) {
|
||||||
var collection = yield Zotero.Collections.getAsync(targetCollectionID);
|
var collection = yield Zotero.Collections.getAsync(targetCollectionID);
|
||||||
Zotero.debug('adding');
|
|
||||||
yield collection.addItems(newIDs);
|
yield collection.addItems(newIDs);
|
||||||
Zotero.debug('added');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If moving, remove items from source collection
|
// If moving, remove items from source collection
|
||||||
|
@ -1902,24 +1936,34 @@ Zotero.CollectionTreeView.prototype.isSorted = function() { return false;
|
||||||
Zotero.CollectionTreeView.prototype.getRowProperties = function(row, prop) {
|
Zotero.CollectionTreeView.prototype.getRowProperties = function(row, prop) {
|
||||||
var props = [];
|
var props = [];
|
||||||
|
|
||||||
if (this._highlightedRows[row]) {
|
var treeRow = this.getRow(row);
|
||||||
// <=Fx21
|
if (treeRow.isHeader()) {
|
||||||
if (prop) {
|
props.push("header");
|
||||||
var aServ = Components.classes["@mozilla.org/atom-service;1"].
|
|
||||||
getService(Components.interfaces.nsIAtomService);
|
|
||||||
prop.AppendElement(aServ.getAtom("highlighted"));
|
|
||||||
}
|
}
|
||||||
// Fx22+
|
else if (this._highlightedRows[row]) {
|
||||||
else {
|
|
||||||
props.push("highlighted");
|
props.push("highlighted");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return props.join(" ");
|
return props.join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.CollectionTreeView.prototype.getColumnProperties = function(col, prop) { }
|
Zotero.CollectionTreeView.prototype.getColumnProperties = function(col, prop) {}
|
||||||
Zotero.CollectionTreeView.prototype.getCellProperties = function(row, col, prop) { }
|
|
||||||
|
Zotero.CollectionTreeView.prototype.getCellProperties = function(row, col, prop) {
|
||||||
|
var props = [];
|
||||||
|
|
||||||
|
var treeRow = this.getRow(row);
|
||||||
|
if (treeRow.isHeader()) {
|
||||||
|
props.push("header");
|
||||||
|
props.push("notwisty");
|
||||||
|
}
|
||||||
|
else if (treeRow.isPublications()) {
|
||||||
|
props.push("notwisty");
|
||||||
|
}
|
||||||
|
|
||||||
|
return props.join(" ");
|
||||||
|
|
||||||
|
}
|
||||||
Zotero.CollectionTreeView.prototype.isSeparator = function(index) {
|
Zotero.CollectionTreeView.prototype.isSeparator = function(index) {
|
||||||
var source = this.getRow(index);
|
var source = this.getRow(index);
|
||||||
return source.type == 'separator';
|
return source.type == 'separator';
|
||||||
|
@ -1965,6 +2009,9 @@ Zotero.CollectionTreeRow.prototype.__defineGetter__('id', function () {
|
||||||
case 'search':
|
case 'search':
|
||||||
return 'S' + this.ref.id;
|
return 'S' + this.ref.id;
|
||||||
|
|
||||||
|
case 'publications':
|
||||||
|
return 'P';
|
||||||
|
|
||||||
case 'duplicates':
|
case 'duplicates':
|
||||||
return 'D' + this.ref.libraryID;
|
return 'D' + this.ref.libraryID;
|
||||||
|
|
||||||
|
@ -1990,7 +2037,7 @@ Zotero.CollectionTreeRow.prototype.__defineGetter__('id', function () {
|
||||||
Zotero.CollectionTreeRow.prototype.isLibrary = function (includeGlobal)
|
Zotero.CollectionTreeRow.prototype.isLibrary = function (includeGlobal)
|
||||||
{
|
{
|
||||||
if (includeGlobal) {
|
if (includeGlobal) {
|
||||||
return this.type == 'library' || this.type == 'group';
|
return this.type == 'library' || this.type == 'publications' || this.type == 'group';
|
||||||
}
|
}
|
||||||
return this.type == 'library';
|
return this.type == 'library';
|
||||||
}
|
}
|
||||||
|
@ -2022,6 +2069,10 @@ Zotero.CollectionTreeRow.prototype.isHeader = function () {
|
||||||
return this.type == 'header';
|
return this.type == 'header';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Zotero.CollectionTreeRow.prototype.isPublications = function() {
|
||||||
|
return this.type == 'publications';
|
||||||
|
}
|
||||||
|
|
||||||
Zotero.CollectionTreeRow.prototype.isGroup = function() {
|
Zotero.CollectionTreeRow.prototype.isGroup = function() {
|
||||||
return this.type == 'group';
|
return this.type == 'group';
|
||||||
}
|
}
|
||||||
|
@ -2059,7 +2110,7 @@ Zotero.CollectionTreeRow.prototype.__defineGetter__('editable', function () {
|
||||||
if (this.isTrash() || this.isShare() || this.isBucket()) {
|
if (this.isTrash() || this.isShare() || this.isBucket()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!this.isWithinGroup()) {
|
if (this.isPublications || !this.isWithinGroup()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var libraryID = this.ref.libraryID;
|
var libraryID = this.ref.libraryID;
|
||||||
|
@ -2107,6 +2158,9 @@ Zotero.CollectionTreeRow.prototype.getName = function()
|
||||||
case 'library':
|
case 'library':
|
||||||
return Zotero.getString('pane.collections.library');
|
return Zotero.getString('pane.collections.library');
|
||||||
|
|
||||||
|
case 'publications':
|
||||||
|
return Zotero.getString('pane.collections.publications');
|
||||||
|
|
||||||
case 'trash':
|
case 'trash':
|
||||||
return Zotero.getString('pane.collections.trash');
|
return Zotero.getString('pane.collections.trash');
|
||||||
|
|
||||||
|
@ -2130,9 +2184,6 @@ Zotero.CollectionTreeRow.prototype.getItems = Zotero.Promise.coroutine(function*
|
||||||
|
|
||||||
case 'bucket':
|
case 'bucket':
|
||||||
return this.ref.getItems();
|
return this.ref.getItems();
|
||||||
|
|
||||||
case 'header':
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var ids = yield this.getSearchResults();
|
var ids = yield this.getSearchResults();
|
||||||
|
@ -2220,7 +2271,7 @@ Zotero.CollectionTreeRow.prototype.getSearchObject = Zotero.Promise.coroutine(fu
|
||||||
yield s.addCondition('deleted', 'true');
|
yield s.addCondition('deleted', 'true');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw ('Invalid search mode in Zotero.CollectionTreeRow.getSearchObject()');
|
throw new Error('Invalid search mode in Zotero.CollectionTreeRow.getSearchObject()');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2263,9 +2314,6 @@ Zotero.CollectionTreeRow.prototype.getChildTags = Zotero.Promise.method(function
|
||||||
|
|
||||||
case 'bucket':
|
case 'bucket':
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case 'header':
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Zotero.Tags.getAllWithinSearchResults(this.getSearchResults(true));
|
return Zotero.Tags.getAllWithinSearchResults(this.getSearchResults(true));
|
||||||
|
|
|
@ -606,7 +606,10 @@ Zotero.Collection.prototype.erase = function(deleteItems) {
|
||||||
return Zotero.DB.executeTransaction(function* () {
|
return Zotero.DB.executeTransaction(function* () {
|
||||||
var descendents = yield this.getDescendents(false, null, true);
|
var descendents = yield this.getDescendents(false, null, true);
|
||||||
var items = [];
|
var items = [];
|
||||||
notifierData[this.id] = { old: this.toJSON() };
|
notifierData[this.id] = {
|
||||||
|
libraryID: this.libraryID,
|
||||||
|
key: this.key
|
||||||
|
};
|
||||||
|
|
||||||
var del = [];
|
var del = [];
|
||||||
for(var i=0, len=descendents.length; i<len; i++) {
|
for(var i=0, len=descendents.length; i<len; i++) {
|
||||||
|
@ -615,7 +618,10 @@ Zotero.Collection.prototype.erase = function(deleteItems) {
|
||||||
collections.push(descendents[i].id);
|
collections.push(descendents[i].id);
|
||||||
var c = yield this.ObjectsClass.getAsync(descendents[i].id);
|
var c = yield this.ObjectsClass.getAsync(descendents[i].id);
|
||||||
if (c) {
|
if (c) {
|
||||||
notifierData[c.id] = { old: c.toJSON() };
|
notifierData[c.id] = {
|
||||||
|
libraryID: c.libraryID,
|
||||||
|
key: c.key
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Descendent items
|
// Descendent items
|
||||||
|
|
|
@ -292,6 +292,7 @@ Zotero.DataObject.prototype._getLinkedObject = Zotero.Promise.coroutine(function
|
||||||
var predicate = Zotero.Relations.linkedObjectPredicate;
|
var predicate = Zotero.Relations.linkedObjectPredicate;
|
||||||
var uri = Zotero.URI['get' + this._ObjectType + 'URI'](this);
|
var uri = Zotero.URI['get' + this._ObjectType + 'URI'](this);
|
||||||
|
|
||||||
|
// Get all relations with this object as the subject or object
|
||||||
var links = yield Zotero.Promise.all([
|
var links = yield Zotero.Promise.all([
|
||||||
Zotero.Relations.getSubject(false, predicate, uri),
|
Zotero.Relations.getSubject(false, predicate, uri),
|
||||||
Zotero.Relations.getObject(uri, predicate, false)
|
Zotero.Relations.getObject(uri, predicate, false)
|
||||||
|
@ -311,7 +312,7 @@ Zotero.DataObject.prototype._getLinkedObject = Zotero.Promise.coroutine(function
|
||||||
|
|
||||||
for (let i=0; i<links.length; i++) {
|
for (let i=0; i<links.length; i++) {
|
||||||
let link = links[i];
|
let link = links[i];
|
||||||
if (link.indexOf(libraryObjectPrefix) == 0) {
|
if (link.startsWith(libraryObjectPrefix)) {
|
||||||
var obj = yield Zotero.URI['getURI' + this._ObjectType](link);
|
var obj = yield Zotero.URI['getURI' + this._ObjectType](link);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
Zotero.debug("Referenced linked " + this._objectType + " '" + link + "' not found "
|
Zotero.debug("Referenced linked " + this._objectType + " '" + link + "' not found "
|
||||||
|
@ -599,6 +600,7 @@ Zotero.DataObject.prototype.erase = Zotero.Promise.coroutine(function* () {
|
||||||
yield this._erasePreCommit(env);
|
yield this._erasePreCommit(env);
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
|
Zotero.debug(e);
|
||||||
return this._eraseRecoverFromFailure(env);
|
return this._eraseRecoverFromFailure(env);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,7 @@ Zotero.Item = function(itemTypeOrID) {
|
||||||
this._fileExists = null;
|
this._fileExists = null;
|
||||||
|
|
||||||
this._deleted = null;
|
this._deleted = null;
|
||||||
|
this._publication = null;
|
||||||
this._hasNote = null;
|
this._hasNote = null;
|
||||||
|
|
||||||
this._noteAccessTime = null;
|
this._noteAccessTime = null;
|
||||||
|
@ -1037,28 +1038,35 @@ Zotero.Item.prototype.removeCreator = function(orderIndex, allowMissing) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.defineProperty(Zotero.Item.prototype, 'deleted', {
|
|
||||||
|
// Define 'deleted' and 'publication' properties
|
||||||
|
for (let name of ['deleted', 'publication']) {
|
||||||
|
let prop = '_' + name;
|
||||||
|
|
||||||
|
Zotero.defineProperty(Zotero.Item.prototype, name, {
|
||||||
get: function() {
|
get: function() {
|
||||||
if (!this.id) {
|
if (!this.id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this._deleted !== null) {
|
if (this[prop] !== null) {
|
||||||
return this._deleted;
|
return this[prop];
|
||||||
}
|
}
|
||||||
this._requireData('primaryData');
|
this._requireData('primaryData');
|
||||||
},
|
},
|
||||||
set: function(val) {
|
set: function(val) {
|
||||||
var deleted = !!val;
|
val = !!val;
|
||||||
|
|
||||||
if (this._deleted == deleted) {
|
if (this[prop] == val) {
|
||||||
Zotero.debug("Deleted state hasn't changed for item " + this.id);
|
Zotero.debug(Zotero.Utilities.capitalize(name)
|
||||||
|
+ " state hasn't changed for item " + this.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._markFieldChange('deleted', !!this._deleted);
|
this._markFieldChange('publication', !!this[prop]);
|
||||||
this._changed.deleted = true;
|
this._changed[name] = true;
|
||||||
this._deleted = deleted;
|
this[prop] = val;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Zotero.Item.prototype.addRelatedItem = Zotero.Promise.coroutine(function* (itemID) {
|
Zotero.Item.prototype.addRelatedItem = Zotero.Promise.coroutine(function* (itemID) {
|
||||||
|
@ -1407,7 +1415,7 @@ Zotero.Item.prototype._saveData = Zotero.Promise.coroutine(function* (env) {
|
||||||
|
|
||||||
// Trashed status
|
// Trashed status
|
||||||
if (this._changed.deleted) {
|
if (this._changed.deleted) {
|
||||||
if (this.deleted) {
|
if (this._deleted) {
|
||||||
sql = "REPLACE INTO deletedItems (itemID) VALUES (?)";
|
sql = "REPLACE INTO deletedItems (itemID) VALUES (?)";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3710,14 +3718,14 @@ Zotero.Item.prototype.multiDiff = Zotero.Promise.coroutine(function* (otherItems
|
||||||
* @param {Number} [libraryID] - libraryID of the new item, or the same as original if omitted
|
* @param {Number} [libraryID] - libraryID of the new item, or the same as original if omitted
|
||||||
* @param {Boolean} [skipTags=false] - Skip tags
|
* @param {Boolean} [skipTags=false] - Skip tags
|
||||||
*/
|
*/
|
||||||
Zotero.Item.prototype.clone = function(libraryID, skipTags) {
|
Zotero.Item.prototype.clone = Zotero.Promise.coroutine(function* (libraryID, skipTags) {
|
||||||
Zotero.debug('Cloning item ' + this.id);
|
Zotero.debug('Cloning item ' + this.id);
|
||||||
|
|
||||||
if (libraryID !== undefined && libraryID !== null && typeof libraryID !== 'number') {
|
if (libraryID !== undefined && libraryID !== null && typeof libraryID !== 'number') {
|
||||||
throw new Error("libraryID must be null or an integer");
|
throw new Error("libraryID must be null or an integer");
|
||||||
}
|
}
|
||||||
|
|
||||||
this._requireData('primaryData');
|
yield this.loadPrimaryData();
|
||||||
|
|
||||||
if (libraryID === undefined || libraryID === null) {
|
if (libraryID === undefined || libraryID === null) {
|
||||||
libraryID = this.libraryID;
|
libraryID = this.libraryID;
|
||||||
|
@ -3728,6 +3736,7 @@ Zotero.Item.prototype.clone = function(libraryID, skipTags) {
|
||||||
newItem.libraryID = libraryID;
|
newItem.libraryID = libraryID;
|
||||||
newItem.setType(this.itemTypeID);
|
newItem.setType(this.itemTypeID);
|
||||||
|
|
||||||
|
yield this.loadItemData();
|
||||||
var fieldIDs = this.getUsedFields();
|
var fieldIDs = this.getUsedFields();
|
||||||
for (let i = 0; i < fieldIDs.length; i++) {
|
for (let i = 0; i < fieldIDs.length; i++) {
|
||||||
let fieldID = fieldIDs[i];
|
let fieldID = fieldIDs[i];
|
||||||
|
@ -3736,9 +3745,11 @@ Zotero.Item.prototype.clone = function(libraryID, skipTags) {
|
||||||
|
|
||||||
// Regular item
|
// Regular item
|
||||||
if (this.isRegularItem()) {
|
if (this.isRegularItem()) {
|
||||||
|
yield this.loadCreators();
|
||||||
newItem.setCreators(newItem.getCreators());
|
newItem.setCreators(newItem.getCreators());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
yield this.loadNote();
|
||||||
newItem.setNote(this.getNote());
|
newItem.setNote(this.getNote());
|
||||||
if (sameLibrary) {
|
if (sameLibrary) {
|
||||||
var parent = this.parentKey;
|
var parent = this.parentKey;
|
||||||
|
@ -3763,16 +3774,18 @@ Zotero.Item.prototype.clone = function(libraryID, skipTags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skipTags) {
|
if (!skipTags) {
|
||||||
|
yield this.loadTags();
|
||||||
newItem.setTags(this.getTags());
|
newItem.setTags(this.getTags());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sameLibrary) {
|
if (sameLibrary) {
|
||||||
// DEBUG: this will add reverse-only relateds too
|
// DEBUG: this will add reverse-only relateds too
|
||||||
|
yield this.loadRelations();
|
||||||
newItem.setRelations(this.getRelations());
|
newItem.setRelations(this.getRelations());
|
||||||
}
|
}
|
||||||
|
|
||||||
return newItem;
|
return newItem;
|
||||||
}
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3791,7 +3804,10 @@ Zotero.Item.prototype._eraseInit = Zotero.Promise.coroutine(function* (env) {
|
||||||
if (!proceed) return false;
|
if (!proceed) return false;
|
||||||
|
|
||||||
env.deletedItemNotifierData = {};
|
env.deletedItemNotifierData = {};
|
||||||
env.deletedItemNotifierData[this.id] = { old: this.toJSON() };
|
env.deletedItemNotifierData[this.id] = {
|
||||||
|
libraryID: this.libraryID,
|
||||||
|
key: this.key
|
||||||
|
};
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
@ -4572,9 +4588,9 @@ Zotero.Item.prototype._getRelatedItems = function () {
|
||||||
// Pull out object values from related-item relations, turn into items, and pull out keys
|
// Pull out object values from related-item relations, turn into items, and pull out keys
|
||||||
var keys = [];
|
var keys = [];
|
||||||
for (let i=0; i<relatedItemURIs.length; i++) {
|
for (let i=0; i<relatedItemURIs.length; i++) {
|
||||||
item = Zotero.URI.getURIItem(relatedItemURIs[i]);
|
let {libraryID, key} = Zotero.URI.getURIItemLibraryKey(relatedItemURIs[i]);
|
||||||
if (item) {
|
if (key) {
|
||||||
keys.push(item.key);
|
keys.push(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return keys;
|
return keys;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
Zotero.Libraries = new function () {
|
Zotero.Libraries = new function () {
|
||||||
let _libraryData = {},
|
let _libraryData = {},
|
||||||
_userLibraryID,
|
_userLibraryID,
|
||||||
|
_publicationsLibraryID,
|
||||||
_libraryDataLoaded = false;
|
_libraryDataLoaded = false;
|
||||||
|
|
||||||
Zotero.defineProperty(this, 'userLibraryID', {
|
Zotero.defineProperty(this, 'userLibraryID', {
|
||||||
|
@ -37,6 +38,15 @@ Zotero.Libraries = new function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Zotero.defineProperty(this, 'publicationsLibraryID', {
|
||||||
|
get: function() {
|
||||||
|
if (!_libraryDataLoaded) {
|
||||||
|
throw new Error("Library data not yet loaded");
|
||||||
|
}
|
||||||
|
return _publicationsLibraryID;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.init = Zotero.Promise.coroutine(function* () {
|
this.init = Zotero.Promise.coroutine(function* () {
|
||||||
// Library data
|
// Library data
|
||||||
var sql = "SELECT * FROM libraries";
|
var sql = "SELECT * FROM libraries";
|
||||||
|
@ -47,6 +57,9 @@ Zotero.Libraries = new function () {
|
||||||
if (row.libraryType == 'user') {
|
if (row.libraryType == 'user') {
|
||||||
_userLibraryID = row.libraryID;
|
_userLibraryID = row.libraryID;
|
||||||
}
|
}
|
||||||
|
else if (row.libraryType == 'publications') {
|
||||||
|
_publicationsLibraryID = row.libraryID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_libraryDataLoaded = true;
|
_libraryDataLoaded = true;
|
||||||
});
|
});
|
||||||
|
@ -82,6 +95,10 @@ Zotero.Libraries = new function () {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'user':
|
case 'user':
|
||||||
return Zotero.getString('pane.collections.library');
|
return Zotero.getString('pane.collections.library');
|
||||||
|
|
||||||
|
case 'publications':
|
||||||
|
return Zotero.getString('pane.collections.publications');
|
||||||
|
|
||||||
case 'group':
|
case 'group':
|
||||||
var groupID = Zotero.Groups.getGroupIDFromLibraryID(libraryID);
|
var groupID = Zotero.Groups.getGroupIDFromLibraryID(libraryID);
|
||||||
var group = Zotero.Groups.get(groupID);
|
var group = Zotero.Groups.get(groupID);
|
||||||
|
@ -147,6 +164,7 @@ Zotero.Libraries = new function () {
|
||||||
var type = this.getType(libraryID);
|
var type = this.getType(libraryID);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'user':
|
case 'user':
|
||||||
|
case 'publications':
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 'group':
|
case 'group':
|
||||||
|
@ -164,6 +182,7 @@ Zotero.Libraries = new function () {
|
||||||
var type = this.getType(libraryID);
|
var type = this.getType(libraryID);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'user':
|
case 'user':
|
||||||
|
case 'publications':
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 'group':
|
case 'group':
|
||||||
|
@ -184,7 +203,6 @@ Zotero.Libraries = new function () {
|
||||||
return this.getType(libraryID) == 'group';
|
return this.getType(libraryID) == 'group';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function parseDBRow(row) {
|
function parseDBRow(row) {
|
||||||
return {
|
return {
|
||||||
type: row.libraryType,
|
type: row.libraryType,
|
||||||
|
|
|
@ -51,8 +51,8 @@ Zotero.Relation.prototype.__defineSetter__('object', function (val) { this._set(
|
||||||
|
|
||||||
|
|
||||||
Zotero.Relation.prototype._get = function (field) {
|
Zotero.Relation.prototype._get = function (field) {
|
||||||
if (this._id && !this._loaded) {
|
if (!this._loaded) {
|
||||||
this.load();
|
throw new Error("Data not loaded for relation " + this._id);
|
||||||
}
|
}
|
||||||
return this['_' + field];
|
return this['_' + field];
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,8 @@ Zotero.Relation.prototype.erase = Zotero.Promise.coroutine(function* () {
|
||||||
|
|
||||||
var deleteData = {};
|
var deleteData = {};
|
||||||
deleteData[this.id] = {
|
deleteData[this.id] = {
|
||||||
old: this.serialize()
|
libraryID: this.libraryID,
|
||||||
|
key: Zotero.Utilities.Internal.md5(this.subject + "_" + this.predicate + "_" + this.object)
|
||||||
}
|
}
|
||||||
|
|
||||||
var sql = "DELETE FROM relations WHERE ROWID=?";
|
var sql = "DELETE FROM relations WHERE ROWID=?";
|
||||||
|
@ -249,15 +250,11 @@ Zotero.Relation.prototype.serialize = function () {
|
||||||
var key = Zotero.Utilities.Internal.md5(this.subject + "_" + this.predicate + "_" + this.object);
|
var key = Zotero.Utilities.Internal.md5(this.subject + "_" + this.predicate + "_" + this.object);
|
||||||
|
|
||||||
var obj = {
|
var obj = {
|
||||||
primary: {
|
|
||||||
libraryID: this.libraryID,
|
libraryID: this.libraryID,
|
||||||
key: key,
|
key: key,
|
||||||
},
|
|
||||||
fields: {
|
|
||||||
subject: this.subject,
|
subject: this.subject,
|
||||||
predicate: this.predicate,
|
predicate: this.predicate,
|
||||||
object: this.object
|
object: this.object
|
||||||
}
|
|
||||||
};
|
};
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,8 @@ Zotero.Relations = function () {
|
||||||
var ids = yield Zotero.DB.columnQueryAsync(sql, params);
|
var ids = yield Zotero.DB.columnQueryAsync(sql, params);
|
||||||
|
|
||||||
for (let i=0; i<ids.length; i++) {
|
for (let i=0; i<ids.length; i++) {
|
||||||
let relation = yield this.get(ids[i]);
|
let relation = this.get(ids[i]);
|
||||||
|
yield relation.load();
|
||||||
yield relation.erase();
|
yield relation.erase();
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
@ -206,7 +207,8 @@ Zotero.Relations = function () {
|
||||||
var ids = yield Zotero.DB.columnQueryAsync(sql, params);
|
var ids = yield Zotero.DB.columnQueryAsync(sql, params);
|
||||||
|
|
||||||
for (let i=0; i<ids.length; i++) {
|
for (let i=0; i<ids.length; i++) {
|
||||||
let relation = yield this.get(ids[i]);
|
let relation = this.get(ids[i]);
|
||||||
|
yield relation.load();
|
||||||
yield relation.erase();
|
yield relation.erase();
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
@ -214,6 +216,8 @@ Zotero.Relations = function () {
|
||||||
|
|
||||||
|
|
||||||
this.purge = Zotero.Promise.coroutine(function* () {
|
this.purge = Zotero.Promise.coroutine(function* () {
|
||||||
|
Zotero.debug("Purging relations");
|
||||||
|
var t = new Date;
|
||||||
var sql = "SELECT subject FROM relations WHERE predicate != ? "
|
var sql = "SELECT subject FROM relations WHERE predicate != ? "
|
||||||
+ "UNION SELECT object FROM relations WHERE predicate != ?";
|
+ "UNION SELECT object FROM relations WHERE predicate != ?";
|
||||||
var uris = yield Zotero.DB.columnQueryAsync(sql, [this.deletedItemPredicate, this.deletedItemPredicate]);
|
var uris = yield Zotero.DB.columnQueryAsync(sql, [this.deletedItemPredicate, this.deletedItemPredicate]);
|
||||||
|
@ -226,14 +230,15 @@ Zotero.Relations = function () {
|
||||||
if (uri.indexOf(prefix) == -1) {
|
if (uri.indexOf(prefix) == -1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (uri.indexOf(/\/items\//) != -1 && !Zotero.URI.getURIItem(uri)) {
|
if (uri.indexOf("/items/") != -1 && !Zotero.URI.getURIItemID(uri)) {
|
||||||
this.eraseByURI(uri);
|
yield this.eraseByURI(uri);
|
||||||
}
|
}
|
||||||
if (uri.indexOf(/\/collections\//) != -1 && !Zotero.URI.getURICollection(uri)) {
|
if (uri.indexOf("/collections/") != -1 && !Zotero.URI.getURICollectionID(uri)) {
|
||||||
this.eraseByURI(uri);
|
yield this.eraseByURI(uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
Zotero.debug("Purged relations in " + ((new Date) - t) + "ms");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3100,6 +3100,8 @@ Zotero.Integration.URIMap.prototype.getZoteroItemForURIs = function(uris) {
|
||||||
|
|
||||||
// Next try getting URI directly
|
// Next try getting URI directly
|
||||||
try {
|
try {
|
||||||
|
// TEMP
|
||||||
|
throw new Error("getURIItem() is now async");
|
||||||
zoteroItem = Zotero.URI.getURIItem(uri);
|
zoteroItem = Zotero.URI.getURIItem(uri);
|
||||||
if(zoteroItem) {
|
if(zoteroItem) {
|
||||||
// Ignore items in the trash
|
// Ignore items in the trash
|
||||||
|
@ -3134,6 +3136,8 @@ Zotero.Integration.URIMap.prototype.getZoteroItemForURIs = function(uris) {
|
||||||
seen.push(uri);
|
seen.push(uri);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// TEMP
|
||||||
|
throw new Error("getURIItem() is now async");
|
||||||
zoteroItem = Zotero.URI.getURIItem(uri);
|
zoteroItem = Zotero.URI.getURIItem(uri);
|
||||||
if(zoteroItem) {
|
if(zoteroItem) {
|
||||||
// Ignore items in the trash
|
// Ignore items in the trash
|
||||||
|
|
|
@ -476,6 +476,11 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
yield this.refresh();
|
yield this.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (type == 'publications') {
|
||||||
|
if (collectionTreeRow.isPublications()) {
|
||||||
|
yield this.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
// If refreshing a single item, clear caches and then unselect and reselect row
|
// If refreshing a single item, clear caches and then unselect and reselect row
|
||||||
else if (savedSelection.length == 1 && savedSelection[0] == ids[0]) {
|
else if (savedSelection.length == 1 && savedSelection[0] == ids[0]) {
|
||||||
let row = this._itemRowMap[ids[0]];
|
let row = this._itemRowMap[ids[0]];
|
||||||
|
@ -545,7 +550,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
var rows = [];
|
var rows = [];
|
||||||
for (var i=0, len=ids.length; i<len; i++) {
|
for (var i=0, len=ids.length; i<len; i++) {
|
||||||
let push = false;
|
let push = false;
|
||||||
if (action == 'delete' && action == 'trash') {
|
if (action == 'delete' || action == 'trash') {
|
||||||
push = true;
|
push = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -627,8 +632,15 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
var parentItemID = this.getRow(row).ref.parentItemID;
|
var parentItemID = this.getRow(row).ref.parentItemID;
|
||||||
var parentIndex = this.getParentIndex(row);
|
var parentIndex = this.getParentIndex(row);
|
||||||
|
|
||||||
if (this.isContainer(row))
|
// Top-level item
|
||||||
{
|
if (this.isContainer(row)) {
|
||||||
|
// If removed from My Publications, remove row
|
||||||
|
if (collectionTreeRow.isPublications() && !item.publication) {
|
||||||
|
this._removeRow(row);
|
||||||
|
this._treebox.rowCountChanged(row, -1)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//yield this.toggleOpenState(row);
|
//yield this.toggleOpenState(row);
|
||||||
//yield this.toggleOpenState(row);
|
//yield this.toggleOpenState(row);
|
||||||
sort = id;
|
sort = id;
|
||||||
|
@ -1753,7 +1765,7 @@ Zotero.ItemTreeView.prototype.deleteSelection = Zotero.Promise.coroutine(functio
|
||||||
if (collectionTreeRow.isBucket()) {
|
if (collectionTreeRow.isBucket()) {
|
||||||
collectionTreeRow.ref.deleteItems(ids);
|
collectionTreeRow.ref.deleteItems(ids);
|
||||||
}
|
}
|
||||||
else if (collectionTreeRow.isTrash()) {
|
else if (collectionTreeRow.isTrash() || collectionTreeRow.isPublications()) {
|
||||||
Zotero.Items.erase(ids);
|
Zotero.Items.erase(ids);
|
||||||
}
|
}
|
||||||
else if (collectionTreeRow.isLibrary(true) || force) {
|
else if (collectionTreeRow.isLibrary(true) || force) {
|
||||||
|
|
|
@ -105,6 +105,7 @@ Zotero.LibraryTreeView.prototype = {
|
||||||
else {
|
else {
|
||||||
throw new Error("Invalid tree id '" + tree.id + "'");
|
throw new Error("Invalid tree id '" + tree.id + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!view.canDropCheck(row.value, Zotero.DragDrop.currentOrientation, event.dataTransfer)) {
|
if (!view.canDropCheck(row.value, Zotero.DragDrop.currentOrientation, event.dataTransfer)) {
|
||||||
this._setDropEffect(event, "none");
|
this._setDropEffect(event, "none");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -28,7 +28,8 @@ Zotero.Notifier = new function(){
|
||||||
var _disabled = false;
|
var _disabled = false;
|
||||||
var _types = [
|
var _types = [
|
||||||
'collection', 'search', 'share', 'share-items', 'item', 'file',
|
'collection', 'search', 'share', 'share-items', 'item', 'file',
|
||||||
'collection-item', 'item-tag', 'tag', 'setting', 'group', 'trash', 'bucket', 'relation'
|
'collection-item', 'item-tag', 'tag', 'setting', 'group', 'trash', 'publications',
|
||||||
|
'bucket', 'relation'
|
||||||
];
|
];
|
||||||
var _inTransaction;
|
var _inTransaction;
|
||||||
var _locked = false;
|
var _locked = false;
|
||||||
|
@ -50,7 +51,7 @@ Zotero.Notifier = new function(){
|
||||||
|
|
||||||
for (var i=0; i<types.length; i++){
|
for (var i=0; i<types.length; i++){
|
||||||
if (_types.indexOf(types[i]) == -1){
|
if (_types.indexOf(types[i]) == -1){
|
||||||
throw ('Invalid type ' + types[i] + ' in registerObserver()');
|
throw new Error('Invalid type ' + types[i] + ' in registerObserver()');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ Zotero.Report.HTML = new function () {
|
||||||
}
|
}
|
||||||
for (let i=0; i<rels.length; i++) {
|
for (let i=0; i<rels.length; i++) {
|
||||||
let rel = rels[i];
|
let rel = rels[i];
|
||||||
let relItem = Zotero.URI.getURIItem(rel);
|
let relItem = yield Zotero.URI.getURIItem(rel);
|
||||||
if (relItem) {
|
if (relItem) {
|
||||||
content += '\t\t\t\t\t<li id="item_' + relItem.key + '">';
|
content += '\t\t\t\t\t<li id="item_' + relItem.key + '">';
|
||||||
content += escapeXML(relItem.getDisplayTitle());
|
content += escapeXML(relItem.getDisplayTitle());
|
||||||
|
|
|
@ -1420,6 +1420,7 @@ Zotero.Schema = new function(){
|
||||||
yield _updateDBVersion('compatibility', _maxCompatibility);
|
yield _updateDBVersion('compatibility', _maxCompatibility);
|
||||||
|
|
||||||
yield Zotero.DB.queryAsync("INSERT INTO libraries (libraryID, libraryType) VALUES (?, 'user')", userLibraryID);
|
yield Zotero.DB.queryAsync("INSERT INTO libraries (libraryID, libraryType) VALUES (?, 'user')", userLibraryID);
|
||||||
|
yield Zotero.DB.queryAsync("INSERT INTO libraries (libraryID, libraryType) VALUES (2, 'publications')");
|
||||||
|
|
||||||
if (!Zotero.Schema.skipDefaultData) {
|
if (!Zotero.Schema.skipDefaultData) {
|
||||||
// Quick Start Guide web page item
|
// Quick Start Guide web page item
|
||||||
|
@ -1775,6 +1776,7 @@ Zotero.Schema = new function(){
|
||||||
yield _updateDBVersion('compatibility', 1);
|
yield _updateDBVersion('compatibility', 1);
|
||||||
|
|
||||||
yield Zotero.DB.queryAsync("INSERT INTO libraries VALUES (1, 'user')");
|
yield Zotero.DB.queryAsync("INSERT INTO libraries VALUES (1, 'user')");
|
||||||
|
yield Zotero.DB.queryAsync("INSERT INTO libraries VALUES (2, 'publications')");
|
||||||
|
|
||||||
let oldUserLibraryID = yield Zotero.DB.valueQueryAsync("SELECT value FROM settings WHERE setting='account' AND key='libraryID'");
|
let oldUserLibraryID = yield Zotero.DB.valueQueryAsync("SELECT value FROM settings WHERE setting='account' AND key='libraryID'");
|
||||||
|
|
||||||
|
|
|
@ -1007,7 +1007,6 @@ Zotero.Search.prototype._buildQuery = Zotero.Promise.coroutine(function* () {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'unfiled':
|
case 'unfiled':
|
||||||
this._conditions[i]['operator']
|
|
||||||
var unfiled = this._conditions[i]['operator'] == 'true';
|
var unfiled = this._conditions[i]['operator'] == 'true';
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1704,7 +1703,10 @@ Zotero.Searches = function() {
|
||||||
search.id = id;
|
search.id = id;
|
||||||
yield search.loadPrimaryData();
|
yield search.loadPrimaryData();
|
||||||
yield search.loadConditions();
|
yield search.loadConditions();
|
||||||
notifierData[id] = { old: search.serialize() };
|
notifierData[id] = {
|
||||||
|
libraryID: this.libraryID,
|
||||||
|
old: search.serialize() // TODO: replace with toJSON()
|
||||||
|
};
|
||||||
|
|
||||||
var sql = "DELETE FROM savedSearchConditions WHERE savedSearchID=?";
|
var sql = "DELETE FROM savedSearchConditions WHERE savedSearchID=?";
|
||||||
yield Zotero.DB.queryAsync(sql, id);
|
yield Zotero.DB.queryAsync(sql, id);
|
||||||
|
@ -1712,7 +1714,7 @@ Zotero.Searches = function() {
|
||||||
var sql = "DELETE FROM savedSearches WHERE savedSearchID=?";
|
var sql = "DELETE FROM savedSearches WHERE savedSearchID=?";
|
||||||
yield Zotero.DB.queryAsync(sql, id);
|
yield Zotero.DB.queryAsync(sql, id);
|
||||||
}
|
}
|
||||||
});
|
}.bind(this));
|
||||||
|
|
||||||
Zotero.Notifier.trigger('delete', 'search', ids, notifierData);
|
Zotero.Notifier.trigger('delete', 'search', ids, notifierData);
|
||||||
});
|
});
|
||||||
|
@ -1784,8 +1786,6 @@ Zotero.SearchConditions = new function(){
|
||||||
//
|
//
|
||||||
// Special conditions
|
// Special conditions
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'deleted',
|
name: 'deleted',
|
||||||
operators: {
|
operators: {
|
||||||
|
|
|
@ -301,14 +301,14 @@ Zotero.Sync.Storage.QueueManager = new function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function _reconcileConflicts(conflicts) {
|
var _reconcileConflicts = Zotero.Promise.coroutine(function* (conflicts) {
|
||||||
var objectPairs = [];
|
var objectPairs = [];
|
||||||
for each(var conflict in conflicts) {
|
for each(var conflict in conflicts) {
|
||||||
var item = Zotero.Sync.Storage.getItemFromRequestName(conflict.name);
|
var item = Zotero.Sync.Storage.getItemFromRequestName(conflict.name);
|
||||||
var item1 = item.clone(false, false, true);
|
var item1 = yield item.clone(false, false, true);
|
||||||
item1.setField('dateModified',
|
item1.setField('dateModified',
|
||||||
Zotero.Date.dateToSQL(new Date(conflict.localData.modTime), true));
|
Zotero.Date.dateToSQL(new Date(conflict.localData.modTime), true));
|
||||||
var item2 = item.clone(false, false, true);
|
var item2 = yield item.clone(false, false, true);
|
||||||
item2.setField('dateModified',
|
item2.setField('dateModified',
|
||||||
Zotero.Date.dateToSQL(new Date(conflict.remoteData.modTime), true));
|
Zotero.Date.dateToSQL(new Date(conflict.remoteData.modTime), true));
|
||||||
objectPairs.push([item1, item2]);
|
objectPairs.push([item1, item2]);
|
||||||
|
@ -342,7 +342,7 @@ Zotero.Sync.Storage.QueueManager = new function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
return io.dataOut;
|
return io.dataOut;
|
||||||
}
|
});
|
||||||
|
|
||||||
|
|
||||||
function _processMergeData(data) {
|
function _processMergeData(data) {
|
||||||
|
|
|
@ -86,10 +86,15 @@ Zotero.URI = new function () {
|
||||||
|
|
||||||
switch (libraryType) {
|
switch (libraryType) {
|
||||||
case 'user':
|
case 'user':
|
||||||
|
case 'publications':
|
||||||
var id = Zotero.Users.getCurrentUserID();
|
var id = Zotero.Users.getCurrentUserID();
|
||||||
if (!id) {
|
if (!id) {
|
||||||
throw new Exception("User id not available in Zotero.URI.getLibraryPath()");
|
throw new Exception("User id not available in Zotero.URI.getLibraryPath()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (libraryType == 'publications') {
|
||||||
|
return "users/" + id + "/publications";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'group':
|
case 'group':
|
||||||
|
@ -171,31 +176,78 @@ Zotero.URI = new function () {
|
||||||
*
|
*
|
||||||
* @param {String} itemURI
|
* @param {String} itemURI
|
||||||
* @param {Zotero.Item|FALSE}
|
* @param {Zotero.Item|FALSE}
|
||||||
|
* @return {Promise<Zotero.Item|FALSE>}
|
||||||
*/
|
*/
|
||||||
this.getURIItem = function (itemURI) {
|
this.getURIItem = Zotero.Promise.method(function (itemURI) {
|
||||||
|
var {libraryID, key} = this._getURIObject(itemURI, 'item');
|
||||||
|
if (!key) return false;
|
||||||
|
return Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} itemURI
|
||||||
|
* @return {Object|FALSE} - Object with 'libraryID' and 'key', or FALSE if item not found
|
||||||
|
*/
|
||||||
|
this.getURIItemLibraryKey = function (itemURI) {
|
||||||
return this._getURIObject(itemURI, 'item');
|
return this._getURIObject(itemURI, 'item');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} itemURI
|
||||||
|
* @return {Integer|FALSE} - itemID of matching item, or FALSE if none
|
||||||
|
*/
|
||||||
|
this.getURIItemID = function (itemURI) {
|
||||||
|
var {libraryID, key} = this._getURIObject(itemURI, 'item');
|
||||||
|
if (!key) return false;
|
||||||
|
return Zotero.Items.getIDFromLibraryAndKey(libraryID, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a collection URI into a collection
|
* Convert a collection URI into a collection
|
||||||
*
|
*
|
||||||
* @param {String} collectionURI
|
* @param {String} collectionURI
|
||||||
* @param {Zotero.Collection|FALSE}
|
* @param {Zotero.Collection|FALSE}
|
||||||
|
* @return {Promise<Zotero.Collection|FALSE>}
|
||||||
*/
|
*/
|
||||||
this.getURICollection = function (collectionURI) {
|
this.getURICollection = Zotero.Promise.method(function (collectionURI) {
|
||||||
|
var {libraryID, key} = this._getURIObject(collectionURI, 'collection');
|
||||||
|
if (!key) return false;
|
||||||
|
return Zotero.Collections.getByLibraryAndKeyAsync(libraryID, key);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} collectionURI
|
||||||
|
* @return {Object|FALSE} - Object with 'libraryID' and 'key', or FALSE if item not found
|
||||||
|
*/
|
||||||
|
this.getURICollectionLibraryKey = function (collectionURI) {
|
||||||
return this._getURIObject(collectionURI, 'collection');
|
return this._getURIObject(collectionURI, 'collection');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} collectionURI
|
||||||
|
* @return {Integer|FALSE} - collectionID of matching collection, or FALSE if none
|
||||||
|
*/
|
||||||
|
this.getURICollectionID = function (collectionURI) {
|
||||||
|
var {libraryID, key} = this._getURIObject(collectionURI, 'item');
|
||||||
|
if (!key) return false;
|
||||||
|
return Zotero.Collections.getIDFromLibraryAndKey(libraryID, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a library URI into a libraryID
|
* Convert a library URI into a libraryID
|
||||||
*
|
*
|
||||||
* @param {String} libraryURI
|
* @param {String} libraryURI
|
||||||
* @return {Zotero.Collection|FALSE}
|
* @return {Integer|FALSE} - libraryID, or FALSE if no matching library
|
||||||
*/
|
*/
|
||||||
this.getURILibrary = function (libraryURI) {
|
this.getURILibrary = function (libraryURI) {
|
||||||
return this._getURIObject(libraryURI, "library");
|
var {libraryID} = this._getURIObject(libraryURI, "library");
|
||||||
|
return libraryID !== undefined ? libraryID : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,17 +255,13 @@ Zotero.URI = new function () {
|
||||||
* Convert an object URI into an object (item, collection, etc.)
|
* Convert an object URI into an object (item, collection, etc.)
|
||||||
*
|
*
|
||||||
* @param {String} objectURI
|
* @param {String} objectURI
|
||||||
* @param {"item"|"collection"|"library"} [type] The type of object to return. If the object
|
* @param {'library'|'collection'|'item'} - The type of URI to expect
|
||||||
* is valid but not available, returns "false". Note that if type is "library", this
|
* @return {Object|FALSE} - An object containing 'libraryID' and, if applicable, 'key',
|
||||||
* this function may return null for the default library, which is distinct from false.
|
* or FALSE if library not found
|
||||||
*
|
|
||||||
* @return {Zotero.Item|Zotero.Collection|Integer|NULL|FALSE}
|
|
||||||
*/
|
*/
|
||||||
this._getURIObject = function (objectURI, type) {
|
this._getURIObject = function (objectURI, type) {
|
||||||
var Types = type[0].toUpperCase() + type.substr(1) + 's';
|
var libraryType;
|
||||||
var types = Types.toLowerCase();
|
var libraryTypeID;
|
||||||
|
|
||||||
var libraryType = null;
|
|
||||||
|
|
||||||
// If this is a local URI, compare to the local user key
|
// If this is a local URI, compare to the local user key
|
||||||
if (objectURI.match(/\/users\/local\//)) {
|
if (objectURI.match(/\/users\/local\//)) {
|
||||||
|
@ -229,72 +277,82 @@ Zotero.URI = new function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
var libraryType = 'user';
|
libraryType = 'user';
|
||||||
var id = null;
|
libraryTypeID = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not found, try global URI
|
// If not found, try global URI
|
||||||
if (!libraryType) {
|
if (!libraryType) {
|
||||||
if (objectURI.indexOf(_baseURI) != 0) {
|
if (!objectURI.startsWith(_baseURI)) {
|
||||||
throw ("Invalid base URI '" + objectURI + "' in Zotero.URI._getURIObject()");
|
throw new Error("Invalid base URI '" + objectURI + "'");
|
||||||
}
|
}
|
||||||
objectURI = objectURI.substr(_baseURI.length);
|
objectURI = objectURI.substr(_baseURI.length);
|
||||||
var typeRE = /^(users|groups)\/([0-9]+)(?:\/|$)/;
|
let typeRE = /^(users|groups)\/([0-9]+)(?:\/|$)/;
|
||||||
var matches = objectURI.match(typeRE);
|
let matches = objectURI.match(typeRE);
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
throw ("Invalid library URI '" + objectURI + "' in Zotero.URI._getURIObject()");
|
throw new Error("Invalid library URI '" + objectURI + "'");
|
||||||
}
|
}
|
||||||
var libraryType = matches[1].substr(0, matches[1].length-1);
|
libraryType = matches[1].substr(0, matches[1].length-1);
|
||||||
var id = matches[2];
|
libraryTypeID = matches[2];
|
||||||
objectURI = objectURI.replace(typeRE, '');
|
objectURI = objectURI.replace(typeRE, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libraryType == 'group') {
|
if (libraryType == 'user' && objectURI.startsWith('publications/')) {
|
||||||
if (!Zotero.Groups.get(id)) {
|
libraryType = 'publications';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (libraryType == 'user') {
|
||||||
|
var libraryID = Zotero.Libraries.userLibraryID;
|
||||||
|
}
|
||||||
|
else if (libraryType == 'group') {
|
||||||
|
if (!Zotero.Groups.exists(libraryTypeID)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var libraryID = Zotero.Groups.getLibraryIDFromGroupID(id);
|
var libraryID = Zotero.Groups.getLibraryIDFromGroupID(libraryTypeID);
|
||||||
|
}
|
||||||
|
else if (libraryType == 'publications') {
|
||||||
|
var libraryID = Zotero.Libraries.publicationsLibraryID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type === 'library') {
|
if(type === 'library') {
|
||||||
if (libraryType == 'user') {
|
if (libraryType == 'user') {
|
||||||
if(id === null) {
|
if (libraryTypeID) {
|
||||||
|
if (libraryTypeID == Zotero.Users.getCurrentUserID()) {
|
||||||
|
return {
|
||||||
|
libraryID: libraryID
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
var localUserURI = this.getLocalUserURI();
|
var localUserURI = this.getLocalUserURI();
|
||||||
if (localUserURI) {
|
if (localUserURI) {
|
||||||
localUserURI += "/";
|
localUserURI += "/";
|
||||||
if (objectURI.indexOf(localUserURI) == 0) {
|
if (objectURI.startsWith(localUserURI)) {
|
||||||
objectURI = objectURI.substr(localUserURI.length);
|
return {
|
||||||
return null;
|
libraryID: Zotero.Libraries.userLibraryID
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if(id == Zotero.Users.getCurrentUserID()) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libraryType == 'group') {
|
if (libraryType == 'group') {
|
||||||
return libraryID;
|
return {
|
||||||
|
libraryID: libraryID
|
||||||
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: objectID-based URI?
|
var re = /(?:items|collections)\/([A-Z0-9]{8})/;
|
||||||
var re = new RegExp(types + "\/([A-Z0-9]{8})");
|
|
||||||
var matches = objectURI.match(re);
|
var matches = objectURI.match(re);
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
throw ("Invalid object URI '" + objectURI + "' in Zotero.URI._getURIObject()");
|
throw ("Invalid object URI '" + objectURI + "' in Zotero.URI._getURIObject()");
|
||||||
}
|
}
|
||||||
var objectKey = matches[1];
|
let objectKey = matches[1];
|
||||||
|
return {
|
||||||
if (libraryType == 'user') {
|
libraryID: libraryID,
|
||||||
return Zotero[Types].getByLibraryAndKey(null, objectKey);
|
key: objectKey
|
||||||
}
|
};
|
||||||
|
|
||||||
if (libraryType == 'group') {
|
|
||||||
return Zotero[Types].getByLibraryAndKey(libraryID, objectKey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -847,6 +847,10 @@ Zotero.Utilities = {
|
||||||
return newString;
|
return newString;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"capitalize": function (str) {
|
||||||
|
return str[0].toUpperCase() + str.substr(1);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces accented characters in a string with ASCII equivalents
|
* Replaces accented characters in a string with ASCII equivalents
|
||||||
*
|
*
|
||||||
|
|
|
@ -2079,7 +2079,7 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
//Zotero.Fulltext.purgeUnusedWords();
|
//Zotero.Fulltext.purgeUnusedWords();
|
||||||
yield Zotero.Items.purge();
|
yield Zotero.Items.purge();
|
||||||
// DEBUG: this might not need to be permanent
|
// DEBUG: this might not need to be permanent
|
||||||
Zotero.Relations.purge();
|
yield Zotero.Relations.purge();
|
||||||
yield Zotero.CharacterSets.purge();
|
yield Zotero.CharacterSets.purge();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2679,7 +2679,7 @@ Zotero.DragDrop = {
|
||||||
|
|
||||||
getDragSource: function (dataTransfer) {
|
getDragSource: function (dataTransfer) {
|
||||||
if (!dataTransfer) {
|
if (!dataTransfer) {
|
||||||
Zotero.debug("Drag data not available", 2);
|
//Zotero.debug("Drag data not available", 2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -523,13 +523,17 @@ var ZoteroPane = new function()
|
||||||
function setHighlightedRowsCallback() {
|
function setHighlightedRowsCallback() {
|
||||||
var itemIDs = ZoteroPane_Local.getSelectedItems(true);
|
var itemIDs = ZoteroPane_Local.getSelectedItems(true);
|
||||||
if (itemIDs && itemIDs.length) {
|
if (itemIDs && itemIDs.length) {
|
||||||
Zotero.Collections.getCollectionsContainingItems(itemIDs, true)
|
Zotero.Promise.coroutine(function* () {
|
||||||
.then(function (collectionIDs) {
|
var collectionIDs = yield Zotero.Collections.getCollectionsContainingItems(itemIDs, true);
|
||||||
if (collectionIDs) {
|
var ids = collectionIDs.map(id => "C" + id);
|
||||||
ZoteroPane_Local.collectionsView.setHighlightedRows(collectionIDs);
|
Zotero.debug(Zotero.Items.get(itemIDs).some(item => !item.publication));
|
||||||
|
if (!Zotero.Items.get(itemIDs).some(item => !item.publication)) {
|
||||||
|
ids.push("P");
|
||||||
}
|
}
|
||||||
})
|
if (ids.length) {
|
||||||
.done();
|
ZoteroPane_Local.collectionsView.setHighlightedRows(ids);
|
||||||
|
}
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1543,7 +1547,7 @@ var ZoteroPane = new function()
|
||||||
var id = yield newItem.save();
|
var id = yield newItem.save();
|
||||||
|
|
||||||
var newItem = yield Zotero.Items.getAsync(id);
|
var newItem = yield Zotero.Items.getAsync(id);
|
||||||
item.clone(false, newItem, false, !Zotero.Prefs.get('groups.copyTags'));
|
yield item.clone(false, newItem, false, !Zotero.Prefs.get('groups.copyTags'));
|
||||||
yield newItem.save();
|
yield newItem.save();
|
||||||
|
|
||||||
if (self.collectionsView.selectedTreeRow.isCollection() && newItem.isTopLevelItem()) {
|
if (self.collectionsView.selectedTreeRow.isCollection() && newItem.isTopLevelItem()) {
|
||||||
|
@ -1591,7 +1595,10 @@ var ZoteroPane = new function()
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (collectionTreeRow.isLibrary(true)) {
|
if (collectionTreeRow.isPublications()) {
|
||||||
|
var prompt = toDelete;
|
||||||
|
}
|
||||||
|
else if (collectionTreeRow.isLibrary(true)) {
|
||||||
// In library, don't prompt if meta key was pressed
|
// In library, don't prompt if meta key was pressed
|
||||||
var prompt = (force && !fromMenu) ? false : toTrash;
|
var prompt = (force && !fromMenu) ? false : toTrash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,7 @@ pane.collections.newSavedSeach = New Saved Search
|
||||||
pane.collections.savedSearchName = Enter a name for this saved search:
|
pane.collections.savedSearchName = Enter a name for this saved search:
|
||||||
pane.collections.rename = Rename collection:
|
pane.collections.rename = Rename collection:
|
||||||
pane.collections.library = My Library
|
pane.collections.library = My Library
|
||||||
|
pane.collections.publications = My Publications
|
||||||
pane.collections.groupLibraries = Group Libraries
|
pane.collections.groupLibraries = Group Libraries
|
||||||
pane.collections.trash = Trash
|
pane.collections.trash = Trash
|
||||||
pane.collections.untitled = Untitled
|
pane.collections.untitled = Untitled
|
||||||
|
|
|
@ -10,6 +10,12 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Why is this necessary? */
|
||||||
|
#zotero-collections-tree treechildren::-moz-tree-image,
|
||||||
|
#zotero-items-tree treechildren::-moz-tree-image {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
#zotero-collections-pane
|
#zotero-collections-pane
|
||||||
{
|
{
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
|
@ -20,17 +26,17 @@
|
||||||
min-height: 5.2em;
|
min-height: 5.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-collections-tree treechildren::-moz-tree-image(primary)
|
#zotero-collections-tree treechildren::-moz-tree-row {
|
||||||
{
|
height: 1.7em;
|
||||||
margin-right: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-collections-tree #zotero-collections-sync-status-column {
|
/*#zotero-collections-tree treechildren::-moz-tree-separator {
|
||||||
width: 35px;
|
border: none;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#zotero-collections-tree[hidevscroll] #zotero-collections-sync-status-column {
|
#zotero-collections-tree treechildren::-moz-tree-twisty(notwisty),
|
||||||
width: 21px;
|
#zotero-collections-tree treechildren::-moz-tree-twisty(header) {
|
||||||
|
width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set by setHighlightedRows() and getRowProperties() in collectionTreeView.js) */
|
/* Set by setHighlightedRows() and getRowProperties() in collectionTreeView.js) */
|
||||||
|
@ -39,11 +45,6 @@
|
||||||
background: #FFFF99 !important;
|
background: #FFFF99 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#zotero-collections-tree treechildren::-moz-tree-row(separator)
|
|
||||||
{
|
|
||||||
height: .25em;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
#zotero-pane splitter
|
#zotero-pane splitter
|
||||||
{
|
{
|
||||||
border: 0;
|
border: 0;
|
||||||
|
@ -60,11 +61,6 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-items-tree treechildren::-moz-tree-image
|
|
||||||
{
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#zotero-items-tree treechildren::-moz-tree-image(hasAttachment, pie)
|
#zotero-items-tree treechildren::-moz-tree-image(hasAttachment, pie)
|
||||||
{
|
{
|
||||||
margin: 1px 0 0;
|
margin: 1px 0 0;
|
||||||
|
|
BIN
chrome/skin/default/zotero/treeitem-journalArticle@2x.png
Normal file
BIN
chrome/skin/default/zotero/treeitem-journalArticle@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Loading…
Reference in a new issue