diff --git a/chrome/content/zotero/integration/addCitationDialog.js b/chrome/content/zotero/integration/addCitationDialog.js
index cb7174e349..a169c8b6cc 100644
--- a/chrome/content/zotero/integration/addCitationDialog.js
+++ b/chrome/content/zotero/integration/addCitationDialog.js
@@ -492,7 +492,7 @@ var Zotero_Citation_Dialog = new function () {
// run preview function to re-sort, if it hasn't already been
// run
- io.previewFunction();
+ io.sort();
// add items back to list
scrollToItem = null;
@@ -588,22 +588,16 @@ var Zotero_Citation_Dialog = new function () {
if(isCustom) {
var citation = document.getElementById('editor').value;
- } else {
- var citation = (io.citation.citationItems.length ? io.previewFunction() : "");
+ if(Zotero.Utilities.trim(citation) == "") {
+ var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+ var insert = promptService.confirm(window,
+ Zotero.getString("integration.emptyCitationWarning.title"),
+ Zotero.getString("integration.emptyCitationWarning.body"));
+ if(!insert) return false;
+ }
+ io.citation.properties.custom = citation;
}
- Zotero.debug("verified not custom");
-
- if(Zotero.Utilities.trim(citation) == "") {
- var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
- var insert = promptService.confirm(window,
- Zotero.getString("integration.emptyCitationWarning.title"),
- Zotero.getString("integration.emptyCitationWarning.body"));
- if(!insert) return false;
- }
- Zotero.debug("verified not empty");
-
- if(isCustom) io.citation.properties.custom = citation;
return true;
}
diff --git a/chrome/content/zotero/integration/quickFormat.js b/chrome/content/zotero/integration/quickFormat.js
index 0187858bb4..c891f1b66d 100644
--- a/chrome/content/zotero/integration/quickFormat.js
+++ b/chrome/content/zotero/integration/quickFormat.js
@@ -573,7 +573,7 @@ var Zotero_QuickFormat = new function () {
if(!shouldKeepSorted && !editorShowing) return;
_updateCitationObject();
- io.previewFunction();
+ io.sort();
if(shouldKeepSorted) {
// means we need to resort citations
_clearCitation();
@@ -652,12 +652,26 @@ var Zotero_QuickFormat = new function () {
panel.addEventListener("popuphidden", closeListener, false);
}
+ /**
+ * Called when progress changes
+ */
+ function _onProgress(percent) {
+ var meter = document.getElementById("quick-format-progress-meter");
+ if(percent === null) {
+ meter.mode = "undetermined";
+ } else {
+ meter.mode = "determined";
+ meter.value = Math.round(percent);
+ }
+ }
+
/**
* Accepts current selection and adds citation
*/
function _accept() {
_updateCitationObject();
- window.close();
+ document.getElementById("quick-format-deck").selectedIndex = 1;
+ io.accept(_onProgress);
}
/**
@@ -667,7 +681,7 @@ var Zotero_QuickFormat = new function () {
var keyCode = event.keyCode;
if(keyCode === event.DOM_VK_ESCAPE) {
io.citation.citationItems = [];
- window.close();
+ io.accept();
}
}
diff --git a/chrome/content/zotero/integration/quickFormat.xul b/chrome/content/zotero/integration/quickFormat.xul
index 87e1dd5bac..6cf5b945e1 100644
--- a/chrome/content/zotero/integration/quickFormat.xul
+++ b/chrome/content/zotero/integration/quickFormat.xul
@@ -43,22 +43,27 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js
index 0f81f37224..1d055ac3a2 100644
--- a/chrome/content/zotero/xpcom/integration.js
+++ b/chrome/content/zotero/xpcom/integration.js
@@ -23,6 +23,8 @@
***** END LICENSE BLOCK *****
*/
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
const RESELECT_KEY_URI = 1;
const RESELECT_KEY_ITEM_KEY = 2;
const RESELECT_KEY_ITEM_ID = 3;
@@ -37,12 +39,13 @@ Zotero.Integration = new function() {
var _tmpFile = null;
var _osascriptFile;
- var _inProgress = false;
var _integrationVersionsOK = null;
// these need to be global because of GC
var _updateTimer;
+ var _inProgress = false;
+ this.currentWindow = false;
this.sessions = {};
/**
@@ -189,6 +192,9 @@ Zotero.Integration = new function() {
this.execCommand = function execCommand(agent, command, docId) {
if(_inProgress) {
Zotero.Integration.activate();
+ if(Zotero.Integration.currentWindow && !Zotero.Integration.currentWindow.closed) {
+ Zotero.Integration.currentWindow.focus();
+ }
Zotero.debug("Integration: Request already in progress; not executing "+agent+" "+command);
return;
}
@@ -198,7 +204,7 @@ Zotero.Integration = new function() {
if(_checkPluginVersions()) {
_callIntegration(agent, command, docId);
} else {
- inProgress = false;
+ _inProgress = false;
}
}
@@ -248,71 +254,8 @@ Zotero.Integration = new function() {
document = (application.getDocument && docId ? application.getDocument(docId) : application.getActiveDocument());
integration = new Zotero.Integration.Document(application, document);
integration[command]();
- integration.cleanup();
} catch(e) {
- if(integration) {
- try {
- integration.cleanup();
- } catch(e) {
- Components.utils.reportError(e);
- }
- }
-
- if(!(e instanceof Zotero.Integration.UserCancelledException)) {
- try {
- var displayError = null;
- if(e instanceof Zotero.Integration.DisplayException) {
- displayError = e.toString();
- } else {
- // check to see whether there's a pyxpcom error in the console, since it doesn't
- // get thrown directly
- var message = "";
-
- var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
- .getService(Components.interfaces.nsIConsoleService);
-
- var messages = {};
- consoleService.getMessageArray(messages, {});
- messages = messages.value;
- if(messages && messages.length) {
- var lastMessage = messages[messages.length-1];
- try {
- var error = lastMessage.QueryInterface(Components.interfaces.nsIScriptError);
- } catch(e2) {
- if(lastMessage.message && lastMessage.message.substr(0, 12) == "ERROR:xpcom:") {
- // print just the last line of the message, but re-throw the rest
- message = lastMessage.message.substr(0, lastMessage.message.length-1);
- message = "\n"+message.substr(message.lastIndexOf("\n"))
- }
- }
- }
-
- if(!message && typeof(e) == "object" && e.message) message = "\n\n"+e.message;
-
- if(message != "\n\nExceptionAlreadyDisplayed") {
- displayError = Zotero.getString("integration.error.generic")+message;
- }
- Zotero.debug(e);
- }
-
- if(displayError) {
- if(integration) {
- integration._doc.displayAlert(displayError,
- Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_STOP,
- Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK);
- } else {
- Zotero.Integration.activate();
- Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService)
- .alert(null, Zotero.getString("integration.error.title"), displayError);
- }
- }
- } finally {
- throw e;
- }
- }
- } finally {
- _inProgress = false;
+ Zotero.Integration.handleError(e, document);
}
}
@@ -370,6 +313,86 @@ Zotero.Integration = new function() {
}
}
+ /**
+ * Show appropriate dialogs for an integration error
+ */
+ this.handleError = function(e, document) {
+ if(!(e instanceof Zotero.Integration.UserCancelledException)) {
+ try {
+ var displayError = null;
+ if(e instanceof Zotero.Integration.DisplayException) {
+ displayError = e.toString();
+ } else {
+ // check to see whether there's a pyxpcom error in the console, since it doesn't
+ // get thrown directly
+ var message = "";
+
+ var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService);
+
+ var messages = {};
+ consoleService.getMessageArray(messages, {});
+ messages = messages.value;
+ if(messages && messages.length) {
+ var lastMessage = messages[messages.length-1];
+ try {
+ var error = lastMessage.QueryInterface(Components.interfaces.nsIScriptError);
+ } catch(e2) {
+ if(lastMessage.message && lastMessage.message.substr(0, 12) == "ERROR:xpcom:") {
+ // print just the last line of the message, but re-throw the rest
+ message = lastMessage.message.substr(0, lastMessage.message.length-1);
+ message = "\n"+message.substr(message.lastIndexOf("\n"))
+ }
+ }
+ }
+
+ if(!message && typeof(e) == "object") message = "\n\n"+e.toString();
+
+ if(message != "\n\nExceptionAlreadyDisplayed") {
+ displayError = Zotero.getString("integration.error.generic")+message;
+ }
+ Zotero.debug(e);
+ }
+
+ if(displayError) {
+ if(document) {
+ document.displayAlert(displayError,
+ Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_STOP,
+ Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK);
+ } else {
+ Zotero.Integration.activate();
+ Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService)
+ .alert(null, Zotero.getString("integration.error.title"), displayError);
+ }
+ }
+ } finally {
+ Zotero.logError(e);
+ }
+ }
+
+ this.complete(document);
+ }
+
+ /**
+ * Called when integration is complete
+ */
+ this.complete = function(doc) {
+ if(doc) {
+ try {
+ doc.cleanup();
+ doc.activate();
+ } catch(e) {
+ Zotero.logError(e);
+ }
+ }
+
+ if(Zotero.Integration.currentWindow && !Zotero.Integration.currentWindow.closed) {
+ Zotero.Integration.currentWindow.close();
+ }
+ _inProgress = Zotero.Integration.currentWindow = false;
+ }
+
/**
* Runs an AppleScript on OS X
*
@@ -446,27 +469,6 @@ Zotero.Integration.Document = function(app, doc) {
this._doc = doc;
}
-/**
- * Gets the type of the field
- */
-Zotero.Integration.Document.prototype._getCodeTypeAndContent = function(rawCode) {
- for each(var code in ["ITEM", "CITATION"]) {
- if(rawCode.substr(0, code.length) === code) {
- return [INTEGRATION_TYPE_ITEM, rawCode.substr(code.length+1)];
- }
- }
-
- if(rawCode.substr(0, 4) === "BIBL") {
- return [INTEGRATION_TYPE_BIBLIOGRAPHY, rawCode.substr(5)];
- }
-
- if(rawCode.substr(0, 4) === "TEMP") {
- return [INTEGRATION_TYPE_TEMP, rawCode.substr(5)];
- }
-
- return [null, rawCode];
-}
-
/**
* Creates a new session
* @param data {Zotero.Integration.DocumentData} Document data for new session
@@ -485,7 +487,6 @@ Zotero.Integration.Document.prototype._createNewSession = function(data) {
* preferences exist
*/
Zotero.Integration.Document.prototype._getSession = function(require, dontRunSetDocPrefs) {
- this._reloadSession = false;
var dataString = this._doc.getDocumentData();
if(!dataString) {
var haveFields = false;
@@ -525,7 +526,7 @@ Zotero.Integration.Document.prototype._getSession = function(require, dontRunSet
this._doc.setDocumentData(this._session.data.serializeXML());
if(haveFields) {
- this._reloadSession = true;
+ this._session.reload = true;
}
} else {
var data = new Zotero.Integration.DocumentData(dataString);
@@ -570,49 +571,228 @@ Zotero.Integration.Document.prototype._getSession = function(require, dontRunSet
}
this._doc.setDocumentData(this._session.data.serializeXML());
- this._reloadSession = true;
+ this._session.reload = true;
}
}
- this._session.resetRequest(this);
return !!dataString;
}
/**
- * Gets all fields for a document
- * @param require {Boolean} Whether an error should be thrown if no fields exist
- * @param dontRunSetDocPrefs {Boolean} Whether to show the Set Document Preferences window if no
- * preferences exist
+ * Adds a citation to the current document.
*/
-Zotero.Integration.Document.prototype._getFields = function(require, dontRunSetDocPrefs) {
- if(this._fields) return;
- if(!this._session && !this._getSession(require, dontRunSetDocPrefs)) return;
+Zotero.Integration.Document.prototype.addCitation = function() {
+ this._getSession();
- var getFieldsTime = (new Date()).getTime();
- var fields = this._doc.getFields(this._session.data.prefs['fieldType']);
- this._fields = [];
- while(fields.hasMoreElements()) {
- this._fields.push(fields.getNext().QueryInterface(Components.interfaces.zoteroIntegrationField));
- }
- var endTime = (new Date()).getTime();
- if(Zotero.Debug.enabled) {
- Zotero.debug("Integration: got "+this._fields.length+" fields in "+
- (endTime-getFieldsTime)/1000+"; "+
- 1000/((endTime-getFieldsTime)/this._fields.length)+" fields/second");
+ var fieldGetter = new Zotero.Integration.Fields(this._session, this._doc),
+ me = this;
+ fieldGetter.addEditCitation(null, function() {
+ Zotero.Integration.complete(me._doc);
+ });
+}
+
+/**
+ * Edits the citation at the cursor position.
+ */
+Zotero.Integration.Document.prototype.editCitation = function() {
+ this._getSession(true);
+
+ var field = this._doc.cursorInField(this._session.data.prefs['fieldType'])
+ if(!field) {
+ throw new Zotero.Integration.DisplayException("notInCitation");
}
- if(require && !this._fields.length) {
- throw new Zotero.Integration.DisplayException("mustInsertCitation");
+ var fieldGetter = new Zotero.Integration.Fields(this._session, this._doc),
+ me = this;
+ fieldGetter.addEditCitation(field, function() {
+ Zotero.Integration.complete(me._doc);
+ });
+}
+
+/**
+ * Adds a bibliography to the current document.
+ */
+Zotero.Integration.Document.prototype.addBibliography = function() {
+ this._getSession(true);
+
+ // Make sure we can have a bibliography
+ if(!this._session.data.style.hasBibliography) {
+ throw new Zotero.Integration.DisplayException("noBibliography");
}
- return;
+ var fieldGetter = new Zotero.Integration.Fields(this._session, this._doc),
+ field = fieldGetter.addField(),
+ me = this;
+ field.setCode("BIBL");
+ fieldGetter.updateSession(function() {
+ fieldGetter.updateDocument(false, true);
+ Zotero.Integration.complete(me._doc);
+ });
+}
+
+/**
+ * Edits bibliography metadata.
+ */
+Zotero.Integration.Document.prototype.editBibliography = function() {
+ // Make sure we have a bibliography
+ this._getSession(true);
+
+ var fieldGetter = new Zotero.Integration.Fields(this._session, this._doc),
+ me = this;
+ fieldGetter.get(function(fields) {
+ var haveBibliography = false;
+ for(var i=fields.length-1; i>=0; i--) {
+ var code = fields[i].getCode();
+ var [type, content] = fieldGetter.getCodeTypeAndContent(code);
+ if(type == INTEGRATION_TYPE_BIBLIOGRAPHY) {
+ haveBibliography = true;
+ break;
+ }
+ }
+
+ if(!haveBibliography) {
+ throw new Zotero.Integration.DisplayException("mustInsertBibliography");
+ }
+
+ fieldGetter.updateSession();
+ me._session.editBibliography();
+ me._doc.activate();
+ fieldGetter.updateDocument(false, true);
+
+ Zotero.Integration.complete(me._doc);
+ });
+}
+
+/**
+ * Updates the citation data for all citations and bibliography entries.
+ */
+Zotero.Integration.Document.prototype.refresh = function() {
+ this._getSession(true);
+
+ // Send request, forcing update of citations and bibliography
+ var fieldGetter = new Zotero.Integration.Fields(this._session, this._doc),
+ me = this;
+ fieldGetter.updateSession(function() {
+ fieldGetter.updateDocument(true, true);
+ Zotero.Integration.complete(me._doc);
+ });
+}
+
+/**
+ * Deletes field codes.
+ */
+Zotero.Integration.Document.prototype.removeCodes = function() {
+ this._getSession(true);
+
+ var fieldGetter = new Zotero.Integration.Fields(this._session, this._doc),
+ me = this;
+ fieldGetter.get(function(fields) {
+ var result = me._doc.displayAlert(Zotero.getString("integration.removeCodesWarning"),
+ Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_WARNING,
+ Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK_CANCEL);
+ if(result) {
+ for(var i=fields.length-1; i>=0; i--) {
+ fields[i].removeCode();
+ }
+ }
+
+ Zotero.Integration.complete(me._doc);
+ });
+}
+
+/**
+ * Displays a dialog to set document preferences (style, footnotes/endnotes, etc.)
+ */
+Zotero.Integration.Document.prototype.setDocPrefs = function() {
+ this._getSession(false, true);
+
+ var fieldGetter = new Zotero.Integration.Fields(this._session, this._doc);
+ fieldGetter.get();
+
+ try {
+ var oldData = this._session.setDocPrefs(this._app.primaryFieldType, this._app.secondaryFieldType);
+ } finally {
+ this._doc.activate();
+ }
+
+ if(oldData) {
+ this._doc.setDocumentData(this._session.data.serializeXML());
+
+ var me = this;
+ fieldGetter.get(function(fields) {
+ if(fields && fields.length) {
+ // if there are fields, we will have to convert some things; get a list of what we need to deal with
+ var convertBibliographies = oldData === true || oldData.prefs.fieldType != me._session.data.prefs.fieldType;
+ var convertItems = convertBibliographies || oldData.prefs.noteType != me._session.data.prefs.noteType;
+ var fieldsToConvert = new Array();
+ var fieldNoteTypes = new Array();
+ for(var i=0, n=fields.length; i=0; i--) {
- var code = this._fields[i].getCode();
- var [type, content] = this._getCodeTypeAndContent(code);
- if(type == INTEGRATION_TYPE_BIBLIOGRAPHY) {
- haveBibliography = true;
- break;
+ // if there's already a citation, make sure we have item IDs in addition to keys
+ if(field) {
+ var code = field.getCode();
+ [type, content] = this.getCodeTypeAndContent(code);
+ if(type != INTEGRATION_TYPE_ITEM) {
+ throw new Zotero.Integration.DisplayException("notInCitation");
}
- }
-
- if(!haveBibliography) {
- throw new Zotero.Integration.DisplayException("mustInsertBibliography");
- }
-
- this._updateSession();
- this._session.editBibliography();
- this._doc.activate();
- this._updateDocument(false, true);
-}
-
-/**
- * Updates the citation data for all citations and bibliography entries.
- */
-Zotero.Integration.Document.prototype.refresh = function() {
- this._getFields(true);
-
- // Send request, forcing update of citations and bibliography
- this._updateSession();
- this._updateDocument(true, true);
-}
-
-/**
- * Deletes field codes.
- */
-Zotero.Integration.Document.prototype.removeCodes = function() {
- this._getFields(true);
-
- var result = this._doc.displayAlert(Zotero.getString("integration.removeCodesWarning"),
- Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_WARNING,
- Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK_CANCEL);
- if(result) {
- for(var i=this._fields.length-1; i>=0; i--) {
- this._fields[i].removeCode();
- }
- }
-}
-
-
-/**
- * Displays a dialog to set document preferences (style, footnotes/endnotes, etc.)
- */
-Zotero.Integration.Document.prototype.setDocPrefs = function() {
- this._getFields(false, true);
-
- try {
- var oldData = this._session.setDocPrefs(this._app.primaryFieldType, this._app.secondaryFieldType);
- } finally {
- this._doc.activate();
- }
- if(oldData) {
- this._doc.setDocumentData(this._session.data.serializeXML());
- if(this._fields && this._fields.length) {
- // if there are fields, we will have to convert some things; get a list of what we need to deal with
- var convertBibliographies = oldData === true || oldData.prefs.fieldType != this._session.data.prefs.fieldType;
- var convertItems = convertBibliographies || oldData.prefs.noteType != this._session.data.prefs.noteType;
- var fieldsToConvert = new Array();
- var fieldNoteTypes = new Array();
- for each(var field in this._fields) {
- var fieldCode = field.getCode();
- var [type, content] = this._getCodeTypeAndContent(fieldCode);
-
- if(convertItems && type === INTEGRATION_TYPE_ITEM) {
- var citation = this._session.unserializeCitation(fieldCode);
- if(!citation.properties.dontUpdate) {
- fieldsToConvert.push(field);
- fieldNoteTypes.push(this._session.data.prefs.noteType);
- }
- } else if(convertBibliographies && type === INTEGRATION_TYPE_BIBLIOGRAPHY) {
- fieldsToConvert.push(field);
- fieldNoteTypes.push(0);
+
+ citation = io.citation = session.unserializeCitation(content);
+
+ var zoteroItem;
+ for each(var citationItem in citation.citationItems) {
+ var item = false;
+ if(!citationItem.id) {
+ zoteroItem = false;
+ if(citationItem.uris) {
+ [zoteroItem, ] = session.uriMap.getZoteroItemForURIs(citationItem.uris);
+ } else if(citationItem.key) {
+ zoteroItem = Zotero.Items.getByKey(citationItem.key);
}
+ if(zoteroItem) citationItem.id = zoteroItem.id;
}
-
- if(fieldsToConvert.length) {
- // pass to conversion function
- this._doc.convert(new Zotero.Integration.Document.JSEnumerator(fieldsToConvert),
- this._session.data.prefs.fieldType, fieldNoteTypes, fieldNoteTypes.length);
-
- // clear fields so that they will get collected again before refresh
- this._fields = undefined;
+ }
+
+ if(citation.properties.dontUpdate) {
+ if(!this._doc.displayAlert(Zotero.getString("integration.citationChanged.edit"),
+ Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_WARNING,
+ Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK_CANCEL)) {
+ throw new Zotero.Integration.UserCancelledException;
}
-
- // refresh contents
- this._getFields(true);
- this._updateSession();
- this._updateDocument(true, true, true);
+ }
+
+ // make sure it's going to get updated
+ delete citation.properties["formattedCitation"];
+ delete citation.properties["plainCitation"];
+ delete citation.properties["dontUpdate"];
+ } else {
+ newField = true;
+ var field = this.addField(true);
+ field.setCode("TEMP");
+
+ citation = io.citation = {"citationItems":{}, "properties":{}};
+ }
+
+ // assign preview function
+ io.previewFunction = function() {
+ throw "Not yet implemented";
+ citation.properties.zoteroIndex = parseInt(index, 10);
+ citation.properties.noteIndex = parseInt(noteIndex, 10);
+ return me._session.previewCitation(io.citation);
+ }
+ // assign sort function
+ io.sort = function() {
+ me._session.previewCitation(io.citation);
+ }
+ // assign accept function
+ io.accept = function(progressCallback) {
+ me._progressCallback = progressCallback;
+
+ if(io.citation.citationItems.length) {
+ // Citation added
+ me.get(function() {
+ me.updateSession();
+ if(fieldIndex !== undefined) {
+ session.addCitation(fieldIndex, field.getNoteIndex(), io.citation);
+ }
+ session.updateIndices[fieldIndex] = true;
+ me.updateDocument();
+
+ callback();
+ });
+ } else if(newField) {
+ // New citation was cancelled
+ field.delete();
+ callback();
}
}
-}
-
-/**
- * Cleans up any changes made before returning, even if an error occurred
- */
-Zotero.Integration.Document.prototype.cleanup = function() {
- this._doc.cleanup()
-}
-
-/**
- * An exceedingly simple nsISimpleEnumerator implementation
- */
-Zotero.Integration.Document.JSEnumerator = function(objArray) {
- this.objArray = objArray;
-}
-Zotero.Integration.Document.JSEnumerator.prototype.hasMoreElements = function() {
- return this.objArray.length;
-}
-Zotero.Integration.Document.JSEnumerator.prototype.getNext = function() {
- return this.objArray.shift();
+ // determine whether citation is sortable in current style
+ io.sortable = session.style.opt.sort_citations;
+
+ // citeproc-js style object for use of third-party extension
+ io.style = session.style;
+
+ // Find this citation
+ var fieldIndex;
+ this.get(function(fields) {
+ for(var i=0, n=fields.length; i