www

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

commit 7c4a69b9e1b3bf8f504f398d6c51f787001708de
parent cc4d3db84583d818421bce545af7a8108da8ef4d
Author: Dan Stillman <dstillman@zotero.org>
Date:   Tue, 17 Jan 2012 01:16:47 -0500

Merge branch '3.0'

Diffstat:
Mchrome/content/zotero-platform/unix/integration.css | 7+++----
Mchrome/content/zotero-platform/unix/standalone/menuOverlay.xul | 6++++++
Mchrome/content/zotero-platform/win/integration.css | 2+-
Mchrome/content/zotero-platform/win/standalone/menuOverlay.xul | 8+++++++-
Mchrome/content/zotero/browser.js | 9+++++++++
Mchrome/content/zotero/integration/quickFormat.js | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Mchrome/content/zotero/itemPane.xul | 7++++---
Mchrome/content/zotero/reportInterface.js | 2+-
Mchrome/content/zotero/xpcom/citeproc.js | 398++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mchrome/content/zotero/xpcom/collectionTreeView.js | 41+++++++++++++++++++++++++++++++++++++----
Mchrome/content/zotero/xpcom/data/relations.js | 6+++---
Mchrome/content/zotero/xpcom/debug.js | 18+++++++++++++++++-
Mchrome/content/zotero/xpcom/integration.js | 28++++++++++++++++++++--------
Mchrome/content/zotero/xpcom/schema.js | 5++++-
Mchrome/content/zotero/xpcom/style.js | 5++++-
Mchrome/content/zotero/xpcom/sync.js | 24++++++++++++++++++++++++
Mchrome/content/zotero/xpcom/utilities.js | 1+
Mchrome/content/zotero/xpcom/zotero.js | 17++++++++++++++---
Mchrome/content/zotero/zoteroPane.js | 24+++++++++++++++++-------
Mchrome/content/zotero/zoteroPane.xul | 2++
Mchrome/locale/en-US/zotero/zotero.properties | 2++
Mchrome/skin/default/zotero/itemPane.css | 5+++++
Mcomponents/zotero-protocol-handler.js | 9+++++++++
23 files changed, 435 insertions(+), 265 deletions(-)

diff --git a/chrome/content/zotero-platform/unix/integration.css b/chrome/content/zotero-platform/unix/integration.css @@ -10,7 +10,7 @@ body { background: white; padding: 1px 2px 1px 0; border: 1px solid rgba(0, 0, 0, 0.5); - -moz-appearance: textbox; + -moz-appearance: textfield; } #quick-format-dialog { @@ -19,6 +19,6 @@ body { } #zotero-icon { - margin: 3px 0 0 2px; + margin: 0 0 0 2px; -moz-appearance: none; -} -\ No newline at end of file +} diff --git a/chrome/content/zotero-platform/unix/standalone/menuOverlay.xul b/chrome/content/zotero-platform/unix/standalone/menuOverlay.xul @@ -48,4 +48,10 @@ key="key_quitApplication" command="cmd_quitApplication"/> </menupopup> + <menupopup id="menu_EditPopup"> + <menuseparator/> + <menuitem id="menu_preferences" + label="&preferencesCmd.label;" + oncommand="ZoteroPane.openPreferences();"/> + </menupopup> </overlay> diff --git a/chrome/content/zotero-platform/win/integration.css b/chrome/content/zotero-platform/win/integration.css @@ -31,7 +31,7 @@ } #zotero-icon { - margin: 2px 0 0 2px; + margin: 2px 0 0 3px; -moz-appearance: none; } diff --git a/chrome/content/zotero-platform/win/standalone/menuOverlay.xul b/chrome/content/zotero-platform/win/standalone/menuOverlay.xul @@ -42,10 +42,16 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <menupopup id="menu_FilePopup"> - <menuseparator/> + <menuseparator/> <menuitem id="menu_FileQuitItem" label="&quitApplicationCmdWin.label;" key="key_quitApplication" command="cmd_quitApplication"/> </menupopup> + <menupopup id="menu_ToolsPopup"> + <menuseparator/> + <menuitem id="menu_preferences" + label="&preferencesCmd.label;" + oncommand="ZoteroPane.openPreferences();"/> + </menupopup> </overlay> diff --git a/chrome/content/zotero/browser.js b/chrome/content/zotero/browser.js @@ -152,6 +152,15 @@ var Zotero_Browser = new function() { var libraryID = null, collectionID = null; if(ZoteroPane && !Zotero.isConnector) { try { + if (!ZoteroPane.collectionsView.editable) { + Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError")); + var desc = Zotero.getString('save.error.cannotMakeChangesToLibrary'); + Zotero_Browser.progress.addDescription(desc); + Zotero_Browser.progress.show(); + Zotero_Browser.progress.startCloseTimer(8000); + return; + } + libraryID = ZoteroPane.getSelectedLibraryID(); collectionID = ZoteroPane.getSelectedCollection(true); } catch(e) {} diff --git a/chrome/content/zotero/integration/quickFormat.js b/chrome/content/zotero/integration/quickFormat.js @@ -25,10 +25,10 @@ var Zotero_QuickFormat = new function () { var initialized, io, qfs, qfi, qfiWindow, qfiDocument, qfe, qfb, qfbHeight, keepSorted, - showEditor, referencePanel, referenceBox, referenceHeight = 0, separatorHeight = 0, + showEditor, referencePanel, referenceBox, referenceHeight = 0, separatorHeight = 0, currentLocator, currentLocatorLabel, currentSearchTime, dragging, panel, panelPrefix, panelSuffix, panelSuppressAuthor, panelLocatorLabel, panelLocator, panelInfo, - panelRefersToBubble; + panelRefersToBubble, panelFrameHeight = 0; // A variable that contains the timeout object for the latest onKeyPress event var eventTimeout = null; @@ -106,9 +106,10 @@ var Zotero_QuickFormat = new function () { * Initialize add citation dialog */ this.onLoad = function(event) { - if(event.target !== document) return; + if(event.target !== document) return; // make sure we are visible - window.setTimeout(function() { + window.setTimeout(function() { + if(!Zotero.isFx4) window.sizeToContent(); var screenX = window.screenX; var screenY = window.screenY; var xRange = [window.screen.availLeft, window.screen.width-window.outerWidth]; @@ -142,9 +143,9 @@ var Zotero_QuickFormat = new function () { }; function _refocusQfe() { + referencePanel.blur(); window.focus(); qfe.focus(); - referencePanel.blur(); } /** @@ -687,10 +688,13 @@ var Zotero_QuickFormat = new function () { for(var i=0, n=childNodes.length; i<n && numReferences < SHOWN_REFERENCES; i++) { if(childNodes[i].className === "quick-format-item") { numReferences++; - firstReference = childNodes[i]; + if(!firstReference) { + firstReference = childNodes[i]; + if(referenceBox.selectedIndex === -1) referenceBox.selectedIndex = i; + } } else if(childNodes[i].className === "quick-format-separator") { numSeparators++; - firstSeparator = childNodes[i]; + if(!firstSeparator) firstSeparator = childNodes[i]; } } @@ -711,29 +715,64 @@ var Zotero_QuickFormat = new function () { var panelShowing = referencePanel.state === "open" || referencePanel.state === "showing"; if(numReferences || numSeparators) { + if(((!referenceHeight && firstReference) || (!separatorHeight && firstSeparator) + || !panelFrameHeight) && !panelShowing) { + _openReferencePanel(); + if(!Zotero.isFx4) { + referencePanel.addEventListener("popupshown", function() { + referencePanel.removeEventListener("popupshown", arguments.callee, false); + panelShowing = true; + _resize(); + }, false); + return; + } else { + panelShowing = true; + } + } + if(!referenceHeight && firstReference) { - if(!panelShowing) referencePanel.openPopup(document.documentElement, "after_start", 15, - null, false, false, null); - panelShowing = true; referenceHeight = firstReference.scrollHeight; if(firstReference === referenceBox.lastChild) referenceHeight += 1; } if(!separatorHeight && firstSeparator) { - if(!panelShowing) referencePanel.openPopup(document.documentElement, "after_start", 15, - null, false, false, null); - panelShowing = true; separatorHeight = firstSeparator.scrollHeight; if(firstSeparator === referenceBox.lastChild) separatorHeight += 1; } + if(!panelFrameHeight) { + panelFrameHeight = referencePanel.boxObject.height - referencePanel.clientHeight; + } + referencePanel.sizeTo(window.outerWidth-30, - numReferences*referenceHeight+1+numSeparators*separatorHeight-1); - if(!panelShowing) referencePanel.openPopup(document.documentElement, "after_start", 15, - null, false, false, null); + numReferences*referenceHeight+numSeparators*separatorHeight+2*panelFrameHeight-1); + if(!panelShowing) _openReferencePanel(); } else if(panelShowing) { referencePanel.hidePopup(); referencePanel.sizeTo(window.outerWidth-30, 0); + _refocusQfe(); + } + } + + /** + * Opens the reference panel and potentially refocuses the main text box + */ + function _openReferencePanel() { + referencePanel.openPopup(document.documentElement, "after_start", 15, + null, false, false, null); + if(!Zotero.isMac && !Zotero.isWin) { + // When it opens, we will lose focus + referencePanel.addEventListener("popupshown", function() { + referencePanel.removeEventListener("popupshown", arguments.callee, false); + _refocusQfe(); + + // This is a nasty hack, but seems to be necessary to fix loss of focus on Linux + window.setTimeout(function() { _refocusQfe(); }, 25); + window.setTimeout(function() { _refocusQfe(); }, 50); + window.setTimeout(function() { _refocusQfe(); }, 100); + window.setTimeout(function() { _refocusQfe(); }, 175); + window.setTimeout(function() { _refocusQfe(); }, 250); + }, false); } } @@ -1133,4 +1172,4 @@ var Zotero_QuickFormat = new function () { } window.addEventListener("DOMContentLoaded", Zotero_QuickFormat.onDOMContentLoaded, false); -window.addEventListener("load", Zotero_QuickFormat.onLoad, false); -\ No newline at end of file +window.addEventListener("load", Zotero_QuickFormat.onLoad, false); diff --git a/chrome/content/zotero/itemPane.xul b/chrome/content/zotero/itemPane.xul @@ -34,9 +34,10 @@ <vbox id="zotero-item-pane" zotero-persist="width"> <!-- Trash --> - <!-- TODO: Make look less awful --> - <button id="zotero-item-restore-button" label="&zotero.items.menu.restoreToLibrary;" - oncommand="ZoteroPane_Local.restoreSelectedItems()" hidden="true"/> + <vbox id="zotero-item-restore-button-holder"> + <button id="zotero-item-restore-button" label="&zotero.items.menu.restoreToLibrary;" + oncommand="ZoteroPane_Local.restoreSelectedItems()" hidden="true"/> + </vbox> <!-- Commons --> <button id="zotero-item-show-original" label="Show Original" diff --git a/chrome/content/zotero/reportInterface.js b/chrome/content/zotero/reportInterface.js @@ -40,7 +40,7 @@ var Zotero_Report_Interface = new function() { var sortColumn = ZoteroPane_Local.getSortField(); var sortDirection = ZoteroPane_Local.getSortDirection(); if (sortColumn != 'title' || sortDirection != 'ascending') { - queryString = '?sort=' + sortColumn + (sortDirection != 'ascending' ? '' : '/d'); + queryString = '?sort=' + sortColumn + (sortDirection == 'ascending' ? '' : '/d'); } if (col) { diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js @@ -57,6 +57,12 @@ if (!Array.indexOf) { }; } var CSL = { + NestedBraces: [ + ["(", "["], + [")", "]"] + ], + checkNestedBraceOpen: new RegExp(".*\\("), + checkNestedBraceClose: new RegExp(".*\\)"), LangPrefsMap: { "title":"titles", "title-short":"titles", @@ -105,9 +111,8 @@ var CSL = { FINISH: 1, POSITION_FIRST: 0, POSITION_SUBSEQUENT: 1, - POSITION_SUBSEQUENT_PARALLEL: 2, - POSITION_IBID: 3, - POSITION_IBID_WITH_LOCATOR: 4, + POSITION_IBID: 2, + POSITION_IBID_WITH_LOCATOR: 3, MARK_TRAILING_NAMES: true, POSITION_TEST_VARS: ["position", "first-reference-note-number", "near-note"], AREAS: ["citation", "citation_sort", "bibliography", "bibliography_sort"], @@ -807,6 +812,12 @@ CSL.Output.Queue.prototype.openLevel = function (token, ephemeral) { } blob = new CSL.Blob(undefined, this.formats.value()[token], token); } + if (this.nestedBraces) { + blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); + blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); + blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); + blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); + } curr = this.current.value(); curr.push(blob); this.current.push(blob); @@ -865,6 +876,12 @@ CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePr } } blob = new CSL.Blob(str, token); + if (this.nestedBraces) { + blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); + blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); + blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]); + blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]); + } curr = this.current.value(); if ("undefined" === typeof curr && this.current.mystack.length === 0) { this.current.mystack.push([]); @@ -897,7 +914,7 @@ CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePr }; CSL.Output.Queue.prototype.string = function (state, myblobs, blob) { var i, ilen, j, jlen, b; - var txt_esc = CSL.getSafeEscape(this.state.opt.mode, this.state.tmp.area); + var txt_esc = CSL.getSafeEscape(this.state); var blobs = myblobs.slice(); var ret = []; if (blobs.length === 0) { @@ -936,7 +953,7 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) { } } if (b && b.length) { - b = txt_esc(blobjr.strings.prefix) + b + txt_esc(blobjr.strings.suffix); + b = txt_esc(blobjr.strings.prefix, state.tmp.nestedBraces) + b + txt_esc(blobjr.strings.suffix, state.tmp.nestedBraces); ret.push(b); if (state.tmp.count_offset_characters) { state.tmp.offset_characters += (blen + blobjr.strings.suffix.length + blobjr.strings.prefix.length); @@ -986,7 +1003,7 @@ CSL.Output.Queue.prototype.string = function (state, myblobs, blob) { use_suffix = blob.strings.suffix; if (b && b.length) { use_prefix = blob.strings.prefix; - b = txt_esc(use_prefix) + b + txt_esc(use_suffix); + b = txt_esc(use_prefix, state.tmp.nestedBraces) + b + txt_esc(use_suffix, state.tmp.nestedBraces); if (state.tmp.count_offset_characters) { state.tmp.offset_characters += (use_prefix.length + use_suffix.length); } @@ -1039,7 +1056,7 @@ CSL.Output.Queue.prototype.clearlevel = function () { }; CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, has_more) { var state, ret, ret_last_char, use_delim, i, blob, pos, len, ppos, llen, pppos, lllen, res, str, params, txt_esc; - txt_esc = CSL.getSafeEscape(this.state.opt.mode, this.state.tmp.area); + txt_esc = CSL.getSafeEscape(this.state); if (!delim) { delim = ""; } @@ -1963,7 +1980,7 @@ CSL.DateParser = function () { }; CSL.Engine = function (sys, style, lang, forceLang) { var attrs, langspec, localexml, locale; - this.processor_version = "1.0.255"; + this.processor_version = "1.0.260"; this.csl_version = "1.0"; this.sys = sys; this.sys.xml = new CSL.System.Xml.Parsing(); @@ -2519,6 +2536,7 @@ CSL.Engine.Opt = function () { this.development_extensions.locator_label_parse = true; this.development_extensions.raw_date_parsing = true; this.development_extensions.clean_up_csl_flaws = true; + this.development_extensions.flip_parentheses_to_braces = true; this.gender = {}; this['cite-lang-prefs'] = { persons:['orig'], @@ -3241,6 +3259,7 @@ 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 = {}; @@ -3250,6 +3269,11 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, 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 (k = 0, klen = citations[j].sortedItems.length; k < klen; k += 1) { item = citations[j].sortedItems[k]; if (flag === CSL.PREVIEW) { @@ -3280,7 +3304,9 @@ 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) { - useme = true; + if (citationsInNote[citations[j - 1].properties.noteIndex] === 1) { + useme = true; + } } for (n = 0, nlen = items.slice(1).length; n < nlen; n += 1) { var itmp = items.slice(1)[n]; @@ -3345,11 +3371,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, } } if (suprame) { - if (this.registry.registry[item[1].id].parallel) { - item[1].position = CSL.POSITION_SUBSEQUENT_PARALLEL; - } else { - item[1].position = CSL.POSITION_SUBSEQUENT; - } + item[1].position = CSL.POSITION_SUBSEQUENT; if (first_ref[item[1].id] != onecitation.properties.noteIndex) { item[1]["first-reference-note-number"] = first_ref[item[1].id]; } @@ -3527,7 +3549,8 @@ CSL.getSpliceDelimiter = function (last_collapsed, pos) { CSL.getCitationCluster = function (inputList, citationID) { var result, objects, myparams, len, pos, item, last_collapsed, params, empties, composite, compie, myblobs, Item, llen, ppos, obj, preceding_item, txt_esc, error_object; this.tmp.last_primary_names_string = false; - txt_esc = CSL.Output.Formats[this.opt.mode].text_escape; + this.tmp.nestedBraces = false; + txt_esc = CSL.getSafeEscape(this); this.tmp.area = "citation"; result = ""; objects = []; @@ -3540,6 +3563,50 @@ CSL.getCitationCluster = function (inputList, citationID) { this.registry.citationreg.citationById[citationID].properties.backref_index = false; this.registry.citationreg.citationById[citationID].properties.backref_citation = false; } + if (this.opt.xclass === "note") { + var parasets = []; + var lastTitle = false; + var lastPosition = false; + var lastID = false; + for (var i=0, ilen = inputList.length; i < ilen; i += 1) { + var type = inputList[i][0].type; + var title = inputList[i][0].title; + var position = inputList[i][1].position; + var id = inputList[i][0].id; + if (title && type === "legal_case" && id !== lastID && position) { + if (title !== lastTitle || parasets.length === 0) { + var lst = []; + parasets.push(lst); + } + lst.push(inputList[i][1]); + } + lastTitle = title; + lastPosition = position; + lastID = id; + } + for (var i=0, ilen=parasets.length; i < ilen; i += 1) { + var lst = parasets[i]; + if (lst.length < 2) { + continue; + } + var locatorInLastPosition = lst.slice(-1)[0].locator; + if (locatorInLastPosition) { + for (var j=0, jlen=lst.length - 1; j < jlen; j += 1) { + if (lst[j].locator) { + locatorInLastPosition = false; + } + } + } + if (locatorInLastPosition) { + lst[0].locator = locatorInLastPosition; + delete lst.slice(-1)[0].locator; + lst[0].label = lst.slice(-1)[0].label; + if (lst.slice(-1)[0].label) { + delete lst.slice(-1)[0].label; + } + } + } + } myparams = []; len = inputList.length; for (pos = 0; pos < len; pos += 1) { @@ -3689,6 +3756,7 @@ CSL.getCitationCluster = function (inputList, citationID) { && this.tmp.last_chr === use_layout_suffix.slice(0, 1)) { use_layout_suffix = use_layout_suffix.slice(1); } + this.output.nestedBraces = false; result = txt_esc(this.citation.opt.layout_prefix) + result + txt_esc(use_layout_suffix); if (!this.tmp.suppress_decorations) { len = this.citation.opt.layout_decorations.length; @@ -3764,6 +3832,21 @@ CSL.citeStart = function (Item, item) { } this.tmp.shadow_numbers = {}; this.tmp.first_name_string = false; + if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.prefix) { + var openBrace = CSL.checkNestedBraceOpen.exec(item.prefix); + var closeBrace = CSL.checkNestedBraceClose.exec(item.prefix); + if (openBrace) { + if (!closeBrace) { + this.output.nestedBraces = CSL.NestedBraces; + } else if (closeBrace[0].length < openBrace[0].length) { + this.output.nestedBraces = CSL.NestedBraces; + } else { + this.output.nestedBraces = false; + } + } else if (closeBrace) { + this.output.nestedBraces = false; + } + } }; CSL.citeEnd = function (Item, item) { if (this.tmp.disambig_restore) { @@ -3777,6 +3860,21 @@ CSL.citeEnd = function (Item, item) { this.tmp.cut_var = false; this.tmp.disambig_request = false; this.tmp.cite_locales.push(this.tmp.last_cite_locale); + if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.suffix) { + var openBrace = CSL.checkNestedBraceOpen.exec(item.suffix); + var closeBrace = CSL.checkNestedBraceClose.exec(item.suffix); + if (closeBrace) { + if (!openBrace) { + this.output.nestedBraces = false; + } else if (openBrace[0].length < closeBrace[0].length) { + this.output.nestedBraces = false; + } else { + this.output.nestedBraces = CSL.NestedBraces; + } + } else if (openBrace) { + this.output.nestedBraces = CSL.NestedBraces; + } + } }; CSL.Node = {}; CSL.Node.bibliography = { @@ -7841,8 +7939,6 @@ CSL.Attributes["@position"] = function (state, arg) { for (var i = 0, ilen = lst.length; i < ilen; i += 1) { if (lst[i] === "first") { tryposition = CSL.POSITION_FIRST; - } else if (lst[i] === "subsequent-parallel") { - tryposition = CSL.POSITION_SUBSEQUENT_PARALLEL; } else if (lst[i] === "subsequent") { tryposition = CSL.POSITION_SUBSEQUENT; } else if (lst[i] === "ibid") { @@ -8923,7 +9019,7 @@ CSL.Blob = function (str, token, levelname) { var len, pos, key; this.levelname = levelname; if (token) { - this.strings = {}; + this.strings = {"prefix":"","suffix":""}; for (key in token.strings) { if (token.strings.hasOwnProperty(key)) { this.strings[key] = token.strings[key]; @@ -9509,7 +9605,7 @@ CSL.Util.substituteEnd = function (state, target) { author_substitute = new CSL.Token("text", CSL.SINGLETON); func = function (state, Item) { var i, ilen; - var text_esc = CSL.getSafeEscape(state.opt.mode, state.tmp.area); + var text_esc = CSL.getSafeEscape(state); var printing = !state.tmp.suppress_decorations; if (printing && state.tmp.area === "bibliography") { if (!state.tmp.rendered_name) { @@ -10003,7 +10099,7 @@ CSL.Util.FlipFlopper = function (state) { this.okReverseHash = hashes[4]; }; CSL.Util.FlipFlopper.prototype.init = function (str, blob) { - this.txt_esc = CSL.getSafeEscape(this.state.opt.mode, this.state.tmp.area); + this.txt_esc = CSL.getSafeEscape(this.state); str = this._normalizeString(str); if (!blob) { this.strs = this.getSplitStrings(str); @@ -10230,9 +10326,9 @@ CSL.Util.FlipFlopper.prototype.addFlipFlop = function (blob, fun) { return newdecor; }; CSL.Output.Formatters = {}; -CSL.getSafeEscape = function(outputModeOpt, outputArea) { - if (["bibliography", "citation"].indexOf(outputArea) > -1) { - return CSL.Output.Formats[outputModeOpt].text_escape; +CSL.getSafeEscape = function(state) { + if (["bibliography", "citation"].indexOf(state.tmp.area) > -1) { + return CSL.Output.Formats[state.opt.mode].text_escape; } else { return function (txt) { return txt; }; } @@ -10304,7 +10400,7 @@ CSL.Output.Formatters.title = function (state, string) { lowerCaseVariant = words[pos].toLowerCase(); var totallyskip = false; if (!isAllUpperCase || (words.length === 1 && words[pos].length < 4)) { - if (words[pos] === upperCaseVariant) { + if (words[pos] !== lowerCaseVariant) { totallyskip = true; } } @@ -11206,7 +11302,7 @@ CSL.Disambiguation = function (state) { this.registry = state.registry.registry; this.ambigcites = state.registry.ambigcites; this.configModes(); - this.clashes = [1, 0]; + this.debug = false; }; CSL.Disambiguation.prototype.run = function(akey) { if (!this.modes.length) { @@ -11221,22 +11317,15 @@ CSL.Disambiguation.prototype.runDisambig = function () { this.nnameset = 0; this.gnameset = 0; this.gname = 0; + this.clashes = [1, 0]; while(this.lists[pos][1].length) { this.listpos = pos; if (!this.base) { this.base = this.lists[pos][0]; } - if (this.rerun) { - this.rerun = false; - } else { - this.scanItems(this.lists[pos], 0); - } var names_used = []; ismax = this.incrementDisambig(); this.scanItems(this.lists[pos], 1); - if (this.clashes[1] < this.clashes[0]) { - this.base.better = this.base.names.slice(); - } this.evalScan(ismax); } } @@ -11255,19 +11344,21 @@ CSL.Disambiguation.prototype.scanItems = function (list, phase) { this.minval = tempResult[2]; ItemCite = tempResult[3]; this.partners.push(Item); - this.clashes[phase] = 0; this.nonpartners = []; + var clashes = 0; for (pos = 1, len = list[1].length; pos < len; pos += 1) { otherItem = list[1][pos]; var otherItemData = this.getItemDesc(otherItem); var otherItemCite = otherItemData[3]; if (ItemCite === otherItemCite) { - this.clashes[phase] += 1; + clashes += 1; this.partners.push(otherItem); } else { this.nonpartners.push(otherItem); } } + this.clashes[0] = this.clashes[1]; + this.clashes[1] = clashes; }; CSL.Disambiguation.prototype.evalScan = function (ismax) { this[this.modes[this.modeindex]](ismax); @@ -11281,92 +11372,27 @@ CSL.Disambiguation.prototype.disNames = function (ismax) { this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, mybase); this.lists[this.listpos] = [this.base, []]; } else if (this.clashes[1] === 0) { - mybase = CSL.cloneAmbigConfig(this.base); - mybase.year_suffix = false; - this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, mybase); + this.betterbase = CSL.cloneAmbigConfig(this.base); + this.betterbase.year_suffix = false; + this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, this.betterbase); this.lists[this.listpos] = [this.base, []]; } else if (this.nonpartners.length === 1) { - mybase = CSL.cloneAmbigConfig(this.base); - mybase.year_suffix = false; - this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, mybase); - this.lists[this.listpos] = [this.base, this.partners]; - } else if (this.clashes[1] < this.clashes[0]) { - this.lists[this.listpos] = [this.base, this.partners]; - if (this.nonpartners.length === 1) { - this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, this.base); - } else { - this.lists.push([this.base, this.nonpartners]); - } - } else { - if (ismax || this.advance_mode) { - if (ismax) { - var better = this.lists[this.listpos][0].better; - if (better) { - this.base.names = better.slice(); - } else { - this.base = new CSL.AmbigConfig(); - } - this.lists[this.listpos] = [this.base, this.nonpartners]; - } - for (pos = 0, len = this.partners.length; pos < len; pos += 1) { - this.state.registry.registerAmbigToken(this.akey, "" + this.partners[pos].id, this.base); - } - } else { - this.rerun = true; - } - } -}; -CSL.Disambiguation.prototype.disGivens = function (ismax) { - var pos, len, mybase; - if (this.clashes[1] === 0 && this.nonpartners.length === 1) { - if (this.clashes[0] === 1) { - this.base = this.decrementNames(); - } - mybase = CSL.cloneAmbigConfig(this.base); - mybase.year_suffix = false; - this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, this.base); - this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, mybase); - this.lists[this.listpos] = [this.base, []]; - } else if (this.clashes[1] === 0) { - if (this.clashes[0] === 1) { - this.base = this.decrementNames(); - } - mybase = CSL.cloneAmbigConfig(this.base); - mybase.year_suffix = false; - this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, mybase); - this.lists[this.listpos] = [this.base, this.nonpartners]; - } else if (this.nonpartners.length === 1) { - if (this.clashes[0] === 1) { - this.base = this.decrementNames(); - } - mybase = CSL.cloneAmbigConfig(this.base); - mybase.year_suffix = false; - this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, mybase); + this.betterbase = CSL.cloneAmbigConfig(this.base); + this.betterbase.year_suffix = false; + this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, this.betterbase); this.lists[this.listpos] = [this.base, this.partners]; } else if (this.clashes[1] < this.clashes[0]) { this.lists[this.listpos] = [this.base, this.partners]; - if (this.nonpartners.length === 1) { - this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, this.base); - } else { - this.lists.push([this.base, this.nonpartners]); - } + this.lists.push([this.base, this.nonpartners]); } else { - this.base = CSL.cloneAmbigConfig(this.oldbase); - if (ismax || this.advance_mode) { - if (ismax) { - var better = this.lists[this.listpos][0].better; - if (better) { - this.base.names = better.slice(); - } else { - this.base = new CSL.AmbigConfig(); - } - this.lists[this.listpos] = [this.base, this.nonpartners]; + if (ismax) { + if (this.betterbase) { + this.base = CSL.cloneAmbigConfig(this.betterbase); } + this.lists[this.listpos] = [this.base, this.nonpartners]; for (pos = 0, len = this.partners.length; pos < len; pos += 1) { this.state.registry.registerAmbigToken(this.akey, "" + this.partners[pos].id, this.base); } - } else { - this.rerun = true; } } }; @@ -11384,7 +11410,6 @@ CSL.Disambiguation.prototype.disExtraText = function () { } } else { this.base.disambiguate = false; - this.lists[this.listpos] = [this.base, this.lists[this.listpos][1].slice(1)]; } }; CSL.Disambiguation.prototype.disYears = function () { @@ -11413,77 +11438,59 @@ CSL.Disambiguation.prototype.disYears = function () { CSL.Disambiguation.prototype.incrementDisambig = function () { var val, maxed; maxed = false; - this.oldbase = CSL.cloneAmbigConfig(this.base); - if (this.advance_mode) { - this.modeindex += 1; - this.advance_mode = false; - } - if (!maxed && "disNames" === this.modes[this.modeindex]) { - if (this.base.names[this.nnameset] < this.maxvals[this.nnameset]) { - this.base.names[this.nnameset] += 1; - } else { - if (this.nnameset < (this.base.names.length - 1)) { - this.nnameset += 1; - } - if (this.base.names[this.nnameset] < this.maxvals[this.nnameset]) { - this.base.names[this.nnameset] += 1; - } - } - if (this.nnameset === (this.base.names.length - 1) && this.base.names[this.nnameset] === this.maxvals[this.nnameset]) { - if (this.modeindex === (this.modes.length - 1)) { - return true; - } else { - maxed = false; - } - } - } - if (!maxed && "disGivens" === this.modes[this.modeindex]) { - if (this.gname < this.maxvals[this.gnameset]) { - if (this.base.givens[this.gnameset][this.gname] === this.minval) { + if ("disNames" === this.modes[this.modeindex]) { + var increment_name = false; + var increment_nameset = false; + if (this.state.opt["disambiguate-add-givenname"] && this.state.opt["givenname-disambiguation-rule"] === "by-cite") { + if (this.base.givens[this.gnameset][this.gname] < 2) { this.base.givens[this.gnameset][this.gname] += 1; + } else { + this.base.givens[this.gnameset][this.gname] = this.betterbase.givens[this.gnameset][this.gname]; + if (this.gname < this.base.names[this.gnameset]) { + this.gname += 1; + this.base.names[this.gnameset] += 1; + this.base.givens[this.gnameset][this.gname] += 1; + } else { + increment_name = true; + } } - this.base.givens[this.gnameset][this.gname] += 1; - this.gname += 1; } else { - if (this.gnameset < (this.base.givens.length - 1)) { - this.gnameset += 1; - this.gname = 0; - } - if (this.gname < this.maxvals[this.gnameset]) { - this.base.givens[this.gnameset][this.gname] += 1; - this.gname += 1; + increment_name = true; + } + if (this.state.opt["disambiguate-add-names"]) { + if (increment_name) { + if (this.base.names[this.gnameset] < this.maxvals[this.gnameset]) { + this.gname += 1; + this.base.names[this.gnameset] += 1; + } else { + increment_nameset = true; + } + } + if (increment_nameset) { + if (this.gnameset < this.base.names.length - 1) { + this.gnameset += 1; + this.gname = 0; + if (this.state.opt["disambiguate-add-givenname"] && this.state.opt["givenname-disambiguation-rule"] === "by-cite") { + this.base.givens[this.gnameset][this.gname] += 1; + } else if (this.base.names[this.gnameset] < this.maxvals[this.gnameset]) { + this.gname += 1; + this.base.names[this.gnameset] += 1; + } + } else { + maxed = true; + if (this.modeindex < this.modes.length - 1) { + this.modeindex += 1; + } + } } } } if (!maxed && "disExtraText" === this.modes[this.modeindex]) { - maxed = false; this.base.disambiguate = true; - if (this.modeindex === (this.modes.length - 1)) { - return true; - } else { - maxed = false; - } + maxed = true; } if (!maxed && "disYears" === this.modes[this.modeindex]) { - maxed = false; - } - if (!maxed && this.modes[this.modeindex] === "disGivens") { - if ((this.gnameset >= (this.base.names.length - 1) && ("undefined" === typeof this.maxvals[this.gnameset] || this.gname === this.maxvals[this.gnameset])) || this.base.names.length === 0) { - if (this.modeindex === (this.modes.length - 1)) { - maxed = true; - } else { - this.advance_mode = true; - } - } - } - if (!maxed && this.modes[this.modeindex] === "disNames") { - if ((this.nnameset >= (this.base.names.length - 1) && ("undefined" === typeof this.maxvals[this.nnameset] ||this.base.names[this.nnameset] === this.maxvals[this.nnameset])) || this.base.names.length === 0) { - if (this.modeindex === (this.modes.length - 1)) { - maxed = true; - } else { - this.advance_mode = true; - } - } + maxed = true; } return maxed; }; @@ -11499,8 +11506,8 @@ CSL.Disambiguation.prototype.initVars = function (akey) { var i, ilen, myIds, myItemBundles, myItems; this.lists = []; this.base = false; + this.betterbase = false; this.akey = akey; - this.advance_mode = false; myItemBundles = []; this.old_desc = {}; myIds = this.ambigcites[akey]; @@ -11508,6 +11515,12 @@ CSL.Disambiguation.prototype.initVars = function (akey) { for (i = 0, ilen = myIds.length; i < ilen; i += 1) { var myItem = this.state.retrieveItem("" + myIds[i]); var myDesc = this.getItemDesc(myItem); + if (!this.betterbase) { + this.betterbase = CSL.cloneAmbigConfig(myDesc[0]); + this.base = myDesc[0]; + this.maxvals = myDesc[1]; + this.minval = myDesc[2]; + } myItemBundles.push([myDesc, myItem]); this.old_desc[myIds[i]] = [this.state.registry.registry[myIds[i]].disambig.year_suffix, this.state.registry.registry[myIds[i]].disambig.disambiguate]; } @@ -11539,13 +11552,10 @@ CSL.Disambiguation.prototype.initVars = function (akey) { CSL.Disambiguation.prototype.configModes = function () { var dagopt, gdropt; this.modes = []; - if (this.state.opt["disambiguate-add-names"]) { - this.modes.push("disNames"); - } dagopt = this.state.opt["disambiguate-add-givenname"]; gdropt = this.state.opt["givenname-disambiguation-rule"]; - if (dagopt && gdropt === "by-cite") { - this.modes.push("disGivens"); + if (this.state.opt['disambiguate-add-names'] || (dagopt && gdropt === "by-cite")) { + this.modes.push("disNames"); } if (this.state.opt.has_disambiguate) { this.modes.push("disExtraText"); @@ -11554,35 +11564,6 @@ CSL.Disambiguation.prototype.configModes = function () { this.modes.push("disYears"); } }; -CSL.Disambiguation.prototype.decrementNames = function () { - var base_return, do_me, i, j, pos, len, ppos, llen, ids; - base_return = CSL.cloneAmbigConfig(this.base); - do_me = false; - len = base_return.givens.length - 1; - for (pos = len; pos > -1; pos += -1) { - llen = base_return.givens[pos].length - 1; - for (ppos = llen; ppos > -1; ppos += -1) { - if (base_return.givens[pos][ppos] > this.oldbase.givens[pos][ppos]) { - do_me = true; - } - } - } - if (do_me) { - len = base_return.givens.length - 1; - for (pos = len; pos > -1; pos += -1) { - llen = base_return.givens[pos].length - 1; - for (ppos = llen; ppos > -1; ppos += -1) { - if (base_return.givens[pos][ppos] > this.oldbase.givens[pos][ppos]) { - break; - } - if (ppos < base_return.names[pos]) { - base_return.names[pos] += -1; - } - } - } - } - return base_return; -}; CSL.Registry.CitationReg = function (state) { this.citationById = {}; this.citationByIndex = []; @@ -11596,4 +11577,3 @@ CSL.Node.generate = { } } }; - diff --git a/chrome/content/zotero/xpcom/collectionTreeView.js b/chrome/content/zotero/xpcom/collectionTreeView.js @@ -1242,7 +1242,7 @@ Zotero.CollectionTreeView.prototype.canDrop = function(row, orient, dragData) } var linkedItem = item.getLinkedItem(itemGroup.ref.libraryID); - if (linkedItem) { + if (linkedItem && !linkedItem.deleted) { // For drag to root, skip if linked item exists if (itemGroup.isLibrary(true)) { continue; @@ -1373,6 +1373,18 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) // Check if there's already a copy of this item in the library var linkedItem = item.getLinkedItem(targetLibraryID); if (linkedItem) { + // If linked item is in the trash, undelete it + if (linkedItem.deleted) { + // Remove from any existing collections, or else when it gets + // undeleted it would reappear in those collections + var collectionIDs = linkedItem.getCollections(); + for each(var collectionID in collectionIDs) { + var col = Zotero.Collections.get(collectionID); + col.removeItem(linkedItem.id); + } + linkedItem.deleted = false; + linkedItem.save(); + } return linkedItem.id; /* @@ -1415,6 +1427,19 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) // Standalone attachment if (item.isAttachment()) { + var linkMode = item.attachmentLinkMode; + + // Skip linked files + if (linkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE) { + Zotero.debug("Skipping standalone linked file attachment on drag"); + return false; + } + + if (!itemGroup.filesEditable) { + Zotero.debug("Skipping standalone file attachment on drag"); + return false; + } + return Zotero.Attachments.copyAttachmentToLibrary(item, targetLibraryID); } @@ -1468,6 +1493,7 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) // Skip linked files if (linkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE) { + Zotero.debug("Skipping child linked file attachment on drag"); continue; } @@ -1529,6 +1555,10 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) else { var item = Zotero.Items.get(desc.id); var id = copyItem(item, targetLibraryID); + // Standalone attachments might not get copied + if (!id) { + continue; + } // Mark copied item for adding to collection if (parent) { if (!addItems[parent]) { @@ -1538,8 +1568,6 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) } } } - - return collectionID; } var collections = [{ @@ -1613,7 +1641,12 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) var newIDs = []; for each(var item in newItems) { - newIDs.push(copyItem(item, targetLibraryID)); + var id = copyItem(item, targetLibraryID) + // Standalone attachments might not get copied + if (!id) { + continue; + } + newIDs.push(id); } if (toReconcile.length) { diff --git a/chrome/content/zotero/xpcom/data/relations.js b/chrome/content/zotero/xpcom/data/relations.js @@ -124,15 +124,15 @@ Zotero.Relations = new function () { Zotero.DB.beginTransaction(); var sql = "UPDATE relations SET libraryID=? WHERE libraryID=?"; - Zotero.DB.query(sql, [fromLibraryID, toLibraryID]); + Zotero.DB.query(sql, [toLibraryID, fromLibraryID]); sql = "UPDATE relations SET " + "subject=REPLACE(subject, 'zotero.org/users/" + fromUserID + "', " + "'zotero.org/users/" + toUserID + "'), " + "object=REPLACE(object, 'zotero.org/users/" + fromUserID + "', " + "'zotero.org/users/" + toUserID + "') " - + "WHERE predicate='owl:sameAs'"; - Zotero.DB.query(sql); + + "WHERE predicate IN (?, ?)"; + Zotero.DB.query(sql, [this.linkedObjectPredicate, this.deletedItemPredicate]); Zotero.DB.commitTransaction(); } diff --git a/chrome/content/zotero/xpcom/debug.js b/chrome/content/zotero/xpcom/debug.js @@ -46,7 +46,23 @@ Zotero.Debug = new function () { return; } - if (typeof message != 'string') { + // Properly display thrown Error objects + if (message && message.constructor) { + switch (message.constructor.name) { + case 'Error': + case 'EvalError': + case 'RangeError': + case 'ReferenceError': + case 'SyntaxError': + case 'TypeError': + case 'URIError': + message = "'message' => \"" + message.message + "\"\n" + + Zotero.Utilities.varDump(message) + "\n" + + message.stack; + break; + } + } + else if (typeof message != 'string') { message = Zotero.Utilities.varDump(message); } diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js @@ -30,6 +30,14 @@ const RESELECT_KEY_ITEM_KEY = 2; const RESELECT_KEY_ITEM_ID = 3; const DATA_VERSION = 3; +// Specifies that citations should only be updated if changed +const FORCE_CITATIONS_FALSE = 0; +// Specifies that citations should only be updated if formattedText has changed from what is encoded +// in the field code +const FORCE_CITATIONS_REGENERATE = 1; +// Specifies that citations should be reset regardless of whether formattedText has changed +const FORCE_CITATIONS_RESET_TEXT = 2; + // this is used only for update checking const INTEGRATION_PLUGINS = ["zoteroMacWordIntegration@zotero.org", "zoteroOpenOfficeIntegration@zotero.org", "zoteroWinWordIntegration@zotero.org"]; @@ -628,7 +636,8 @@ Zotero.Integration.Document.prototype._getSession = function(require, dontRunSet } catch(e) { // make sure style is defined if(e instanceof Zotero.Integration.DisplayException && e.name === "invalidStyle") { - this._session.setDocPrefs(this._doc, this._app.primaryFieldType, this._app.secondaryFieldType, function() { + this._session.setDocPrefs(this._doc, this._app.primaryFieldType, + this._app.secondaryFieldType, function() { me._doc.setDocumentData(me._session.data.serializeXML()); me._session.reload = true; callback(true); @@ -692,7 +701,7 @@ Zotero.Integration.Document.prototype.addBibliography = function() { field = fieldGetter.addField(); field.setCode("BIBL"); fieldGetter.updateSession(function() { - fieldGetter.updateDocument(false, true, false, function() { + fieldGetter.updateDocument(FORCE_CITATIONS_FALSE, true, false, function() { Zotero.Integration.complete(me._doc); }); }); @@ -725,7 +734,7 @@ Zotero.Integration.Document.prototype.editBibliography = function(callback) { fieldGetter.updateSession(function() { me._session.editBibliography(this._doc, function() { me._doc.activate(); - fieldGetter.updateDocument(false, true, false, function() { + fieldGetter.updateDocument(FORCE_CITATIONS_FALSE, true, false, function() { Zotero.Integration.complete(me._doc); }); }); @@ -743,7 +752,7 @@ Zotero.Integration.Document.prototype.refresh = function() { // Send request, forcing update of citations and bibliography var fieldGetter = new Zotero.Integration.Fields(me._session, me._doc); fieldGetter.updateSession(function() { - fieldGetter.updateDocument(true, true, false, function() { + fieldGetter.updateDocument(FORCE_CITATIONS_REGENERATE, true, false, function() { Zotero.Integration.complete(me._doc); }); }); @@ -779,7 +788,8 @@ Zotero.Integration.Document.prototype.setDocPrefs = function() { var me = this; this._getSession(false, true, function(haveSession) { var setDocPrefs = function() { - me._session.setDocPrefs(me._app.primaryFieldType, me._app.secondaryFieldType, function(oldData) { + me._session.setDocPrefs(me._doc, me._app.primaryFieldType, me._app.secondaryFieldType, + function(oldData) { if(oldData || oldData === null) { me._doc.setDocumentData(me._session.data.serializeXML()); if(oldData === null) return; @@ -820,7 +830,8 @@ Zotero.Integration.Document.prototype.setDocPrefs = function() { // refresh contents fieldGetter = new Zotero.Integration.Fields(me._session, me._doc); fieldGetter.updateSession(function() { - fieldGetter.updateDocument(true, true, true, function() { + fieldGetter.updateDocument(FORCE_CITATIONS_RESET_TEXT, true, true, + function() { Zotero.Integration.complete(me._doc); }); }); @@ -1221,7 +1232,8 @@ Zotero.Integration.Fields.prototype._updateDocument = function(forceCitations, f isRich = true; } - if(citation.properties.formattedCitation !== formattedCitation) { + if(forceCitations === FORCE_CITATIONS_RESET_TEXT + || citation.properties.formattedCitation !== formattedCitation) { // Check if citation has been manually modified if(!ignoreCitationChanges && citation.properties.plainCitation) { var plainCitation = field.getText(); @@ -1501,7 +1513,7 @@ Zotero.Integration.CitationEditInterface.prototype = { } } - me._fields.updateDocument(false, false, false, me._doneCallback); + me._fields.updateDocument(FORCE_CITATIONS_FALSE, false, false, me._doneCallback); }); } else { if(this._deleteOnCancel) this._field.delete(); diff --git a/chrome/content/zotero/xpcom/schema.js b/chrome/content/zotero/xpcom/schema.js @@ -1088,7 +1088,9 @@ Zotero.Schema = new function(){ // 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)", + + "SELECT COUNT(*) FROM creatorData WHERE firstName='' AND lastName=''" ]; for each(var sql in queries) { @@ -3068,6 +3070,7 @@ Zotero.Schema = new function(){ // TODO // // Replace customBaseFieldMappings to fix FK fields/customField -> customFields->customFieldID + // If libraryID set, make sure no relations still use a local user key, and then remove on-error code in sync.js _updateDBVersion('userdata', toVersion); diff --git a/chrome/content/zotero/xpcom/style.js b/chrome/content/zotero/xpcom/style.js @@ -169,7 +169,10 @@ Zotero.Styles = new function() { var xml = enConverter.parse(); } else { // CSL - var xml = new XML(this.cleanXML(style)); + var xml = this.cleanXML(style); + if (!xml.name()) { + throw new Error("File is not XML"); + } } } catch(e) { error = e; diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js @@ -1867,6 +1867,21 @@ Zotero.Sync.Server = new function () { } } } + + // Make sure this isn't due to relations using a local user key + // + // TEMP: This can be removed once a DB upgrade step is added + try { + var sql = "SELECT libraryID FROM relations WHERE libraryID LIKE 'local/%' LIMIT 1"; + var repl = Zotero.DB.valueQuery(sql); + if (repl) { + Zotero.Relations.updateUser(repl, repl, Zotero.userID, Zotero.libraryID); + } + } + catch (e) { + Components.utils.reportError(e); + Zotero.debug(e); + } break; case 'FULL_SYNC_REQUIRED': @@ -2177,6 +2192,10 @@ Zotero.Sync.Server = new function () { } if (lastUserID != userID || lastLibraryID != libraryID) { + if (!lastLibraryID) { + var repl = "local/" + Zotero.getLocalUserKey(); + } + Zotero.userID = userID; Zotero.libraryID = libraryID; @@ -2188,6 +2207,11 @@ Zotero.Sync.Server = new function () { Zotero.Sync.Server.resetClient(); Zotero.Sync.Storage.resetAllSyncStates(); } + // Replace local user key with libraryID, in case duplicates were + // merged before the first sync + else if (!lastLibraryID) { + Zotero.Relations.updateUser(repl, repl, userID, libraryID); + } } if (lastUsername != username) { diff --git a/chrome/content/zotero/xpcom/utilities.js b/chrome/content/zotero/xpcom/utilities.js @@ -37,6 +37,7 @@ const CSL_NAMES_MAPPINGS = { "bookAuthor":"container-author", "composer":"composer", "interviewer":"interviewer", + "inventor":"author", "recipient":"recipient", "seriesEditor":"collection-editor", "translator":"translator" diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js @@ -35,7 +35,7 @@ const ZOTERO_CONFIG = { API_URL: 'https://api.zotero.org/', PREF_BRANCH: 'extensions.zotero.', BOOKMARKLET_URL: 'https://www.zotero.org/bookmarklet/', - VERSION: "3.0b3.SOURCE" + VERSION: "3.0rc1" }; /* @@ -227,8 +227,19 @@ const ZOTERO_CONFIG = { this.isStandalone = appInfo.ID == ZOTERO_CONFIG['GUID']; if(this.isStandalone) { this.version = appInfo.version; - } else { + } else if(this.isFx4) { + // Use until we collect version from extension manager this.version = ZOTERO_CONFIG['VERSION']; + + Components.utils.import("resource://gre/modules/AddonManager.jsm"); + AddonManager.getAddonByID(ZOTERO_CONFIG['GUID'], + function(addon) { Zotero.version = addon.version; }); + } else { + var gExtensionManager = + Components.classes["@mozilla.org/extensions/manager;1"] + .getService(Components.interfaces.nsIExtensionManager); + this.version + = gExtensionManager.getItemForID(ZOTERO_CONFIG['GUID']).version; } // OS platform @@ -2422,7 +2433,7 @@ Zotero.Browser = new function() { hiddenBrowser.docShell.allowAuth = false; hiddenBrowser.docShell.allowDNSPrefetch = false; hiddenBrowser.docShell.allowImages = false; - hiddenBrowser.docShell.allowJavascript = false; + hiddenBrowser.docShell.allowJavascript = true; hiddenBrowser.docShell.allowMetaRedirects = false; hiddenBrowser.docShell.allowPlugins = false; Zotero.debug("created hidden browser (" diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js @@ -1063,10 +1063,17 @@ var ZoteroPane = new function() itemgroup.setSearch(''); itemgroup.setTags(getTagSelection()); - // Enable or disable toolbar icons as necessary - const disableIfNoEdit = ["cmd_zotero_newCollection", "zotero-tb-add", - "cmd_zotero_newItemFromCurrentPage", "zotero-tb-lookup", "cmd_zotero_newStandaloneNote", - "zotero-tb-note-add", "zotero-tb-attachment-add"]; + // Enable or disable toolbar icons and menu options as necessary + const disableIfNoEdit = [ + "cmd_zotero_newCollection", + "cmd_zotero_newSavedSearch", + "zotero-tb-add", + "cmd_zotero_newItemFromCurrentPage", + "zotero-tb-lookup", + "cmd_zotero_newStandaloneNote", + "zotero-tb-note-add", + "zotero-tb-attachment-add" + ]; for(var i=0; i<disableIfNoEdit.length; i++) { var el = document.getElementById(disableIfNoEdit[i]); if(itemgroup.editable) { @@ -1519,6 +1526,7 @@ var ZoteroPane = new function() // Remove virtual duplicates collection if (itemGroup.isDuplicates()) { this.setVirtual(itemGroup.ref.libraryID, 'duplicates', false); + return; } // Remove virtual unfiled collection else if (itemGroup.isUnfiled()) { @@ -2122,7 +2130,9 @@ var ZoteroPane = new function() } // Disable some actions if user doesn't have write access - var s = [m.editSelectedCollection, m.removeCollection, m.newCollection, m.newSavedSearch, m.newSubcollection]; + // + // Some actions are disabled via their commands in onCollectionSelected() + var s = [m.newSubcollection, m.editSelectedCollection, m.removeCollection, m.emptyTrash]; if (itemGroup.isWithinGroup() && !itemGroup.editable && !itemGroup.isDuplicates() && !itemGroup.isUnfiled()) { disable = disable.concat(s); } @@ -3522,14 +3532,14 @@ var ZoteroPane = new function() this.displayCannotEditLibraryMessage = function () { var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] .getService(Components.interfaces.nsIPromptService); - ps.alert(null, "", "You cannot make changes to the currently selected library."); + ps.alert(null, "", Zotero.getString('save.error.cannotMakeChangesToLibrary')); } this.displayCannotEditLibraryFilesMessage = function () { var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] .getService(Components.interfaces.nsIPromptService); - ps.alert(null, "", "You cannot add files to the currently selected library."); + ps.alert(null, "", Zotero.getString('save.error.cannotAddFilesToLibrary')); } diff --git a/chrome/content/zotero/zoteroPane.xul b/chrome/content/zotero/zoteroPane.xul @@ -236,6 +236,7 @@ <popupset> <menupopup id="zotero-collectionmenu" onpopupshowing="ZoteroPane_Local.buildCollectionContextMenu();"> + <!-- Keep order in sync with buildCollectionContextMenu --> <menuitem label="&zotero.toolbar.newCollection.label;" command="cmd_zotero_newCollection"/> <menuitem label="&zotero.toolbar.newSavedSearch.label;" command="cmd_zotero_newSavedSearch"/> <menuitem label="&zotero.toolbar.newSubcollection.label;" oncommand="ZoteroPane_Local.newCollection(ZoteroPane_Local.getSelectedCollection().id)"/> @@ -254,6 +255,7 @@ <menuitem label="Refresh" oncommand="ZoteroPane_Local.refreshCommonsBucket();"/><!--TODO localize --> </menupopup> <menupopup id="zotero-itemmenu" onpopupshowing="ZoteroPane_Local.buildItemContextMenu();"> + <!-- Keep order in sync with buildItemContextMenu --> <menuitem label="&zotero.items.menu.showInLibrary;" oncommand="ZoteroPane_Local.selectItem(this.parentNode.getAttribute('itemID'), true)"/> <menuseparator/> <!-- with icon: <menuitem class="menuitem-iconic" id="zotero-menuitem-note" label="&zotero.items.menu.attach.note;" oncommand="ZoteroPane_Local.newNote(false, this.parentNode.getAttribute('itemID'))"/>--> diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties @@ -396,6 +396,8 @@ fileTypes.document = Document save.attachment = Saving Snapshot… save.link = Saving Link… save.link.error = An error occurred while saving this link. +save.error.cannotMakeChangesToLibrary = You cannot make changes to the currently selected library. +save.error.cannotAddFilesToLibrary = You cannot add files to the currently selected library. ingester.saveToZotero = Save to Zotero ingester.saveToZoteroUsing = Save to Zotero using "%S" diff --git a/chrome/skin/default/zotero/itemPane.css b/chrome/skin/default/zotero/itemPane.css @@ -36,6 +36,11 @@ margin-left: 5px; } +/* Restore button in trash view */ +#zotero-item-restore-button-holder +{ + -moz-appearance: toolbar; +} /* Merge pane in duplicates view */ #zotero-duplicates-merge-button diff --git a/components/zotero-protocol-handler.js b/components/zotero-protocol-handler.js @@ -424,6 +424,15 @@ function ChromeExtensionHandler() { valA = Zotero.Date.strToMultipart(a[sorts[index].field]); valB = Zotero.Date.strToMultipart(b[sorts[index].field]); } + // TEMP: This is an ugly hack to make creator sorting + // slightly less broken. To do this right, real creator + // sorting needs to be abstracted from itemTreeView.js. + else if (sorts[index].field == 'firstCreator') { + var itemA = Zotero.Items.getByLibraryAndKey(a.libraryID, a.key); + var itemB = Zotero.Items.getByLibraryAndKey(b.libraryID, b.key); + valA = itemA.getField('firstCreator'); + valB = itemB.getField('firstCreator'); + } else { valA = a[sorts[index].field]; valB = b[sorts[index].field];