Add a connector document integration endpoint
Specifically for google docs via the connector, but could potentially be used for any integration via HTTP or connector.
This commit is contained in:
parent
7c093b4fb0
commit
5e5b567782
|
@ -147,6 +147,8 @@ var Zotero_File_Interface_Bibliography = new function() {
|
||||||
let dialog = document.getElementById("zotero-doc-prefs-dialog");
|
let dialog = document.getElementById("zotero-doc-prefs-dialog");
|
||||||
dialog.setAttribute('title', `${Zotero.clientName} - ${dialog.getAttribute('title')}`);
|
dialog.setAttribute('title', `${Zotero.clientName} - ${dialog.getAttribute('title')}`);
|
||||||
|
|
||||||
|
if (document.getElementById("formatUsing-groupbox")) {
|
||||||
|
if (["Field", "ReferenceMark"].includes(_io.primaryFieldType)) {
|
||||||
if(_io.fieldType == "Bookmark") document.getElementById("formatUsing").selectedIndex = 1;
|
if(_io.fieldType == "Bookmark") document.getElementById("formatUsing").selectedIndex = 1;
|
||||||
var formatOption = (_io.primaryFieldType == "ReferenceMark" ? "referenceMarks" : "fields");
|
var formatOption = (_io.primaryFieldType == "ReferenceMark" ? "referenceMarks" : "fields");
|
||||||
document.getElementById("fields").label =
|
document.getElementById("fields").label =
|
||||||
|
@ -157,8 +159,12 @@ var Zotero_File_Interface_Bibliography = new function() {
|
||||||
Zotero.getString("integration."+formatOption+".fileFormatNotice");
|
Zotero.getString("integration."+formatOption+".fileFormatNotice");
|
||||||
document.getElementById("bookmarks-file-format-notice").textContent =
|
document.getElementById("bookmarks-file-format-notice").textContent =
|
||||||
Zotero.getString("integration.fields.fileFormatNotice");
|
Zotero.getString("integration.fields.fileFormatNotice");
|
||||||
|
} else {
|
||||||
|
document.getElementById("formatUsing-groupbox").style.display = "none";
|
||||||
|
_io.fieldType = _io.primaryFieldType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(document.getElementById("automaticJournalAbbreviations-checkbox")) {
|
||||||
if(_io.automaticJournalAbbreviations === undefined) {
|
if(_io.automaticJournalAbbreviations === undefined) {
|
||||||
_io.automaticJournalAbbreviations = Zotero.Prefs.get("cite.automaticJournalAbbreviations");
|
_io.automaticJournalAbbreviations = Zotero.Prefs.get("cite.automaticJournalAbbreviations");
|
||||||
}
|
}
|
||||||
|
@ -168,6 +174,7 @@ var Zotero_File_Interface_Bibliography = new function() {
|
||||||
|
|
||||||
document.getElementById("automaticCitationUpdates-checkbox").checked = !_io.delayCitationUpdates;
|
document.getElementById("automaticCitationUpdates-checkbox").checked = !_io.delayCitationUpdates;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set style to false, in case this is cancelled
|
// set style to false, in case this is cancelled
|
||||||
_io.style = false;
|
_io.style = false;
|
||||||
|
@ -204,7 +211,8 @@ var Zotero_File_Interface_Bibliography = new function() {
|
||||||
if (isDocPrefs) {
|
if (isDocPrefs) {
|
||||||
// update status of displayAs box based on style class
|
// update status of displayAs box based on style class
|
||||||
var isNote = selectedStyleObj.class == "note";
|
var isNote = selectedStyleObj.class == "note";
|
||||||
document.getElementById("displayAs-groupbox").hidden = !isNote;
|
var multipleNotesSupported = _io.supportedNotes.length > 1;
|
||||||
|
document.getElementById("displayAs-groupbox").hidden = !isNote || !multipleNotesSupported;
|
||||||
|
|
||||||
// update status of formatUsing box based on style class
|
// update status of formatUsing box based on style class
|
||||||
if(isNote) document.getElementById("formatUsing").selectedIndex = 0;
|
if(isNote) document.getElementById("formatUsing").selectedIndex = 0;
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
</radiogroup>
|
</radiogroup>
|
||||||
</groupbox>
|
</groupbox>
|
||||||
|
|
||||||
<groupbox>
|
<groupbox id="formatUsing-groupbox">
|
||||||
<caption label="&zotero.integration.prefs.formatUsing.label;"/>
|
<caption label="&zotero.integration.prefs.formatUsing.label;"/>
|
||||||
|
|
||||||
<radiogroup id="formatUsing" orient="vertical">
|
<radiogroup id="formatUsing" orient="vertical">
|
||||||
|
|
194
chrome/content/zotero/xpcom/connector/httpIntegrationClient.js
Normal file
194
chrome/content/zotero/xpcom/connector/httpIntegrationClient.js
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright © 2017 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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a HTTP-based integration interface for Zotero. The actual
|
||||||
|
* heavy lifting occurs in the connector and/or wherever the connector delegates the heavy
|
||||||
|
* lifting to.
|
||||||
|
*/
|
||||||
|
Zotero.HTTPIntegrationClient = {
|
||||||
|
deferredResponse: null,
|
||||||
|
sendCommandPromise: Zotero.Promise.resolve(),
|
||||||
|
sendCommand: async function(command, args=[]) {
|
||||||
|
let payload = JSON.stringify({command, arguments: args});
|
||||||
|
function sendCommand() {
|
||||||
|
Zotero.HTTPIntegrationClient.deferredResponse = Zotero.Promise.defer();
|
||||||
|
Zotero.HTTPIntegrationClient.sendResponse.apply(Zotero.HTTPIntegrationClient,
|
||||||
|
[200, 'application/json', payload]);
|
||||||
|
return Zotero.HTTPIntegrationClient.deferredResponse.promise;
|
||||||
|
}
|
||||||
|
// Force issued commands to occur sequentially, since these are really just
|
||||||
|
// a sequence of HTTP requests and responses.
|
||||||
|
// We might want to consider something better later, but this has the advantage of
|
||||||
|
// being easy to interface with as a Client, as you don't need SSE or WS.
|
||||||
|
if (command != 'Document.complete') {
|
||||||
|
Zotero.HTTPIntegrationClient.sendCommandPromise =
|
||||||
|
Zotero.HTTPIntegrationClient.sendCommandPromise.then(sendCommand, sendCommand);
|
||||||
|
} else {
|
||||||
|
await Zotero.HTTPIntegrationClient.sendCommandPromise;
|
||||||
|
sendCommand();
|
||||||
|
}
|
||||||
|
return Zotero.HTTPIntegrationClient.sendCommandPromise;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Zotero.HTTPIntegrationClient.Application = function() {
|
||||||
|
this.primaryFieldType = "Http";
|
||||||
|
this.secondaryFieldType = "Http";
|
||||||
|
this.outputFormat = 'html';
|
||||||
|
this.supportedNotes = ['footnotes'];
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Application.prototype = {
|
||||||
|
getActiveDocument: async function() {
|
||||||
|
let result = await Zotero.HTTPIntegrationClient.sendCommand('Application.getActiveDocument');
|
||||||
|
this.outputFormat = result.outputFormat || this.outputFormat;
|
||||||
|
this.supportedNotes = result.supportedNotes || this.supportedNotes;
|
||||||
|
return new Zotero.HTTPIntegrationClient.Document(result.documentID);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See integrationTests.js
|
||||||
|
*/
|
||||||
|
Zotero.HTTPIntegrationClient.Document = function(documentID) {
|
||||||
|
this._documentID = documentID;
|
||||||
|
};
|
||||||
|
for (let method of ["activate", "canInsertField", "displayAlert", "getDocumentData",
|
||||||
|
"setDocumentData", "setBibliographyStyle"]) {
|
||||||
|
Zotero.HTTPIntegrationClient.Document.prototype[method] = async function() {
|
||||||
|
return Zotero.HTTPIntegrationClient.sendCommand("Document."+method,
|
||||||
|
[this._documentID].concat(Array.prototype.slice.call(arguments)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// @NOTE Currently unused, prompts are done using the connector
|
||||||
|
Zotero.HTTPIntegrationClient.Document.prototype._displayAlert = async function(dialogText, icon, buttons) {
|
||||||
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIPromptService);
|
||||||
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_OK)
|
||||||
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_IS_STRING);
|
||||||
|
|
||||||
|
switch (buttons) {
|
||||||
|
case DIALOG_BUTTONS_OK:
|
||||||
|
buttonFlags = ps.BUTTON_POS_0_DEFAULT + ps.BUTTON_POS_0 * ps.BUTTON_TITLE_OK; break;
|
||||||
|
case DIALOG_BUTTONS_OK_CANCEL:
|
||||||
|
buttonFlags = ps.BUTTON_POS_0_DEFAULT + ps.STD_OK_CANCEL_BUTTONS; break;
|
||||||
|
case DIALOG_BUTTONS_YES_NO:
|
||||||
|
buttonFlags = ps.BUTTON_POS_0_DEFAULT + ps.STD_YES_NO_BUTTONS; break;
|
||||||
|
case DIALOG_BUTTONS_YES_NO_CANCEL:
|
||||||
|
buttonFlags = ps.BUTTON_POS_0_DEFAULT + ps.BUTTON_POS_0 * ps.BUTTON_TITLE_YES +
|
||||||
|
ps.BUTTON_POS_1 * ps.BUTTON_TITLE_NO +
|
||||||
|
ps.BUTTON_POS_2 * ps.BUTTON_TITLE_CANCEL; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = ps.confirmEx(
|
||||||
|
null,
|
||||||
|
"Zotero",
|
||||||
|
dialogText,
|
||||||
|
buttonFlags,
|
||||||
|
null, null, null,
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (buttons) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case DIALOG_BUTTONS_OK_CANCEL:
|
||||||
|
case DIALOG_BUTTONS_YES_NO:
|
||||||
|
result = (result+1)%2; break;
|
||||||
|
case DIALOG_BUTTONS_YES_NO_CANCEL:
|
||||||
|
result = result == 0 ? 2 : result == 2 ? 0 : 1; break;
|
||||||
|
}
|
||||||
|
await this.activate();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Zotero.HTTPIntegrationClient.Document.prototype.cleanup = async function() {};
|
||||||
|
Zotero.HTTPIntegrationClient.Document.prototype.cursorInField = async function(fieldType) {
|
||||||
|
var retVal = await Zotero.HTTPIntegrationClient.sendCommand("Document.cursorInField", [this._documentID, fieldType]);
|
||||||
|
if (!retVal) return null;
|
||||||
|
return new Zotero.HTTPIntegrationClient.Field(this._documentID, retVal);
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Document.prototype.insertField = async function(fieldType, noteType) {
|
||||||
|
var retVal = await Zotero.HTTPIntegrationClient.sendCommand("Document.insertField", [this._documentID, fieldType, parseInt(noteType) || 0]);
|
||||||
|
return new Zotero.HTTPIntegrationClient.Field(this._documentID, retVal);
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Document.prototype.getFields = async function(fieldType) {
|
||||||
|
var retVal = await Zotero.HTTPIntegrationClient.sendCommand("Document.getFields", [this._documentID, fieldType]);
|
||||||
|
return retVal.map(field => new Zotero.HTTPIntegrationClient.Field(this._documentID, field));
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Document.prototype.convert = async function(fields, fieldType, noteTypes) {
|
||||||
|
fields = fields.map((f) => f._id);
|
||||||
|
await Zotero.HTTPIntegrationClient.sendCommand("Field.convert", [this._documentID, fields, fieldType, noteTypes]);
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Document.prototype.complete = async function() {
|
||||||
|
Zotero.HTTPIntegrationClient.inProgress = false;
|
||||||
|
Zotero.HTTPIntegrationClient.sendCommand("Document.complete", [this._documentID]);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See integrationTests.js
|
||||||
|
*/
|
||||||
|
Zotero.HTTPIntegrationClient.Field = function(documentID, json) {
|
||||||
|
this._documentID = documentID;
|
||||||
|
this._id = json.id;
|
||||||
|
this._code = json.code;
|
||||||
|
this._text = json.text;
|
||||||
|
this._noteIndex = json.noteIndex;
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Field.prototype = {};
|
||||||
|
|
||||||
|
for (let method of ["delete", "select", "removeCode"]) {
|
||||||
|
Zotero.HTTPIntegrationClient.Field.prototype[method] = async function() {
|
||||||
|
return Zotero.HTTPIntegrationClient.sendCommand("Field."+method,
|
||||||
|
[this._documentID, this._id].concat(Array.prototype.slice.call(arguments)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Zotero.HTTPIntegrationClient.Field.prototype.getText = async function() {
|
||||||
|
return this._text;
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Field.prototype.setText = async function(text, isRich) {
|
||||||
|
// The HTML will be stripped by Google Docs and and since we're
|
||||||
|
// caching this value, we need to strip it ourselves
|
||||||
|
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||||
|
.getService(Components.interfaces.nsIWindowMediator);
|
||||||
|
var win = wm.getMostRecentWindow('navigator:browser');
|
||||||
|
var doc = new win.DOMParser().parseFromString(text, "text/html");
|
||||||
|
this._text = doc.documentElement.textContent;
|
||||||
|
return Zotero.HTTPIntegrationClient.sendCommand("Field.setText", [this._documentID, this._id, text, isRich]);
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Field.prototype.getCode = async function() {
|
||||||
|
return this._code;
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Field.prototype.setCode = async function(code) {
|
||||||
|
this._code = code;
|
||||||
|
return Zotero.HTTPIntegrationClient.sendCommand("Field.setCode", [this._documentID, this._id, code]);
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Field.prototype.getNoteIndex = async function() {
|
||||||
|
return this._noteIndex;
|
||||||
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Field.prototype.equals = async function(arg) {
|
||||||
|
return this._id === arg._id;
|
||||||
|
};
|
|
@ -484,12 +484,6 @@ Zotero.Server.Connector.SavePage.prototype = {
|
||||||
* @param {Function} sendResponseCallback function to send HTTP response
|
* @param {Function} sendResponseCallback function to send HTTP response
|
||||||
*/
|
*/
|
||||||
init: function(url, data, sendResponseCallback) {
|
init: function(url, data, sendResponseCallback) {
|
||||||
var { library, collection, editable } = Zotero.Server.Connector.getSaveTarget();
|
|
||||||
if (!library.editable) {
|
|
||||||
Zotero.logError("Can't add item to read-only library " + library.name);
|
|
||||||
return sendResponseCallback(500, "application/json", JSON.stringify({ libraryEditable: false }));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.sendResponse = sendResponseCallback;
|
this.sendResponse = sendResponseCallback;
|
||||||
Zotero.Server.Connector.Detect.prototype.init.apply(this, [url, data, sendResponseCallback])
|
Zotero.Server.Connector.Detect.prototype.init.apply(this, [url, data, sendResponseCallback])
|
||||||
},
|
},
|
||||||
|
@ -539,7 +533,11 @@ Zotero.Server.Connector.SavePage.prototype = {
|
||||||
var jsonItems = [];
|
var jsonItems = [];
|
||||||
translate.setHandler("select", function(obj, item, callback) { return me._selectItems(obj, item, callback) });
|
translate.setHandler("select", function(obj, item, callback) { return me._selectItems(obj, item, callback) });
|
||||||
translate.setHandler("itemDone", function(obj, item, jsonItem) {
|
translate.setHandler("itemDone", function(obj, item, jsonItem) {
|
||||||
|
if(collection) {
|
||||||
|
collection.addItem(item.id);
|
||||||
|
}
|
||||||
Zotero.Server.Connector.AttachmentProgressManager.add(jsonItem.attachments);
|
Zotero.Server.Connector.AttachmentProgressManager.add(jsonItem.attachments);
|
||||||
|
|
||||||
jsonItems.push(jsonItem);
|
jsonItems.push(jsonItem);
|
||||||
});
|
});
|
||||||
translate.setHandler("attachmentProgress", function(obj, attachment, progress, error) {
|
translate.setHandler("attachmentProgress", function(obj, attachment, progress, error) {
|
||||||
|
@ -559,7 +557,7 @@ Zotero.Server.Connector.SavePage.prototype = {
|
||||||
} else {
|
} else {
|
||||||
translate.setTranslator(translators[0]);
|
translate.setTranslator(translators[0]);
|
||||||
}
|
}
|
||||||
translate.translate({libraryID, collections: collection ? [collection.id] : false});
|
translate.translate(libraryID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright © 2017 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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds integration endpoints related to doc integration via HTTP/connector.
|
||||||
|
*
|
||||||
|
* document/execCommand initiates an integration command and responds with the
|
||||||
|
* next request for the http client (e.g. 'Application.getDocument').
|
||||||
|
* The client should respond to document/respond with the payload and expect
|
||||||
|
* another response with the next request, until it receives 'Document.complete'
|
||||||
|
* at which point the integration transaction is considered complete.
|
||||||
|
*/
|
||||||
|
Zotero.Server.Endpoints['/connector/document/execCommand'] = function() {};
|
||||||
|
Zotero.Server.Endpoints['/connector/document/execCommand'].prototype = {
|
||||||
|
supportedMethods: ["POST"],
|
||||||
|
supportedDataTypes: ["application/json"],
|
||||||
|
permitBookmarklet: true,
|
||||||
|
init: function(data, sendResponse) {
|
||||||
|
if (Zotero.HTTPIntegrationClient.inProgress) {
|
||||||
|
// This will focus the last integration window if present
|
||||||
|
Zotero.Integration.execCommand('http', data.command, data.docId);
|
||||||
|
sendResponse(503, 'text/plain', 'Integration transaction is already in progress')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Zotero.HTTPIntegrationClient.inProgress = true;
|
||||||
|
Zotero.HTTPIntegrationClient.sendResponse = sendResponse;
|
||||||
|
Zotero.Integration.execCommand('http', data.command, data.docId);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Zotero.Server.Endpoints['/connector/document/respond'] = function() {};
|
||||||
|
Zotero.Server.Endpoints['/connector/document/respond'].prototype = {
|
||||||
|
supportedMethods: ["POST"],
|
||||||
|
supportedDataTypes: ["application/json"],
|
||||||
|
permitBookmarklet: true,
|
||||||
|
|
||||||
|
init: function(data, sendResponse) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
if (data && data.error) {
|
||||||
|
// Apps Script stack is a JSON object
|
||||||
|
if (typeof data.stack != "string") {
|
||||||
|
data.stack = JSON.stringify(data.stack);
|
||||||
|
}
|
||||||
|
Zotero.HTTPIntegrationClient.deferredResponse.reject(data);
|
||||||
|
} else {
|
||||||
|
Zotero.HTTPIntegrationClient.deferredResponse.resolve(data);
|
||||||
|
}
|
||||||
|
Zotero.HTTPIntegrationClient.sendResponse = sendResponse;
|
||||||
|
}
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
|
@ -36,6 +36,7 @@ Zotero.Server = new function() {
|
||||||
412:"Precondition Failed",
|
412:"Precondition Failed",
|
||||||
500:"Internal Server Error",
|
500:"Internal Server Error",
|
||||||
501:"Not Implemented",
|
501:"Not Implemented",
|
||||||
|
503:"Service Unavailable",
|
||||||
504:"Gateway Timeout"
|
504:"Gateway Timeout"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -132,18 +132,9 @@ const xpcomFilesLocal = [
|
||||||
'users',
|
'users',
|
||||||
'translation/translate_item',
|
'translation/translate_item',
|
||||||
'translation/translators',
|
'translation/translators',
|
||||||
'server_connector'
|
'connector/httpIntegrationClient',
|
||||||
];
|
'connector/server_connector',
|
||||||
|
'connector/server_connectorIntegration',
|
||||||
/** XPCOM files to be loaded only for connector translation and DB access **/
|
|
||||||
const xpcomFilesConnector = [
|
|
||||||
'connector/translate_item',
|
|
||||||
'connector/translator',
|
|
||||||
'connector/connector',
|
|
||||||
'connector/connector_firefox',
|
|
||||||
'connector/cachedTypes',
|
|
||||||
'connector/repo',
|
|
||||||
'connector/typeSchemaData'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
|
|
@ -7,6 +7,9 @@ describe("Zotero.Integration", function () {
|
||||||
const INTEGRATION_TYPE_TEMP = 3;
|
const INTEGRATION_TYPE_TEMP = 3;
|
||||||
/**
|
/**
|
||||||
* To be used as a reference for Zotero-Word Integration plugins
|
* To be used as a reference for Zotero-Word Integration plugins
|
||||||
|
*
|
||||||
|
* NOTE: Functions must return promises instead of values!
|
||||||
|
* The functions defined for the dummy are promisified below
|
||||||
*/
|
*/
|
||||||
var DocumentPluginDummy = {};
|
var DocumentPluginDummy = {};
|
||||||
|
|
||||||
|
@ -17,6 +20,7 @@ describe("Zotero.Integration", function () {
|
||||||
this.doc = new DocumentPluginDummy.Document();
|
this.doc = new DocumentPluginDummy.Document();
|
||||||
this.primaryFieldType = "Field";
|
this.primaryFieldType = "Field";
|
||||||
this.secondaryFieldType = "Bookmark";
|
this.secondaryFieldType = "Bookmark";
|
||||||
|
this.supportedNotes = ['footnotes', 'endnotes'];
|
||||||
this.fields = [];
|
this.fields = [];
|
||||||
};
|
};
|
||||||
DocumentPluginDummy.Application.prototype = {
|
DocumentPluginDummy.Application.prototype = {
|
||||||
|
@ -88,25 +92,14 @@ describe("Zotero.Integration", function () {
|
||||||
}
|
}
|
||||||
var field = new DocumentPluginDummy.Field(this);
|
var field = new DocumentPluginDummy.Field(this);
|
||||||
this.fields.push(field);
|
this.fields.push(field);
|
||||||
return field
|
return field;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Gets all fields present in the document.
|
* Gets all fields present in the document.
|
||||||
* @param {String} fieldType
|
* @param {String} fieldType
|
||||||
* @returns {DocumentPluginDummy.FieldEnumerator}
|
* @returns {DocumentPluginDummy.Field[]}
|
||||||
*/
|
*/
|
||||||
getFields: function(fieldType) {return new DocumentPluginDummy.FieldEnumerator(this)},
|
getFields: function(fieldType) {return Array.from(this.fields)},
|
||||||
/**
|
|
||||||
* Gets all fields present in the document. The observer will receive notifications for two
|
|
||||||
* topics: "fields-progress", with the document as the subject and percent progress as data, and
|
|
||||||
* "fields-available", with an nsISimpleEnumerator of fields as the subject and the length as
|
|
||||||
* data
|
|
||||||
* @param {String} fieldType
|
|
||||||
* @param {nsIObserver} observer
|
|
||||||
*/
|
|
||||||
getFieldsAsync: function(fieldType, observer) {
|
|
||||||
observer.observe(this.getFields(fieldType), 'fields-available', null)
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Sets the bibliography style, overwriting the current values for this document
|
* Sets the bibliography style, overwriting the current values for this document
|
||||||
*/
|
*/
|
||||||
|
@ -114,7 +107,7 @@ describe("Zotero.Integration", function () {
|
||||||
tabStops, tabStopsCount) => 0,
|
tabStops, tabStopsCount) => 0,
|
||||||
/**
|
/**
|
||||||
* Converts all fields in a document to a different fieldType or noteType
|
* Converts all fields in a document to a different fieldType or noteType
|
||||||
* @params {DocumentPluginDummy.FieldEnumerator} fields
|
* @params {DocumentPluginDummy.Field[]} fields
|
||||||
*/
|
*/
|
||||||
convert: (fields, toFieldType, toNoteType, count) => 0,
|
convert: (fields, toFieldType, toNoteType, count) => 0,
|
||||||
/**
|
/**
|
||||||
|
@ -128,14 +121,6 @@ describe("Zotero.Integration", function () {
|
||||||
complete: () => 0,
|
complete: () => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
DocumentPluginDummy.FieldEnumerator = function(doc) {this.doc = doc; this.idx = 0};
|
|
||||||
DocumentPluginDummy.FieldEnumerator.prototype = {
|
|
||||||
hasMoreElements: function() {return this.idx < this.doc.fields.length;},
|
|
||||||
getNext: function() {return this.doc.fields[this.idx++]},
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports,
|
|
||||||
Components.interfaces.nsISimpleEnumerator])
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Field class corresponds to a field containing an individual citation
|
* The Field class corresponds to a field containing an individual citation
|
||||||
* or bibliography
|
* or bibliography
|
||||||
|
@ -197,11 +182,12 @@ describe("Zotero.Integration", function () {
|
||||||
getNoteIndex: () => 0,
|
getNoteIndex: () => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let cls of ['Application', 'Document', 'FieldEnumerator', 'Field']) {
|
// Processing functions for logging and promisification
|
||||||
|
for (let cls of ['Application', 'Document', 'Field']) {
|
||||||
for (let methodName in DocumentPluginDummy[cls].prototype) {
|
for (let methodName in DocumentPluginDummy[cls].prototype) {
|
||||||
if (methodName !== 'QueryInterface') {
|
if (methodName !== 'QueryInterface') {
|
||||||
let method = DocumentPluginDummy[cls].prototype[methodName];
|
let method = DocumentPluginDummy[cls].prototype[methodName];
|
||||||
DocumentPluginDummy[cls].prototype[methodName] = function() {
|
DocumentPluginDummy[cls].prototype[methodName] = async function() {
|
||||||
try {
|
try {
|
||||||
Zotero.debug(`DocumentPluginDummy: ${cls}.${methodName} invoked with args ${JSON.stringify(arguments)}`, 2);
|
Zotero.debug(`DocumentPluginDummy: ${cls}.${methodName} invoked with args ${JSON.stringify(arguments)}`, 2);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -250,7 +236,7 @@ describe("Zotero.Integration", function () {
|
||||||
editBibliographyDialog: {}
|
editBibliographyDialog: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
function initDoc(docID, options={}) {
|
async function initDoc(docID, options={}) {
|
||||||
applications[docID] = new DocumentPluginDummy.Application();
|
applications[docID] = new DocumentPluginDummy.Application();
|
||||||
var data = new Zotero.Integration.DocumentData();
|
var data = new Zotero.Integration.DocumentData();
|
||||||
data.prefs = {
|
data.prefs = {
|
||||||
|
@ -261,7 +247,7 @@ describe("Zotero.Integration", function () {
|
||||||
data.style = {styleID, locale: 'en-US', hasBibliography: true, bibliographyStyleHasBeenSet: true};
|
data.style = {styleID, locale: 'en-US', hasBibliography: true, bibliographyStyleHasBeenSet: true};
|
||||||
data.sessionID = Zotero.Utilities.randomString(10);
|
data.sessionID = Zotero.Utilities.randomString(10);
|
||||||
Object.assign(data, options);
|
Object.assign(data, options);
|
||||||
applications[docID].getActiveDocument().setDocumentData(data.serialize());
|
await (await applications[docID].getDocument(docID)).setDocumentData(data.serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDefaultIntegrationDocPrefs() {
|
function setDefaultIntegrationDocPrefs() {
|
||||||
|
@ -354,10 +340,10 @@ describe("Zotero.Integration", function () {
|
||||||
var displayAlertStub;
|
var displayAlertStub;
|
||||||
var style;
|
var style;
|
||||||
before(function* () {
|
before(function* () {
|
||||||
displayAlertStub = sinon.stub(DocumentPluginDummy.Document.prototype, 'displayAlert').returns(0);
|
displayAlertStub = sinon.stub(DocumentPluginDummy.Document.prototype, 'displayAlert').resolves(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(async function () {
|
||||||
// 🦉birds?
|
// 🦉birds?
|
||||||
style = {styleID: "http://www.example.com/csl/waterbirds", locale: 'en-US'};
|
style = {styleID: "http://www.example.com/csl/waterbirds", locale: 'en-US'};
|
||||||
|
|
||||||
|
@ -365,7 +351,7 @@ describe("Zotero.Integration", function () {
|
||||||
try {
|
try {
|
||||||
Zotero.Styles.get(style.styleID).remove();
|
Zotero.Styles.get(style.styleID).remove();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
initDoc(docID, {style});
|
await initDoc(docID, {style});
|
||||||
displayDialogStub.resetHistory();
|
displayDialogStub.resetHistory();
|
||||||
displayAlertStub.reset();
|
displayAlertStub.reset();
|
||||||
});
|
});
|
||||||
|
@ -386,7 +372,7 @@ describe("Zotero.Integration", function () {
|
||||||
}
|
}
|
||||||
return style;
|
return style;
|
||||||
});
|
});
|
||||||
displayAlertStub.returns(1);
|
displayAlertStub.resolves(1);
|
||||||
yield execCommand('addEditCitation', docID);
|
yield execCommand('addEditCitation', docID);
|
||||||
assert.isTrue(displayAlertStub.calledOnce);
|
assert.isTrue(displayAlertStub.calledOnce);
|
||||||
assert.isFalse(displayDialogStub.calledWith(applications[docID].doc, 'chrome://zotero/content/integration/integrationDocPrefs.xul'));
|
assert.isFalse(displayDialogStub.calledWith(applications[docID].doc, 'chrome://zotero/content/integration/integrationDocPrefs.xul'));
|
||||||
|
@ -397,7 +383,7 @@ describe("Zotero.Integration", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should prompt with the document preferences dialog if user clicks NO', function* () {
|
it('should prompt with the document preferences dialog if user clicks NO', function* () {
|
||||||
displayAlertStub.returns(0);
|
displayAlertStub.resolves(0);
|
||||||
yield execCommand('addEditCitation', docID);
|
yield execCommand('addEditCitation', docID);
|
||||||
assert.isTrue(displayAlertStub.calledOnce);
|
assert.isTrue(displayAlertStub.calledOnce);
|
||||||
// Prefs to select a new style and quickFormat
|
// Prefs to select a new style and quickFormat
|
||||||
|
@ -407,7 +393,7 @@ describe("Zotero.Integration", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should download the style without prompting if it is from zotero.org', function* (){
|
it('should download the style without prompting if it is from zotero.org', function* (){
|
||||||
initDoc(docID, {styleID: "http://www.zotero.org/styles/waterbirds", locale: 'en-US'});
|
yield initDoc(docID, {styleID: "http://www.zotero.org/styles/waterbirds", locale: 'en-US'});
|
||||||
var styleInstallStub = sinon.stub(Zotero.Styles, "install").resolves();
|
var styleInstallStub = sinon.stub(Zotero.Styles, "install").resolves();
|
||||||
var style = Zotero.Styles.get(styleID);
|
var style = Zotero.Styles.get(styleID);
|
||||||
var styleGetCalledOnce = false;
|
var styleGetCalledOnce = false;
|
||||||
|
@ -418,7 +404,7 @@ describe("Zotero.Integration", function () {
|
||||||
}
|
}
|
||||||
return style;
|
return style;
|
||||||
});
|
});
|
||||||
displayAlertStub.returns(1);
|
displayAlertStub.resolves(1);
|
||||||
yield execCommand('addEditCitation', docID);
|
yield execCommand('addEditCitation', docID);
|
||||||
assert.isFalse(displayAlertStub.called);
|
assert.isFalse(displayAlertStub.called);
|
||||||
assert.isFalse(displayDialogStub.calledWith(applications[docID].doc, 'chrome://zotero/content/integration/integrationDocPrefs.xul'));
|
assert.isFalse(displayDialogStub.calledWith(applications[docID].doc, 'chrome://zotero/content/integration/integrationDocPrefs.xul'));
|
||||||
|
@ -433,20 +419,20 @@ describe("Zotero.Integration", function () {
|
||||||
describe('#addEditCitation', function() {
|
describe('#addEditCitation', function() {
|
||||||
var insertMultipleCitations = Zotero.Promise.coroutine(function *() {
|
var insertMultipleCitations = Zotero.Promise.coroutine(function *() {
|
||||||
var docID = this.test.fullTitle();
|
var docID = this.test.fullTitle();
|
||||||
if (!(docID in applications)) initDoc(docID);
|
if (!(docID in applications)) yield initDoc(docID);
|
||||||
var doc = applications[docID].doc;
|
var doc = applications[docID].doc;
|
||||||
|
|
||||||
setAddEditItems(testItems[0]);
|
setAddEditItems(testItems[0]);
|
||||||
yield execCommand('addEditCitation', docID);
|
yield execCommand('addEditCitation', docID);
|
||||||
assert.equal(doc.fields.length, 1);
|
assert.equal(doc.fields.length, 1);
|
||||||
var citation = (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
var citation = yield (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
||||||
assert.equal(citation.citationItems.length, 1);
|
assert.equal(citation.citationItems.length, 1);
|
||||||
assert.equal(citation.citationItems[0].id, testItems[0].id);
|
assert.equal(citation.citationItems[0].id, testItems[0].id);
|
||||||
|
|
||||||
setAddEditItems(testItems.slice(1, 3));
|
setAddEditItems(testItems.slice(1, 3));
|
||||||
yield execCommand('addEditCitation', docID);
|
yield execCommand('addEditCitation', docID);
|
||||||
assert.equal(doc.fields.length, 2);
|
assert.equal(doc.fields.length, 2);
|
||||||
citation = (new Zotero.Integration.CitationField(doc.fields[1], doc.fields[1].code)).unserialize();
|
citation = yield (new Zotero.Integration.CitationField(doc.fields[1], doc.fields[1].code)).unserialize();
|
||||||
assert.equal(citation.citationItems.length, 2);
|
assert.equal(citation.citationItems.length, 2);
|
||||||
for (let i = 1; i < 3; i++) {
|
for (let i = 1; i < 3; i++) {
|
||||||
assert.equal(citation.citationItems[i-1].id, testItems[i].id);
|
assert.equal(citation.citationItems[i-1].id, testItems[i].id);
|
||||||
|
@ -459,13 +445,13 @@ describe("Zotero.Integration", function () {
|
||||||
var docID = this.test.fullTitle();
|
var docID = this.test.fullTitle();
|
||||||
var doc = applications[docID].doc;
|
var doc = applications[docID].doc;
|
||||||
|
|
||||||
sinon.stub(doc, 'cursorInField').returns(doc.fields[0]);
|
sinon.stub(doc, 'cursorInField').resolves(doc.fields[0]);
|
||||||
sinon.stub(doc, 'canInsertField').returns(false);
|
sinon.stub(doc, 'canInsertField').resolves(false);
|
||||||
|
|
||||||
setAddEditItems(testItems.slice(3, 5));
|
setAddEditItems(testItems.slice(3, 5));
|
||||||
yield execCommand('addEditCitation', docID);
|
yield execCommand('addEditCitation', docID);
|
||||||
assert.equal(doc.fields.length, 2);
|
assert.equal(doc.fields.length, 2);
|
||||||
var citation = (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
var citation = yield (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
||||||
assert.equal(citation.citationItems.length, 2);
|
assert.equal(citation.citationItems.length, 2);
|
||||||
assert.equal(citation.citationItems[0].id, testItems[3].id);
|
assert.equal(citation.citationItems[0].id, testItems[3].id);
|
||||||
});
|
});
|
||||||
|
@ -494,7 +480,7 @@ describe("Zotero.Integration", function () {
|
||||||
describe('when original citation text has been modified', function() {
|
describe('when original citation text has been modified', function() {
|
||||||
var displayAlertStub;
|
var displayAlertStub;
|
||||||
before(function* () {
|
before(function* () {
|
||||||
displayAlertStub = sinon.stub(DocumentPluginDummy.Document.prototype, 'displayAlert').returns(0);
|
displayAlertStub = sinon.stub(DocumentPluginDummy.Document.prototype, 'displayAlert').resolves(0);
|
||||||
});
|
});
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
displayAlertStub.reset();
|
displayAlertStub.reset();
|
||||||
|
@ -508,8 +494,8 @@ describe("Zotero.Integration", function () {
|
||||||
var doc = applications[docID].doc;
|
var doc = applications[docID].doc;
|
||||||
|
|
||||||
doc.fields[0].text = "modified";
|
doc.fields[0].text = "modified";
|
||||||
sinon.stub(doc, 'cursorInField').returns(doc.fields[0]);
|
sinon.stub(doc, 'cursorInField').resolves(doc.fields[0]);
|
||||||
sinon.stub(doc, 'canInsertField').returns(false);
|
sinon.stub(doc, 'canInsertField').resolves(false);
|
||||||
|
|
||||||
await execCommand('addEditCitation', docID);
|
await execCommand('addEditCitation', docID);
|
||||||
assert.equal(doc.fields.length, 2);
|
assert.equal(doc.fields.length, 2);
|
||||||
|
@ -523,9 +509,9 @@ describe("Zotero.Integration", function () {
|
||||||
let origText = doc.fields[0].text;
|
let origText = doc.fields[0].text;
|
||||||
doc.fields[0].text = "modified";
|
doc.fields[0].text = "modified";
|
||||||
// Return OK
|
// Return OK
|
||||||
displayAlertStub.returns(1);
|
displayAlertStub.resolves(1);
|
||||||
sinon.stub(doc, 'cursorInField').returns(doc.fields[0]);
|
sinon.stub(doc, 'cursorInField').resolves(doc.fields[0]);
|
||||||
sinon.stub(doc, 'canInsertField').returns(false);
|
sinon.stub(doc, 'canInsertField').resolves(false);
|
||||||
setAddEditItems(testItems[0]);
|
setAddEditItems(testItems[0]);
|
||||||
|
|
||||||
await execCommand('addEditCitation', docID);
|
await execCommand('addEditCitation', docID);
|
||||||
|
@ -538,17 +524,17 @@ describe("Zotero.Integration", function () {
|
||||||
var docID = this.test.fullTitle();
|
var docID = this.test.fullTitle();
|
||||||
var doc = applications[docID].doc;
|
var doc = applications[docID].doc;
|
||||||
|
|
||||||
var citation = (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
var citation = await (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
||||||
assert.isNotOk(citation.properties.dontUpdate);
|
assert.isNotOk(citation.properties.dontUpdate);
|
||||||
doc.fields[0].text = "modified";
|
doc.fields[0].text = "modified";
|
||||||
// Return Yes
|
// Return Yes
|
||||||
displayAlertStub.returns(1);
|
displayAlertStub.resolves(1);
|
||||||
|
|
||||||
await execCommand('refresh', docID);
|
await execCommand('refresh', docID);
|
||||||
assert.isTrue(displayAlertStub.called);
|
assert.isTrue(displayAlertStub.called);
|
||||||
assert.equal(doc.fields.length, 2);
|
assert.equal(doc.fields.length, 2);
|
||||||
assert.equal(doc.fields[0].text, "modified");
|
assert.equal(doc.fields[0].text, "modified");
|
||||||
var citation = (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
var citation = await (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
||||||
assert.isOk(citation.properties.dontUpdate);
|
assert.isOk(citation.properties.dontUpdate);
|
||||||
});
|
});
|
||||||
it('should reset citation text if "no" selected in refresh prompt', async function() {
|
it('should reset citation text if "no" selected in refresh prompt', async function() {
|
||||||
|
@ -556,18 +542,18 @@ describe("Zotero.Integration", function () {
|
||||||
var docID = this.test.fullTitle();
|
var docID = this.test.fullTitle();
|
||||||
var doc = applications[docID].doc;
|
var doc = applications[docID].doc;
|
||||||
|
|
||||||
var citation = (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
var citation = await (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
||||||
assert.isNotOk(citation.properties.dontUpdate);
|
assert.isNotOk(citation.properties.dontUpdate);
|
||||||
let origText = doc.fields[0].text;
|
let origText = doc.fields[0].text;
|
||||||
doc.fields[0].text = "modified";
|
doc.fields[0].text = "modified";
|
||||||
// Return No
|
// Return No
|
||||||
displayAlertStub.returns(0);
|
displayAlertStub.resolves(0);
|
||||||
|
|
||||||
await execCommand('refresh', docID);
|
await execCommand('refresh', docID);
|
||||||
assert.isTrue(displayAlertStub.called);
|
assert.isTrue(displayAlertStub.called);
|
||||||
assert.equal(doc.fields.length, 2);
|
assert.equal(doc.fields.length, 2);
|
||||||
assert.equal(doc.fields[0].text, origText);
|
assert.equal(doc.fields[0].text, origText);
|
||||||
var citation = (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
var citation = await (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
|
||||||
assert.isNotOk(citation.properties.dontUpdate);
|
assert.isNotOk(citation.properties.dontUpdate);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -673,11 +659,11 @@ describe("Zotero.Integration", function () {
|
||||||
var field = setTextSpy.firstCall.thisValue;
|
var field = setTextSpy.firstCall.thisValue;
|
||||||
|
|
||||||
for (let i = 0; i < setTextSpy.callCount; i++) {
|
for (let i = 0; i < setTextSpy.callCount; i++) {
|
||||||
assert.isTrue(field.equals(setTextSpy.getCall(i).thisValue));
|
assert.isTrue(yield field.equals(setTextSpy.getCall(i).thisValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < setCodeSpy.callCount; i++) {
|
for (let i = 0; i < setCodeSpy.callCount; i++) {
|
||||||
assert.isTrue(field.equals(setCodeSpy.getCall(i).thisValue));
|
assert.isTrue(yield field.equals(setCodeSpy.getCall(i).thisValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
setTextSpy.restore();
|
setTextSpy.restore();
|
||||||
|
@ -689,7 +675,7 @@ describe("Zotero.Integration", function () {
|
||||||
describe('#addEditBibliography', function() {
|
describe('#addEditBibliography', function() {
|
||||||
var docID = this.fullTitle();
|
var docID = this.fullTitle();
|
||||||
beforeEach(function* () {
|
beforeEach(function* () {
|
||||||
initDoc(docID);
|
yield initDoc(docID);
|
||||||
yield execCommand('addEditCitation', docID);
|
yield execCommand('addEditCitation', docID);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -699,7 +685,7 @@ describe("Zotero.Integration", function () {
|
||||||
assert.isFalse(displayDialogStub.called);
|
assert.isFalse(displayDialogStub.called);
|
||||||
var biblPresent = false;
|
var biblPresent = false;
|
||||||
for (let i = applications[docID].doc.fields.length-1; i >= 0; i--) {
|
for (let i = applications[docID].doc.fields.length-1; i >= 0; i--) {
|
||||||
let field = Zotero.Integration.Field.loadExisting(applications[docID].doc.fields[i]);
|
let field = yield Zotero.Integration.Field.loadExisting(applications[docID].doc.fields[i]);
|
||||||
if (field.type == INTEGRATION_TYPE_BIBLIOGRAPHY) {
|
if (field.type == INTEGRATION_TYPE_BIBLIOGRAPHY) {
|
||||||
biblPresent = true;
|
biblPresent = true;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user