commit f1ed5f1f03f5e1144bab55dc0df7c40be6373924
parent 89833e2da7a763bb6b2df5701a1652d587e1176d
Author: Dan Stillman <dstillman@zotero.org>
Date: Sun, 10 Aug 2014 15:00:08 -0400
Remove obsolete file (Zotero.Tag no longer exists)
Diffstat:
1 file changed, 0 insertions(+), 779 deletions(-)
diff --git a/chrome/content/zotero/xpcom/data/tag.js b/chrome/content/zotero/xpcom/data/tag.js
@@ -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();
-}
-