Load synced settings (incl. tag colors) at startup

This commit is contained in:
Dan Stillman 2016-03-14 17:10:18 -04:00
parent 60830c27ee
commit 8e5016ae4d
17 changed files with 252 additions and 184 deletions

View file

@ -137,7 +137,8 @@
return Zotero.spawn(function* () { return Zotero.spawn(function* () {
if (type == 'setting') { if (type == 'setting') {
if (ids.some(function (val) val.split("/")[1] == 'tagColors') && this.item) { if (ids.some(function (val) val.split("/")[1] == 'tagColors') && this.item) {
return this.reload(); this.reload();
return;
} }
} }
else if (type == 'item-tag') { else if (type == 'item-tag') {
@ -194,7 +195,8 @@
} }
else if (type == 'tag') { else if (type == 'tag') {
if (event == 'modify') { if (event == 'modify') {
return this.reload(); this.reload();
return;
} }
} }
}.bind(this)); }.bind(this));
@ -204,38 +206,32 @@
<method name="reload"> <method name="reload">
<body><![CDATA[ <body><![CDATA[
return Zotero.spawn(function* () { Zotero.debug('Reloading tags box');
Zotero.debug('Reloading tags box');
// Cancel field focusing while we're updating
// Cancel field focusing while we're updating this._reloading = true;
this._reloading = true;
this.id('addButton').hidden = !this.editable;
this.id('addButton').hidden = !this.editable;
this._tagColors = Zotero.Tags.getColors(this.item.libraryID);
this._tagColors = yield Zotero.Tags.getColors(this.item.libraryID)
.tap(() => Zotero.Promise.check(this.mode)); var rows = this.id('tagRows');
while(rows.hasChildNodes()) {
var rows = this.id('tagRows'); rows.removeChild(rows.firstChild);
while(rows.hasChildNodes()) { }
rows.removeChild(rows.firstChild); var tags = this.item.getTags();
}
var tags = this.item.getTags(); // Sort tags alphabetically
var collation = Zotero.getLocaleCollation();
// Sort tags alphabetically tags.sort(function (a, b) collation.compareString(1, a.tag, b.tag));
var collation = Zotero.getLocaleCollation();
tags.sort(function (a, b) collation.compareString(1, a.tag, b.tag)); for (let i=0; i<tags.length; i++) {
this.addDynamicRow(tags[i], i+1);
for (let i=0; i<tags.length; i++) { }
this.addDynamicRow(tags[i], i+1); this.updateCount(tags.length);
}
this.updateCount(tags.length); this._reloading = false;
this._focusField();
this._reloading = false;
this._focusField();
var event = new Event('refresh');
this.dispatchEvent(event);
}, this);
]]></body> ]]></body>
</method> </method>
@ -711,7 +707,7 @@
this._lastTabIndex = this.item.getTags().length; this._lastTabIndex = this.item.getTags().length;
} }
yield this.reload(); this.reload();
} }
// Single tag at end // Single tag at end
else { else {

View file

@ -236,8 +236,7 @@
var emptyRegular = true; var emptyRegular = true;
var tagsBox = this.id('tags-box'); var tagsBox = this.id('tags-box');
var tagColors = yield Zotero.Tags.getColors(this.libraryID) var tagColors = Zotero.Tags.getColors(this.libraryID);
.tap(() => Zotero.Promise.check(this.mode));
// If new data, rebuild boxes // If new data, rebuild boxes
if (fetch || this._dirty) { if (fetch || this._dirty) {
@ -375,45 +374,43 @@
<method name="insertSorted"> <method name="insertSorted">
<parameter name="tagObjs"/> <parameter name="tagObjs"/>
<body><![CDATA[ <body><![CDATA[
return Zotero.spawn(function* () { var tagColors = Zotero.Tags.getColors(this._libraryID);
var tagColors = yield Zotero.Tags.getColors(this._libraryID);
var collation = Zotero.getLocaleCollation();
var collation = Zotero.getLocaleCollation(); tagObjs.sort(function (a, b) {
tagObjs.sort(function (a, b) { return collation.compareString(1, a.tag, b.tag);
return collation.compareString(1, a.tag, b.tag); });
});
// Create tag elements in sorted order
// Create tag elements in sorted order var tagsBox = this.id('tags-box');
var tagsBox = this.id('tags-box'); var tagElems = tagsBox.childNodes;
var tagElems = tagsBox.childNodes; var j = 0;
var j = 0; loop:
loop: for (let i = 0; i < tagObjs.length; i++) {
for (let i = 0; i < tagObjs.length; i++) { let tagObj = tagObjs[i];
let tagObj = tagObjs[i]; while (j < tagElems.length) {
while (j < tagElems.length) { let elem = tagElems[j];
let elem = tagElems[j]; let comp = collation.compareString(
let comp = collation.compareString( 1, tagObj.tag, elem.textContent
1, tagObj.tag, elem.textContent
);
// If tag already exists, update type if new one is lower
if (comp == 0) {
let tagType = elem.getAttribute('tagType');
if (parseInt(tagObj.type) < parseInt(tagType)) {
elem.setAttribute('tagType', tagObj.type);
}
continue loop;
}
if (comp < 0) {
break;
}
j++;
}
this._insertClickableTag(tagsBox, tagObj, tagElems[j]);
this._updateClickableTag(
tagElems[j], tagElems[j].textContent, tagColors
); );
// If tag already exists, update type if new one is lower
if (comp == 0) {
let tagType = elem.getAttribute('tagType');
if (parseInt(tagObj.type) < parseInt(tagType)) {
elem.setAttribute('tagType', tagObj.type);
}
continue loop;
}
if (comp < 0) {
break;
}
j++;
} }
}, this); this._insertClickableTag(tagsBox, tagObj, tagElems[j]);
this._updateClickableTag(
tagElems[j], tagElems[j].textContent, tagColors
);
}
]]></body> ]]></body>
</method> </method>
@ -512,7 +509,7 @@
}.bind(this)); }.bind(this));
if (tagObjs.length) { if (tagObjs.length) {
yield this.insertSorted(tagObjs); this.insertSorted(tagObjs);
} }
} }
// Don't add anything for item or collection-item; just update scope // Don't add anything for item or collection-item; just update scope
@ -671,7 +668,7 @@
// Colored tags don't need to exist, so in that case // Colored tags don't need to exist, so in that case
// just rename the color setting // just rename the color setting
else { else {
let color = yield Zotero.Tags.getColor(this.libraryID, oldName); let color = Zotero.Tags.getColor(this.libraryID, oldName);
if (!color) { if (!color) {
throw new Error("Can't rename missing tag"); throw new Error("Can't rename missing tag");
} }
@ -715,18 +712,6 @@
]]></body> ]]></body>
</method> </method>
<method name="getColor">
<parameter name="tagIDs"/>
<body><![CDATA[
return Zotero.spawn(function* () {
tagIDs = tagIDs.split('-');
var name = yield Zotero.Tags.getName(tagIDs[0]);
var colorData = yield Zotero.Tags.getColor(this.libraryID, name);
return colorData ? colorData.color : '#000000';
}.bind(this));
]]></body>
</method>
<method name="_insertClickableTag"> <method name="_insertClickableTag">
<parameter name="tagsBox"/> <parameter name="tagsBox"/>
@ -877,7 +862,7 @@
name: name name: name
}; };
var tagColors = yield Zotero.Tags.getColors(this.libraryID); var tagColors = Zotero.Tags.getColors(this.libraryID);
if (tagColors.size >= Zotero.Tags.MAX_COLORED_TAGS && !tagColors.has(io.name)) { if (tagColors.size >= Zotero.Tags.MAX_COLORED_TAGS && !tagColors.has(io.name)) {
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService); .getService(Components.interfaces.nsIPromptService);

View file

@ -30,7 +30,7 @@ Zotero.Creators = new function() {
var _cache = {}; var _cache = {};
this.init = Zotero.Promise.coroutine(function* (libraryID) { this.init = Zotero.Promise.coroutine(function* () {
var sql = "SELECT * FROM creators"; var sql = "SELECT * FROM creators";
var rows = yield Zotero.DB.queryAsync(sql); var rows = yield Zotero.DB.queryAsync(sql);
for (let i = 0; i < rows.length; i++) { for (let i = 0; i < rows.length; i++) {

View file

@ -373,12 +373,13 @@ Zotero.DataObjects.prototype._loadDataType = Zotero.Promise.coroutine(function*
Zotero.debug(`Loaded ${dataType} in ${libraryName} in ${new Date() - t} ms`); Zotero.debug(`Loaded ${dataType} in ${libraryName} in ${new Date() - t} ms`);
}); });
Zotero.DataObjects.prototype.loadAllData = Zotero.Promise.coroutine(function* (libraryID, ids) { Zotero.DataObjects.prototype.loadAll = Zotero.Promise.coroutine(function* (libraryID, ids) {
var t = new Date(); var t = new Date();
var libraryName = Zotero.Libraries.get(libraryID).name; var libraryName = Zotero.Libraries.get(libraryID).name;
Zotero.debug("Loading all data" Zotero.debug("Loading "
+ (ids ? " for " + ids.length + " " + this._ZDO_objects : '') + (ids ? ids.length : "all") + " "
+ (ids && ids.length == 1 ? this._ZDO_object : this._ZDO_objects)
+ " in " + libraryName); + " in " + libraryName);
let dataTypes = this.ObjectClass.prototype._dataTypes; let dataTypes = this.ObjectClass.prototype._dataTypes;

View file

@ -3548,7 +3548,7 @@ Zotero.Item.prototype.getImageSrcWithTags = Zotero.Promise.coroutine(function* (
return uri; return uri;
} }
var tagColors = yield Zotero.Tags.getColors(this.libraryID); var tagColors = Zotero.Tags.getColors(this.libraryID);
var colorData = []; var colorData = [];
for (let i=0; i<tags.length; i++) { for (let i=0; i<tags.length; i++) {
let tag = tags[i]; let tag = tags[i];

View file

@ -315,6 +315,16 @@ Zotero.Library.prototype._reloadFromDB = Zotero.Promise.coroutine(function* () {
this._loadDataFromRow(row); this._loadDataFromRow(row);
}); });
/**
* Load object data in this library
*/
Zotero.Library.prototype.loadAllDataTypes = Zotero.Promise.coroutine(function* () {
yield Zotero.SyncedSettings.loadAll(this.libraryID);
yield Zotero.Collections.loadAll(this.libraryID);
yield Zotero.Searches.loadAll(this.libraryID);
yield Zotero.Items.loadAll(this.libraryID);
});
Zotero.Library.prototype.isChildObjectAllowed = function(type) { Zotero.Library.prototype.isChildObjectAllowed = function(type) {
return this._childObjectTypes.indexOf(type) != -1; return this._childObjectTypes.indexOf(type) != -1;
}; };
@ -461,6 +471,8 @@ Zotero.Library.prototype._finalizeSave = Zotero.Promise.coroutine(function* (env
yield this._reloadFromDB(); yield this._reloadFromDB();
Zotero.Libraries.register(this); Zotero.Libraries.register(this);
yield this.loadAllDataTypes();
} }
}); });

View file

@ -77,7 +77,7 @@ Zotero.Tags = new function() {
/** /**
* Get all tags indexed by tagID * Get all tags in library
* *
* @param {Number} libraryID * @param {Number} libraryID
* @param {Array} [types] Tag types to fetch * @param {Array} [types] Tag types to fetch
@ -181,7 +181,7 @@ Zotero.Tags = new function() {
// We need to know if the old tag has a color assigned so that // We need to know if the old tag has a color assigned so that
// we can assign it to the new name // we can assign it to the new name
var oldColorData = yield this.getColor(libraryID, oldName); var oldColorData = this.getColor(libraryID, oldName);
yield Zotero.DB.executeTransaction(function* () { yield Zotero.DB.executeTransaction(function* () {
var oldItemIDs = yield this.getTagItems(libraryID, oldTagID); var oldItemIDs = yield this.getTagItems(libraryID, oldTagID);
@ -393,13 +393,13 @@ Zotero.Tags = new function() {
* *
* @param {Integer} libraryID * @param {Integer} libraryID
* @param {String} name Tag name * @param {String} name Tag name
* @return {Promise} A Q promise for the tag color as a hex string (e.g., '#990000') * @return {Object|false} An object containing 'color' as a hex string (e.g., '#990000') and
* 'position', or false if no colored tag with that name
*/ */
this.getColor = function (libraryID, name) { this.getColor = function (libraryID, name) {
return this.getColors(libraryID) // Cache colors
.then(function () { this.getColors(libraryID);
return _libraryColorsByName[libraryID].get(name) || false; return _libraryColorsByName[libraryID].get(name) || false;
});
} }
@ -408,14 +408,12 @@ Zotero.Tags = new function() {
* *
* @param {Integer} libraryID * @param {Integer} libraryID
* @param {Integer} position The position of the tag, starting at 0 * @param {Integer} position The position of the tag, starting at 0
* @return {Promise} A promise for an object containing 'name' and 'color' * @return {Object|false} An object containing 'name' and 'color', or false if no color at
* the given position
*/ */
this.getColorByPosition = function (libraryID, position) { this.getColorByPosition = function (libraryID, position) {
return this.getColors(libraryID) this.getColors(libraryID);
.then(function () { return _libraryColors[libraryID][position] ? _libraryColors[libraryID][position] : false;
return _libraryColors[libraryID][position]
? _libraryColors[libraryID][position] : false;
});
} }
@ -423,20 +421,19 @@ Zotero.Tags = new function() {
* Get colored tags within a given library * Get colored tags within a given library
* *
* @param {Integer} libraryID * @param {Integer} libraryID
* @return {Promise<Map>} - A promise for a Map with tag names as keys and * @return {Map} - A Map with tag names as keys and objects containing 'color' and 'position'
* objects containing 'color' and 'position' as values * as values
*/ */
this.getColors = Zotero.Promise.coroutine(function* (libraryID) { this.getColors = function (libraryID) {
if (!libraryID) {
throw new Error("libraryID not provided");
}
if (_libraryColorsByName[libraryID]) { if (_libraryColorsByName[libraryID]) {
return _libraryColorsByName[libraryID]; return _libraryColorsByName[libraryID];
} }
var tagColors = yield Zotero.SyncedSettings.get(libraryID, 'tagColors'); var tagColors = Zotero.SyncedSettings.get(libraryID, 'tagColors');
// If the colors became available from another run
if (_libraryColorsByName[libraryID]) {
return _libraryColorsByName[libraryID];
}
tagColors = tagColors || []; tagColors = tagColors || [];
@ -452,7 +449,7 @@ Zotero.Tags = new function() {
} }
return _libraryColorsByName[libraryID]; return _libraryColorsByName[libraryID];
}); };
/** /**
@ -465,7 +462,7 @@ Zotero.Tags = new function() {
throw new Error("libraryID must be an integer"); throw new Error("libraryID must be an integer");
} }
yield this.getColors(libraryID); this.getColors(libraryID);
var tagColors = _libraryColors[libraryID]; var tagColors = _libraryColors[libraryID];
@ -541,7 +538,7 @@ Zotero.Tags = new function() {
delete _libraryColorsByName[libraryID]; delete _libraryColorsByName[libraryID];
// Get the tag colors for each library in which they were modified // Get the tag colors for each library in which they were modified
let tagColors = yield Zotero.SyncedSettings.get(libraryID, 'tagColors'); let tagColors = Zotero.SyncedSettings.get(libraryID, 'tagColors');
if (!tagColors) { if (!tagColors) {
tagColors = []; tagColors = [];
} }

View file

@ -170,12 +170,11 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
if (coloredTagsRE.test(key)) { if (coloredTagsRE.test(key)) {
let libraryID = self.collectionTreeRow.ref.libraryID; let libraryID = self.collectionTreeRow.ref.libraryID;
let position = parseInt(key) - 1; let position = parseInt(key) - 1;
let colorData = yield Zotero.Tags.getColorByPosition(libraryID, position); let colorData = Zotero.Tags.getColorByPosition(libraryID, position);
// If a color isn't assigned to this number or any // If a color isn't assigned to this number or any
// other numbers, allow key navigation // other numbers, allow key navigation
if (!colorData) { if (!colorData) {
let colors = yield Zotero.Tags.getColors(libraryID); return !Zotero.Tags.getColors(libraryID).size;
return !colors.size;
} }
var items = self.getSelectedItems(); var items = self.getSelectedItems();

View file

@ -815,7 +815,7 @@ Zotero.Search.prototype.search = Zotero.Promise.coroutine(function* (asTempTable
/** /**
* Populate the object's data from an API JSON data object * Populate the object's data from an API JSON data object
* *
* If this object is identified (has an id or library/key), loadAllData() must have been called. * If this object is identified (has an id or library/key), loadAll() must have been called.
*/ */
Zotero.Search.prototype.fromJSON = function (json) { Zotero.Search.prototype.fromJSON = function (json) {
if (!json.name) { if (!json.name) {

View file

@ -290,7 +290,7 @@ Zotero.Sync.Data.Engine.prototype._startDownload = Zotero.Promise.coroutine(func
} }
if (objectType == 'setting') { if (objectType == 'setting') {
let meta = yield Zotero.SyncedSettings.getMetadata(this.libraryID, key); let meta = Zotero.SyncedSettings.getMetadata(this.libraryID, key);
if (!meta) { if (!meta) {
continue; continue;
} }

View file

@ -27,6 +27,8 @@
* @namespace * @namespace
*/ */
Zotero.SyncedSettings = (function () { Zotero.SyncedSettings = (function () {
var _cache = {};
// //
// Public methods // Public methods
// //
@ -34,47 +36,95 @@ Zotero.SyncedSettings = (function () {
idColumn: "setting", idColumn: "setting",
table: "syncedSettings", table: "syncedSettings",
get: Zotero.Promise.coroutine(function* (libraryID, setting) { loadAll: Zotero.Promise.coroutine(function* (libraryID) {
var sql = "SELECT value FROM syncedSettings WHERE setting=? AND libraryID=?"; Zotero.debug("Loading synced settings for library " + libraryID);
var json = yield Zotero.DB.valueQueryAsync(sql, [setting, libraryID]);
if (!json) { if (!_cache[libraryID]) {
return false; _cache[libraryID] = {};
} }
return JSON.parse(json);
var invalid = [];
var sql = "SELECT setting, value, synced, version FROM syncedSettings "
+ "WHERE libraryID=?";
yield Zotero.DB.queryAsync(
sql,
libraryID,
{
onRow: function (row) {
var setting = row.getResultByIndex(0);
var value = row.getResultByIndex(1);
try {
value = JSON.parse(value);
}
catch (e) {
invalid.push([libraryID, setting]);
return;
}
_cache[libraryID][setting] = {
value,
synced: !!row.getResultByIndex(2),
version: row.getResultByIndex(3)
};
}
}
);
// TODO: Delete invalid settings
}), }),
/**
* Return settings object
*
* @return {Object|null}
*/
get: function (libraryID, setting) {
if (!_cache[libraryID]) {
throw new Zotero.Exception.UnloadedDataException(
"Synced settings not loaded for library " + libraryID,
"syncedSettings"
);
}
if (!_cache[libraryID][setting]) {
return null;
}
return JSON.parse(JSON.stringify(_cache[libraryID][setting].value));
},
/** /**
* Used by sync and tests * Used by sync and tests
* *
* @return {Object} - Object with 'synced' and 'version' properties * @return {Object} - Object with 'synced' and 'version' properties
*/ */
getMetadata: Zotero.Promise.coroutine(function* (libraryID, setting) { getMetadata: function (libraryID, setting) {
var sql = "SELECT * FROM syncedSettings WHERE setting=? AND libraryID=?"; if (!_cache[libraryID]) {
var row = yield Zotero.DB.rowQueryAsync(sql, [setting, libraryID]); throw new Zotero.Exception.UnloadedDataException(
if (!row) { "Synced settings not loaded for library " + libraryID,
return false; "syncedSettings"
);
}
var o = _cache[libraryID][setting];
if (!o) {
return null;
} }
return { return {
synced: !!row.synced, synced: o.synced,
version: row.version version: o.version
}; };
}), },
set: Zotero.Promise.coroutine(function* (libraryID, setting, value, version = 0, synced) { set: Zotero.Promise.coroutine(function* (libraryID, setting, value, version = 0, synced) {
if (typeof value == undefined) { if (typeof value == undefined) {
throw new Error("Value not provided"); throw new Error("Value not provided");
} }
// TODO: get rid of this once we have proper affected rows handling var currentValue = this.get(libraryID, setting);
var sql = "SELECT value FROM syncedSettings WHERE setting=? AND libraryID=?"; var hasCurrentValue = currentValue !== null;
var currentValue = yield Zotero.DB.valueQueryAsync(sql, [setting, libraryID]);
// Make sure we can tell the difference between a
// missing setting (FALSE as returned by valueQuery())
// and a FALSE setting (FALSE as returned by JSON.parse())
var hasCurrentValue = currentValue !== false;
currentValue = JSON.parse(currentValue);
// Value hasn't changed // Value hasn't changed
if (value === currentValue) { if (value === currentValue) {
@ -93,7 +143,7 @@ Zotero.SyncedSettings = (function () {
}; };
} }
if (currentValue === false) { if (!hasCurrentValue) {
var event = 'add'; var event = 'add';
var extraData = {}; var extraData = {};
} }
@ -102,6 +152,7 @@ Zotero.SyncedSettings = (function () {
} }
synced = synced ? 1 : 0; synced = synced ? 1 : 0;
version = parseInt(version);
if (hasCurrentValue) { if (hasCurrentValue) {
var sql = "UPDATE syncedSettings SET value=?, version=?, synced=? " var sql = "UPDATE syncedSettings SET value=?, version=?, synced=? "
@ -117,6 +168,13 @@ Zotero.SyncedSettings = (function () {
sql, [setting, libraryID, JSON.stringify(value), version, synced] sql, [setting, libraryID, JSON.stringify(value), version, synced]
); );
} }
_cache[libraryID][setting] = {
value,
synced: !!synced,
version
}
yield Zotero.Notifier.trigger(event, 'setting', [id], extraData); yield Zotero.Notifier.trigger(event, 'setting', [id], extraData);
return true; return true;
}), }),
@ -124,22 +182,16 @@ Zotero.SyncedSettings = (function () {
clear: Zotero.Promise.coroutine(function* (libraryID, setting, options) { clear: Zotero.Promise.coroutine(function* (libraryID, setting, options) {
options = options || {}; options = options || {};
// TODO: get rid of this once we have proper affected rows handling var currentValue = this.get(libraryID, setting);
var sql = "SELECT value FROM syncedSettings WHERE setting=? AND libraryID=?"; var hasCurrentValue = currentValue !== null;
var currentValue = yield Zotero.DB.valueQueryAsync(sql, [setting, libraryID]);
if (currentValue === false) {
return false;
}
currentValue = JSON.parse(currentValue);
var id = libraryID + '/' + setting; var id = libraryID + '/' + setting;
var extraData = {}; var extraData = {};
extraData[id] = { extraData[id] = {
changed: {} changed: {
}; value: currentValue
extraData[id].changed = { }
value: currentValue
}; };
if (options.skipDeleteLog) { if (options.skipDeleteLog) {
extraData[id].skipDeleteLog = true; extraData[id].skipDeleteLog = true;
@ -148,6 +200,8 @@ Zotero.SyncedSettings = (function () {
var sql = "DELETE FROM syncedSettings WHERE setting=? AND libraryID=?"; var sql = "DELETE FROM syncedSettings WHERE setting=? AND libraryID=?";
yield Zotero.DB.queryAsync(sql, [setting, libraryID]); yield Zotero.DB.queryAsync(sql, [setting, libraryID]);
delete _cache[libraryID][setting];
yield Zotero.Notifier.trigger('delete', 'setting', [id], extraData); yield Zotero.Notifier.trigger('delete', 'setting', [id], extraData);
return true; return true;
}) })

View file

@ -629,9 +629,8 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
let libraryIDs = Zotero.Libraries.getAll().map(x => x.libraryID); let libraryIDs = Zotero.Libraries.getAll().map(x => x.libraryID);
for (let libraryID of libraryIDs) { for (let libraryID of libraryIDs) {
yield Zotero.Collections.loadAllData(libraryID); let library = Zotero.Libraries.get(libraryID);
yield Zotero.Searches.loadAllData(libraryID); yield library.loadAllDataTypes();
yield Zotero.Items.loadAllData(libraryID);
} }
yield Zotero.QuickCopy.init(); yield Zotero.QuickCopy.init();

View file

@ -150,6 +150,11 @@ describe("Zotero.Library", function() {
yield library.saveTx(); yield library.saveTx();
assert.isFalse(Zotero.Libraries.isEditable(library.libraryID)); assert.isFalse(Zotero.Libraries.isEditable(library.libraryID));
}); });
it("should initialize library after creation", function* () {
let library = yield createGroup({});
Zotero.SyncedSettings.get(library.libraryID, "tagColors");
});
}); });
describe("#erase()", function() { describe("#erase()", function() {
it("should erase a group library", function* () { it("should erase a group library", function* () {

View file

@ -239,10 +239,10 @@ describe("Zotero.Sync.Data.Engine", function () {
assert.equal(Zotero.Libraries.getVersion(userLibraryID), 3); assert.equal(Zotero.Libraries.getVersion(userLibraryID), 3);
// Make sure local objects exist // Make sure local objects exist
var setting = yield Zotero.SyncedSettings.get(userLibraryID, "tagColors"); var setting = Zotero.SyncedSettings.get(userLibraryID, "tagColors");
assert.lengthOf(setting, 1); assert.lengthOf(setting, 1);
assert.equal(setting[0].name, 'A'); assert.equal(setting[0].name, 'A');
var settingMetadata = yield Zotero.SyncedSettings.getMetadata(userLibraryID, "tagColors"); var settingMetadata = Zotero.SyncedSettings.getMetadata(userLibraryID, "tagColors");
assert.equal(settingMetadata.version, 2); assert.equal(settingMetadata.version, 2);
assert.isTrue(settingMetadata.synced); assert.isTrue(settingMetadata.synced);
@ -812,7 +812,7 @@ describe("Zotero.Sync.Data.Engine", function () {
yield engine._startDownload(); yield engine._startDownload();
// Make sure objects were deleted // Make sure objects were deleted
assert.isFalse(yield Zotero.SyncedSettings.get(userLibraryID, 'tagColors')); assert.isNull(Zotero.SyncedSettings.get(userLibraryID, 'tagColors'));
assert.isFalse(Zotero.Collections.exists(collectionID)); assert.isFalse(Zotero.Collections.exists(collectionID));
assert.isFalse(Zotero.Searches.exists(searchID)); assert.isFalse(Zotero.Searches.exists(searchID));
assert.isFalse(Zotero.Items.exists(itemID)); assert.isFalse(Zotero.Items.exists(itemID));
@ -901,7 +901,7 @@ describe("Zotero.Sync.Data.Engine", function () {
yield engine._startDownload(); yield engine._startDownload();
// Make sure objects weren't deleted // Make sure objects weren't deleted
assert.ok(yield Zotero.SyncedSettings.get(userLibraryID, 'tagColors')); assert.ok(Zotero.SyncedSettings.get(userLibraryID, 'tagColors'));
assert.ok(Zotero.Collections.exists(collectionID)); assert.ok(Zotero.Collections.exists(collectionID));
assert.ok(Zotero.Searches.exists(searchID)); assert.ok(Zotero.Searches.exists(searchID));
}) })
@ -1212,10 +1212,10 @@ describe("Zotero.Sync.Data.Engine", function () {
yield engine._fullSync(); yield engine._fullSync();
// Check settings // Check settings
var setting = yield Zotero.SyncedSettings.get(userLibraryID, "tagColors"); var setting = Zotero.SyncedSettings.get(userLibraryID, "tagColors");
assert.lengthOf(setting, 1); assert.lengthOf(setting, 1);
assert.equal(setting[0].name, 'A'); assert.equal(setting[0].name, 'A');
var settingMetadata = yield Zotero.SyncedSettings.getMetadata(userLibraryID, "tagColors"); var settingMetadata = Zotero.SyncedSettings.getMetadata(userLibraryID, "tagColors");
assert.equal(settingMetadata.version, 2); assert.equal(settingMetadata.version, 2);
assert.isTrue(settingMetadata.synced); assert.isTrue(settingMetadata.synced);

View file

@ -4,7 +4,7 @@ describe("Tag Selector", function () {
var win, doc, collectionsView; var win, doc, collectionsView;
var clearTagColors = Zotero.Promise.coroutine(function* (libraryID) { var clearTagColors = Zotero.Promise.coroutine(function* (libraryID) {
var tagColors = yield Zotero.Tags.getColors(libraryID); var tagColors = Zotero.Tags.getColors(libraryID);
for (let name of tagColors.keys()) { for (let name of tagColors.keys()) {
yield Zotero.Tags.setColor(libraryID, name, false); yield Zotero.Tags.setColor(libraryID, name, false);
} }

View file

@ -64,4 +64,38 @@ describe("Zotero.Tags", function () {
assert.isFalse(yield Zotero.Tags.getName(tagID)); assert.isFalse(yield Zotero.Tags.getName(tagID));
}) })
}) })
describe("#setColor()", function () {
var libraryID;
before(function* () {
libraryID = Zotero.Libraries.userLibraryID;
// Clear library tag colors
var colors = Zotero.Tags.getColors(libraryID);
for (let color of colors.keys()) {
yield Zotero.Tags.setColor(libraryID, color);
}
});
it("should set color for a tag", function* () {
var aColor = '#ABCDEF';
var bColor = '#BCDEF0';
yield Zotero.Tags.setColor(libraryID, "A", aColor);
yield Zotero.Tags.setColor(libraryID, "B", bColor);
var o = Zotero.Tags.getColor(libraryID, "A")
assert.equal(o.color, aColor);
assert.equal(o.position, 0);
var o = Zotero.Tags.getColor(libraryID, "B")
assert.equal(o.color, bColor);
assert.equal(o.position, 1);
var o = Zotero.SyncedSettings.get(libraryID, 'tagColors');
assert.isArray(o);
assert.lengthOf(o, 2);
assert.sameMembers(o.map(c => c.color), [aColor, bColor]);
});
});
}) })

View file

@ -14,17 +14,6 @@ describe("Item Tags Box", function () {
win.close(); win.close();
}); });
function waitForTagsBox() {
var deferred = Zotero.Promise.defer();
var tagsbox = doc.getElementById('zotero-editpane-tags');
var onRefresh = function (event) {
tagsbox.removeEventListener('refresh', onRefresh);
deferred.resolve();
}
tagsbox.addEventListener('refresh', onRefresh);
return deferred.promise;
}
describe("#notify()", function () { describe("#notify()", function () {
it("should update an existing tag on rename", function* () { it("should update an existing tag on rename", function* () {
var tag = Zotero.Utilities.randomString(); var tag = Zotero.Utilities.randomString();
@ -43,7 +32,6 @@ describe("Item Tags Box", function () {
var tabbox = doc.getElementById('zotero-view-tabbox'); var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2; tabbox.selectedIndex = 2;
yield waitForTagsBox();
var tagsbox = doc.getElementById('zotero-editpane-tags'); var tagsbox = doc.getElementById('zotero-editpane-tags');
var rows = tagsbox.id('tagRows').getElementsByTagName('row'); var rows = tagsbox.id('tagRows').getElementsByTagName('row');
assert.equal(rows.length, 1); assert.equal(rows.length, 1);
@ -77,7 +65,6 @@ describe("Item Tags Box", function () {
var tabbox = doc.getElementById('zotero-view-tabbox'); var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2; tabbox.selectedIndex = 2;
yield waitForTagsBox();
var tagsbox = doc.getElementById('zotero-editpane-tags'); var tagsbox = doc.getElementById('zotero-editpane-tags');
var rows = tagsbox.id('tagRows').getElementsByTagName('row'); var rows = tagsbox.id('tagRows').getElementsByTagName('row');
@ -108,7 +95,6 @@ describe("Item Tags Box", function () {
var tabbox = doc.getElementById('zotero-view-tabbox'); var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2; tabbox.selectedIndex = 2;
yield waitForTagsBox();
var tagsbox = doc.getElementById('zotero-editpane-tags'); var tagsbox = doc.getElementById('zotero-editpane-tags');
var rows = tagsbox.id('tagRows').getElementsByTagName('row'); var rows = tagsbox.id('tagRows').getElementsByTagName('row');
assert.equal(rows.length, 1); assert.equal(rows.length, 1);