fx-compat: Add preferences with full-text/keyword search (#2659)

This commit is contained in:
Abe Jellinek 2022-08-10 18:26:23 -04:00 committed by GitHub
parent db600cb5b9
commit 8d75f37548
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 2510 additions and 6827 deletions

View file

@ -2,56 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
prefwindow,
prefwindow:root /* override :root from above */ {
-moz-binding: url("chrome://zotero/content/bindings/preferences-mac.xml#prefwindow");
-moz-box-orient: vertical;
}
prefpane {
-moz-binding: url("chrome://zotero/content/bindings/preferences-mac.xml#prefpane");
-moz-box-orient: vertical;
}
prefwindow > .paneDeckContainer {
overflow: hidden;
}
prefpane > .content-box {
overflow: hidden;
}
prefwindow[type="child"] > .paneDeckContainer {
overflow: -moz-hidden-unscrollable;
}
prefwindow[type="child"] > prefpane > .content-box {
-moz-box-flex: 1;
overflow: -moz-hidden-unscrollable;
}
preferences {
-moz-binding: url("chrome://zotero/content/bindings/preferences-mac.xml#preferences");
visibility: collapse;
}
preference {
-moz-binding: url("chrome://zotero/content/bindings/preferences-mac.xml#preference");
visibility: collapse;
}
radio[pane] {
-moz-binding: url("chrome://zotero/content/bindings/preferences-mac.xml#panebutton") !important;
-moz-box-orient: vertical;
-moz-box-align: center;
}
prefwindow[chromehidden~="toolbar"] .chromeclass-toolbar {
display: none;
}
prefwindow {
window[windowtype="zotero:pref"] {
padding: 0;
font: -moz-dialog !important;
@ -59,79 +10,11 @@ prefwindow {
color: -moz-DialogText;
}
prefpane {
padding: 12px 12px 0 12px;
}
prefwindow[type="child"] > prefpane {
padding: 0;
}
.prefWindow-dlgbuttons {
margin: 0 12px 12px;
padding-top: 0 !important;
}
.paneSelector {
font: message-box;
padding: 1px 4px;
-moz-appearance: toolbar;
margin: 0;
}
radio[pane] {
border: solid transparent;
border-width: 0 2px;
padding: 5px 4px 3px;
margin: 0;
-moz-appearance: none;
text-shadow: rgba(255, 255, 255, 0.4) 0 1px;
}
radio[pane]:active:hover {
text-shadow: none;
}
radio[pane]:active:hover > .paneButtonIcon {
filter: brightness(0.55);
}
radio[pane][selected="true"] {
-moz-border-image: url("chrome://zotero-platform/content/panebutton-active.png") 0 2 fill repeat stretch;
}
radio[pane][selected="true"]:-moz-window-inactive {
-moz-border-image: url("chrome://zotero-platform/content/panebutton-inactive.png") 0 2 fill repeat stretch;
}
.paneButtonLabel {
margin: 0 !important;
}
groupbox {
padding: 5px 1px 1px;
padding-inline-start: 0;
margin: 6px;
}
groupbox > label > h2 {
groupbox > label > h2, groupbox > * > label > h2 {
border-bottom: #b5b5b5 1px solid;
}
groupbox > .groupbox-body {
padding: 8px 8px 3px;
margin: 0;
}
groupbox > label > h2, caption {
padding-inline-start: 4px;
padding-bottom: 1px;
groupbox > label > h2, groupbox > * > label > h2, caption {
padding-bottom: 0.2em;
font: caption;
}
/* !important is needed to override label in global.css */
.caption-text {
margin-top: 0 !important;
margin-bottom: 0 !important;
margin-inline-start: 1px !important;
}

View file

@ -2,56 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
prefwindow,
prefwindow:root /* override :root from above */ {
-moz-binding: url("chrome://zotero/content/bindings/preferences-unix.xml#prefwindow");
-moz-box-orient: vertical;
}
prefpane {
-moz-binding: url("chrome://zotero/content/bindings/preferences-unix.xml#prefpane");
-moz-box-orient: vertical;
}
prefwindow > .paneDeckContainer {
overflow: hidden;
}
prefpane > .content-box {
overflow: hidden;
}
prefwindow[type="child"] > .paneDeckContainer {
overflow: -moz-hidden-unscrollable;
}
prefwindow[type="child"] > prefpane > .content-box {
-moz-box-flex: 1;
overflow: -moz-hidden-unscrollable;
}
preferences {
-moz-binding: url("chrome://zotero/content/bindings/preferences-unix.xml#preferences");
visibility: collapse;
}
preference {
-moz-binding: url("chrome://zotero/content/bindings/preferences-unix.xml#preference");
visibility: collapse;
}
radio[pane] {
-moz-binding: url("chrome://zotero/content/bindings/preferences-unix.xml#panebutton") !important;
-moz-box-orient: vertical;
-moz-box-align: center;
}
prefwindow[chromehidden~="toolbar"] .chromeclass-toolbar {
display: none;
}
prefwindow {
window[windowtype="zotero:pref"] {
padding: 0px;
-moz-appearance: window;
@ -60,52 +11,6 @@ prefwindow {
font: message-box;
}
prefpane {
padding: 8px;
}
prefwindow[type="child"] {
padding: 8px;
}
prefwindow[type="child"] > prefpane {
padding: 0px;
}
.prefWindow-dlgbuttons {
padding-bottom: 8px;
padding-inline-start: 8px;
padding-inline-end: 8px;
}
prefwindow[type="child"] .prefWindow-dlgbuttons {
padding: 0px;
}
radio[pane] {
-moz-appearance: none;
min-width: 4.5em;
margin: 0;
padding: 3px;
color: -moz-FieldText;
}
.paneSelector {
-moz-appearance: listbox;
margin: 8px 8px 0 8px;
padding: 0;
}
.paneButtonIcon {
width: 32px;
height: 32px;
}
radio[pane][selected="true"] {
background-color: Highlight;
color: HighlightText;
}
#sync-reset-library-menu {
height: initial !important;
}

View file

@ -2,120 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
prefwindow,
prefwindow:root /* override :root from above */ {
-moz-binding: url("chrome://zotero/content/bindings/preferences-win.xml#prefwindow");
-moz-box-orient: vertical;
}
prefpane {
-moz-binding: url("chrome://zotero/content/bindings/preferences-win.xml#prefpane");
-moz-box-orient: vertical;
}
prefwindow > .paneDeckContainer {
overflow: hidden;
}
prefpane > .content-box {
overflow: hidden;
}
prefwindow[type="child"] > .paneDeckContainer {
overflow: -moz-hidden-unscrollable;
}
prefwindow[type="child"] > prefpane > .content-box {
-moz-box-flex: 1;
overflow: -moz-hidden-unscrollable;
}
preferences {
-moz-binding: url("chrome://zotero/content/bindings/preferences-win.xml#preferences");
visibility: collapse;
}
preference {
-moz-binding: url("chrome://zotero/content/bindings/preferences-win.xml#preference");
visibility: collapse;
}
radio[pane] {
-moz-binding: url("chrome://zotero/content/bindings/preferences-win.xml#panebutton") !important;
-moz-box-orient: vertical;
-moz-box-align: center;
}
prefwindow[chromehidden~="toolbar"] .chromeclass-toolbar {
display: none;
}
prefwindow {
padding: 0px;
window[windowtype="zotero:pref"] {
padding: 0;
-moz-appearance: window;
background-color: -moz-Dialog;
color: -moz-DialogText;
font: message-box;
}
prefpane {
padding-top: 8px;
padding-bottom: 10px;
padding-inline-start: 8px;
padding-inline-end: 10px;
}
prefwindow[type="child"] {
padding-top: 8px;
padding-bottom: 10px;
padding-inline-start: 8px;
padding-inline-end: 10px;
}
prefwindow[type="child"] > prefpane {
padding: 0px;
}
.prefWindow-dlgbuttons {
padding-bottom: 10px;
padding-inline-start: 8px;
padding-inline-end: 10px;
}
prefwindow[type="child"] .prefWindow-dlgbuttons {
padding: 0px;
}
radio[pane] {
-moz-appearance: none;
margin: 0px 1px 0px 1px;
padding: 1px 3px 1px 3px;
min-width: 4.5em;
}
.paneSelector {
border-bottom: 2px groove ThreeDFace;
margin: 0px;
padding-inline-start: 10px;
background-color: -moz-Field;
color: -moz-FieldText;
}
.paneButtonIcon {
width: 32px;
height: 32px;
}
radio[pane]:hover {
background-color: #E0E8F6;
color: black;
-moz-appearance: none;
}
radio[pane][selected="true"] {
background-color: #C1D2EE;
color: black;
-moz-appearance: none;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,123 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Toolkit.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** -->
<bindings id="textBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<binding id="text-link" extends="chrome://global/content/bindings/text.xml#text-label">
<implementation implements="nsIAccessibleProvider">
<property name="accessibleType" readonly="true">
<getter>
<![CDATA[
return Components.interfaces.nsIAccessibleProvider.XULLink;
]]>
</getter>
</property>
<property name="href" onget="return this.getAttribute('href');"
onset="this.setAttribute('href', val); return val;" />
<method name="open">
<parameter name="aEvent"/>
<body>
<![CDATA[
var href = this.href;
if (!href || this.disabled || aEvent.defaultPrevented)
return;
var uri = null;
try {
const nsISSM = Components.interfaces.nsIScriptSecurityManager;
const secMan =
Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(nsISSM);
const ioService =
Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
uri = ioService.newURI(href, null, null);
var nullPrincipal =
Components.classes["@mozilla.org/nullprincipal;1"]
.createInstance(Components.interfaces.nsIPrincipal);
try {
secMan.checkLoadURIWithPrincipal(nullPrincipal, uri,
nsISSM.DISALLOW_INHERIT_PRINCIPAL)
}
catch (ex) {
var msg = "Error: Cannot open a " + uri.scheme + ": link using \
the text-link binding.";
Components.utils.reportError(msg);
return;
}
// Open HTTP URLs externally
if (window.Zotero && ["http", "https"].includes(uri.scheme)) {
Zotero.launchURL(uri.spec);
aEvent.preventDefault();
return;
}
}
catch (ex) {
Components.utils.reportError(ex);
}
// otherwise, fall back to opening the anchor directly
var win = window;
if (window instanceof Components.interfaces.nsIDOMChromeWindow) {
while (win.opener && !win.opener.closed)
win = win.opener;
}
if (uri)
win.open(uri.spec);
else
win.open(href);
aEvent.preventDefault();
]]>
</body>
</method>
</implementation>
<handlers>
<handler event="click" phase="capturing" button="0" action="this.open(event)"/>
<handler event="keypress" preventdefault="true" keycode="VK_ENTER" action="this.click()" />
<handler event="keypress" preventdefault="true" keycode="VK_RETURN" action="this.click()" />
</handlers>
</binding>
</bindings>

View file

@ -23,6 +23,7 @@
***** END LICENSE BLOCK *****
*/
var Zotero_Charset_Menu = new function() {
this.populate = populate;
@ -64,31 +65,16 @@ var Zotero_Charset_Menu = new function() {
else {
var charsetSeparator = document.createXULElement("menuseparator");
charsetPopup.appendChild(charsetSeparator);
charsets = [
{ "label": "Unicode (UTF-8)", "value": "UTF-8" },
{ "label": "Western", "value": "windows-1252" },
{ "label": "UTF-16LE", "value": "UTF-16LE" },
{ "label": "UTF-16BE", "value": "UTF-16BE" },
{ "label": "Western (IBM-850)", "value": "IBM850" },
{ "label": "Western (MacRoman)", "value": "macintosh" }
];
Components.utils.import("resource://gre/modules/CharsetMenu.jsm");
var cmData = CharsetMenu.getData();
for (let charsetList of [cmData.pinnedCharsets, cmData.otherCharsets]) {
for (let charsetInfo of charsetList) {
if(charsetInfo.value == "UTF-8") {
charsets.push({
"label":"Unicode (UTF-8)",
"value":"UTF-8"
});
} else {
charsets.push({
"label":charsetInfo.label,
"value":charsetInfo.value
});
}
}
}
charsets = charsets.concat([
{"label":"UTF-16LE", "value":"UTF-16LE"},
{"label":"UTF-16BE", "value":"UTF-16BE"},
{"label":"Western (IBM-850)", "value":"IBM850"},
{"label":"Western (MacRoman)", "value":"macintosh"}
]);
for(var i=0; i<charsets.length; i++) {
var charset = charsets[i].value,
label = charsets[i].label;

View file

@ -0,0 +1,90 @@
"use strict";
{
class ZoteroTextLink extends XULTextElement {
constructor() {
super();
this.addEventListener('click', (event) => {
if (event.button == 0) {
this.open(event);
}
}, true);
this.addEventListener('keypress', (event) => {
if (event.key == 'Enter' || event.key == 'Return') {
event.preventDefault();
this.click();
}
});
}
connectedCallback() {
this.classList.add('zotero-text-link');
}
get href() {
return this.getAttribute('href');
}
set href(href) {
this.setAttribute('href', href);
}
open(event) {
let href = this.href;
if (!href || this.disabled || event.defaultPrevented) {
return;
}
var uri = null;
try {
const nsISSM = Components.interfaces.nsIScriptSecurityManager;
const secMan =
Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(nsISSM);
const ioService =
Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
uri = ioService.newURI(href, null, null);
var nullPrincipal = secMan.createNullPrincipal({});
try {
secMan.checkLoadURIWithPrincipal(nullPrincipal, uri,
nsISSM.DISALLOW_INHERIT_PRINCIPAL);
}
catch (ex) {
var msg = "Error: Cannot open a " + uri.scheme + ": link using the zotero-text-link CE.";
Components.utils.reportError(msg);
return;
}
// Open HTTP URLs externally
if (window.Zotero && ["http", "https"].includes(uri.scheme)) {
Zotero.launchURL(uri.spec);
event.preventDefault();
return;
}
}
catch (ex) {
Components.utils.reportError(ex);
}
// otherwise, fall back to opening the anchor directly
var win = window;
if (window instanceof Components.interfaces.nsIDOMChromeWindow) {
while (win.opener && !win.opener.closed)
win = win.opener;
}
if (uri)
win.open(uri.spec);
else
win.open(href);
event.preventDefault();
}
}
customElements.define('zotero-text-link', ZoteroTextLink, { extends: 'label' });
}

View file

@ -31,17 +31,6 @@
<?xml-stylesheet href="chrome://zotero/skin/preferences.css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/zotero-react-client.css"?>
<!--
To add a new preference:
1) Add a new <preference> to <preferences>
2) Add a XUL control with a 'preference' attribute
3) (Optional) Add additional setup/change logic to preferences.js
4) (Optional) To add an observer for a preference change,
add an appropriate case in the switch statement
in Zotero.Prefs.observe()
-->
<window
id="zotero-locate-manager-prefs"
title="&zotero.preferences.title;" onload="init()"

View file

@ -0,0 +1,64 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 2007 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 *****
-->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://zotero/skin/preferences.css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/zotero-react-client.css"?>
<!DOCTYPE window [
<!ENTITY % prefWindow SYSTEM "chrome://zotero/locale/preferences.dtd">
%prefWindow;
<!ENTITY % common SYSTEM "chrome://zotero/locale/zotero.dtd">
%common;
]>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title=""
onload="Zotero_Preferences.Sync.initLibrariesToSync(); sizeToContent()"
style="display: flex;">
<dialog buttons="accept"
id="zotero-librariesToSync">
<script src="chrome://zotero/content/include.js"/>
<script src="preferences.js"/>
<script src="preferences_sync.js"/>
<label style="font-size: 14px; margin-bottom: 0.5em;" value="&zotero.preferences.sync.librariesToSync;"/>
<hbox class="virtualized-table-container" flex="1" height="200" width="600">
<html:div id="libraries-to-sync-tree"/>
</hbox>
<script>
<![CDATA[
var io = window.arguments[0];
]]>
</script>
</dialog>
</window>

View file

@ -1,62 +0,0 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 2007 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 *****
-->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://zotero/skin/preferences.css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/zotero-react-client.css"?>
<!DOCTYPE window [
<!ENTITY % prefWindow SYSTEM "chrome://zotero/locale/preferences.dtd">
%prefWindow;
<!ENTITY % common SYSTEM "chrome://zotero/locale/zotero.dtd">
%common;
]>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="" buttons="accept"
id="zotero-librariesToSync"
onload="Zotero_Preferences.Sync.initLibrariesToSync(); sizeToContent()" >
<script src="chrome://zotero/content/include.js"/>
<script src="preferences.js"/>
<script src="preferences_sync.js"/>
<groupbox>
<caption label="&zotero.preferences.sync.librariesToSync;"/>
<hbox class="virtualized-table-container" flex="1" height="200" width="600">
<html:div id="libraries-to-sync-tree"/>
</hbox>
</groupbox>
<script>
<![CDATA[
var io = window.arguments[0];
]]>
</script>
</dialog>

View file

@ -27,56 +27,85 @@
var Zotero_Preferences = {
init: function () {
if(Zotero.isConnector) {
Zotero.activateStandalone();
window.close();
return;
this.observerSymbols = [];
this.panes = new Map();
this.navigation = document.getElementById('prefs-navigation');
this.content = document.getElementById('prefs-content');
this.navigation.addEventListener('select', () => this._onNavigationSelect());
document.getElementById('prefs-search').addEventListener('command',
event => this.search(event.target.value));
document.getElementById('prefs-subpane-back-button').addEventListener('command', () => {
let parent = this.panes.get(this.navigation.value).parent;
if (parent) {
this.navigation.value = parent;
}
});
document.getElementById('prefs-search').focus();
this.initPanes();
},
initPanes: function () {
// Save positions and clear content in case we're reinitializing
// because of a plugin lifecycle event
let navigationValue = this.navigation.value;
let navigationScrollTop = this.navigation.scrollTop;
let navigationScrollLeft = this.navigation.scrollLeft;
this.navigation.replaceChildren();
let contentScrollTop = this.content.scrollTop;
let contentScrollLeft = this.content.scrollLeft;
this.content.replaceChildren();
Zotero.PreferencePanes.builtInPanes.forEach(pane => this.addPane(pane));
if (Zotero.PreferencePanes.pluginPanes.length) {
this.navigation.append(document.createElement('hr'));
Zotero.PreferencePanes.pluginPanes
.sort((a, b) => Zotero.localeCompare(a.rawLabel, b.rawLabel))
.forEach(pane => this.addPane(pane));
}
observerService.addObserver(function() {
if(Zotero.isConnector) window.close();
}, "zotero-reloaded", false);
if(window.arguments) {
if (navigationValue) {
this.navigation.value = navigationValue;
this.navigation.scrollTop = navigationScrollTop;
this.navigation.scrollLeft = navigationScrollLeft;
this.content.scrollTop = contentScrollTop;
this.content.scrollLeft = contentScrollLeft;
}
else if (window.arguments) {
var io = window.arguments[0];
io = io.wrappedJSObject || io;
if(io.pane) {
if (io.pane) {
let tabID = io.tab;
let tabIndex = io.tabIndex;
var pane = document.getElementById(io.pane);
document.getElementById('zotero-prefs').showPane(pane);
this.navigation.value = io.pane;
// Select tab within pane by tab id
if (tabID !== undefined) {
if (pane.loaded) {
let tab = document.querySelector('tab#' + tabID);
if (tab) {
document.getElementsByTagName('tabbox')[0].selectedTab = tab;
}
}
else {
pane.addEventListener('paneload', function () {
let tab = document.querySelector('tab#' + tabID);
if (tab) {
document.getElementsByTagName('tabbox')[0].selectedTab = tab;
}
})
let tab = document.getElementById(tabID);
if (tab) {
tab.control.selectedItem = tab;
}
}
// Select tab within pane by index
else if (tabIndex !== undefined) {
if (pane.loaded) {
document.getElementsByTagName('tabbox')[0].selectedIndex = tabIndex;
}
else {
pane.addEventListener('paneload', function () {
document.getElementsByTagName('tabbox')[0].selectedIndex = tabIndex;
})
}
pane.querySelector('tabbox').selectedIndex = tabIndex;
}
}
} else if(document.location.hash == "#cite") {
document.getElementById('zotero-prefs').showPane(document.getElementById("zotero-prefpane-cite"));
}
else if (document.location.hash == "#cite") {
this.navigation.value = 'zotero-prefpane-cite';
}
if (!this.navigation.value) {
this.navigation.value = Zotero.Prefs.get('lastSelectedPrefPane');
// If no last selected pane or ID is invalid, select General
if (!this.navigation.value) {
this.navigation.value = 'zotero-prefpane-general';
}
}
},
@ -84,6 +113,451 @@ var Zotero_Preferences = {
if (Zotero_Preferences.Debug_Output) {
Zotero_Preferences.Debug_Output.onUnload();
}
while (this.observerSymbols.length) {
Zotero.Prefs.unregisterObserver(this.observerSymbols.shift());
}
},
/**
* Add a pane to the left navigation sidebar. The pane source (`src`) is
* loaded as a fragment, not a full document.
*
* @param {Object} options
* @param {String} options.id Must be unique
* @param {String} [options.pluginID] ID of the plugin that registered the pane
* @param {String} [options.parent] ID of parent pane (if provided, pane is hidden from the sidebar)
* @param {String} [options.label] A DTD/.properties key (optional for panes with parents)
* @param {String} [options.rawLabel] A raw string to use as the label if optios.label is not provided
* @param {String} [options.image] URI of an icon (displayed in the navigation sidebar)
* @param {String} options.src URI of an XHTML fragment
* @param {String[]} [options.extraDTD] Array of URIs of DTD files to use for parsing the XHTML fragment
* @param {String[]} [options.scripts] Array of URIs of scripts to load along with the pane
* @param {Boolean} [options.defaultXUL] If true, parse the markup at `src` as XUL instead of XHTML:
* whitespace-only text nodes are ignored, XUL is the default namespace, and HTML tags are
* namespaced under `html:`. Default behavior is the opposite: whitespace nodes are preserved,
* HTML is the default namespace, and XUL tags are under `xul:`.
*/
async addPane(options) {
let { id, parent, label, rawLabel, image } = options;
let listItem = document.createXULElement('richlistitem');
listItem.value = id;
if (image) {
let imageElem = document.createXULElement('image');
imageElem.src = image;
listItem.append(imageElem);
}
// We still add a hidden richlistitem even if this is a subpane,
// so we can invisibly select it and prevent richlistbox from selecting
// its first visible child on focus (which would hide the visible subpane)
if (parent) {
listItem.hidden = true;
}
else {
let labelElem = document.createXULElement('label');
if (rawLabel) {
labelElem.value = rawLabel;
}
else if (Zotero.Intl.strings.hasOwnProperty(label)) {
labelElem.value = Zotero.Intl.strings[label];
}
else {
labelElem.value = Zotero.getString(label);
}
listItem.append(labelElem);
}
this.navigation.append(listItem);
let container = document.createXULElement('vbox');
container.id = id;
container.hidden = true;
this.content.append(container);
this.panes.set(id, {
...options,
imported: false,
container,
});
},
/**
* Select a pane in the navigation sidebar, displaying its content.
* Clears the current search and hides all other panes' content.
*
* @param {String} id
*/
navigateToPane(id) {
this.navigation.value = id;
},
/**
* Display a pane's content, alongside any other panes already showing.
* If the pane is not yet loaded, it will be loaded first.
*
* @param {String} id
*/
_loadAndDisplayPane(id) {
let pane = this.panes.get(id);
if (!pane.imported) {
if (pane.scripts) {
for (let script of pane.scripts) {
Services.scriptloader.loadSubScript(script, this);
}
}
let markup = Zotero.File.getContentsFromURL(pane.src);
let dtdFiles = [
'chrome://zotero/locale/zotero.dtd',
'chrome://zotero/locale/preferences.dtd',
...(pane.extraDTD || []),
];
let contentFragment = pane.defaultXUL
? MozXULElement.parseXULToFragment(markup, dtdFiles)
: this.parseXHTMLToFragment(markup, dtdFiles);
contentFragment = document.importNode(contentFragment, true);
pane.container.append(contentFragment);
pane.imported = true;
this._initImportedNodes(pane.container);
}
pane.container.hidden = false;
let backButton = document.getElementById('prefs-subpane-back-button');
backButton.hidden = !pane.parent;
},
parseXHTMLToFragment(str, entities = []) {
// Adapted from MozXULElement.parseXULToFragment
/* eslint-disable indent */
let parser = new DOMParser();
parser.forceEnableXULXBL();
let doc = parser.parseFromSafeString(
`
${entities.length
? `<!DOCTYPE bindings [ ${entities.reduce((preamble, url, index) => {
return preamble + `<!ENTITY % _dtd-${index} SYSTEM "${url}"> %_dtd-${index}; `;
}, '')}]>`
: ""}
<div xmlns="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
${str}
</div>`, "application/xml");
/* eslint-enable indent */
if (doc.documentElement.localName === 'parsererror') {
throw new Error('not well-formed XHTML');
}
// We use a range here so that we don't access the inner DOM elements from
// JavaScript before they are imported and inserted into a document.
let range = doc.createRange();
range.selectNodeContents(doc.querySelector('div'));
return range.extractContents();
},
/**
* If term is falsy, clear the current search and show the first pane.
* If term is truthy, execute a search:
* - Deselect the selected section
* - Show all preferences from all sections
* - Hide those not matching the search term (by full text and data-search-strings[-raw])
* - Highlight full-text matches and show tooltips by search string matches
*
* @param {String} [term]
*/
search(term) {
// Initial housekeeping:
// Clear existing highlights
this._getSearchSelection().removeAllRanges();
// Remove existing tooltips
// Need to convert to array before iterating so elements being removed from the
// live collection doesn't mess with the iteration
for (let oldTooltipParent of [...this.content.getElementsByClassName('search-tooltip-parent')]) {
oldTooltipParent.replaceWith(oldTooltipParent.firstElementChild);
}
// Show hidden sections
for (let hidden of [...this.content.getElementsByClassName('hidden-by-search')]) {
hidden.classList.remove('hidden-by-search');
hidden.ariaHidden = false;
}
if (!term) {
if (this.navigation.selectedIndex == -1) {
this.navigation.selectedIndex = 0;
}
return;
}
// Clear pane selection
this.navigation.clearSelection();
// Make sure all panes are loaded into the DOM and show top-level ones
for (let [id, pane] of this.panes) {
if (pane.parent) {
pane.container.hidden = true;
}
else {
this._loadAndDisplayPane(id);
}
}
// Replace <label value="abc"/> with <label>abc</label>
// This renders exactly the same and enables highlighting using ranges
for (let label of document.getElementsByTagNameNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'label')) {
if (label.getAttribute('value') && !label.textContent) {
label.textContent = label.getAttribute('value');
label.removeAttribute('value');
}
}
// Clean the search term but keep the original -
//displaying with diacritics removed is confusing
let termForDisplay = Zotero.Utilities.trimInternal(term).toLowerCase();
term = this._normalizeSearch(term);
for (let container of this.content.children) {
let root = container.firstElementChild;
if (!root) continue;
for (let child of root.children) {
let matches = this._searchRecursively(child, term);
if (matches.length) {
let touchedTabPanels = new Set();
for (let node of matches) {
if (node.nodeType === Node.TEXT_NODE) {
// For text nodes, add a native highlight on the matched range
let value = node.nodeValue.toLowerCase();
let index = value.indexOf(term);
if (index == -1) continue; // Should not happen
let range = document.createRange();
range.setStart(node, index);
range.setEnd(node, index + term.length);
this._getSearchSelection().addRange(range);
}
else if (node.nodeType == Node.ELEMENT_NODE) {
// For element nodes, wrap the element and add a tooltip
// (So please don't use .parentElement etc. in event listeners)
// Structure:
// hbox.search-tooltip-parent
// | <node>
// | span.search-tooltip
// | span
// | <termForDisplay>
let tooltipParent = document.createXULElement('hbox');
tooltipParent.className = 'search-tooltip-parent';
node.replaceWith(tooltipParent);
let tooltip = document.createElement('span');
tooltip.className = 'search-tooltip';
let tooltipText = document.createElement('span');
tooltipText.append(termForDisplay);
tooltip.append(tooltipText);
tooltipParent.append(node, tooltip);
// https://searchfox.org/mozilla-central/rev/703391c381f92a73d9a938cbe0d33ca64d94583b/browser/components/preferences/findInPage.js#689-691
let tooltipRect = tooltip.getBoundingClientRect();
tooltip.style.left = `calc(50% - ${tooltipRect.width / 2}px)`;
}
let tabPanel = this._closest(node, 'tabpanels > tabpanel');
let tabPanels = tabPanel?.parentElement;
if (tabPanels && !touchedTabPanels.has(tabPanels)) {
let tab = tabPanels.getRelatedElement(tabPanel);
if (tab.control) {
tab.control.selectedItem = tab;
touchedTabPanels.add(tabPanels);
}
}
}
}
else {
child.classList.add('hidden-by-search');
child.ariaHidden = true;
}
}
}
},
/**
* Search for the given term (case-insensitive) in the tree.
*
* @param {Element} root
* @param {String} term Must be normalized (normalizeSearch())
* @return {Node[]}
*/
_searchRecursively(root, term) {
const EXCLUDE_SELECTOR = 'input, [hidden="true"], [no-highlight]';
let matched = new Set();
let treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
let currentNode;
while ((currentNode = treeWalker.nextNode())) {
if (this._closest(currentNode, EXCLUDE_SELECTOR)
|| !currentNode.nodeValue
|| currentNode.length < term.length) {
continue;
}
if (this._normalizeSearch(currentNode.nodeValue).includes(term)) {
let unhighlightableParent = this._closest(currentNode, 'menulist');
if (unhighlightableParent) {
matched.add(unhighlightableParent);
}
else {
matched.add(currentNode);
}
}
}
for (let elem of root.querySelectorAll('[data-search-strings-raw], [data-search-strings]')) {
if (elem.closest(EXCLUDE_SELECTOR)) {
continue;
}
if (elem.hasAttribute('data-search-strings-raw')) {
let rawStrings = elem.getAttribute('data-search-strings-raw')
.split(',')
.map(this._normalizeSearch)
.filter(Boolean);
if (rawStrings.some(s => s.includes(term))) {
matched.add(elem);
continue;
}
}
if (elem.hasAttribute('data-search-strings')) {
let stringKeys = elem.getAttribute('data-search-strings')
.split(',')
.map(s => s.trim())
.filter(Boolean);
for (let key of stringKeys) {
if (Zotero.Intl.strings.hasOwnProperty(key)) {
if (this._normalizeSearch(Zotero.Intl.strings[key]).includes(term)) {
matched.add(elem);
break;
}
}
else if (this._normalizeSearch(Zotero.getString(key).replace(/%(\d+\$)?S/g, ''))
.includes(term)) {
matched.add(elem);
break;
}
}
}
}
return [...matched];
},
/**
* @param {String} s
* @return {String}
*/
_normalizeSearch(s) {
return Zotero.Utilities.removeDiacritics(
Zotero.Utilities.trimInternal(s).toLowerCase(),
true);
},
/**
* @return {Selection}
*/
_getSearchSelection() {
// https://searchfox.org/mozilla-central/rev/703391c381f92a73d9a938cbe0d33ca64d94583b/browser/components/preferences/findInPage.js#226-239
let controller = window.docShell
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
let selection = controller.getSelection(
Ci.nsISelectionController.SELECTION_FIND
);
selection.setColors('currentColor', '#ffe900', 'currentColor', '#003eaa');
return selection;
},
/**
* Like {@link Element#closest} for all nodes.
*
* @param {Node} node
* @param {String} selector
* @return {Element | null}
*/
_closest(node, selector) {
while (node && node.nodeType != Node.ELEMENT_NODE) {
node = node.parentNode;
}
return node?.closest(selector);
},
_onNavigationSelect() {
for (let child of this.content.children) {
child.setAttribute('hidden', true);
}
let paneID = this.navigation.value;
if (paneID) {
this.content.scrollTop = 0;
document.getElementById('prefs-search').value = '';
this.search('');
this._loadAndDisplayPane(paneID);
}
Zotero.Prefs.set('lastSelectedPrefPane', paneID);
},
_initImportedNodes(root) {
// Activate `preference` attributes
for (let elem of root.querySelectorAll('[preference]')) {
let preference = elem.getAttribute('preference');
if (root.querySelector('preferences > preference#' + preference)) {
Zotero.debug('<preference> is deprecated -- `preference` attribute values '
+ 'should be full preference keys, not <preference> IDs');
preference = root.querySelector('preferences > preference#' + preference)
.getAttribute('name');
}
let useChecked = (elem instanceof HTMLInputElement && elem.type == 'checkbox')
|| elem.tagName == 'checkbox';
elem.addEventListener(elem instanceof XULElement ? 'command' : 'input', () => {
let value = useChecked ? elem.checked : elem.value;
Zotero.Prefs.set(preference, value, true);
elem.dispatchEvent(new Event('synctopreference'));
});
let syncFromPref = () => {
let value = Zotero.Prefs.get(preference, true);
if (useChecked) {
elem.checked = value;
}
else {
elem.value = value;
}
elem.dispatchEvent(new Event('syncfrompreference'));
};
// Set timeout so pane can add listeners first
setTimeout(() => {
syncFromPref();
this.observerSymbols.push(Zotero.Prefs.registerObserver(preference, syncFromPref, true));
});
}
// parseXULToFragment() doesn't convert oncommand attributes into actual
// listeners, so we'll do it here
for (let elem of root.querySelectorAll('[oncommand]')) {
elem.oncommand = elem.getAttribute('oncommand');
}
for (let child of root.children) {
child.dispatchEvent(new Event('load'));
}
},
openURL: function (url, windowName) {

View file

@ -0,0 +1,98 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062013 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 *****
-->
<!DOCTYPE window [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd"> %globalDTD;
<!ENTITY % editMenuOverlayDTD SYSTEM "chrome://zotero/locale/mozilla/editMenuOverlay.dtd" > %editMenuOverlayDTD;
<!ENTITY % zoteroDTD SYSTEM "chrome://zotero/locale/zotero.dtd"> %zoteroDTD;
<!ENTITY % preferencesDTD SYSTEM "chrome://zotero/locale/preferences.dtd"> %preferencesDTD;
]>
<?xml-stylesheet href="chrome://global/skin/global.css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/preferences.css"?>
<?xml-stylesheet href="chrome://zotero/skin/preferences.css"?>
<?xml-stylesheet href="chrome://zotero/skin/zotero.css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/overlay.css"?>
<?xml-stylesheet href="chrome://zotero-platform-version/content/style.css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/zotero-react-client.css"?>
<!--
To add an observer for a preference change, add an appropriate case in
the switch statement in Zotero.Prefs.observe().
-->
<window id="zotero-prefs"
title="&zotero.preferences.title;"
onload="Zotero_Preferences.init()"
onunload="Zotero_Preferences.onUnload()"
windowtype="zotero:pref"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
style="display: flex;"
width="800"
height="600">
<script>
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
Services.scriptloader.loadSubScript("chrome://zotero/content/include.js", this);
Services.scriptloader.loadSubScript("chrome://zotero/content/charsetMenu.js");
Services.scriptloader.loadSubScript("chrome://zotero/content/preferences/preferences.js");
// Mozilla scripts
Services.scriptloader.loadSubScript("chrome://global/content/globalOverlay.js", this);
Services.scriptloader.loadSubScript("chrome://global/content/editMenuOverlay.js", this);
Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", this);
if (Zotero.isMac) {
Services.scriptloader.loadSubScript("chrome://global/content/macWindowMenu.js", this);
}
// Custom elements
Services.scriptloader.loadSubScript("chrome://global/content/customElements.js", this);
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/textLink.js", this);
</script>
<keyset>
<key id="key_close" modifiers="accel" key="W" oncommand="window.close()"/>
<key modifiers="accel" key="L" oncommand="document.getElementById('prefs-search').focus()"/>
<key id="key_find" modifiers="accel" key="F" oncommand="document.getElementById('prefs-search').focus()"/>
</keyset>
<hbox id="prefs-outer-container" flex="1">
<richlistbox id="prefs-navigation"></richlistbox>
<vbox id="prefs-inner-container" flex="1">
<hbox id="prefs-search-container" align="center">
<hbox flex="1" pack="start" align="center">
<button
id="prefs-subpane-back-button"
label=""
aria-label="&zotero.pdfReader.back;"
hidden="true"/>
</hbox>
<search-textbox id="prefs-search" placeholder="&zotero.lookup.button.search;" timeout="1"/>
</hbox>
<vbox id="prefs-content" flex="1"/>
</vbox>
</hbox>
</window>

View file

@ -1,966 +0,0 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062013 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 *****
-->
<!DOCTYPE prefwindow [
<!ENTITY % zoteroDTD SYSTEM "chrome://zotero/locale/zotero.dtd"> %zoteroDTD;
<!ENTITY % preferencesDTD SYSTEM "chrome://zotero/locale/preferences.dtd"> %preferencesDTD;
]>
<?xml-stylesheet href="chrome://global/skin/global.css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/preferences.css"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
<?xml-stylesheet href="chrome://zotero/skin/preferences.css"?>
<?xml-stylesheet href="chrome://zotero/skin/zotero.css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/overlay.css"?>
<?xml-stylesheet href="chrome://zotero-platform-version/content/style.css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/zotero-react-client.css"?>
<!--
To add an observer for a preference change, add an appropriate case in
the switch statement in Zotero.Prefs.observe().
-->
<prefwindow id="zotero-prefs"
title="&zotero.preferences.title;"
onload="Zotero_Preferences.init()"
onunload="Zotero_Preferences.onUnload()"
ondialoghelp="Zotero_Preferences.openHelpLink()"
windowtype="zotero:pref"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="chrome://zotero/content/include.js"></script>
<script src="preferences.js"></script>
<script src="preferences_general.js"></script>
<script src="preferences_sync.js"></script>
<script src="preferences_search.js"></script>
<script src="preferences_export.js"></script>
<script src="preferences_cite.js"></script>
<script src="preferences_advanced.js"></script>
<script src="chrome://zotero/content/charsetMenu.js"></script>
<script>
<![CDATA[
var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.notifyObservers(null, "charsetmenu-selected", "other");
]]>
</script>
<!-- General -->
<prefpane id="zotero-prefpane-general"
label="&zotero.preferences.prefpane.general;"
image="chrome://zotero/skin/prefs-general.png"
onpaneload="Zotero_Preferences.General.init()"
helpTopic="general">
<preferences id="zotero-prefpane-general-preferences">
<preference id="pref-automaticSnapshots" name="extensions.zotero.automaticSnapshots" type="bool"/>
<preference id="pref-downloadAssociatedFiles" name="extensions.zotero.downloadAssociatedFiles" type="bool"/>
<preference id="pref-autoRecognizeFiles" name="extensions.zotero.autoRecognizeFiles" type="bool"/>
<preference id="pref-autoRenameFiles" name="extensions.zotero.autoRenameFiles" type="bool"/>
<preference id="pref-autoRenameFilesLinked" name="extensions.zotero.autoRenameFiles.linked" type="bool"/>
<preference id="pref-automaticTags" name="extensions.zotero.automaticTags" type="bool"/>
<preference id="pref-trashAutoEmptyDays" name="extensions.zotero.trashAutoEmptyDays" type="int"/>
<preference id="pref-groups-copyChildNotes" name="extensions.zotero.groups.copyChildNotes" type="bool"/>
<preference id="pref-groups-copyChildFileAttachments" name="extensions.zotero.groups.copyChildFileAttachments" type="bool"/>
<preference id="pref-groups-copyAnnotations" name="extensions.zotero.groups.copyAnnotations" type="bool"/>
<preference id="pref-groups-copyChildLinks" name="extensions.zotero.groups.copyChildLinks" type="bool"/>
<preference id="pref-groups-copyTags" name="extensions.zotero.groups.copyTags" type="bool"/>
</preferences>
<groupbox id="zotero-prefpane-file-handling-groupbox">
<caption label="&zotero.preferences.fileHandling;"/>
<checkbox id="automaticSnapshots-checkbox"
label="&zotero.preferences.automaticSnapshots;"
preference="pref-automaticSnapshots"/>
<checkbox label="&zotero.preferences.downloadAssociatedFiles;" preference="pref-downloadAssociatedFiles"/>
<checkbox label="&zotero.preferences.autoRecognizeFiles;" preference="pref-autoRecognizeFiles"/>
<checkbox label="&zotero.preferences.autoRenameFiles;"
preference="pref-autoRenameFiles"
oncommand="Zotero_Preferences.General.updateAutoRenameFilesUI()"/>
<checkbox id="rename-linked-files" class="indented-pref"
label="&zotero.preferences.autoRenameFiles.renameLinked;"
preference="pref-autoRenameFilesLinked"
oncommand="Zotero_Preferences.General.updateAutoRenameFilesUI()"/>
<hbox align="center">
<label value="&zotero.preferences.fileHandler.openPDFsUsing;" control="file-handler-pdf"/>
<menulist id="fileHandler-pdf" class="fileHandler-menu">
<menupopup>
<menuitem id="fileHandler-internal"
oncommand="Zotero_Preferences.General.setFileHandler('pdf', '')"/>
<menuitem label="&zotero.preferences.fileHandler.systemDefault;"
oncommand="Zotero_Preferences.General.setFileHandler('pdf', 'system')"/>
<menuitem id="fileHandler-custom"/>
<menuitem label="&zotero.preferences.custom;"
oncommand="Zotero_Preferences.General.chooseFileHandler('pdf')"/>
</menupopup>
</menulist>
</hbox>
</groupbox>
<groupbox id="zotero-prefpane-miscellaneous-groupbox">
<caption label="&zotero.preferences.miscellaneous;"/>
<checkbox label="&zotero.preferences.automaticTags;" preference="pref-automaticTags"/>
<hbox align="center">
<label value="&zotero.preferences.trashAutoEmptyDaysPre;"/>
<textbox size="2" preference="pref-trashAutoEmptyDays"/>
<label value="&zotero.preferences.trashAutoEmptyDaysPost;"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.groups;"/>
<label value="&zotero.preferences.groups.whenCopyingInclude;"/>
<vbox style="margin-left: 2em">
<checkbox label="&zotero.preferences.groups.childNotes;" preference="pref-groups-copyChildNotes"/>
<checkbox label="&zotero.preferences.groups.childFiles;" preference="pref-groups-copyChildFileAttachments"/>
<checkbox label="&zotero.preferences.groups.annotations;" preference="pref-groups-copyAnnotations"/>
<checkbox label="&zotero.preferences.groups.childLinks;" preference="pref-groups-copyChildLinks"/>
<checkbox label="&zotero.preferences.groups.tags;" preference="pref-groups-copyTags"/>
</vbox>
</groupbox>
<separator/>
<separator/>
</prefpane>
<!-- Sync -->
<prefpane id="zotero-prefpane-sync"
label="&zotero.preferences.prefpane.sync;"
image="chrome://zotero/skin/prefs-sync.png"
src="chrome://zotero/content/preferences/preferences_sync.xul"
onpaneload="Zotero_Preferences.Sync.init()"
helpTopic="sync">
<preferences>
<preference id="pref-sync-autosync" name="extensions.zotero.sync.autoSync" type="bool"/>
<preference id="pref-sync-username" name="extensions.zotero.sync.server.username" type="unichar" instantApply="true"/>
<preference id="pref-sync-fulltext-enabled" name="extensions.zotero.sync.fulltext.enabled" type="bool"/>
<preference id="pref-storage-enabled" name="extensions.zotero.sync.storage.enabled" type="bool"/>
<preference id="pref-storage-protocol" name="extensions.zotero.sync.storage.protocol" type="string"/>
<preference id="pref-storage-scheme" name="extensions.zotero.sync.storage.scheme" type="string" instantApply="true"/>
<preference id="pref-storage-url" name="extensions.zotero.sync.storage.url" type="string"/>
<preference id="pref-storage-username" name="extensions.zotero.sync.storage.username" type="string"/>
<preference id="pref-storage-downloadMode-personal" name="extensions.zotero.sync.storage.downloadMode.personal" type="string"/>
<preference id="pref-storage-downloadMode-groups" name="extensions.zotero.sync.storage.downloadMode.groups" type="string"/>
<preference id="pref-storage-groups-enabled" name="extensions.zotero.sync.storage.groups.enabled" type="bool"/>
</preferences>
<tabbox>
<tabs>
<tab label="&zotero.preferences.settings;"/>
<tab id="sync-reset-tab" label="&zotero.preferences.sync.reset;" disabled="true"/>
</tabs>
<tabpanels>
<tabpanel orient="vertical">
<vbox id="sync-unauthorized">
<groupbox>
<caption label="&zotero.preferences.sync.syncServer;"/>
<hbox>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<label value="&zotero.preferences.sync.username;"/>
<textbox id="sync-username-textbox"
preference="pref-sync-username"
onblur="Zotero_Preferences.Sync.trimUsername()"
oninput="Zotero_Preferences.Sync.credentialsChange(event)"
onchange="Zotero_Preferences.Sync.credentialsChange(event)"
onkeypress="Zotero_Preferences.Sync.credentialsKeyPress(event)"/>
</row>
<row>
<label value="&zotero.preferences.sync.password;"/>
<textbox id="sync-password" type="password"
oninput="Zotero_Preferences.Sync.credentialsChange(event)"
onchange="Zotero_Preferences.Sync.credentialsChange(event)"
onkeypress="Zotero_Preferences.Sync.credentialsKeyPress(event)"/>
</row>
<row>
<box/>
<hbox align="baseline">
<button id="sync-auth-button"
label="&zotero.preferences.sync.setUpSync;"
oncommand="Zotero_Preferences.Sync.linkAccount(event)"
disabled="true"/>
<label id="sync-status-indicator"/>
</hbox>
</row>
</rows>
</grid>
<vbox style="width:2em"/>
<vbox>
<label class="zotero-text-link" value="&zotero.preferences.sync.createAccount;" href="http://zotero.org/user/register"/>
<separator class="thin"/>
<label class="zotero-text-link" value="&zotero.preferences.sync.lostPassword;" href="http://zotero.org/user/lostpassword"/>
<separator class="thin"/>
<label class="zotero-text-link" value="&zotero.preferences.sync.about;" href="http://www.zotero.org/support/sync"/>
</vbox>
</hbox>
</groupbox>
</vbox>
<vbox id="sync-authorized" hidden="true">
<groupbox>
<caption label="&zotero.preferences.sync.syncServer;"/>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<label value="&zotero.preferences.sync.username;"/>
<hbox>
<label id="sync-username" value="Username"/>
<button label="&zotero.preferences.sync.unlinkAccount;"
oncommand="Zotero_Preferences.Sync.unlinkAccount()"/>
</hbox>
</row>
<row>
<box/>
<box>
<button id="sync-libraries-button" label="&zotero.preferences.sync.librariesToSync.button;"
oncommand="Zotero_Preferences.Sync.showLibrariesToSyncDialog()"/>
</box>
</row>
<row>
<box/>
<checkbox label="&zotero.preferences.sync.syncAutomatically;"
preference="pref-sync-autosync"/>
</row>
<row>
<box/>
<checkbox label="&zotero.preferences.sync.syncFullTextContent;"
preference="pref-sync-fulltext-enabled"
tooltiptext="&zotero.preferences.sync.syncFullTextContent.desc;"/>
</row>
<row>
<box/>
<label class="zotero-text-link" value="&zotero.preferences.sync.about;" href="http://www.zotero.org/support/sync"/>
</row>
</rows>
</grid>
</groupbox>
<groupbox id="storage-settings">
<caption label="&zotero.preferences.sync.fileSyncing;"/>
<!-- My Library -->
<hbox>
<checkbox label="&zotero.preferences.sync.fileSyncing.myLibrary;"
preference="pref-storage-enabled"
oncommand="Zotero_Preferences.Sync.onStorageSettingsChange()"/>
<menulist id="storage-protocol" class="storage-personal"
style="margin-left: .5em"
preference="pref-storage-protocol"
oncommand="Zotero_Preferences.Sync.onStorageSettingsChange()">
<menupopup>
<menuitem label="Zotero" value="zotero"/>
<menuitem label="WebDAV" value="webdav"/>
</menupopup>
</menulist>
</hbox>
<stack id="storage-webdav-settings" style="margin-top: .5em; margin-bottom: .8em; border: 1px gray solid; border-radius: 3px">
<!-- Background shading -->
<box style="background: black; opacity:.03"/>
<grid style="padding: .7em .4em .7em 0">
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row>
<label value="&zotero.preferences.sync.fileSyncing.url;"/>
<hbox>
<menulist id="storage-url-prefix"
preference="pref-storage-scheme"
onsynctopreference="Zotero_Preferences.Sync.unverifyStorageServer()"
style="padding: 0; width: 7em">
<menupopup>
<menuitem label="https" value="https" style="padding: 0"/>
<menuitem label="http" value="http" style="padding: 0"/>
</menupopup>
</menulist>
<label value="://"/>
<textbox id="storage-url" flex="1"
preference="pref-storage-url"
onkeypress="Zotero_Preferences.Sync.onStorageSettingsKeyPress(event)"
onchange="Zotero_Preferences.Sync.onStorageSettingsChange()"/>
<label value="/zotero/"/>
</hbox>
</row>
<row>
<label value="&zotero.preferences.sync.username;"/>
<hbox>
<textbox id="storage-username"
preference="pref-storage-username"
onkeypress="Zotero_Preferences.Sync.onStorageSettingsKeyPress(event)"
onchange="Zotero_Preferences.Sync.onStorageSettingsChange()"/>
</hbox>
</row>
<row>
<label value="&zotero.preferences.sync.password;"/>
<hbox>
<textbox id="storage-password" flex="0" type="password"
onkeypress="Zotero_Preferences.Sync.onStorageSettingsKeyPress(event)"
onchange="Zotero_Preferences.Sync.onStorageSettingsChange()"/>
</hbox>
</row>
<row>
<box/>
<hbox>
<button id="storage-verify" label="&zotero.preferences.sync.fileSyncing.verifyServer;"
oncommand="Zotero_Preferences.Sync.verifyStorageServer()"/>
<button id="storage-abort" label="Stop" hidden="true"/>
<progressmeter id="storage-progress" hidden="true"
mode="undetermined"/>
</hbox>
</row>
</rows>
</grid>
</stack>
<hbox class="storage-settings-download-options" align="center">
<label value="&zotero.preferences.sync.fileSyncing.download;"/>
<menulist id="storage-user-download-mode"
class="storage-mode"
preference="pref-storage-downloadMode-personal"
style="margin-left: 0">
<menupopup>
<menuitem label="&zotero.preferences.sync.fileSyncing.download.onDemand;" value="on-demand"/>
<menuitem label="&zotero.preferences.sync.fileSyncing.download.atSyncTime;" value="on-sync"/>
</menupopup>
</menulist>
</hbox>
<separator id="storage-separator" class="thin"/>
<!-- Group Libraries -->
<checkbox label="&zotero.preferences.sync.fileSyncing.groups;"
preference="pref-storage-groups-enabled"
oncommand="Zotero_Preferences.Sync.updateStorageSettingsGroupsUI()"/>
<hbox class="storage-settings-download-options" align="center">
<label value="&zotero.preferences.sync.fileSyncing.download;"/>
<menulist id="storage-groups-download-mode"
class="storage-mode"
preference="pref-storage-downloadMode-groups"
style="margin-left: 0">
<menupopup>
<menuitem label="&zotero.preferences.sync.fileSyncing.download.onDemand;" value="on-demand"/>
<menuitem label="&zotero.preferences.sync.fileSyncing.download.atSyncTime;" value="on-sync"/>
</menupopup>
</menulist>
</hbox>
<separator class="thin"/>
<vbox id="storage-terms">
<hbox style="margin-top: .4em; display: block" align="center">
<label>&zotero.preferences.sync.fileSyncing.tos1;</label>
<label class="zotero-text-link" href="https://www.zotero.org/support/terms/terms_of_service" value="&zotero.preferences.sync.fileSyncing.tos2;"/>
<label>&zotero.preferences.period;</label>
</hbox>
</vbox>
</groupbox>
</vbox>
</tabpanel>
<tabpanel id="sync-reset" orient="vertical">
<!-- This doesn't wrap without an explicit width, for some reason -->
<description id="reset-sync-warning" width="45em">&zotero.preferences.sync.reset.warning1;<label style="margin-left: 0; margin-right: 0" class="zotero-text-link" href="http://zotero.org/support/kb/sync_reset_options">&zotero.preferences.sync.reset.warning2;</label>&zotero.preferences.sync.reset.warning3;</description>
<div id="sync-reset-form" xmlns="http://www.w3.org/1999/xhtml">
<div id="sync-reset-library-menu-container">
<label>Library: <select id="sync-reset-library-menu"/></label>
</div>
<ul id="sync-reset-list">
<!--<li>
<p>&zotero.preferences.sync.reset.restoreFromServer;</p>
<p>&zotero.preferences.sync.reset.restoreFromServer.desc;</p>
</li>-->
<li id="restore-to-server">
<label>
<input name="sync-reset-radiogroup" value="restore-to-server" type="radio"/>
<span class="sync-reset-option-name">&zotero.preferences.sync.reset.restoreToServer;</span>
<span class="sync-reset-option-desc">&zotero.preferences.sync.reset.restoreToServer.desc;</span>
</label>
</li>
<!--<li>
<h2>&zotero.preferences.sync.reset.resetDataSyncHistory;</h2>
<description>&zotero.preferences.sync.reset.resetDataSyncHistory.desc;</p>
</li>-->
<li id="reset-file-sync-history">
<label>
<input name="sync-reset-radiogroup" value="reset-file-sync-history" type="radio"/>
<span class="sync-reset-option-name">&zotero.preferences.sync.reset.resetFileSyncHistory;</span>
<span class="sync-reset-option-desc">&zotero.preferences.sync.reset.resetFileSyncHistory.desc;</span>
</label>
</li>
</ul>
<button id="sync-reset-button"
disabled="disabled"
onclick="Zotero_Preferences.Sync.reset()">&zotero.preferences.sync.reset.button;</button>
</div>
</tabpanel>
</tabpanels>
</tabbox>
<separator/>
<separator/>
</prefpane>
<!-- Search -->
<prefpane id="zotero-prefpane-search"
label="&zotero.preferences.prefpane.search;"
image="chrome://zotero/skin/prefs-search.png"
onpaneload="Zotero_Preferences.Search.init()"
helpTopic="search">
<preferences>
<preference id="pref-fulltext-textMaxLength" name="extensions.zotero.fulltext.textMaxLength" type="int"/>
<preference id="pref-fulltext-pdfmaxpages" name="extensions.zotero.fulltext.pdfMaxPages" type="int"/>
</preferences>
<groupbox>
<caption label="&zotero.preferences.search.fulltextCache;"/>
<hbox>
<button id="fulltext-rebuildIndex" flex="1" oncommand="Zotero_Preferences.Search.rebuildIndexPrompt()"/>
<button id="fulltext-clearIndex" flex="1" oncommand="Zotero_Preferences.Search.clearIndexPrompt()"/>
</hbox>
<separator/>
<hbox align="center">
<label value="&zotero.preferences.fulltext.textMaxLength;"/>
<textbox size="10" preference="pref-fulltext-textMaxLength"/>
<label value="(&zotero.preferences.default; 500000)"/>
</hbox>
<separator class="thin"/>
<hbox align="center">
<label value="&zotero.preferences.fulltext.pdfMaxPages;"/>
<textbox size="5" preference="pref-fulltext-pdfmaxpages"/>
<label value="(&zotero.preferences.default; 100)"/>
</hbox>
</groupbox>
<groupbox id="fulltext-stats">
<caption label="&zotero.preferences.search.indexStats;"/>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row id="fulltext-stats-indexed">
<label value="&zotero.preferences.search.indexStats.indexed;"/>
<label/>
</row>
<row id="fulltext-stats-partial">
<label value="&zotero.preferences.search.indexStats.partial;"/>
<label/>
</row>
<row id="fulltext-stats-unindexed">
<label value="&zotero.preferences.search.indexStats.unindexed;"/>
<label/>
</row>
<row id="fulltext-stats-words">
<label value="&zotero.preferences.search.indexStats.words;"/>
<label/>
</row>
</rows>
</grid>
</groupbox>
<separator/>
<separator/>
</prefpane>
<!-- Export -->
<prefpane id="zotero-prefpane-export"
label="&zotero.preferences.prefpane.export;"
image="chrome://zotero/skin/prefs-export.png"
onpaneload="Zotero_Preferences.Export.init()"
helpTopic="export">
<preferences>
<preference id="pref-quickCopy-setting" name="extensions.zotero.export.quickCopy.setting" type="string"/>
<preference id="pref-quickCopy-dragLimit" name="extensions.zotero.export.quickCopy.dragLimit" type="int"/>
<preference id="pref-quickCopy-locale" name="extensions.zotero.export.quickCopy.locale" type="string"/>
<preference id="pref-noteQuickCopy-setting" name="extensions.zotero.export.noteQuickCopy.setting" type="string"/>
<preference id="pref-import-charset" name="extensions.zotero.import.charset" type="string"/>
</preferences>
<groupbox id="zotero-prefpane-export-groupbox">
<caption label="&zotero.preferences.quickCopy.caption;"/>
<label id="quickCopy-instructions"/>
<separator class="thin"/>
<label id="quickCopy-citationInstructions"/>
<separator/>
<label value="&zotero.preferences.quickCopy.itemFormat;" control="quickCopy-menu"/>
<menulist id="zotero-quickCopy-menu" label="&zotero.general.loading;"/>
<hbox align="center">
<label id="zotero-quickCopy-locale-menu-label" value="&zotero.bibliography.locale.label;" control="zotero-quickCopy-locale-menu"/>
<menulist id="zotero-quickCopy-locale-menu" oncommand="Zotero_Preferences.Export._lastSelectedLocale = this.value"/>
<separator orient="vertical" width="15px"/>
<checkbox id="zotero-quickCopy-copyAsHTML" label="&zotero.preferences.quickCopy.copyAsHTML;"
oncommand="Zotero_Preferences.Export.onCopyAsHTMLChange(this.checked)"/>
</hbox>
<separator/>
<label value="&zotero.preferences.quickCopy.noteFormat;" control="zotero-noteQuickCopy-menu"/>
<menulist id="zotero-noteQuickCopy-menu" label="&zotero.general.loading;"/>
<separator/>
<label value="&zotero.preferences.quickCopy.siteEditor.setings;" control="quickCopy-siteSettings"/>
<hbox class="virtualized-table-container" flex="1" height="120px">
<html:div id="quickCopy-siteSettings"/>
</hbox>
<separator class="thin"/>
<hbox>
<button disabled="true" id="quickCopy-edit" label="&zotero.general.edit;"
onclick="Zotero_Preferences.Export.showQuickCopySiteEditor(true)"/>
<spacer flex="1"/>
<button disabled="true" id="quickCopy-delete" label="-" onclick="Zotero_Preferences.Export.deleteSelectedQuickCopySite()"/>
<button label="+"
onclick="Zotero_Preferences.Export.showQuickCopySiteEditor()"/>
</hbox>
<hbox align="center">
<label value="&zotero.preferences.quickCopy.dragLimit;"/>
<textbox preference="pref-quickCopy-dragLimit" size="3"/>
<label value="&zotero.preferences.items;" flex="1"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.charset;"/>
<hbox align="center">
<label value="&zotero.preferences.charset.importCharset;:" control="zotero-import-charsetMenu"/>
<menulist id="zotero-import-charsetMenu" preference="pref-import-charset"/>
</hbox>
</groupbox>
</prefpane>
<!-- Cite -->
<prefpane id="zotero-prefpane-cite"
label="&zotero.preferences.prefpane.cite;"
image="chrome://zotero/skin/prefs-styles.png"
onpaneload="Zotero_Preferences.Cite.init()"
helpTopic="cite">
<preferences id="zotero-preferences-cite">
<preference id="pref-cite-useClassicAddCitationDialog" name="extensions.zotero.integration.useClassicAddCitationDialog" type="bool"/>
<preference id="pref-cite-citePaperJournalArticleURL" name="extensions.zotero.export.citePaperJournalArticleURL" type="bool"/>
</preferences>
<tabbox>
<tabs>
<tab id="styles-tab" label="&zotero.preferences.cite.styles;"/>
<tab id="wordProcessors-tab" label="&zotero.preferences.cite.wordProcessors;"/>
</tabs>
<tabpanels>
<tabpanel orient="vertical" id="styles">
<groupbox flex="1">
<caption label="&zotero.preferences.cite.styles.styleManager;"/>
<hbox class="virtualized-table-container" flex="1" height="300px">
<html:div id="styleManager"/>
</hbox>
<separator class="thin"/>
<hbox align="center" flex="1" height="40">
<label class="zotero-text-link"
value="&zotero.preferences.export.getAdditionalStyles;" flex="1"
onclick="Zotero_Preferences.Cite.openStylesPage(); event.preventDefault()"/>
<button disabled="true" id="styleManager-delete" label="-"
oncommand="Zotero_Preferences.Cite.deleteStyle()"/>
<button label="+" oncommand="Zotero_Preferences.Cite.addStyle()"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.citationOptions.caption;"/>
<checkbox label="&zotero.preferences.export.citePaperJournalArticleURL;" preference="pref-cite-citePaperJournalArticleURL"/>
<!-- This doesn't wrap without an explicit width, for some reason -->
<label id="export-citePaperJournalArticleURL" width="45em">
&zotero.preferences.export.citePaperJournalArticleURL.description;
</label>
</groupbox>
<groupbox>
<caption label="&zotero.general.tools;"/>
<hbox>
<button id="openCSLEdit"
label="&zotero.preferences.styleEditor;"
oncommand="Zotero_Preferences.openInViewer('chrome://zotero/content/tools/csledit.xhtml', true)"/>
<button id="openCSLPreview"
label="&zotero.preferences.stylePreview;"
oncommand="Zotero_Preferences.openInViewer('chrome://zotero/content/tools/cslpreview.xul', true)"/>
</hbox>
</groupbox>
</tabpanel>
<tabpanel orient="vertical" id="wordProcessors">
<vbox id="wordProcessors-somePluginsDisabled" hidden="true">
<label style="font-weight: bold; margin-top: 1em; text-align: center">Some word processor plugins are disabled.</label>
<hbox pack="center" style="margin-bottom: 2em">
<button id="wordProcessors-enablePlugins"
label="Enable Plugins and Restart Zotero"
oncommand="Zotero_Preferences.Cite.enableWordPlugins()"/>
</hbox>
</vbox>
<checkbox label="&zotero.preferences.cite.wordProcessors.useClassicAddCitationDialog;" preference="pref-cite-useClassicAddCitationDialog"/>
</tabpanel>
</tabpanels>
</tabbox>
</prefpane>
<!-- Advanced -->
<prefpane id="zotero-prefpane-advanced"
label="&zotero.preferences.prefpane.advanced;"
image="chrome://zotero/skin/prefs-advanced.png"
onpaneload="Zotero_Preferences.Advanced.init()"
helpTopic="advanced">
<preferences>
<preference id="pref-automaticScraperUpdates" name="extensions.zotero.automaticScraperUpdates" type="bool"/>
<preference id="pref-reportTranslationFailure" name="extensions.zotero.reportTranslationFailure" type="bool"/>
<preference id="pref-baseAttachmentPath" name="extensions.zotero.baseAttachmentPath" type="string"/>
<preference id="pref-useDataDir" name="extensions.zotero.useDataDir" type="bool"/>
<preference id="pref-dataDir" name="extensions.zotero.dataDir" type="string"/>
<preference id="pref-debug-output-enableAfterRestart" name="extensions.zotero.debug.store" type="bool"/>
<preference id="pref-openURL-resolver" name="extensions.zotero.openURL.resolver" type="string"/>
<preference id="pref-openURL-version" name="extensions.zotero.openURL.version" type="string"/>
<preference id="pref-keys-saveToZotero" name="extensions.zotero.keys.saveToZotero" type="string"/>
<preference id="pref-keys-library" name="extensions.zotero.keys.library" type="string"/>
<preference id="pref-keys-quicksearch" name="extensions.zotero.keys.quicksearch" type="string"/>
<preference id="pref-keys-newItem" name="extensions.zotero.keys.newItem" type="string"/>
<preference id="pref-keys-newNote" name="extensions.zotero.keys.newNote" type="string"/>
<preference id="pref-keys-toggleRead" name="extensions.zotero.keys.toggleRead" type="string"/>
<preference id="pref-keys-toggleAllRead" name="extensions.zotero.keys.toggleAllRead" type="string"/>
<preference id="pref-keys-copySelectedItemCitationsToClipboard" name="extensions.zotero.keys.copySelectedItemCitationsToClipboard" type="string"/>
<preference id="pref-keys-copySelectedItemsToClipboard" name="extensions.zotero.keys.copySelectedItemsToClipboard" type="string"/>
<preference id="pref-feeds-sortAscending" name="extensions.zotero.feeds.sortAscending" type="bool"/>
</preferences>
<tabbox id="zotero-prefpane-advanced-tabs">
<tabs>
<tab label="&zotero.preferences.prefpane.general;"/>
<tab label="&zotero.preferences.advanced.filesAndFolders;"/>
<tab label="&zotero.preferences.advanced.keys;"/>
<tab label="&zotero.preferences.feeds;"/>
</tabs>
<tabpanels id="zotero-prefpane-advanced-tabpanels">
<tabpanel id="zotero-prefpane-advanced-general-tab" orient="vertical">
<groupbox id="zotero-prefpane-advanced-miscellaneous">
<caption label="&zotero.preferences.miscellaneous;"/>
<hbox align="center">
<checkbox label="&zotero.preferences.autoUpdate;" preference="pref-automaticScraperUpdates"/>
<button id="updateButton" style="margin-top:0" label="&zotero.preferences.updateNow;"
oncommand="Zotero_Preferences.Advanced.updateTranslators()"/>
</hbox>
<checkbox label="&zotero.preferences.reportTranslationFailure;" preference="pref-reportTranslationFailure"/>
<hbox align="center">
<label value="&zotero.bibliography.locale.label;"/>
<menulist id="locale-menu"
onblur="if (!Zotero.isMac) Zotero_Preferences.Advanced.onLocaleChange()">
<menupopup onpopuphidden="Zotero_Preferences.Advanced.onLocaleChange()"/>
</menulist>
</hbox>
</groupbox>
<groupbox>
<caption label="OpenURL"/>
<hbox>
<menulist id="openurl-menu">
<menupopup
id="openurl-primary-popup"
onpopupshowing="Zotero_Preferences.Advanced.handleOpenURLPopupShowing(event)"
oncommand="Zotero_Preferences.Advanced.handleOpenURLSelected(event)">
<menuitem label="&zotero.preferences.openurl.choose;"/>
</menupopup>
</menulist>
</hbox>
<hbox align="center">
<label value="&zotero.preferences.openurl.server;"/>
<textbox id="openURLServerField" flex="1"
oninput="Zotero_Preferences.Advanced.onOpenURLCustomized();"
preference="pref-openURL-resolver"
/>
</hbox>
<hbox align="center">
<label value="&zotero.preferences.openurl.version;" control="openURLVersionMenu"/>
<menulist id="openURLVersionMenu"
oncommand="Zotero_Preferences.Advanced.onOpenURLCustomized();"
preference="pref-openURL-version">
<menupopup>
<menuitem label="0.1" value="0.1"/>
<menuitem label="1.0" value="1.0"/>
</menupopup>
</menulist>
</hbox>
</groupbox>
<groupbox id="zotero-prefpane-advanced-advancedConfiguration">
<caption label="&zotero.preferences.advanced.advancedConfiguration;"/>
<hbox id="zotero-prefpane-advanced-openbuttons" align="center" style="display: block">
<button id="config-editor"
label="&zotero.preferences.configEditor;"
oncommand="Zotero_Preferences.openInViewer('about:config')"/>
<button id="memory-info"
label="Memory Info"
oncommand="Zotero_Preferences.openInViewer('about:memory')"
hidden="true"/>
</hbox>
</groupbox>
</tabpanel>
<tabpanel orient="vertical">
<groupbox>
<caption label="&zotero.preferences.attachmentBaseDir.caption;"/>
<!-- This doesn't wrap without an explicit width -->
<vbox>
<description width="45em">&zotero.preferences.attachmentBaseDir.message;</description>
</vbox>
<hbox align="center">
<label value="&zotero.preferences.attachmentBaseDir.basePath;"/>
<filefield id="baseAttachmentPath"
preference="pref-baseAttachmentPath"
onsyncfrompreference="Zotero_Preferences.Attachment_Base_Directory.updateUI()"
preference-editable="true"
readonly="true"
flex="1"
tabindex="-1"/>
<button id="baseAttachmentPathButton"
label="&zotero.preferences.attachmentBaseDir.selectBasePath;"
oncommand="Zotero_Preferences.Attachment_Base_Directory.choosePath()"/>
</hbox>
<hbox>
<button id="resetBasePath"
label="&zotero.preferences.attachmentBaseDir.resetBasePath;"
oncommand="Zotero_Preferences.Attachment_Base_Directory.clearPath()"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.dataDir;"/>
<radiogroup id="data-dir"
preference="pref-useDataDir"
onsyncfrompreference="return Zotero_Preferences.Advanced.onDataDirLoad()"
onsynctopreference="Zotero_Preferences.Advanced.onDataDirUpdate(event);">
<radio id="default-data-dir" label="&zotero.preferences.dataDir.useProfile;" value="false"/>
<hbox>
<radio label="&zotero.preferences.dataDir.custom;" value="true"/>
<textbox id="data-dir-path" preference="pref-dataDir"
onsyncfrompreference="return Zotero_Preferences.Advanced.getDataDirPath();"
readonly="true" flex="1"/>
<button label="&zotero.preferences.dataDir.choose;"
oncommand="return Zotero_Preferences.Advanced.chooseDataDir(event)"/>
</hbox>
</radiogroup>
<vbox id="command-line-data-dir" hidden="true">
<description id="command-line-data-dir-path"/>
<label value="&zotero.preferences.dataDir.viaCommandLine;"/>
</vbox>
<hbox>
<button label="&zotero.preferences.dataDir.reveal;"
oncommand="Zotero.DataDirectory.reveal()"/>
<button id="migrate-data-dir" label="&zotero.preferences.dataDir.migrate;"
oncommand="Zotero_Preferences.Advanced.migrateDataDirectory()" hidden="true"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.dbMaintenance;"/>
<hbox style="display: block">
<button label="&zotero.preferences.dbMaintenance.integrityCheck;"
oncommand="Zotero_Preferences.Advanced.runIntegrityCheck(this)"/>
<button id="reset-translators-button"
label="&zotero.preferences.dbMaintenance.resetTranslators;"
oncommand="Zotero_Preferences.Advanced.resetTranslators()"/>
<button id="reset-styles-button"
label="&zotero.preferences.dbMaintenance.resetStyles;"
oncommand="Zotero_Preferences.Advanced.resetStyles()"/>
</hbox>
</groupbox>
</tabpanel>
<tabpanel id="zotero-prefpane-advanced-keys-tab" orient="vertical">
<grid id="zotero-keys-grid">
<columns>
<column flex="1"/>
<column/>
<column/>
</columns>
<rows id="zotero-keys-rows">
<row id="zotero-keys-new-item">
<label value="&zotero.preferences.keys.newItem;" control="textbox-newItem"/>
<label class="modifier"/>
<textbox id="textbox-newItem" maxlength="1" size="1" preference="pref-keys-newItem"/>
</row>
<row>
<label value="&zotero.preferences.keys.newNote;" control="textbox-newNote"/>
<label class="modifier"/>
<textbox id="textbox-newNote" maxlength="1" size="1" preference="pref-keys-newNote"/>
</row>
<row id="zotero-keys-focus-libraries-pane">
<label value="&zotero.preferences.keys.focusLibrariesPane;" control="textbox-library"/>
<label class="modifier"/>
<textbox id="textbox-library" maxlength="1" size="1" preference="pref-keys-library"/>
</row>
<row>
<label value="&zotero.preferences.keys.quicksearch;" control="textbox-quicksearch"/>
<label class="modifier"/>
<textbox id="textbox-quicksearch" maxlength="1" size="1" preference="pref-keys-quicksearch"/>
</row>
<row>
<label value="&zotero.preferences.keys.copySelectedItemCitationsToClipboard;" control="textbox-copySelectedItemCitationsToClipboard"/>
<label class="modifier"/>
<textbox id="textbox-copySelectedItemCitationsToClipboard" maxlength="1" size="1"
preference="pref-keys-copySelectedItemCitationsToClipboard"
onchange="if (Zotero_Preferences.Export) { Zotero_Preferences.Export.updateQuickCopyInstructions(); }"/>
</row>
<row>
<label value="&zotero.preferences.keys.copySelectedItemsToClipboard;" control="textbox-copySelectedItemsToClipboard"/>
<label class="modifier"/>
<textbox id="textbox-copySelectedItemsToClipboard" maxlength="1" size="1"
preference="pref-keys-copySelectedItemsToClipboard"
onchange="if (Zotero_Preferences.Export) { Zotero_Preferences.Export.updateQuickCopyInstructions(); }"/>
</row>
<row>
<label value="&zotero.preferences.keys.toggleAllRead;" control="textbox-toggleAllRead"/>
<label class="modifier"/>
<textbox id="textbox-toggleAllRead" maxlength="1" size="1" preference="pref-keys-toggleAllRead"/>
</row>
</rows>
</grid>
<label class="statusLine" value="&zotero.preferences.keys.changesTakeEffect;"/>
<separator/>
</tabpanel>
<tabpanel id="zotero-prefpane-advanced-feeds-tab" orient="vertical">
<groupbox>
<hbox>
<hbox align="center">
<label value="&zotero.preferences.feeds.sorting.label;"/>
<menulist id="feed-sort" preference="pref-feeds-sortAscending">
<menupopup>
<menuitem label="&zotero.preferences.feeds.sorting.newest;" value="false"/>
<menuitem label="&zotero.preferences.feeds.sorting.oldest;" value="true"/>
</menupopup>
</menulist>
</hbox>
</hbox>
</groupbox>
<groupbox id="zotero-prefpane-advanced-feeds-feedDefaults">
<caption label="&zotero.preferences.feeds.feedDefaults;"/>
<hbox>
<hbox align="center">
<label value="&zotero.feedSettings.refresh.label1;"/>
<html:input class="html-input" type="number" min="1" step="1" size="3" data-preference="feeds.defaultTTL"/>
<label value="&zotero.feedSettings.refresh.label2;"/>
</hbox>
</hbox>
<hbox>
<hbox align="center">
<label value="&zotero.feedSettings.cleanupReadAfter.label1;"/>
<html:input class="html-input" type="number" min="1" step="1" size="2" data-preference="feeds.defaultCleanupUnreadAfter"/>
<label value="&zotero.feedSettings.cleanupReadAfter.label2;"/>
</hbox>
</hbox>
<hbox>
<hbox align="center">
<label value="&zotero.feedSettings.cleanupUnreadAfter.label1;"/>
<html:input class="html-input" type="number" min="1" step="1" size="2" data-preference="feeds.defaultCleanupReadAfter"/>
<label value="&zotero.feedSettings.cleanupUnreadAfter.label2;"/>
</hbox>
</hbox>
</groupbox>
</tabpanel>
</tabpanels>
</tabbox>
</prefpane>
</prefwindow>

View file

@ -26,11 +26,7 @@
Components.utils.import("resource://gre/modules/Services.jsm");
import FilePicker from 'zotero/modules/filePicker';
Zotero_Preferences.Advanced = {
DEFAULT_OPENURL_RESOLVER: 'https://www.worldcat.org/registry/gateway',
_openURLResolvers: null,
Zotero_Preferences.Advanced = {
init: function () {
Zotero_Preferences.Keys.init();
@ -51,16 +47,31 @@ Zotero_Preferences.Advanced = {
input.value = Zotero.Prefs.get(preferenceName);
}
// Set OpenURL resolver drop-down to last-known name
if (Zotero.Prefs.get('openURL.resolver')) {
let name = Zotero.Prefs.get('openURL.name');
if (name) {
document.getElementById('openurl-primary-popup').firstChild.setAttribute('label', name);
}
}
document.getElementById('baseAttachmentPath').addEventListener('syncfrompreference',
() => Zotero_Preferences.Attachment_Base_Directory.updateUI());
document.getElementById('data-dir').addEventListener('syncfrompreference', (event) => {
event.target.value = this.onDataDirLoad();
});
document.getElementById('data-dir').addEventListener('synctopreference', (event) => {
this.onDataDirUpdate(event);
});
document.getElementById('data-dir-path').addEventListener('syncfrompreference', (event) => {
event.target.value = this.getDataDirPath();
});
this.onDataDirLoad();
this.refreshLocale();
document.getElementById('fulltext-rebuildIndex').setAttribute('label',
Zotero.getString('zotero.preferences.search.rebuildIndex')
+ Zotero.getString('punctuation.ellipsis'));
document.getElementById('fulltext-clearIndex').setAttribute('label',
Zotero.getString('zotero.preferences.search.clearIndex')
+ Zotero.getString('punctuation.ellipsis'));
this.updateIndexStats();
},
@ -429,238 +440,97 @@ Zotero_Preferences.Advanced = {
return false;
},
handleOpenURLPopupShowing: async function (event) {
if (event.target.id != 'openurl-primary-popup') {
return;
}
if (!this._openURLResolvers) {
let menupopup = document.getElementById('openurl-primary-popup');
menupopup.firstChild.setAttribute('label', Zotero.getString('general.loading'));
try {
this._openURLResolvers = await Zotero.Utilities.Internal.OpenURL.getResolvers();
}
catch (e) {
Zotero.logError(e);
menupopup.firstChild.setAttribute('label', "Error loading resolvers");
return;
}
}
this.updateOpenURLResolversMenu();
},
updateIndexStats: Zotero.Promise.coroutine(function* () {
var stats = yield Zotero.Fulltext.getIndexStats();
document.getElementById('fulltext-stats-indexed')
.setAttribute('value', stats.indexed);
document.getElementById('fulltext-stats-partial')
.setAttribute('value', stats.partial);
document.getElementById('fulltext-stats-unindexed')
.setAttribute('value', stats.unindexed);
document.getElementById('fulltext-stats-words')
.setAttribute('value', stats.words);
}),
updateOpenURLResolversMenu: function () {
if (!this._openURLResolvers) {
Zotero.debug("Resolvers not loaded -- not updating menu");
return;
}
var currentResolver = Zotero.Prefs.get('openURL.resolver');
var openURLMenu = document.getElementById('openurl-menu');
var menupopup = openURLMenu.firstChild;
menupopup.innerHTML = '';
var defaultMenuItem = document.createElement('menuitem');
defaultMenuItem.setAttribute('label', Zotero.getString('general.default'));
defaultMenuItem.setAttribute('value', this.DEFAULT_OPENURL_RESOLVER);
defaultMenuItem.setAttribute('type', 'checkbox');
menupopup.appendChild(defaultMenuItem);
var customMenuItem = document.createElement('menuitem');
customMenuItem.setAttribute('label', Zotero.getString('general.custom'));
customMenuItem.setAttribute('value', 'custom');
customMenuItem.setAttribute('type', 'checkbox');
menupopup.appendChild(customMenuItem);
menupopup.appendChild(document.createElement('menuseparator'));
var selectedName;
var lastContinent;
var lastCountry;
var currentContinentPopup;
var currentMenuPopup;
for (let r of this._openURLResolvers) {
// Create submenus for continents
if (r.continent != lastContinent) {
let menu = document.createElement('menu');
menu.setAttribute('label', r.continent);
openURLMenu.firstChild.appendChild(menu);
currentContinentPopup = currentMenuPopup = document.createElement('menupopup');
menu.appendChild(currentContinentPopup);
lastContinent = r.continent;
}
if (r.country != lastCountry) {
// If there's a country, create a submenu for it
if (r.country) {
let menu = document.createElement('menu');
menu.setAttribute('label', r.country);
currentContinentPopup.appendChild(menu);
let menupopup = document.createElement('menupopup');
menu.appendChild(menupopup);
currentMenuPopup = menupopup;
}
// Otherwise use the continent popup
else {
currentMenuPopup = currentContinentPopup;
}
lastCountry = r.country;
}
let menuitem = document.createElement('menuitem');
menuitem.setAttribute('label', r.name);
menuitem.setAttribute('value', r.url);
menuitem.setAttribute('type', 'checkbox');
currentMenuPopup.appendChild(menuitem);
var checked = r.url == Zotero.Prefs.get('openURL.resolver');
menuitem.setAttribute('checked', checked);
if (checked) {
selectedName = r.name;
}
}
// Default
if (currentResolver == this.DEFAULT_OPENURL_RESOLVER) {
openURLMenu.setAttribute('label', Zotero.getString('general.default'));
defaultMenuItem.setAttribute('checked', true);
Zotero.Prefs.clear('openURL.name');
}
else if (selectedName) {
openURLMenu.setAttribute('label', selectedName);
// If we found a match, update stored name
Zotero.Prefs.set('openURL.name', selectedName);
}
// Custom
else {
openURLMenu.setAttribute('label', Zotero.getString('general.custom'));
customMenuItem.setAttribute('checked', true);
Zotero.Prefs.clear('openURL.name');
}
},
handleOpenURLSelected: function (event) {
event.stopPropagation();
event.preventDefault();
if (event.target.localName != 'menuitem') {
Zotero.debug("Ignoring click on " + event.target.localName);
return;
}
var openURLMenu = document.getElementById('openurl-menu');
var openURLServerField = document.getElementById('openURLServerField');
var openURLVersionMenu = document.getElementById('openURLVersionMenu');
// Default
if (event.target.value == this.DEFAULT_OPENURL_RESOLVER) {
Zotero.Prefs.clear('openURL.name');
Zotero.Prefs.clear('openURL.resolver');
Zotero.Prefs.clear('openURL.version');
openURLServerField.value = this.DEFAULT_OPENURL_RESOLVER;
}
// If "Custom" selected, clear URL field
else if (event.target.value == "custom") {
Zotero.Prefs.clear('openURL.name');
Zotero.Prefs.set('openURL.resolver', '');
Zotero.Prefs.clear('openURL.version');
openURLServerField.value = '';
openURLServerField.focus();
}
else {
Zotero.Prefs.set('openURL.name', openURLServerField.value = event.target.label);
Zotero.Prefs.set('openURL.resolver', openURLServerField.value = event.target.value);
Zotero.Prefs.set('openURL.version', openURLVersionMenu.value = "1.0");
}
openURLMenu.firstChild.hidePopup();
setTimeout(() => {
this.updateOpenURLResolversMenu();
});
},
onOpenURLCustomized: function () {
setTimeout(() => {
this.updateOpenURLResolversMenu();
});
},
_getAutomaticLocaleMenuLabel: function () {
return Zotero.getString(
'zotero.preferences.locale.automaticWithLocale',
Zotero.Locale.availableLocales[Zotero.locale] || Zotero.locale
);
},
refreshLocale: function () {
var autoLocaleName, currentValue;
// If matching OS, get the name of the current locale
if (Zotero.Prefs.get('intl.locale.requested', true) === '') {
autoLocaleName = this._getAutomaticLocaleMenuLabel();
currentValue = 'automatic';
}
// Otherwise get the name of the locale specified in the pref
else {
autoLocaleName = Zotero.getString('zotero.preferences.locale.automatic');
currentValue = Zotero.locale;
}
// Populate menu
var menu = document.getElementById('locale-menu');
var menupopup = menu.firstChild;
menupopup.textContent = '';
// Show "Automatic (English)", "Automatic (Français)", etc.
menu.appendItem(autoLocaleName, 'automatic');
menu.menupopup.appendChild(document.createElement('menuseparator'));
// Add all available locales
for (let locale in Zotero.Locale.availableLocales) {
menu.appendItem(Zotero.Locale.availableLocales[locale], locale);
}
menu.value = currentValue;
},
onLocaleChange: function () {
var requestedLocale = Services.locale.requestedLocale;
var menu = document.getElementById('locale-menu');
if (menu.value == 'automatic') {
// Changed if not already set to automatic (unless we have the automatic locale name,
// meaning we just switched away to the same manual locale and back to automatic)
var changed = requestedLocale
&& requestedLocale == Zotero.locale
&& menu.label != this._getAutomaticLocaleMenuLabel();
Services.locale.requestedLocales = null;
}
else {
// Changed if moving to a locale other than the current one
var changed = requestedLocale != menu.value
Services.locale.requestedLocales = [menu.value];
}
if (!changed) {
return;
}
rebuildIndexPrompt: async function () {
var buttons = [
document.getElementById('fulltext-rebuildIndex'),
document.getElementById('fulltext-clearIndex')
];
buttons.forEach(b => b.disabled = true);
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.appName),
buttonFlags,
Zotero.getString('general.restartNow'),
Zotero.getString('general.restartLater'),
null, null, {});
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL
+ ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING;
if (index == 0) {
Zotero.Utilities.Internal.quitZotero(true);
var index = ps.confirmEx(null,
Zotero.getString('zotero.preferences.search.rebuildIndex'),
Zotero.getString('zotero.preferences.search.rebuildWarning',
Zotero.getString('zotero.preferences.search.indexUnindexed')),
buttonFlags,
Zotero.getString('zotero.preferences.search.rebuildIndex'),
null,
// Position 2 because of https://bugzilla.mozilla.org/show_bug.cgi?id=345067
Zotero.getString('zotero.preferences.search.indexUnindexed'),
null, {});
try {
if (index == 0) {
await Zotero.Fulltext.rebuildIndex();
}
else if (index == 2) {
await Zotero.Fulltext.rebuildIndex(true)
}
await this.updateIndexStats();
}
catch (e) {
Zotero.alert(null, Zotero.getString('general.error'), e);
}
finally {
buttons.forEach(b => b.disabled = false);
}
},
clearIndexPrompt: async function () {
var buttons = [
document.getElementById('fulltext-rebuildIndex'),
document.getElementById('fulltext-clearIndex')
];
buttons.forEach(b => b.disabled = true);
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.preferences.search.clearIndex'),
Zotero.getString('zotero.preferences.search.clearWarning',
Zotero.getString('zotero.preferences.search.clearNonLinkedURLs')),
buttonFlags,
Zotero.getString('zotero.preferences.search.clearIndex'),
null,
// Position 2 because of https://bugzilla.mozilla.org/show_bug.cgi?id=345067
Zotero.getString('zotero.preferences.search.clearNonLinkedURLs'), null, {});
try {
if (index == 0) {
await Zotero.Fulltext.clearIndex();
}
else if (index == 2) {
await Zotero.Fulltext.clearIndex(true);
}
await this.updateIndexStats();
}
catch (e) {
Zotero.alert(null, Zotero.getString('general.error'), e);
}
finally {
buttons.forEach(b => b.disabled = false);
}
}
};
@ -943,50 +813,47 @@ Zotero_Preferences.Attachment_Base_Directory = {
}),
updateUI: Zotero.Promise.coroutine(function* () {
updateUI: async function () {
var filefield = document.getElementById('baseAttachmentPath');
var path = Zotero.Prefs.get('baseAttachmentPath');
Components.utils.import("resource://gre/modules/osfile.jsm");
if (yield OS.File.exists(path)) {
filefield.file = Zotero.File.pathToFile(path);
filefield.label = path;
if (await OS.File.exists(path)) {
filefield.style.backgroundImage = 'url(moz-icon://file://' + path + '?size=16)';
filefield.value = path;
}
else {
filefield.label = '';
filefield.value = '';
}
document.getElementById('resetBasePath').disabled = !path;
})
}
};
Zotero_Preferences.Keys = {
init: function () {
var rows = document.getElementById('zotero-prefpane-advanced-keys-tab').getElementsByTagName('row');
for (var i=0; i<rows.length; i++) {
for (let label of document.querySelectorAll('#zotero-keys-grid .modifier')) {
// Display the appropriate modifier keys for the platform
let label = rows[i].firstChild.nextSibling;
if (label.className == 'modifier') {
label.value = Zotero.isMac ? Zotero.getString('general.keys.cmdShift') : Zotero.getString('general.keys.ctrlShift');
}
label.value = Zotero.isMac ? Zotero.getString('general.keys.cmdShift') : Zotero.getString('general.keys.ctrlShift');
}
var textboxes = document.getElementById('zotero-keys-rows').getElementsByTagName('textbox');
var textboxes = document.querySelectorAll('#zotero-keys-grid input');
for (let i=0; i<textboxes.length; i++) {
let textbox = textboxes[i];
textbox.value = textbox.value.toUpperCase();
// .value takes care of the initial value, and this takes care of direct pref changes
// while the window is open
textbox.setAttribute('onsyncfrompreference', 'return Zotero_Preferences.Keys.capitalizePref(this.id)');
textbox.setAttribute('oninput', 'this.value = this.value.toUpperCase()');
textbox.addEventListener('syncfrompreference', () => {
textbox.value = Zotero_Preferences.Keys.capitalizePref(textbox.id) || '';
});
textbox.addEventListener('input', () => {
textbox.value = textbox.value.toUpperCase();
});
}
},
capitalizePref: function (id) {
var elem = document.getElementById(id);
var pref = document.getElementById(elem.getAttribute('preference'));
if (pref.value) {
return pref.value.toUpperCase();
}
return Zotero.Prefs.get(elem.getAttribute('preference'), true).toUpperCase();
}
};

View file

@ -0,0 +1,265 @@
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062022 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 *****
-->
<vbox id="zotero-prefpane-advanced" onload="Zotero_Preferences.Advanced.init()">
<vbox class="main-section" id="zotero-prefpane-advanced-general-tab">
<html:h1>&zotero.preferences.prefpane.general;</html:h1>
<groupbox id="zotero-prefpane-advanced-miscellaneous">
<html:label><html:h2>&zotero.preferences.miscellaneous;</html:h2></html:label>
<hbox align="center">
<checkbox label="&zotero.preferences.autoUpdate;" preference="extensions.zotero.automaticScraperUpdates" native="true"/>
<button id="updateButton" style="margin-top:0" label="&zotero.preferences.updateNow;"
oncommand="Zotero_Preferences.Advanced.updateTranslators()"/>
</hbox>
<checkbox label="&zotero.preferences.reportTranslationFailure;" preference="extensions.zotero.reportTranslationFailure" native="true"/>
</groupbox>
<groupbox id="zotero-prefpane-advanced-advancedConfiguration">
<html:label><html:h2>&zotero.preferences.advanced.advancedConfiguration;</html:h2></html:label>
<hbox id="zotero-prefpane-advanced-openbuttons" align="center" style="display: block">
<button id="config-editor"
label="&zotero.preferences.configEditor;"
oncommand="Zotero_Preferences.openInViewer('about:config')"/>
<button id="memory-info"
label="Memory Info"
oncommand="Zotero_Preferences.openInViewer('about:memory')"
hidden="true"/>
</hbox>
</groupbox>
</vbox>
<vbox class="main-section">
<html:h1>&zotero.preferences.advanced.filesAndFolders;</html:h1>
<groupbox>
<html:label><html:h2>&zotero.preferences.attachmentBaseDir.caption;</html:h2></html:label>
<!-- This doesn't wrap without an explicit width -->
<vbox>
<description style="width: 45em;">&zotero.preferences.attachmentBaseDir.message;</description>
</vbox>
<hbox align="center">
<label value="&zotero.preferences.attachmentBaseDir.basePath;"/>
<html:input type="text" id="baseAttachmentPath"
preference="extensions.zotero.baseAttachmentPath"
readonly="true"
flex="1"
tabindex="-1"/>
<button id="baseAttachmentPathButton"
label="&zotero.preferences.attachmentBaseDir.selectBasePath;"
oncommand="Zotero_Preferences.Attachment_Base_Directory.choosePath()"/>
</hbox>
<hbox>
<button id="resetBasePath"
label="&zotero.preferences.attachmentBaseDir.resetBasePath;"
oncommand="Zotero_Preferences.Attachment_Base_Directory.clearPath()"
data-search-strings="attachmentBasePath.clearBasePath.message"/>
</hbox>
</groupbox>
<groupbox>
<html:label><html:h2>&zotero.preferences.dataDir;</html:h2></html:label>
<radiogroup id="data-dir"
preference="extensions.zotero.useDataDir">
<radio id="default-data-dir" label="&zotero.preferences.dataDir.useProfile;" value="false"/>
<hbox>
<radio label="&zotero.preferences.dataDir.custom;" value="true"/>
<html:input type="text" id="data-dir-path" preference="extensions.zotero.dataDir"
readonly="true" style="-moz-box-flex: 1;"/>
<button label="&zotero.preferences.dataDir.choose;"
oncommand="return Zotero_Preferences.Advanced.chooseDataDir(event)"/>
</hbox>
</radiogroup>
<vbox id="command-line-data-dir" hidden="true">
<description id="command-line-data-dir-path"/>
<label value="&zotero.preferences.dataDir.viaCommandLine;"/>
</vbox>
<hbox>
<button label="&zotero.preferences.dataDir.reveal;"
oncommand="Zotero.DataDirectory.reveal()"/>
<button id="migrate-data-dir" label="&zotero.preferences.dataDir.migrate;"
oncommand="Zotero_Preferences.Advanced.migrateDataDirectory()" hidden="true"/>
</hbox>
</groupbox>
<groupbox>
<html:label><html:h2>&zotero.preferences.dbMaintenance;</html:h2></html:label>
<hbox style="display: block">
<button label="&zotero.preferences.dbMaintenance.integrityCheck;"
oncommand="Zotero_Preferences.Advanced.runIntegrityCheck(this)"/>
<button id="reset-translators-button"
label="&zotero.preferences.dbMaintenance.resetTranslators;"
oncommand="Zotero_Preferences.Advanced.resetTranslators()"/>
<button id="reset-styles-button"
label="&zotero.preferences.dbMaintenance.resetStyles;"
oncommand="Zotero_Preferences.Advanced.resetStyles()"/>
</hbox>
</groupbox>
</vbox>
<vbox class="main-section" id="zotero-prefpane-advanced-keys-tab">
<html:h1>&zotero.preferences.advanced.keys;</html:h1>
<html:div id="zotero-keys-grid">
<label value="&zotero.preferences.keys.newItem;" control="textbox-newItem"/>
<label class="modifier"/>
<html:input type="text" id="textbox-newItem" maxlength="1" size="1" preference="extensions.zotero.keys.newItem"/>
<label value="&zotero.preferences.keys.newNote;" control="textbox-newNote"/>
<label class="modifier"/>
<html:input type="text" id="textbox-newNote" maxlength="1" size="1" preference="extensions.zotero.keys.newNote"/>
<label value="&zotero.preferences.keys.focusLibrariesPane;" control="textbox-library"/>
<label class="modifier"/>
<html:input type="text" id="textbox-library" maxlength="1" size="1" preference="extensions.zotero.keys.library"/>
<label value="&zotero.preferences.keys.quicksearch;" control="textbox-quicksearch"/>
<label class="modifier"/>
<html:input type="text" id="textbox-quicksearch" maxlength="1" size="1" preference="extensions.zotero.keys.quicksearch"/>
<label value="&zotero.preferences.keys.copySelectedItemCitationsToClipboard;" control="textbox-copySelectedItemCitationsToClipboard"/>
<label class="modifier"/>
<html:input type="text" id="textbox-copySelectedItemCitationsToClipboard" maxlength="1" size="1"
preference="extensions.zotero.keys.copySelectedItemCitationsToClipboard"
oninput="if (Zotero_Preferences.Export) { Zotero_Preferences.Export.updateQuickCopyInstructions(); }"/>
<label value="&zotero.preferences.keys.copySelectedItemsToClipboard;" control="textbox-copySelectedItemsToClipboard"/>
<label class="modifier"/>
<html:input type="text" id="textbox-copySelectedItemsToClipboard" maxlength="1" size="1"
preference="extensions.zotero.keys.copySelectedItemsToClipboard"
oninput="if (Zotero_Preferences.Export) { Zotero_Preferences.Export.updateQuickCopyInstructions(); }"/>
<label value="&zotero.preferences.keys.toggleAllRead;" control="textbox-toggleAllRead"/>
<label class="modifier"/>
<html:input type="text" id="textbox-toggleAllRead" maxlength="1" size="1" preference="extensions.zotero.keys.toggleAllRead"/>
</html:div>
<label class="statusLine" value="&zotero.preferences.keys.changesTakeEffect;"/>
<separator/>
</vbox>
<vbox class="main-section" id="zotero-prefpane-advanced-feeds-tab">
<html:h1>&zotero.preferences.feeds;</html:h1>
<groupbox>
<hbox>
<hbox align="center">
<label value="&zotero.preferences.feeds.sorting.label;"/>
<menulist id="feed-sort" preference="extensions.zotero.feeds.sortAscending" native="true">
<menupopup>
<menuitem label="&zotero.preferences.feeds.sorting.newest;" value="false"/>
<menuitem label="&zotero.preferences.feeds.sorting.oldest;" value="true"/>
</menupopup>
</menulist>
</hbox>
</hbox>
</groupbox>
<groupbox id="zotero-prefpane-advanced-feeds-feedDefaults">
<html:label><html:h2>&zotero.preferences.feeds.feedDefaults;</html:h2></html:label>
<hbox>
<hbox align="center">
<label value="&zotero.feedSettings.refresh.label1;"/>
<html:input class="html-input" type="number" min="1" step="1" size="3" data-preference="feeds.defaultTTL"/>
<label value="&zotero.feedSettings.refresh.label2;"/>
</hbox>
</hbox>
<hbox>
<hbox align="center">
<label value="&zotero.feedSettings.cleanupReadAfter.label1;"/>
<html:input class="html-input" type="number" min="1" step="1" size="2" data-preference="feeds.defaultCleanupUnreadAfter"/>
<label value="&zotero.feedSettings.cleanupReadAfter.label2;"/>
</hbox>
</hbox>
<hbox>
<hbox align="center">
<label value="&zotero.feedSettings.cleanupUnreadAfter.label1;"/>
<html:input class="html-input" type="number" min="1" step="1" size="2" data-preference="feeds.defaultCleanupReadAfter"/>
<label value="&zotero.feedSettings.cleanupUnreadAfter.label2;"/>
</hbox>
</hbox>
</groupbox>
</vbox>
<vbox class="main-section">
<html:h1>&zotero.preferences.prefpane.search;</html:h1>
<groupbox>
<html:label><html:h2>&zotero.preferences.search.fulltextCache;</html:h2></html:label>
<hbox>
<button id="fulltext-rebuildIndex" flex="1" oncommand="Zotero_Preferences.Advanced.rebuildIndexPrompt()"
data-search-strings="zotero.preferences.search.rebuildWarning"/>
<button id="fulltext-clearIndex" flex="1" oncommand="Zotero_Preferences.Advanced.clearIndexPrompt()"
data-search-strings="zotero.preferences.search.clearWarning"/>
</hbox>
<separator/>
<hbox align="center">
<label value="&zotero.preferences.fulltext.textMaxLength;"/>
<html:input type="text" size="10" preference="extensions.zotero.fulltext.textMaxLength"/>
<label value="(&zotero.preferences.default; 500000)"/>
</hbox>
<separator class="thin"/>
<hbox align="center">
<label value="&zotero.preferences.fulltext.pdfMaxPages;"/>
<html:input type="text" size="5" preference="extensions.zotero.fulltext.pdfMaxPages"/>
<label value="(&zotero.preferences.default; 100)"/>
</hbox>
</groupbox>
<groupbox id="fulltext-stats">
<html:label><html:h2>&zotero.preferences.search.indexStats;</html:h2></html:label>
<vbox class="form-grid">
<label value="&zotero.preferences.search.indexStats.indexed;"/>
<label id="fulltext-stats-indexed"/>
<label value="&zotero.preferences.search.indexStats.partial;"/>
<label id="fulltext-stats-partial"/>
<label value="&zotero.preferences.search.indexStats.unindexed;"/>
<label id="fulltext-stats-unindexed"/>
<label value="&zotero.preferences.search.indexStats.words;"/>
<label id="fulltext-stats-words"/>
</vbox>
</groupbox>
</vbox>
</vbox>

View file

@ -1,333 +0,0 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062013 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 *****
-->
<!DOCTYPE window [
<!ENTITY % zoteroDTD SYSTEM "chrome://zotero/locale/zotero.dtd">
%zoteroDTD;
<!ENTITY % preferencesDTD SYSTEM "chrome://zotero/locale/preferences.dtd">
%preferencesDTD;
]>
<overlay id="zotero-prefpane-advanced-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<prefpane id="zotero-prefpane-advanced"
onpaneload="Zotero_Preferences.Advanced.init()"
helpTopic="advanced">
<preferences>
<preference id="pref-automaticScraperUpdates" name="extensions.zotero.automaticScraperUpdates" type="bool"/>
<preference id="pref-reportTranslationFailure" name="extensions.zotero.reportTranslationFailure" type="bool"/>
<preference id="pref-baseAttachmentPath" name="extensions.zotero.baseAttachmentPath" type="string"/>
<preference id="pref-useDataDir" name="extensions.zotero.useDataDir" type="bool"/>
<preference id="pref-dataDir" name="extensions.zotero.dataDir" type="string"/>
<preference id="pref-debug-output-enableAfterRestart" name="extensions.zotero.debug.store" type="bool"/>
<preference id="pref-openURL-resolver" name="extensions.zotero.openURL.resolver" type="string"/>
<preference id="pref-openURL-version" name="extensions.zotero.openURL.version" type="string"/>
<preference id="pref-keys-saveToZotero" name="extensions.zotero.keys.saveToZotero" type="string"/>
<preference id="pref-keys-library" name="extensions.zotero.keys.library" type="string"/>
<preference id="pref-keys-quicksearch" name="extensions.zotero.keys.quicksearch" type="string"/>
<preference id="pref-keys-newItem" name="extensions.zotero.keys.newItem" type="string"/>
<preference id="pref-keys-newNote" name="extensions.zotero.keys.newNote" type="string"/>
<preference id="pref-keys-toggleRead" name="extensions.zotero.keys.toggleRead" type="string"/>
<preference id="pref-keys-toggleAllRead" name="extensions.zotero.keys.toggleAllRead" type="string"/>
<preference id="pref-keys-copySelectedItemCitationsToClipboard" name="extensions.zotero.keys.copySelectedItemCitationsToClipboard" type="string"/>
<preference id="pref-keys-copySelectedItemsToClipboard" name="extensions.zotero.keys.copySelectedItemsToClipboard" type="string"/>
<preference id="pref-feeds-sortAscending" name="extensions.zotero.feeds.sortAscending" type="bool"/>
</preferences>
<tabbox id="zotero-prefpane-advanced-tabs">
<tabs>
<tab label="&zotero.preferences.prefpane.general;"/>
<tab label="&zotero.preferences.advanced.filesAndFolders;"/>
<tab label="&zotero.preferences.advanced.keys;"/>
<tab label="&zotero.preferences.feeds;"/>
</tabs>
<tabpanels id="zotero-prefpane-advanced-tabpanels">
<tabpanel id="zotero-prefpane-advanced-general-tab" orient="vertical">
<groupbox id="zotero-prefpane-advanced-miscellaneous">
<caption label="&zotero.preferences.miscellaneous;"/>
<hbox align="center">
<checkbox label="&zotero.preferences.autoUpdate;" preference="pref-automaticScraperUpdates"/>
<button id="updateButton" style="margin-top:0" label="&zotero.preferences.updateNow;"
oncommand="Zotero_Preferences.Advanced.updateTranslators()"/>
</hbox>
<checkbox label="&zotero.preferences.reportTranslationFailure;" preference="pref-reportTranslationFailure"/>
<hbox align="center">
<label value="&zotero.bibliography.locale.label;"/>
<menulist id="locale-menu"
onblur="if (!Zotero.isMac) Zotero_Preferences.Advanced.onLocaleChange()">
<menupopup onpopuphidden="Zotero_Preferences.Advanced.onLocaleChange()"/>
</menulist>
</hbox>
</groupbox>
<groupbox>
<caption label="OpenURL"/>
<hbox>
<menulist id="openurl-menu">
<menupopup
id="openurl-primary-popup"
onpopupshowing="Zotero_Preferences.Advanced.handleOpenURLPopupShowing(event)"
oncommand="Zotero_Preferences.Advanced.handleOpenURLSelected(event)">
<menuitem label="&zotero.preferences.openurl.choose;"/>
</menupopup>
</menulist>
</hbox>
<hbox align="center">
<label value="&zotero.preferences.openurl.server;"/>
<textbox id="openURLServerField" flex="1"
oninput="Zotero_Preferences.Advanced.onOpenURLCustomized();"
preference="pref-openURL-resolver"
/>
</hbox>
<hbox align="center">
<label value="&zotero.preferences.openurl.version;" control="openURLVersionMenu"/>
<menulist id="openURLVersionMenu"
oncommand="Zotero_Preferences.Advanced.onOpenURLCustomized();"
preference="pref-openURL-version">
<menupopup>
<menuitem label="0.1" value="0.1"/>
<menuitem label="1.0" value="1.0"/>
</menupopup>
</menulist>
</hbox>
</groupbox>
<groupbox id="zotero-prefpane-advanced-advancedConfiguration">
<caption label="&zotero.preferences.advanced.advancedConfiguration;"/>
<hbox id="zotero-prefpane-advanced-openbuttons" align="center" style="display: block">
<button id="config-editor"
label="&zotero.preferences.configEditor;"
oncommand="Zotero_Preferences.openInViewer('about:config')"/>
<button id="memory-info"
label="Memory Info"
oncommand="Zotero_Preferences.openInViewer('about:memory')"
hidden="true"/>
</hbox>
</groupbox>
</tabpanel>
<tabpanel orient="vertical">
<groupbox>
<caption label="&zotero.preferences.attachmentBaseDir.caption;"/>
<!-- This doesn't wrap without an explicit width -->
<vbox>
<description width="45em">&zotero.preferences.attachmentBaseDir.message;</description>
</vbox>
<hbox align="center">
<label value="&zotero.preferences.attachmentBaseDir.basePath;"/>
<filefield id="baseAttachmentPath"
preference="pref-baseAttachmentPath"
onsyncfrompreference="Zotero_Preferences.Attachment_Base_Directory.updateUI()"
preference-editable="true"
readonly="true"
flex="1"
tabindex="-1"/>
<button id="baseAttachmentPathButton"
label="&zotero.preferences.attachmentBaseDir.selectBasePath;"
oncommand="Zotero_Preferences.Attachment_Base_Directory.choosePath()"/>
</hbox>
<hbox>
<button id="resetBasePath"
label="&zotero.preferences.attachmentBaseDir.resetBasePath;"
oncommand="Zotero_Preferences.Attachment_Base_Directory.clearPath()"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.dataDir;"/>
<radiogroup id="data-dir"
preference="pref-useDataDir"
onsyncfrompreference="return Zotero_Preferences.Advanced.onDataDirLoad()"
onsynctopreference="Zotero_Preferences.Advanced.onDataDirUpdate(event);">
<radio id="default-data-dir" label="&zotero.preferences.dataDir.useProfile;" value="false"/>
<hbox>
<radio label="&zotero.preferences.dataDir.custom;" value="true"/>
<textbox id="data-dir-path" preference="pref-dataDir"
onsyncfrompreference="return Zotero_Preferences.Advanced.getDataDirPath();"
readonly="true" flex="1"/>
<button label="&zotero.preferences.dataDir.choose;"
oncommand="return Zotero_Preferences.Advanced.chooseDataDir(event)"/>
</hbox>
</radiogroup>
<vbox id="command-line-data-dir" hidden="true">
<description id="command-line-data-dir-path"/>
<label value="&zotero.preferences.dataDir.viaCommandLine;"/>
</vbox>
<hbox>
<button label="&zotero.preferences.dataDir.reveal;"
oncommand="Zotero.DataDirectory.reveal()"/>
<button id="migrate-data-dir" label="&zotero.preferences.dataDir.migrate;"
oncommand="Zotero_Preferences.Advanced.migrateDataDirectory()" hidden="true"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.dbMaintenance;"/>
<hbox style="display: block">
<button label="&zotero.preferences.dbMaintenance.integrityCheck;"
oncommand="Zotero_Preferences.Advanced.runIntegrityCheck(this)"/>
<button id="reset-translators-button"
label="&zotero.preferences.dbMaintenance.resetTranslators;"
oncommand="Zotero_Preferences.Advanced.resetTranslators()"/>
<button id="reset-styles-button"
label="&zotero.preferences.dbMaintenance.resetStyles;"
oncommand="Zotero_Preferences.Advanced.resetStyles()"/>
</hbox>
</groupbox>
</tabpanel>
<tabpanel id="zotero-prefpane-advanced-keys-tab" orient="vertical">
<grid id="zotero-keys-grid">
<columns>
<column flex="1"/>
<column/>
<column/>
</columns>
<rows id="zotero-keys-rows">
<row id="zotero-keys-new-item">
<label value="&zotero.preferences.keys.newItem;" control="textbox-newItem"/>
<label class="modifier"/>
<textbox id="textbox-newItem" maxlength="1" size="1" preference="pref-keys-newItem"/>
</row>
<row>
<label value="&zotero.preferences.keys.newNote;" control="textbox-newNote"/>
<label class="modifier"/>
<textbox id="textbox-newNote" maxlength="1" size="1" preference="pref-keys-newNote"/>
</row>
<row id="zotero-keys-focus-libraries-pane">
<label value="&zotero.preferences.keys.focusLibrariesPane;" control="textbox-library"/>
<label class="modifier"/>
<textbox id="textbox-library" maxlength="1" size="1" preference="pref-keys-library"/>
</row>
<row>
<label value="&zotero.preferences.keys.quicksearch;" control="textbox-quicksearch"/>
<label class="modifier"/>
<textbox id="textbox-quicksearch" maxlength="1" size="1" preference="pref-keys-quicksearch"/>
</row>
<row>
<label value="&zotero.preferences.keys.copySelectedItemCitationsToClipboard;" control="textbox-copySelectedItemCitationsToClipboard"/>
<label class="modifier"/>
<textbox id="textbox-copySelectedItemCitationsToClipboard" maxlength="1" size="1"
preference="pref-keys-copySelectedItemCitationsToClipboard"
onchange="if (Zotero_Preferences.Export) { Zotero_Preferences.Export.updateQuickCopyInstructions(); }"/>
</row>
<row>
<label value="&zotero.preferences.keys.copySelectedItemsToClipboard;" control="textbox-copySelectedItemsToClipboard"/>
<label class="modifier"/>
<textbox id="textbox-copySelectedItemsToClipboard" maxlength="1" size="1"
preference="pref-keys-copySelectedItemsToClipboard"
onchange="if (Zotero_Preferences.Export) { Zotero_Preferences.Export.updateQuickCopyInstructions(); }"/>
</row>
<row>
<label value="&zotero.preferences.keys.toggleAllRead;" control="textbox-toggleAllRead"/>
<label class="modifier"/>
<textbox id="textbox-toggleAllRead" maxlength="1" size="1" preference="pref-keys-toggleAllRead"/>
</row>
</rows>
</grid>
<label class="statusLine" value="&zotero.preferences.keys.changesTakeEffect;"/>
<separator/>
</tabpanel>
<tabpanel id="zotero-prefpane-advanced-feeds-tab" orient="vertical">
<groupbox>
<hbox>
<hbox align="center">
<label value="&zotero.preferences.feeds.sorting.label;"/>
<menulist id="feed-sort" preference="pref-feeds-sortAscending">
<menupopup>
<menuitem label="&zotero.preferences.feeds.sorting.newest;" value="false"/>
<menuitem label="&zotero.preferences.feeds.sorting.oldest;" value="true"/>
</menupopup>
</menulist>
</hbox>
</hbox>
</groupbox>
<groupbox id="zotero-prefpane-advanced-feeds-feedDefaults">
<caption label="&zotero.preferences.feeds.feedDefaults;"/>
<hbox>
<hbox align="center">
<label value="&zotero.feedSettings.refresh.label1;"/>
<html:input class="html-input" type="number" min="1" step="1" size="3" data-preference="feeds.defaultTTL"/>
<label value="&zotero.feedSettings.refresh.label2;"/>
</hbox>
</hbox>
<hbox>
<hbox align="center">
<label value="&zotero.feedSettings.cleanupReadAfter.label1;"/>
<html:input class="html-input" type="number" min="1" step="1" size="2" data-preference="feeds.defaultCleanupUnreadAfter"/>
<label value="&zotero.feedSettings.cleanupReadAfter.label2;"/>
</hbox>
</hbox>
<hbox>
<hbox align="center">
<label value="&zotero.feedSettings.cleanupUnreadAfter.label1;"/>
<html:input class="html-input" type="number" min="1" step="1" size="2" data-preference="feeds.defaultCleanupReadAfter"/>
<label value="&zotero.feedSettings.cleanupUnreadAfter.label2;"/>
</hbox>
</hbox>
</groupbox>
</tabpanel>
</tabpanels>
</tabbox>
<separator/>
<separator/>
<separator/>
</prefpane>
<script src="preferences_advanced.js" type="application/javascript"/>
</overlay>

View file

@ -41,11 +41,11 @@ Zotero_Preferences.Cite = {
'zoteroWinWordIntegration@zotero.org'
]),
init: Zotero.Promise.coroutine(function* () {
init: async function () {
Components.utils.import("resource://gre/modules/AddonManager.jsm");
this.updateWordProcessorInstructions();
yield this.refreshStylesList();
}),
await this.refreshStylesList();
},
/**
@ -129,13 +129,18 @@ Zotero_Preferences.Cite = {
columns={columns}
staticColumns={true}
disableFontSizeScaling={true}
onSelectionChange={() => document.getElementById('styleManager-delete').disabled = undefined}
onSelectionChange={selection => document.getElementById('styleManager-delete').disabled = !selection.count}
onKeyDown={handleKeyDown}
getRowString={index => this.styles[index].title}
/>
</IntlProvider>
);
await new Promise(resolve => ReactDOM.render(elem, document.getElementById("styleManager"), resolve));
let styleManager = document.getElementById("styleManager");
await new Promise(resolve => ReactDOM.render(elem, styleManager, resolve));
// Fix style manager showing partially blank until scrolled
setTimeout(() => this._tree.invalidate());
}
else {
this._tree.invalidate();
@ -147,6 +152,9 @@ Zotero_Preferences.Cite = {
this._tree.selection.select(index);
}
}
else if ([...this._tree.selection.selected].some(i => i >= this.styles.length)) {
this._tree.selection.clearSelection();
}
},
@ -228,7 +236,6 @@ Zotero_Preferences.Cite = {
}
yield this.refreshStylesList();
document.getElementById('styleManager-delete').disabled = true;
}
}),

View file

@ -0,0 +1,84 @@
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062022 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 *****
-->
<vbox id="zotero-prefpane-cite" onload="Zotero_Preferences.Cite.init()">
<vbox class="main-section" id="styles">
<html:h1>&zotero.preferences.cite.styles;</html:h1>
<groupbox flex="1">
<!-- HTML needs to be wrapped in an hbox to isolate from XUL box layout -->
<hbox><html:label><html:h2>&zotero.preferences.cite.styles.styleManager;</html:h2></html:label></hbox>
<hbox class="virtualized-table-container" flex="1" height="300px">
<html:div id="styleManager"/>
</hbox>
<separator class="thin"/>
<hbox id="styleManager-buttons" align="center">
<label is="zotero-text-link"
value="&zotero.preferences.export.getAdditionalStyles;" flex="1"
onclick="Zotero_Preferences.Cite.openStylesPage(); event.preventDefault()"/>
<button disabled="true" id="styleManager-delete" label="-"
oncommand="Zotero_Preferences.Cite.deleteStyle()"/>
<button label="+" oncommand="Zotero_Preferences.Cite.addStyle()"/>
</hbox>
</groupbox>
<groupbox>
<html:label><html:h2>&zotero.preferences.citationOptions.caption;</html:h2></html:label>
<checkbox label="&zotero.preferences.export.citePaperJournalArticleURL;" preference="extensions.zotero.export.citePaperJournalArticleURL" native="true"/>
<!-- This doesn't wrap without an explicit width, for some reason -->
<label id="export-citePaperJournalArticleURL" width="45em">
&zotero.preferences.export.citePaperJournalArticleURL.description;
</label>
</groupbox>
<groupbox>
<html:label><html:h2>&zotero.general.tools;</html:h2></html:label>
<hbox>
<button id="openCSLEdit"
label="&zotero.preferences.styleEditor;"
oncommand="Zotero_Preferences.openInViewer('chrome://zotero/content/tools/csledit.xhtml', true)"/>
<button id="openCSLPreview"
label="&zotero.preferences.stylePreview;"
oncommand="Zotero_Preferences.openInViewer('chrome://zotero/content/tools/cslpreview.xhtml', true)"/>
</hbox>
</groupbox>
</vbox>
<vbox class="main-section" id="wordProcessors">
<html:h1>&zotero.preferences.cite.wordProcessors;</html:h1>
<vbox id="wordProcessors-somePluginsDisabled" hidden="true">
<label style="font-weight: bold; margin-top: 1em; text-align: center">Some word processor plugins are disabled.</label>
<hbox pack="center" style="margin-bottom: 2em">
<button id="wordProcessors-enablePlugins"
label="Enable Plugins and Restart Zotero"
oncommand="Zotero_Preferences.Cite.enableWordPlugins()"/>
</hbox>
</vbox>
<checkbox label="&zotero.preferences.cite.wordProcessors.useClassicAddCitationDialog;" preference="extensions.zotero.integration.useClassicAddCitationDialog" native="true"/>
</vbox>
</vbox>

View file

@ -1,109 +0,0 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062013 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 *****
-->
<!DOCTYPE window [
<!ENTITY % zoteroDTD SYSTEM "chrome://zotero/locale/zotero.dtd">
%zoteroDTD;
<!ENTITY % preferencesDTD SYSTEM "chrome://zotero/locale/preferences.dtd">
%preferencesDTD;
]>
<overlay id="zotero-prefpane-cite-overlay"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<prefpane id="zotero-prefpane-cite"
onpaneload="Zotero_Preferences.Cite.init()"
helpTopic="cite">
<preferences id="zotero-preferences-cite">
<preference id="pref-cite-useClassicAddCitationDialog" name="extensions.zotero.integration.useClassicAddCitationDialog" type="bool"/>
<preference id="pref-cite-citePaperJournalArticleURL" name="extensions.zotero.export.citePaperJournalArticleURL" type="bool"/>
</preferences>
<tabbox>
<tabs>
<tab id="styles-tab" label="&zotero.preferences.cite.styles;"/>
<tab id="wordProcessors-tab" label="&zotero.preferences.cite.wordProcessors;"/>
</tabs>
<tabpanels>
<tabpanel orient="vertical" id="styles">
<groupbox flex="1">
<caption label="&zotero.preferences.cite.styles.styleManager;"/>
<hbox class="virtualized-table-container" flex="1" height="300px">
<html:div id="styleManager"/>
</hbox>
<separator class="thin"/>
<hbox align="center" flex="1" height="40">
<label class="zotero-text-link"
value="&zotero.preferences.export.getAdditionalStyles;" flex="1"
onclick="Zotero_Preferences.Cite.openStylesPage(); event.preventDefault()"/>
<button disabled="true" id="styleManager-delete" label="-"
oncommand="Zotero_Preferences.Cite.deleteStyle()"/>
<button label="+" oncommand="Zotero_Preferences.Cite.addStyle()"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.citationOptions.caption;"/>
<checkbox label="&zotero.preferences.export.citePaperJournalArticleURL;" preference="pref-cite-citePaperJournalArticleURL"/>
<!-- This doesn't wrap without an explicit width, for some reason -->
<label id="export-citePaperJournalArticleURL" width="45em">
&zotero.preferences.export.citePaperJournalArticleURL.description;
</label>
</groupbox>
<groupbox>
<caption label="&zotero.general.tools;"/>
<hbox>
<button id="openCSLEdit"
label="&zotero.preferences.styleEditor;"
oncommand="Zotero_Preferences.openInViewer('chrome://zotero/content/tools/csledit.xul', true)"/>
<button id="openCSLPreview"
label="&zotero.preferences.stylePreview;"
oncommand="Zotero_Preferences.openInViewer('chrome://zotero/content/tools/cslpreview.xul', true)"/>
</hbox>
</groupbox>
</tabpanel>
<tabpanel orient="vertical" id="wordProcessors">
<vbox id="wordProcessors-somePluginsDisabled" hidden="true">
<label style="font-weight: bold; margin-top: 1em; text-align: center">Some word processor plugins are disabled.</label>
<hbox pack="center" style="margin-bottom: 2em">
<button id="wordProcessors-enablePlugins"
label="Enable Plugins and Restart Zotero"
oncommand="Zotero_Preferences.Cite.enableWordPlugins()"/>
</hbox>
</vbox>
<checkbox label="&zotero.preferences.cite.wordProcessors.useClassicAddCitationDialog;" preference="pref-cite-useClassicAddCitationDialog"/>
</tabpanel>
</tabpanels>
</tabbox>
</prefpane>
<script src="preferences_cite.js" type="application/javascript"/>
</overlay>

View file

@ -36,12 +36,6 @@ Zotero_Preferences.Export = {
this.updateQuickCopyInstructions();
yield this.populateQuickCopyList();
yield this.populateNoteQuickCopyList();
var charsetMenu = document.getElementById("zotero-import-charsetMenu");
var charsetMap = Zotero_Charset_Menu.populate(charsetMenu, false);
charsetMenu.selectedItem =
charsetMap[Zotero.Prefs.get("import.charset")] ?
charsetMap[Zotero.Prefs.get("import.charset")] : charsetMap["auto"];
}),
@ -104,7 +98,7 @@ Zotero_Preferences.Export = {
menulist.selectedItem = null;
menulist.removeAllItems();
var popup = document.createElement('menupopup');
var popup = document.createXULElement('menupopup');
menulist.appendChild(popup);
// add export formats to list
@ -150,7 +144,7 @@ Zotero_Preferences.Export = {
}
var val = JSON.stringify({ mode: 'export', id: translator.translatorID });
var itemNode = document.createElement('menuitem');
var itemNode = document.createXULElement('menuitem');
itemNode.setAttribute('value', val);
itemNode.setAttribute('label', translator.label);
// itemNode.setAttribute('oncommand', 'Zotero_Preferences.Export.updateQuickCopyUI()');
@ -178,17 +172,10 @@ Zotero_Preferences.Export = {
menulist.selectedItem = null;
menulist.removeAllItems();
// Prevent Cmd-w from setting "Wikipedia"
menulist.onkeydown = function (event) {
if ((Zotero.isMac && event.metaKey) || event.ctrlKey) {
event.preventDefault();
}
}
var popup = document.createElement('menupopup');
var popup = document.createXULElement('menupopup');
menulist.appendChild(popup);
var itemNode = document.createElement("menuitem");
var itemNode = document.createXULElement("menuitem");
itemNode.setAttribute("label", Zotero.getString('zotero.preferences.export.quickCopy.citationStyles'));
itemNode.setAttribute("disabled", true);
popup.appendChild(itemNode);
@ -197,7 +184,7 @@ Zotero_Preferences.Export = {
var styles = Zotero.Styles.getVisible();
styles.forEach(function (style) {
var val = 'bibliography' + (contentType == 'html' ? '/html' : '') + '=' + style.styleID;
var itemNode = document.createElement("menuitem");
var itemNode = document.createXULElement("menuitem");
itemNode.setAttribute("value", val);
itemNode.setAttribute("label", style.title);
itemNode.setAttribute("oncommand", 'Zotero_Preferences.Export.updateQuickCopyUI()');
@ -208,7 +195,7 @@ Zotero_Preferences.Export = {
}
});
var itemNode = document.createElement("menuitem");
var itemNode = document.createXULElement("menuitem");
itemNode.setAttribute("label", Zotero.getString('zotero.preferences.export.quickCopy.exportFormats'));
itemNode.setAttribute("disabled", true);
popup.appendChild(itemNode);
@ -223,7 +210,7 @@ Zotero_Preferences.Export = {
return;
}
var val = 'export=' + translator.translatorID;
var itemNode = document.createElement("menuitem");
var itemNode = document.createXULElement("menuitem");
itemNode.setAttribute("value", val);
itemNode.setAttribute("label", translator.label);
itemNode.setAttribute("oncommand", 'Zotero_Preferences.Export.updateQuickCopyUI()');
@ -307,7 +294,7 @@ Zotero_Preferences.Export = {
var translators = await translation.getTranslators();
var io = { domain, format, locale, asHTML, ok: false, styles, translators };
window.openDialog('chrome://zotero/content/preferences/quickCopySiteEditor.xul',
window.openDialog('chrome://zotero/content/preferences/quickCopySiteEditor.xhtml',
"zotero-preferences-quickCopySiteEditor", "chrome,modal,centerscreen", io);
if (!io.ok || !io.domain) {
@ -400,7 +387,7 @@ Zotero_Preferences.Export = {
onSelectionChange={handleSelectionChange}
onKeyDown={handleKeyDown}
getRowString={index => this._rows[index].domain}
onActivate={(event, indices) => Zotero_Preferences.Export.showQuickCopySiteEditor()}
onActivate={(event, indices) => Zotero_Preferences.Export.showQuickCopySiteEditor(true)}
/>
</IntlProvider>
);

View file

@ -0,0 +1,79 @@
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062022 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 *****
-->
<vbox id="zotero-prefpane-export" onload="Zotero_Preferences.Export.init()">
<groupbox id="zotero-prefpane-export-groupbox">
<vbox>
<html:label><html:h2>&zotero.preferences.quickCopy.caption;</html:h2></html:label>
</vbox>
<label id="quickCopy-instructions"/>
<separator class="thin"/>
<label id="quickCopy-citationInstructions"/>
<separator/>
<label value="&zotero.preferences.quickCopy.itemFormat;" control="quickCopy-menu"/>
<menulist id="zotero-quickCopy-menu" label="&zotero.general.loading;" native="true"/>
<hbox align="center">
<label id="zotero-quickCopy-locale-menu-label" value="&zotero.bibliography.locale.label;" control="zotero-quickCopy-locale-menu"/>
<menulist id="zotero-quickCopy-locale-menu" oncommand="Zotero_Preferences.Export._lastSelectedLocale = this.value" native="true"/>
<separator orient="vertical" width="15px"/>
<checkbox id="zotero-quickCopy-copyAsHTML" label="&zotero.preferences.quickCopy.copyAsHTML;"
oncommand="Zotero_Preferences.Export.onCopyAsHTMLChange(this.checked)"
native="true"/>
</hbox>
<separator/>
<label value="&zotero.preferences.quickCopy.noteFormat;" control="zotero-noteQuickCopy-menu"/>
<menulist id="zotero-noteQuickCopy-menu" label="&zotero.general.loading;" native="true"/>
<separator/>
<label value="&zotero.preferences.quickCopy.siteEditor.setings;" control="quickCopy-siteSettings"/>
<hbox class="virtualized-table-container" flex="1" height="120px">
<html:div id="quickCopy-siteSettings"/>
</hbox>
<separator class="thin"/>
<hbox>
<button disabled="true" id="quickCopy-edit" label="&zotero.general.edit;"
onclick="if (!this.disabled) Zotero_Preferences.Export.showQuickCopySiteEditor(true)"/>
<spacer flex="1"/>
<button disabled="true" id="quickCopy-delete" label="-" onclick="if (!this.disabled) Zotero_Preferences.Export.deleteSelectedQuickCopySite()"/>
<button label="+"
onclick="Zotero_Preferences.Export.showQuickCopySiteEditor()"/>
</hbox>
<hbox align="center">
<label value="&zotero.preferences.quickCopy.dragLimit;"/>
<html:input type="text" preference="extensions.zotero.export.quickCopy.dragLimit" size="3"/>
<label value="&zotero.preferences.items;" flex="1"/>
</hbox>
</groupbox>
</vbox>

View file

@ -1,115 +0,0 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062013 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 *****
-->
<!DOCTYPE window [
<!ENTITY % prefWindow SYSTEM "chrome://zotero/locale/preferences.dtd">
%prefWindow;
<!ENTITY % common SYSTEM "chrome://zotero/locale/zotero.dtd">
%common;
]>
<overlay
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<prefpane id="zotero-prefpane-export"
onpaneload="Zotero_Preferences.Export.init()"
helpTopic="export">
<preferences>
<preference id="pref-quickCopy-setting" name="extensions.zotero.export.quickCopy.setting" type="string"/>
<preference id="pref-quickCopy-dragLimit" name="extensions.zotero.export.quickCopy.dragLimit" type="int"/>
<preference id="pref-quickCopy-locale" name="extensions.zotero.export.quickCopy.locale" type="string"/>
<preference id="pref-noteQuickCopy-setting" name="extensions.zotero.export.noteQuickCopy.setting" type="string"/>
<preference id="pref-import-charset" name="extensions.zotero.import.charset" type="string"/>
</preferences>
<groupbox id="zotero-prefpane-export-groupbox">
<caption label="&zotero.preferences.quickCopy.caption;"/>
<label id="quickCopy-instructions"/>
<separator class="thin"/>
<label id="quickCopy-citationInstructions"/>
<separator/>
<label value="&zotero.preferences.quickCopy.itemFormat;" control="quickCopy-menu"/>
<menulist id="zotero-quickCopy-menu" label="&zotero.general.loading;"/>
<hbox align="center">
<label id="zotero-quickCopy-locale-menu-label" value="&zotero.bibliography.locale.label;" control="zotero-quickCopy-locale-menu"/>
<menulist id="zotero-quickCopy-locale-menu" oncommand="Zotero_Preferences.Export._lastSelectedLocale = this.value"/>
<separator orient="vertical" width="15px"/>
<checkbox id="zotero-quickCopy-copyAsHTML" label="&zotero.preferences.quickCopy.copyAsHTML;"
oncommand="Zotero_Preferences.Export.onCopyAsHTMLChange(this.checked)"/>
</hbox>
<separator/>
<label value="&zotero.preferences.quickCopy.noteFormat;" control="zotero-noteQuickCopy-menu"/>
<menulist id="zotero-noteQuickCopy-menu" label="&zotero.general.loading;"/>
<separator/>
<label value="&zotero.preferences.quickCopy.siteEditor.setings;" control="quickCopy-siteSettings"/>
<hbox class="virtualized-table-container" flex="1" height="120px">
<html:div id="quickCopy-siteSettings"/>
</hbox>
<separator class="thin"/>
<hbox>
<button disabled="true" id="quickCopy-edit" label="&zotero.general.edit;"
onclick="Zotero_Preferences.Export.showQuickCopySiteEditor(true)"/>
<spacer flex="1"/>
<button disabled="true" id="quickCopy-delete" label="-" onclick="Zotero_Preferences.Export.deleteSelectedQuickCopySite()"/>
<button label="+"
onclick="Zotero_Preferences.Export.showQuickCopySiteEditor()"/>
</hbox>
<hbox align="center">
<label value="&zotero.preferences.quickCopy.dragLimit;"/>
<textbox preference="pref-quickCopy-dragLimit" size="3"/>
<label value="&zotero.preferences.items;" flex="1"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.charset;"/>
<hbox align="center">
<label value="&zotero.preferences.charset.importCharset;:" control="zotero-import-charsetMenu"/>
<menulist id="zotero-import-charsetMenu" preference="pref-import-charset"/>
</hbox>
</groupbox>
<!-- Unclear why this is necessary to prevent the menulist from getting cut off -->
<separator/>
<separator/>
<separator/>
<separator/>
<script src="preferences_export.js" type="application/javascript"/>
</prefpane>
</overlay>

View file

@ -30,6 +30,10 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
import FilePicker from 'zotero/modules/filePicker';
Zotero_Preferences.General = {
DEFAULT_OPENURL_RESOLVER: 'https://www.worldcat.org/registry/gateway',
_openURLResolvers: null,
init: function () {
// JS-based strings
var checkbox = document.getElementById('launchNonNativeFiles-checkbox');
@ -40,10 +44,93 @@ Zotero_Preferences.General = {
}
var menuitem = document.getElementById('fileHandler-internal');
menuitem.setAttribute('label', Zotero.appName);
// Set OpenURL resolver drop-down to last-known name
if (Zotero.Prefs.get('openURL.resolver')) {
let name = Zotero.Prefs.get('openURL.name');
if (name) {
document.getElementById('openurl-primary-popup').firstChild.setAttribute('label', name);
}
}
this.refreshLocale();
this.updateAutoRenameFilesUI();
this._updateFileHandlerUI();
},
_getAutomaticLocaleMenuLabel: function () {
return Zotero.getString(
'zotero.preferences.locale.automaticWithLocale',
Zotero.Locale.availableLocales[Zotero.locale] || Zotero.locale
);
},
refreshLocale: function () {
var autoLocaleName, currentValue;
// If matching OS, get the name of the current locale
if (Zotero.Prefs.get('intl.locale.requested', true) === '') {
autoLocaleName = this._getAutomaticLocaleMenuLabel();
currentValue = 'automatic';
}
// Otherwise get the name of the locale specified in the pref
else {
autoLocaleName = Zotero.getString('zotero.preferences.locale.automatic');
currentValue = Zotero.locale;
}
// Populate menu
var menu = document.getElementById('locale-menu');
var menupopup = menu.firstChild;
menupopup.textContent = '';
// Show "Automatic (English)", "Automatic (Français)", etc.
menu.appendItem(autoLocaleName, 'automatic');
menu.menupopup.appendChild(document.createXULElement('menuseparator'));
// Add all available locales
for (let locale in Zotero.Locale.availableLocales) {
menu.appendItem(Zotero.Locale.availableLocales[locale], locale);
}
menu.value = currentValue;
},
onLocaleChange: function () {
var requestedLocale = Services.locale.requestedLocale;
var menu = document.getElementById('locale-menu');
if (menu.value == 'automatic') {
// Changed if not already set to automatic (unless we have the automatic locale name,
// meaning we just switched away to the same manual locale and back to automatic)
var changed = requestedLocale
&& requestedLocale == Zotero.locale
&& menu.label != this._getAutomaticLocaleMenuLabel();
Services.locale.requestedLocales = null;
}
else {
// Changed if moving to a locale other than the current one
var changed = requestedLocale != menu.value
Services.locale.requestedLocales = [menu.value];
}
if (!changed) {
return;
}
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.appName),
buttonFlags,
Zotero.getString('general.restartNow'),
Zotero.getString('general.restartLater'),
null, null, {});
if (index == 0) {
Zotero.Utilities.Internal.quitZotero(true);
}
},
updateAutoRenameFilesUI: function () {
setTimeout(() => {
@ -116,6 +203,10 @@ Zotero_Preferences.General = {
}
customMenuItem.hidden = false;
menulist.selectedIndex = 2;
// There's almost certainly a better way to do this...
// but why doesn't the icon just behave by default?
menulist.shadowRoot.querySelector('[part="icon"]').style.height = '16px';
}
// Zotero
else {
@ -130,5 +221,164 @@ Zotero_Preferences.General = {
throw new Error(`Unknown file type ${type}`);
}
return 'fileHandler.pdf';
},
handleOpenURLPopupShowing: async function (event) {
if (event.target.id != 'openurl-primary-popup') {
return;
}
if (!this._openURLResolvers) {
let menupopup = document.getElementById('openurl-primary-popup');
menupopup.firstChild.setAttribute('label', Zotero.getString('general.loading'));
try {
this._openURLResolvers = await Zotero.Utilities.Internal.OpenURL.getResolvers();
}
catch (e) {
Zotero.logError(e);
menupopup.firstChild.setAttribute('label', "Error loading resolvers");
return;
}
}
this.updateOpenURLResolversMenu();
},
updateOpenURLResolversMenu: function () {
if (!this._openURLResolvers) {
Zotero.debug("Resolvers not loaded -- not updating menu");
return;
}
var currentResolver = Zotero.Prefs.get('openURL.resolver');
var openURLMenu = document.getElementById('openurl-menu');
var menupopup = openURLMenu.firstChild;
menupopup.innerHTML = '';
var defaultMenuItem = document.createXULElement('menuitem');
defaultMenuItem.setAttribute('label', Zotero.getString('general.default'));
defaultMenuItem.setAttribute('value', this.DEFAULT_OPENURL_RESOLVER);
defaultMenuItem.setAttribute('type', 'checkbox');
menupopup.appendChild(defaultMenuItem);
var customMenuItem = document.createXULElement('menuitem');
customMenuItem.setAttribute('label', Zotero.getString('general.custom'));
customMenuItem.setAttribute('value', 'custom');
customMenuItem.setAttribute('type', 'checkbox');
menupopup.appendChild(customMenuItem);
menupopup.appendChild(document.createXULElement('menuseparator'));
var selectedName;
var lastContinent;
var lastCountry;
var currentContinentPopup;
var currentMenuPopup;
for (let r of this._openURLResolvers) {
// Create submenus for continents
if (r.continent != lastContinent) {
let menu = document.createXULElement('menu');
menu.setAttribute('label', r.continent);
openURLMenu.firstChild.appendChild(menu);
currentContinentPopup = currentMenuPopup = document.createXULElement('menupopup');
menu.appendChild(currentContinentPopup);
lastContinent = r.continent;
}
if (r.country != lastCountry) {
// If there's a country, create a submenu for it
if (r.country) {
let menu = document.createXULElement('menu');
menu.setAttribute('label', r.country);
currentContinentPopup.appendChild(menu);
let menupopup = document.createXULElement('menupopup');
menu.appendChild(menupopup);
currentMenuPopup = menupopup;
}
// Otherwise use the continent popup
else {
currentMenuPopup = currentContinentPopup;
}
lastCountry = r.country;
}
let menuitem = document.createXULElement('menuitem');
menuitem.setAttribute('label', r.name);
menuitem.setAttribute('value', r.url);
menuitem.setAttribute('type', 'checkbox');
currentMenuPopup.appendChild(menuitem);
var checked = r.url == Zotero.Prefs.get('openURL.resolver');
menuitem.setAttribute('checked', checked);
if (checked) {
selectedName = r.name;
}
}
// Default
if (currentResolver == this.DEFAULT_OPENURL_RESOLVER) {
openURLMenu.setAttribute('label', Zotero.getString('general.default'));
defaultMenuItem.setAttribute('checked', true);
Zotero.Prefs.clear('openURL.name');
}
else if (selectedName) {
openURLMenu.setAttribute('label', selectedName);
// If we found a match, update stored name
Zotero.Prefs.set('openURL.name', selectedName);
}
// Custom
else {
openURLMenu.setAttribute('label', Zotero.getString('general.custom'));
customMenuItem.setAttribute('checked', true);
Zotero.Prefs.clear('openURL.name');
}
},
handleOpenURLSelected: function (event) {
event.stopPropagation();
event.preventDefault();
if (event.target.localName != 'menuitem') {
Zotero.debug("Ignoring click on " + event.target.localName);
return;
}
var openURLMenu = document.getElementById('openurl-menu');
var openURLServerField = document.getElementById('openURLServerField');
var openURLVersionMenu = document.getElementById('openURLVersionMenu');
// Default
if (event.target.value == this.DEFAULT_OPENURL_RESOLVER) {
Zotero.Prefs.clear('openURL.name');
Zotero.Prefs.clear('openURL.resolver');
Zotero.Prefs.clear('openURL.version');
openURLServerField.value = this.DEFAULT_OPENURL_RESOLVER;
}
// If "Custom" selected, clear URL field
else if (event.target.value == "custom") {
Zotero.Prefs.clear('openURL.name');
Zotero.Prefs.set('openURL.resolver', '');
Zotero.Prefs.clear('openURL.version');
openURLServerField.value = '';
openURLServerField.focus();
}
else {
Zotero.Prefs.set('openURL.name', openURLServerField.value = event.target.label);
Zotero.Prefs.set('openURL.resolver', openURLServerField.value = event.target.value);
Zotero.Prefs.set('openURL.version', openURLVersionMenu.value = "1.0");
}
openURLMenu.firstChild.hidePopup();
setTimeout(() => {
this.updateOpenURLResolversMenu();
});
},
onOpenURLCustomized: function () {
setTimeout(() => {
this.updateOpenURLResolversMenu();
});
}
}

View file

@ -0,0 +1,133 @@
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062022 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 *****
-->
<vbox id="zotero-prefpane-general" onload="Zotero_Preferences.General.init()">
<groupbox>
<html:label><html:h2>&zotero.preferences.interface;</html:h2></html:label>
<hbox align="center">
<label value="&zotero.bibliography.locale.label;"/>
<menulist id="locale-menu"
onblur="if (!Zotero.isMac) Zotero_Preferences.General.onLocaleChange()"
native="true">
<menupopup onpopuphidden="Zotero_Preferences.General.onLocaleChange()"/>
</menulist>
</hbox>
</groupbox>
<groupbox id="zotero-prefpane-file-handling-groupbox">
<html:label><html:h2>&zotero.preferences.fileHandling;</html:h2></html:label>
<vbox>
<checkbox id="automaticSnapshots-checkbox"
label="&zotero.preferences.automaticSnapshots;"
preference="extensions.zotero.automaticSnapshots"
native="true"/>
<checkbox label="&zotero.preferences.downloadAssociatedFiles;" preference="extensions.zotero.downloadAssociatedFiles" native="true"/>
<checkbox label="&zotero.preferences.autoRecognizeFiles;" preference="extensions.zotero.autoRecognizeFiles" native="true"/>
<checkbox label="&zotero.preferences.autoRenameFiles;"
preference="extensions.zotero.autoRenameFiles"
oncommand="Zotero_Preferences.General.updateAutoRenameFilesUI()" native="true"/>
<checkbox id="rename-linked-files" class="indented-pref"
label="&zotero.preferences.autoRenameFiles.renameLinked;"
preference="extensions.zotero.autoRenameFiles.linked"
oncommand="Zotero_Preferences.General.updateAutoRenameFilesUI()" native="true"/>
</vbox>
<hbox align="center">
<label value="&zotero.preferences.fileHandler.openPDFsUsing;" control="file-handler-pdf"/>
<menulist id="fileHandler-pdf" class="fileHandler-menu" native="true">
<menupopup>
<menuitem id="fileHandler-internal"
oncommand="Zotero_Preferences.General.setFileHandler('pdf', '')"/>
<menuitem label="&zotero.preferences.fileHandler.systemDefault;"
oncommand="Zotero_Preferences.General.setFileHandler('pdf', 'system')"/>
<menuitem id="fileHandler-custom"/>
<menuitem label="&zotero.preferences.custom;"
oncommand="Zotero_Preferences.General.chooseFileHandler('pdf')"/>
</menupopup>
</menulist>
</hbox>
</groupbox>
<groupbox>
<html:label><html:h2>&zotero.preferences.prefpane.locate;</html:h2></html:label>
<hbox>
<menulist id="openurl-menu" native="true">
<menupopup
id="openurl-primary-popup"
onpopupshowing="Zotero_Preferences.General.handleOpenURLPopupShowing(event)"
oncommand="Zotero_Preferences.General.handleOpenURLSelected(event)">
<menuitem label="&zotero.preferences.openurl.choose;"/>
</menupopup>
</menulist>
</hbox>
<hbox style="display: flex; align-items: center;">
<label value="&zotero.preferences.openurl.server;"/>
<html:input type="text" id="openURLServerField" style="flex: 1;"
oninput="Zotero_Preferences.General.onOpenURLCustomized();"
preference="extensions.zotero.openURL.resolver"
/>
</hbox>
<hbox align="center">
<label value="&zotero.preferences.openurl.version;" control="openURLVersionMenu"/>
<menulist id="openURLVersionMenu"
oncommand="Zotero_Preferences.General.onOpenURLCustomized();"
preference="extensions.zotero.openURL.version"
native="true">
<menupopup>
<menuitem label="0.1" value="0.1"/>
<menuitem label="1.0" value="1.0"/>
</menupopup>
</menulist>
</hbox>
</groupbox>
<groupbox id="zotero-prefpane-miscellaneous-groupbox">
<html:label><html:h2>&zotero.preferences.miscellaneous;</html:h2></html:label>
<checkbox label="&zotero.preferences.automaticTags;" preference="extensions.zotero.automaticTags" native="true"/>
<hbox align="center">
<label value="&zotero.preferences.trashAutoEmptyDaysPre;"/>
<html:input type="text" size="2" preference="extensions.zotero.trashAutoEmptyDays"/>
<label value="&zotero.preferences.trashAutoEmptyDaysPost;"/>
</hbox>
</groupbox>
<groupbox>
<html:label><html:h2>&zotero.preferences.groups;</html:h2></html:label>
<label value="&zotero.preferences.groups.whenCopyingInclude;"/>
<vbox style="margin-left: 2em">
<checkbox label="&zotero.preferences.groups.childNotes;" preference="extensions.zotero.groups.copyChildNotes" native="true"/>
<checkbox label="&zotero.preferences.groups.childFiles;" preference="extensions.zotero.groups.copyChildFileAttachments" native="true"/>
<checkbox label="&zotero.preferences.groups.annotations;" preference="extensions.zotero.groups.copyAnnotations" native="true"/>
<checkbox label="&zotero.preferences.groups.childLinks;" preference="extensions.zotero.groups.copyChildLinks" native="true"/>
<checkbox label="&zotero.preferences.groups.tags;" preference="extensions.zotero.groups.copyTags" native="true"/>
</vbox>
</groupbox>
</vbox>

View file

@ -1,111 +0,0 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20062013 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 *****
-->
<!DOCTYPE prefwindow SYSTEM "chrome://zotero/locale/preferences.dtd">
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<prefpane id="zotero-prefpane-general"
onpaneload="Zotero_Preferences.General.init()"
helpTopic="general">
<preferences id="zotero-prefpane-general-preferences">
<preference id="pref-automaticSnapshots" name="extensions.zotero.automaticSnapshots" type="bool"/>
<preference id="pref-downloadAssociatedFiles" name="extensions.zotero.downloadAssociatedFiles" type="bool"/>
<preference id="pref-autoRecognizeFiles" name="extensions.zotero.autoRecognizeFiles" type="bool"/>
<preference id="pref-autoRenameFiles" name="extensions.zotero.autoRenameFiles" type="bool"/>
<preference id="pref-autoRenameFilesLinked" name="extensions.zotero.autoRenameFiles.linked" type="bool"/>
<preference id="pref-automaticTags" name="extensions.zotero.automaticTags" type="bool"/>
<preference id="pref-trashAutoEmptyDays" name="extensions.zotero.trashAutoEmptyDays" type="int"/>
<preference id="pref-groups-copyChildNotes" name="extensions.zotero.groups.copyChildNotes" type="bool"/>
<preference id="pref-groups-copyChildFileAttachments" name="extensions.zotero.groups.copyChildFileAttachments" type="bool"/>
<preference id="pref-groups-copyAnnotations" name="extensions.zotero.groups.copyAnnotations" type="bool"/>
<preference id="pref-groups-copyChildLinks" name="extensions.zotero.groups.copyChildLinks" type="bool"/>
<preference id="pref-groups-copyTags" name="extensions.zotero.groups.copyTags" type="bool"/>
</preferences>
<groupbox id="zotero-prefpane-file-handling-groupbox">
<caption label="&zotero.preferences.fileHandling;"/>
<checkbox id="automaticSnapshots-checkbox"
label="&zotero.preferences.automaticSnapshots;"
preference="pref-automaticSnapshots"/>
<checkbox label="&zotero.preferences.downloadAssociatedFiles;" preference="pref-downloadAssociatedFiles"/>
<checkbox label="&zotero.preferences.autoRecognizeFiles;" preference="pref-autoRecognizeFiles"/>
<checkbox label="&zotero.preferences.autoRenameFiles;"
preference="pref-autoRenameFiles"
oncommand="Zotero_Preferences.General.updateAutoRenameFilesUI()"/>
<checkbox id="rename-linked-files" class="indented-pref"
label="&zotero.preferences.autoRenameFiles.renameLinked;"
preference="pref-autoRenameFilesLinked"
oncommand="Zotero_Preferences.General.updateAutoRenameFilesUI()"/>
<hbox align="center">
<label value="&zotero.preferences.fileHandler.openPDFsUsing;" control="file-handler-pdf"/>
<menulist id="fileHandler-pdf" class="fileHandler-menu">
<menupopup>
<menuitem id="fileHandler-internal"
oncommand="Zotero_Preferences.General.setFileHandler('pdf', '')"/>
<menuitem label="&zotero.preferences.fileHandler.systemDefault;"
oncommand="Zotero_Preferences.General.setFileHandler('pdf', 'system')"/>
<menuitem id="fileHandler-custom"/>
<menuitem label="&zotero.preferences.custom;"
oncommand="Zotero_Preferences.General.chooseFileHandler('pdf')"/>
</menupopup>
</menulist>
</hbox>
</groupbox>
<groupbox id="zotero-prefpane-miscellaneous-groupbox">
<caption label="&zotero.preferences.miscellaneous;"/>
<checkbox label="&zotero.preferences.automaticTags;" preference="pref-automaticTags"/>
<hbox align="center">
<label value="&zotero.preferences.trashAutoEmptyDaysPre;"/>
<textbox size="2" preference="pref-trashAutoEmptyDays"/>
<label value="&zotero.preferences.trashAutoEmptyDaysPost;"/>
</hbox>
</groupbox>
<groupbox>
<caption label="&zotero.preferences.groups;"/>
<label value="&zotero.preferences.groups.whenCopyingInclude;"/>
<vbox style="margin-left: 2em">
<checkbox label="&zotero.preferences.groups.childNotes;" preference="pref-groups-copyChildNotes"/>
<checkbox label="&zotero.preferences.groups.childFiles;" preference="pref-groups-copyChildFileAttachments"/>
<checkbox label="&zotero.preferences.groups.annotations;" preference="pref-groups-copyAnnotations"/>
<checkbox label="&zotero.preferences.groups.childLinks;" preference="pref-groups-copyChildLinks"/>
<checkbox label="&zotero.preferences.groups.tags;" preference="pref-groups-copyTags"/>
</vbox>
</groupbox>
<separator/>
<separator/>
</prefpane>
<script src="preferences_general.js" type="application/javascript"/>
</overlay>

View file

@ -1,136 +0,0 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 20062013 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 *****
*/
"use strict";
Components.utils.import("resource://gre/modules/Services.jsm");
Zotero_Preferences.Search = {
init: function () {
document.getElementById('fulltext-rebuildIndex').setAttribute('label',
Zotero.getString('zotero.preferences.search.rebuildIndex')
+ Zotero.getString('punctuation.ellipsis'));
document.getElementById('fulltext-clearIndex').setAttribute('label',
Zotero.getString('zotero.preferences.search.clearIndex')
+ Zotero.getString('punctuation.ellipsis'));
this.updateIndexStats();
},
updateIndexStats: Zotero.Promise.coroutine(function* () {
var stats = yield Zotero.Fulltext.getIndexStats();
document.getElementById('fulltext-stats-indexed').
lastChild.setAttribute('value', stats.indexed);
document.getElementById('fulltext-stats-partial').
lastChild.setAttribute('value', stats.partial);
document.getElementById('fulltext-stats-unindexed').
lastChild.setAttribute('value', stats.unindexed);
document.getElementById('fulltext-stats-words').
lastChild.setAttribute('value', stats.words);
}),
rebuildIndexPrompt: async function () {
var buttons = [
document.getElementById('fulltext-rebuildIndex'),
document.getElementById('fulltext-clearIndex')
];
buttons.forEach(b => b.disabled = true);
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.preferences.search.rebuildIndex'),
Zotero.getString('zotero.preferences.search.rebuildWarning',
Zotero.getString('zotero.preferences.search.indexUnindexed')),
buttonFlags,
Zotero.getString('zotero.preferences.search.rebuildIndex'),
null,
// Position 2 because of https://bugzilla.mozilla.org/show_bug.cgi?id=345067
Zotero.getString('zotero.preferences.search.indexUnindexed'),
null, {});
try {
if (index == 0) {
await Zotero.Fulltext.rebuildIndex();
}
else if (index == 2) {
await Zotero.Fulltext.rebuildIndex(true)
}
await this.updateIndexStats();
}
catch (e) {
Zotero.alert(null, Zotero.getString('general.error'), e);
}
finally {
buttons.forEach(b => b.disabled = false);
}
},
clearIndexPrompt: async function () {
var buttons = [
document.getElementById('fulltext-rebuildIndex'),
document.getElementById('fulltext-clearIndex')
];
buttons.forEach(b => b.disabled = true);
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.preferences.search.clearIndex'),
Zotero.getString('zotero.preferences.search.clearWarning',
Zotero.getString('zotero.preferences.search.clearNonLinkedURLs')),
buttonFlags,
Zotero.getString('zotero.preferences.search.clearIndex'),
null,
// Position 2 because of https://bugzilla.mozilla.org/show_bug.cgi?id=345067
Zotero.getString('zotero.preferences.search.clearNonLinkedURLs'), null, {});
try {
if (index == 0) {
await Zotero.Fulltext.clearIndex();
}
else if (index == 2) {
await Zotero.Fulltext.clearIndex(true);
}
await this.updateIndexStats();
}
catch (e) {
Zotero.alert(null, Zotero.getString('general.error'), e);
}
finally {
buttons.forEach(b => b.disabled = false);
}
}
};

View file

@ -39,12 +39,12 @@ Zotero_Preferences.Sync = {
checkmarkChar: '\u2705',
noChar: '\uD83D\uDEAB',
init: Zotero.Promise.coroutine(function* () {
init: async function () {
this.updateStorageSettingsUI();
this.updateStorageSettingsGroupsUI();
var username = Zotero.Users.getCurrentUsername() || Zotero.Prefs.get('sync.server.username') || " ";
var apiKey = yield Zotero.Sync.Data.Local.getAPIKey();
var apiKey = await Zotero.Sync.Data.Local.getAPIKey();
this.displayFields(apiKey ? username : "");
var pass = Zotero.Sync.Runner.getStorageController('webdav').password;
@ -54,7 +54,7 @@ Zotero_Preferences.Sync = {
if (apiKey) {
try {
var keyInfo = yield Zotero.Sync.Runner.checkAccess(
var keyInfo = await Zotero.Sync.Runner.checkAccess(
Zotero.Sync.Runner.getAPIClient({apiKey}),
{timeout: 5000}
);
@ -75,14 +75,16 @@ Zotero_Preferences.Sync = {
}
}
}
this.initResetPane();
}),
document.getElementById('storage-url-prefix').addEventListener('synctopreference', () => {
this.unverifyStorageServer();
});
},
displayFields: function (username) {
document.getElementById('sync-unauthorized').hidden = !!username;
document.getElementById('sync-authorized').hidden = !username;
document.getElementById('sync-reset-tab').disabled = !username;
document.getElementById('sync-reset').hidden = !username;
document.getElementById('sync-username').value = username;
document.getElementById('sync-password').value = '';
document.getElementById('sync-username-textbox').value = Zotero.Prefs.get('sync.server.username');
@ -235,7 +237,7 @@ Zotero_Preferences.Sync = {
showLibrariesToSyncDialog: function() {
var io = {};
window.openDialog('chrome://zotero/content/preferences/librariesToSync.xul',
window.openDialog('chrome://zotero/content/preferences/librariesToSync.xhtml',
"zotero-preferences-librariesToSyncDialog", "chrome,modal,centerscreen", io);
},
@ -284,7 +286,7 @@ Zotero_Preferences.Sync = {
div.innerHTML = "";
}
else {
div = document.createElementNS("http://www.w3.org/1999/xhtml", 'div');
div = document.createElement('div');
div.className = "row";
div.addEventListener('dblclick', () => {
this.toggleLibraryToSync(index);
@ -294,7 +296,7 @@ Zotero_Preferences.Sync = {
for (let column of columns) {
if (column.dataKey === 'checked') {
let span = document.createElementNS("http://www.w3.org/1999/xhtml", 'span');
let span = document.createElement('span');
span.className = `cell ${column.className}`;
if (row.id != 'loading') {
span.innerText = row.checked ? this.checkmarkChar : this.noChar;
@ -397,8 +399,8 @@ Zotero_Preferences.Sync = {
updateStorageSettingsUI: Zotero.Promise.coroutine(function* () {
this.unverifyStorageServer();
var protocol = document.getElementById('pref-storage-protocol').value;
var enabled = document.getElementById('pref-storage-enabled').value;
var protocol = Zotero.Prefs.get('sync.storage.protocol');
var enabled = Zotero.Prefs.get('sync.storage.enabled');
var storageSettings = document.getElementById('storage-settings');
var protocolMenu = document.getElementById('storage-protocol');
@ -423,7 +425,7 @@ Zotero_Preferences.Sync = {
updateStorageSettingsGroupsUI: function () {
setTimeout(() => {
var enabled = document.getElementById('pref-storage-groups-enabled').value;
var enabled = Zotero.Prefs.get('sync.storage.groups.enabled');
document.getElementById('storage-groups-download-mode').disabled = !enabled;
this.updateStorageTerms();
});
@ -433,9 +435,9 @@ Zotero_Preferences.Sync = {
updateStorageTerms: function () {
var terms = document.getElementById('storage-terms');
var libraryEnabled = document.getElementById('pref-storage-enabled').value;
var storageProtocol = document.getElementById('pref-storage-protocol').value;
var groupsEnabled = document.getElementById('pref-storage-groups-enabled').value;
var libraryEnabled = Zotero.Prefs.get('sync.storage.enabled');
var storageProtocol = Zotero.Prefs.get('sync.storage.protocol');
var groupsEnabled = Zotero.Prefs.get('sync.storage.groups.enabled');
terms.hidden = !((libraryEnabled && storageProtocol == 'zotero') || groupsEnabled);
},
@ -450,16 +452,14 @@ Zotero_Preferences.Sync = {
onStorageSettingsChange: Zotero.Promise.coroutine(function* () {
// Clean URL
var urlPref = document.getElementById('pref-storage-url');
urlPref.value = urlPref.value.replace(/(^https?:\/\/|\/zotero\/?$|\/$)/g, '');
Zotero.Prefs.set('sync.storage.url', Zotero.Prefs.get('sync.storage.url')
.replace(/(^https?:\/\/|\/zotero\/?$|\/$)/g, ''));
var oldProtocol = document.getElementById('pref-storage-protocol').value;
var oldEnabled = document.getElementById('pref-storage-enabled').value;
var oldProtocol = Zotero.Prefs.get('sync.storage.protocol');
yield Zotero.Promise.delay(1);
var newProtocol = document.getElementById('pref-storage-protocol').value;
var newEnabled = document.getElementById('pref-storage-enabled').value;
var newProtocol = Zotero.Prefs.get('sync.storage.protocol');
if (oldProtocol != newProtocol) {
yield Zotero.Sync.Storage.Local.resetAllSyncStates(Zotero.Libraries.userLibraryID);
@ -634,17 +634,18 @@ Zotero_Preferences.Sync = {
this.onResetLibraryChange(parseInt(event.target.value));
}
this.onResetLibraryChange(Zotero.Libraries.userLibraryID);
document.querySelectorAll('#sync-reset-radiogroup radio')
.forEach(radio => radio.removeAttribute('selected'));
var libraries = Zotero.Libraries.getAll()
.filter(x => x.libraryType == 'user' || x.libraryType == 'group');
Zotero.Utilities.Internal.buildLibraryMenuHTML(libraryMenu, libraries);
Zotero.Utilities.Internal.buildLibraryMenu(libraryMenu, libraries);
// Disable read-only libraries, at least until there are options that make sense for those
Array.from(libraryMenu.querySelectorAll('option'))
Array.from(libraryMenu.querySelectorAll('menuitem'))
.filter(x => x.getAttribute('data-editable') == 'false')
.forEach(x => x.disabled = true);
var list = document.getElementById('sync-reset-list');
for (let li of document.querySelectorAll('#sync-reset-list li')) {
li.addEventListener('click', function (event) {
for (let row of document.querySelectorAll('#sync-reset-radiogroup > *')) {
row.addEventListener('click', function (event) {
// Ignore clicks if disabled
if (this.hasAttribute('disabled')) {
event.stopPropagation();
@ -659,19 +660,19 @@ Zotero_Preferences.Sync = {
onResetLibraryChange: function (libraryID) {
var library = Zotero.Libraries.get(libraryID);
var section = document.getElementById('reset-file-sync-history');
var input = section.querySelector('input');
var radio = section.querySelector('radio');
if (library.filesEditable) {
section.removeAttribute('disabled');
input.disabled = false;
radio.disabled = false;
}
else {
section.setAttribute('disabled', '');
// If radio we're disabling is already selected, select the first one in the list
// instead
if (input.checked) {
document.querySelector('#sync-reset-list li:first-child input').checked = true;
if (radio.selected) {
document.querySelector('#sync-reset-radiogroup > div:first-child radio').selected = true;
}
input.disabled = true;
radio.disabled = true;
}
},
@ -690,14 +691,10 @@ Zotero_Preferences.Sync = {
return;
}
var libraryID = parseInt(
Array.from(document.querySelectorAll('#sync-reset-library-menu option'))
.filter(x => x.selected)[0]
.value
);
var libraryID = document.getElementById('sync-reset-library-menu').value;
var library = Zotero.Libraries.get(libraryID);
var action = Array.from(document.querySelectorAll('#sync-reset-list input[name=sync-reset-radiogroup]'))
.filter(x => x.checked)[0]
var action = Array.from(document.querySelectorAll('#sync-reset-radiogroup radio'))
.filter(x => x.selected)[0]
.getAttribute('value');
switch (action) {

View file

@ -0,0 +1,249 @@
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 20082022 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 *****
-->
<vbox id="zotero-prefpane-sync" onload="Zotero_Preferences.Sync.init()">
<vbox class="main-section">
<html:h1>&zotero.preferences.settings;</html:h1>
<vbox id="sync-unauthorized">
<groupbox>
<html:label><html:h2>&zotero.preferences.sync.syncServer;</html:h2></html:label>
<hbox>
<html:div class="form-grid">
<label value="&zotero.preferences.sync.username;"/>
<html:input id="sync-username-textbox"
preference="extensions.zotero.sync.server.username"
onblur="Zotero_Preferences.Sync.trimUsername()"
oninput="Zotero_Preferences.Sync.credentialsChange(event)"
onchange="Zotero_Preferences.Sync.credentialsChange(event)"
onkeypress="Zotero_Preferences.Sync.credentialsKeyPress(event)"/>
<label value="&zotero.preferences.sync.password;"/>
<html:input id="sync-password" type="password"
oninput="Zotero_Preferences.Sync.credentialsChange(event)"
onchange="Zotero_Preferences.Sync.credentialsChange(event)"
onkeypress="Zotero_Preferences.Sync.credentialsKeyPress(event)"/>
<box/>
<hbox align="baseline">
<button id="sync-auth-button"
label="&zotero.preferences.sync.setUpSync;"
oncommand="Zotero_Preferences.Sync.linkAccount(event)"
disabled="true"/>
<label id="sync-status-indicator"/>
</hbox>
</html:div>
<vbox style="width:2em"/>
<vbox>
<label is="zotero-text-link" value="&zotero.preferences.sync.createAccount;" href="http://zotero.org/user/register"/>
<separator class="thin"/>
<label is="zotero-text-link" value="&zotero.preferences.sync.lostPassword;" href="http://zotero.org/user/lostpassword"/>
<separator class="thin"/>
<label is="zotero-text-link" value="&zotero.preferences.sync.about;" href="http://www.zotero.org/support/sync"/>
</vbox>
</hbox>
</groupbox>
</vbox>
<vbox id="sync-authorized" hidden="true">
<groupbox>
<html:label><html:h2>&zotero.preferences.sync.syncServer;</html:h2></html:label>
<html:div class="form-grid">
<label value="&zotero.preferences.sync.username;"/>
<hbox>
<label id="sync-username" value="Username"/>
<button label="&zotero.preferences.sync.unlinkAccount;"
oncommand="Zotero_Preferences.Sync.unlinkAccount()"/>
</hbox>
<box/>
<box>
<button id="sync-libraries-button" label="&zotero.preferences.sync.librariesToSync.button;"
oncommand="Zotero_Preferences.Sync.showLibrariesToSyncDialog()"
data-search-strings="zotero.preferences.sync.librariesToSync"/>
</box>
<box/>
<checkbox label="&zotero.preferences.sync.syncAutomatically;"
preference="extensions.zotero.sync.autoSync"
native="true"/>
<box/>
<checkbox label="&zotero.preferences.sync.syncFullTextContent;"
preference="extensions.zotero.sync.fulltext.enabled"
tooltiptext="&zotero.preferences.sync.syncFullTextContent.desc;"
native="true"/>
<box/>
<label is="zotero-text-link" value="&zotero.preferences.sync.about;" href="http://www.zotero.org/support/sync"/>
</html:div>
</groupbox>
<groupbox id="storage-settings">
<html:label><html:h2>&zotero.preferences.sync.fileSyncing;</html:h2></html:label>
<!-- My Library -->
<hbox>
<checkbox label="&zotero.preferences.sync.fileSyncing.myLibrary;"
preference="extensions.zotero.sync.storage.enabled"
oncommand="Zotero_Preferences.Sync.onStorageSettingsChange()"
native="true"/>
<menulist id="storage-protocol" class="storage-personal"
style="margin-left: .5em"
preference="extensions.zotero.sync.storage.protocol"
oncommand="Zotero_Preferences.Sync.onStorageSettingsChange()"
native="true">
<menupopup>
<menuitem label="Zotero" value="zotero"/>
<menuitem label="WebDAV" value="webdav"/>
</menupopup>
</menulist>
</hbox>
<stack id="storage-webdav-settings" style="margin-top: .5em; margin-bottom: .8em; border: 1px gray solid; border-radius: 3px">
<!-- Background shading -->
<box style="background: black; opacity:.03"/>
<grid style="padding: .7em .4em .7em 0">
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row>
<label value="&zotero.preferences.sync.fileSyncing.url;"/>
<hbox>
<menulist id="storage-url-prefix"
preference="extensions.zotero.sync.storage.scheme"
style="padding: 0; width: 7em"
native="true">
<menupopup>
<menuitem label="https" value="https" style="padding: 0"/>
<menuitem label="http" value="http" style="padding: 0"/>
</menupopup>
</menulist>
<label value="://"/>
<html:input id="storage-url" style="-moz-box-flex: 1;"
preference="extensions.zotero.sync.storage.url"
onkeypress="Zotero_Preferences.Sync.onStorageSettingsKeyPress(event)"
onchange="Zotero_Preferences.Sync.onStorageSettingsChange()"/>
<label value="/zotero/"/>
</hbox>
</row>
<row>
<label value="&zotero.preferences.sync.username;"/>
<hbox>
<html:input id="storage-username"
preference="extensions.zotero.sync.storage.username"
onkeypress="Zotero_Preferences.Sync.onStorageSettingsKeyPress(event)"
onchange="Zotero_Preferences.Sync.onStorageSettingsChange()"/>
</hbox>
</row>
<row>
<label value="&zotero.preferences.sync.password;"/>
<hbox>
<html:input id="storage-password" style="-moz-box-flex: 0;" type="password"
onkeypress="Zotero_Preferences.Sync.onStorageSettingsKeyPress(event)"
onchange="Zotero_Preferences.Sync.onStorageSettingsChange()"/>
</hbox>
</row>
<row>
<box/>
<hbox>
<button id="storage-verify" label="&zotero.preferences.sync.fileSyncing.verifyServer;"
oncommand="Zotero_Preferences.Sync.verifyStorageServer()"/>
<button id="storage-abort" label="Stop" hidden="true"/>
<progressmeter id="storage-progress" hidden="true"
mode="undetermined"/>
</hbox>
</row>
</rows>
</grid>
</stack>
<hbox class="storage-settings-download-options" align="center">
<label value="&zotero.preferences.sync.fileSyncing.download;"/>
<menulist id="storage-user-download-mode"
class="storage-mode"
preference="extensions.zotero.sync.storage.downloadMode.personal"
style="margin-left: 0"
native="true">
<menupopup>
<menuitem label="&zotero.preferences.sync.fileSyncing.download.onDemand;" value="on-demand"/>
<menuitem label="&zotero.preferences.sync.fileSyncing.download.atSyncTime;" value="on-sync"/>
</menupopup>
</menulist>
</hbox>
<separator id="storage-separator" class="thin"/>
<!-- Group Libraries -->
<checkbox label="&zotero.preferences.sync.fileSyncing.groups;"
preference="extensions.zotero.sync.storage.groups.enabled"
oncommand="Zotero_Preferences.Sync.updateStorageSettingsGroupsUI()"
native="true"/>
<hbox class="storage-settings-download-options" align="center">
<label value="&zotero.preferences.sync.fileSyncing.download;"/>
<menulist id="storage-groups-download-mode"
class="storage-mode"
preference="extensions.zotero.sync.storage.downloadMode.groups"
style="margin-left: 0"
native="true">
<menupopup>
<menuitem label="&zotero.preferences.sync.fileSyncing.download.onDemand;" value="on-demand"/>
<menuitem label="&zotero.preferences.sync.fileSyncing.download.atSyncTime;" value="on-sync"/>
</menupopup>
</menulist>
</hbox>
<separator class="thin"/>
<vbox id="storage-terms">
<hbox style="margin-top: .4em; display: block" align="center">
<label>&zotero.preferences.sync.fileSyncing.tos1;</label>
<label is="zotero-text-link" href="https://www.zotero.org/support/terms/terms_of_service" value="&zotero.preferences.sync.fileSyncing.tos2;"/>
<label>&zotero.preferences.period;</label>
</hbox>
</vbox>
</groupbox>
</vbox>
</vbox>
<vbox class="main-section" id="sync-reset" align="start">
<html:h1>&zotero.preferences.sync.reset;</html:h1>
<button label="&zotero.preferences.sync.reset.showResetOptions;" oncommand="Zotero_Preferences.navigateToPane('zotero-subpane-reset-sync')"
data-search-strings="
zotero.preferences.sync.reset.restoreToServer,
zotero.preferences.sync.reset.restoreToServer.desc,
zotero.preferences.sync.reset.fileSyncHistory,
zotero.preferences.sync.reset.resetFileSyncHistory.desc"/>
</vbox>
</vbox>

View file

@ -0,0 +1,40 @@
<vbox class="main-section" id="sync-reset" onload="Zotero_Preferences.Sync.initResetPane()">
<html:h1>&zotero.preferences.sync.reset;</html:h1>
<!-- This doesn't wrap without an explicit width, for some reason -->
<description id="reset-sync-warning" width="45em">&zotero.preferences.sync.reset.warning1;<label style="margin-left: 0; margin-right: 0" is="zotero-text-link" href="http://zotero.org/support/kb/sync_reset_options">&zotero.preferences.sync.reset.warning2;</label>&zotero.preferences.sync.reset.warning3;</description>
<div id="sync-reset-form" xmlns="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<div id="sync-reset-library-menu-container">
<label for="sync-reset-library-menu">Library:</label>
<xul:menulist id="sync-reset-library-menu" native="true"><xul:menupopup/></xul:menulist>
</div>
<xul:radiogroup id="sync-reset-radiogroup">
<!--<li>
<p>&zotero.preferences.sync.reset.restoreFromServer;</p>
<p>&zotero.preferences.sync.reset.restoreFromServer.desc;</p>
</li>-->
<div id="restore-to-server">
<xul:radio value="restore-to-server" label="&zotero.preferences.sync.reset.restoreToServer;"/>
<span class="sync-reset-option-desc">&zotero.preferences.sync.reset.restoreToServer.desc;</span>
</div>
<!--<li>
<h2>&zotero.preferences.sync.reset.resetDataSyncHistory;</h2>
<description>&zotero.preferences.sync.reset.resetDataSyncHistory.desc;</p>
</li>-->
<div id="reset-file-sync-history">
<xul:radio value="reset-file-sync-history" label="&zotero.preferences.sync.reset.resetFileSyncHistory;"/>
<span class="sync-reset-option-desc">&zotero.preferences.sync.reset.resetFileSyncHistory.desc;</span>
</div>
</xul:radiogroup>
<button id="sync-reset-button"
disabled="disabled"
onclick="Zotero_Preferences.Sync.reset()">&zotero.preferences.sync.reset.button;</button>
</div>
</vbox>

View file

@ -35,11 +35,13 @@
%common;
]>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="" buttons="cancel,accept"
id="zotero-quickCopySiteEditor"
onload="Zotero_QuickCopySiteEditor.onLoad(); Zotero_Preferences.Export.updateQuickCopyUI(); sizeToContent()"
ondialogaccept="Zotero_QuickCopySiteEditor.onAccept();">
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title=""
onload="Zotero_QuickCopySiteEditor.onLoad(); Zotero_Preferences.Export.updateQuickCopyUI(); sizeToContent()">
<dialog
buttons="cancel,accept"
id="zotero-quickCopySiteEditor">
<script src="chrome://zotero/content/include.js"/>
<script src="preferences.js"/>
@ -47,18 +49,18 @@
<vbox id="zotero-preferences-quickCopySiteEditor">
<label value="&zotero.preferences.quickCopy.siteEditor.domainPath; &zotero.preferences.quickCopy.siteEditor.domainPath.example;" control="zotero-quickCopy-domain"/>
<textbox id="zotero-quickCopy-domain" oninput="Zotero_QuickCopySiteEditor.onDomainInput(event)"/>
<html:input type="text" id="zotero-quickCopy-domain" oninput="Zotero_QuickCopySiteEditor.onDomainInput(event)"/>
<separator class="thin"/>
<label value="&zotero.preferences.quickCopy.siteEditor.format;" control="zotero-quickCopy-menu"/>
<menulist id="zotero-quickCopy-menu"/>
<menulist id="zotero-quickCopy-menu" native="true"/>
<separator class="thin"/>
<label id="zotero-quickCopy-locale-menu-label" value="&zotero.preferences.quickCopy.siteEditor.locale;" control="zotero-quickCopy-locale-menu"/>
<hbox align="center">
<menulist id="zotero-quickCopy-locale-menu" oncommand="Zotero_Preferences.Export._lastSelectedLocale = this.value"/>
<menulist id="zotero-quickCopy-locale-menu" oncommand="Zotero_Preferences.Export._lastSelectedLocale = this.value" native="true"/>
</hbox>
<separator class="thin"/>
@ -69,17 +71,20 @@
this.checked ? 'html' : '',
null,
io.translators
)"/>
)"
native="true"/>
</vbox>
<script>
<![CDATA[
document.addEventListener('dialogaccept', () => Zotero_QuickCopySiteEditor.onAccept());
var Zotero_QuickCopySiteEditor = new function () {
var menu = document.getElementById('zotero-quickCopy-menu');
this.onLoad = function () {
// Hide OK button initially if domain field is empty
document.documentElement.getButton('accept').disabled
document.getElementById('zotero-quickCopySiteEditor').getButton('accept').disabled
= document.getElementById('zotero-quickCopy-domain').value.trim() === '';
};
@ -98,7 +103,7 @@
this.onDomainInput = function (event) {
// Hide OK button if domain field is empty
document.documentElement.getButton('accept').disabled = event.target.value.trim() === '';
document.getElementById('zotero-quickCopySiteEditor').getButton('accept').disabled = event.target.value.trim() === '';
// Auto-select Wikipedia Citation Templates
if (event.target.value == 'wikipedia.org') {
@ -125,3 +130,4 @@
]]>
</script>
</dialog>
</window>

View file

@ -27,6 +27,7 @@
Zotero.Plugins = new function () {
var { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
var scopes = new Map();
var observers = new Set();
const REASONS = {
APP_STARTUP: 1,
@ -135,7 +136,21 @@ Zotero.Plugins = new function () {
Zotero.logError(`Error running bootstrap method '${method}' on ${id}`);
Zotero.logError(e);
}
for (let observer of observers) {
if (observer[method]) {
try {
let maybePromise = observer[method](params, reason);
if (maybePromise && maybePromise.then) {
await maybePromise;
}
}
catch (e) {
Zotero.logError(e);
}
}
}
// TODO: Needed?
/*if (method == "startup") {
activeAddon.startupPromise = Promise.resolve(result);
@ -159,6 +174,42 @@ Zotero.Plugins = new function () {
};
this.getName = async function (id) {
var addon = await AddonManager.getAddonByID(id);
return addon.name;
};
/**
* @param {String} id
* @param {Number} idealSize In logical pixels (scaled automatically on hiDPI displays)
* @returns {Promise<String | null>}
*/
this.getIconURI = async function (id, idealSize) {
var addon = await AddonManager.getAddonByID(id);
return AddonManager.getPreferredIconURL(addon, idealSize, Services.appShell.hiddenDOMWindow);
};
/**
* Add an observer to be notified of lifecycle events on all plugins.
*
* @param observer
* @param {Function} [observer.install]
* @param {Function} [observer.startup]
* @param {Function} [observer.shutdown]
* @param {Function} [observer.uninstall]
*/
this.addObserver = function (observer) {
observers.add(observer);
};
this.removeObserver = function (observer) {
observers.delete(observer);
};
this._addonObserver = {
initialized: false,

View file

@ -0,0 +1,164 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2022 Corporation for Digital Scholarship
Vienna, 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 *****
*/
/**
* Manages preference panes.
*/
Zotero.PreferencePanes = {
builtInPanes: Object.freeze([
{
id: 'zotero-prefpane-general',
label: 'zotero.preferences.prefpane.general',
image: 'chrome://zotero/skin/prefs-general.png',
src: 'chrome://zotero/content/preferences/preferences_general.xhtml',
scripts: ['chrome://zotero/content/preferences/preferences_general.js'],
defaultXUL: true,
},
{
id: 'zotero-prefpane-sync',
label: 'zotero.preferences.prefpane.sync',
image: 'chrome://zotero/skin/prefs-sync.png',
src: 'chrome://zotero/content/preferences/preferences_sync.xhtml',
scripts: ['chrome://zotero/content/preferences/preferences_sync.js'],
defaultXUL: true,
},
{
id: 'zotero-prefpane-export',
label: 'zotero.preferences.prefpane.export',
image: 'chrome://zotero/skin/prefs-export.png',
src: 'chrome://zotero/content/preferences/preferences_export.xhtml',
scripts: ['chrome://zotero/content/preferences/preferences_export.js'],
defaultXUL: true,
},
{
id: 'zotero-prefpane-cite',
label: 'zotero.preferences.prefpane.cite',
image: 'chrome://zotero/skin/prefs-styles.png',
src: 'chrome://zotero/content/preferences/preferences_cite.xhtml',
scripts: ['chrome://zotero/content/preferences/preferences_cite.js'],
defaultXUL: true,
},
{
id: 'zotero-prefpane-advanced',
label: 'zotero.preferences.prefpane.advanced',
image: 'chrome://zotero/skin/prefs-advanced.png',
src: 'chrome://zotero/content/preferences/preferences_advanced.xhtml',
scripts: ['chrome://zotero/content/preferences/preferences_advanced.js'],
defaultXUL: true,
},
{
id: 'zotero-subpane-reset-sync',
parent: 'zotero-prefpane-sync',
label: 'zotero.preferences.subpane.resetSync',
src: 'chrome://zotero/content/preferences/preferences_sync_reset.xhtml',
scripts: ['chrome://zotero/content/preferences/preferences_sync.js'],
defaultXUL: true,
}
]),
pluginPanes: [],
/**
* Register a pane to be displayed in the preferences. The pane XHTML (`src`)
* is loaded as a fragment, not a full document, with XUL as the default
* namespace and (X)HTML tags available under `html:`.
*
* The pane will be unregistered automatically when the registering plugin
* shuts down.
*
* @param {Object} options
* @param {String} options.id Represents the pane and must be unique
* @param {String} options.pluginID ID of the plugin registering the pane
* @param {String} [options.parent] ID of parent pane (if provided, pane is hidden from the sidebar)
* @param {String} [options.label] Displayed as the pane's label in the sidebar.
* If not provided, the plugin's name is used
* @param {String} [options.image] URI of an icon to be displayed in the navigation sidebar.
* If not provided, the plugin's icon (from manifest.json) is used
* @param {String} options.src URI of an XHTML fragment
* @param {String[]} [options.extraDTD] Array of URIs of DTD files to use for parsing the XHTML fragment
* @param {String[]} [options.scripts] Array of URIs of scripts to load along with the pane
* @return {Promise<void>}
*/
register: async function (options) {
if (!options.id || !options.pluginID || !options.src) {
throw new Error('id, pluginID, and src must be provided');
}
if (this.builtInPanes.some(p => p.id === options.id)
|| this.pluginPanes.some(p => p.id === options.id)) {
throw new Error(`Pane with ID ${options.id} already registered`);
}
let addPaneOptions = {
id: options.id,
pluginID: options.pluginID,
parent: options.parent,
rawLabel: options.label || await Zotero.Plugins.getName(options.pluginID),
image: options.image || await Zotero.Plugins.getIconURI(options.pluginID, 24),
src: options.src,
extraDTD: options.extraDTD,
scripts: options.scripts,
defaultXUL: false,
};
this.pluginPanes.push(addPaneOptions);
Zotero.debug(`Plugin ${options.pluginID} registered preference pane ${options.id} ("${addPaneOptions.rawLabel}")`);
this._refreshPreferences();
this._ensureObserverAdded();
},
/**
* Called automatically on plugin shutdown.
*
* @param {String} id
*/
unregister: function (id) {
this.pluginPanes = this.pluginPanes.filter(p => p.id !== id);
this._refreshPreferences();
},
_refreshPreferences() {
for (let win of Services.wm.getEnumerator("zotero:pref")) {
win.Zotero_Preferences.initPanes();
}
},
_ensureObserverAdded() {
if (this._observerAdded) {
return;
}
Zotero.Plugins.addObserver({
shutdown({ id: pluginID }) {
let beforeLength = this.pluginPanes.length;
this.pluginPanes = this.pluginPanes.filter(pane => pane.pluginID !== pluginID);
if (this.pluginPanes.length !== beforeLength) {
Zotero.debug(`Preference panes registered by plugin ${pluginID} unregistered due to shutdown`);
this._refreshPreferences();
}
}
});
this._observerAdded = true;
}
};

View file

@ -564,7 +564,7 @@ Zotero.Styles = new function() {
for (let i=0; i<menulist.itemCount; i++) {
let item = menulist.getItemAtIndex(i);
if (item.getAttributeNS('zotero:', 'customLocale')) {
menulist.removeItemAt(i);
item.remove();
i--;
continue;
}

View file

@ -1681,6 +1681,8 @@ Zotero.Utilities.Internal = {
let menuitem = menulist.ownerDocument.createXULElement('menuitem');
menuitem.value = library.libraryID;
menuitem.setAttribute('label', library.name);
menuitem.setAttribute('data-editable', library.editable ? 'true' : 'false');
menuitem.setAttribute('data-filesEditable', library.filesEditable ? 'true' : 'false');
menupopup.appendChild(menuitem);
if (library.libraryID == selectedLibraryID) {
selectedIndex = i;
@ -1814,7 +1816,7 @@ Zotero.Utilities.Internal = {
openPreferences: function (paneID, options = {}) {
if (typeof options == 'string') {
Zotero.debug("ZoteroPane.openPreferences() now takes an 'options' object -- update your code", 2);
Zotero.debug("openPreferences() now takes an 'options' object -- update your code", 2);
options = {
action: options
};
@ -1837,8 +1839,7 @@ Zotero.Utilities.Internal = {
var win = enumerator.getNext();
win.focus();
if (paneID) {
var pane = win.document.getElementsByAttribute('id', paneID)[0];
pane.parentElement.showPane(pane);
win.Zotero_Preferences.navigation.value = paneID;
// TODO: tab/action
}
@ -1846,9 +1847,9 @@ Zotero.Utilities.Internal = {
}
if (!win) {
let args = [
'chrome://zotero/content/preferences/preferences.xul',
'chrome://zotero/content/preferences/preferences.xhtml',
'zotero-prefs',
'chrome,titlebar,toolbar,centerscreen',
'chrome,titlebar,centerscreen,resizable=yes',
io
];

View file

@ -8,6 +8,7 @@
<!ENTITY zotero.preferences.prefpane.general "General">
<!ENTITY zotero.preferences.interface "Interface">
<!ENTITY zotero.preferences.fileHandling "File Handling">
<!ENTITY zotero.preferences.automaticSnapshots "Automatically take snapshots when creating items from web pages">
<!ENTITY zotero.preferences.downloadAssociatedFiles "Automatically attach associated PDFs and other files when saving items">
@ -83,6 +84,7 @@
<!ENTITY zotero.preferences.sync.reset.resetFileSyncHistory "Reset File Sync History">
<!ENTITY zotero.preferences.sync.reset.resetFileSyncHistory.desc "Compare all attachment files with the storage service">
<!ENTITY zotero.preferences.sync.reset "Reset">
<!ENTITY zotero.preferences.sync.reset.showResetOptions "Show Reset Options…">
<!ENTITY zotero.preferences.sync.reset.button "Reset…">

View file

@ -37,6 +37,7 @@
.zotero-view-item > tabpanel > *
{
overflow: auto;
min-width: 0;
}
.zotero-view-item:not([selectedIndex="0"]) > tabpanel > * {

View file

@ -1,3 +1,142 @@
#prefs-content {
min-height: 600px;
overflow-y: scroll;
}
#prefs-content > * {
margin: 5px 15px;
}
#prefs-search-container {
height: 40px;
padding-right: 8px;
}
#prefs-search {
width: 16em;
-moz-box-pack: end;
}
#prefs-navigation {
width: 180px;
appearance: none;
background: transparent;
margin: 6px;
}
#prefs-navigation > richlistitem {
padding: 1em;
border-radius: 5px;
-moz-box-align: center;
font-size: 1.1em;
transition: background-color 0.2s ease;
}
#prefs-navigation > richlistitem[selected="true"] {
background-color: highlight;
color: highlighttext;
}
#prefs-navigation > richlistitem:not([selected="true"]):hover {
background-color: color-mix(in srgb, transparent 60%, highlight);
}
#prefs-navigation > richlistitem image {
width: 24px;
}
#prefs-navigation > hr {
margin: 8px 0;
border: none;
border-top: 1px solid lightgray;
}
#prefs-subpane-back-button {
appearance: none;
font-size: 32px;
min-width: auto;
padding: 8px;
color: -moz-dialogtext;
background-color: transparent;
transition: color 0.1s ease;
}
#prefs-subpane-back-button:hover {
color: color-mix(in srgb, -moz-dialogtext 30%, SelectedItem);
}
#prefs-subpane-back-button:hover:active {
color: SelectedItem;
}
h1 {
margin: 0 0 4px 0;
font-size: 1.3em;
font-weight: normal;
}
.main-section {
margin-bottom: 16px;
}
.main-section:not([hidden]):not(.hidden-by-search) ~ .main-section {
padding-top: 16px;
margin-top: 32px;
border-top: 1px solid lightgray;
}
groupbox > label > h2, groupbox > * > label > h2 {
border-bottom: none;
font-weight: bold;
}
/* Approach to search tooltips (mostly borrowed from Fx prefs): */
.search-tooltip-parent {
position: relative;
}
.search-tooltip {
min-width: 20px;
max-width: 200px;
position: absolute;
bottom: 24px;
background-color: #ffe900;
border: 1px solid rgba(0, 0, 0, 40%);
padding: 2px 8px;
text-align: center;
}
.search-tooltip::before, .search-tooltip::after {
content: '';
position: absolute;
width: 0;
height: 0;
left: calc(50% - 3px);
border-right: 6px solid transparent;
border-left: 6px solid transparent;
}
.search-tooltip::before {
top: calc(100% + 1px);
border-top: 6px solid rgba(0, 0, 0, 40%);
}
.search-tooltip::after {
top: 100%;
border-top: 6px solid #ffe900;
}
.search-tooltip > span {
user-select: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.hidden-by-search {
display: none;
}
prefwindow .chromeclass-toolbar
{
display: -moz-box !important; /* Ignore toolbar collapse button on OS X */
@ -23,6 +162,12 @@ checkbox[disabled="true"] {
color: gray !important;
}
menulist[disabled="true"] {
opacity: 75%;
/* Disable default hover styling */
pointer-events: none;
}
#export-citePaperJournalArticleURL
{
font-size: .85em;
@ -41,17 +186,17 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
margin: 0;
}
/* General pane */
grid row:not(:first-child)
{
margin-top: .3em;
.form-grid {
display: grid;
grid-template-columns: max-content 1fr;
row-gap: .3em;
}
grid row hbox:first-child
{
.form-grid > :nth-child(odd) {
-moz-box-pack: end; /* Right-justify left column */
}
/* General pane */
#zotero-prefpane-general .statusLine {
margin-left: .75em;
}
@ -69,30 +214,36 @@ grid row hbox:first-child
*/
/* Settings tab */
#zotero-prefpane-sync row, #zotero-prefpane-sync row hbox
{
#zotero-prefpane-sync .form-grid {
align-items: center;
}
#zotero-prefpane-sync .form-grid > hbox {
-moz-box-align: center;
}
#zotero-prefpane-sync row label:first-child
#zotero-prefpane-sync .form-grid > label:nth-child(odd)
{
text-align: right;
}
#zotero-prefpane-sync row hbox
#zotero-prefpane-sync .form-grid > hbox
{
margin-left: 4px;
}
#zotero-prefpane-sync row hbox label:first-child,
#zotero-prefpane-sync row hbox menulist:first-child
#zotero-prefpane-sync .form-grid > hbox label:first-child,
#zotero-prefpane-sync .form-grid > hbox menulist:first-child
{
margin-left: 0;
margin-right: 0;
}
#zotero-prefpane-sync row hbox textbox
#zotero-prefpane-sync .form-grid > hbox textbox
{
margin-left: 3px;
margin-right: 3px;
}
#zotero-prefpane-sync row hbox label:last-child
#zotero-prefpane-sync .form-grid > hbox label:last-child
{
margin-left: 0;
margin-right: 10px;
@ -166,7 +317,7 @@ grid row hbox:first-child
margin-top: 1em;
}
#sync-reset-library-menu-container {
#sync-reset-library-menu-container > label {
font-weight: bold;
font-size: 15px;
}
@ -178,47 +329,45 @@ grid row hbox:first-child
height: 1.6em;
}
#sync-reset-list {
margin: 0;
padding: 0;
height: 9em;
#sync-reset-radiogroup {
margin-bottom: 1.4em;
}
#sync-reset-list li {
#sync-reset-radiogroup > div {
margin: 0;
margin-top: 1.6em;
padding: 0;
list-style: none;
height: 2.8em;
}
/* Allow a click between lines to select the radio */
#sync-reset-list li label {
#sync-reset-radiogroup > div label {
display: block;
}
#sync-reset-list li:first-child {
#sync-reset-radiogroup > div:first-child {
margin-top: 1.4em;
}
#sync-reset-list li .sync-reset-option-name {
#sync-reset-radiogroup > div radio .radio-label {
font-weight: bold;
display: block;
font-size: 15px;
margin-bottom: .2em;
}
#sync-reset-list li .sync-reset-option-desc {
#sync-reset-radiogroup > div .sync-reset-option-desc {
font-size: 12px;
}
#sync-reset-list li input {
#sync-reset-radiogroup > div radio {
float: left;
margin-top: 1em;
}
#sync-reset-radiogroup > div radio .radio-check {
margin-right: 1.05em;
}
#sync-reset-list li[disabled] span {
#sync-reset-radiogroup > div[disabled] span {
color: gray;
}
@ -235,7 +384,7 @@ grid row hbox:first-child
margin-top: 0 !important;
}
#fulltext-stats row > label:first-child
#fulltext-stats > .form-grid > label:nth-child(odd)
{
text-align: right;
}
@ -288,28 +437,18 @@ grid row hbox:first-child
}
/* Shortcut Keys pane */
#zotero-prefpane-advanced-keys-tab row
{
-moz-box-align: center;
}
#zotero-prefpane-advanced-keys-tab textbox
#zotero-prefpane-advanced-keys-tab input
{
margin-left: -1px;
}
treechildren::-moz-tree-checkbox {
/* unchecked checkbox treecells. This style MUST come before treechildren::-moz-tree-checkbox(checked) otherwise it won't take effect. */
list-style-image: none;
}
treechildren::-moz-tree-checkbox(checked){
/* css for checked cells. cbox-check.gif isn't available in Firefox 1, 2, and 3 on Mac OS X, so you should specify a URL to an image
in your extension or elsewhere. */
list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
}
/* Advanced pane */
#zotero-keys-grid {
display: grid;
align-items: center;
grid-template-columns: 1fr max-content max-content;
}
#command-line-data-dir description {
font-size: 12px;
cursor: text;
@ -333,6 +472,17 @@ treechildren::-moz-tree-checkbox(checked){
align-items: center;
}
#baseAttachmentPath {
padding-inline-start: 24px;
/* Background set in JS */
background: none;
background-repeat: no-repeat;
background-size: 16px;
background-position: center left 4px;
appearance: none;
border: none;
}
/* BEGIN 2X BLOCK -- DO NOT EDIT MANUALLY -- USE 2XIZE */
@media (min-resolution: 1.25dppx) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -52,14 +52,13 @@ richlistitem, richlistitem > * {
text-overflow: ellipsis;
}
groupbox > label > h2 {
groupbox > label > h2, groupbox > * > label > h2 {
font-size: 14px;
margin-top: 1em;
margin-bottom: .3em;
}
label.zotero-text-link {
-moz-binding: url('chrome://zotero/content/bindings/text-link.xml#text-link');
-moz-user-focus: normal;
color: -moz-nativehyperlinktext;
text-decoration: underline;

View file

@ -61,6 +61,7 @@ const xpcomFilesAll = [
'translate/src/tlds',
'translation/translate_firefox',
'isbn',
'preferencePanes',
];
/** XPCOM files to be loaded only for local translation and DB access **/

View file

@ -117,7 +117,6 @@ pref("extensions.zotero.export.displayCharsetOption", true);
pref("extensions.zotero.export.citePaperJournalArticleURL", false);
pref("extensions.zotero.cite.automaticJournalAbbreviations", true);
pref("extensions.zotero.cite.useCiteprocRs", false);
pref("extensions.zotero.import.charset", "auto");
pref("extensions.zotero.import.createNewCollection.fromFileOpenHandler", true);
pref("extensions.zotero.rtfScan.lastInputFile", "");
pref("extensions.zotero.rtfScan.lastOutputFile", "");

View file

@ -110,7 +110,7 @@ var loadZoteroPane = async function (win) {
var loadPrefPane = Zotero.Promise.coroutine(function* (paneName) {
var id = 'zotero-prefpane-' + paneName;
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xul", {
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xhtml", {
pane: id
});
var doc = win.document;

View file

@ -19,7 +19,7 @@ describe("Create Bibliography Dialog", function () {
var deferred = Zotero.Promise.defer();
var called = false;
waitForWindow("chrome://zotero/content/bibliography.xhtml", function (dialog) {
waitForWindow("chrome://zotero/content/preferences/preferences.xul", function (window) {
waitForWindow("chrome://zotero/content/preferences/preferences.xhtml", function (window) {
// Wait for pane switch
(async function () {
do {

View file

@ -16,7 +16,7 @@ describe("Advanced Preferences", function () {
describe("Debug Output", function () {
it("should log output and submit to server", function* () {
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xul", {
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xhtml", {
pane: 'zotero-prefpane-advanced',
tabIndex: 0
});
@ -64,7 +64,7 @@ describe("Advanced Preferences", function () {
describe("Files & Folders", function () {
describe("Linked Attachment Base Directory", function () {
var setBaseDirectory = Zotero.Promise.coroutine(function* (basePath) {
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xul", {
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xhtml", {
pane: 'zotero-prefpane-advanced',
tabIndex: 1
});
@ -89,7 +89,7 @@ describe("Advanced Preferences", function () {
});
var clearBaseDirectory = Zotero.Promise.coroutine(function* (basePath) {
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xul", {
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xhtml", {
pane: 'zotero-prefpane-advanced',
tabIndex: 1
});

View file

@ -2,7 +2,7 @@ describe("Sync Preferences", function () {
var win, doc;
before(function* () {
// Load prefs with sync pane
win = yield loadWindow("chrome://zotero/content/preferences/preferences.xul", {
win = yield loadWindow("chrome://zotero/content/preferences/preferences.xhtml", {
pane: 'zotero-prefpane-sync',
tabIndex: 0
});