Closes #1868, Dragging collections into group libraries
This commit is contained in:
parent
7aa474e584
commit
067df94822
|
@ -235,24 +235,8 @@ Zotero.CollectionTreeView.prototype.refresh = function()
|
|||
*/
|
||||
Zotero.CollectionTreeView.prototype.reload = function()
|
||||
{
|
||||
var openCollections = [];
|
||||
|
||||
for (var i=0; i<this.rowCount; i++) {
|
||||
if (this.isContainer(i) && this.isContainerOpen(i)) {
|
||||
openCollections.push(this._getItemAtRow(i).ref.id);
|
||||
}
|
||||
}
|
||||
|
||||
this._treebox.beginUpdateBatch();
|
||||
this.refresh();
|
||||
|
||||
for(var i = 0; i < openCollections.length; i++)
|
||||
{
|
||||
var row = this._collectionRowMap[openCollections[i]];
|
||||
if (typeof row != 'undefined') {
|
||||
this.toggleOpenState(row);
|
||||
}
|
||||
}
|
||||
this._treebox.invalidate();
|
||||
this._treebox.endUpdateBatch();
|
||||
}
|
||||
|
@ -360,9 +344,9 @@ Zotero.CollectionTreeView.prototype.notify = function(action, type, ids)
|
|||
{
|
||||
case 'collection':
|
||||
var collection = Zotero.Collections.get(ids);
|
||||
var collectionID = collection.id;
|
||||
|
||||
// Open container if creating subcollection
|
||||
var parentID = collection.getParent();
|
||||
var parentID = collection.parent;
|
||||
if (parentID) {
|
||||
if (!this.isContainerOpen(this._collectionRowMap[parentID])){
|
||||
this.toggleOpenState(this._collectionRowMap[parentID]);
|
||||
|
@ -374,7 +358,7 @@ Zotero.CollectionTreeView.prototype.notify = function(action, type, ids)
|
|||
this.rememberSelection(savedSelection);
|
||||
break;
|
||||
}
|
||||
this.selection.select(this._collectionRowMap[collectionID]);
|
||||
this.selection.select(this._collectionRowMap[collection.id]);
|
||||
break;
|
||||
|
||||
case 'search':
|
||||
|
@ -1259,27 +1243,42 @@ Zotero.CollectionTreeView.prototype.canDrop = function(row, orient, dragData)
|
|||
return true;
|
||||
}
|
||||
else if (dataType == 'zotero/collection') {
|
||||
// Collections cannot be dropped on themselves
|
||||
if (data[0] == itemGroup.ref.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Nor in their children
|
||||
if (Zotero.Collections.get(data[0]).hasDescendent('collection', itemGroup.ref.id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var col = Zotero.Collections.get(data[0]);
|
||||
|
||||
// Nor, at least for now, on another group
|
||||
if (itemGroup.isWithinGroup()) {
|
||||
if (itemGroup.ref.libraryID != col.libraryID) {
|
||||
if (itemGroup.ref.libraryID == col.libraryID) {
|
||||
// Collections cannot be dropped on themselves
|
||||
if (data[0] == itemGroup.ref.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Nor in their children
|
||||
if (Zotero.Collections.get(data[0]).hasDescendent('collection', itemGroup.ref.id)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Nor from a group library to the local library
|
||||
else if (col.libraryID) {
|
||||
return false;
|
||||
// Dragging a collection to a different library
|
||||
else {
|
||||
// Allow cross-library drag only to root library and collections
|
||||
if (!itemGroup.isLibrary(true) && !itemGroup.isCollection()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disallow if linked collection already exists
|
||||
if (col.getLinkedCollection(itemGroup.ref.libraryID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var descendents = col.getDescendents(false, 'collection');
|
||||
for each(var descendent in descendents) {
|
||||
descendent = Zotero.Collections.get(descendent.id);
|
||||
// Disallow if linked collection already exists for any subcollections
|
||||
//
|
||||
// If this is allowed in the future for the root collection,
|
||||
// need to allow drag only to root
|
||||
if (descendent.getLinkedCollection(itemGroup.ref.libraryID)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1303,15 +1302,202 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
var data = dragData.data;
|
||||
var itemGroup = this._getItemAtRow(row);
|
||||
|
||||
if(dataType == 'zotero/collection')
|
||||
{
|
||||
var targetCollectionID;
|
||||
if (itemGroup.isCollection()) {
|
||||
targetCollectionID = itemGroup.ref.id;
|
||||
function copyItem (item, targetLibraryID) {
|
||||
// Check if there's already a copy of this item in the library
|
||||
var linkedItem = item.getLinkedItem(targetLibraryID);
|
||||
if (linkedItem) {
|
||||
return linkedItem.id;
|
||||
|
||||
/*
|
||||
// TODO: support tags, related, attachments, etc.
|
||||
|
||||
// Overlay source item fields on unsaved clone of linked item
|
||||
var newItem = item.clone(false, linkedItem.clone(true));
|
||||
newItem.setField('dateAdded', item.dateAdded);
|
||||
newItem.setField('dateModified', item.dateModified);
|
||||
|
||||
var diff = newItem.diff(linkedItem, false, ["dateAdded", "dateModified"]);
|
||||
if (!diff) {
|
||||
// Check if creators changed
|
||||
var creatorsChanged = false;
|
||||
|
||||
var creators = item.getCreators();
|
||||
var linkedCreators = linkedItem.getCreators();
|
||||
if (creators.length != linkedCreators.length) {
|
||||
Zotero.debug('Creators have changed');
|
||||
creatorsChanged = true;
|
||||
}
|
||||
else {
|
||||
for (var i=0; i<creators.length; i++) {
|
||||
if (!creators[i].ref.equals(linkedCreators[i].ref)) {
|
||||
Zotero.debug('changed');
|
||||
creatorsChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!creatorsChanged) {
|
||||
Zotero.debug("Linked item hasn't changed -- skipping conflict resolution");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
toReconcile.push([newItem, linkedItem]);
|
||||
continue;
|
||||
*/
|
||||
}
|
||||
|
||||
// Standalone attachment
|
||||
if (item.isAttachment()) {
|
||||
return Zotero.Attachments.copyAttachmentToLibrary(item, targetLibraryID);
|
||||
}
|
||||
|
||||
// Create new unsaved clone item in target library
|
||||
var newItem = new Zotero.Item(item.itemTypeID);
|
||||
newItem.libraryID = targetLibraryID;
|
||||
// DEBUG: save here because clone() doesn't currently work on unsaved tagged items
|
||||
var id = newItem.save();
|
||||
newItem = Zotero.Items.get(id);
|
||||
item.clone(false, newItem);
|
||||
newItem.save();
|
||||
//var id = newItem.save();
|
||||
//var newItem = Zotero.Items.get(id);
|
||||
|
||||
// Record link
|
||||
item.addLinkedItem(newItem);
|
||||
var newID = id;
|
||||
|
||||
if (item.isNote()) {
|
||||
return newID;
|
||||
}
|
||||
|
||||
// For regular items, add child items if prefs and permissions allow
|
||||
|
||||
// Child notes
|
||||
if (Zotero.Prefs.get('groups.copyChildNotes')) {
|
||||
var noteIDs = item.getNotes();
|
||||
var notes = Zotero.Items.get(noteIDs);
|
||||
for each(var note in notes) {
|
||||
var newNote = new Zotero.Item('note');
|
||||
newNote.libraryID = targetLibraryID;
|
||||
// DEBUG: save here because clone() doesn't currently work on unsaved tagged items
|
||||
var id = newNote.save();
|
||||
newNote = Zotero.Items.get(id);
|
||||
note.clone(false, newNote);
|
||||
newNote.setSource(newItem.id);
|
||||
newNote.save();
|
||||
|
||||
note.addLinkedItem(newNote);
|
||||
}
|
||||
}
|
||||
|
||||
// Child attachments
|
||||
var copyChildLinks = Zotero.Prefs.get('groups.copyChildLinks');
|
||||
var copyChildFileAttachments = Zotero.Prefs.get('groups.copyChildFileAttachments');
|
||||
if (copyChildLinks || copyChildFileAttachments) {
|
||||
var attachmentIDs = item.getAttachments();
|
||||
var attachments = Zotero.Items.get(attachmentIDs);
|
||||
for each(var attachment in attachments) {
|
||||
var linkMode = attachment.attachmentLinkMode;
|
||||
|
||||
// Skip linked files
|
||||
if (linkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip imported files if we don't have pref and permissions
|
||||
if (linkMode == Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
||||
if (!copyChildLinks) {
|
||||
Zotero.debug("Skipping child link attachment on drag");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!copyChildFileAttachments || !itemGroup.filesEditable) {
|
||||
Zotero.debug("Skipping child file attachment on drag");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Zotero.Attachments.copyAttachmentToLibrary(attachment, targetLibraryID, newItem.id);
|
||||
}
|
||||
}
|
||||
|
||||
return newID;
|
||||
}
|
||||
|
||||
|
||||
var targetLibraryID = itemGroup.isWithinGroup() ? itemGroup.ref.libraryID : null;
|
||||
var targetCollectionID = itemGroup.isCollection() ? itemGroup.ref.id : false;
|
||||
|
||||
if (dataType == 'zotero/collection') {
|
||||
var droppedCollection = Zotero.Collections.get(data[0]);
|
||||
droppedCollection.parent = targetCollectionID;
|
||||
droppedCollection.save();
|
||||
|
||||
// Collection drag between libraries
|
||||
if (targetLibraryID != droppedCollection.libraryID) {
|
||||
Zotero.DB.beginTransaction();
|
||||
|
||||
function copyCollections(descendents, parent, addItems) {
|
||||
for each(var desc in descendents) {
|
||||
// Collections
|
||||
if (desc.type == 'collection') {
|
||||
var c = Zotero.Collections.get(desc.id);
|
||||
|
||||
var newCollection = new Zotero.Collection;
|
||||
newCollection.libraryID = targetLibraryID;
|
||||
c.clone(false, newCollection);
|
||||
if (parent) {
|
||||
newCollection.parent = parent;
|
||||
}
|
||||
var collectionID = newCollection.save();
|
||||
|
||||
// Record link
|
||||
c.addLinkedCollection(newCollection);
|
||||
|
||||
// Recursively copy subcollections
|
||||
if (desc.children.length) {
|
||||
copyCollections(desc.children, collectionID, addItems);
|
||||
}
|
||||
}
|
||||
// Items
|
||||
else {
|
||||
var item = Zotero.Items.get(desc.id);
|
||||
var id = copyItem(item, targetLibraryID);
|
||||
// Mark copied item for adding to collection
|
||||
if (parent) {
|
||||
if (!addItems[parent]) {
|
||||
addItems[parent] = [];
|
||||
}
|
||||
addItems[parent].push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return collectionID;
|
||||
}
|
||||
|
||||
var collections = [{
|
||||
id: droppedCollection.id,
|
||||
children: droppedCollection.getDescendents(true),
|
||||
type: 'collection'
|
||||
}];
|
||||
|
||||
var addItems = {};
|
||||
copyCollections(collections, targetCollectionID, addItems);
|
||||
for (var collectionID in addItems) {
|
||||
var collection = Zotero.Collections.get(collectionID);
|
||||
collection.addItems(addItems[collectionID]);
|
||||
}
|
||||
|
||||
// TODO: add subcollections and subitems, if they don't already exist,
|
||||
// and display a warning if any of the subcollections already exist
|
||||
|
||||
Zotero.DB.commitTransaction();
|
||||
}
|
||||
// Collection drag within a library
|
||||
else {
|
||||
droppedCollection.parent = targetCollectionID;
|
||||
droppedCollection.save();
|
||||
}
|
||||
}
|
||||
else if (dataType == 'zotero/item') {
|
||||
var ids = data;
|
||||
|
@ -1319,13 +1505,6 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
return;
|
||||
}
|
||||
|
||||
if (itemGroup.isWithinGroup()) {
|
||||
var targetLibraryID = itemGroup.ref.libraryID;
|
||||
}
|
||||
else {
|
||||
var targetLibraryID = null;
|
||||
}
|
||||
|
||||
if(itemGroup.isBucket()) {
|
||||
itemGroup.ref.uploadItems(ids);
|
||||
return;
|
||||
|
@ -1335,6 +1514,7 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
|
||||
var items = Zotero.Items.get(ids);
|
||||
if (!items) {
|
||||
Zotero.DB.commitTransaction();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1364,131 +1544,9 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
if (!sameLibrary) {
|
||||
var toReconcile = [];
|
||||
|
||||
var newIDs = [];
|
||||
for each(var item in newItems) {
|
||||
// Check if there's already a copy of this item in the library
|
||||
var linkedItem = item.getLinkedItem(targetLibraryID);
|
||||
if (linkedItem) {
|
||||
// Add linked item to target collection rather than copying
|
||||
if (itemGroup.isCollection()) {
|
||||
itemGroup.ref.addItem(linkedItem.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: support tags, related, attachments, etc.
|
||||
|
||||
// Overlay source item fields on unsaved clone of linked item
|
||||
var newItem = item.clone(false, linkedItem.clone(true));
|
||||
newItem.setField('dateAdded', item.dateAdded);
|
||||
newItem.setField('dateModified', item.dateModified);
|
||||
|
||||
var diff = newItem.diff(linkedItem, false, ["dateAdded", "dateModified"]);
|
||||
if (!diff) {
|
||||
// Check if creators changed
|
||||
var creatorsChanged = false;
|
||||
|
||||
var creators = item.getCreators();
|
||||
var linkedCreators = linkedItem.getCreators();
|
||||
if (creators.length != linkedCreators.length) {
|
||||
Zotero.debug('Creators have changed');
|
||||
creatorsChanged = true;
|
||||
}
|
||||
else {
|
||||
for (var i=0; i<creators.length; i++) {
|
||||
if (!creators[i].ref.equals(linkedCreators[i].ref)) {
|
||||
Zotero.debug('changed');
|
||||
creatorsChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!creatorsChanged) {
|
||||
Zotero.debug("Linked item hasn't changed -- skipping conflict resolution");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
toReconcile.push([newItem, linkedItem]);
|
||||
continue;
|
||||
*/
|
||||
}
|
||||
|
||||
// Standalone attachment
|
||||
if (item.isAttachment()) {
|
||||
var id = Zotero.Attachments.copyAttachmentToLibrary(item, targetLibraryID);
|
||||
newIDs.push(id);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create new unsaved clone item in target library
|
||||
var newItem = new Zotero.Item(item.itemTypeID);
|
||||
newItem.libraryID = targetLibraryID;
|
||||
// DEBUG: save here because clone() doesn't currently work on unsaved tagged items
|
||||
var id = newItem.save();
|
||||
newItem = Zotero.Items.get(id);
|
||||
item.clone(false, newItem);
|
||||
newItem.save();
|
||||
//var id = newItem.save();
|
||||
//var newItem = Zotero.Items.get(id);
|
||||
|
||||
// Record link
|
||||
item.addLinkedItem(newItem);
|
||||
newIDs.push(id);
|
||||
|
||||
if (item.isNote()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For regular items, add child items if prefs and permissions allow
|
||||
|
||||
// Child notes
|
||||
if (Zotero.Prefs.get('groups.copyChildNotes')) {
|
||||
var noteIDs = item.getNotes();
|
||||
var notes = Zotero.Items.get(noteIDs);
|
||||
for each(var note in notes) {
|
||||
var newNote = new Zotero.Item('note');
|
||||
newNote.libraryID = targetLibraryID;
|
||||
// DEBUG: save here because clone() doesn't currently work on unsaved tagged items
|
||||
var id = newNote.save();
|
||||
newNote = Zotero.Items.get(id);
|
||||
note.clone(false, newNote);
|
||||
newNote.setSource(newItem.id);
|
||||
newNote.save();
|
||||
|
||||
note.addLinkedItem(newNote);
|
||||
}
|
||||
}
|
||||
|
||||
// Child attachments
|
||||
var copyChildLinks = Zotero.Prefs.get('groups.copyChildLinks');
|
||||
var copyChildFileAttachments = Zotero.Prefs.get('groups.copyChildFileAttachments');
|
||||
if (copyChildLinks || copyChildFileAttachments) {
|
||||
var attachmentIDs = item.getAttachments();
|
||||
var attachments = Zotero.Items.get(attachmentIDs);
|
||||
for each(var attachment in attachments) {
|
||||
var linkMode = attachment.attachmentLinkMode;
|
||||
|
||||
// Skip linked files
|
||||
if (linkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip imported files if we don't have pref and permissions
|
||||
if (linkMode == Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
||||
if (!copyChildLinks) {
|
||||
Zotero.debug("Skipping child link attachment on drag");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!copyChildFileAttachments || !itemGroup.filesEditable) {
|
||||
Zotero.debug("Skipping child file attachment on drag");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var id = Zotero.Attachments.copyAttachmentToLibrary(attachment, targetLibraryID, newItem.id);
|
||||
}
|
||||
}
|
||||
newIDs.push(copyItem(item, libraryID));
|
||||
}
|
||||
|
||||
if (toReconcile.length) {
|
||||
|
@ -1529,8 +1587,10 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
}
|
||||
}
|
||||
|
||||
if (newIDs.length && itemGroup.isCollection()) {
|
||||
itemGroup.ref.addItems(newIDs);
|
||||
// Add items to target collection
|
||||
if (targetCollectionID) {
|
||||
var collection = Zotero.Collections.get(targetCollectionID);
|
||||
collection.addItems(newIDs);
|
||||
}
|
||||
|
||||
Zotero.DB.commitTransaction();
|
||||
|
|
|
@ -896,6 +896,40 @@ Zotero.Collection.prototype.diff = function (collection, includeMatches, ignoreO
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an unsaved copy of the collection
|
||||
*
|
||||
* Does not copy parent collection or child items
|
||||
*
|
||||
* @param {Boolean} [includePrimary=false]
|
||||
* @param {Zotero.Collection} [newCollection=null]
|
||||
*/
|
||||
Zotero.Collection.prototype.clone = function (includePrimary, newCollection) {
|
||||
Zotero.debug('Cloning collection ' + this.id);
|
||||
|
||||
if (newCollection) {
|
||||
var sameLibrary = newCollection.libraryID == this.libraryID;
|
||||
}
|
||||
else {
|
||||
var newCollection = new Zotero.Collection;
|
||||
var sameLibrary = true;
|
||||
|
||||
if (includePrimary) {
|
||||
newCollection.id = this.id;
|
||||
newCollection.libraryID = this.libraryID;
|
||||
newCollection.key = this.key;
|
||||
|
||||
// TODO: This isn't used, but if it were, it should probably include
|
||||
// parent collection and child items
|
||||
}
|
||||
}
|
||||
|
||||
newCollection.name = this.name;
|
||||
|
||||
return newCollection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes collection and all descendent collections (and optionally items)
|
||||
**/
|
||||
|
@ -930,6 +964,10 @@ Zotero.Collection.prototype.erase = function(deleteItems) {
|
|||
Zotero.Items.erase(del);
|
||||
}
|
||||
|
||||
// Remove relations
|
||||
var uri = Zotero.URI.getCollectionURI(this);
|
||||
Zotero.Relations.eraseByURIPrefix(uri);
|
||||
|
||||
var placeholders = collections.map(function () '?').join();
|
||||
|
||||
// Remove item associations for all descendent collections
|
||||
|
@ -1095,6 +1133,60 @@ Zotero.Collection.prototype.getDescendents = function(nested, type, includeDelet
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a collection in the specified library equivalent to this collection
|
||||
*/
|
||||
Zotero.Collection.prototype.getLinkedCollection = function (libraryID) {
|
||||
if (libraryID == this.libraryID) {
|
||||
throw ("Collection is already in library " + libraryID + " in Zotero.Collection.getLinkedCollection()");
|
||||
}
|
||||
|
||||
var predicate = Zotero.Relations.linkedObjectPredicate;
|
||||
var collectionURI = Zotero.URI.getCollectionURI(this);
|
||||
var links = Zotero.Relations.getObject(collectionURI, predicate, false).concat(
|
||||
Zotero.Relations.getSubject(false, predicate, collectionURI)
|
||||
);
|
||||
|
||||
if (!links.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (libraryID) {
|
||||
var libraryCollectionPrefix = Zotero.URI.getLibraryURI(libraryID) + "/collections/";
|
||||
}
|
||||
else {
|
||||
var libraryCollectionPrefix = Zotero.URI.getCurrentUserURI() + "/collections/";
|
||||
}
|
||||
for each(var link in links) {
|
||||
if (link.indexOf(libraryCollectionPrefix) == 0) {
|
||||
var collection = Zotero.URI.getURICollection(link);
|
||||
if (!collection) {
|
||||
Zotero.debug("Referenced linked collection '" + link + "' not found in Zotero.Collection.getLinkedCollection()", 2);
|
||||
continue;
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Zotero.Collection.prototype.addLinkedCollection = function (collection) {
|
||||
var url1 = Zotero.URI.getCollectionURI(this);
|
||||
var url2 = Zotero.URI.getCollectionURI(collection);
|
||||
var predicate = Zotero.Relations.linkedObjectPredicate;
|
||||
if (Zotero.Relations.getByURIs(url1, predicate, url2).length
|
||||
|| Zotero.Relations.getByURIs(url2, predicate, url1).length) {
|
||||
Zotero.debug("Collections " + this.key + " and " + collection.key + " are already linked");
|
||||
return false;
|
||||
}
|
||||
Zotero.Relations.add(null, url1, predicate, url2);
|
||||
}
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
|
||||
Zotero.Collection.prototype._prepFieldChange = function (field) {
|
||||
if (!this._changed) {
|
||||
this._changed = {};
|
||||
|
|
|
@ -3548,12 +3548,12 @@ Zotero.Item.prototype.getLinkedItem = function (libraryID) {
|
|||
throw ("Item is already in library " + libraryID + " in Zotero.Item.getLinkedItem()");
|
||||
}
|
||||
|
||||
var predicate = Zotero.Items.linkedItemPredicate;
|
||||
var predicate = Zotero.Relations.linkedObjectPredicate;
|
||||
var itemURI = Zotero.URI.getItemURI(this);
|
||||
var links = Zotero.Relations.getObject(itemURI, predicate, false).concat(
|
||||
Zotero.Relations.getSubject(false, predicate, itemURI)
|
||||
);
|
||||
Zotero.debug(links);
|
||||
|
||||
if (!links.length) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3581,7 +3581,7 @@ Zotero.Item.prototype.getLinkedItem = function (libraryID) {
|
|||
Zotero.Item.prototype.addLinkedItem = function (item) {
|
||||
var url1 = Zotero.URI.getItemURI(this);
|
||||
var url2 = Zotero.URI.getItemURI(item);
|
||||
var predicate = Zotero.Items.linkedItemPredicate;
|
||||
var predicate = Zotero.Relations.linkedObjectPredicate;
|
||||
if (Zotero.Relations.getByURIs(url1, predicate, url2).length
|
||||
|| Zotero.Relations.getByURIs(url2, predicate, url1).length) {
|
||||
Zotero.debug("Items " + this.key + " and " + item.key + " are already linked");
|
||||
|
|
|
@ -52,7 +52,6 @@ Zotero.Items = new function() {
|
|||
return _primaryFields;
|
||||
});
|
||||
|
||||
this.__defineGetter__('linkedItemPredicate', function () "owl:sameAs");
|
||||
|
||||
// Private members
|
||||
var _cachedFields = [];
|
||||
|
|
|
@ -27,6 +27,7 @@ Zotero.Relations = new function () {
|
|||
Zotero.DataObjects.apply(this, ['relation']);
|
||||
this.constructor.prototype = new Zotero.DataObjects();
|
||||
|
||||
this.__defineGetter__('linkedObjectPredicate', function () "owl:sameAs");
|
||||
this.__defineGetter__('deletedItemPredicate', function () 'dc:isReplacedBy');
|
||||
|
||||
var _namespaces = {
|
||||
|
@ -226,7 +227,10 @@ Zotero.Relations = new function () {
|
|||
if (uri.indexOf(prefix) == -1) {
|
||||
continue;
|
||||
}
|
||||
if (!Zotero.URI.getURIItem(uri)) {
|
||||
if (uri.indexOf(/\/items\//) != -1 && !Zotero.URI.getURIItem(uri)) {
|
||||
this.eraseByURI(uri);
|
||||
}
|
||||
if (uri.indexOf(/\/collections\//) != -1 && !Zotero.URI.getURICollection(uri)) {
|
||||
this.eraseByURI(uri);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,28 @@ Zotero.URI = new function () {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return URI of collection, which might be a local URI if user hasn't synced
|
||||
*/
|
||||
this.getCollectionURI = function (collection) {
|
||||
if (collection.libraryID) {
|
||||
var baseURI = this.getLibraryURI(collection.libraryID);
|
||||
}
|
||||
else {
|
||||
var baseURI = this.getCurrentUserURI();
|
||||
}
|
||||
return baseURI + "/collections/" + collection.key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get path portion of collection URI (e.g., users/6/collections/ABCD1234 or groups/1/collections/ABCD1234)
|
||||
*/
|
||||
this.getCollectionPath = function (collection) {
|
||||
return this.getLibraryPath(collection.libraryID) + "/collections/" + collection.key;
|
||||
}
|
||||
|
||||
|
||||
this.getGroupsURL = function () {
|
||||
return ZOTERO_CONFIG.WWW_BASE_URL + "groups";
|
||||
}
|
||||
|
@ -156,17 +178,42 @@ Zotero.URI = new function () {
|
|||
* @param {Zotero.Item|FALSE}
|
||||
*/
|
||||
this.getURIItem = function (itemURI) {
|
||||
return this._getURIObject(itemURI, 'item');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a collection URI into a collection
|
||||
*
|
||||
* @param {String} collectionURI
|
||||
* @param {Zotero.Collection|FALSE}
|
||||
*/
|
||||
this.getURICollection = function (collectionURI) {
|
||||
return this._getURIObject(collectionURI, 'collection');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an object URI into an object (item, collection, etc.)
|
||||
*
|
||||
* @param {String} objectURI
|
||||
* @param {Zotero.Item|Zotero.Collection|FALSE}
|
||||
*/
|
||||
this._getURIObject = function (objectURI, type) {
|
||||
var Types = type[0].toUpperCase() + type.substr(1) + 's';
|
||||
var types = Types.toLowerCase();
|
||||
|
||||
var libraryType = null;
|
||||
|
||||
// If this is a local URI, compare to the local user key
|
||||
if (itemURI.match(/\/users\/local\//)) {
|
||||
if (objectURI.match(/\/users\/local\//)) {
|
||||
// For now, at least, don't check local id
|
||||
/*
|
||||
var localUserURI = this.getLocalUserURI();
|
||||
if (localUserURI) {
|
||||
localUserURI += "/";
|
||||
if (itemURI.indexOf(localUserURI) == 0) {
|
||||
itemURI = itemURI.substr(localUserURI.length);
|
||||
if (objectURI.indexOf(localUserURI) == 0) {
|
||||
objectURI = objectURI.substr(localUserURI.length);
|
||||
var libraryType = 'user';
|
||||
var id = null;
|
||||
}
|
||||
|
@ -178,29 +225,30 @@ Zotero.URI = new function () {
|
|||
|
||||
// If not found, try global URI
|
||||
if (!libraryType) {
|
||||
if (itemURI.indexOf(_baseURI) != 0) {
|
||||
throw ("Invalid base URI '" + itemURI + "' in Zotero.URI.getURIItem()");
|
||||
if (objectURI.indexOf(_baseURI) != 0) {
|
||||
throw ("Invalid base URI '" + objectURI + "' in Zotero.URI._getURIObject()");
|
||||
}
|
||||
itemURI = itemURI.substr(_baseURI.length);
|
||||
objectURI = objectURI.substr(_baseURI.length);
|
||||
var typeRE = /^(users|groups)\/([0-9]+)\//;
|
||||
var matches = itemURI.match(typeRE);
|
||||
var matches = objectURI.match(typeRE);
|
||||
if (!matches) {
|
||||
throw ("Invalid library URI '" + itemURI + "' in Zotero.URI.getURIItem()");
|
||||
throw ("Invalid library URI '" + objectURI + "' in Zotero.URI._getURIObject()");
|
||||
}
|
||||
var libraryType = matches[1].substr(0, matches[1].length-1);
|
||||
var id = matches[2];
|
||||
itemURI = itemURI.replace(typeRE, '');
|
||||
objectURI = objectURI.replace(typeRE, '');
|
||||
}
|
||||
|
||||
// TODO: itemID-based URI?
|
||||
var matches = itemURI.match(/items\/([A-Z0-9]{8})/);
|
||||
// TODO: objectID-based URI?
|
||||
var re = new RegExp(types + "\/([A-Z0-9]{8})");
|
||||
var matches = objectURI.match(re);
|
||||
if (!matches) {
|
||||
throw ("Invalid item URI '" + itemURI + "' in Zotero.URI.getURIItem()");
|
||||
throw ("Invalid object URI '" + objectURI + "' in Zotero.URI._getURIObject()");
|
||||
}
|
||||
var itemKey = matches[1];
|
||||
var objectKey = matches[1];
|
||||
|
||||
if (libraryType == 'user') {
|
||||
return Zotero.Items.getByLibraryAndKey(null, itemKey);
|
||||
return Zotero[Types].getByLibraryAndKey(null, objectKey);
|
||||
}
|
||||
|
||||
if (libraryType == 'group') {
|
||||
|
@ -208,7 +256,7 @@ Zotero.URI = new function () {
|
|||
return false;
|
||||
}
|
||||
var libraryID = Zotero.Groups.getLibraryIDFromGroupID(id);
|
||||
return Zotero.Items.getByLibraryAndKey(libraryID, itemKey);
|
||||
return Zotero[Types].getByLibraryAndKey(libraryID, objectKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user