www

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

httpIntegrationClient.js (7772B)


      1 /*
      2 	***** BEGIN LICENSE BLOCK *****
      3 	
      4 	Copyright © 2017 Center for History and New Media
      5 					George Mason University, Fairfax, Virginia, USA
      6 					http://zotero.org
      7 	
      8 	This file is part of Zotero.
      9 	
     10 	Zotero is free software: you can redistribute it and/or modify
     11 	it under the terms of the GNU Affero General Public License as published by
     12 	the Free Software Foundation, either version 3 of the License, or
     13 	(at your option) any later version.
     14 	
     15 	Zotero is distributed in the hope that it will be useful,
     16 	but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 	GNU Affero General Public License for more details.
     19 
     20 	You should have received a copy of the GNU Affero General Public License
     21 	along with Zotero.  If not, see <http://www.gnu.org/licenses/>.
     22 	
     23 	***** END LICENSE BLOCK *****
     24 */
     25 
     26 /**
     27  * This is a HTTP-based integration interface for Zotero. The actual
     28  * heavy lifting occurs in the connector and/or wherever the connector delegates the heavy
     29  * lifting to.
     30  */
     31 Zotero.HTTPIntegrationClient = {
     32 	deferredResponse: null,
     33 	sendCommandPromise: Zotero.Promise.resolve(),
     34 	sendCommand: async function(command, args=[]) {
     35 		let payload = JSON.stringify({command, arguments: args});
     36 		function sendCommand() {
     37 			Zotero.HTTPIntegrationClient.deferredResponse = Zotero.Promise.defer();
     38 			Zotero.HTTPIntegrationClient.sendResponse.apply(Zotero.HTTPIntegrationClient,
     39 				[200, 'application/json', payload]);
     40 			return Zotero.HTTPIntegrationClient.deferredResponse.promise;
     41 		}
     42 		// Force issued commands to occur sequentially, since these are really just
     43 		// a sequence of HTTP requests and responses.
     44 		// We might want to consider something better later, but this has the advantage of
     45 		// being easy to interface with as a Client, as you don't need SSE or WS.
     46 		if (command != 'Document.complete') {
     47 			Zotero.HTTPIntegrationClient.sendCommandPromise = 
     48 				Zotero.HTTPIntegrationClient.sendCommandPromise.then(sendCommand, sendCommand);
     49 		} else {
     50 			await Zotero.HTTPIntegrationClient.sendCommandPromise;
     51 			sendCommand();
     52 		}
     53 		return Zotero.HTTPIntegrationClient.sendCommandPromise;
     54 	}
     55 };
     56 
     57 Zotero.HTTPIntegrationClient.Application = function() {
     58 	this.primaryFieldType = "Http";
     59 	this.secondaryFieldType = "Http";
     60 	this.outputFormat = 'html';
     61 	this.supportedNotes = ['footnotes'];
     62 };
     63 Zotero.HTTPIntegrationClient.Application.prototype = {
     64 	getActiveDocument: async function() {
     65 		let result = await Zotero.HTTPIntegrationClient.sendCommand('Application.getActiveDocument');
     66 		this.outputFormat = result.outputFormat || this.outputFormat;
     67 		this.supportedNotes = result.supportedNotes || this.supportedNotes;
     68 		return new Zotero.HTTPIntegrationClient.Document(result.documentID);
     69 	}
     70 };
     71 
     72 /**
     73  * See integrationTests.js
     74  */
     75 Zotero.HTTPIntegrationClient.Document = function(documentID) {
     76 	this._documentID = documentID;
     77 };
     78 for (let method of ["activate", "canInsertField", "displayAlert", "getDocumentData",
     79 	"setDocumentData", "setBibliographyStyle"]) {
     80 	Zotero.HTTPIntegrationClient.Document.prototype[method] = async function() {
     81 		return Zotero.HTTPIntegrationClient.sendCommand("Document."+method,
     82 			[this._documentID].concat(Array.prototype.slice.call(arguments)));
     83 	};
     84 }
     85 
     86 // @NOTE Currently unused, prompts are done using the connector
     87 Zotero.HTTPIntegrationClient.Document.prototype._displayAlert = async function(dialogText, icon, buttons) {
     88 	var ps = Services.prompt;
     89 	var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_OK)
     90 		+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_IS_STRING);
     91 	
     92 	switch (buttons) {
     93 		case DIALOG_BUTTONS_OK:
     94 			buttonFlags = ps.BUTTON_POS_0_DEFAULT + ps.BUTTON_POS_0 * ps.BUTTON_TITLE_OK; break;
     95 		case DIALOG_BUTTONS_OK_CANCEL:
     96 			buttonFlags = ps.BUTTON_POS_0_DEFAULT + ps.STD_OK_CANCEL_BUTTONS; break;
     97 		case DIALOG_BUTTONS_YES_NO:
     98 			buttonFlags = ps.BUTTON_POS_0_DEFAULT + ps.STD_YES_NO_BUTTONS; break;
     99 		case DIALOG_BUTTONS_YES_NO_CANCEL:
    100 			buttonFlags = ps.BUTTON_POS_0_DEFAULT + ps.BUTTON_POS_0 * ps.BUTTON_TITLE_YES +
    101 				ps.BUTTON_POS_1 * ps.BUTTON_TITLE_NO +
    102 				ps.BUTTON_POS_2 * ps.BUTTON_TITLE_CANCEL; break;
    103 	}
    104 
    105 	var result = ps.confirmEx(
    106 		null,
    107 		"Zotero",
    108 		dialogText,
    109 		buttonFlags,
    110 		null, null, null,
    111 		null,
    112 		{}
    113 	);
    114 	
    115 	switch (buttons) {
    116 		default:
    117 			break;
    118 		case DIALOG_BUTTONS_OK_CANCEL:
    119 		case DIALOG_BUTTONS_YES_NO:
    120 			result = (result+1)%2; break;
    121 		case DIALOG_BUTTONS_YES_NO_CANCEL:
    122 			result = result == 0 ? 2 : result == 2 ? 0 : 1; break;
    123 	}
    124 	await this.activate();
    125 	return result;
    126 }
    127 Zotero.HTTPIntegrationClient.Document.prototype.cleanup = async function() {};
    128 Zotero.HTTPIntegrationClient.Document.prototype.cursorInField = async function(fieldType) {
    129 	var retVal = await Zotero.HTTPIntegrationClient.sendCommand("Document.cursorInField", [this._documentID, fieldType]);
    130 	if (!retVal) return null;
    131 	return new Zotero.HTTPIntegrationClient.Field(this._documentID, retVal);
    132 };
    133 Zotero.HTTPIntegrationClient.Document.prototype.insertField = async function(fieldType, noteType) {
    134 	var retVal = await Zotero.HTTPIntegrationClient.sendCommand("Document.insertField", [this._documentID, fieldType, parseInt(noteType) || 0]);
    135 	return new Zotero.HTTPIntegrationClient.Field(this._documentID, retVal);
    136 };
    137 Zotero.HTTPIntegrationClient.Document.prototype.getFields = async function(fieldType) {
    138 	var retVal = await Zotero.HTTPIntegrationClient.sendCommand("Document.getFields", [this._documentID, fieldType]);
    139 	return retVal.map(field => new Zotero.HTTPIntegrationClient.Field(this._documentID, field));
    140 };
    141 Zotero.HTTPIntegrationClient.Document.prototype.convert = async function(fields, fieldType, noteTypes) {
    142 	fields = fields.map((f) => f._id);
    143 	await Zotero.HTTPIntegrationClient.sendCommand("Field.convert", [this._documentID, fields, fieldType, noteTypes]);
    144 };
    145 Zotero.HTTPIntegrationClient.Document.prototype.complete = async function() {
    146 	Zotero.HTTPIntegrationClient.inProgress = false;
    147 	Zotero.HTTPIntegrationClient.sendCommand("Document.complete", [this._documentID]);
    148 };
    149 
    150 /**
    151  * See integrationTests.js
    152  */
    153 Zotero.HTTPIntegrationClient.Field = function(documentID, json) {
    154 	this._documentID = documentID; 
    155 	this._id = json.id;
    156 	this._code = json.code;
    157 	this._text = json.text;
    158 	this._noteIndex = json.noteIndex;
    159 };
    160 Zotero.HTTPIntegrationClient.Field.prototype = {};
    161 
    162 for (let method of ["delete", "select", "removeCode"]) {
    163 	Zotero.HTTPIntegrationClient.Field.prototype[method] = async function() {
    164 		return Zotero.HTTPIntegrationClient.sendCommand("Field."+method,
    165 			[this._documentID, this._id].concat(Array.prototype.slice.call(arguments)));
    166 	};
    167 }
    168 Zotero.HTTPIntegrationClient.Field.prototype.getText = async function() {
    169 	return this._text;
    170 };
    171 Zotero.HTTPIntegrationClient.Field.prototype.setText = async function(text, isRich) {
    172 	// The HTML will be stripped by Google Docs and and since we're 
    173 	// caching this value, we need to strip it ourselves
    174 	var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
    175              .createInstance(Components.interfaces.nsIDOMParser);
    176 	var doc = parser.parseFromString(text, "text/html");
    177 	this._text = doc.documentElement.textContent;
    178 	return Zotero.HTTPIntegrationClient.sendCommand("Field.setText", [this._documentID, this._id, text, true]);
    179 };
    180 Zotero.HTTPIntegrationClient.Field.prototype.getCode = async function() {
    181 	return this._code;
    182 };
    183 Zotero.HTTPIntegrationClient.Field.prototype.setCode = async function(code) {
    184 	this._code = code;
    185 	return Zotero.HTTPIntegrationClient.sendCommand("Field.setCode", [this._documentID, this._id, code]);
    186 };
    187 Zotero.HTTPIntegrationClient.Field.prototype.getNoteIndex = async function() {
    188 	return this._noteIndex;
    189 };
    190 Zotero.HTTPIntegrationClient.Field.prototype.equals = async function(arg) {
    191 	return this._id === arg._id;
    192 };