diff --git a/chrome/content/zotero/xpcom/data/dataObject.js b/chrome/content/zotero/xpcom/data/dataObject.js index 26fc8d9872..f20a9fb52d 100644 --- a/chrome/content/zotero/xpcom/data/dataObject.js +++ b/chrome/content/zotero/xpcom/data/dataObject.js @@ -23,10 +23,21 @@ ***** END LICENSE BLOCK ***** */ -Zotero.DataObject = function (objectType, objectTypePlural, dataTypes) { +/** + * + * @param {String} objectType + * @param {String[]} dataTypes A set of data types that can be loaded for this data object + * + * @property {String} (readOnly) objectType + * @property {String} (readOnly) libraryKey + * @property {String|null} parentKey Null if no parent + * @property {Integer|false|undefined} parentID False if no parent. Undefined if not applicable (e.g. search objects) + */ + +Zotero.DataObject = function (objectType, dataTypes) { this._objectType = objectType; this._ObjectType = objectType[0].toUpperCase() + objectType.substr(1); - this._objectTypePlural = objectTypePlural ? objectTypePlural : objectType + 's'; + this._objectTypePlural = Zotero.DataObjectUtilities.getObjectTypePlural(objectType); this._dataTypes = dataTypes; this._id = null; @@ -46,12 +57,20 @@ Zotero.DataObject = function (objectType, objectTypePlural, dataTypes) { this._clearChanged(); }; -Zotero.DataObject.prototype.__defineGetter__('objectType', function () { return this._objectType; }); -Zotero.DataObject.prototype.__defineGetter__('libraryKey', function () this.libraryID + "/" + this.key); -Zotero.DataObject.prototype.__defineGetter__('parentKey', function () this._parentKey ); -Zotero.DataObject.prototype.__defineSetter__('parentKey', function (val) this._setParentKey(val) ); -Zotero.DataObject.prototype.__defineGetter__('parentID', function () this._getParentID() ); -Zotero.DataObject.prototype.__defineSetter__('parentID', function (val) this._setParentID(val) ); +Zotero.Utilities.Internal.defineProperty(Zotero.DataObject, 'objectType', { + get: function() this._objectType +}); +Zotero.Utilities.Internal.defineProperty(Zotero.DataObject, 'libraryKey', { + get: function() this._libraryID + "/" + this._key +}); +Zotero.Utilities.Internal.defineProperty(Zotero.DataObject, 'parentKey', { + get: function() this._parentKey, + set: function(v) this._setParentKey(v) +}); +Zotero.Utilities.Internal.defineProperty(Zotero.DataObject, 'parentID', { + get: function() this._getParentID(), + set: function(v) this._setParentID(v) +}); Zotero.DataObject.prototype._get = function (field) { @@ -82,7 +101,7 @@ Zotero.DataObject.prototype._setIdentifier = function (field, value) { if (this._key) { throw new Error("Cannot set id if key is already set"); } - value = parseInt(value); + value = Zotero.DataObjectUtilities.checkDataID(value); this._identified = true; break; @@ -91,12 +110,13 @@ Zotero.DataObject.prototype._setIdentifier = function (field, value) { break; case 'key': - if (this._libraryID === undefined) { + if (this._libraryID === null) { throw new Error("libraryID must be set before key"); } if (this._id) { throw new Error("Cannot set key if id is already set"); } + value = Zotero.DataObjectUtilities.checkKey(value); this._identified = true; } @@ -129,25 +149,36 @@ Zotero.DataObject.prototype._getParentID = function () { * Set the id of the parent object * * @param {Number|false} [id=false] + * @return {Boolean} True if changed, false if stayed the same */ Zotero.DataObject.prototype._setParentID = function (id) { - return this._setParentKey(id ? this._getClass().getLibraryAndKeyFromID(id)[1] : false); + return this._setParentKey( + id + ? this._getClass().getLibraryAndKeyFromID(Zotero.DataObjectUtilities.checkDataID(id))[1] + : null + ); } - +/** + * Set the key of the parent object + * + * @param {String|null} [key=null] + * @return {Boolean} True if changed, false if stayed the same + */ Zotero.DataObject.prototype._setParentKey = function(key) { if (this._objectType == 'item') { if (!this.isNote() && !this.isAttachment()) { throw new Error("_setParentKey() can only be called on items of type 'note' or 'attachment'"); } } + key = Zotero.DataObjectUtilities.checkKey(key); if (this._parentKey == key) { return false; } this._markFieldChange('parentKey', this._parentKey); this._changed.parentKey = true; - this._parentKey = key ? key : null; + this._parentKey = key; this._parentID = null; return true; } @@ -156,7 +187,8 @@ Zotero.DataObject.prototype._setParentKey = function(key) { /** * Returns all relations of the object * - * @return object Object with predicates as keys and URIs as values + * @return {object} Object with predicates as keys and URI[], or URI (as string) + * in the case of a single object, as values */ Zotero.DataObject.prototype.getRelations = function () { this._requireData('relations'); @@ -187,14 +219,15 @@ Zotero.DataObject.prototype.getRelations = function () { /** * Updates the object's relations * - * @param {Object} newRelations Object with predicates as keys and URIs/arrays-of-URIs as values + * @param {Object} newRelations Object with predicates as keys and URI[] as values + * @return {Boolean} True if changed, false if stayed the same */ Zotero.DataObject.prototype.setRelations = function (newRelations) { this._requireData('relations'); // There can be more than one object for a given predicate, so build - // flat arrays with individual predicate-object pairs converted to - // JSON strings so we can use array_diff to determine what changed + // flat arrays with individual predicate-object pairs so we can use + // array_diff to determine what changed var oldRelations = this._relations; var sortFunc = function (a, b) { @@ -208,13 +241,8 @@ Zotero.DataObject.prototype.setRelations = function (newRelations) { var newRelationsFlat = []; for (let predicate in newRelations) { let object = newRelations[predicate]; - if (Array.isArray(object)) { - for (let i=0; i