diff --git a/chrome/content/zotero-platform/mac/integration.css b/chrome/content/zotero-platform/mac/integration.css
index a8aab911b..ee8c9f8bf 100644
--- a/chrome/content/zotero-platform/mac/integration.css
+++ b/chrome/content/zotero-platform/mac/integration.css
@@ -31,6 +31,7 @@ body[multiline="true"] {
#quick-format-entry {
background: -moz-linear-gradient(-90deg, rgb(243,123,119) 0, rgb(180,47,38) 50%, rgb(156,36,27) 50%);
-moz-border-radius:15px;
+ border-radius:15px;
padding: 10px;
}
diff --git a/chrome/content/zotero-platform/win/integration.css b/chrome/content/zotero-platform/win/integration.css
index 38432c6c1..05bb899e8 100644
--- a/chrome/content/zotero-platform/win/integration.css
+++ b/chrome/content/zotero-platform/win/integration.css
@@ -28,6 +28,7 @@
#quick-format-entry:not([square="true"]) {
-moz-border-radius: 15px;
+ border-radius: 15px;
}
#zotero-icon {
diff --git a/chrome/content/zotero/about.xul b/chrome/content/zotero/about.xul
index 12a1b32c0..7c9369502 100644
--- a/chrome/content/zotero/about.xul
+++ b/chrome/content/zotero/about.xul
@@ -279,7 +279,6 @@
-
diff --git a/chrome/content/zotero/preferences/preferences.js b/chrome/content/zotero/preferences/preferences.js
index 46c3b907c..0c3cbbafc 100644
--- a/chrome/content/zotero/preferences/preferences.js
+++ b/chrome/content/zotero/preferences/preferences.js
@@ -1928,7 +1928,7 @@ function handleShowInPreferenceChange() {
/**
* Opens a URI in the basic viewer in Standalone, or a new window in Firefox
*/
-function openInViewer(uri) {
+function openInViewer(uri, newTab) {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
const features = "menubar=yes,toolbar=no,location=no,scrollbars,centerscreen,resizable";
@@ -1944,7 +1944,11 @@ function openInViewer(uri) {
} else {
var win = wm.getMostRecentWindow("navigator:browser");
if(win) {
- win.open(uri, null, features);
+ if(newTab) {
+ win.gBrowser.selectedTab = win.gBrowser.addTab(uri);
+ } else {
+ win.open(uri, null, features);
+ }
}
else {
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
diff --git a/chrome/content/zotero/preferences/preferences.xul b/chrome/content/zotero/preferences/preferences.xul
index f26520214..7cc3afd03 100644
--- a/chrome/content/zotero/preferences/preferences.xul
+++ b/chrome/content/zotero/preferences/preferences.xul
@@ -819,9 +819,9 @@ To add a new preference:
-
-
-
+
+
+
diff --git a/chrome/content/zotero/recognizePDF.js b/chrome/content/zotero/recognizePDF.js
index 11754ec3b..72b6cb3ca 100644
--- a/chrome/content/zotero/recognizePDF.js
+++ b/chrome/content/zotero/recognizePDF.js
@@ -269,7 +269,18 @@ Zotero_RecognizePDF.Recognizer.prototype.recognize = function(file, libraryID, c
var args = ['-enc', 'UTF-8', '-nopgbrk', '-layout', '-l', MAX_PAGES];
args.push(file.path, cacheFile.path);
- proc.run(true, args, args.length);
+ try {
+ if (!Zotero.isFx36) {
+ proc.runw(true, args, args.length);
+ }
+ else {
+ proc.run(true, args, args.length);
+ }
+ }
+ catch (e) {
+ Zotero.debug("Error running pdfinfo", 1);
+ Zotero.debug(e, 1);
+ }
if(!cacheFile.exists()) {
this._callback(false, "recognizePDF.couldNotRead");
diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js
index 5c6a6757c..fedc1ef26 100644
--- a/chrome/content/zotero/tools/testTranslators/testTranslators.js
+++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js
@@ -70,7 +70,7 @@ var Issues = new function() {
};
var req = new XMLHttpRequest();
- req.open("GET", "https://api.github.com/repos/zotero/translators/issues", true);
+ req.open("GET", "https://api.github.com/repos/zotero/translators/issues?per_page=100", true);
req.onreadystatechange = function(e) {
if(req.readyState != 4) return;
@@ -488,7 +488,7 @@ function init() {
hashVars[myVar.substr(0, index)] = myVar.substr(index+1);
}
- if(hashVars["browser"] && /^[a-z]$/.test(hashVars["browser"])
+ if(hashVars["browser"] && /^[a-z]+$/.test(hashVars["browser"])
&& hashVars["version"] && /^[0-9a-zA-Z\-._]/.test(hashVars["version"])) {
loc = "testResults-"+hashVars["browser"]+"-"+hashVars["version"]+".json";
}
diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js
index c987bc120..909637898 100644
--- a/chrome/content/zotero/tools/testTranslators/translatorTester.js
+++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js
@@ -220,7 +220,9 @@ Zotero_TranslatorTester._sanitizeItem = function(item, forSave) {
const skipFields = ["note", "notes", "itemID", "attachments", "tags", "seeAlso",
"itemType", "complete", "creators"];
for(var field in item) {
- if(skipFields.indexOf(field) !== -1) continue;
+ if(skipFields.indexOf(field) !== -1) {
+ continue;
+ }
if(!item[field] || !(fieldID = Zotero.ItemFields.getID(field))) {
delete item[field];
@@ -241,6 +243,9 @@ Zotero_TranslatorTester._sanitizeItem = function(item, forSave) {
// remove fields to be ignored
if("accessDate" in item) delete item.accessDate;
+
+ //sort tags, if they're still there
+ if(item.tags && typeof item.tags === "object" && "sort" in item.tags) item.tags.sort();
return item;
};
diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js
index a4ac284c7..98a361602 100644
--- a/chrome/content/zotero/xpcom/citeproc.js
+++ b/chrome/content/zotero/xpcom/citeproc.js
@@ -126,7 +126,7 @@ var CSL = {
MARK_TRAILING_NAMES: true,
POSITION_TEST_VARS: ["position", "first-reference-note-number", "near-note"],
AREAS: ["citation", "citation_sort", "bibliography", "bibliography_sort"],
- MULTI_FIELDS: ["event", "publisher", "publisher-place", "event-place", "title", "container-title", "collection-title", "authority","edition","genre","title-short","subjurisdiction","medium"],
+ MULTI_FIELDS: ["event", "publisher", "publisher-place", "event-place", "title", "container-title", "collection-title", "authority","edition","genre","title-short","medium","jurisdiction"],
CITE_FIELDS: ["first-reference-note-number", "locator", "locator-revision"],
MINIMAL_NAME_FIELDS: ["literal", "family"],
SWAPPING_PUNCTUATION: [".", "!", "?", ":",","],
@@ -1061,9 +1061,6 @@ CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePr
curr = this.current.value();
}
if ("string" === typeof blob.blobs) {
- if (this.state.tmp.strip_periods && !noStripPeriods) {
- blob.blobs = blob.blobs.replace(/\./g, "");
- }
if (!ignorePredecessor) {
this.state.tmp.term_predecessor = true;
}
@@ -1076,6 +1073,9 @@ CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePr
if (blob.strings["text-case"]) {
blob.blobs = CSL.Output.Formatters[blob.strings["text-case"]](this.state, str);
}
+ if (this.state.tmp.strip_periods && !noStripPeriods) {
+ blob.blobs = blob.blobs.replace(/\./g, "");
+ }
this.state.fun.flipflopper.init(str, blob);
this.state.fun.flipflopper.processTags();
} else if (useblob) {
@@ -1276,6 +1276,9 @@ CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, has_more) {
if (blob.strings["text-case"]) {
str = CSL.Output.Formatters[blob.strings["text-case"]](this.state, str);
}
+ if (str && this.state.tmp.strip_periods && !noStripPeriods) {
+ str = str.replace(/\./g, "");
+ }
if (!state.tmp.suppress_decorations) {
llen = blob.decorations.length;
for (ppos = 0; ppos < llen; ppos += 1) {
@@ -2153,7 +2156,7 @@ CSL.DateParser = function () {
};
CSL.Engine = function (sys, style, lang, forceLang) {
var attrs, langspec, localexml, locale;
- this.processor_version = "1.0.295";
+ this.processor_version = "1.0.302";
this.csl_version = "1.0";
this.sys = sys;
this.sys.xml = new CSL.System.Xml.Parsing();
@@ -2163,6 +2166,7 @@ CSL.Engine = function (sys, style, lang, forceLang) {
if (CSL.getAbbreviation) {
this.sys.getAbbreviation = CSL.getAbbreviation;
}
+ this.sys.AbbreviationSegments = CSL.AbbreviationSegments;
this.parallel = new CSL.Parallel(this);
this.transform = new CSL.Transform(this);
this.setParseNames = function (val) {
@@ -2337,10 +2341,12 @@ CSL.Engine.prototype.getTerm = function (term, form, plural, gender, mode) {
if (!ret && term === "range-delimiter") {
ret = "\u2013";
}
- if (typeof ret === "undefined" && mode === CSL.STRICT) {
- throw "Error in getTerm: term \"" + term + "\" does not exist.";
- } else if (mode === CSL.TOLERANT) {
- ret = false;
+ if (typeof ret === "undefined") {
+ if (mode === CSL.STRICT) {
+ throw "Error in getTerm: term \"" + term + "\" does not exist.";
+ } else if (mode === CSL.TOLERANT) {
+ ret = "";
+ }
}
if (ret) {
this.tmp.cite_renders_content = true;
@@ -2470,6 +2476,14 @@ CSL.Engine.prototype.retrieveItem = function (id) {
Item.volume = Item.number;
Item.number = undefined;
}
+ if (Item.page) {
+ Item["page-first"] = Item.page;
+ var num = "" + Item.page;
+ m = num.split(/\s*(?:&|,|-)\s*/);
+ if (m[0].slice(-1) !== "\\") {
+ Item["page-first"] = m[0];
+ }
+ }
if (this.opt.development_extensions.field_hack && Item.note) {
m = Item.note.match(CSL.NOTE_FIELDS_REGEXP);
if (m) {
@@ -2495,12 +2509,6 @@ CSL.Engine.prototype.retrieveItem = function (id) {
}
}
}
- if (this.opt.development_extensions.jurisdiction_subfield && Item.jurisdiction) {
- var subjurisdictions = Item.jurisdiction.split(";");
- if (subjurisdictions.length > 1) {
- Item.subjurisdiction = subjurisdictions.join(";");
- }
- }
for (var i = 1, ilen = CSL.DATE_VARIABLES.length; i < ilen; i += 1) {
var dateobj = Item[CSL.DATE_VARIABLES[i]];
if (dateobj) {
@@ -3510,10 +3518,10 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
} else {
var ibidme = false;
var suprame = false;
- if (j > 0 && parseInt(k, 10) === 0) {
+ if (j > 0 && parseInt(k, 10) === 0 && citations[j - 1].properties.noteIndex !== citations[j].properties.noteIndex) {
var items = citations[(j - 1)].sortedItems;
var useme = false;
- if ((citations[(j - 1)].sortedItems[0][1].id == item[1].id && citations[j - 1].properties.noteIndex >= (citations[j].properties.noteIndex - 1)) || citations[(j - 1)].sortedItems[0][1].id == this.registry.registry[item[1].id].parallel) {
+ if ((citations[j - 1].sortedItems[0][1].id == item[1].id && citations[j - 1].properties.noteIndex >= (citations[j].properties.noteIndex - 1)) || citations[j - 1].sortedItems[0][1].id == this.registry.registry[item[1].id].parallel) {
if (citationsInNote[citations[j - 1].properties.noteIndex] == 1 || citations[j - 1].properties.noteIndex == 0) {
useme = true;
}
@@ -3529,7 +3537,11 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
} else {
suprame = true;
}
- } else if (k > 0 && onecitation.sortedItems[(k - 1)][1].id == item[1].id) {
+ } else if (k > 0 && onecitation.sortedItems[k - 1][1].id == item[1].id) {
+ ibidme = true;
+ } else if (k == 0 && citations[j - 1].properties.noteIndex == citations[j].properties.noteIndex
+ && citations[j - 1].sortedItems.length
+ && citations[j - 1].sortedItems.slice(-1)[0][1].id == item[1].id) {
ibidme = true;
} else {
suprame = true;
@@ -4717,7 +4729,11 @@ CSL.Node.group = {
if (state.tmp.group_context.mystack.length) {
state.output.current.value().parent = state.tmp.group_context.value()[4];
}
- state.tmp.group_context.push([false, false, false, false, state.output.current.value()], CSL.LITERAL);
+ var label_form = state.tmp.group_context.value()[5];
+ if (this.strings.label_form_override) {
+ label_form = this.strings.label_form_override;
+ }
+ state.tmp.group_context.push([false, false, false, false, state.output.current.value(), label_form], CSL.LITERAL);
if (this.strings.oops) {
state.tmp.group_context.value()[3] = this.strings.oops;
}
@@ -5016,9 +5032,11 @@ CSL.Node.key = {
func = CSL.dateAsSortKey;
single_text.variables = this.variables;
} else if ("title" === variable) {
- state.transform.init("empty", "title");
- state.transform.setTransformFallback(true);
- func = state.transform.getOutputFunction(this.variables);
+ var abbrevfam = "title";
+ var abbrfall = false;
+ var altvar = false;
+ var transfall = true;
+ func = state.transform.getOutputFunction(this.variables, abbrevfam, abbrfall, altvar, transfall);
} else {
func = function (state, Item) {
var varval = Item[variable];
@@ -5465,7 +5483,7 @@ CSL.NameOutput.prototype._buildLabel = function (term, plural, position) {
var ret = false;
var node = this.label[position];
if (node) {
- ret = CSL.castLabel(this.state, node, term, plural);
+ ret = CSL.castLabel(this.state, node, term, plural, CSL.TOLERANT);
}
return ret;
};
@@ -6836,7 +6854,7 @@ CSL.evaluateLabel = function (node, state, Item, item) {
plural = state.tmp.shadow_numbers[myterm].plural;
}
}
- return CSL.castLabel(state, node, myterm, plural);
+ return CSL.castLabel(state, node, myterm, plural, CSL.TOLERANT);
};
CSL.evaluateStringPluralism = function (str) {
if (str) {
@@ -6848,7 +6866,11 @@ CSL.evaluateStringPluralism = function (str) {
return 0;
};
CSL.castLabel = function (state, node, term, plural, mode) {
- var ret = state.getTerm(term, node.strings.form, plural, false, mode);
+ var label_form = node.strings.form;
+ if (state.tmp.group_context.value()[5]) {
+ label_form = state.tmp.group_context.value()[5];
+ }
+ var ret = state.getTerm(term, label_form, plural, false, mode);
if (state.tmp.strip_periods) {
ret = ret.replace(/\./g, "");
} else {
@@ -7280,9 +7302,6 @@ CSL.Node.number = {
varname = this.variables[0];
state.parallel.StartVariable(this.variables[0]);
state.parallel.AppendToVariable(Item[this.variables[0]]);
- if (varname === "page-range" || varname === "page-first") {
- varname = "page";
- }
var node = this;
if (!state.tmp.shadow_numbers[varname]
|| (state.tmp.shadow_numbers[varname].values.length
@@ -7521,25 +7540,26 @@ CSL.Node.text = {
};
this.execs.push(func);
if (CSL.MULTI_FIELDS.indexOf(this.variables_real[0]) > -1) {
+ var abbrevfam = this.variables[0];
+ var abbrfall = false;
+ var altvar = false;
+ var transfall = false;
if (form === "short") {
- state.transform.init(this, this.variables_real[0], this.variables_real[0]);
if (this.variables_real[0] === "container-title") {
- state.transform.setAlternativeVariableName("journalAbbreviation");
+ altvar = "journalAbbreviation";
} else if (this.variables_real[0] === "title") {
- state.transform.setAlternativeVariableName("shortTitle");
+ altvar = "shortTitle";
}
} else {
- state.transform.init(this, this.variables_real[0]);
+ abbrevfam = false;
}
if (state.build.extension) {
- state.transform.init(this, this.variables_real[0], this.variables_real[0]);
- state.transform.setTransformFallback(true);
- func = state.transform.getOutputFunction(this.variables);
+ transfall = true;
} else {
- state.transform.setTransformFallback(true);
- state.transform.setAbbreviationFallback(true);
- func = state.transform.getOutputFunction(this.variables);
+ transfall = true;
+ abbrfall = true;
}
+ func = state.transform.getOutputFunction(this.variables, abbrevfam, abbrfall, altvar, transfall);
if (this.variables_real[0] === "container-title") {
var xfunc = function (state, Item, item) {
if (Item['container-title'] && state.tmp.citeblob.has_volume) {
@@ -7561,14 +7581,9 @@ CSL.Node.text = {
} else if (this.variables_real[0] === "page-first") {
func = function (state, Item) {
var idx, value;
- value = state.getVariable(Item, "page", form);
+ value = state.getVariable(Item, "page-first", form);
if (value) {
- value = ""+value;
- value = value.replace("\u2013", "-", "g");
- idx = value.indexOf("-");
- if (idx > -1) {
- value = value.slice(0, idx);
- }
+ value = value.replace("\\", "");
state.output.append(value, this, false, false, true);
}
};
@@ -7594,15 +7609,15 @@ CSL.Node.text = {
}
};
} else if (this.variables_real[0] === "hereinafter") {
- if (state.sys.getAbbreviation) {
- func = function (state, Item) {
- var hereinafter_info = state.transform.getHereinafter(Item);
+ func = function (state, Item) {
+ var hereinafter_info = state.transform.getHereinafter(Item);
+ if (state.transform.abbrevs[hereinafter_info[0]]) {
var value = state.transform.abbrevs[hereinafter_info[0]].hereinafter[hereinafter_info[1]];
if (value) {
state.tmp.group_context.value()[2] = true;
state.output.append(value, this);
}
- };
+ }
}
} else if (this.variables_real[0] === "URL") {
func = function (state, Item) {
@@ -7685,9 +7700,30 @@ CSL.Node.text = {
}
};
CSL.Attributes = {};
+CSL.Attributes["@subjurisdictions"] = function (state, arg) {
+ var trysubjurisdictions = parseInt(arg, 10);
+ var func = function (state, Item, item) {
+ var subjurisdictions = 0;
+ if (Item.jurisdiction) {
+ var subjurisdictions = Item.jurisdiction.split(";").length;
+ }
+ if (subjurisdictions) {
+ subjurisdictions += -1;
+ }
+ var ret = false;
+ if (subjurisdictions >= trysubjurisdictions) {
+ ret = true;
+ }
+ return [ret];
+ };
+ this.tests.push(func);
+}
+CSL.Attributes["@label-form"] = function (state, arg) {
+ this.strings.label_form_override = arg;
+}
CSL.Attributes["@has-year-only"] = function (state, arg) {
- trydates = arg.split(/\s+/);
- func = function (state, Item, item) {
+ var trydates = arg.split(/\s+/);
+ var func = function (state, Item, item) {
var ret = [];
for (var i = 0, ilen = trydates.length; i < ilen; i += 1) {
var trydate = Item[trydates[i]];
@@ -7702,8 +7738,8 @@ CSL.Attributes["@has-year-only"] = function (state, arg) {
this.tests.push(func);
}
CSL.Attributes["@has-month-or-season-only"] = function (state, arg) {
- trydates = arg.split(/\s+/);
- func = function (state, Item, item) {
+ var trydates = arg.split(/\s+/);
+ var func = function (state, Item, item) {
var ret = [];
for (var i = 0, ilen = trydates.length; i < ilen; i += 1) {
var trydate = Item[trydates[i]];
@@ -7718,8 +7754,8 @@ CSL.Attributes["@has-month-or-season-only"] = function (state, arg) {
this.tests.push(func);
}
CSL.Attributes["@has-day-only"] = function (state, arg) {
- trydates = arg.split(/\s+/);
- func = function (state, Item, item) {
+ var trydates = arg.split(/\s+/);
+ var func = function (state, Item, item) {
var ret = [];
for (var i = 0, ilen = trydates.length; i < ilen; i += 1) {
var trydate = Item[trydates[i]];
@@ -7843,9 +7879,6 @@ CSL.Attributes["@variable"] = function (state, arg) {
len = this.variables.length;
for (pos = 0; pos < len; pos += 1) {
variable = this.variables[pos];
- if (variable === "page-first") {
- variable = "page";
- }
if (variable === "authority"
&& "string" === typeof Item[variable]
&& "names" === this.name) {
@@ -8204,7 +8237,7 @@ CSL.Attributes["@position"] = function (state, arg) {
state.opt.update_mode = CSL.POSITION;
if ("near-note" === arg) {
var near_note_func = function (state, Item, item) {
- if (item && item["near-note"]) {
+ if (item && item["position"] === CSL.POSITION_SUBSEQUENT && item["near-note"]) {
return true;
}
return false;
@@ -8401,7 +8434,9 @@ CSL.Attributes["@text-case"] = function (state, arg) {
if (arg === "title") {
var m = false;
var default_locale = state.opt["default-locale"][0].slice(0, 2);
- if (Item.language) {
+ if (Item.jurisdiction) {
+ this.strings["text-case"] = "passthrough";
+ } else if (Item.language) {
m = Item.language.match(/^\s*([A-Za-z]{2})(?:$|-| )/);
if (!m) {
this.strings["text-case"] = "passthrough";
@@ -8622,24 +8657,13 @@ CSL.Util.Match = function () {
CSL.Transform = function (state) {
var debug = false, abbreviations, token, fieldname, abbrev_family, opt;
this.abbrevs = {};
- this.abbrevs["default"] = new CSL.AbbreviationSegments();
- function init(mytoken, myfieldname, myabbrev_family) {
- token = mytoken;
- fieldname = myfieldname;
- abbrev_family = myabbrev_family;
- opt = {
- abbreviation_fallback: false,
- alternative_varname: false,
- transform_fallback: false
- };
- }
- this.init = init;
+ this.abbrevs["default"] = new state.sys.AbbreviationSegments();
function abbreviate(state, Item, altvar, basevalue, myabbrev_family, use_field) {
var value;
if (!myabbrev_family) {
return basevalue;
}
- if (["publisher-place", "event-place", "subjurisdiction"].indexOf(myabbrev_family) > -1) {
+ if (["publisher-place", "event-place", "jurisdiction"].indexOf(myabbrev_family) > -1) {
myabbrev_family = "place";
}
if (["publisher", "authority"].indexOf(myabbrev_family) > -1) {
@@ -8702,18 +8726,6 @@ CSL.Transform = function (state) {
}
return ret;
}
- function setAbbreviationFallback(b) {
- opt.abbreviation_fallback = b;
- }
- this.setAbbreviationFallback = setAbbreviationFallback;
- function setAlternativeVariableName(s) {
- opt.alternative_varname = s;
- }
- this.setAlternativeVariableName = setAlternativeVariableName;
- function setTransformFallback(b) {
- opt.transform_fallback = b;
- }
- this.setTransformFallback = setTransformFallback;
function loadAbbreviation(jurisdiction, category, orig) {
var pos, len;
if (!jurisdiction) {
@@ -8721,7 +8733,7 @@ CSL.Transform = function (state) {
}
if (!orig) {
if (!this.abbrevs[jurisdiction]) {
- this.abbrevs[jurisdiction] = new CSL.AbbreviationSegments();
+ this.abbrevs[jurisdiction] = new state.sys.AbbreviationSegments();
}
return jurisdiction;
}
@@ -8735,7 +8747,7 @@ CSL.Transform = function (state) {
}
for (var i=tryList.length - 1; i > -1; i += -1) {
if (!this.abbrevs[tryList[i]]) {
- this.abbrevs[tryList[i]] = new CSL.AbbreviationSegments();
+ this.abbrevs[tryList[i]] = new state.sys.AbbreviationSegments();
}
if (!this.abbrevs[tryList[i]][category][orig]) {
state.sys.getAbbreviation(state.opt.styleID, this.abbrevs, tryList[i], category, orig);
@@ -8772,15 +8784,9 @@ CSL.Transform = function (state) {
}
return false;
}
- function getOutputFunction(variables) {
- var myabbrev_family, myfieldname, abbreviation_fallback, alternative_varname, transform_locale, transform_fallback, getTextSubfield;
- myabbrev_family = abbrev_family;
- myfieldname = fieldname;
- var abbreviation_fallback = opt.abbreviation_fallback;
- var alternative_varname = opt.alternative_varname;
- var transform_fallback = opt.transform_fallback;
+ function getOutputFunction(variables, myabbrev_family, abbreviation_fallback, alternative_varname, transform_fallback) {
var localesets;
- var langPrefs = CSL.LangPrefsMap[myfieldname];
+ var langPrefs = CSL.LangPrefsMap[variables[0]];
if (!langPrefs) {
localesets = false;
} else {
@@ -8825,7 +8831,7 @@ CSL.Transform = function (state) {
}
return null;
}
- var res = getTextSubField(Item, myfieldname, slot.primary, true);
+ var res = getTextSubField(Item, variables[0], slot.primary, true);
primary = res.name;
if (publisherCheck(this, Item, primary, myabbrev_family)) {
return null;
@@ -8833,21 +8839,24 @@ CSL.Transform = function (state) {
secondary = false;
tertiary = false;
if (slot.secondary) {
- res = getTextSubField(Item, myfieldname, slot.secondary, false, res.usedOrig);
+ res = getTextSubField(Item, variables[0], slot.secondary, false, res.usedOrig);
secondary = res.name;
}
if (slot.tertiary) {
- res = getTextSubField(Item, myfieldname, slot.tertiary, false, res.usedOrig);
+ res = getTextSubField(Item, variables[0], slot.tertiary, false, res.usedOrig);
tertiary = res.name;
}
if (myabbrev_family) {
primary = abbreviate(state, Item, alternative_varname, primary, myabbrev_family, true);
if (primary) {
- var m = primary.match(/^!([-_a-z]+)<<);
+ var m = primary.match(/^!([-,_a-z]+)<<);
if (m) {
+ var fields = m[1].split(",");
primary = primary.slice(m[0].length);
- if (state.tmp.done_vars.indexOf(m[1]) === -1) {
- state.tmp.done_vars.push(m[1]);
+ for (var i = 0, ilen = fields.length; i < ilen; i += 1) {
+ if (state.tmp.done_vars.indexOf(fields[i]) === -1) {
+ state.tmp.done_vars.push(fields[i]);
+ }
}
}
}
@@ -10098,15 +10107,6 @@ CSL.Engine.prototype.processNumber = function (node, ItemObject, variable) {
if (num.indexOf("&") > -1 || num.indexOf("--") > -1) {
this.tmp.shadow_numbers[variable].plural = 1;
}
- if (this.variable === "page-first") {
- m = num.split(/\s*(?:&|,|-)\s*/);
- if (m) {
- num = m[0];
- if (num.match(/[0-9]/)) {
- this.tmp.shadow_numbers[variable].numeric = true;
- }
- }
- }
var lst = num.split(/(?:,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/);
var m = num.match(/(,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/g);
var elements = [];
@@ -11153,44 +11153,6 @@ CSL.Registry.prototype.doinserts = function (mylist) {
}
}
}
- if (this.state.sys.getAbbreviation) {
- for (var field in this.state.transform.abbrevs["default"]) {
- switch (field) {
- case "place":
- if (Item["publisher-place"]) {
- this.state.transform.loadAbbreviation(Item.jurisdiction, "place", Item["publisher-place"]);
- } else if (Item["event-place"]) {
- this.state.transform.loadAbbreviation(Item.jurisdiction, "place", Item["event-place"]);
- }
- break;
- case "institution-part":
- for (var creatorVar in CSL.CREATORS) {
- for (var creatorList in Item[creatorVar]) {
- for (j = 0, jlen = creatorList.length; j < jlen; j += 1) {
- if (creatorList[j].isInstitution) {
- var subOrganizations = creatorList[j].literal;
- if (!subOrganizations) {
- subOrganizations = creatorList[j].family;
- }
- if (subOrganizations) {
- subOrganizations = subOrganizations.split(/\s*|\s*/);
- for (k = 0, klen = subOrganizations.length; k < klen; k += 1) {
- this.state.transform.loadAbbreviation(Item.jurisdiction, "institution-part", subOrganizations[k]);
- }
- }
- }
- }
- }
- }
- break;
- default:
- if (Item[field]) {
- this.state.transform.loadAbbreviation(Item.jurisdiction, field, Item[field]);
- }
- break;
- }
- }
- }
akey = CSL.getAmbiguousCite.call(this.state, Item);
this.akeys[akey] = true;
newitem = {
@@ -11730,6 +11692,7 @@ CSL.Disambiguation.prototype.disNames = function (ismax) {
mybase.year_suffix = false;
this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, mybase);
this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, mybase);
+ this.state.tmp.taintedItemIDs[this.nonpartners[0].id] = true;
this.lists[this.listpos] = [this.base, []];
} else if (this.clashes[1] === 0) {
this.betterbase = CSL.cloneAmbigConfig(this.base);
diff --git a/chrome/content/zotero/xpcom/connector/translate_item.js b/chrome/content/zotero/xpcom/connector/translate_item.js
index e24c65caa..e47c42694 100644
--- a/chrome/content/zotero/xpcom/connector/translate_item.js
+++ b/chrome/content/zotero/xpcom/connector/translate_item.js
@@ -72,7 +72,7 @@ Zotero.Translate.ItemSaver.prototype = {
newItems.push(Zotero.Utilities.itemToServerJSON(items[i]));
}
- var url = 'users/%%USERID%%/items?key=%%APIKEY%%';
+ var url = 'users/%%USERID%%/items';
var payload = JSON.stringify({"items":newItems}, null, "\t")
Zotero.OAuth.doAuthenticatedPost(url, payload, function(status) {
diff --git a/chrome/content/zotero/xpcom/data/items.js b/chrome/content/zotero/xpcom/data/items.js
index 748bafe85..cca97c184 100644
--- a/chrome/content/zotero/xpcom/data/items.js
+++ b/chrome/content/zotero/xpcom/data/items.js
@@ -62,6 +62,8 @@ Zotero.Items = new function() {
var _cachedFields = [];
var _firstCreatorSQL = '';
var _primaryFields = [];
+ var _emptyTrashIdleObserver = null;
+ var _emptyTrashTimer = null;
/*
@@ -490,18 +492,80 @@ Zotero.Items = new function() {
/**
* @param {Integer} days Only delete items deleted more than this many days ago
*/
- this.emptyTrash = function (libraryID, days) {
+ this.emptyTrash = function (libraryID, days, limit) {
+ var t = new Date();
+
Zotero.DB.beginTransaction();
var deletedIDs = this.getDeleted(libraryID, true, days);
if (deletedIDs.length) {
+ if (limit) {
+ deletedIDs = deletedIDs.slice(0, limit - 1)
+ }
this.erase(deletedIDs);
- Zotero.Notifier.trigger('refresh', 'collection', libraryID ? libraryID : 0);
+ Zotero.Notifier.trigger('refresh', 'trash', libraryID ? libraryID : 0);
}
Zotero.DB.commitTransaction();
+
+ if (deletedIDs.length) {
+ Zotero.debug("Emptied " + deletedIDs.length + " item(s) from trash in " + (new Date() - t) + " ms");
+ }
+
return deletedIDs.length;
}
+ /**
+ * Start idle observer to delete trashed items older than a certain number of days
+ */
+ this.startEmptyTrashTimer = function () {
+ _emptyTrashIdleObserver = {
+ observe: function (subject, topic, data) {
+ if (topic == 'idle' || topic == 'timer-callback') {
+ var days = Zotero.Prefs.get('trashAutoEmptyDays');
+ if (!days) {
+ return;
+ }
+
+ // TODO: empty group trashes if permissions
+
+ // Delete a few items a time
+ //
+ // TODO: increase number after dealing with slow
+ // tag.getLinkedItems() call during deletes
+ var num = 10;
+ var deleted = Zotero.Items.emptyTrash(null, days, num);
+
+ if (!deleted) {
+ _emptyTrashTimer = null;
+ return;
+ }
+
+ // Set a timer to do more every few seconds
+ if (!_emptyTrashTimer) {
+ _emptyTrashTimer = Components.classes["@mozilla.org/timer;1"].
+ createInstance(Components.interfaces.nsITimer);
+ }
+ _emptyTrashTimer.init(
+ _emptyTrashIdleObserver.observe,
+ 5 * 1000,
+ Components.interfaces.nsITimer.TYPE_ONE_SHOT
+ );
+ }
+ // When no longer idle, cancel timer
+ else if (topic == 'back') {
+ if (_emptyTrashTimer) {
+ _emptyTrashTimer.cancel();
+ }
+ }
+ }
+ };
+
+ var idleService = Components.classes["@mozilla.org/widget/idleservice;1"].
+ getService(Components.interfaces.nsIIdleService);
+ idleService.addIdleObserver(_emptyTrashIdleObserver, 305);
+ }
+
+
/**
* Delete item(s) from database and clear from internal array
*
diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js
index 45bd0b182..5aeebecf9 100644
--- a/chrome/content/zotero/xpcom/integration.js
+++ b/chrome/content/zotero/xpcom/integration.js
@@ -54,10 +54,10 @@ Zotero.Integration = new function() {
var _updateTimer;
// For Carbon and X11
- var _carbon, ProcessSerialNumber, SetFrontProcessWithOptions,
- _x11, _x11Display, _x11RootWindow, XClientMessageEvent, XFetchName, XFree, XQueryTree,
+ var _carbon, ProcessSerialNumber, SetFrontProcessWithOptions;
+ var _x11, _x11Display, _x11RootWindow, XClientMessageEvent, XFetchName, XFree, XQueryTree,
XOpenDisplay, XCloseDisplay, XFlush, XDefaultRootWindow, XInternAtom, XSendEvent,
- XMapRaised, XGetWindowProperty;
+ XMapRaised, XGetWindowProperty, X11Atom, X11Bool, X11Display, X11Window, X11Status;
var _inProgress = false;
this.currentWindow = false;
@@ -356,11 +356,11 @@ Zotero.Integration = new function() {
}
}
- const Status = ctypes.int,
- Display = new ctypes.StructType("Display"),
- Window = ctypes.unsigned_long,
- Atom = ctypes.unsigned_long,
- Bool = ctypes.int;
+ X11Atom = ctypes.unsigned_long;
+ X11Bool = ctypes.int;
+ X11Display = new ctypes.StructType("Display");
+ X11Window = ctypes.unsigned_long;
+ X11Status = ctypes.int;
/*
* typedef struct {
@@ -382,10 +382,10 @@ Zotero.Integration = new function() {
[
{"type":ctypes.int},
{"serial":ctypes.unsigned_long},
- {"send_event":Bool},
- {"display":Display.ptr},
- {"window":Window},
- {"message_type":Atom},
+ {"send_event":X11Bool},
+ {"display":X11Display.ptr},
+ {"window":X11Window},
+ {"message_type":X11Atom},
{"format":ctypes.int},
{"l0":ctypes.long},
{"l1":ctypes.long},
@@ -402,8 +402,8 @@ Zotero.Integration = new function() {
* char** window_name_return
* );
*/
- XFetchName = _x11.declare("XFetchName", ctypes.default_abi, Status, Display.ptr,
- Window, ctypes.char.ptr.ptr);
+ XFetchName = _x11.declare("XFetchName", ctypes.default_abi, X11Status,
+ X11Display.ptr, X11Window, ctypes.char.ptr.ptr);
/*
* Status XQueryTree(
@@ -415,8 +415,9 @@ Zotero.Integration = new function() {
* unsigned int* nchildren_return
* );
*/
- XQueryTree = _x11.declare("XQueryTree", ctypes.default_abi, Status, Display.ptr,
- Window, Window.ptr, Window.ptr, Window.ptr.ptr, ctypes.unsigned_int.ptr);
+ XQueryTree = _x11.declare("XQueryTree", ctypes.default_abi, X11Status,
+ X11Display.ptr, X11Window, X11Window.ptr, X11Window.ptr, X11Window.ptr.ptr,
+ ctypes.unsigned_int.ptr);
/*
* int XFree(
@@ -430,7 +431,7 @@ Zotero.Integration = new function() {
* _Xconst char* display_name
* );
*/
- XOpenDisplay = _x11.declare("XOpenDisplay", ctypes.default_abi, Display.ptr,
+ XOpenDisplay = _x11.declare("XOpenDisplay", ctypes.default_abi, X11Display.ptr,
ctypes.char.ptr);
/*
@@ -439,14 +440,14 @@ Zotero.Integration = new function() {
* );
*/
XCloseDisplay = _x11.declare("XCloseDisplay", ctypes.default_abi, ctypes.int,
- Display.ptr);
+ X11Display.ptr);
/*
* int XFlush(
* Display* display
* );
*/
- XFlush = _x11.declare("XFlush", ctypes.default_abi, ctypes.int, Display.ptr);
+ XFlush = _x11.declare("XFlush", ctypes.default_abi, ctypes.int, X11Display.ptr);
/*
* Window XDefaultRootWindow(
@@ -454,7 +455,7 @@ Zotero.Integration = new function() {
* );
*/
XDefaultRootWindow = _x11.declare("XDefaultRootWindow", ctypes.default_abi,
- Window, Display.ptr);
+ X11Window, X11Display.ptr);
/*
* Atom XInternAtom(
@@ -463,8 +464,8 @@ Zotero.Integration = new function() {
* Bool only_if_exists
* );
*/
- XInternAtom = _x11.declare("XInternAtom", ctypes.default_abi, Atom, Display.ptr,
- ctypes.char.ptr, Bool);
+ XInternAtom = _x11.declare("XInternAtom", ctypes.default_abi, X11Atom,
+ X11Display.ptr, ctypes.char.ptr, X11Bool);
/*
* Status XSendEvent(
@@ -475,8 +476,8 @@ Zotero.Integration = new function() {
* XEvent* event_send
* );
*/
- XSendEvent = _x11.declare("XSendEvent", ctypes.default_abi, Status, Display.ptr,
- Window, Bool, ctypes.long, XClientMessageEvent.ptr);
+ XSendEvent = _x11.declare("XSendEvent", ctypes.default_abi, X11Status,
+ X11Display.ptr, X11Window, X11Bool, ctypes.long, XClientMessageEvent.ptr);
/*
* int XMapRaised(
@@ -484,8 +485,29 @@ Zotero.Integration = new function() {
* Window w
* );
*/
- XMapRaised = _x11.declare("XMapRaised", ctypes.default_abi, ctypes.int, Display.ptr,
- Window);
+ XMapRaised = _x11.declare("XMapRaised", ctypes.default_abi, ctypes.int,
+ X11Display.ptr, X11Window);
+
+ /*
+ * extern int XGetWindowProperty(
+ * Display* display,
+ * Window w,
+ * Atom property,
+ * long long_offset,
+ * long long_length,
+ * Bool delete,
+ * Atom req_type,
+ * Atom* actual_type_return,
+ * int* actual_format_return,
+ * unsigned long* nitems_return,
+ * unsigned long* bytes_after_return,
+ * unsigned char** prop_return
+ * );
+ */
+ XGetWindowProperty = _x11.declare("XGetWindowProperty", ctypes.default_abi,
+ ctypes.int, X11Display.ptr, X11Window, X11Atom, ctypes.long, ctypes.long,
+ X11Bool, X11Atom, X11Atom.ptr, ctypes.int.ptr, ctypes.unsigned_long.ptr,
+ ctypes.unsigned_long.ptr, ctypes.char.ptr.ptr);
_x11Display = XOpenDisplay(null);
@@ -516,6 +538,26 @@ Zotero.Integration = new function() {
}
}
+ /**
+ * Get a property from an X11 window
+ */
+ function _X11GetProperty(win, propertyName, propertyType) {
+ Components.utils.import("resource://gre/modules/ctypes.jsm");
+
+ var returnType = new X11Atom(),
+ returnFormat = new ctypes.int(),
+ nItemsReturned = new ctypes.unsigned_long(),
+ nBytesAfterReturn = new ctypes.unsigned_long(),
+ data = new ctypes.char.ptr();
+ if(!XGetWindowProperty(_x11Display, win, XInternAtom(_x11Display, propertyName, 0), 0, 1024,
+ 0, propertyType, returnType.address(), returnFormat.address(),
+ nItemsReturned.address(), nBytesAfterReturn.address(), data.address())) {
+ var nElements = ctypes.cast(nItemsReturned, ctypes.unsigned_int).value;
+ if(nElements) return [data, nElements];
+ }
+ return null;
+ }
+
/**
* Bring a window to the foreground by interfacing directly with X11
*/
@@ -553,34 +595,26 @@ Zotero.Integration = new function() {
function _X11FindWindow(w, searchName) {
Components.utils.import("resource://gre/modules/ctypes.jsm");
- var childrenPtr = new ctypes.unsigned_long.ptr(),
- dummy = new ctypes.unsigned_long(),
- foundName = new ctypes.char.ptr(),
- nChildren = new ctypes.unsigned_int();
+ var res = _X11GetProperty(w, "_NET_CLIENT_LIST", 33 /** XA_WINDOW **/)
+ || _X11GetProperty(w, "_WIN_CLIENT_LIST", 6 /** XA_CARDINAL **/);
+ if(!res) return false;
- if(XFetchName(_x11Display, w, foundName.address())) {
- var foundNameString = foundName.readString();
- XFree(foundName);
- if(foundNameString === searchName) return w;
+ var nClients = res[1],
+ clientList = ctypes.cast(res[0], X11Window.array(nClients).ptr).contents,
+ foundName = new ctypes.char.ptr();
+ for(var i=0; i maxLevel){
+ return dumped_text + level_padding + "...\n";
+ }
if (typeof(arr) == 'object') { // Array/Hashes/Objects
for (var item in arr) {
@@ -1016,7 +1040,7 @@ Zotero.Utilities = {
if (typeof(value) == 'object') { // If it is an array,
dumped_text += level_padding + "'" + item + "' ...\n";
- dumped_text += arguments.callee(value,level+1);
+ dumped_text += arguments.callee(value,level+1,maxLevel);
}
else {
if (typeof value == 'function'){
@@ -1099,7 +1123,7 @@ Zotero.Utilities = {
} else if(field === "creators") {
// normalize creators
var n = val.length;
- var newCreators = newItem.creators = new Array(n);
+ var newCreators = newItem.creators = [];
for(var j=0; j label, row > hbox
-moz-margin-end: 5px !important;
padding: 0 2px 0 2px !important;
-moz-border-radius: 6px;
+ border-radius: 6px;
border: 1px solid transparent;
}
diff --git a/chrome/skin/default/zotero/bindings/itembox.css b/chrome/skin/default/zotero/bindings/itembox.css
index 511bedb39..aa608e7e9 100644
--- a/chrome/skin/default/zotero/bindings/itembox.css
+++ b/chrome/skin/default/zotero/bindings/itembox.css
@@ -153,6 +153,7 @@ hbox.zotero-date-field-status > label
background-position: center !important;
border-width: 0 !important;
-moz-border-radius: 4px !important;
+ border-radius: 4px !important;
}
/* Merge pane in duplicates view */
diff --git a/chrome/skin/default/zotero/bindings/noteeditor.css b/chrome/skin/default/zotero/bindings/noteeditor.css
index 329e17221..49d0a4ece 100644
--- a/chrome/skin/default/zotero/bindings/noteeditor.css
+++ b/chrome/skin/default/zotero/bindings/noteeditor.css
@@ -24,6 +24,7 @@ row > label, row > hbox
-moz-margin-end: 5px !important;
padding: 0 2px 0 2px !important;
-moz-border-radius: 6px;
+ border-radius: 6px;
border: 1px solid transparent;
}
diff --git a/chrome/skin/default/zotero/integration.css b/chrome/skin/default/zotero/integration.css
index fbe18965c..ea6d2ba74 100644
--- a/chrome/skin/default/zotero/integration.css
+++ b/chrome/skin/default/zotero/integration.css
@@ -108,6 +108,7 @@
.quick-format-bubble {
-moz-border-radius: 8px;
+ border-radius: 8px;
background-color: #dee7f8;
border-style: solid;
border-width: 1px;
@@ -124,6 +125,7 @@
.quick-format-bubble[selected="true"] {
-moz-border-radius: 8px !important;
+ border-radius: 8px !important;
background-color: #598bec;
color: #fff;
}
diff --git a/chrome/skin/default/zotero/zotero.css b/chrome/skin/default/zotero/zotero.css
index f936711a5..9913fd43d 100644
--- a/chrome/skin/default/zotero/zotero.css
+++ b/chrome/skin/default/zotero/zotero.css
@@ -163,6 +163,7 @@ label.zotero-text-link {
.zotero-clicky
{
-moz-border-radius: 6px;
+ border-radius: 6px;
border: 1px solid transparent;
}
diff --git a/translators b/translators
index 7b8cb18ea..6791c1961 160000
--- a/translators
+++ b/translators
@@ -1 +1 @@
-Subproject commit 7b8cb18ea06006a89cf1afb94bb481cebed3e43c
+Subproject commit 6791c19618a281a19a9d4254b97e77afac414846