';
- } else if(this.format == "RTF") {
- this.string += "\\tab ";
- } else if(this.format == "Integration") {
- this.string += "\t";
- } else {
- this.string += " ";
- }
-
- this.insertTabBeforeField = false;
- if(prefix !== "") {
- prefix = prefix.replace(/^\s+/, "");
- } else {
- string = string.replace(/^\s+/, "");
- }
- }
-
- // append delimiter if necessary
- if(this.delimiter && this.string && !dontDelimit) {
- this.append(this.delimiter, null, true);
- }
-
- // append prefix before closing punctuation
- if(prefix !== "") {
- this.append(prefix, null, true);
- }
-
- var addBefore = "";
- var addAfter = "";
-
- // prepend line before if display="block"
- if(element && (element["@display"] == "block" || this.prependLine)) {
- if(this.format == "HTML") {
- if(this.option.(@name == "hanging-indent").@value == "true") {
- addBefore += ''
- } else {
- addBefore += ' ';
- }
- addAfter = ' ';
- } else {
- if(this.format == "RTF") {
- addBefore += "\r\n\\line ";
- } else if(this.format == "Integration") {
- addBefore += "\x0B";
- } else {
- addBefore += (Zotero.isWin ? "\r\n" : "\n");
- }
- this.prependLine = element["@display"] == "block";
- }
- }
-
- // close quotes, etc. using punctuation
- if(this.closePunctuation) {
- if(Zotero.CSL.FormattedString._punctuation.indexOf(string[0]) != -1) {
- this.string += string[0];
- string = string.substr(1);
- }
- this.string += this.closePunctuation;
- this.closePunctuation = "";
- }
-
- // clean up
- if(string.length && string[0] == "." &&
- Zotero.CSL.FormattedString._punctuation.indexOf(this.string[this.string.length-1]) != -1) {
- // if string already ends in punctuation, preserve the existing stuff
- // and don't add a period
- string = string.substr(1);
- } else if(this.string[this.string.length-1] == "(" && string[0] == " ") {
- string = string.substr(1);
- } else if(this.string[this.string.length-1] == " " && string[0] == ")") {
- this.string = this.string.substr(0, this.string.length-1);
- }
-
- // close previous formatting
- this.string += this.closeFormatting;
- this.closeFormatting = "";
-
- // handling of "text-transform" attribute (now obsolete)
- if(element && element["@text-transform"].length() && !element["@text-case"].length()) {
- var mapping = {"lowercase":"lowercase", "uppercase":"uppercase", "capitalize":"capitalize-first"};
- element["@text-case"] = mapping[element["@text-transform"].toString()];
- }
-
- // handle text case
- if(element) {
- if(element["@text-case"].length()) {
- if(element["@text-case"] == "lowercase") {
- // all lowercase
- string = string.toLowerCase();
- } else if(element["@text-case"] == "uppercase") {
- // all uppercase
- string = string.toUpperCase();
- } else if(element["@text-case"] == "sentence") {
- // for now capitalizes only the first letter, the rest are lowercase
- string = string[0].toUpperCase()+string.substr(1).toLowerCase();
- } else if(element["@text-case"] == "capitalize-first") {
- // capitalize first
- string = string[0].toUpperCase()+string.substr(1);
- } else if(element["@text-case"] == "capitalize-all") {
- // capitalize first
- var strings = string.split(" ");
- for(var i=0; i 1) {
- strings[i] = strings[i][0].toUpperCase()+strings[i].substr(1).toLowerCase();
- } else if(strings[i].length == 1) {
- strings[i] = strings[i].toUpperCase();
- }
- }
- string = strings.join(" ");
- } else if(element["@text-case"] == "title") {
- string = Zotero.Text.titleCase(string);
- }
- }
-
- // style attributes
- if(this.format == "HTML") {
- var style = "";
-
- var cssAttributes = ["font-family", "font-style", "font-variant",
- "font-weight", "vertical-align", "display",
- "text-decoration" ];
- for(var j in cssAttributes) {
- var value = element["@"+cssAttributes[j]].toString();
- if(value && value.indexOf('"') == -1) {
- style += cssAttributes[j]+":"+value+";";
- }
- }
-
- if(style) {
- addBefore += '';
- addAfter = ''+addAfter;
- }
- } else {
- if(this.format == "RTF" || this.format == "Integration") {
- var rtfAttributes = {
- "font-style":{"oblique":"i", "italic":"i"},
- "font-variant":{"small-caps":"scaps"},
- "font-weight":{"bold":"b"},
- "text-decoration":{"underline":"ul"},
- "vertical-align":{"sup":"super", "sub":"sub"}
- }
-
- for(var j in rtfAttributes) {
- for(var k in rtfAttributes[j]) {
- if(element["@"+j] == k) {
- addBefore += "\\"+rtfAttributes[j][k]+" ";
- addAfter = "\\"+rtfAttributes[j][k]+"0 "+addAfter;
- }
- }
- }
- }
- }
-
- // add quotes if necessary
- if(element.@quotes == "true") {
- this.string += this._openQuote;
-
- if(this.useBritishStyleQuotes) {
- string += this._closeQuote;
- } else {
- this.closePunctuation = this._closeQuote;
- }
- }
- }
-
- if(!dontEscape) {
- if(this.format == "HTML") {
- string = string.replace("&", "&", "g")
- .replace("<", "<", "g")
- .replace(">", ">", "g")
- .replace(/(\r\n|\r|\n)/g, " ")
- .replace(/[\x00-\x1F]/g, "");
- } else if(this.format == "RTF" || this.format == "Integration") {
- string = string.replace("\\", "\\\\", "g")
- .replace(/(\r\n|\r|\n)/g, "\\line ");
- if(string.substr(string.length-6) == "\\line ") {
- string = string.substr(0, string.length-6);
- addAfter = "\\line "+addAfter;
- }
-
- if(this.format == "RTF") {
- string = string.replace(/[{}\x7F-\uFFFF]/g, Zotero.CSL.FormattedString._rtfEscapeFunction)
- .replace("\t", "\\tab ", "g");
-
- if(string.substr(string.length-5) == "\\tab ") {
- string = string.substr(0, string.length-5);
- addAfter = "\\tab "+addAfter;
- }
- }
- } else {
- string = string.replace(/(\r\n|\r|\n)/g, (Zotero.isWin ? "\r\n" : "\n"));
- }
- }
-
- this.string += addBefore+string;
-
- if(element && element.@suffix.length()) {
- this.append(element.@suffix.toString(), null, true);
- }
-
- // save for second-field-align
- if(!dontDelimit && this.insertTabAfterField) {
- this.insertTabAfterField = false;
- this.insertTabBeforeField = true;
- }
-
- this.closeFormatting = addAfter;
-
- return true;
-}
-
-/*
- * gets the formatted string
- */
-Zotero.CSL.FormattedString.prototype.get = function() {
- return this.string+this.closeFormatting+this.closePunctuation;
-}
-
-/*
- * creates a new formatted string with the same formatting parameters as this one
- */
-Zotero.CSL.FormattedString.prototype.clone = function(delimiter) {
- return new Zotero.CSL.FormattedString(this.context, this.format, delimiter, true);
-}
-
-/*
- * Implementation of FormattedString for sort purposes.
- */
-Zotero.CSL.SortString = function() {
- default xml namespace = "http://purl.org/net/xbiblio/csl";
-
- this.format = "Sort";
- this.string = [];
-}
-
-Zotero.CSL.SortString.prototype.concat = function(newString) {
- if(newString.string.length == 0) {
- return;
- } else if(newString.string.length == 1) {
- this.string.push(newString.string[0]);
- } else {
- this.string.push(newString.string);
- }
-}
-
-Zotero.CSL.SortString.prototype.append = function(newString) {
- this.string.push(newString);
-}
-
-Zotero.CSL.SortString.prototype.compare = function(b, a) {
- // by default, a is this string
- if(a == undefined) {
- a = this.string;
- b = b.string;
- }
-
- var aIsString = typeof(a) != "object";
- var bIsString = typeof(b) != "object";
- if(aIsString && bIsString) {
- if(a == b) {
- return 0;
- } else if(!isNaN(a % 1) && !isNaN(b % 1)) {
- // both numeric
- if(b > a) return -1;
- return 1; // already know they're not equal
- } else {
- var cmp = Zotero.CSL.Global.collation.compareString(Zotero.CSL.Global.collation.kCollationCaseInSensitive, a, b);
- if(cmp == 0) {
- // for some reason collation service returned 0; the collation
- // service sucks! they can't be equal!
- if(b > a) {
- return -1;
- } else {
- return 1;
- }
- }
- return cmp;
- }
- } else if(aIsString && !bIsString) {
- var cmp = this.compare(b[0], a);
- if(cmp == 0) {
- return -1; // a before b
- }
- return cmp;
- } else if(bIsString && !aIsString) {
- var cmp = this.compare(b, a[0]);
- if(cmp == 0) {
- return 1; // b before a
- }
- return cmp;
- }
-
- var maxLength = Math.min(b.length, a.length);
- for(var i = 0; i < maxLength; i++) {
- var cmp = this.compare(b[i], a[i]);
- if(cmp != 0) {
- return cmp;
- }
- }
-
- if(b.length > a.length) {
- return -1; // a before b
- } else if(b.length < a.length) {
- return 1; // b before a
- }
-
- return 0;
-}
-
-
-Zotero.CSL.SortString.prototype.clone = function() {
- return new Zotero.CSL.SortString();
-}
\ No newline at end of file
diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js
index 3fd0925896..d3223200cd 100644
--- a/chrome/content/zotero/xpcom/integration.js
+++ b/chrome/content/zotero/xpcom/integration.js
@@ -26,6 +26,7 @@
const RESELECT_KEY_URI = 1;
const RESELECT_KEY_ITEM_KEY = 2;
const RESELECT_KEY_ITEM_ID = 3;
+const DATA_VERSION = 3;
Zotero.Integration = new function() {
var _fifoFile = null;
@@ -222,6 +223,7 @@ Zotero.Integration = new function() {
integration._doc.displayAlert(Zotero.getString("integration.error.generic")+message,
Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_STOP,
Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK);
+ Zotero.debug(e);
throw e;
}
}
@@ -294,8 +296,11 @@ Zotero.Integration.UserCancelledException.prototype.name = "UserCancelledExcepti
Zotero.Integration.UserCancelledException.prototype.message = "User cancelled document update.";
Zotero.Integration.UserCancelledException.prototype.toString = function() { return this.message; };
-Zotero.Integration.DisplayException = function(name) { this.name = name };
-Zotero.Integration.DisplayException.prototype.toString = function() { return Zotero.getString("integration.error."+this.name); };
+Zotero.Integration.DisplayException = function(name, params) {
+ this.name = name;
+ this.params = params ? params : [];
+};
+Zotero.Integration.DisplayException.prototype.toString = function() { return Zotero.getString("integration.error."+this.name, this.params); };
Zotero.Integration.CorruptFieldException = function(corruptFieldString) {
this.corruptFieldString = corruptFieldString;
@@ -358,14 +363,15 @@ Zotero.Integration.Document.prototype._getSession = function(require, dontRunSet
this._doc.setDocumentData(this._session.data.serializeXML());
}
} else {
- if(dataString[0] != "<") {
+ var data = new Zotero.Integration.DocumentData(dataString);
+ if(data.dataVersion < DATA_VERSION) {
var warning = this._doc.displayAlert(Zotero.getString("integration.upgradeWarning"),
Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_WARNING,
Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK_CANCEL);
if(!warning) throw new Zotero.Integration.UserCancelledException();
+ } else if(data.dataVersion > DATA_VERSION) {
+ throw new Zotero.Integration.DisplayException("newerDocumentVersion", [data.zoteroVersion, Zotero.version]);
}
-
- var data = new Zotero.Integration.DocumentData(dataString);
if(Zotero.Integration.sessions[data.sessionID]) {
this._session = Zotero.Integration.sessions[data.sessionID];
} else {
@@ -409,7 +415,7 @@ Zotero.Integration.Document.prototype._getFields = function(require) {
while(fields.hasMoreElements()) {
this._fields.push(fields.getNext().QueryInterface(Components.interfaces.zoteroIntegrationField));
}
- var endTime = (new Date()).getTime();;
+ var endTime = (new Date()).getTime();
Zotero.debug("Got "+this._fields.length+" fields in "+(endTime-getFieldsTime)/1000+"; "+1000/((endTime-getFieldsTime)/this._fields.length)+" fields/second");
if(require && !this._fields.length) {
@@ -468,7 +474,7 @@ Zotero.Integration.Document.prototype._updateSession = function(newField, editFi
var fieldCode = field.getCode();
if(fieldCode.substr(0, ITEM_CODE.length) == ITEM_CODE) {
- var noteIndex = (this._session.style.class == "note" ? field.getNoteIndex() : 0);
+ var noteIndex = (this._session.styleClass == "note" ? field.getNoteIndex() : 0);
try {
this._session.addCitation(i, noteIndex, fieldCode.substr(ITEM_CODE.length+1));
} catch(e) {
@@ -582,7 +588,8 @@ Zotero.Integration.Document.prototype._updateSession = function(newField, editFi
}
}
- this._session.updateItemSet();
+ //this._session.updateItems();
+ this._session.updateCitations();
// create new citation or edit existing citation
if(editFieldIndex) {
@@ -602,6 +609,7 @@ Zotero.Integration.Document.prototype._updateSession = function(newField, editFi
}
}
}
+ this._session.updateItems();
}
/**
@@ -632,37 +640,28 @@ Zotero.Integration.Document.prototype._updateDocument = function(forceCitations,
// update citations
this._session.updateUpdateIndices(forceCitations);
- for(var i in this._session.updateIndices) {
+ this._deleteFields = this._deleteFields.concat(this._session.updateCitations());
+ for(var i in this._session.citationText) {
citation = this._session.citationsByIndex[i];
if(!citation) continue;
- if(citation.properties["delete"]) {
- // delete citation
- this._deleteFields.push(i);
+ var fieldCode = this._session.getCitationField(citation);
+ if(fieldCode != citation.properties.field) {
+ this._fields[citation.properties.index].setCode(ITEM_CODE+" "+fieldCode);
+ }
+
+ if(citation.properties.custom) {
+ var citationText = citation.properties.custom;
} else {
- var fieldCode = this._session.getCitationField(citation);
- if(fieldCode != citation.properties.field) {
- this._fields[citation.properties.index].setCode(ITEM_CODE+" "+fieldCode);
- }
-
- if(citation.properties.custom) {
- var citationText = citation.properties.custom;
- // XML uses real RTF, rather than the format used for
- // integration, so we have to escape things properly
- citationText = citationText.replace(/[{}\x7F-\uFFFF]/g,
- Zotero.Integration.Session._rtfEscapeFunction).
- replace("\t", "\\tab ", "g");
- } else {
- var citationText = this._session.style.formatCitation(citation, "RTF");
- }
-
- if(citationText.indexOf("\\") !== -1) {
- // need to set text as RTF
- this._fields[citation.properties.index].setText("{\\rtf "+citationText+"}", true);
- } else {
- // set text as plain
- this._fields[citation.properties.index].setText(citationText, false);
- }
+ var citationText = this._session.citationText[i];
+ }
+
+ if(citationText.indexOf("\\") !== -1) {
+ // need to set text as RTF
+ this._fields[citation.properties.index].setText("{\\rtf "+citationText+"}", true);
+ } else {
+ // set text as plain
+ this._fields[citation.properties.index].setText(citationText, false);
}
}
@@ -713,7 +712,7 @@ Zotero.Integration.Document.prototype.addBibliography = function() {
this._getSession(true);
// Make sure we can have a bibliography
- if(!this._session.style.hasBibliography) {
+ if(!this._session.data.style.hasBibliography) {
throw new Zotero.Integration.DisplayException("noBibliography");
}
@@ -856,7 +855,29 @@ Zotero.Integration.Document.JSEnumerator.prototype.getNext = function() {
Zotero.Integration.Session = function() {
// holds items not in document that should be in bibliography
this.uncitedItems = new Object();
+ this.customBibliographyText = new Object();
this.reselectedItems = new Object();
+ this.citationIDs = new Object();
+}
+
+/**
+ * Resets per-request variables in the CitationSet
+ */
+Zotero.Integration.Session.prototype.resetRequest = function() {
+ this.citationsByItemID = new Object();
+ this.citationsByIndex = new Array();
+ this.uriMap = new Zotero.Integration.URIMap(this);
+
+ this.regenerateAll = false;
+ this.bibliographyHasChanged = false;
+ this.bibliographyDataHasChanged = false;
+ this.updateItemIDs = new Object();
+ this.updateIndices = new Object();
+ this.newIndices = new Object();
+
+ this.oldCitationIDs = this.citationIDs;
+ this.citationIDs = new Object();
+ this.citationText = new Object();
}
/**
@@ -868,12 +889,14 @@ Zotero.Integration.Session.prototype.setData = function(data) {
this.data = data;
if(data.style.styleID && oldStyleID != data.style.styleID) {
this.styleID = data.style.styleID;
+ Zotero.debug("style is "+data.style.styleID);
try {
- this.style = Zotero.Styles.get(data.style.styleID).csl;
+ var getStyle = Zotero.Styles.get(data.style.styleID);
+ data.style.hasBibliography = getStyle.hasBibliography;
+ this.style = getStyle.csl;
+ this.style.setOutputFormat("rtf");
+ this.styleClass = getStyle.class;
this.dateModified = new Object();
-
- this.itemSet = this.style.createItemSet();
- this.loadUncitedItems();
} catch(e) {
Zotero.debug(e)
data.style.styleID = undefined;
@@ -916,7 +939,7 @@ Zotero.Integration.Session.prototype.setDocPrefs = function(primaryFieldType, se
data.prefs.fieldType = io.fieldType;
this.setData(data);
// need to do this after setting the data so that we know if it's a note style
- this.data.prefs.noteType = this.style && this.style.class == "note" ? io.useEndnotes+1 : 0;
+ this.data.prefs.noteType = this.style && this.styleClass == "note" ? io.useEndnotes+1 : 0;
if(!oldData || oldData.style.styleID != data.style.styleID
|| oldData.prefs.noteType != data.prefs.noteType
@@ -960,71 +983,61 @@ Zotero.Integration.Session.prototype.reselectItem = function(exception) {
}
}
-/**
- * Resets per-request variables in the CitationSet
- */
-Zotero.Integration.Session.prototype.resetRequest = function() {
- this.citationsByItemID = new Object();
- this.citationsByIndex = new Array();
- this.uriMap = new Zotero.Integration.URIMap(this);
-
- this.regenerateAll = false;
- this.bibliographyHasChanged = false;
- this.bibliographyDataHasChanged = false;
- this.updateItemIDs = new Object();
- this.updateIndices = new Object();
-}
-
/**
* Generates a field from a citation object
*/
Zotero.Integration.Session._acceptableTypes = ["string", "boolean", "number"];
Zotero.Integration.Session._saveProperties = ["custom", "sort"];
+Zotero.Integration.Session._saveItems = ["locator", "label", "suppress-author", "author-only", "prefix", "suffix"];
Zotero.Integration.Session.prototype.getCitationField = function(citation) {
- var type, field = "";
+ var type;
+ var field = [];
+ field.push('"citationID":'+Zotero.JSON.serialize(citation.citationID));
+ var properties = [];
for(var j=0; j= citation.properties.index
- ? Zotero.CSL.POSITION_FIRST : Zotero.CSL.POSITION_SUBSEQUENT);
-
- // update if desired
- if(update && (citation.citationItems[i].position || newPosition) && citation.citationItems[i].position != newPosition) {
- this.updateIndices[citation.properties.index] = true;
- }
- citation.citationItems[i].position = newPosition;
- }
- }
-}
-
-/**
- * Updates the ItemSet, adding and deleting bibliography items as appropriate, then re-sorting
- */
-Zotero.Integration.Session.prototype.updateItemSet = function() {
- var deleteItems = [];
- var missingItems = [];
-
- // see if items were deleted from Zotero
- for(var i in this.citationsByItemID) {
- if (!Zotero.Items.get(i)) {
- deleteItems.push(i);
- missingItems.push(i);
- }
- }
-
- // see if old items were deleted or changed
- for each(var item in this.itemSet.items) {
- var itemID = item.id;
-
- // see if items were removed
- if(!this.citationsByItemID[itemID] && !this.uncitedItems[itemID]) {
- deleteItems.push(itemID);
- continue;
- }
-
- if(item.zoteroItem && this.dateModified[itemID] != item.zoteroItem.getField("dateModified", true, true)) {
- // update date modified
- this.dateModified[itemID] = item.zoteroItem.getField("dateModified", true, true);
- // add to list of updated item IDs
- this.updateItemIDs[itemID] = true;
- }
- }
-
- // delete items from item set
- if(deleteItems.length) {
- this.itemSet.remove(deleteItems);
- this.bibliographyHasChanged = true;
- }
-
- this.sortItemSet();
-}
-
-/**
- * Sorts the ItemSet
- */
-Zotero.Integration.Session.prototype.sortItemSet = function() {
- // save first index
- for(var itemID in this.citationsByItemID) {
- if(this.citationsByItemID[itemID]) {
- var item = this.itemSet.getItemsByIds([itemID])[0];
- if(item) item.setProperty("index", this.citationsByItemID[itemID][0].properties.index);
- }
- }
-
- var citationChanged = this.itemSet.resort();
-
- // add to list of updated item IDs
- for each(var item in citationChanged) {
- this.updateItemIDs[item.id] = true;
- this.bibliographyHasChanged = true;
- }
-}
-
-/**
- * Edits integration bibliography
- */
-Zotero.Integration.Session.prototype.editBibliography = function() {
- var bibliographyEditor = new Zotero.Integration.Session.BibliographyEditInterface(this);
- var io = new function() { this.wrappedJSObject = bibliographyEditor; }
-
- this.bibliographyDataHasChanged = this.bibliographyHasChanged = true;
-
- var window = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
- .getService(Components.interfaces.nsIWindowWatcher)
- .openWindow(null, 'chrome://zotero/content/integration/editBibliographyDialog.xul', '',
- 'chrome,centerscreen,resizable', io, true);
- while(!window.closed) Zotero.mainThread.processNextEvent(true);
+ this.updateIndices[index] = true;
}
/**
@@ -1450,13 +1265,46 @@ Zotero.Integration.Session.prototype.editBibliography = function() {
*/
Zotero.Integration.Session.prototype.getBibliography = function() {
// use real RTF, but chop off the first \n
- var text = this.style.formatBibliography(this.itemSet, "RTF")
- var nlIndex = text.indexOf("\n");
- if(nlIndex !== -1) {
- return "{\\rtf "+text.substr(text.indexOf("\n"));
- } else {
- return "";
- }
+ return Zotero.Cite.makeFormattedBibliography(this.style, "rtf", this.customBibliographyText);
+}
+
+/**
+ * Calls CSL.Engine.updateItems() to reconcile item list with current items in document
+ */
+Zotero.Integration.Session.prototype.updateItems = function() {
+ var items = [[i, this.citationsByItemID[i][0]] for(i in this.citationsByItemID)
+ if(this.citationsByItemID[i] && this.citationsByItemID[i].length &&
+ this.citationsByItemID[i].some(function(citation) citation.properties && !citation.properties.delete))];
+
+ items.sort(function(a, b) {
+ // if first citation of each in different citations, use citation index
+ if(a[1].properties.index != b[1].properties.index) {
+ return a[1].properties.index-b[1].properties.index;
+ }
+
+ // if a and b were both first cited in the same citation, look for index in the citation
+ for each(var citationItem in a[1].citationItems) {
+ if(citationItem.id == a[0]) {
+ return -1;
+ } else if(citationItem.id == b[0]) {
+ return 1;
+ }
+ }
+
+ // should never happen
+ Zotero.debug("WARNING: Zotero.Integration.Session.updateItems sort function returned 0");
+ return 0;
+ });
+
+ // get rid of the second part of the items (the first citation, used for sort purposes)
+ // and also add in the uncited items
+ items = [parseInt(item[0]) for each(item in items)].concat([parseInt(i) for(i in this.uncitedItems)]);
+
+ //Zotero.debug("items are ");
+ //Zotero.debug(items);
+
+ // set items in the bibliography
+ this.style.updateItems(items);
}
/**
@@ -1480,8 +1328,70 @@ Zotero.Integration.Session.prototype.updateUpdateIndices = function(regenerateAl
}
}
-Zotero.Integration.Session._rtfEscapeFunction = function(aChar) {
- return "{\\uc0\\u"+aChar.charCodeAt(0).toString()+"}"
+/**
+ * Returns a formatted citation
+ */
+Zotero.Integration.Session.prototype.formatCitation = function(index, citation) {
+ if(!this.citationText[index]) {
+ //this.updateItems();
+ var citationIndices = [];
+ var citationsPre = [];
+ for(var i=0; i 1);
+ }
+}
+
+/**
+ * Updates the list of citations to be serialized to the document
+ */
+Zotero.Integration.Session.prototype.updateCitations = function() {
+ Zotero.debug("Zotero.Integration: indices of new citations");
+ Zotero.debug([key for(key in this.newIndices)]);
+ Zotero.debug("Zotero.Integration: indices of updated citations");
+ Zotero.debug([key for(key in this.updateIndices)]);
+ var deleteCitations = [];
+ for each(var indexList in [this.newIndices, this.updateIndices]) {
+ for(var index in indexList) {
+ index = parseInt(index, 10);
+ var citation = this.citationsByIndex[index];
+ if(citation.properties.delete) {
+ deleteCitations.push(index);
+ continue;
+ }
+ if(this.formatCitation(index, citation)) {
+ this.bibliographyHasChanged = true;
+ }
+ if(!this.citationIDs[citation.citationID]) {
+ this.citationIDs[citation.citationID] = citation;
+ }
+ delete this.newIndices[index];
+ }
+ }
+
+ return deleteCitations;
}
/**
@@ -1519,8 +1429,6 @@ Zotero.Integration.Session.prototype.loadBibliographyData = function(json) {
}
}
- this.loadUncitedItems();
-
// set custom bibliography entries
if(documentData.custom) {
if(documentData.custom[0]) {
@@ -1531,11 +1439,9 @@ Zotero.Integration.Session.prototype.loadBibliographyData = function(json) {
if(!zoteroItem) continue;
if(needUpdate) this.bibliographyDataHasChanged = true;
- var item = this.itemSet.getItemsByIds([zoteroItem.id])[0];
- if(!item) continue;
-
- item.setProperty("bibliography-Integration", custom[1]);
- item.setProperty("bibliography-RTF", custom[1]);
+ if(this.citationsByItemID[zoteroItem.id] || this.uncitedItems[zoteroItem.id]) {
+ this.customBibliographyText[zoteroItem.id] = custom[1];
+ }
}
} else {
// old style hash
@@ -1544,10 +1450,9 @@ Zotero.Integration.Session.prototype.loadBibliographyData = function(json) {
if(!zoteroItem) zoteroItem = Zotero.Items.get(itemID);
if(!zoteroItem) continue;
- var item = this.itemSet.getItemsByIds([zoteroItem.id])[0];
- if (!item) continue;
- item.setProperty("bibliography-Integration", documentData.custom[itemID]);
- item.setProperty("bibliography-RTF", documentData.custom[itemID]);
+ if(this.citationsByItemID[zoteroItem.id] || this.uncitedItems[zoteroItem.id]) {
+ this.customBibliographyText[zoteroItem.id] = documentData.custom[itemID];
+ }
}
this.bibliographyDataHasChanged = true;
}
@@ -1556,21 +1461,6 @@ Zotero.Integration.Session.prototype.loadBibliographyData = function(json) {
this.bibliographyData = json;
}
-/**
- * Adds items in this.uncitedItems to itemSet, if they are not already there
- */
-Zotero.Integration.Session.prototype.loadUncitedItems = function() {
- for(var itemID in this.uncitedItems) {
- // skip "undefined"
- if(!this.uncitedItems[itemID]) continue;
- var item = this.itemSet.getItemsByIds([itemID])[0];
- if(!item) {
- var zoteroItem = Zotero.Items.get(itemID);
- if(zoteroItem) this.itemSet.add([zoteroItem]);
- }
- }
-}
-
/**
* Saves document data from a JSON object
*/
@@ -1586,17 +1476,8 @@ Zotero.Integration.Session.prototype.getBibliographyData = function() {
}
// look for custom bibliography entries
- if(this.itemSet.items.length) {
- for(var i=0; i
+ var xmlData =
;
@@ -1719,6 +1684,8 @@ Zotero.Integration.DocumentData.prototype.unserializeXML = function(xmlData) {
for each(var pref in xmlData.prefs.children()) {
this.prefs[pref.@name.toString()] = pref.@value.toString();
}
+ this.zoteroVersion = xmlData["@zotero-version"].length() ? xmlData["@zotero-version"].toString() : "2.0";
+ this.dataVersion = xmlData["@data-version"].length() ? xmlData["@data-version"].toString() : 2;
}
/**
@@ -1749,6 +1716,9 @@ Zotero.Integration.DocumentData.prototype.unserialize = function(input) {
} else {
this.prefs.noteType = 0;
}
+
+ this.zoteroVersion = "2.0b6 or earlier";
+ this.dataVersion = 1;
}
}
diff --git a/chrome/content/zotero/xpcom/quickCopy.js b/chrome/content/zotero/xpcom/quickCopy.js
index 057afd1057..696b70acc6 100644
--- a/chrome/content/zotero/xpcom/quickCopy.js
+++ b/chrome/content/zotero/xpcom/quickCopy.js
@@ -391,28 +391,21 @@ Zotero.QuickCopy = new function() {
}
var csl = Zotero.Styles.get(format).csl;
- var itemSet = csl.createItemSet(items);
+ csl.updateItems([item.id for each(item in items)]);
// Copy citations if shift key pressed
if (modified) {
- var itemIDs = [];
- for (var i=0; i]*\?>\s*\n/g, "");
+ var ret = new XML(str);
+ return ret;
+ }
/**
* Finishes installing a style, copying the file, reloading the style cache, and refreshing the
@@ -346,20 +353,13 @@ Zotero.Style = function(file) {
this.type = "csl";
- var xml = Zotero.CSL.Global.cleanXML(Zotero.File.getContents(file));
- try {
- xml = new XML(xml);
- } catch(e) {
- Zotero.log(e.toString(), "error",
- Zotero.Styles.ios.newFileURI(this.file).spec, xml.split(/\r?\n/)[e.lineNumber-1],
- e.lineNumber);
- return;
- }
+ var xml = Zotero.Styles.cleanXML(Zotero.File.getContents(file));
this.styleID = xml.info.id.toString();
this.title = xml.info.title.toString();
this.updated = xml.info.updated.toString().replace(/(.+)T([^\+]+)\+?.*/, "$1 $2");
this._class = xml.@class.toString();
+ this._hasBibliography = !!xml.bibliography.length();
this.source = null;
for each(var link in xml.info.link) {
@@ -381,22 +381,57 @@ Zotero.Style.prototype.__defineGetter__("csl",
* @type Zotero.CSL
*/
function() {
- // cache last style
- if(Zotero.Styles.cacheTranslatorData && Zotero.Styles.lastCSL &&
- Zotero.Styles.lastCSL.styleID == this.styleID) {
- return Zotero.Styles.lastCSL;
+ var locale = Zotero.Prefs.get('export.bibliographyLocale');
+ if(!locale) {
+ var locale = Zotero.locale;
+ if(!locale) {
+ var locale = 'en-US';
+ }
}
+ return new Zotero.CiteProc.CSL.Engine(Zotero.Cite.System, this.getXML(), Zotero.locale);
+});
+
+Zotero.Style.prototype.__defineGetter__("class",
+/**
+ * Retrieves the style class, either from the metadata that's already loaded or by loading the file
+ * @type String
+ */
+function() {
+ if(!this._class) this.getXML();
+ return this._class;
+});
+
+Zotero.Style.prototype.__defineGetter__("hasBibliography",
+/**
+ * Determines whether or not this style has a bibliography, either from the metadata that's already\
+ * loaded or by loading the file
+ * @type String
+ */
+function() {
+ if(!this._hasBibliography) this.getXML();
+ return this._hasBibliography;
+});
+
+/**
+ * Retrieves the XML corresponding to this style
+ * @type String
+ */
+Zotero.Style.prototype.getXML = function() {
+ // "with ({});" needed to fix default namespace scope issue
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=330572
+ default xml namespace = "http://purl.org/net/xbiblio/csl"; with ({});
+
if(this.type == "ens") {
// EN style
var string = Zotero.File.getBinaryContents(this.file);
var enConverter = new Zotero.ENConverter(string, null, this.title);
var xml = enConverter.parse();
- } else {
- // "with ({});" needed to fix default namespace scope issue
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=330572
- default xml namespace = "http://purl.org/net/xbiblio/csl"; with ({});
+ this._class = xml.@class.toString();
+ this._hasBibliography = !!xml.bibliography.length();
+ return XML.toXMLString();
+ } else {
if(this.source) {
// parent/child
var formatCSL = Zotero.Styles.get(this.source);
@@ -409,22 +444,9 @@ function() {
var file = this.file;
}
- var cslString = Zotero.File.getContents(file);
- var xml = new XML(Zotero.CSL.Global.cleanXML(cslString));
+ return Zotero.File.getContents(file);
}
-
- return (Zotero.Styles.lastCSL = new Zotero.CSL(xml));
-});
-
-Zotero.Style.prototype.__defineGetter__("class",
-/**
- * Retrieves the style class, either from the metadata that's already loaded or by loading the file
- * @type String
- */
-function() {
- if(this._class) return this._class;
- return (this._class = this.csl.class);
-});
+};
/**
* Deletes a style
diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js
index 60aaecfc17..cedec20ea9 100644
--- a/chrome/content/zotero/xpcom/zotero.js
+++ b/chrome/content/zotero/xpcom/zotero.js
@@ -1943,8 +1943,8 @@ Zotero.Date = new function(){
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
// If using a non-English bibliography locale, try those too
- if (Zotero.CSL.Global.locale != 'en-US') {
- months = months.concat(Zotero.CSL.Global.getMonthStrings("short"));
+ if (Zotero.locale != 'en-US') {
+ months = months.concat(Zotero.Cite.getMonthStrings("short"));
}
if(!_monthRe) {
_monthRe = new RegExp("^(.*)\\b("+months.join("|")+")[^ ]*(?: (.*)$|$)", "i");
@@ -2020,7 +2020,7 @@ Zotero.Date = new function(){
string += date.part+" ";
}
- var months = Zotero.CSL.Global.getMonthStrings("long");
+ var months = Zotero.Cite.getMonthStrings("long");
if(date.month != undefined && months[date.month]) {
// get short month strings from CSL interpreter
string += months[date.month];
diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties
index 6396df396c..0cad8e1227 100644
--- a/chrome/locale/en-US/zotero/zotero.properties
+++ b/chrome/locale/en-US/zotero/zotero.properties
@@ -575,7 +575,8 @@ integration.missingItem.single = This item no longer exists in your Zotero dat
integration.missingItem.multiple = Item %1$S in this citation no longer exists in your Zotero database. Do you want to select a substitute item?
integration.missingItem.description = Clicking "No" will delete the field codes for citations containing this item, preserving the citation text but deleting it from your bibliography.
integration.removeCodesWarning = Removing field codes will prevent Zotero from updating citations and bibliographies in this document. Are you sure you want to continue?
-integration.upgradeWarning = Your document must be permanently upgraded in order to work with Zotero 2.0b7 or later. It is recommended that you make a backup before proceeding. Are you sure you want to continue?
+integration.upgradeWarning = Your document must be permanently upgraded in order to work with Zotero 2.1 or later. It is recommended that you make a backup before proceeding. Are you sure you want to continue?
+integration.error.newerDocumentVersion = Your document was created with a newer version of Zotero (%1$S) than the currently installed version (%1$S). Please upgrade Zotero before editing this document.
integration.corruptField = The Zotero field code corresponding to this citation, which tells Zotero which item in your library this citation represents, has been corrupted. Would you like to reselect the item?
integration.corruptField.description = Clicking "No" will delete the field codes for citations containing this item, preserving the citation text but potentially deleting it from your bibliography.
integration.corruptBibliography = The Zotero field code for your bibliography is corrupted. Should Zotero clear this field code and generate a new bibliography?
diff --git a/chrome/skin/default/zotero/timeline/bundle.js b/chrome/skin/default/zotero/timeline/bundle.js
index b23f699c6b..6cd0b539de 100644
--- a/chrome/skin/default/zotero/timeline/bundle.js
+++ b/chrome/skin/default/zotero/timeline/bundle.js
@@ -233,7 +233,7 @@ Timeline.GregorianDateLabeller=function(locale,timeZone){this._locale=locale;thi
Modified by Ben for Zotero
*/
-Timeline.GregorianDateLabeller.monthNames = Zotero.CSL.Global.getMonthStrings("short");
+Timeline.GregorianDateLabeller.monthNames = Zotero.Cite.getMonthStrings("short");
Timeline.GregorianDateLabeller.getMonthName=function(month,locale) {
return Timeline.GregorianDateLabeller.monthNames[month];
};
diff --git a/components/zotero-service.js b/components/zotero-service.js
index 8dafdb9f25..4d9138b167 100644
--- a/components/zotero-service.js
+++ b/components/zotero-service.js
@@ -18,9 +18,9 @@ var xpcomFiles = [
'zotero',
'annotate',
'attachments',
+ 'cite',
'collectionTreeView',
'commons',
- 'csl',
'dataServer',
'data_access',
'data/dataObjects',
@@ -74,7 +74,17 @@ var xpcomFiles = [
'zeroconf'
];
-for (var i=0; i |