www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit c729dc8a54492c47f96cff1f1c999fb05b950b85
parent a67521e9dd606744fff8057a1bbf59f4f1db2411
Author: Dan Stillman <dstillman@zotero.org>
Date:   Tue, 12 Aug 2014 21:36:45 -0400

Fixes #522, [Async DB] Quick Copy is broken

Export depends on #520 (but still with a synchronous interface, somehow)

Diffstat:
Mchrome/content/zotero/preferences/preferences_export.js | 76+++++++++++++++++++++++++++++++++++++---------------------------------------
Mchrome/content/zotero/xpcom/data/cachedTypes.js | 31++++++++++++++++++++-----------
Mchrome/content/zotero/xpcom/itemTreeView.js | 70+++++++++++++++++++++++++++++++++-------------------------------------
Mchrome/content/zotero/xpcom/quickCopy.js | 119++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mchrome/content/zotero/xpcom/zotero.js | 2++
5 files changed, 164 insertions(+), 134 deletions(-)

diff --git a/chrome/content/zotero/preferences/preferences_export.js b/chrome/content/zotero/preferences/preferences_export.js @@ -146,7 +146,7 @@ Zotero_Preferences.Export = { }, - showQuickCopySiteEditor: function (index) { + showQuickCopySiteEditor: Zotero.Promise.coroutine(function* (index) { var treechildren = document.getElementById('quickCopy-siteSettings-rows'); if (index != undefined && index > -1 && index < treechildren.childNodes.length) { @@ -156,29 +156,28 @@ Zotero_Preferences.Export = { var asHTML = treerow.childNodes[2].getAttribute('label') != ''; } - Zotero.QuickCopy.getSettingFromFormattedName(format) - .then(function (format) { - if (asHTML) { - format = format.replace('bibliography=', 'bibliography/html='); - } - - var io = {domain: domain, format: format, ok: false}; - window.openDialog('chrome://zotero/content/preferences/quickCopySiteEditor.xul', "zotero-preferences-quickCopySiteEditor", "chrome, modal", io); - - if (!io.ok) { - return; - } - - if (domain && domain != io.domain) { - Zotero.DB.query("DELETE FROM settings WHERE setting='quickCopySite' AND key=?", [domain]); - } - - Zotero.DB.query("REPLACE INTO settings VALUES ('quickCopySite', ?, ?)", [io.domain, io.format]); - - this.refreshQuickCopySiteList(); - }.bind(this)) - .done(); - }, + var format = yield Zotero.QuickCopy.getSettingFromFormattedName(format); + if (asHTML) { + format = format.replace('bibliography=', 'bibliography/html='); + } + + var io = {domain: domain, format: format, ok: false}; + window.openDialog('chrome://zotero/content/preferences/quickCopySiteEditor.xul', "zotero-preferences-quickCopySiteEditor", "chrome, modal", io); + + if (!io.ok) { + return; + } + + if (domain && domain != io.domain) { + yield Zotero.DB.queryAsync("DELETE FROM settings WHERE setting='quickCopySite' AND key=?", [domain]); + } + + yield Zotero.DB.queryAsync("REPLACE INTO settings VALUES ('quickCopySite', ?, ?)", [io.domain, io.format]); + + yield Zotero.QuickCopy.loadSiteSettings(); + + yield this.refreshQuickCopySiteList(); + }), refreshQuickCopySiteList: Zotero.Promise.coroutine(function* () { @@ -200,29 +199,28 @@ Zotero_Preferences.Export = { domainCell.setAttribute('label', siteData[i].domainPath); - yield Zotero.QuickCopy.getFormattedNameFromSetting(siteData[i].format) - .then(function (formatted) { - formatCell.setAttribute('label', formatted); - var copyAsHTML = Zotero.QuickCopy.getContentType(siteData[i].format) == 'html'; - HTMLCell.setAttribute('label', copyAsHTML ? ' ✓ ' : ''); - - treerow.appendChild(domainCell); - treerow.appendChild(formatCell); - treerow.appendChild(HTMLCell); - treeitem.appendChild(treerow); - treechildren.appendChild(treeitem); - }); + var formatted = yield Zotero.QuickCopy.getFormattedNameFromSetting(siteData[i].format); + formatCell.setAttribute('label', formatted); + var copyAsHTML = Zotero.QuickCopy.getContentType(siteData[i].format) == 'html'; + HTMLCell.setAttribute('label', copyAsHTML ? ' ✓ ' : ''); + + treerow.appendChild(domainCell); + treerow.appendChild(formatCell); + treerow.appendChild(HTMLCell); + treeitem.appendChild(treerow); + treechildren.appendChild(treeitem); } }), - deleteSelectedQuickCopySite: function () { + deleteSelectedQuickCopySite: Zotero.Promise.coroutine(function* () { var tree = document.getElementById('quickCopy-siteSettings'); var treeitem = tree.lastChild.childNodes[tree.currentIndex]; var domainPath = treeitem.firstChild.firstChild.getAttribute('label'); - Zotero.DB.query("DELETE FROM settings WHERE setting='quickCopySite' AND key=?", [domainPath]); + yield Zotero.DB.queryAsync("DELETE FROM settings WHERE setting='quickCopySite' AND key=?", [domainPath]); + yield Zotero.QuickCopy.loadSiteSettings(); this.refreshQuickCopySiteList(); - }, + }), updateQuickCopyInstructions: function () { diff --git a/chrome/content/zotero/xpcom/data/cachedTypes.js b/chrome/content/zotero/xpcom/data/cachedTypes.js @@ -167,14 +167,13 @@ Zotero.CreatorTypes = new function() { this.getTypesForItemType = getTypesForItemType; this.isValidForItemType = isValidForItemType; - this.getPrimaryIDForType = getPrimaryIDForType; this._typeDesc = 'creator type'; this._idCol = 'creatorTypeID'; this._nameCol = 'creatorType'; this._table = 'creatorTypes'; - var _primaryIDCache = {}; + var _primaryIDCache; var _hasCreatorTypeCache = {}; var _creatorTypesByItemType = {}; var _isValidForItemType = {}; @@ -200,6 +199,16 @@ Zotero.CreatorTypes = new function() { name: row.name }); } + + // Load primary creator type ids + _primaryIDCache = {}; + var sql = "SELECT itemTypeID, creatorTypeID FROM itemTypeCreatorTypes " + + "WHERE primaryField=1"; + var rows = yield Zotero.DB.queryAsync(sql); + for (let i=0; i<rows.length; i++) { + let row = rows[i]; + _primaryIDCache[row.itemTypeID] = row.creatorTypeID; + } }); @@ -248,18 +257,18 @@ Zotero.CreatorTypes = new function() { } - function getPrimaryIDForType(itemTypeID) { - if (_primaryIDCache[itemTypeID]) { - return _primaryIDCache[itemTypeID]; + this.getPrimaryIDForType = function (itemTypeID) { + if (!_primaryIDCache) { + throw new Zotero.Exception.UnloadedDataException( + "Primary creator types not yet loaded" + ); } - var sql = "SELECT creatorTypeID FROM itemTypeCreatorTypes " - + "WHERE itemTypeID=? AND primaryField=1"; - var creatorTypeID = Zotero.DB.valueQuery(sql, itemTypeID); - if (!creatorTypeID) { + + if (_primaryIDCache[itemTypeID] === undefined) { return false; } - _primaryIDCache[itemTypeID] = creatorTypeID; - return creatorTypeID; + + return _primaryIDCache[itemTypeID]; } } diff --git a/chrome/content/zotero/xpcom/itemTreeView.js b/chrome/content/zotero/xpcom/itemTreeView.js @@ -2473,49 +2473,45 @@ Zotero.ItemTreeView.prototype.onDragStart = function (event) { } } - // Quick Copy is asynchronous - Zotero.spawn(function* () { - // Get Quick Copy format for current URL - var url = this._ownerDocument.defaultView.content && this._ownerDocument.defaultView.content.location ? - this._ownerDocument.defaultView.content.location.href : null; - //var format = yield Zotero.QuickCopy.getFormatFromURL(url); - var format = 'bibliography=http://www.zotero.org/styles/chicago-note-bibliography'; - - Zotero.debug("Dragging with format " + (yield Zotero.QuickCopy.getFormattedNameFromSetting(format))); - - var exportCallback = function(obj, worked) { - if (!worked) { - Zotero.log(Zotero.getString("fileInterface.exportError"), 'warning'); - return; - } - - var text = obj.string.replace(/\r\n/g, "\n"); - event.dataTransfer.setData("text/plain", text); + // Get Quick Copy format for current URL + var url = this._ownerDocument.defaultView.content && this._ownerDocument.defaultView.content.location ? + this._ownerDocument.defaultView.content.location.href : null; + var format = Zotero.QuickCopy.getFormatFromURL(url); + + Zotero.debug("Dragging with format " + format); + + var exportCallback = function(obj, worked) { + if (!worked) { + Zotero.log(Zotero.getString("fileInterface.exportError"), 'warning'); + return; } - try { - var [mode, ] = format.split('='); - if (mode == 'export') { - Zotero.QuickCopy.getContentFromItems(items, format, exportCallback); - } - else if (mode.indexOf('bibliography') == 0) { - var content = Zotero.QuickCopy.getContentFromItems(items, format, null, event.shiftKey); - if (content) { - if (content.html) { - event.dataTransfer.setData("text/html", content.html); - } - event.dataTransfer.setData("text/plain", content.text); + var text = obj.string.replace(/\r\n/g, "\n"); + event.dataTransfer.setData("text/plain", text); + } + + try { + var [mode, ] = format.split('='); + if (mode == 'export') { + Zotero.QuickCopy.getContentFromItems(items, format, exportCallback); + } + else if (mode.indexOf('bibliography') == 0) { + var content = Zotero.QuickCopy.getContentFromItems(items, format, null, event.shiftKey); + if (content) { + if (content.html) { + event.dataTransfer.setData("text/html", content.html); } - } - else { - Components.utils.reportError("Invalid Quick Copy mode '" + mode + "'"); + event.dataTransfer.setData("text/plain", content.text); } } - catch (e) { - Zotero.debug(e); - Components.utils.reportError(e + " with format '" + format + "'"); + else { + Components.utils.reportError("Invalid Quick Copy mode '" + mode + "'"); } - }.bind(this)); + } + catch (e) { + Zotero.debug(e); + Components.utils.reportError(e + " with format '" + format + "'"); + } }; diff --git a/chrome/content/zotero/xpcom/quickCopy.js b/chrome/content/zotero/xpcom/quickCopy.js @@ -29,53 +29,42 @@ Zotero.QuickCopy = new function() { this.stripContentType = stripContentType; this.getContentFromItems = getContentFromItems; - var _formattedNames = {}; + var _siteSettings; + var _formattedNames; + this.init = Zotero.Promise.coroutine(function* () { + yield this.loadSiteSettings(); + }); - var _init = Zotero.lazy(function () { - Zotero.debug("Initializing Quick Copy"); - - var translation = new Zotero.Translate.Export; - return translation.getTranslators() - .then(function (translators) { - // add styles to list - var styles = Zotero.Styles.getVisible(); - for each(var style in styles) { - _formattedNames['bibliography=' + style.styleID] = style.title; - } - - for (var i=0; i<translators.length; i++) { - // Skip RDF formats - switch (translators[i].translatorID) { - case '6e372642-ed9d-4934-b5d1-c11ac758ebb7': - case '14763d24-8ba0-45df-8f52-b8d1108e7ac9': - continue; - } - _formattedNames['export=' + translators[i].translatorID] = translators[i].label; - } - }); + + this.loadSiteSettings = Zotero.Promise.coroutine(function* () { + var sql = "SELECT key AS domainPath, value AS format FROM settings " + + "WHERE setting='quickCopySite'"; + var rows = yield Zotero.DB.queryAsync(sql); + // Unproxify storage row + _siteSettings = [for (row of rows) { domainPath: row.domainPath, format: row.format }]; }); - this.getFormattedNameFromSetting = function (setting) { - return _init() - .then(function () { - var name = _formattedNames[this.stripContentType(setting)]; - return name ? name : ''; - }.bind(this)); - } + this.getFormattedNameFromSetting = Zotero.Promise.coroutine(function* (setting) { + if (!_formattedNames) { + yield _loadFormattedNames(); + } + var name = _formattedNames[this.stripContentType(setting)]; + return name ? name : ''; + }); - this.getSettingFromFormattedName = function (name) { - return _init() - .then(function () { - for (var setting in _formattedNames) { - if (_formattedNames[setting] == name) { - return setting; - } + this.getSettingFromFormattedName = Zotero.Promise.coroutine(function* (name) { + if (!_formattedNames) { + yield _loadFormattedNames(); + } + for (var setting in _formattedNames) { + if (_formattedNames[setting] == name) { + return setting; } - return ''; - }); - } + } + return ''; + }); /* @@ -95,7 +84,7 @@ Zotero.QuickCopy = new function() { } - this.getFormatFromURL = Zotero.Promise.coroutine(function* (url) { + this.getFormatFromURL = function (url) { if (!url) { return Zotero.Prefs.get("export.quickCopy.setting"); } @@ -112,13 +101,21 @@ Zotero.QuickCopy = new function() { return Zotero.Prefs.get("export.quickCopy.setting"); } - var matches = []; + if (!_siteSettings) { + throw new Zotero.Exception.UnloadedDataException("Quick Copy site settings not loaded"); + } - var sql = "SELECT key AS domainPath, value AS format FROM settings " - + "WHERE setting='quickCopySite' AND (key LIKE ? OR key LIKE ?)"; var urlDomain = urlHostPort.match(/[^\.]+\.[^\.]+$/); - var rows = yield Zotero.DB.queryAsync(sql, ['%' + urlDomain + '%', '/%']); - for each(var row in rows) { + var matches = []; + for (let i=0; i<_siteSettings.length; i++) { + let row = _siteSettings[i]; + + // Only concern ourselves with entries containing the current domain + // or paths that apply to all domains + if (!row.domainPath.contains(urlDomain) && !row.domainPath.startsWith('/')) { + continue; + } + var [domain, path] = row.domainPath.split(/\//); path = '/' + (path ? path : ''); var re = new RegExp(domain + '$'); @@ -156,7 +153,7 @@ Zotero.QuickCopy = new function() { } return Zotero.Prefs.get("export.quickCopy.setting"); - }); + }; /* @@ -364,4 +361,32 @@ Zotero.QuickCopy = new function() { throw ("Invalid mode '" + mode + "' in Zotero.QuickCopy.getContentFromItems()"); } + + + var _loadFormattedNames = Zotero.Promise.coroutine(function* () { + var t = new Date; + Zotero.debug("Loading formatted names for Quick Copy"); + + var translation = new Zotero.Translate.Export; + var translators = yield translation.getTranslators(); + + // add styles to list + _formattedNames = {}; + var styles = Zotero.Styles.getVisible(); + for each(var style in styles) { + _formattedNames['bibliography=' + style.styleID] = style.title; + } + + for (var i=0; i<translators.length; i++) { + // Skip RDF formats + switch (translators[i].translatorID) { + case '6e372642-ed9d-4934-b5d1-c11ac758ebb7': + case '14763d24-8ba0-45df-8f52-b8d1108e7ac9': + continue; + } + _formattedNames['export=' + translators[i].translatorID] = translators[i].label; + } + + Zotero.debug("Loaded formatted names for Quick Copy in " + (new Date - t) + " ms"); + }); } diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js @@ -621,6 +621,8 @@ Components.utils.import("resource://gre/modules/osfile.jsm"); Zotero.Searches.init(); Zotero.Groups.init(); + // TODO: Delay until after UI is shown + yield Zotero.QuickCopy.init(); Zotero.Items.startEmptyTrashTimer(); } catch (e) {