e537018e71
Not working: - Web tests (hidden browser is broken) - Test Updated status text - Various platform menu things (code copied from ZP and will use whichever approach we settle on there)
959 lines
No EOL
28 KiB
JavaScript
959 lines
No EOL
28 KiB
JavaScript
/*
|
|
***** BEGIN LICENSE BLOCK *****
|
|
|
|
Copyright © 2009 Center for History and New Media
|
|
George Mason University, Fairfax, Virginia, USA
|
|
http://zotero.org
|
|
|
|
This file is part of Zotero.
|
|
|
|
Zotero is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Zotero is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
***** END LICENSE BLOCK *****
|
|
*/
|
|
|
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
|
|
|
/**
|
|
* This object contains the various functions for the interface
|
|
*/
|
|
const ZoteroStandalone = new function() {
|
|
const FONT_SIZES = ["1.0", "1.15", "1.3", "1.5", "1.7", "1.9", "2.1"];
|
|
//const NOTE_FONT_SIZES = ["11", "12", "13", "14", "18", "24", "36", "48", "64", "72", "96"];
|
|
const NOTE_FONT_SIZE_DEFAULT = "12";
|
|
|
|
/**
|
|
* Run when standalone window first opens
|
|
*/
|
|
this.onLoad = function() {
|
|
// Fix window without menubar/titlebar when Zotero is closed in full-screen mode in OS X 10.11+
|
|
if (Zotero.isMac && window.document.documentElement.getAttribute('sizemode') == 'fullscreen') {
|
|
window.document.documentElement.setAttribute('sizemode', 'normal');
|
|
}
|
|
|
|
if (Zotero.isMac) {
|
|
// Create tab bar by default
|
|
document.documentElement.setAttribute('drawintitlebar', true);
|
|
document.documentElement.setAttribute('tabsintitlebar', true);
|
|
document.documentElement.setAttribute('chromemargin', '0,-1,-1,-1');
|
|
}
|
|
|
|
this.switchMenuType('library');
|
|
this._notifierID = Zotero.Notifier.registerObserver(
|
|
{
|
|
notify: async (action, type, ids, extraData) => {
|
|
if (action == 'select') {
|
|
// Reader doesn't have tabID yet
|
|
setTimeout(async () => {
|
|
// Item and other things might not be loaded yet when reopening tabs
|
|
await Zotero.Schema.schemaUpdatePromise;
|
|
this.updateQuickCopyOptions();
|
|
}, 0);
|
|
// "library" or "reader"
|
|
this.switchMenuType(extraData[ids[0]].type);
|
|
setTimeout(() => ZoteroPane.updateToolbarPosition(), 0);
|
|
}
|
|
}
|
|
},
|
|
['tab'],
|
|
'tab'
|
|
);
|
|
|
|
Zotero.Promise.try(function () {
|
|
if(!Zotero) {
|
|
throw true;
|
|
}
|
|
if(Zotero.initializationPromise.isPending()) {
|
|
Zotero.showZoteroPaneProgressMeter();
|
|
}
|
|
return Zotero.initializationPromise;
|
|
})
|
|
.then(async function () {
|
|
document.getElementById('key_copyCitation')
|
|
.setAttribute('key', Zotero.Keys.getKeyForCommand('copySelectedItemCitationsToClipboard'));
|
|
document.getElementById('key_copyBibliography')
|
|
.setAttribute('key', Zotero.Keys.getKeyForCommand('copySelectedItemsToClipboard'));
|
|
|
|
ZoteroStandalone.DebugOutput.init();
|
|
|
|
Zotero.hideZoteroPaneOverlays();
|
|
ZoteroPane.init();
|
|
ZoteroPane.makeVisible();
|
|
|
|
// Don't ask before handing http and https URIs
|
|
var eps = Components.classes['@mozilla.org/uriloader/external-protocol-service;1']
|
|
.getService(Components.interfaces.nsIExternalProtocolService);
|
|
var hs = Components.classes["@mozilla.org/uriloader/handler-service;1"]
|
|
.getService(Components.interfaces.nsIHandlerService);
|
|
for (let scheme of ["http", "https"]) {
|
|
var handlerInfo = eps.getProtocolHandlerInfo(scheme);
|
|
handlerInfo.preferredAction = Components.interfaces.nsIHandlerInfo.useSystemDefault;
|
|
handlerInfo.alwaysAskBeforeHandling = false;
|
|
hs.store(handlerInfo);
|
|
}
|
|
|
|
// Add add-on listeners (not yet hooked up)
|
|
Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false);
|
|
Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false);
|
|
Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
|
|
Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
|
|
Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
|
|
})
|
|
.catch(function (e) {
|
|
try { Zotero.debug(e, 1); } catch (e) {}
|
|
Components.utils.reportError(e);
|
|
ZoteroPane.displayStartupError();
|
|
window.close();
|
|
return;
|
|
});
|
|
|
|
// Switch to library tab if dragging over one or more PDF files
|
|
window.addEventListener('dragover', function (event) {
|
|
// TODO: Consider allowing more (or all) file types, although shouldn't interfere with image dragging to note editor
|
|
if (Zotero_Tabs.selectedID != 'zotero-pane'
|
|
&& event.dataTransfer.items
|
|
&& event.dataTransfer.items.length
|
|
&& !Array.from(event.dataTransfer.items).find(x => x.type != 'application/pdf')) {
|
|
Zotero_Tabs.select('zotero-pane');
|
|
}
|
|
}, true);
|
|
}
|
|
|
|
this.switchMenuType = function (type) {
|
|
document.querySelectorAll('.menu-type-library, .menu-type-reader').forEach(el => el.hidden = true);
|
|
document.querySelectorAll('.menu-type-' + type).forEach(el => el.hidden = false);
|
|
};
|
|
|
|
this.onReaderCmd = function (cmd) {
|
|
let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
|
reader.menuCmd(cmd);
|
|
};
|
|
|
|
this.onFileMenuOpen = function () {
|
|
var active = false;
|
|
try {
|
|
let zp = Zotero.getActiveZoteroPane();
|
|
if (zp) {
|
|
active = !!zp.getSelectedItems().filter((item) => {
|
|
return item.isAttachment()
|
|
|| (item.isRegularItem() && item.getAttachments().length);
|
|
}).length;
|
|
}
|
|
}
|
|
catch (e) {}
|
|
this.updateMenuItemEnabled('manage-attachments-menu', active);
|
|
|
|
// PDF annotation transfer ("Import Annotation"/"Store Annotations in File")
|
|
let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
|
if (reader) {
|
|
let item = Zotero.Items.get(reader.itemID);
|
|
let library = Zotero.Libraries.get(item.libraryID);
|
|
if (item
|
|
// Don't allow annotation transfer in group libraries
|
|
&& library.libraryType == 'user'
|
|
&& library.editable
|
|
&& !(item.deleted || item.parentItem && item.parentItem.deleted)) {
|
|
let annotations = item.getAnnotations();
|
|
let canTransferFromPDF = annotations.find(x => x.annotationIsExternal);
|
|
this.updateMenuItemEnabled('menu_transferFromPDF', canTransferFromPDF);
|
|
}
|
|
else {
|
|
this.updateMenuItemEnabled('menu_transferFromPDF', false);
|
|
}
|
|
}
|
|
|
|
// TEMP: Quick implementation
|
|
try {
|
|
let menuitem = document.getElementById('menu_export_files');
|
|
let sep = menuitem.nextSibling;
|
|
|
|
let zp = Zotero.getActiveZoteroPane();
|
|
if (zp && !reader) {
|
|
let numFiles = zp.getSelectedItems().reduce((num, item) => {
|
|
if (item.isPDFAttachment()) {
|
|
return num + 1;
|
|
}
|
|
if (item.isRegularItem()) {
|
|
return num + item.numPDFAttachments();
|
|
}
|
|
return num;
|
|
}, 0);
|
|
if (numFiles) {
|
|
menuitem.hidden = false;
|
|
sep.hidden = false;
|
|
if (numFiles == 1) {
|
|
menuitem.label = 'Export PDF…';
|
|
}
|
|
else {
|
|
menuitem.label = 'Export PDFs…';
|
|
}
|
|
}
|
|
else {
|
|
menuitem.hidden = true;
|
|
sep.hidden = true;
|
|
}
|
|
}
|
|
else {
|
|
menuitem.hidden = true;
|
|
sep.hidden = true;
|
|
}
|
|
}
|
|
catch (e) {
|
|
Zotero.logError(e);
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Builds new item menu
|
|
*/
|
|
this.buildNewItemMenu = function() {
|
|
var addMenu = document.getElementById('menu_NewItemPopup');
|
|
|
|
// Remove all nodes so we can regenerate
|
|
while(addMenu.hasChildNodes()) addMenu.removeChild(addMenu.firstChild);
|
|
|
|
var typeSets = [Zotero.ItemTypes.getPrimaryTypes(), Zotero.ItemTypes.getSecondaryTypes()];
|
|
for(var j=0; j<typeSets.length; j++) {
|
|
var t = typeSets[j];
|
|
|
|
// Sort by localized name
|
|
var itemTypes = [];
|
|
for (var i=0; i<t.length; i++) {
|
|
itemTypes.push({
|
|
id: t[i].id,
|
|
name: t[i].name,
|
|
localized: Zotero.ItemTypes.getLocalizedString(t[i].id)
|
|
});
|
|
}
|
|
var collation = Zotero.getLocaleCollation();
|
|
itemTypes.sort(function(a, b) {
|
|
return collation.compareString(1, a.localized, b.localized);
|
|
});
|
|
|
|
for (var i = 0; i<itemTypes.length; i++) {
|
|
var menuitem = document.createXULElement("menuitem");
|
|
menuitem.setAttribute("label", itemTypes[i].localized);
|
|
menuitem.setAttribute("tooltiptext", "");
|
|
let type = itemTypes[i].id;
|
|
menuitem.addEventListener("command", function() {
|
|
ZoteroPane_Local.newItem(type, null, null, true);
|
|
}, false);
|
|
menuitem.className = "zotero-tb-add";
|
|
addMenu.appendChild(menuitem);
|
|
}
|
|
|
|
// add separator between sets
|
|
if(j !== typeSets.length-1) {
|
|
addMenu.appendChild(document.createXULElement("menuseparator"));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
this.onManageAttachmentsMenuOpen = function () {
|
|
// Convert Linked Files to Stored Files
|
|
var active = false;
|
|
try {
|
|
let zp = Zotero.getActiveZoteroPane();
|
|
if (zp) {
|
|
active = !!zp.getSelectedItems().filter((item) => {
|
|
return item.isLinkedFileAttachment()
|
|
|| (item.isRegularItem()
|
|
&& item.getAttachments()
|
|
.map(id => Zotero.Items.get(id))
|
|
.some(att => att.isLinkedFileAttachment()));
|
|
}).length;
|
|
}
|
|
}
|
|
catch (e) {}
|
|
this.updateMenuItemEnabled('file-menuitem-convert-to-stored', active);
|
|
};
|
|
|
|
|
|
this.onManageAttachmentsMenuItemClick = function (event) {
|
|
var menuitem = event.originalTarget;
|
|
var id = menuitem.id;
|
|
var prefix = 'file-menuitem-';
|
|
if (menuitem.disabled || !id.startsWith(prefix)) {
|
|
return;
|
|
}
|
|
id = id.substr(prefix.length);
|
|
|
|
switch (id) {
|
|
case 'convert-to-stored':
|
|
ZoteroPane.convertLinkedFilesToStoredFiles();
|
|
break;
|
|
}
|
|
};
|
|
|
|
|
|
this.updateQuickCopyOptions = function () {
|
|
var selected = [];
|
|
|
|
let win = Zotero.getMainWindow();
|
|
if (win) {
|
|
if (win.Zotero_Tabs.selectedID == 'zotero-pane') {
|
|
try {
|
|
selected = win.ZoteroPane.getSelectedItems();
|
|
}
|
|
catch (e) {
|
|
}
|
|
win.ZoteroPane.updateQuickCopyCommands(selected);
|
|
}
|
|
else {
|
|
let reader = Zotero.Reader.getByTabID(win.Zotero_Tabs.selectedID);
|
|
if (reader) {
|
|
let item = Zotero.Items.get(reader.itemID);
|
|
selected = item.parentItem && [item.parentItem] || [];
|
|
item = item.parentItem || item;
|
|
win.ZoteroPane.updateQuickCopyCommands([item]);
|
|
}
|
|
}
|
|
}
|
|
|
|
var format = Zotero.QuickCopy.getFormatFromURL(Zotero.QuickCopy.lastActiveURL);
|
|
var exportingNotes = selected.every(item => item.isNote() || item.isAttachment());
|
|
if (exportingNotes) {
|
|
format = Zotero.QuickCopy.getNoteFormat();
|
|
}
|
|
format = Zotero.QuickCopy.unserializeSetting(format);
|
|
|
|
var copyCitation = document.getElementById('menu_copyCitation');
|
|
var copyBibliography = document.getElementById('menu_copyBibliography');
|
|
var copyExport = document.getElementById('menu_copyExport');
|
|
var copyNote = document.getElementById('menu_copyNote');
|
|
|
|
copyCitation.hidden = !selected.length || format.mode != 'bibliography';
|
|
copyBibliography.hidden = !selected.length || format.mode != 'bibliography';
|
|
copyExport.hidden = !selected.length || format.mode != 'export' || exportingNotes;
|
|
copyNote.hidden = !selected.length || format.mode != 'export' || !exportingNotes;
|
|
if (format.mode == 'export') {
|
|
try {
|
|
let obj = Zotero.Translators.get(format.id);
|
|
if (obj) {
|
|
copyExport.label = Zotero.getString('quickCopy.copyAs', obj.label);
|
|
}
|
|
else {
|
|
copyExport.hidden = true;
|
|
}
|
|
}
|
|
catch (e) {
|
|
if (!(e instanceof Zotero.Exception.UnloadedDataException && e.dataType == 'translators')) {
|
|
Zotero.logError(e);
|
|
}
|
|
copyExport.hidden = true;
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
this.onGoMenuOpen = function () {
|
|
var keyBack = document.getElementById('key_back');
|
|
var keyForward = document.getElementById('key_forward');
|
|
|
|
if (Zotero.isMac) {
|
|
keyBack.setAttribute('key', '[');
|
|
keyBack.setAttribute('modifiers', 'meta');
|
|
keyForward.setAttribute('key', ']');
|
|
keyForward.setAttribute('modifiers', 'meta');
|
|
}
|
|
else {
|
|
keyBack.setAttribute('keycode', 'VK_LEFT');
|
|
keyBack.setAttribute('modifiers', 'alt');
|
|
keyForward.setAttribute('keycode', 'VK_RIGHT');
|
|
keyForward.setAttribute('modifiers', 'alt');
|
|
}
|
|
|
|
// `key` attribute needs to be dynamically set for `menuitem` when
|
|
// the key changes after DOM initialization
|
|
var menuItemBack = document.getElementById('go-menuitem-back');
|
|
var menuItemForward = document.getElementById('go-menuitem-forward');
|
|
menuItemBack.setAttribute('key', 'key_back');
|
|
menuItemForward.setAttribute('key', 'key_forward');
|
|
|
|
var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
|
if (reader) {
|
|
this.updateMenuItemEnabled('go-menuitem-first-page', reader.allowNavigateFirstPage());
|
|
this.updateMenuItemEnabled('go-menuitem-last-page', reader.allowNavigateLastPage());
|
|
this.updateMenuItemEnabled('go-menuitem-back', reader.allowNavigateBack());
|
|
this.updateMenuItemEnabled('go-menuitem-forward', reader.allowNavigateForward());
|
|
}
|
|
};
|
|
|
|
|
|
this.onViewMenuOpen = function () {
|
|
// PDF Reader
|
|
var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
|
if (reader) {
|
|
var { state } = reader;
|
|
this.updateMenuItemCheckmark('view-menuitem-vertical-scrolling', state.scrollMode == 0);
|
|
this.updateMenuItemCheckmark('view-menuitem-horizontal-scrolling', state.scrollMode == 1);
|
|
this.updateMenuItemCheckmark('view-menuitem-wrapped-scrolling', state.scrollMode == 2);
|
|
this.updateMenuItemCheckmark('view-menuitem-no-spreads', state.spreadMode == 0);
|
|
this.updateMenuItemCheckmark('view-menuitem-odd-spreads', state.spreadMode == 1);
|
|
this.updateMenuItemCheckmark('view-menuitem-even-spreads', state.spreadMode == 2);
|
|
this.updateMenuItemCheckmark('view-menuitem-hand-tool', reader.isHandToolActive());
|
|
this.updateMenuItemCheckmark('view-menuitem-zoom-auto', reader.isZoomAutoActive());
|
|
this.updateMenuItemCheckmark('view-menuitem-zoom-page-width', reader.isZoomPageWidthActive());
|
|
this.updateMenuItemCheckmark('view-menuitem-zoom-page-height', reader.isZoomPageHeightActive());
|
|
}
|
|
|
|
// Layout mode
|
|
var mode = Zotero.Prefs.get('layout');
|
|
this.updateMenuItemCheckmark('view-menuitem-standard', mode != 'stacked');
|
|
this.updateMenuItemCheckmark('view-menuitem-stacked', mode == 'stacked');
|
|
|
|
// Panes
|
|
this.updateMenuItemCheckmark(
|
|
'view-menuitem-collections-pane',
|
|
document.getElementById('zotero-collections-pane').getAttribute('collapsed') != 'true'
|
|
);
|
|
this.updateMenuItemCheckmark(
|
|
'view-menuitem-item-pane',
|
|
document.getElementById('zotero-item-pane').getAttribute('collapsed') != 'true'
|
|
);
|
|
this.updateMenuItemCheckmark(
|
|
'view-menuitem-tag-selector',
|
|
document.getElementById('zotero-tag-selector-container').getAttribute('collapsed') != 'true'
|
|
);
|
|
|
|
// Font size
|
|
var fontSize = Zotero.Prefs.get('fontSize');
|
|
this.updateMenuItemEnabled('view-menuitem-font-size-bigger', fontSize < FONT_SIZES[FONT_SIZES.length - 1]);
|
|
this.updateMenuItemEnabled('view-menuitem-font-size-smaller', fontSize > FONT_SIZES[0]);
|
|
this.updateMenuItemEnabled('view-menuitem-font-size-reset', fontSize != FONT_SIZES[0]);
|
|
|
|
var noteFontSize = Zotero.Prefs.get('note.fontSize');
|
|
for (let menuitem of document.querySelectorAll(`#note-font-size-menu menuitem`)) {
|
|
if (parseInt(menuitem.getAttribute('label')) == noteFontSize) {
|
|
menuitem.setAttribute('checked', true);
|
|
}
|
|
else {
|
|
menuitem.removeAttribute('checked');
|
|
}
|
|
}
|
|
this.updateMenuItemEnabled(
|
|
'view-menuitem-note-font-size-reset',
|
|
noteFontSize != NOTE_FONT_SIZE_DEFAULT
|
|
);
|
|
|
|
// Recursive collections
|
|
this.updateMenuItemCheckmark(
|
|
'view-menuitem-recursive-collections',
|
|
Zotero.Prefs.get('recursiveCollections')
|
|
);
|
|
};
|
|
|
|
|
|
this.onViewMenuItemClick = function (event) {
|
|
var menuitem = event.originalTarget;
|
|
var id = menuitem.id;
|
|
var prefix = 'view-menuitem-';
|
|
if (menuitem.disabled || !id.startsWith(prefix)) {
|
|
return;
|
|
}
|
|
id = id.substr(prefix.length);
|
|
|
|
switch (id) {
|
|
case 'standard':
|
|
Zotero.Prefs.set('layout', 'standard');
|
|
break;
|
|
|
|
case 'stacked':
|
|
Zotero.Prefs.set('layout', 'stacked');
|
|
break;
|
|
|
|
case 'collections-pane':
|
|
var collectionsPane = document.getElementById('zotero-collections-pane');
|
|
// Show
|
|
if (collectionsPane.getAttribute('collapsed') == 'true') {
|
|
document.getElementById('zotero-collections-splitter').setAttribute('state', 'open');
|
|
collectionsPane.setAttribute('collapsed', false);
|
|
}
|
|
// Hide
|
|
else {
|
|
document.getElementById('zotero-collections-splitter').setAttribute('state', 'collapsed');
|
|
collectionsPane.setAttribute('collapsed', true);
|
|
}
|
|
ZoteroPane.updateToolbarPosition();
|
|
break;
|
|
|
|
case 'item-pane':
|
|
var itemPane = document.getElementById('zotero-item-pane');
|
|
// Show
|
|
if (itemPane.getAttribute('collapsed') == 'true') {
|
|
document.getElementById('zotero-items-splitter').setAttribute('state', 'open');
|
|
itemPane.setAttribute('collapsed', false);
|
|
}
|
|
// Hide
|
|
else {
|
|
document.getElementById('zotero-items-splitter').setAttribute('state', 'collapsed');
|
|
itemPane.setAttribute('collapsed', true);
|
|
}
|
|
ZoteroPane.updateToolbarPosition();
|
|
break;
|
|
|
|
case 'tag-selector':
|
|
ZoteroPane.toggleTagSelector();
|
|
break;
|
|
|
|
case 'font-size-bigger':
|
|
increaseFontSize('fontSize', FONT_SIZES);
|
|
break;
|
|
|
|
case 'font-size-smaller':
|
|
decreaseFontSize('fontSize', FONT_SIZES);
|
|
break;
|
|
|
|
case 'font-size-reset':
|
|
Zotero.Prefs.clear('fontSize');
|
|
break;
|
|
|
|
/*case 'note-font-size-bigger':
|
|
increaseFontSize('note.fontSize', NOTE_FONT_SIZES);
|
|
break;
|
|
|
|
case 'note-font-size-smaller':
|
|
decreaseFontSize('note.fontSize', NOTE_FONT_SIZES);
|
|
break;
|
|
*/
|
|
|
|
case 'note-font-size-reset':
|
|
Zotero.Prefs.clear('note.fontSize');
|
|
break;
|
|
|
|
case 'recursive-collections':
|
|
this.toggleBooleanPref('recursiveCollections');
|
|
break;
|
|
}
|
|
};
|
|
|
|
|
|
this.updateMenuItemCheckmark = function (id, checked) {
|
|
var menuitem = document.getElementById(id);
|
|
if (checked) {
|
|
menuitem.setAttribute('checked', true);
|
|
}
|
|
else {
|
|
menuitem.removeAttribute('checked');
|
|
}
|
|
};
|
|
|
|
|
|
this.updateMenuItemEnabled = function (id, enabled) {
|
|
var menuitem = document.getElementById(id);
|
|
if (enabled) {
|
|
menuitem.removeAttribute('disabled');
|
|
}
|
|
else {
|
|
menuitem.setAttribute('disabled', true);
|
|
}
|
|
};
|
|
|
|
|
|
this.toggleBooleanPref = function (pref) {
|
|
Zotero.Prefs.set(pref, !Zotero.Prefs.get(pref));
|
|
};
|
|
|
|
|
|
function decreaseFontSize(pref, sizes) {
|
|
var fontSize = Zotero.Prefs.get(pref);
|
|
var lastSize = fontSize;
|
|
// Get the highest font size below the current one
|
|
for (let i = sizes.length - 1; i >= 0; i--) {
|
|
if (fontSize > sizes[i]) {
|
|
lastSize = sizes[i];
|
|
break;
|
|
}
|
|
}
|
|
Zotero.Prefs.set(pref, lastSize);
|
|
}
|
|
|
|
function increaseFontSize(pref, sizes) {
|
|
var fontSize = Zotero.Prefs.get(pref);
|
|
var lastSize = fontSize;
|
|
// Get the font size above the current one
|
|
for (let i = 0; i < sizes.length; i++) {
|
|
if (sizes[i] > fontSize) {
|
|
lastSize = sizes[i];
|
|
break;
|
|
}
|
|
}
|
|
Zotero.Prefs.set(pref, lastSize);
|
|
}
|
|
|
|
|
|
this.updateNoteFontSize = function (event) {
|
|
var size = event.originalTarget.getAttribute('label');
|
|
Zotero.Prefs.set('note.fontSize', size);
|
|
};
|
|
|
|
|
|
this.promptForRestart = function () {
|
|
// Prompt to restart
|
|
var ps = Services.prompt;
|
|
var buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING
|
|
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_IS_STRING;
|
|
var index = ps.confirmEx(
|
|
null,
|
|
Zotero.getString('general.restartRequired'),
|
|
Zotero.getString('general.restartRequiredForChange', [ZOTERO_CONFIG.CLIENT_NAME]),
|
|
buttonFlags,
|
|
Zotero.getString('general.restartNow'),
|
|
Zotero.getString('general.restartLater'),
|
|
null, null, {}
|
|
);
|
|
|
|
if (index == 0) {
|
|
Zotero.Utilities.Internal.quitZotero(true);
|
|
}
|
|
};
|
|
|
|
|
|
this.updateAddonsPane = function (doc) {
|
|
// Unsigned add-on warnings are hidden by default in extensions.css (via style rules added
|
|
// by fetch_xulrunner.sh), but allow other warnings
|
|
function updateExtensions () {
|
|
var addonList = doc.getElementById('addon-list');
|
|
|
|
for (let i = 0; i < addonList.itemCount; i++) {
|
|
let richListItem = addonList.getItemAtIndex(i);
|
|
let container = doc.getAnonymousElementByAttribute(
|
|
richListItem, 'anonid', 'warning-container'
|
|
);
|
|
if (container) {
|
|
let link = doc.getAnonymousElementByAttribute(
|
|
richListItem, 'anonid', 'warning-link'
|
|
);
|
|
if (link) {
|
|
if (!link.href.includes('unsigned-addons')) {
|
|
container.classList.add('allowed-warning');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
doc.getElementById('category-extension').onclick = updateExtensions;
|
|
setTimeout(updateExtensions);
|
|
}
|
|
|
|
/**
|
|
* Handles help menu requests
|
|
*/
|
|
this.openHelp = function(type) {
|
|
Components.utils.import("resource://zotero/config.js");
|
|
|
|
switch (type) {
|
|
case "troubleshooting":
|
|
ZoteroPane.loadURI(ZOTERO_CONFIG.TROUBLESHOOTING_URL);
|
|
break;
|
|
|
|
case "feedback":
|
|
ZoteroPane.loadURI(ZOTERO_CONFIG.FEEDBACK_URL);
|
|
break;
|
|
|
|
case "connectors":
|
|
ZoteroPane.loadURI(ZOTERO_CONFIG.CONNECTORS_URL);
|
|
break;
|
|
|
|
default:
|
|
ZoteroPane.loadURI(ZOTERO_CONFIG.SUPPORT_URL);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks for updates
|
|
*/
|
|
this.checkForUpdates = function() {
|
|
window.open('chrome://mozapps/content/update/updates.xul', 'updateChecker', 'chrome,centerscreen');
|
|
}
|
|
|
|
/**
|
|
* Called before standalone window is closed
|
|
*/
|
|
this.onUnload = function() {
|
|
Zotero.Notifier.unregisterObserver(this._notifierID);
|
|
ZoteroPane.destroy();
|
|
}
|
|
}
|
|
|
|
|
|
ZoteroStandalone.DebugOutput = {
|
|
_timer: null,
|
|
|
|
init: function () {
|
|
var storing = Zotero.Debug.storing;
|
|
this._showMenu();
|
|
this.update();
|
|
},
|
|
|
|
|
|
toggleStore: function () {
|
|
Zotero.Debug.setStore(!Zotero.Debug.storing);
|
|
},
|
|
|
|
|
|
update: function () {
|
|
var enabled = Zotero.Debug.storing;
|
|
var lines = Zotero.Debug.count();
|
|
var empty = lines == 0;
|
|
|
|
// Show "Submit" when enabled, but leave disabled until there's output
|
|
var menuitem = document.getElementById('debug-output-submit');
|
|
menuitem.hidden = !enabled && empty;
|
|
menuitem.disabled = empty;
|
|
|
|
// Toggle between "Enable" and "Disable"
|
|
menuitem = document.getElementById('debug-output-enable-disable');
|
|
menuitem.label = Zotero.getString('general.' + (enabled ? 'disable' : 'enable'));
|
|
|
|
// Update line count
|
|
var str = Zotero.getString('zotero.debugOutputLogging.linesLogged', lines, lines);
|
|
document.getElementById('debug-output-status').label = str;
|
|
|
|
// Enable "Clear" when there's output
|
|
document.getElementById('debug-output-clear').disabled = empty;
|
|
},
|
|
|
|
|
|
submit: function () {
|
|
// 'Zotero' isn't defined yet when this function is created, so do it inline
|
|
return Zotero.Promise.coroutine(function* () {
|
|
Zotero.debug("Submitting debug output");
|
|
|
|
Components.utils.import("resource://zotero/config.js");
|
|
|
|
var url = ZOTERO_CONFIG.REPOSITORY_URL + "report?debug=1";
|
|
var output = yield Zotero.Debug.get(
|
|
Zotero.Prefs.get('debug.store.submitSize'),
|
|
Zotero.Prefs.get('debug.store.submitLineLength')
|
|
);
|
|
Zotero.Debug.setStore(false);
|
|
|
|
var ps = Services.prompt;
|
|
try {
|
|
var xmlhttp = yield Zotero.HTTP.request(
|
|
"POST",
|
|
url,
|
|
{
|
|
compressBody: true,
|
|
body: output,
|
|
logBodyLength: 30,
|
|
timeout: 15000,
|
|
requestObserver: function (req) {
|
|
// Don't fail during tests, with fake XHR
|
|
if (!req.channel) {
|
|
return;
|
|
}
|
|
req.channel.notificationCallbacks = {
|
|
onProgress: function (request, progress, progressMax) {},
|
|
|
|
// nsIInterfaceRequestor
|
|
getInterface: function (iid) {
|
|
try {
|
|
return this.QueryInterface(iid);
|
|
}
|
|
catch (e) {
|
|
throw Components.results.NS_NOINTERFACE;
|
|
}
|
|
},
|
|
|
|
QueryInterface: function(iid) {
|
|
if (iid.equals(Components.interfaces.nsISupports) ||
|
|
iid.equals(Components.interfaces.nsIInterfaceRequestor) ||
|
|
iid.equals(Components.interfaces.nsIProgressEventSink)) {
|
|
return this;
|
|
}
|
|
throw Components.results.NS_NOINTERFACE;
|
|
},
|
|
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|
|
catch (e) {
|
|
Zotero.logError(e);
|
|
let title = Zotero.getString('general.error');
|
|
let msg;
|
|
if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
|
|
msg = Zotero.getString('general.invalidResponseServer');
|
|
}
|
|
else if (e instanceof Zotero.HTTP.BrowserOfflineException) {
|
|
msg = Zotero.getString('general.browserIsOffline', Zotero.appName);
|
|
}
|
|
else {
|
|
msg = Zotero.getString('zotero.debugOutputLogging.dialog.error');
|
|
}
|
|
ps.alert(null, title, msg);
|
|
return false;
|
|
}
|
|
|
|
Zotero.debug(xmlhttp.responseText);
|
|
|
|
var reported = xmlhttp.responseXML.getElementsByTagName('reported');
|
|
if (reported.length != 1) {
|
|
ps.alert(
|
|
null,
|
|
Zotero.getString('general.error'),
|
|
Zotero.getString('general.serverError')
|
|
);
|
|
return false;
|
|
}
|
|
|
|
var reportID = reported[0].getAttribute('reportID');
|
|
|
|
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.getString('zotero.debugOutputLogging.dialog.title'),
|
|
Zotero.getString('zotero.debugOutputLogging.dialog.sent', [ZOTERO_CONFIG.DOMAIN_NAME, reportID]),
|
|
buttonFlags,
|
|
Zotero.getString('general.copyToClipboard'),
|
|
null, null, null, {}
|
|
);
|
|
if (index == 0) {
|
|
const helper = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
|
|
.getService(Components.interfaces.nsIClipboardHelper);
|
|
helper.copyString("D" + reportID);
|
|
}
|
|
|
|
Zotero.Debug.clear();
|
|
return true;
|
|
}.bind(this))();
|
|
},
|
|
|
|
|
|
view: function () {
|
|
Zotero.openInViewer("chrome://zotero/content/debugViewer.html", function (doc) {
|
|
var submitted = false;
|
|
doc.querySelector('#submit-button').addEventListener('click', function (event) {
|
|
submitted = true;
|
|
});
|
|
doc.querySelector('#clear-button').addEventListener('click', function (event) {
|
|
Zotero.Debug.clear();
|
|
});
|
|
// If output has been submitted, disable logging when window is closed
|
|
doc.defaultView.addEventListener('unload', function (event) {
|
|
if (submitted) {
|
|
Zotero.Debug.setStore(false);
|
|
Zotero.Debug.clear();
|
|
}
|
|
});
|
|
});
|
|
},
|
|
|
|
|
|
clear: function () {
|
|
Zotero.Debug.clear();
|
|
},
|
|
|
|
|
|
restartEnabled: function () {
|
|
var ps = Services.prompt;
|
|
var buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING
|
|
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL
|
|
+ ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING;
|
|
var index = ps.confirmEx(
|
|
null,
|
|
Zotero.getString('zotero.debugOutputLogging'),
|
|
Zotero.getString('zotero.debugOutputLogging.enabledAfterRestart', [Zotero.clientName]),
|
|
buttonFlags,
|
|
Zotero.getString('general.restartNow'),
|
|
null, Zotero.getString('general.restartLater'), null, {}
|
|
);
|
|
if (index != 1) {
|
|
Zotero.Prefs.set('debug.store', true);
|
|
}
|
|
if (index == 0) {
|
|
Zotero.Utilities.Internal.quit(true);
|
|
}
|
|
},
|
|
|
|
|
|
_showMenu: function () {
|
|
document.getElementById('debug-output-menu').hidden = false;
|
|
}
|
|
};
|
|
|
|
|
|
function toJavaScriptConsole() {
|
|
openWindowByType('chrome://global/content/console.xul', 'global:console');
|
|
}
|
|
|
|
function openRunJSWindow() {
|
|
openWindowByType(
|
|
'chrome://zotero/content/runJS.html',
|
|
'zotero:run-js',
|
|
'chrome,width=900,height=700,resizable,centerscreen'
|
|
);
|
|
}
|
|
|
|
function openStyleEditor() {
|
|
openWindowByType(
|
|
'chrome://zotero/content/tools/csledit.xhtml',
|
|
'zotero:style-editor',
|
|
'chrome,width=950,height=700,resizable'
|
|
);
|
|
}
|
|
|
|
function openScaffold() {
|
|
openWindowByType(
|
|
'chrome://scaffold/content/scaffold.xhtml',
|
|
'zotero:scaffold',
|
|
'chrome,resizable'
|
|
);
|
|
}
|
|
|
|
function openWindowByType(uri, type, features) {
|
|
var win = Services.wm.getMostRecentWindow(type);
|
|
|
|
if (win) {
|
|
win.focus();
|
|
}
|
|
else if (features) {
|
|
window.open(uri, "_blank", features);
|
|
}
|
|
else {
|
|
window.open(uri, "_blank", "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar");
|
|
}
|
|
}
|
|
|
|
const gXPInstallObserver = {
|
|
observe: function (subject, topic, data) {
|
|
const { installs } = subject.wrappedJSObject;
|
|
switch (topic) {
|
|
case "addon-install-disabled":
|
|
case "addon-install-blocked":
|
|
case "addon-install-failed":
|
|
Zotero.alert(
|
|
null,
|
|
Zotero.getString("standalone.addonInstallationFailed.title"),
|
|
Zotero.getString("standalone.addonInstallationFailed.body", installs[0].name));
|
|
break;
|
|
/*case "addon-install-started":
|
|
case "addon-install-complete":*/
|
|
}
|
|
}
|
|
};
|
|
|
|
// Used by update prompt
|
|
function openUILinkIn(url) {
|
|
ZoteroPane.loadURI(url);
|
|
}
|
|
|
|
window.addEventListener("load", function(e) { ZoteroStandalone.onLoad(e); }, false);
|
|
window.addEventListener("unload", function(e) { ZoteroStandalone.onUnload(e); }, false); |