diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js
index 168d86d11..865f9f952 100644
--- a/chrome/content/zotero/overlay.js
+++ b/chrome/content/zotero/overlay.js
@@ -152,10 +152,10 @@ var ZoteroOverlay = new function()
// save current state
_stateBeforeReload = !zoteroPane.hidden && !zoteroPane.collapsed;
// ensure pane is closed
- if(!zoteroPane.collapsed) ZoteroOverlay.toggleDisplay(false);
+ if(!zoteroPane.collapsed) ZoteroOverlay.toggleDisplay(false, true);
} else {
// reopen pane if it was open before
- ZoteroOverlay.toggleDisplay(_stateBeforeReload);
+ ZoteroOverlay.toggleDisplay(_stateBeforeReload, true);
}
});
@@ -202,9 +202,13 @@ var ZoteroOverlay = new function()
/**
* Hides/displays the Zotero interface
+ * @param {Boolean} makeVisible Whether or not Zotero interface should be visible
+ * @param {Boolean} dontRefocus If true, don't focus content when closing Zotero pane. Used
+ * when closing pane because Zotero Standalone is being opened, to avoid pulling Firefox to
+ * the foreground.
*/
- this.toggleDisplay = function(makeVisible)
- {
+ this.toggleDisplay = function(makeVisible, dontRefocus)
+ {
if(!Zotero || !Zotero.initialized) {
ZoteroPane.displayStartupError();
return;
@@ -271,6 +275,11 @@ var ZoteroOverlay = new function()
zoteroPane.height = 0;
document.getElementById('content').setAttribute('collapsed', false);
+
+ if(!dontRefocus) {
+ // Return focus to the browser content pane
+ window.content.window.focus();
+ }
}
}
diff --git a/chrome/content/zotero/preferences/preferences.js b/chrome/content/zotero/preferences/preferences.js
index 6bd332728..46c3b907c 100644
--- a/chrome/content/zotero/preferences/preferences.js
+++ b/chrome/content/zotero/preferences/preferences.js
@@ -604,7 +604,9 @@ function populateQuickCopyList() {
menulist.setAttribute('preference', "pref-quickCopy-setting");
updateQuickCopyHTMLCheckbox();
- refreshQuickCopySiteList();
+ if (!Zotero.isStandalone) {
+ refreshQuickCopySiteList();
+ }
}
@@ -776,11 +778,18 @@ function deleteSelectedQuickCopySite() {
function updateQuickCopyInstructions() {
var prefix = Zotero.isMac ? 'Cmd+Shift+' : 'Ctrl+Alt+';
+
var key = Zotero.Prefs.get('keys.copySelectedItemsToClipboard');
-
- var instr = document.getElementById('quickCopy-instructions');
var str = Zotero.getString('zotero.preferences.export.quickCopy.instructions', prefix + key);
+ var instr = document.getElementById('quickCopy-instructions');
+ while (instr.hasChildNodes()) {
+ instr.removeChild(instr.firstChild);
+ }
+ instr.appendChild(document.createTextNode(str));
+ var key = Zotero.Prefs.get('keys.copySelectedItemCitationsToClipboard');
+ var str = Zotero.getString('zotero.preferences.export.quickCopy.citationInstructions', prefix + key);
+ var instr = document.getElementById('quickCopy-citationInstructions');
while (instr.hasChildNodes()) {
instr.removeChild(instr.firstChild);
}
@@ -1258,6 +1267,55 @@ function runIntegrityCheck() {
var ok = Zotero.DB.integrityCheck();
if (ok) {
ok = Zotero.Schema.integrityCheck();
+ if (!ok) {
+ var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
+ + (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
+ var index = ps.confirmEx(window,
+ Zotero.getString('general.failed'),
+ Zotero.getString('db.integrityCheck.failed') + "\n\n" +
+ Zotero.getString('db.integrityCheck.repairAttempt') + " " +
+ Zotero.getString('db.integrityCheck.appRestartNeeded', Zotero.appName),
+ buttonFlags,
+ Zotero.getString('db.integrityCheck.fixAndRestart', Zotero.appName),
+ null, null, null, {}
+ );
+
+ if (index == 0) {
+ // Safety first
+ Zotero.DB.backupDatabase();
+
+ // Fix the errors
+ Zotero.Schema.integrityCheck(true);
+
+ // And run the check again
+ ok = Zotero.Schema.integrityCheck();
+ var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING);
+ if (ok) {
+ var str = 'success';
+ var msg = Zotero.getString('db.integrityCheck.errorsFixed');
+ }
+ else {
+ var str = 'failed';
+ var msg = Zotero.getString('db.integrityCheck.errorsNotFixed')
+ + "\n\n" + Zotero.getString('db.integrityCheck.reportInForums');
+ }
+
+ ps.confirmEx(window,
+ Zotero.getString('general.' + str),
+ msg,
+ buttonFlags,
+ Zotero.getString('general.restartApp', Zotero.appName),
+ null, null, null, {}
+ );
+
+ var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
+ .getService(Components.interfaces.nsIAppStartup);
+ appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit
+ | Components.interfaces.nsIAppStartup.eRestart);
+ }
+
+ return;
+ }
}
var str = ok ? 'passed' : 'failed';
diff --git a/chrome/content/zotero/preferences/preferences.xul b/chrome/content/zotero/preferences/preferences.xul
index ec16f071c..f26520214 100644
--- a/chrome/content/zotero/preferences/preferences.xul
+++ b/chrome/content/zotero/preferences/preferences.xul
@@ -522,39 +522,24 @@ To add a new preference:
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/chrome/content/zotero/preferences/preferences_firefox.xul b/chrome/content/zotero/preferences/preferences_firefox.xul
index 90aa7f9d8..1a851e267 100644
--- a/chrome/content/zotero/preferences/preferences_firefox.xul
+++ b/chrome/content/zotero/preferences/preferences_firefox.xul
@@ -76,6 +76,35 @@ To add a new preference:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
td {
background-color: #b4d5ff !important;
}
diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js
index 191b7cd52..5c6a6757c 100644
--- a/chrome/content/zotero/tools/testTranslators/testTranslators.js
+++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js
@@ -25,16 +25,64 @@
const NUM_CONCURRENT_TESTS = 6;
const TRANSLATOR_TYPES = ["Web", "Import", "Export", "Search"];
-const TABLE_COLUMNS = ["Translator", "Supported", "Status", "Pending", "Succeeded", "Failed", "Unknown"];
+const TABLE_COLUMNS = ["Translator", "Supported", "Status", "Pending", "Succeeded", "Failed", "Mismatch", "Issues"];
var translatorTables = {},
translatorTestViews = {},
translatorTestViewsToRun = {},
+ translatorTestStats = {},
translatorBox,
outputBox,
allOutputView,
currentOutputView,
viewerMode = true;
+/**
+ * Fetches issue information from GitHub
+ */
+var Issues = new function() {
+ var _executeWhenRetrieved = [];
+ var githubInfo;
+
+ /**
+ * Gets issues for a specific translator
+ * @param {String} translatorLabel Gets issues starting with translatorLabel
+ * @param {Function} callback Function to call when issue information is available
+ */
+ this.getFor = function(translatorLabel, callback) {
+ translatorLabel = translatorLabel.toLowerCase();
+
+ var whenRetrieved = function() {
+ var issues = [];
+ for(var i=0; i '+error[i];
+ }
+ }
+ }
+ testDoneCallback(this, test, "failed", errorString);
+ return;
+ }
+
if(!returnValue) {
testDoneCallback(this, test, "failed", "Translation failed; examine debug output for errors");
return;
@@ -289,6 +469,12 @@ Zotero_TranslatorTester.prototype._checkResult = function(test, translate, retur
var translatedItem = Zotero_TranslatorTester._sanitizeItem(translate.newItems[i]);
if(!this._compare(testItem, translatedItem)) {
+ var m = translate.newItems.length;
+ test.itemsReturned = new Array(m);
+ for(var j=0; j 1) {
- Item.subjurisdiction = subjurisdictions.slice(0,2).join(";");
+ Item.subjurisdiction = subjurisdictions.join(";");
}
}
for (var i = 1, ilen = CSL.DATE_VARIABLES.length; i < ilen; i += 1) {
@@ -2510,7 +2515,7 @@ CSL.Engine.prototype.retrieveItem = function (id) {
return Item;
};
CSL.Engine.prototype.setOpt = function (token, name, value) {
- if (token.name === "style") {
+ if (token.name === "style" || token.name === "cslstyle") {
this.opt[name] = value;
} else if (["citation", "bibliography"].indexOf(token.name) > -1) {
this[token.name].opt[name] = value;
@@ -2690,7 +2695,20 @@ CSL.Engine.prototype.setAbbreviations = function (arg) {
if (this.sys.setAbbreviations) {
this.sys.setAbbreviations(arg);
}
-}
+};
+CSL.Engine.prototype.setEnglishLocaleEscapes = function (arg) {
+ if ("string" === typeof arg) {
+ arg = arg.split(/\s+,\s+/);
+ }
+ if (!arg || !arg.length) {
+ arg = [];
+ }
+ for (var i = 0, ilen = arg.length; i < ilen; i += 1) {
+ if (this.opt.english_locale_escapes.indexOf(arg[i]) === -1) {
+ this.opt.english_locale_escapes.push(arg[i]);
+ }
+ }
+};
CSL.Engine.Opt = function () {
this.has_disambiguate = false;
this.mode = "html";
@@ -2713,6 +2731,7 @@ CSL.Engine.Opt = function () {
this.citation_number_slug = false;
this.max_number_of_names = 0;
this.trigraph = "Aaaa00:AaAa00:AaAA00:AAAA00";
+ this.english_locale_escapes = [];
this.development_extensions = {};
this.development_extensions.field_hack = true;
this.development_extensions.locator_date_and_revision = true;
@@ -2933,6 +2952,7 @@ CSL.Engine.prototype.restoreProcessorState = function (citations) {
} else {
this.registry = new CSL.Registry(this);
this.tmp = new CSL.Engine.Tmp();
+ this.disambiguate = new CSL.Disambiguation(this);
}
return ret;
};
@@ -3240,6 +3260,7 @@ CSL.getBibliographyEntries = function (bibsection) {
this.parallel.ComposeSet();
this.parallel.PruneOutputQueue();
} else if (!this.registry.registry[item.id].siblings) {
+ this.parallel.StartCitation(sortedItems);
this.tmp.term_predecessor = false;
entry_item_ids.push("" + CSL.getCite.call(this, item));
}
@@ -3387,11 +3408,12 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
if (this.opt.update_mode === CSL.POSITION) {
textCitations = [];
noteCitations = [];
+ var citationsInNote = {};
}
var update_items = [];
for (i = 0, ilen = citationByIndex.length; i < ilen; i += 1) {
citationByIndex[i].properties.index = i;
- for (j = 0, jlen = citationByIndex[i].sortedItems.length; j < jlen; j += 1) {
+ for (j = 0, jlen = citationByIndex[i].sortedItems.length; j < jlen; j += 1) {
item = citationByIndex[i].sortedItems[j];
if (!this.registry.citationreg.citationsByItemId[item[1].id]) {
this.registry.citationreg.citationsByItemId[item[1].id] = [];
@@ -3405,6 +3427,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
if (citationByIndex[i].properties.noteIndex) {
noteCitations.push(citationByIndex[i]);
} else {
+ citationByIndex[i].properties.noteIndex = 0;
textCitations.push(citationByIndex[i]);
}
}
@@ -3446,20 +3469,20 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
}
var citations;
if (this.opt.update_mode === CSL.POSITION) {
- var citationsInNote = {};
for (i = 0; i < 2; i += 1) {
citations = [textCitations, noteCitations][i];
var first_ref = {};
var last_ref = {};
for (j = 0, jlen = citations.length; j < jlen; j += 1) {
var onecitation = citations[j];
- if (!onecitation.properties.noteIndex) {
- onecitation.properties.noteIndex = 0;
- }
- if (!citationsInNote[onecitation.properties.noteIndex]) {
- citationsInNote[onecitation.properties.noteIndex] = 1;
- } else {
- citationsInNote[onecitation.properties.noteIndex] += 1;
+ for (var k = 0, klen = onecitation.sortedItems.length; k < klen; k += 1) {
+ if (!this.registry.registry[onecitation.sortedItems[k][1].id].parallel) {
+ if (!citationsInNote[onecitation.properties.noteIndex]) {
+ citationsInNote[onecitation.properties.noteIndex] = 1;
+ } else {
+ citationsInNote[onecitation.properties.noteIndex] += 1;
+ }
+ }
}
for (k = 0, klen = citations[j].sortedItems.length; k < klen; k += 1) {
item = citations[j].sortedItems[k];
@@ -3491,7 +3514,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre,
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 (citationsInNote[citations[j - 1].properties.noteIndex] === 1 || citations[j - 1].properties.noteIndex === 0) {
+ if (citationsInNote[citations[j - 1].properties.noteIndex] == 1 || citations[j - 1].properties.noteIndex == 0) {
useme = true;
}
}
@@ -4226,17 +4249,22 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) {
}
for (termname in this.locale[lang_out].terms) {
if (this.locale[lang_out].terms.hasOwnProperty(termname)) {
- for (i = 0, ilen = 2; i < ilen; i += 1) {
- genderform = CSL.GENDERS[i];
- if (this.locale[lang_out].terms[termname][genderform]) {
- for (form in this.locale[lang_out].terms[termname]) {
- if (!this.locale[lang_out].terms[termname][genderform][form]) {
- this.locale[lang_out].terms[termname][genderform][form] = this.locale[lang_out].terms[termname][form];
+ for (i = 0, ilen = 2; i < ilen; i += 1) {
+ genderform = CSL.GENDERS[i];
+ if (this.locale[lang_out].terms[termname][genderform]) {
+ for (form in this.locale[lang_out].terms[termname]) {
+ if (!this.locale[lang_out].terms[termname][genderform][form]) {
+ this.locale[lang_out].terms[termname][genderform][form] = this.locale[lang_out].terms[termname][form];
+ }
}
}
}
}
- }
+ }
+ if (lang_out && ["fr", "pt"].indexOf(lang_out.slice(0, 2).toLowerCase()) > -1) {
+ this.locale[lang_out].terms["page-range-delimiter"] = "-";
+ } else {
+ this.locale[lang_out].terms["page-range-delimiter"] = "\u2013";
}
nodes = this.sys.xml.getNodesByName(locale, 'style-options');
for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) {
@@ -5334,15 +5362,17 @@ CSL.NameOutput.prototype.outputNames = function () {
var blob = this.state.output.pop();
this.state.output.append(blob, this.names);
this.state.tmp.name_node.top = this.state.output.current.value();
- var oldSuppressDecorations = this.state.tmp.suppress_decorations;
- this.state.tmp.suppress_decorations = true;
- var lastBlob = this.state.tmp.name_node.top.blobs.pop();
- var name_node_string = this.state.output.string(this.state, lastBlob.blobs, false);
- this.state.tmp.name_node.top.blobs.push(lastBlob);
- if (name_node_string) {
- this.state.tmp.name_node.string = name_node_string;
+ if (variables[0] !== "authority") {
+ var oldSuppressDecorations = this.state.tmp.suppress_decorations;
+ this.state.tmp.suppress_decorations = true;
+ var lastBlob = this.state.tmp.name_node.top.blobs.pop();
+ var name_node_string = this.state.output.string(this.state, lastBlob.blobs, false);
+ this.state.tmp.name_node.top.blobs.push(lastBlob);
+ if (name_node_string) {
+ this.state.tmp.name_node.string = name_node_string;
+ }
+ this.state.tmp.suppress_decorations = oldSuppressDecorations;
}
- this.state.tmp.suppress_decorations = oldSuppressDecorations;
if (this.state.tmp.name_node.string && !this.state.tmp.first_name_string) {
this.state.tmp.first_name_string = this.state.tmp.name_node.string;
}
@@ -5813,6 +5843,9 @@ CSL.NameOutput.prototype.disambigNames = function () {
CSL.NameOutput.prototype._runDisambigNames = function (lst, pos) {
var chk, myform, myinitials, param, i, ilen, paramx;
for (i = 0, ilen = lst.length; i < ilen; i += 1) {
+ if (!lst[i].given || !lst[i].family) {
+ continue;
+ }
this.state.registry.namereg.addname("" + this.Item.id, lst[i], i);
chk = this.state.tmp.disambig_settings.givens[pos];
if ("undefined" === typeof chk) {
@@ -7260,6 +7293,9 @@ CSL.Node.number = {
state.processNumber(node, Item, varname);
}
}
+ if (varname === "locator") {
+ state.tmp.done_vars.push("locator");
+ }
var values = state.tmp.shadow_numbers[varname].values;
var blob;
var newstr = ""
@@ -7273,18 +7309,20 @@ CSL.Node.number = {
if (newstr && !newstr.match(/^[-.\u20130-9]+$/)) {
state.output.append(newstr, this);
} else {
- state.output.openLevel("empty");
- for (var i = 0, ilen = values.length; i < ilen; i += 1) {
- var blob = new CSL[values[i][0]](values[i][1], values[i][2], Item.id);
- if (i > 0) {
- blob.strings.prefix = blob.strings.prefix.replace(/^\s*/, "");
+ if (values.length) {
+ state.output.openLevel("empty");
+ for (var i = 0, ilen = values.length; i < ilen; i += 1) {
+ var blob = new CSL[values[i][0]](values[i][1], values[i][2], Item.id);
+ if (i > 0) {
+ blob.strings.prefix = blob.strings.prefix.replace(/^\s*/, "");
+ }
+ if (i < values.length - 1) {
+ blob.strings.suffix = blob.strings.suffix.replace(/\s*$/, "");
+ }
+ state.output.append(blob, "literal", false, false, true);
}
- if (i < values.length - 1) {
- blob.strings.suffix = blob.strings.suffix.replace(/\s*$/, "");
- }
- state.output.append(blob, "literal", false, false, true);
+ state.output.closeLevel("empty");
}
- state.output.closeLevel("empty");
}
state.parallel.CloseVariable("number");
};
@@ -7500,9 +7538,6 @@ CSL.Node.text = {
} else {
state.transform.setTransformFallback(true);
state.transform.setAbbreviationFallback(true);
- if (this.variables_real[0] === "subjurisdiction") {
- state.transform.setSuppressMonitor("container-title");
- }
func = state.transform.getOutputFunction(this.variables);
}
if (this.variables_real[0] === "container-title") {
@@ -7518,7 +7553,7 @@ CSL.Node.text = {
func = function (state, Item, item) {
if (item && item[this.variables[0]]) {
var locator = "" + item[this.variables[0]];
- locator = locator.replace(/([^\\])--*/g,"$1\u2013");
+ locator = locator.replace(/([^\\])--*/g,"$1"+state.getTerm("page-range-delimiter"));
locator = locator.replace(/\\-/g,"-");
state.output.append(locator, this, false, false, true);
}
@@ -7528,6 +7563,7 @@ CSL.Node.text = {
var idx, value;
value = state.getVariable(Item, "page", form);
if (value) {
+ value = ""+value;
value = value.replace("\u2013", "-", "g");
idx = value.indexOf("-");
if (idx > -1) {
@@ -7540,7 +7576,8 @@ CSL.Node.text = {
func = function (state, Item) {
var value = state.getVariable(Item, "page", form);
if (value) {
- value = value.replace(/([^\\])--*/g,"$1\u2013");
+ value = ""+value;
+ value = value.replace(/([^\\])--*/g,"$1"+state.getTerm("page-range-delimiter"));
value = value.replace(/\\-/g,"-");
value = state.fun.page_mangler(value);
state.output.append(value, this, false, false, true);
@@ -8363,18 +8400,22 @@ CSL.Attributes["@text-case"] = function (state, arg) {
this.strings["text-case"] = arg;
if (arg === "title") {
var m = false;
+ var default_locale = state.opt["default-locale"][0].slice(0, 2);
if (Item.language) {
- m = Item.language.match(/^\s*([a-z]{2})(?:$|-| )/);
- }
- if (state.opt["default-locale"][0].slice(0, 2) === "en") {
- if (m && m[1] !== "en") {
+ m = Item.language.match(/^\s*([A-Za-z]{2})(?:$|-| )/);
+ if (!m) {
this.strings["text-case"] = "passthrough";
+ } else if (m[1].toLowerCase() !== "en") {
+ this.strings["text-case"] = "passthrough";
+ for (var i = 0, ilen = state.opt.english_locale_escapes.length; i < ilen; i += 1) {
+ var escaper = state.opt.english_locale_escapes[i];
+ if (m[1].slice(0, escaper.length).toLowerCase() === escaper) {
+ this.strings["text-case"] = arg;
+ }
+ }
}
- } else {
+ } else if (default_locale !== "en") {
this.strings["text-case"] = "passthrough";
- if (m && m[1] === "en") {
- this.strings["text-case"] = arg;
- }
}
}
};
@@ -8448,10 +8489,9 @@ CSL.Attributes["@display"] = function (state, arg) {
this.strings.cls = arg;
};
var XML_PARSING;
-var CSL_E4X;
-var CSL_CHROME;
-var DOMParser;
-if ("undefined" !== typeof CSL_E4X) {
+if ("undefined" !== typeof CSL_IS_NODEJS) {
+ XML_PARSING = CSL_NODEJS;
+} else if ("undefined" !== typeof CSL_E4X) {
XML_PARSING = CSL_E4X;
} else {
XML_PARSING = CSL_CHROME;
@@ -8590,8 +8630,7 @@ CSL.Transform = function (state) {
opt = {
abbreviation_fallback: false,
alternative_varname: false,
- transform_fallback: false,
- suppress_monitor: false
+ transform_fallback: false
};
}
this.init = init;
@@ -8667,10 +8706,6 @@ CSL.Transform = function (state) {
opt.abbreviation_fallback = b;
}
this.setAbbreviationFallback = setAbbreviationFallback;
- function setSuppressMonitor(b) {
- opt.suppress_monitor = b;
- }
- this.setSuppressMonitor = setSuppressMonitor;
function setAlternativeVariableName(s) {
opt.alternative_varname = s;
}
@@ -8744,7 +8779,6 @@ CSL.Transform = function (state) {
var abbreviation_fallback = opt.abbreviation_fallback;
var alternative_varname = opt.alternative_varname;
var transform_fallback = opt.transform_fallback;
- var suppress_monitor = opt.suppress_monitor;
var localesets;
var langPrefs = CSL.LangPrefsMap[myfieldname];
if (!langPrefs) {
@@ -8808,10 +8842,13 @@ CSL.Transform = function (state) {
}
if (myabbrev_family) {
primary = abbreviate(state, Item, alternative_varname, primary, myabbrev_family, true);
- if (suppress_monitor && primary) {
- suppressing_partner = abbreviate(state, Item, false, Item["container-title"], "container-title", true);
- if (suppressing_partner && suppressing_partner.slice(0, primary.length) === primary) {
- return null;
+ if (primary) {
+ var m = primary.match(/^!([-_a-z]+)<<);
+ if (m) {
+ primary = primary.slice(m[0].length);
+ if (state.tmp.done_vars.indexOf(m[1]) === -1) {
+ state.tmp.done_vars.push(m[1]);
+ }
}
}
secondary = abbreviate(state, Item, false, secondary, myabbrev_family, true);
@@ -10092,10 +10129,10 @@ CSL.Engine.prototype.processNumber = function (node, ItemObject, variable) {
&& elements[i].match(/^[0-9]+/)
&& parseInt(elements[i - 2]) < parseInt(elements[i].replace(/[^0-9].*/,""))) {
var start = this.tmp.shadow_numbers[variable].values.slice(-2);
- middle[0][1] = "\u2013";
+ middle[0][1] = this.getTerm("page-range-delimiter");
if (this.opt["page-range-format"] ) {
var newstr = this.fun.page_mangler(start[0][1] +"-"+elements[i]);
- newstr = newstr.split(/\u2013/);
+ newstr = newstr.split(this.getTerm("page-range-delimiter"));
elements[i] = newstr[1];
}
count = count + 1;
@@ -10162,7 +10199,7 @@ CSL.Engine.prototype.processNumber = function (node, ItemObject, variable) {
CSL.Util.PageRangeMangler = {};
CSL.Util.PageRangeMangler.getFunction = function (state) {
var rangerex, pos, len, stringify, listify, expand, minimize, minimize_internal, chicago, lst, m, b, e, ret, begin, end, ret_func, ppos, llen;
- var range_delimiter = state.getTerm("range-delimiter");
+ var range_delimiter = state.getTerm("page-range-delimiter");
rangerex = /([a-zA-Z]*)([0-9]+)\s*-\s*([a-zA-Z]*)([0-9]+)/;
stringify = function (lst) {
len = lst.length;
@@ -10172,7 +10209,7 @@ CSL.Util.PageRangeMangler.getFunction = function (state) {
}
}
var ret = lst.join("");
- ret = ret.replace(/([0-9])\-/, "$1\u2013", "g").replace(/\-([0-9])/, "\u2013$1", "g")
+ ret = ret.replace(/([0-9])\-/, "$1"+state.getTerm("page-range-delimiter"), "g").replace(/\-([0-9])/, state.getTerm("page-range-delimiter")+"$1", "g")
return ret;
};
listify = function (str, hyphens) {
diff --git a/chrome/content/zotero/xpcom/cookieSandbox.js b/chrome/content/zotero/xpcom/cookieSandbox.js
index 6be727fd8..b54d38069 100755
--- a/chrome/content/zotero/xpcom/cookieSandbox.js
+++ b/chrome/content/zotero/xpcom/cookieSandbox.js
@@ -141,38 +141,40 @@ Zotero.CookieSandbox.Observer = new function() {
notificationCallbacks = channel.notificationCallbacks;
// try the notification callbacks
- trackedBy = this.trackedInterfaceRequestors.get(notificationCallbacks);
- if(trackedBy) {
- tested = true;
- } else {
- // try the browser
- try {
- browser = notificationCallbacks.getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell).chromeEventHandler;
- } catch(e) {}
- if(browser) {
+ if(notificationCallbacks) {
+ trackedBy = this.trackedInterfaceRequestors.get(notificationCallbacks);
+ if(trackedBy) {
tested = true;
- trackedBy = this.trackedBrowsers.get(browser);
} else {
- // try the document for the load group
+ // try the browser
try {
- browser = channel.loadGroup.notificationCallbacks.getInterface(Ci.nsIWebNavigation)
+ browser = notificationCallbacks.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell).chromeEventHandler;
} catch(e) {}
if(browser) {
tested = true;
trackedBy = this.trackedBrowsers.get(browser);
} else {
- // try getting as an XHR or nsIWBP
+ // try the document for the load group
try {
- notificationCallbacks.QueryInterface(Components.interfaces.nsIXMLHttpRequest);
- tested = true;
+ browser = channel.loadGroup.notificationCallbacks.getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell).chromeEventHandler;
} catch(e) {}
- if(!tested) {
+ if(browser) {
+ tested = true;
+ trackedBy = this.trackedBrowsers.get(browser);
+ } else {
+ // try getting as an XHR or nsIWBP
try {
- notificationCallbacks.QueryInterface(Components.interfaces.nsIWebBrowserPersist);
+ notificationCallbacks.QueryInterface(Components.interfaces.nsIXMLHttpRequest);
tested = true;
} catch(e) {}
+ if(!tested) {
+ try {
+ notificationCallbacks.QueryInterface(Components.interfaces.nsIWebBrowserPersist);
+ tested = true;
+ } catch(e) {}
+ }
}
}
}
diff --git a/chrome/content/zotero/xpcom/data/cachedTypes.js b/chrome/content/zotero/xpcom/data/cachedTypes.js
index ff411b245..1b23b69de 100644
--- a/chrome/content/zotero/xpcom/data/cachedTypes.js
+++ b/chrome/content/zotero/xpcom/data/cachedTypes.js
@@ -273,7 +273,7 @@ Zotero.ItemTypes = new function() {
mru = mru.split(',').slice(0, limit);
for (var i=0, len=mru.length; i 0) {
+ if (this._getItemAtRow(this.getParentIndex(row)).ref.id == parentItemID) {
+ return false;
+ }
+ }
+ // Including immediately after the parent
+ if (orient == 1) {
+ if (row == parentIndex) {
+ return false;
+ }
+ }
+ // And immediately before the next parent
+ if (orient == -1) {
+ var nextParentIndex = null;
+ for (var i = parentIndex + 1; i < this.rowCount; i++) {
+ if (this.getLevel(i) == 0) {
+ nextParentIndex = i;
+ break;
+ }
+ }
+ if (row === nextParentIndex) {
+ return false;
+ }
+ }
+
// Disallow cross-library child drag
if (item.libraryID != itemGroup.ref.libraryID) {
return false;
diff --git a/chrome/content/zotero/xpcom/mimeTypeHandler.js b/chrome/content/zotero/xpcom/mimeTypeHandler.js
index 16e94e728..c6e6fdb0e 100644
--- a/chrome/content/zotero/xpcom/mimeTypeHandler.js
+++ b/chrome/content/zotero/xpcom/mimeTypeHandler.js
@@ -39,6 +39,11 @@ Zotero.MIMETypeHandler = new function () {
getService(Components.interfaces.nsIObserverService).
addObserver(_Observer, "http-on-examine-response", false);
this.initializeHandlers();
+ Zotero.addShutdownListener(function() {
+ Components.classes["@mozilla.org/observer-service;1"].
+ getService(Components.interfaces.nsIObserverService).
+ removeObserver(_Observer, "http-on-examine-response", false);
+ });
}
/**
diff --git a/chrome/content/zotero/xpcom/schema.js b/chrome/content/zotero/xpcom/schema.js
index 6996b8bce..ea36394ea 100644
--- a/chrome/content/zotero/xpcom/schema.js
+++ b/chrome/content/zotero/xpcom/schema.js
@@ -206,20 +206,15 @@ Zotero.Schema = new function(){
Zotero.debug(e);
}
}
-
- try {
- var up4 = this.updateBundledFiles(null, null, up2 || up3);
- }
- catch (e) {
- Zotero.debug(e);
- Zotero.logError(e);
- }
}
finally {
Zotero.UnresponsiveScriptIndicator.enable();
}
- return up1 || up2 || up3 || up4;
+ // After a delay, start update of bundled files and repo updates
+ setTimeout(function () {
+ Zotero.Schema.updateBundledFiles(null, null, up2 || up3);
+ }, 5000);
}
@@ -1119,59 +1114,205 @@ Zotero.Schema = new function(){
}
- this.integrityCheck = function () {
+ this.integrityCheck = function (fix) {
// There should be an equivalent SELECT COUNT(*) statement for every
// statement run by the DB Repair Tool
var queries = [
- "SELECT COUNT(*) FROM annotations WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM collectionItems WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM fulltextItems WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM fulltextItemWords WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM fulltextItemWords WHERE itemID NOT IN (SELECT itemID FROM fulltextItems)",
- "SELECT COUNT(*) FROM highlights WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM itemAttachments WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM itemCreators WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM itemData WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM itemNotes WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM itemSeeAlso WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM itemSeeAlso WHERE linkedItemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM itemTags WHERE itemID NOT IN (SELECT itemID FROM items)",
- "SELECT COUNT(*) FROM itemTags WHERE tagID NOT IN (SELECT tagID FROM tags)",
- "SELECT COUNT(*) FROM savedSearchConditions WHERE savedSearchID NOT IN (select savedSearchID FROM savedSearches)",
- "SELECT COUNT(*) FROM items WHERE itemTypeID IS NULL",
+ [
+ "SELECT COUNT(*) FROM annotations WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM annotations WHERE itemID NOT IN (SELECT itemID FROM items)"
+ ],
+ [
+ "SELECT COUNT(*) FROM collectionItems WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM collectionItems WHERE itemID NOT IN (SELECT itemID FROM items)"
+ ],
+ [
+ "SELECT COUNT(*) FROM fulltextItems WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM fulltextItems WHERE itemID NOT IN (SELECT itemID FROM items)"
+ ],
+ [
+ "SELECT COUNT(*) FROM fulltextItemWords WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM fulltextItemWords WHERE itemID NOT IN (SELECT itemID FROM items)",
+ ],
+ [
+ "SELECT COUNT(*) FROM fulltextItemWords WHERE itemID NOT IN (SELECT itemID FROM fulltextItems)",
+ "DELETE FROM fulltextItemWords WHERE itemID NOT IN (SELECT itemID FROM fulltextItems)",
+ ],
+ [
+ "SELECT COUNT(*) FROM highlights WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM highlights WHERE itemID NOT IN (SELECT itemID FROM items)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemAttachments WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM itemAttachments WHERE itemID NOT IN (SELECT itemID FROM items)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemCreators WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM itemCreators WHERE itemID NOT IN (SELECT itemID FROM items)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemData WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM itemData WHERE itemID NOT IN (SELECT itemID FROM items)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemNotes WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM itemNotes WHERE itemID NOT IN (SELECT itemID FROM items)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemSeeAlso WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM itemSeeAlso WHERE itemID NOT IN (SELECT itemID FROM items)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemSeeAlso WHERE linkedItemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM itemSeeAlso WHERE linkedItemID NOT IN (SELECT itemID FROM items)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemTags WHERE itemID NOT IN (SELECT itemID FROM items)",
+ "DELETE FROM itemTags WHERE itemID NOT IN (SELECT itemID FROM items)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemTags WHERE tagID NOT IN (SELECT tagID FROM tags)",
+ "DELETE FROM itemTags WHERE tagID NOT IN (SELECT tagID FROM tags)",
+ ],
+ [
+ "SELECT COUNT(*) FROM savedSearchConditions WHERE savedSearchID NOT IN (select savedSearchID FROM savedSearches)",
+ "DELETE FROM savedSearchConditions WHERE savedSearchID NOT IN (select savedSearchID FROM savedSearches)",
+ ],
+ [
+ "SELECT COUNT(*) FROM items WHERE itemTypeID IS NULL",
+ "DELETE FROM items WHERE itemTypeID IS NULL",
+ ],
- "SELECT COUNT(*) FROM itemData WHERE valueID NOT IN (SELECT valueID FROM itemDataValues)",
- "SELECT COUNT(*) FROM fulltextItemWords WHERE wordID NOT IN (SELECT wordID FROM fulltextWords)",
- "SELECT COUNT(*) FROM collectionItems WHERE collectionID NOT IN (SELECT collectionID FROM collections)",
- "SELECT COUNT(*) FROM itemCreators WHERE creatorID NOT IN (SELECT creatorID FROM creators)",
- "SELECT COUNT(*) FROM itemTags WHERE tagID NOT IN (SELECT tagID FROM tags)",
- "SELECT COUNT(*) FROM itemData WHERE fieldID NOT IN (SELECT fieldID FROM fields)",
- "SELECT COUNT(*) FROM itemData WHERE valueID NOT IN (SELECT valueID FROM itemDataValues)",
- "SELECT COUNT(*) FROM itemData WHERE fieldID NOT IN (SELECT fieldID FROM itemTypeFields WHERE itemTypeID=(SELECT itemTypeID FROM items WHERE itemID=itemData.itemID))",
+ [
+ "SELECT COUNT(*) FROM itemData WHERE valueID NOT IN (SELECT valueID FROM itemDataValues)",
+ "DELETE FROM itemData WHERE valueID NOT IN (SELECT valueID FROM itemDataValues)",
+ ],
+ [
+ "SELECT COUNT(*) FROM fulltextItemWords WHERE wordID NOT IN (SELECT wordID FROM fulltextWords)",
+ "DELETE FROM fulltextItemWords WHERE wordID NOT IN (SELECT wordID FROM fulltextWords)",
+ ],
+ [
+ "SELECT COUNT(*) FROM collectionItems WHERE collectionID NOT IN (SELECT collectionID FROM collections)",
+ "DELETE FROM collectionItems WHERE collectionID NOT IN (SELECT collectionID FROM collections)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemCreators WHERE creatorID NOT IN (SELECT creatorID FROM creators)",
+ "DELETE FROM itemCreators WHERE creatorID NOT IN (SELECT creatorID FROM creators)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemData WHERE fieldID NOT IN (SELECT fieldID FROM fields)",
+ "DELETE FROM itemData WHERE fieldID NOT IN (SELECT fieldID FROM fields)",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemData WHERE valueID NOT IN (SELECT valueID FROM itemDataValues)",
+ "DELETE FROM itemData WHERE valueID NOT IN (SELECT valueID FROM itemDataValues)",
+ ],
- "SELECT COUNT(*) FROM items WHERE itemTypeID=14 AND itemID NOT IN (SELECT itemID FROM itemAttachments)",
- "SELECT COUNT(*) FROM itemAttachments WHERE sourceItemID IN (SELECT itemID FROM items WHERE itemTypeID IN (1,14))",
- "SELECT COUNT(*) FROM itemNotes WHERE sourceItemID IN (SELECT itemID FROM items WHERE itemTypeID IN (1,14))",
+ // Attachments row with itemTypeID != 14
+ [
+ "SELECT COUNT(*) FROM itemAttachments JOIN items USING (itemID) WHERE itemTypeID != 14",
+ "UPDATE items SET itemTypeID=14, clientDateModified=CURRENT_TIMESTAMP WHERE itemTypeID != 14 AND itemID IN (SELECT itemID FROM itemAttachments)",
+ ],
+ // Fields not in type
+ [
+ "SELECT COUNT(*) FROM itemData WHERE fieldID NOT IN (SELECT fieldID FROM itemTypeFields WHERE itemTypeID=(SELECT itemTypeID FROM items WHERE itemID=itemData.itemID))",
+ "DELETE FROM itemData WHERE fieldID NOT IN (SELECT fieldID FROM itemTypeFields WHERE itemTypeID=(SELECT itemTypeID FROM items WHERE itemID=itemData.itemID))",
+ ],
+ // Missing itemAttachments row
+ [
+ "SELECT COUNT(*) FROM items WHERE itemTypeID=14 AND itemID NOT IN (SELECT itemID FROM itemAttachments)",
+ "INSERT INTO itemAttachments (itemID, linkMode) SELECT itemID, 0 FROM items WHERE itemTypeID=14 AND itemID NOT IN (SELECT itemID FROM itemAttachments)",
+ ],
+ // Note/child parents
+ [
+ "SELECT COUNT(*) FROM itemAttachments WHERE sourceItemID IN (SELECT itemID FROM items WHERE itemTypeID IN (1,14))",
+ "UPDATE itemAttachments SET sourceItemID=NULL WHERE sourceItemID IN (SELECT itemID FROM items WHERE itemTypeID IN (1,14))",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemNotes WHERE sourceItemID IN (SELECT itemID FROM items WHERE itemTypeID IN (1,14))",
+ "UPDATE itemNotes SET sourceItemID=NULL WHERE sourceItemID IN (SELECT itemID FROM items WHERE itemTypeID IN (1,14))",
+ ],
- "SELECT COUNT(*) FROM tags NATURAL JOIN itemTags JOIN items USING (itemID) WHERE IFNULL(tags.libraryID, 0)!=IFNULL(items.libraryID,0)",
-
- "SELECT COUNT(*) FROM itemTags WHERE tagID IS NULL",
- "SELECT COUNT(*) FROM itemAttachments WHERE charsetID='NULL'",
+ // Wrong library tags
+ [
+ "SELECT COUNT(*) FROM tags NATURAL JOIN itemTags JOIN items USING (itemID) WHERE IFNULL(tags.libraryID, 0)!=IFNULL(items.libraryID,0)",
+ [
+ "CREATE TEMPORARY TABLE tmpWrongLibraryTags AS SELECT itemTags.ROWID AS tagRowID, tagID, name, itemID, IFNULL(tags.libraryID,0) AS tagLibraryID, IFNULL(items.libraryID,0) AS itemLibraryID FROM tags NATURAL JOIN itemTags JOIN items USING (itemID) WHERE IFNULL(tags.libraryID, 0)!=IFNULL(items.libraryID,0)",
+ "DELETE FROM itemTags WHERE ROWID IN (SELECT tagRowID FROM tmpWrongLibraryTags)",
+ "DROP TABLE tmpWrongLibraryTags"
+ ]
+ ],
+ [
+ "SELECT COUNT(*) FROM itemTags WHERE tagID IS NULL",
+ "DELETE FROM itemTags WHERE tagID IS NULL",
+ ],
+ [
+ "SELECT COUNT(*) FROM itemAttachments WHERE charsetID='NULL'",
+ "UPDATE itemAttachments SET charsetID=NULL WHERE charsetID='NULL'",
+ ],
+ // Reported by one user
+ // http://forums.zotero.org/discussion/19347/continual-synching-error-message/
// TODO: check 'libraries', not 'groups', but first add a
// migration step to delete 'libraries' rows not in 'groups'
//"SELECT COUNT(*) FROM syncDeleteLog WHERE libraryID != 0 AND libraryID NOT IN (SELECT libraryID FROM libraries)"
- "SELECT COUNT(*) FROM syncDeleteLog WHERE libraryID != 0 AND libraryID NOT IN (SELECT libraryID FROM groups)",
+ [
+ "SELECT COUNT(*) FROM syncDeleteLog WHERE libraryID != 0 AND libraryID NOT IN (SELECT libraryID FROM groups)",
+ "DELETE FROM syncDeleteLog WHERE libraryID != 0 AND libraryID NOT IN (SELECT libraryID FROM libraries)",
+ ],
- "SELECT COUNT(*) FROM creatorData WHERE firstName='' AND lastName=''",
- "SELECT COUNT(*) FROM itemAttachments JOIN items USING (itemID) WHERE itemTypeID != 14"
+ // Delete empty creators
+ // This may cause itemCreator gaps, but that's better than empty creators
+ [
+ "SELECT COUNT(*) FROM creatorData WHERE firstName='' AND lastName=''",
+ [
+ "DELETE FROM itemCreators WHERE creatorID IN (SELECT creatorID FROM creators WHERE creatorDataID IN (SELECT creatorDataID FROM creatorData WHERE firstName='' AND lastName=''))",
+ "DELETE FROM creators WHERE creatorDataID IN (SELECT creatorDataID FROM creatorData WHERE firstName='' AND lastName='')",
+ "DELETE FROM creatorData WHERE firstName='' AND lastName=''"
+ ],
+ ],
+
+ // Non-attachment items in the full-text index
+ [
+ "SELECT COUNT(*) FROM fulltextItemWords WHERE itemID NOT IN (SELECT itemID FROM items WHERE itemTypeID=14)",
+ [
+ "DELETE FROM fulltextItemWords WHERE itemID NOT IN (SELECT itemID FROM items WHERE itemTypeID=14)",
+ "SELECT 1"
+ ]
+ ],
+ [
+ "SELECT COUNT(*) FROM fulltextItems WHERE itemID NOT IN (SELECT itemID FROM items WHERE itemTypeID=14)",
+ "DELETE FROM fulltextItems WHERE itemID NOT IN (SELECT itemID FROM items WHERE itemTypeID=14)"
+ ]
];
for each(var sql in queries) {
- if (Zotero.DB.valueQuery(sql)) {
+ if (Zotero.DB.valueQuery(sql[0])) {
+ Zotero.debug("Test failed!", 1);
+
+ if (fix) {
+ try {
+ // Single query
+ if (typeof sql[1] == 'string') {
+ Zotero.DB.valueQuery(sql[1]);
+ }
+ // Multiple queries
+ else {
+ for each(var s in sql[1]) {
+ Zotero.DB.valueQuery(s);
+ }
+ }
+ continue;
+ }
+ catch (e) {
+ Zotero.debug(e);
+ Components.utils.reportError(e);
+ }
+ }
+
return false;
}
}
@@ -1180,7 +1321,6 @@ Zotero.Schema = new function(){
}
-
/////////////////////////////////////////////////////////////////
//
// Private methods
diff --git a/chrome/content/zotero/xpcom/storage.js b/chrome/content/zotero/xpcom/storage.js
index 0b40d1378..361faa7c8 100644
--- a/chrome/content/zotero/xpcom/storage.js
+++ b/chrome/content/zotero/xpcom/storage.js
@@ -53,8 +53,8 @@ Zotero.Sync.Storage = new function () {
// TEMP
// TODO: localize
- this.defaultError = "A file sync error occurred. Please try syncing again.\n\nIf you receive this message repeatedly, restart " + Zotero.appName + " and/or your computer and try again. If you continue to receive the message, submit an error report and post the Report ID to a new thread in the Zotero Forums.";
- this.defaultErrorRestart = "A file sync error occurred. Please restart " + Zotero.appName + " and/or your computer and try syncing again.\n\nIf you receive this message repeatedly, submit an error report and post the Report ID to a new thread in the Zotero Forums.";
+ this.__defineGetter__("defaultError", function () "A file sync error occurred. Please try syncing again.\n\nIf you receive this message repeatedly, restart " + Zotero.appName + " and/or your computer and try again. If you continue to receive the message, submit an error report and post the Report ID to a new thread in the Zotero Forums.");
+ this.__defineGetter__("defaultErrorRestart", function () "A file sync error occurred. Please restart " + Zotero.appName + " and/or your computer and try syncing again.\n\nIf you receive this message repeatedly, submit an error report and post the Report ID to a new thread in the Zotero Forums.");
//
// Public properties
@@ -1339,7 +1339,10 @@ Zotero.Sync.Storage = new function () {
if (windowsLength) {
var pathLength = destFile.path.length - destFile.leafName.length;
- var newLength = 254 - pathLength;
+ // Limit should be 255, but a shorter limit seems to be
+ // enforced for nsIZipReader.extract() below on
+ // non-English systems
+ var newLength = 240 - pathLength;
// Require 40 available characters in path -- this is arbitrary,
// but otherwise filenames are going to end up being cut off
if (newLength < 40) {
@@ -1351,7 +1354,7 @@ Zotero.Sync.Storage = new function () {
}
}
else {
- var newLength = 254;
+ var newLength = 240;
}
// Shorten file if it's too long -- we don't relink it, but this should
@@ -1415,6 +1418,7 @@ Zotero.Sync.Storage = new function () {
zipReader.extract(entryName, destFile);
}
catch (e) {
+ Zotero.debug(destFile.path);
Zotero.File.checkFileAccessError(e, destFile, 'create');
}
diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js
index 5f97e4adb..f861b6e26 100644
--- a/chrome/content/zotero/xpcom/translation/translate.js
+++ b/chrome/content/zotero/xpcom/translation/translate.js
@@ -124,6 +124,7 @@ Zotero.Translate.Sandbox = {
for(var j=0; j
-
+
diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties
index b50e75090..650ab10ba 100644
--- a/chrome/locale/en-US/zotero/zotero.properties
+++ b/chrome/locale/en-US/zotero/zotero.properties
@@ -11,6 +11,7 @@ general.restartRequiredForChange = %S must be restarted for the change to take e
general.restartRequiredForChanges = %S must be restarted for the changes to take effect.
general.restartNow = Restart now
general.restartLater = Restart later
+general.restartApp = Restart %S
general.errorHasOccurred = An error has occurred.
general.unknownErrorOccurred = An unknown error occurred.
general.restartFirefox = Please restart %S.
@@ -426,8 +427,14 @@ db.dbRestored = The Zotero database '%1$S' appears to have become corrupted.
db.dbRestoreFailed = The Zotero database '%S' appears to have become corrupted, and an attempt to restore from the last automatic backup failed.\n\nA new database file has been created. The damaged file was saved in your Zotero directory.
db.integrityCheck.passed = No errors were found in the database.
-db.integrityCheck.failed = Errors were found in the Zotero database!
+db.integrityCheck.failed = Errors were found in your Zotero database.
db.integrityCheck.dbRepairTool = You can use the database repair tool at http://zotero.org/utils/dbfix to attempt to correct these errors.
+db.integrityCheck.repairAttempt = Zotero can attempt to correct these errors.
+db.integrityCheck.appRestartNeeded = %S will need to be restarted.
+db.integrityCheck.fixAndRestart = Fix Errors and Restart %S
+db.integrityCheck.errorsFixed = The errors in your Zotero database have been corrected.
+db.integrityCheck.errorsNotFixed = Zotero was unable to correct all the errors in your database.
+db.integrityCheck.reportInForums = You can report this problem in the Zotero Forums.
zotero.preferences.update.updated = Updated
zotero.preferences.update.upToDate = Up to date
@@ -460,7 +467,8 @@ zotero.preferences.search.pdf.toolsDownloadError = An error occurred while at
zotero.preferences.search.pdf.tryAgainOrViewManualInstructions = Please try again later, or view the documentation for manual installation instructions.
zotero.preferences.export.quickCopy.bibStyles = Bibliographic Styles
zotero.preferences.export.quickCopy.exportFormats = Export Formats
-zotero.preferences.export.quickCopy.instructions = Quick Copy allows you to copy selected references to the clipboard by pressing a shortcut key (%S) or dragging items into a text box on a web page.
+zotero.preferences.export.quickCopy.instructions = Quick Copy allows you to copy selected items to the clipboard by pressing %S or dragging items into a text box on a web page.
+zotero.preferences.export.quickCopy.citationInstructions = For bibliography styles, you can copy citations or footnotes by pressing %S or holding down Shift before dragging items.
zotero.preferences.styles.addStyle = Add Style
zotero.preferences.advanced.resetTranslatorsAndStyles = Reset Translators and Styles
@@ -581,7 +589,7 @@ integration.revertAll.button = Revert All
integration.revert.title = Are you sure you want to revert this edit?
integration.revert.body = If you choose to continue, the text of the bibliography entries corresponded to the selected item(s) will be replaced with the unmodified text specified by the selected style.
integration.revert.button = Revert
-integration.removeBibEntry.title = The selected references is cited within your document.
+integration.removeBibEntry.title = The selected reference is cited within your document.
integration.removeBibEntry.body = Are you sure you want to omit it from your bibliography?
integration.cited = Cited
@@ -602,7 +610,7 @@ integration.error.cannotInsertHere = Zotero fields cannot be inserted here.
integration.error.notInCitation = You must place the cursor in a Zotero citation to edit it.
integration.error.noBibliography = The current bibliographic style does not define a bibliography. If you wish to add a bibliography, please choose another style.
integration.error.deletePipe = The pipe that Zotero uses to communicate with the word processor could not be initialized. Would you like Zotero to attempt to correct this error? You will be prompted for your password.
-integration.error.invalidStyle = The style you have selected does not appear to be valid. If you have created this style yourself, please ensure that it passes validation as described at http://zotero.org/support/dev/citation_styles. Alternatively, try selecting another style.
+integration.error.invalidStyle = The style you have selected does not appear to be valid. If you have created this style yourself, please ensure that it passes validation as described at https://github.com/citation-style-language/styles/wiki/Validation. Alternatively, try selecting another style.
integration.error.fieldTypeMismatch = Zotero cannot update this document because it was created by a different word processing application with an incompatible field encoding. In order to make a document compatible with both Word and OpenOffice.org/LibreOffice/NeoOffice, open the document in the word processor with which it was originally created and switch the field type to Bookmarks in the Zotero Document Preferences.
integration.replace = Replace this Zotero field?
@@ -617,7 +625,7 @@ integration.corruptField.description = Clicking "No" will delete the field codes
integration.corruptBibliography = The Zotero field code for your bibliography is corrupted. Should Zotero clear this field code and generate a new bibliography?
integration.corruptBibliography.description = All items cited in the text will appear in the new bibliography, but modifications you made in the "Edit Bibliography" dialog will be lost.
integration.citationChanged = You have modified this citation since Zotero generated it. Do you want to keep your modifications and prevent future updates?
-integration.citationChanged.description = Clicking "Yes" will prevent Zotero from updating this citation if you add additional citations, switch styles, or modify the reference to which it refers. Clicking "No" will erase your changes.
+integration.citationChanged.description = Clicking "Yes" will prevent Zotero from updating this citation if you add additional citations, switch styles, or modify the item to which it refers. Clicking "No" will erase your changes.
integration.citationChanged.edit = You have modified this citation since Zotero generated it. Editing will clear your modifications. Do you want to continue?
styles.installStyle = Install style "%1$S" from %2$S?
@@ -758,7 +766,7 @@ standalone.addonInstallationFailed.body = The add-on "%S" could not be installe
connector.error.title = Zotero Connector Error
connector.standaloneOpen = Your database cannot be accessed because Zotero Standalone is currently open. Please view your items in Zotero Standalone.
-firstRunGuidance.saveIcon = Zotero can recognize a reference on this page. Click this icon in the address bar to save the reference to your Zotero library.
+firstRunGuidance.saveIcon = Zotero has found a reference on this page. Click this icon in the address bar to save the reference to your Zotero library.
firstRunGuidance.authorMenu = Zotero lets you specify editors and translators, too. You can turn an author into an editor or translator by selecting from this menu.
firstRunGuidance.quickFormat = Type a title or author to search for a reference.\n\nAfter you've made your selection, click the bubble or press Ctrl-\u2193 to add page numbers, prefixes, or suffixes. You can also include a page number along with your search terms to add it directly.\n\nYou can edit citations directly in the word processor document.
firstRunGuidance.quickFormatMac = Type a title or author to search for a reference.\n\nAfter you've made your selection, click the bubble or press Cmd-\u2193 to add page numbers, prefixes, or suffixes. You can also include a page number along with your search terms to add it directly.\n\nYou can edit citations directly in the word processor document.
\ No newline at end of file
diff --git a/translators b/translators
index 1ba73cb10..7b8cb18ea 160000
--- a/translators
+++ b/translators
@@ -1 +1 @@
-Subproject commit 1ba73cb10ad0c77c171a389dd60bad78ea6a007f
+Subproject commit 7b8cb18ea06006a89cf1afb94bb481cebed3e43c