Remove obsolete file (Zotero.Tag no longer exists)
This commit is contained in:
parent
89833e2da7
commit
f1ed5f1f03
|
@ -1,779 +0,0 @@
|
|||
/*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright © 2009 Center for History and New Media
|
||||
George Mason University, Fairfax, Virginia, USA
|
||||
http://zotero.org
|
||||
|
||||
This file is part of Zotero.
|
||||
|
||||
Zotero is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Zotero is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
|
||||
Zotero.Tag = function () {
|
||||
if (arguments[0]) {
|
||||
throw ("Zotero.Tag constructor doesn't take any parameters");
|
||||
}
|
||||
|
||||
this._init();
|
||||
}
|
||||
|
||||
Zotero.Tag.prototype._init = function () {
|
||||
// Public members for access by public methods -- do not access directly
|
||||
this._id = null;
|
||||
this._libraryID = null
|
||||
this._key = null;
|
||||
this._name = null;
|
||||
this._type = null;
|
||||
this._dateAdded = null;
|
||||
this._dateModified = null;
|
||||
|
||||
this._loaded = false;
|
||||
this._changed = false;
|
||||
this._previousData = false;
|
||||
|
||||
this._linkedItemsLoaded = false;
|
||||
this._linkedItems = {};
|
||||
this._linkedItemIDsToAdd = [];
|
||||
this._linkedItemIDsToRemove = [];
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype.__defineGetter__('objectType', function () { return 'tag'; });
|
||||
Zotero.Tag.prototype.__defineGetter__('id', function () { return this._get('id'); });
|
||||
Zotero.Tag.prototype.__defineSetter__('id', function (val) { this._set('id', val); });
|
||||
Zotero.Tag.prototype.__defineGetter__('libraryID', function () { return this._get('libraryID'); });
|
||||
Zotero.Tag.prototype.__defineSetter__('libraryID', function (val) { return this._set('libraryID', val); });
|
||||
Zotero.Tag.prototype.__defineGetter__('key', function () { return this._get('key'); });
|
||||
Zotero.Tag.prototype.__defineSetter__('key', function (val) { this._set('key', val) });
|
||||
Zotero.Tag.prototype.__defineGetter__('name', function () { return this._get('name'); });
|
||||
Zotero.Tag.prototype.__defineSetter__('name', function (val) { this._set('name', val); });
|
||||
Zotero.Tag.prototype.__defineGetter__('type', function () { return this._get('type'); });
|
||||
Zotero.Tag.prototype.__defineSetter__('type', function (val) { this._set('type', val); });
|
||||
Zotero.Tag.prototype.__defineGetter__('dateAdded', function () { return this._get('dateAdded'); });
|
||||
Zotero.Tag.prototype.__defineSetter__('dateAdded', function (val) { this._set('dateAdded', val); });
|
||||
Zotero.Tag.prototype.__defineGetter__('dateModified', function () { return this._get('dateModified'); });
|
||||
Zotero.Tag.prototype.__defineSetter__('dateModified', function (val) { this._set('dateModified', val); });
|
||||
Zotero.Tag.prototype.__defineGetter__('key', function () { return this._get('key'); });
|
||||
|
||||
Zotero.Tag.prototype.__defineSetter__('linkedItems', function (arr) { this._setLinkedItems(arr); });
|
||||
|
||||
|
||||
Zotero.Tag.prototype._get = function (field) {
|
||||
if ((this._id || this._key) && !this._loaded) {
|
||||
this.load();
|
||||
}
|
||||
return this['_' + field];
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype._set = function (field, val) {
|
||||
switch (field) {
|
||||
case 'id':
|
||||
case 'libraryID':
|
||||
case 'key':
|
||||
if (field == 'libraryID') {
|
||||
val = Zotero.DataObjectUtilities.checkLibraryID(val);
|
||||
}
|
||||
|
||||
if (val == this['_' + field]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._loaded) {
|
||||
throw ("Cannot set " + field + " after object is already loaded in Zotero.Tag._set()");
|
||||
}
|
||||
|
||||
//this._checkValue(field, val);
|
||||
|
||||
this['_' + field] = val;
|
||||
return;
|
||||
|
||||
case 'name':
|
||||
val = Zotero.Utilities.trim(val);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.id || this.key) {
|
||||
if (!this._loaded) {
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
else {
|
||||
this._loaded = true;
|
||||
}
|
||||
|
||||
if (this['_' + field] != val) {
|
||||
this._prepFieldChange(field);
|
||||
|
||||
switch (field) {
|
||||
default:
|
||||
this['_' + field] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if tag exists in the database
|
||||
*
|
||||
* @return bool TRUE if the tag exists, FALSE if not
|
||||
*/
|
||||
Zotero.Tag.prototype.exists = function() {
|
||||
if (!this.id) {
|
||||
throw ('tagID not set in Zotero.Tag.exists()');
|
||||
}
|
||||
|
||||
var sql = "SELECT COUNT(*) FROM tags WHERE tagID=?";
|
||||
return !!Zotero.DB.valueQuery(sql, this.id);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Build tag from database
|
||||
*/
|
||||
Zotero.Tag.prototype.load = function() {
|
||||
var id = this._id;
|
||||
var key = this._key;
|
||||
var libraryID = this._libraryID;
|
||||
var desc = id ? id : libraryID + "/" + key;
|
||||
|
||||
Zotero.debug("Loading data for tag " + desc + " in Zotero.Tag.load()");
|
||||
|
||||
if (!id && !key) {
|
||||
throw ("ID or key not set in Zotero.Tag.load()");
|
||||
}
|
||||
|
||||
var sql = "SELECT * FROM tags WHERE ";
|
||||
if (id) {
|
||||
sql += "tagID=?";
|
||||
var params = id;
|
||||
}
|
||||
else {
|
||||
sql += "key=? AND libraryID=?";
|
||||
var params = [key, libraryID];
|
||||
}
|
||||
var row = Zotero.DB.rowQuery(sql, params);
|
||||
|
||||
if (!row) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadFromRow(row);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype.loadFromRow = function (row) {
|
||||
this._init();
|
||||
for (var col in row) {
|
||||
//Zotero.debug("Setting field '" + col + "' to '" + row[col] + "' for tag " + this.id);
|
||||
switch (col) {
|
||||
case 'clientDateModified':
|
||||
continue;
|
||||
|
||||
case 'tagID':
|
||||
this._id = row[col];
|
||||
continue;
|
||||
|
||||
case 'libraryID':
|
||||
this['_' + col] = row[col];
|
||||
continue;
|
||||
}
|
||||
this['_' + col] = (!row[col] && row[col] !== 0) ? '' : row[col];
|
||||
}
|
||||
this._loaded = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns items linked to this tag
|
||||
*
|
||||
* @param {Boolean} asIDs Return as itemIDs
|
||||
* @return {Array} Array of Zotero.Item instances or itemIDs,
|
||||
* or FALSE if none
|
||||
*/
|
||||
Zotero.Tag.prototype.getLinkedItems = function (asIDs) {
|
||||
if (!this._linkedItemsLoaded) {
|
||||
this._loadLinkedItems();
|
||||
}
|
||||
|
||||
if (Zotero.Utilities.isEmpty(this._linkedItems)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Return itemIDs
|
||||
if (asIDs) {
|
||||
return Object.keys(this._linkedItems);
|
||||
}
|
||||
|
||||
// Return Zotero.Item objects
|
||||
return [item for each(item in this._linkedItems)];
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype.countLinkedItems = function () {
|
||||
return Object.keys(this._linkedItems).length;
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype.addItem = function (itemID) {
|
||||
if (!this._linkedItemsLoaded) {
|
||||
this._loadLinkedItems();
|
||||
}
|
||||
|
||||
if (this._linkedItems[itemID]) {
|
||||
Zotero.debug("Item " + itemID + " already has tag "
|
||||
+ this.id + " in Zotero.Tag.addItem()");
|
||||
return false;
|
||||
}
|
||||
|
||||
var item = Zotero.Items.get(itemID);
|
||||
if (!item) {
|
||||
throw new Error("Can't link invalid item " + itemID + " to tag " + this.id);
|
||||
}
|
||||
this._prepFieldChange('linkedItems');
|
||||
this._linkedItems[itemID] = item;
|
||||
this._linkedItemIDsToAdd.push(itemID);
|
||||
this._linkedItemIDsToRemove = this._linkedItemIDsToRemove.filter(function (x) x != itemID);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype.removeItem = function (itemID) {
|
||||
if (!this._linkedItemsLoaded) {
|
||||
this._loadLinkedItems();
|
||||
}
|
||||
|
||||
if (!this._linkedItems[itemID]) {
|
||||
Zotero.debug("Item " + itemID + " doesn't have tag "
|
||||
+ this.id + " in Zotero.Tag.removeItem()");
|
||||
return false;
|
||||
}
|
||||
|
||||
this._prepFieldChange('linkedItems');
|
||||
delete this._linkedItems[itemID];
|
||||
this._linkedItemIDsToAdd = this._linkedItemIDsToAdd.filter(function (x) x != itemID);
|
||||
this._linkedItemIDsToRemove.push(itemID);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype.save = function (full) {
|
||||
Zotero.Tags.editCheck(this);
|
||||
|
||||
// Default to manual tag
|
||||
if (!this.type) {
|
||||
this.type = 0;
|
||||
}
|
||||
|
||||
if (this.type != 0 && this.type != 1) {
|
||||
Zotero.debug(this);
|
||||
throw ('Invalid tag type ' + this.type + ' for tag ' + this.id + ' in Zotero.Tag.save()');
|
||||
}
|
||||
|
||||
if (!this.name) {
|
||||
throw ('Tag ' + this.id + ' name is empty in Zotero.Tag.save()');
|
||||
}
|
||||
|
||||
if (!this._changed) {
|
||||
Zotero.debug("Tag " + this.id + " has not changed");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Zotero.DB.beginTransaction();
|
||||
|
||||
var isNew = !this.id || !this.exists();
|
||||
|
||||
try {
|
||||
// how to know if date modified changed (in server code too?)
|
||||
|
||||
var tagID = this.id ? this.id : Zotero.ID.get('tags');
|
||||
|
||||
Zotero.debug("Saving tag " + this.id);
|
||||
|
||||
var key = this.key ? this.key : this._generateKey();
|
||||
|
||||
var columns = [
|
||||
'tagID',
|
||||
'name',
|
||||
'type',
|
||||
'dateAdded',
|
||||
'dateModified',
|
||||
'clientDateModified',
|
||||
'libraryID',
|
||||
'key'
|
||||
];
|
||||
var placeholders = columns.map(function () '?').join();
|
||||
var sqlValues = [
|
||||
tagID ? { int: tagID } : null,
|
||||
{ string: this.name },
|
||||
{ int: this.type },
|
||||
// If date added isn't set, use current timestamp
|
||||
this.dateAdded ? this.dateAdded : Zotero.DB.transactionDateTime,
|
||||
// If date modified hasn't changed, use current timestamp
|
||||
this._changed.dateModified ?
|
||||
this.dateModified : Zotero.DB.transactionDateTime,
|
||||
Zotero.DB.transactionDateTime,
|
||||
this.libraryID ? this.libraryID : 0,
|
||||
key
|
||||
];
|
||||
|
||||
try {
|
||||
if (isNew) {
|
||||
var sql = "INSERT INTO tags (" + columns.join(', ') + ") "
|
||||
+ "VALUES (" + placeholders + ")";
|
||||
var insertID = Zotero.DB.query(sql, sqlValues);
|
||||
if (!tagID) {
|
||||
tagID = insertID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Remove tagID from beginning
|
||||
columns.shift();
|
||||
sqlValues.shift();
|
||||
sqlValues.push(tagID);
|
||||
|
||||
var sql = "UPDATE tags SET " + columns.join("=?, ") + "=?"
|
||||
+ " WHERE tagID=?";
|
||||
Zotero.DB.query(sql, sqlValues);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// If an incoming tag is the same as an existing tag, but with a different key,
|
||||
// then delete the old tag and add its linked items to the new tag
|
||||
if (typeof e == 'string' &&
|
||||
(e.indexOf('columns libraryID, name, type are not unique') != -1
|
||||
|| e.indexOf('NS_ERROR_STORAGE_CONSTRAINT') != -1)) {
|
||||
Zotero.debug("Tag matches existing tag with different key -- delete old tag and merging items");
|
||||
|
||||
// GET existing tag
|
||||
var existing = Zotero.Tags.getIDs(this.name, this.libraryID);
|
||||
if (!existing) {
|
||||
throw new Error("Existing tag not found");
|
||||
}
|
||||
for each(var id in existing) {
|
||||
var tag = Zotero.Tags.get(id, true);
|
||||
if (tag.type == this.type) {
|
||||
var linked = tag.getLinkedItems(true);
|
||||
Zotero.Tags.erase(id);
|
||||
Zotero.Tags.purge(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Save again
|
||||
if (isNew) {
|
||||
var sql = "INSERT INTO tags (" + columns.join(', ') + ") "
|
||||
+ "VALUES (" + placeholders + ")";
|
||||
var insertID = Zotero.DB.query(sql, sqlValues);
|
||||
if (!tagID) {
|
||||
tagID = insertID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var sql = "UPDATE tags SET " + columns.join("=?, ") + "=?"
|
||||
+ " WHERE tagID=?";
|
||||
Zotero.DB.query(sql, sqlValues);
|
||||
}
|
||||
|
||||
// TEMP: until getLinkedItems() returns only arrays
|
||||
linked = linked ? linked : [];
|
||||
var linked2 = this.getLinkedItems(true);
|
||||
linked2 = linked2 ? linked2 : [];
|
||||
linked = linked.concat(linked2);
|
||||
|
||||
this.linkedItems = Zotero.Utilities.arrayUnique(linked);
|
||||
}
|
||||
else {
|
||||
throw (e);
|
||||
}
|
||||
}
|
||||
|
||||
// Linked items
|
||||
if (full || this._changed.linkedItems) {
|
||||
var removed = [];
|
||||
var newids = [];
|
||||
var currentIDs = this.getLinkedItems(true);
|
||||
if (!currentIDs) {
|
||||
currentIDs = [];
|
||||
}
|
||||
|
||||
// Use the database for comparison instead of relying on the cache
|
||||
// This is necessary for a syncing edge case (described in sync.js).
|
||||
if (full) {
|
||||
var sql = "SELECT itemID FROM itemTags WHERE tagID=?";
|
||||
var dbItemIDs = Zotero.DB.columnQuery(sql, tagID);
|
||||
if (dbItemIDs) {
|
||||
removed = Zotero.Utilities.arrayDiff(dbItemIDs, currentIDs);
|
||||
newids = Zotero.Utilities.arrayDiff(currentIDs, dbItemIDs);
|
||||
}
|
||||
else {
|
||||
newids = currentIDs;
|
||||
}
|
||||
}
|
||||
else {
|
||||
removed = this._linkedItemIDsToRemove;
|
||||
newids = this._linkedItemIDsToAdd;
|
||||
}
|
||||
|
||||
if (removed.length) {
|
||||
var done = 0;
|
||||
var maxItems = 998; // stay below compiled limit
|
||||
var numItems = removed.length;
|
||||
|
||||
var pairs = [];
|
||||
for each(var itemID in removed) {
|
||||
pairs.push(itemID + "-" + tagID);
|
||||
}
|
||||
|
||||
let tempRemoved = removed.concat();
|
||||
|
||||
do {
|
||||
var chunk = tempRemoved.splice(0, maxItems);
|
||||
|
||||
var sql = "DELETE FROM itemTags WHERE tagID=? "
|
||||
+ "AND itemID IN (" + chunk.map(function () '?').join() + ")";
|
||||
Zotero.DB.query(sql, [tagID].concat(chunk));
|
||||
|
||||
done += chunk.length;
|
||||
}
|
||||
while (done < numItems);
|
||||
|
||||
Zotero.Notifier.trigger('remove', 'item-tag', pairs);
|
||||
}
|
||||
|
||||
if (newids.length) {
|
||||
var sql = "INSERT OR IGNORE INTO itemTags (itemID, tagID) VALUES (?,?)";
|
||||
var insertStatement = Zotero.DB.getStatement(sql);
|
||||
|
||||
var pairs = [];
|
||||
for each(var itemID in newids) {
|
||||
insertStatement.bindInt32Parameter(0, itemID);
|
||||
insertStatement.bindInt32Parameter(1, tagID);
|
||||
|
||||
try {
|
||||
insertStatement.execute();
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug("itemID: " + itemID);
|
||||
Zotero.debug("tagID: " + tagID);
|
||||
throw (e + ' [ERROR: ' + Zotero.DB.getLastErrorString() + ']');
|
||||
}
|
||||
|
||||
pairs.push(itemID + "-" + tagID);
|
||||
}
|
||||
|
||||
Zotero.Notifier.trigger('add', 'item-tag', pairs);
|
||||
}
|
||||
|
||||
// TODO: notify linked items of name changes?
|
||||
Zotero.Notifier.trigger('modify', 'item', removed.concat(newids));
|
||||
}
|
||||
|
||||
Zotero.DB.commitTransaction();
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.DB.rollbackTransaction();
|
||||
throw (e);
|
||||
}
|
||||
|
||||
// If successful, set values in object
|
||||
if (!this.id) {
|
||||
this._id = tagID;
|
||||
}
|
||||
|
||||
if (!this.key) {
|
||||
this._key = key;
|
||||
}
|
||||
|
||||
if (isNew) {
|
||||
Zotero.Notifier.trigger('add', 'tag', this.id);
|
||||
}
|
||||
else {
|
||||
Zotero.Notifier.trigger('modify', 'tag', this.id, this._previousData);
|
||||
}
|
||||
|
||||
this._reset();
|
||||
Zotero.Tags.reload(this.id);
|
||||
|
||||
return this.id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares this tag to another
|
||||
*
|
||||
* Returns a two-element array containing two objects with the differing values,
|
||||
* or FALSE if no differences
|
||||
*
|
||||
* @param {Zotero.Tag} tag Zotero.Tag to compare this item to
|
||||
* @param {Boolean} includeMatches Include all fields, even those that aren't different
|
||||
* @param {Boolean} ignoreOnlyDateModified If no fields other than dateModified
|
||||
* are different, just return false
|
||||
*/
|
||||
Zotero.Tag.prototype.diff = function (tag, includeMatches, ignoreOnlyDateModified) {
|
||||
var diff = [];
|
||||
var thisData = this.serialize();
|
||||
var otherData = tag.serialize();
|
||||
var numDiffs = Zotero.Tags.diff(thisData, otherData, diff, includeMatches);
|
||||
|
||||
// For the moment, just compare linked items and increase numDiffs if any differences
|
||||
var d1 = Zotero.Utilities.arrayDiff(
|
||||
thisData.linkedItems, otherData.linkedItems
|
||||
);
|
||||
var d2 = Zotero.Utilities.arrayDiff(
|
||||
otherData.linkedItems, thisData.linkedItems
|
||||
);
|
||||
numDiffs += d1.length + d2.length;
|
||||
|
||||
if (d1.length || d2.length) {
|
||||
numDiffs += d1.length + d2.length;
|
||||
diff[0].linkedItems = d1;
|
||||
diff[1].linkedItems = d2;
|
||||
}
|
||||
else {
|
||||
diff[0].linkedItems = [];
|
||||
diff[1].linkedItems = [];
|
||||
}
|
||||
|
||||
// DEBUG: ignoreOnlyDateModified wouldn't work if includeMatches was set?
|
||||
if (numDiffs == 0 ||
|
||||
(ignoreOnlyDateModified && numDiffs == 1
|
||||
&& diff[0].primary && diff[0].primary.dateModified)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype.serialize = function () {
|
||||
var linkedItems = this.getLinkedItems(true);
|
||||
|
||||
var obj = {
|
||||
primary: {
|
||||
tagID: this.id,
|
||||
libraryID: this.libraryID,
|
||||
key: this.key,
|
||||
dateAdded: this.dateAdded,
|
||||
dateModified: this.dateModified
|
||||
},
|
||||
fields: {
|
||||
name: this.name,
|
||||
type: this.type,
|
||||
},
|
||||
linkedItems: linkedItems ? linkedItems : []
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove tag from all linked items
|
||||
*
|
||||
* Tags.erase() should be used instead of tag.erase() for deleting multiple tags
|
||||
*
|
||||
* Actual deletion of tag occurs in Zotero.Tags.purge()
|
||||
*/
|
||||
Zotero.Tag.prototype.erase = function () {
|
||||
Zotero.debug('Deleting tag ' + this.id);
|
||||
|
||||
if (!this.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
var linkedItems = [];
|
||||
var linkedItemsNotifierData = {};
|
||||
|
||||
Zotero.DB.beginTransaction();
|
||||
|
||||
// Deletion done in Zotero.Tags.purge()
|
||||
//var deletedTagNotifierData = {};
|
||||
//deletedTagNotifierData[this.id] = { old: this.serialize() };
|
||||
|
||||
var sql = "SELECT itemID FROM itemTags WHERE tagID=?";
|
||||
var linkedItemIDs = Zotero.DB.columnQuery(sql, this.id);
|
||||
|
||||
if (!linkedItemIDs) {
|
||||
Zotero.DB.commitTransaction();
|
||||
return;
|
||||
}
|
||||
|
||||
var sql = "DELETE FROM itemTags WHERE tagID=?";
|
||||
Zotero.DB.query(sql, this.id);
|
||||
|
||||
var itemTags = [];
|
||||
for each(var itemID in linkedItemIDs) {
|
||||
var item = Zotero.Items.get(itemID)
|
||||
if (!item) {
|
||||
throw ('Linked item not found in Zotero.Tag.erase()');
|
||||
}
|
||||
linkedItems.push(itemID);
|
||||
linkedItemsNotifierData[itemID] = { old: item.serialize() };
|
||||
|
||||
itemTags.push(itemID + '-' + this.id);
|
||||
}
|
||||
|
||||
// Deletion done in Zotero.Tags.purge()
|
||||
//Zotero.Tags.unload(this.id);
|
||||
|
||||
Zotero.Notifier.trigger('remove', 'item-tag', itemTags);
|
||||
|
||||
// Send notification of linked items
|
||||
if (linkedItems.length) {
|
||||
Zotero.Notifier.trigger('modify', 'item', linkedItems, linkedItemsNotifierData);
|
||||
}
|
||||
|
||||
// Deletion done in Zotero.Tags.purge()
|
||||
//Zotero.Notifier.trigger('delete', 'tag', this.id, deletedTagNotifierData);
|
||||
|
||||
Zotero.DB.commitTransaction();
|
||||
|
||||
this._reset();
|
||||
|
||||
Zotero.Prefs.set('purge.tags', true);
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype._reset = function () {
|
||||
var id = this._id;
|
||||
var libraryID = this._libraryID;
|
||||
var key = this._key;
|
||||
this._init();
|
||||
this._id = id;
|
||||
this._libraryID = libraryID;
|
||||
this._key = key;
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype._loadLinkedItems = function() {
|
||||
if (!this.id && !this.key) {
|
||||
this._linkedItemsLoaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._loaded) {
|
||||
this.load();
|
||||
}
|
||||
|
||||
if (!this.id) {
|
||||
this._linkedItemsLoaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var sql = "SELECT itemID FROM itemTags WHERE tagID=?";
|
||||
var ids = Zotero.DB.columnQuery(sql, this.id) || [];
|
||||
|
||||
this._linkedItems = {};
|
||||
|
||||
for (let i=0; i<ids.length; i++) {
|
||||
let id = ids[i];
|
||||
this._linkedItems[id] = Zotero.Items.get(id);
|
||||
}
|
||||
|
||||
this._linkedItemsLoaded = true;
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype._setLinkedItems = function (itemIDs) {
|
||||
if (!this._linkedItemsLoaded) {
|
||||
this._loadLinkedItems();
|
||||
}
|
||||
|
||||
if (!Array.isArray(itemIDs)) {
|
||||
throw new Error('itemIDs must be an array');
|
||||
}
|
||||
|
||||
var numCurrent = this.countLinkedItems();
|
||||
|
||||
if (itemIDs.length == 0) {
|
||||
if (numCurrent == 0) {
|
||||
Zotero.debug('No linked items added', 4);
|
||||
return false;
|
||||
}
|
||||
|
||||
// No items passed, so remove all currently linked items
|
||||
this._prepFieldChange('linkedItems');
|
||||
this._linkedItems = {};
|
||||
this._linkedItemIDsToAdd = [];
|
||||
this._linkedItemIDsToRemove = this.getLinkedItems(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get all new items
|
||||
for (let i=0; i<itemIDs.length; i++) {
|
||||
let id = itemIDs[i];
|
||||
if (isNaN(parseInt(id))) {
|
||||
throw new Error("Invalid itemID '" + itemIDs[i] + "'");
|
||||
}
|
||||
|
||||
if (this._linkedItems[id]) {
|
||||
Zotero.debug("Item " + id + " is already linked to tag " + this.id);
|
||||
}
|
||||
else {
|
||||
this._linkedItemIDsToAdd.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
// If no new items and the old and new lengths match, none are being removed either
|
||||
if (!this._linkedItemIDsToAdd.length && numCurrent == itemIDs.length) {
|
||||
Zotero.debug('Linked items not changed in Zotero.Tag._setLinkedItems()', 4);
|
||||
return false;
|
||||
}
|
||||
|
||||
this._prepFieldChange('linkedItems');
|
||||
|
||||
// Rebuild linked items with items that exist
|
||||
var items = Zotero.Items.get(itemIDs) || [];
|
||||
this._linkedItems = {};
|
||||
for (let i=0; i<items.length; i++) {
|
||||
this._linkedItems[items[i].id] = items[i];
|
||||
}
|
||||
|
||||
// Mark items not found for removal
|
||||
for (let i=0; i<itemIDs.length; i++) {
|
||||
let id = itemIDs[i];
|
||||
if (!this._linkedItems[id]) {
|
||||
this._linkedItemIDsToRemove.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype._prepFieldChange = function (field) {
|
||||
if (!this._changed) {
|
||||
this._changed = {};
|
||||
}
|
||||
this._changed[field] = true;
|
||||
|
||||
// Save a copy of the data before changing
|
||||
// TODO: only save previous data if tag exists
|
||||
if (this.id && this.exists() && !this._previousData) {
|
||||
this._previousData = this.serialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Zotero.Tag.prototype._generateKey = function () {
|
||||
return Zotero.Utilities.generateObjectKey();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user