diff --git a/README.md b/README.md index 67bf33443..f49da7045 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Zotero ====== [![Build Status](https://travis-ci.org/zotero/zotero.svg?branch=master)](https://travis-ci.org/zotero/zotero) -Zotero is a free, easy-to-use tool to help you collect, organize, cite, and share your research sources. +[Zotero](https://www.zotero.org/) is a free, easy-to-use tool to help you collect, organize, cite, and share your research sources. + +Please post feature requests or bug reports to the [Zotero Forums](https://forums.zotero.org/). If you're having trouble with Zotero, see [Getting Help](https://www.zotero.org/support/getting_help). For more information on how to use this source code, see the [Zotero wiki](https://www.zotero.org/support/dev/source_code). diff --git a/chrome/content/zotero-platform/mac/integration.css b/chrome/content/zotero-platform/mac/integration.css index ee8c9f8bf..f33b75ad3 100644 --- a/chrome/content/zotero-platform/mac/integration.css +++ b/chrome/content/zotero-platform/mac/integration.css @@ -1,15 +1,17 @@ body { line-height: 1.45em; + font-size: 15px; } body[multiline="true"] { - line-height: 1.63em; + line-height: 26px; } #quick-format-dialog { background: transparent; -moz-appearance: none; padding: 0; + width: 800px; } #quick-format-search { @@ -18,25 +20,24 @@ body[multiline="true"] { } #quick-format-search[multiline="true"] { - padding: 1px 2px 0 18px; + padding: 2px 2px 0 19.5px; + margin: 2.5px 3.5px; border: 1px solid rgba(0, 0, 0, 0.5); - border-radius: 10px; -moz-appearance: none; } #quick-format-search:not([multiline="true"]) { - height: 22px !important; + padding-top: 4.5px; + height: 37px !important; } #quick-format-entry { background: -moz-linear-gradient(-90deg, rgb(243,123,119) 0, rgb(180,47,38) 50%, rgb(156,36,27) 50%); - -moz-border-radius:15px; - border-radius:15px; - padding: 10px; + padding: 12px; } #zotero-icon { - margin: -1px 0 0 -13px; + margin: -2.5px 0 3px -6px; } #quick-format-search[multiline="true"] #zotero-icon { @@ -94,4 +95,8 @@ panel button:hover:active { panel button:-moz-focusring { box-shadow: 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring; +} + +.quick-format-bubble { + padding: 1px 6px 1px 6px; } \ No newline at end of file diff --git a/chrome/content/zotero/browser.js b/chrome/content/zotero/browser.js index 58d4578d7..0770a5ec8 100644 --- a/chrome/content/zotero/browser.js +++ b/chrome/content/zotero/browser.js @@ -52,7 +52,7 @@ var Zotero_Browser = new function() { this.appcontent = null; this.isScraping = false; - var _browserData = new Object(); + var _browserData = new WeakMap(); var _attachmentsMap = new WeakMap(); var _blacklist = [ @@ -154,9 +154,10 @@ var Zotero_Browser = new function() { this.scrapeThisPage = function (translator, event) { // Perform translation var tab = _getTabObject(Zotero_Browser.tabbrowser.selectedBrowser); - if(tab.page.translators && tab.page.translators.length) { - tab.page.translate.setTranslator(translator || tab.page.translators[0]); - Zotero_Browser.performTranslation(tab.page.translate); // TODO: async + var page = tab.getPageObject(); + if(page.translators && page.translators.length) { + page.translate.setTranslator(translator || page.translators[0]); + Zotero_Browser.performTranslation(page.translate); // TODO: async } else { this.saveAsWebPage( @@ -201,7 +202,8 @@ var Zotero_Browser = new function() { // make sure annotation action is toggled var tab = _getTabObject(Zotero_Browser.tabbrowser.selectedBrowser); - if(tab.page && tab.page.annotations && tab.page.annotations.clearAction) tab.page.annotations.clearAction(); + var page = tab.getPageObject(); + if(page && page.annotations && page.annotations.clearAction) page.annotations.clearAction(); if(!toggleTool) return; @@ -225,7 +227,7 @@ var Zotero_Browser = new function() { */ function toggleCollapsed() { var tab = _getTabObject(Zotero_Browser.tabbrowser.selectedBrowser); - tab.page.annotations.toggleCollapsed(); + tab.getPageObject().annotations.toggleCollapsed(); } /* @@ -333,16 +335,19 @@ var Zotero_Browser = new function() { if(annotationID) { if(Zotero.Annotate.isAnnotated(annotationID)) { //window.alert(Zotero.getString("annotations.oneWindowWarning")); - } else if(!tab.page.annotations) { - // enable annotation - tab.page.annotations = new Zotero.Annotations(Zotero_Browser, browser, annotationID); - var saveAnnotations = function() { - tab.page.annotations.save(); - tab.page.annotations = undefined; - }; - browser.contentWindow.addEventListener('beforeunload', saveAnnotations, false); - browser.contentWindow.addEventListener('close', saveAnnotations, false); - tab.page.annotations.load(); + } else { + var page = tab.getPageObject(); + if(!page.annotations) { + // enable annotation + page.annotations = new Zotero.Annotations(Zotero_Browser, browser, annotationID); + var saveAnnotations = function() { + page.annotations.save(); + page.annotations = undefined; + }; + browser.contentWindow.addEventListener('beforeunload', saveAnnotations, false); + browser.contentWindow.addEventListener('close', saveAnnotations, false); + page.annotations.load(); + } } } } @@ -373,8 +378,11 @@ var Zotero_Browser = new function() { var tab = _getTabObject(browser); if(!tab) return; - - if(doc == tab.page.document || doc == rootDoc) { + + var page = tab.getPageObject(); + if(!page) return; + + if(doc == page.document || doc == rootDoc) { // clear translator only if the page on which the pagehide event was called is // either the page to which the translator corresponded, or the root document // (the second check is probably paranoid, but won't hurt) @@ -396,7 +404,7 @@ var Zotero_Browser = new function() { var rootDoc = (doc instanceof HTMLDocument ? doc.defaultView.top.document : doc); var browser = Zotero_Browser.tabbrowser.getBrowserForDocument(rootDoc); var tab = _getTabObject(browser); - if(doc == tab.page.document || doc == rootDoc) tab.clear(); + if(doc == tab.getPageObject().document || doc == rootDoc) tab.clear(); tab.detectTranslators(rootDoc, doc); } catch(e) { Zotero.debug(e); @@ -410,7 +418,8 @@ var Zotero_Browser = new function() { // Save annotations when closing a tab, since the browser is already // gone from tabbrowser by the time contentHide() gets called var tab = _getTabObject(event.target); - if(tab.page && tab.page.annotations) tab.page.annotations.save(); + var page = tab.getPageObject(); + if(page && page.annotations) page.annotations.save(); tab.clear(); // To execute if document object does not exist @@ -423,9 +432,10 @@ var Zotero_Browser = new function() { */ function resize(event) { var tab = _getTabObject(this.tabbrowser.selectedBrowser); - if(!tab.page.annotations) return; + var page = tab.getPageObject(); + if(!page.annotations) return; - tab.page.annotations.refresh(); + page.annotations.refresh(); } /* @@ -460,7 +470,8 @@ var Zotero_Browser = new function() { } // set annotation bar status - if(tab.page.annotations && tab.page.annotations.annotations.length) { + var page = tab.getPageObject(); + if(page.annotations && page.annotations.annotations.length) { document.getElementById('zotero-annotate-tb').hidden = false; toggleMode(); } else { @@ -507,7 +518,7 @@ var Zotero_Browser = new function() { var tab = _getTabObject(this.tabbrowser.selectedBrowser); var captureState = tab.getCaptureState(); if (captureState == tab.CAPTURE_STATE_TRANSLATABLE) { - let translators = tab.page.translators; + let translators = tab.getPageObject().translators; for (var i=0, n = translators.length; i < n; i++) { let translator = translators[i]; @@ -703,10 +714,11 @@ var Zotero_Browser = new function() { function _constructLookupFunction(tab, success) { return function(e) { - tab.page.translate.setTranslator(tab.page.translators[0]); - tab.page.translate.clearHandlers("done"); - tab.page.translate.clearHandlers("itemDone"); - tab.page.translate.setHandler("done", function(obj, status) { + var page = tab.getPageObject(); + page.translate.setTranslator(page.translators[0]); + page.translate.clearHandlers("done"); + page.translate.clearHandlers("itemDone"); + page.translate.setHandler("done", function(obj, status) { if(status) { success(e, obj); Zotero_Browser.progress.close(); @@ -718,7 +730,7 @@ var Zotero_Browser = new function() { Zotero_Browser.progress.show(); Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.lookup.performing")); - tab.page.translate.translate(false); + page.translate.translate(false); e.stopPropagation(); } } @@ -728,10 +740,12 @@ var Zotero_Browser = new function() { */ function _getTabObject(browser) { if(!browser) return false; - if(!browser.zoteroBrowserData) { - browser.zoteroBrowserData = new Zotero_Browser.Tab(browser); + var obj = _browserData.get(browser); + if(!obj) { + obj = new Zotero_Browser.Tab(browser); + _browserData.set(browser, obj); } - return browser.zoteroBrowserData; + return obj; } /** @@ -744,7 +758,7 @@ var Zotero_Browser = new function() { // ignore click if it's on an existing annotation if(e.target.getAttribute("zotero-annotation")) return; - var annotation = tab.page.annotations.createAnnotation(); + var annotation = tab.getPageObject().annotations.createAnnotation(); annotation.initWithEvent(e); // disable add mode, now that we've used it @@ -758,9 +772,9 @@ var Zotero_Browser = new function() { if(selection.isCollapsed) return; if(type == "highlight") { - tab.page.annotations.highlight(selection.getRangeAt(0)); + tab.getPageObject().annotations.highlight(selection.getRangeAt(0)); } else if(type == "unhighlight") { - tab.page.annotations.unhighlight(selection.getRangeAt(0)); + tab.getPageObject().annotations.unhighlight(selection.getRangeAt(0)); } selection.removeAllRanges(); @@ -781,19 +795,33 @@ var Zotero_Browser = new function() { Zotero_Browser.Tab = function(browser) { this.browser = browser; - this.page = new Object(); + this.wm = new WeakMap(); } Zotero_Browser.Tab.prototype.CAPTURE_STATE_DISABLED = 0; Zotero_Browser.Tab.prototype.CAPTURE_STATE_GENERIC = 1; Zotero_Browser.Tab.prototype.CAPTURE_STATE_TRANSLATABLE = 2; +/** + * Gets page-specific information (stored in WeakMap to prevent holding + * a reference to translate) + */ +Zotero_Browser.Tab.prototype.getPageObject = function() { + var doc = this.browser.contentWindow; + if(!doc) return null; + var obj = this.wm.get(doc); + if(!obj) { + obj = {}; + this.wm.set(doc, obj); + } + return obj; +} + /* - * clears page-specific information + * Removes page-specific information from WeakMap */ Zotero_Browser.Tab.prototype.clear = function() { - delete this.page; - this.page = new Object(); + this.wm.delete(this.browser.contentWindow); } /* @@ -874,10 +902,11 @@ Zotero_Browser.Tab.prototype._attemptLocalFileImport = function(doc) { Zotero_Browser.Tab.prototype.getCaptureState = function () { - if (!this.page.saveEnabled) { + var page = this.getPageObject(); + if (!page.saveEnabled) { return this.CAPTURE_STATE_DISABLED; } - if (this.page.translators && this.page.translators.length) { + if (page.translators && page.translators.length) { return this.CAPTURE_STATE_TRANSLATABLE; } return this.CAPTURE_STATE_GENERIC; @@ -892,7 +921,7 @@ Zotero_Browser.Tab.prototype.getCaptureIcon = function (hiDPI) { switch (this.getCaptureState()) { case this.CAPTURE_STATE_TRANSLATABLE: - var itemType = this.page.translators[0].itemType; + var itemType = this.getPageObject().translators[0].itemType; return (itemType === "multiple" ? "chrome://zotero/skin/treesource-collection" + suffix + ".png" : Zotero.ItemTypes.getImageSrc(itemType)); @@ -916,10 +945,11 @@ Zotero_Browser.Tab.prototype.getCaptureTooltip = function() { case this.CAPTURE_STATE_TRANSLATABLE: var text = Zotero.getString('ingester.saveToZotero'); - if (this.page.translators[0].itemType == 'multiple') { + var translator = this.getPageObject().translators[0]; + if (translator.itemType == 'multiple') { text += '…'; } - text += ' (' + this.page.translators[0].label + ')'; + text += ' (' + translator.label + ')'; break; // TODO: Different captions for images, PDFs, etc.? @@ -974,44 +1004,45 @@ Zotero_Browser.Tab.prototype._selectItems = function(obj, itemList, callback) { * called when translators are available */ Zotero_Browser.Tab.prototype._translatorsAvailable = function(translate, translators) { - this.page.saveEnabled = true; + var page = this.getPageObject(); + page.saveEnabled = true; if(translators && translators.length) { //see if we should keep the previous set of translators if(//we already have a translator for part of this page - this.page.translators && this.page.translators.length && this.page.document.location + page.translators && page.translators.length && page.document.location //and the page is still there - && this.page.document.defaultView && !this.page.document.defaultView.closed + && page.document.defaultView && !page.document.defaultView.closed //this set of translators is not targeting the same URL as a previous set of translators, // because otherwise we want to use the newer set, // but only if it's not in a subframe of the previous set - && (this.page.document.location.href != translate.document.location.href || - Zotero.Utilities.Internal.isIframeOf(translate.document.defaultView, this.page.document.defaultView)) + && (page.document.location.href != translate.document.location.href || + Zotero.Utilities.Internal.isIframeOf(translate.document.defaultView, page.document.defaultView)) //the best translator we had was of higher priority than the new set - && (this.page.translators[0].priority < translators[0].priority + && (page.translators[0].priority < translators[0].priority //or the priority was the same, but... - || (this.page.translators[0].priority == translators[0].priority + || (page.translators[0].priority == translators[0].priority //the previous set of translators targets the top frame or the current one does not either - && (this.page.document.defaultView == this.page.document.defaultView.top - || translate.document.defaultView !== this.page.document.defaultView.top) + && (page.document.defaultView == page.document.defaultView.top + || translate.document.defaultView !== page.document.defaultView.top) )) ) { Zotero.debug("Translate: a better translator was already found for this page"); return; //keep what we had } else { this.clear(); //clear URL bar icon - this.page.saveEnabled = true; + page = this.getPageObject(); + page.saveEnabled = true; } Zotero.debug("Translate: found translators for page\n" + "Best translator: " + translators[0].label + " with priority " + translators[0].priority); - - this.page.translate = translate; - this.page.translators = translators; - this.page.document = translate.document; + page.translate = translate; + page.translators = translators; + page.document = translate.document; - this.page.translate.clearHandlers("select"); - this.page.translate.setHandler("select", this._selectItems); + translate.clearHandlers("select"); + translate.setHandler("select", this._selectItems); } else if(translate.type != "import" && translate.document.documentURI.length > 7 && translate.document.documentURI.substr(0, 7) == "file://") { this._attemptLocalFileImport(translate.document); diff --git a/chrome/content/zotero/integration/quickFormat.js b/chrome/content/zotero/integration/quickFormat.js index a455f50ef..ead6a5b3d 100644 --- a/chrome/content/zotero/integration/quickFormat.js +++ b/chrome/content/zotero/integration/quickFormat.js @@ -51,7 +51,9 @@ var Zotero_QuickFormat = new function () { io = window.arguments[0].wrappedJSObject; // Only hide chrome on Windows or Mac - if(Zotero.isMac || Zotero.isWin) { + if(Zotero.isMac) { + document.documentElement.setAttribute("drawintitlebar", true); + } else if(Zotero.isWin) { document.documentElement.setAttribute("hidechrome", true); } @@ -78,7 +80,7 @@ var Zotero_QuickFormat = new function () { var locators = Zotero.Cite.labels; var menu = document.getElementById("locator-label"); var labelList = document.getElementById("locator-label-popup"); - for each(var locator in locators) { + for(var locator of locators) { var locatorLabel = Zotero.getString('citation.locator.'+locator.replace(/\s/g,'')); // add to list of labels @@ -225,7 +227,7 @@ var Zotero_QuickFormat = new function () { var prevNode = node.previousSibling; if(prevNode && prevNode.citationItem && prevNode.citationItem.locator) { prevNode.citationItem.locator += str; - prevNode.value = _buildBubbleString(prevNode.citationItem); + prevNode.textContent = _buildBubbleString(prevNode.citationItem); node.nodeValue = ""; _clearEntryList(); return; @@ -242,7 +244,7 @@ var Zotero_QuickFormat = new function () { var prevNode = node.previousSibling; if(prevNode && prevNode.citationItem) { prevNode.citationItem.locator = m[2]; - prevNode.value = _buildBubbleString(prevNode.citationItem); + prevNode.textContent = _buildBubbleString(prevNode.citationItem); node.nodeValue = ""; _clearEntryList(); return; @@ -265,7 +267,7 @@ var Zotero_QuickFormat = new function () { if(year) str += " "+year; var s = new Zotero.Search(); - str = str.replace(" & ", " ", "g").replace(" and ", " ", "g"); + str = str.replace(/ (?:&|and) /g, " ", "g"); if(charRe.test(str)) { Zotero.debug("QuickFormat: QuickSearch: "+str); s.addCondition("quicksearch-titleCreatorYear", "contains", str); @@ -302,7 +304,7 @@ var Zotero_QuickFormat = new function () { for(var i=0, iCount=citedItems.length; i 30) { qfe.setAttribute("multiline", true); qfs.setAttribute("multiline", true); - qfs.style.height = (4+qfe.scrollHeight)+"px"; + qfs.style.height = ((Zotero.isMac ? 6 : 4)+qfe.scrollHeight)+"px"; window.sizeToContent(); } else { delete qfs.style.height; @@ -784,7 +786,7 @@ var Zotero_QuickFormat = new function () { if(!panelFrameHeight) { panelFrameHeight = referencePanel.boxObject.height - referencePanel.clientHeight; var computedStyle = window.getComputedStyle(referenceBox, null); - for each(var attr in ["border-top-width", "border-bottom-width"]) { + for(var attr of ["border-top-width", "border-bottom-width"]) { var val = computedStyle.getPropertyValue(attr); if(val) { var m = pixelRe.exec(val); @@ -939,7 +941,7 @@ var Zotero_QuickFormat = new function () { if(item.id) { var libraryName = item.libraryID ? Zotero.Libraries.getName(item.libraryID) : Zotero.getString('pane.collections.library'); - panelLibraryLink.textContent = Zotero.getString("integration.openInLibrary", libraryName); + panelLibraryLink.label = Zotero.getString("integration.openInLibrary", libraryName); } target.setAttribute("selected", "true"); @@ -1082,7 +1084,7 @@ var Zotero_QuickFormat = new function () { selection.addRange(nodeRange); } - } else if(keyCode === event.DOM_VK_UP) { + } else if(keyCode === event.DOM_VK_UP && referencePanel.state === "open") { var selectedItem = referenceBox.selectedItem; var previousSibling; @@ -1102,8 +1104,8 @@ var Zotero_QuickFormat = new function () { visibleItem = visibleItem.previousSibling; } referenceBox.ensureElementIsVisible(visibleItem); - event.preventDefault(); }; + event.preventDefault(); } else if(keyCode === event.DOM_VK_DOWN) { if((Zotero.isMac ? event.metaKey : event.ctrlKey)) { // If meta key is held down, show the citation properties panel @@ -1111,7 +1113,7 @@ var Zotero_QuickFormat = new function () { if(bubble) _showCitationProperties(bubble); event.preventDefault(); - } else { + } else if (referencePanel.state === "open") { var selectedItem = referenceBox.selectedItem; var nextSibling; @@ -1124,8 +1126,8 @@ var Zotero_QuickFormat = new function () { if(nextSibling){ referenceBox.selectedItem = nextSibling; referenceBox.ensureElementIsVisible(nextSibling); - event.preventDefault(); }; + event.preventDefault(); } } else { _resetSearchTimer(); @@ -1235,7 +1237,7 @@ var Zotero_QuickFormat = new function () { } else { delete panelRefersToBubble.citationItem["suppress-author"]; } - panelRefersToBubble.value = _buildBubbleString(panelRefersToBubble.citationItem); + panelRefersToBubble.textContent = _buildBubbleString(panelRefersToBubble.citationItem); }; /** diff --git a/chrome/content/zotero/integration/quickFormat.xul b/chrome/content/zotero/integration/quickFormat.xul index 10a45c02b..594663bae 100644 --- a/chrome/content/zotero/integration/quickFormat.xul +++ b/chrome/content/zotero/integration/quickFormat.xul @@ -34,7 +34,6 @@ id="quick-format-dialog" orient="vertical" title="&zotero.integration.quickFormatDialog.title;" - width="600" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" persist="screenX screenY" @@ -61,7 +60,7 @@ oncommand="Zotero_QuickFormat.onClassicViewCommand()"/> -