From ecf0f3397c49e975d98ad98d7a240c9b771a572a Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sun, 30 Jan 2011 09:44:01 +0000 Subject: [PATCH] Zotero as a tab. This may need to be backed out for 2.1 depending on the amount of trouble it generates. --- chrome.manifest | 1 - .../content/zotero-platform/mac/overlay.css | 6 +- chrome/content/zotero/advancedSearch.js | 2 +- chrome/content/zotero/bindings/noteeditor.xml | 2 +- chrome/content/zotero/browser.js | 19 +- chrome/content/zotero/overlay.js | 3563 +---------------- chrome/content/zotero/overlay.xul | 497 +-- .../content/zotero/preferences/preferences.js | 16 + .../zotero/preferences/preferences.xul | 20 +- .../preferences/preferences_firefox.xul | 33 + chrome/content/zotero/standalone.js | 43 + chrome/content/zotero/standalone.xul | 20 +- chrome/content/zotero/tab.js | 67 + chrome/content/zotero/tab.xul | 25 +- chrome/content/zotero/timelineInterface.js | 6 +- chrome/content/zotero/zoteroPane.js | 3425 ++++++++++++++++ chrome/content/zotero/zoteroPane.xul | 440 ++ chrome/locale/en-US/zotero/preferences.dtd | 3 + chrome/skin/default/zotero/overlay.css | 2 - chrome/skin/default/zotero/preferences.css | 4 + .../default/zotero/timeline/timeline.html | 6 +- .../zotero/toolbar-fullscreen-bottom.png | Bin 581 -> 552 bytes components/zotero-protocol-handler.js | 28 +- defaults/preferences/zotero.js | 1 + 24 files changed, 4275 insertions(+), 3954 deletions(-) create mode 100644 chrome/content/zotero/standalone.js create mode 100644 chrome/content/zotero/tab.js create mode 100644 chrome/content/zotero/zoteroPane.js create mode 100644 chrome/content/zotero/zoteroPane.xul diff --git a/chrome.manifest b/chrome.manifest index 04f278924..13031394f 100644 --- a/chrome.manifest +++ b/chrome.manifest @@ -46,7 +46,6 @@ skin zotero default chrome/skin/default/zotero/ overlay chrome://browser/content/browser.xul chrome://zotero/content/statusBarOverlay.xul appversion<4.0 overlay chrome://browser/content/browser.xul chrome://zotero/content/overlay.xul -overlay chrome://browser/content/browser.xul chrome://zotero/content/itemPane.xul overlay chrome://zotero/content/preferences/preferences.xul chrome://zotero/content/preferences/preferences_firefox.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} overlay chrome://zotero/content/preferences/preferences.xul#cite chrome://zotero/content/preferences/preferences_firefox.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} diff --git a/chrome/content/zotero-platform/mac/overlay.css b/chrome/content/zotero-platform/mac/overlay.css index 9517aa6e7..dd9653a47 100644 --- a/chrome/content/zotero-platform/mac/overlay.css +++ b/chrome/content/zotero-platform/mac/overlay.css @@ -36,8 +36,7 @@ } .zotero-tb-button[open="true"], -.zotero-tb-button:hover:active, -#zotero-pane-stack[fullscreenmode="true"] #zotero-tb-fullscreen { +.zotero-tb-button:hover:active { background: url("chrome://zotero/skin/mac/menubutton-end-pressed.png") right center no-repeat; } @@ -63,8 +62,7 @@ } .zotero-tb-button[open="true"] > .toolbarbutton-icon, -.zotero-tb-button:hover:active > .toolbarbutton-icon, -#zotero-pane-stack[fullscreenmode="true"] #zotero-tb-fullscreen > .toolbarbutton-icon { +.zotero-tb-button:hover:active > .toolbarbutton-icon { background: url("chrome://zotero/skin/mac/menubutton-start-pressed.png") left center no-repeat; } diff --git a/chrome/content/zotero/advancedSearch.js b/chrome/content/zotero/advancedSearch.js index 52d567f9a..7553e333e 100644 --- a/chrome/content/zotero/advancedSearch.js +++ b/chrome/content/zotero/advancedSearch.js @@ -153,7 +153,7 @@ var ZoteroAdvancedSearch = new function() { } if (lastWin.document.getElementById('zotero-pane').getAttribute('hidden') == 'true') { - lastWin.ZoteroPane.toggleDisplay(); + lastWin.ZoteroOverlay.toggleDisplay(); } lastWin.ZoteroPane.selectItem(item.getID(), false, true); diff --git a/chrome/content/zotero/bindings/noteeditor.xml b/chrome/content/zotero/bindings/noteeditor.xml index 4f6e37d5e..c9f37bd0f 100644 --- a/chrome/content/zotero/bindings/noteeditor.xml +++ b/chrome/content/zotero/bindings/noteeditor.xml @@ -318,7 +318,7 @@ } if (lastWin.document.getElementById('zotero-pane').getAttribute('hidden') == 'true') { - lastWin.ZoteroPane.toggleDisplay(); + lastWin.ZoteroOverlay.toggleDisplay(); // DEBUG: The actions below seem to crash Firefox 2.0.0.1 on OS X if // the Z pane isn't already open, so we don't try diff --git a/chrome/content/zotero/browser.js b/chrome/content/zotero/browser.js index 64066e5be..a62252de7 100644 --- a/chrome/content/zotero/browser.js +++ b/chrome/content/zotero/browser.js @@ -122,13 +122,10 @@ var Zotero_Browser = new function() { } /** - * Scrapes a page (called when the capture icon is clicked) - * - * @param {Integer} libraryID - * @param {Integer} collectionID + * Scrapes a page (called when the capture icon is clicked * @return void */ - function scrapeThisPage(libraryID, collectionID) { + function scrapeThisPage(/*libraryID, collectionID*/) { if (Zotero.locked) { Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError")); var desc = Zotero.localeJoin([ @@ -151,6 +148,18 @@ var Zotero_Browser = new function() { Zotero_Browser.progress.startCloseTimer(8000); return; } + + // get libraryID and collectionID + var libraryID, collectionID; + var pane = ZoteroOverlay.getActiveZoteroPane(); + if(pane) { + libraryID = ZoteroPane.getSelectedLibraryID(); + collectionID = ZoteroPane.getSelectedCollection(true); + } else { + libraryID = collectionID = null; + } + + // translate into specified library and collection _getTabObject(this.tabbrowser.selectedBrowser).translate(libraryID, collectionID); } diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js index 150e6c15f..2d3956735 100644 --- a/chrome/content/zotero/overlay.js +++ b/chrome/content/zotero/overlay.js @@ -26,350 +26,94 @@ /* * This object contains the various functions for the interface */ -var ZoteroPane = new function() +var ZoteroOverlay = new function() { - this.collectionsView = false; - this.itemsView = false; - this.__defineGetter__('loaded', function () _loaded); - - //Privileged methods - this.onLoad = onLoad; - this.onUnload = onUnload; - this.toggleDisplay = toggleDisplay; - this.isShowing = isShowing; - this.fullScreen = fullScreen; - this.isFullScreen = isFullScreen; - this.handleKeyDown = handleKeyDown; - this.handleKeyUp = handleKeyUp; - this.setHighlightedRowsCallback = setHighlightedRowsCallback; - this.handleKeyPress = handleKeyPress; - this.newItem = newItem; - this.newCollection = newCollection; - this.newSearch = newSearch; - this.openAdvancedSearchWindow = openAdvancedSearchWindow; - this.toggleTagSelector = toggleTagSelector; - this.updateTagSelectorSize = updateTagSelectorSize; - this.getTagSelection = getTagSelection; - this.clearTagSelection = clearTagSelection; - this.updateTagFilter = updateTagFilter; - this.onCollectionSelected = onCollectionSelected; - this.itemSelected = itemSelected; - this.reindexItem = reindexItem; - this.duplicateSelectedItem = duplicateSelectedItem; - this.deleteSelectedCollection = deleteSelectedCollection; - this.editSelectedCollection = editSelectedCollection; - this.copySelectedItemsToClipboard = copySelectedItemsToClipboard; - this.clearQuicksearch = clearQuicksearch; - this.handleSearchKeypress = handleSearchKeypress; - this.handleSearchInput = handleSearchInput; - this.search = search; - this.selectItem = selectItem; - this.getSelectedCollection = getSelectedCollection; - this.getSelectedSavedSearch = getSelectedSavedSearch; - this.getSelectedItems = getSelectedItems; - this.getSortedItems = getSortedItems; - this.getSortField = getSortField; - this.getSortDirection = getSortDirection; - this.buildItemContextMenu = buildItemContextMenu; - this.loadURI = loadURI; - this.setItemsPaneMessage = setItemsPaneMessage; - this.clearItemsPaneMessage = clearItemsPaneMessage; - this.contextPopupShowing = contextPopupShowing; - this.openNoteWindow = openNoteWindow; - this.addTextToNote = addTextToNote; - this.addAttachmentFromDialog = addAttachmentFromDialog; - this.viewAttachment = viewAttachment; - this.viewSelectedAttachment = viewSelectedAttachment; - this.showAttachmentNotFoundDialog = showAttachmentNotFoundDialog; - this.relinkAttachment = relinkAttachment; - this.reportErrors = reportErrors; - this.displayErrorMessage = displayErrorMessage; - + const ZOTERO_TAB_URL = "chrome://zotero/content/tab.xul"; const DEFAULT_ZPANE_HEIGHT = 300; - const COLLECTIONS_HEIGHT = 32; // minimum height of the collections pane and toolbar + var toolbarCollapseState, isFx36, showInPref; - var self = this; - var _loaded = false; - var _isStandaloneOrTab = false; - var titlebarcolorState, toolbarCollapseState, titleState; + this.isTab = false; - // Also needs to be changed in collectionTreeView.js - var _lastViewedFolderRE = /^(?:(C|S|G)([0-9]+)|L)$/; - - /* - * Called when the window is open - */ - function onLoad() - { - _isStandaloneOrTab = Zotero.isStandalone || document.getElementById('zotero-tab'); + this.onLoad = function() { + var appInfo = Components.classes["@mozilla.org/xre/app-info;1"] + .getService(Components.interfaces.nsIXULAppInfo); + isFx36 = appInfo.platformVersion.indexOf('1.9') === 0; - if (!Zotero) return; - if (!Zotero.initialized) { - if(_isStandaloneOrTab) { - _loaded = true; - this.toggleDisplay(); - } - return; - } - - if (Zotero.locked) { - return; - } - _loaded = true; - - Zotero.setFontSize(document.getElementById('zotero-pane')) - - if (Zotero.isMac) { - //document.getElementById('zotero-tb-actions-zeroconf-update').setAttribute('hidden', false); - document.getElementById('zotero-pane-stack').setAttribute('platform', 'mac'); - } else if(Zotero.isWin) { - document.getElementById('zotero-pane-stack').setAttribute('platform', 'win'); - } - - if(Zotero.isFx4) { - // hack, since Fx 4 no longer sets active, and the reverse in polarity of the preferred - // property makes things painful to handle otherwise - // DEBUG: remove this once we only support Fx 4 - document.documentElement.setAttribute("active", "true"); - window.addEventListener("focus", - function() { document.documentElement.setAttribute("active", "true") }, false); - window.addEventListener("blur", - function() { document.documentElement.removeAttribute("active") }, false); - } - - //Initialize collections view - this.collectionsView = new Zotero.CollectionTreeView(); - var collectionsTree = document.getElementById('zotero-collections-tree'); - collectionsTree.view = this.collectionsView; - collectionsTree.controllers.appendController(new Zotero.CollectionTreeCommandController(collectionsTree)); - collectionsTree.addEventListener("click", ZoteroPane.onTreeClick, true); - - var itemsTree = document.getElementById('zotero-items-tree'); - itemsTree.controllers.appendController(new Zotero.ItemTreeCommandController(itemsTree)); - itemsTree.addEventListener("click", ZoteroPane.onTreeClick, true); - - this.buildItemTypeMenus(); - - var menu = document.getElementById("contentAreaContextMenu"); - menu.addEventListener("popupshowing", ZoteroPane.contextPopupShowing, false); - - Zotero.Keys.windowInit(document); - - if (Zotero.restoreFromServer) { - Zotero.restoreFromServer = false; - - setTimeout(function () { - var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] - .getService(Components.interfaces.nsIPromptService); - var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING) - + (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL); - var index = ps.confirmEx( - null, - "Zotero Restore", - "The local Zotero database has been cleared." - + " " - + "Would you like to restore from the Zotero server now?", - buttonFlags, - "Sync Now", - null, null, null, {} - ); - - if (index == 0) { - Zotero.Sync.Server.sync({ - onSuccess: function () { - Zotero.Sync.Runner.setSyncIcon(); - - ps.alert( - null, - "Restore Completed", - "The local Zotero database has been successfully restored." - ); - }, - - onError: function (msg) { - ps.alert( - null, - "Restore Failed", - "An error occurred while restoring from the server:\n\n" - + msg - ); - - Zotero.Sync.Runner.error(msg); - } - }); + // Open Zotero app tab, if in Fx 4 and requested by pref + showInPref = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefService) + .getBranch('extensions.zotero.').getIntPref('showIn'); + this.isTab = showInPref === 2; + if(!isFx36) { + var observerService = Components.classes["@mozilla.org/observer-service;1"] + .getService(Components.interfaces.nsIObserverService); + var zoteroObserver = {"observe":function(subject, topic, data) { + if(subject != window) return; + observerService.removeObserver(this, "browser-delayed-startup-finished"); + Zotero.wait(1000); // there ought to be a better way to determine when the tab + // will have a reasonable URI instead of returning about:blank, + // but I'm not sure what it is + if(showInPref === 2) { + var tabbar = document.getElementById("TabsToolbar"); + if(tabbar && window.getComputedStyle(tabbar).display !== "none") { + // load Zotero as a tab, if it isn't loading by default + ZoteroOverlay.loadZoteroTab(true); + } + } else { + // close Zotero as a tab, in case it was pinned + var zoteroTab = ZoteroOverlay.findZoteroTab(); + if(zoteroTab) gBrowser.removeTab(zoteroTab); } - }, 1000); - } - // If the database was initialized or there are no sync credentials and - // Zotero hasn't been run before in this profile, display the start page - // -- this way the page won't be displayed when they sync their DB to - // another profile or if the DB is initialized erroneously (e.g. while - // switching data directory locations) - else if (Zotero.Prefs.get('firstRun2')) { - if (Zotero.Schema.dbInitialized || !Zotero.Sync.Server.enabled) { - setTimeout(function () { - var url = "http://zotero.org/start"; - gBrowser.selectedTab = gBrowser.addTab(url); - }, 400); - } - Zotero.Prefs.set('firstRun2', false); - try { - Zotero.Prefs.clear('firstRun'); - } - catch (e) {} + }}; + + observerService.addObserver(zoteroObserver, "browser-delayed-startup-finished", false); } - // Hide sync debugging menu by default - if (Zotero.Prefs.get('sync.debugMenu')) { - var sep = document.getElementById('zotero-tb-actions-sync-separator'); - sep.hidden = false; - sep.nextSibling.hidden = false; - sep.nextSibling.nextSibling.hidden = false; - sep.nextSibling.nextSibling.nextSibling.hidden = false; - } + // Make Zotero icon visible, if requested + var iconPref = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefService) + .getBranch('extensions.zotero.').getIntPref('statusBarIcon'); - if (Zotero.Prefs.get('debugShowDuplicates')) { - document.getElementById('zotero-tb-actions-showDuplicates').hidden = false; - } + var fx36Icon = document.getElementById('zotero-status-bar-icon'); + var addonBar = document.getElementById('addon-bar'); - if(_isStandaloneOrTab) { - this.toggleDisplay(true); - this.fullScreen(true); - } else { - // Hide browser chrome on Zotero tab - if(Zotero.isFx4) { - XULBrowserWindow.inContentWhitelist.push("chrome://zotero/content/tab.xul"); + // Status bar in Fx3.6 + if (isFx36) { + var icon = fx36Icon; + } + // In >=Fx4, add to add-on bar + else { + // add Zotero icon + var icon = document.createElement('toolbarbutton'); + icon.id = 'zotero-addon-bar-icon'; + icon.setAttribute('oncommand', 'ZoteroOverlay.toggleDisplay()'); + icon.setAttribute('hidden', true); + addonBar.appendChild(icon); + if (addonBar.collapsed) { + // If no Zotero or icon isn't set to hidden, show add-on bar + if (iconPref != 0) { + setToolbarVisibility(addonBar, true); + } } } - } - - - this.buildItemTypeMenus = function () { - // - // Create the New Item (+) menu with each item type - // - var addMenu = document.getElementById('zotero-tb-add').firstChild; - var moreMenu = document.getElementById('zotero-tb-add-more'); - // Remove all nodes, in case we're reloading - var options = addMenu.getElementsByAttribute("class", "zotero-tb-add"); - while (options.length) { - var p = options[0].parentNode; - p.removeChild(options[0]); - } - - var separator = addMenu.firstChild; - - // Sort by localized name - var t = Zotero.ItemTypes.getPrimaryTypes(); - var itemTypes = []; - for (var i=0; i