diff --git a/chrome/content/zotero-platform/mac/preferences.css b/chrome/content/zotero-platform/mac/preferences.css index 41f7eaed3a..c4b9f6faee 100644 --- a/chrome/content/zotero-platform/mac/preferences.css +++ b/chrome/content/zotero-platform/mac/preferences.css @@ -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; -} \ No newline at end of file diff --git a/chrome/content/zotero-platform/unix/preferences.css b/chrome/content/zotero-platform/unix/preferences.css index 6db578c088..b6876a830f 100644 --- a/chrome/content/zotero-platform/unix/preferences.css +++ b/chrome/content/zotero-platform/unix/preferences.css @@ -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; } diff --git a/chrome/content/zotero-platform/win/preferences.css b/chrome/content/zotero-platform/win/preferences.css index 1b3990d879..1832672d94 100644 --- a/chrome/content/zotero-platform/win/preferences.css +++ b/chrome/content/zotero-platform/win/preferences.css @@ -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; -} diff --git a/chrome/content/zotero/bindings/preferences-mac.xml b/chrome/content/zotero/bindings/preferences-mac.xml deleted file mode 100644 index 7fc6fe939d..0000000000 --- a/chrome/content/zotero/bindings/preferences-mac.xml +++ /dev/null @@ -1,1358 +0,0 @@ - - - - %preferencesDTD; - - %globalKeysDTD; -]> - - - - - - - elements is constructed. Its purpose is to propagate - // the values to the associated form elements - - var elements = this.getElementsByTagName("preference"); - for (let element of elements) { - if (!element._constructed) { - return; - } - } - for (let element of elements) { - element.updateElements(); - } - ]]> - - - - - - - - - - - - - - - - - - - - Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefService); - - - Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - - - this.service.getDefaultBranch(""); - - - Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - - - - - - - - - - - - - - - - - - - - - this.preferences.rootBranchInternal - .removeObserver(this.name, this.preferences); - - false - - - if (this.getAttribute("instantApply") == "false") - return false; - return this.getAttribute("instantApply") == "true" || this.preferences.instantApply; - - - - - - - if (val == this.name) - return val; - - this.preferences.rootBranchInternal - .removeObserver(this.name, this.preferences); - this.setAttribute('name', val); - this.preferences.rootBranchInternal - .addObserver(val, this.preferences, false); - - return val; - - - - - - - null - - - - - - - - - - - return this.preferences.rootBranch.prefIsLocked(this.name); - - - - - - return this.getAttribute("disabled") == "true"; - - - - - - - - - return parseInt(this.getAttribute("tabindex")); - - - - - - - - - - - - - - - // defer reset until preference update - this.value = undefined; - - - - false - - - - - - - - - return this._useDefault ? this.preferences.defaultBranch : this.preferences.rootBranch; - - - - false - - - - with id='" + this.id + "' and name='" + - this.name + "' has unknown type '" + this.type + "'."; - consoleService.logStringMessage(msg); - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - this.updateElements(); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - false - - - - - - - - - - this.setAttribute("lastSelected", val); - document.persist(this.id, "lastSelected"); - return val; - - - - - if (!this._currentPane) - this._currentPane = this.preferencePanes[0]; - - return this._currentPane; - - - null - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - 1) - aPaneElement.removeAttribute("flex"); - // Calling sizeToContent after the first prefpane is loaded - // will size the windows contents so style information is - // available to calculate correct sizing. - if (!this._initialized && prefpanes.length > 1) { - if (this._shouldAnimate) - this.style.minHeight = 0; - window.sizeToContent(); - } - - var oldPane = this.lastSelected ? document.getElementById(this.lastSelected) : this.preferencePanes[0]; - oldPane.selected = !(aPaneElement.selected = true); - this.lastSelected = aPaneElement.id; - this.currentPane = aPaneElement; - this._initialized = true; - - // Only animate if we've switched between prefpanes - if (this._shouldAnimate && oldPane.id != aPaneElement.id) { - aPaneElement.style.opacity = 0.0; - this.animate(oldPane, aPaneElement); - } - else if (!this._shouldAnimate && prefpanes.length > 1) { - var targetHeight = parseInt(window.getComputedStyle(this._paneDeckContainer, "").height); - var verticalPadding = parseInt(window.getComputedStyle(aPaneElement, "").paddingTop); - verticalPadding += parseInt(window.getComputedStyle(aPaneElement, "").paddingBottom); - if (aPaneElement.contentHeight > targetHeight - verticalPadding) { - // To workaround the bottom border of a groupbox from being - // cutoff an hbox with a class of bottomBox may enclose it. - // This needs to include its padding to resize properly. - // See bug 394433 - var bottomPadding = 0; - var bottomBox = aPaneElement.getElementsByAttribute("class", "bottomBox")[0]; - if (bottomBox) - bottomPadding = parseInt(window.getComputedStyle(bottomBox, "").paddingBottom); - window.innerHeight += bottomPadding + verticalPadding + aPaneElement.contentHeight - targetHeight; - } - - // XXX rstrong - extend the contents of the prefpane to - // prevent elements from being cutoff (see bug 349098). - if (aPaneElement.contentHeight + verticalPadding < targetHeight) - aPaneElement._content.style.height = targetHeight - verticalPadding + "px"; - } - } - break; - } - } - ]]> - - - - - - - - - - - - - - oldHeight ? 1 : -1; - var sizeDelta = Math.abs(oldHeight - aNewPane.contentHeight); - this._animateRemainder = sizeDelta % this._animateIncrement; - - this._setUpAnimationTimer(oldHeight); - ]]> - - - - - - 0 && this._currentHeight >= lastSelectedPane.contentHeight) || - (this._multiplier < 0 && this._currentHeight <= lastSelectedPane.contentHeight)) - return 0; - - if ((this._multiplier > 0 && newHeight > lastSelectedPane.contentHeight) || - (this._multiplier < 0 && newHeight < lastSelectedPane.contentHeight)) - increment = this._animateRemainder * this._multiplier; - return increment; - ]]> - - - - - - - - - - - - - - - - - - - - - - - - null - null - 15 - 40 - 5 - 0.40 - 0 - 0 - 0 - - - - - - - - - - - - - - return openDialog(aURL, "", "modal,centerscreen,resizable=no" + (aFeatures != "" ? ("," + aFeatures) : ""), aParams); - - - - - - - - - - - - - - - - - - - if (event.originalTarget.hasAttribute("pane")) { - var pane = document.getElementById(event.originalTarget.getAttribute("pane")); - this.showPane(pane); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - - - return document.getElementById(aElement.getAttribute("preference")); - - - - - - - - - - - - - - - - - - - - - new Set(); - - - - - - - - - - - - - - - - var targetHeight = parseInt(window.getComputedStyle(this._content, "").height); - targetHeight += parseInt(window.getComputedStyle(this._content, "").marginTop); - targetHeight += parseInt(window.getComputedStyle(this._content, "").marginBottom); - return targetHeight; - - - - document.getAnonymousElementByAttribute(this, "class", "content-box"); - - - - - // This "command" event handler tracks changes made to preferences by - // the user in this window. - if (event.sourceEvent) - event = event.sourceEvent; - this.userChangedValue(event.target); - - - // This "select" event handler tracks changes made to colorpicker - // preferences by the user in this window. - if (event.target.localName == "colorpicker") - this.userChangedValue(event.target); - - - // This "change" event handler tracks changes made to preferences by - // the user in this window. - this.userChangedValue(event.target); - - - // This "input" event handler tracks changes made to preferences by - // the user in this window. - this.userChangedValue(event.target); - - - - - - - - - - - - - - - - - - diff --git a/chrome/content/zotero/bindings/preferences-unix.xml b/chrome/content/zotero/bindings/preferences-unix.xml deleted file mode 100644 index 28c6bdf081..0000000000 --- a/chrome/content/zotero/bindings/preferences-unix.xml +++ /dev/null @@ -1,1358 +0,0 @@ - - - - %preferencesDTD; - - %globalKeysDTD; -]> - - - - - - - elements is constructed. Its purpose is to propagate - // the values to the associated form elements - - var elements = this.getElementsByTagName("preference"); - for (let element of elements) { - if (!element._constructed) { - return; - } - } - for (let element of elements) { - element.updateElements(); - } - ]]> - - - - - - - - - - - - - - - - - - - - Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefService); - - - Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - - - this.service.getDefaultBranch(""); - - - Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - - - - - - - - - - - - - - - - - - - - - this.preferences.rootBranchInternal - .removeObserver(this.name, this.preferences); - - false - - - if (this.getAttribute("instantApply") == "false") - return false; - return this.getAttribute("instantApply") == "true" || this.preferences.instantApply; - - - - - - - if (val == this.name) - return val; - - this.preferences.rootBranchInternal - .removeObserver(this.name, this.preferences); - this.setAttribute('name', val); - this.preferences.rootBranchInternal - .addObserver(val, this.preferences, false); - - return val; - - - - - - - null - - - - - - - - - - - return this.preferences.rootBranch.prefIsLocked(this.name); - - - - - - return this.getAttribute("disabled") == "true"; - - - - - - - - - return parseInt(this.getAttribute("tabindex")); - - - - - - - - - - - - - - - // defer reset until preference update - this.value = undefined; - - - - false - - - - - - - - - return this._useDefault ? this.preferences.defaultBranch : this.preferences.rootBranch; - - - - false - - - - with id='" + this.id + "' and name='" + - this.name + "' has unknown type '" + this.type + "'."; - consoleService.logStringMessage(msg); - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - this.updateElements(); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - false - - - - - - - - - - this.setAttribute("lastSelected", val); - document.persist(this.id, "lastSelected"); - return val; - - - - - if (!this._currentPane) - this._currentPane = this.preferencePanes[0]; - - return this._currentPane; - - - null - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - 1) - aPaneElement.removeAttribute("flex"); - // Calling sizeToContent after the first prefpane is loaded - // will size the windows contents so style information is - // available to calculate correct sizing. - if (!this._initialized && prefpanes.length > 1) { - if (this._shouldAnimate) - this.style.minHeight = 0; - window.sizeToContent(); - } - - var oldPane = this.lastSelected ? document.getElementById(this.lastSelected) : this.preferencePanes[0]; - oldPane.selected = !(aPaneElement.selected = true); - this.lastSelected = aPaneElement.id; - this.currentPane = aPaneElement; - this._initialized = true; - - // Only animate if we've switched between prefpanes - if (this._shouldAnimate && oldPane.id != aPaneElement.id) { - aPaneElement.style.opacity = 0.0; - this.animate(oldPane, aPaneElement); - } - else if (!this._shouldAnimate && prefpanes.length > 1) { - var targetHeight = parseInt(window.getComputedStyle(this._paneDeckContainer, "").height); - var verticalPadding = parseInt(window.getComputedStyle(aPaneElement, "").paddingTop); - verticalPadding += parseInt(window.getComputedStyle(aPaneElement, "").paddingBottom); - if (aPaneElement.contentHeight > targetHeight - verticalPadding) { - // To workaround the bottom border of a groupbox from being - // cutoff an hbox with a class of bottomBox may enclose it. - // This needs to include its padding to resize properly. - // See bug 394433 - var bottomPadding = 0; - var bottomBox = aPaneElement.getElementsByAttribute("class", "bottomBox")[0]; - if (bottomBox) - bottomPadding = parseInt(window.getComputedStyle(bottomBox, "").paddingBottom); - window.innerHeight += bottomPadding + verticalPadding + aPaneElement.contentHeight - targetHeight; - } - - // XXX rstrong - extend the contents of the prefpane to - // prevent elements from being cutoff (see bug 349098). - if (aPaneElement.contentHeight + verticalPadding < targetHeight) - aPaneElement._content.style.height = targetHeight - verticalPadding + "px"; - } - } - break; - } - } - ]]> - - - - - - - - - - - - - - oldHeight ? 1 : -1; - var sizeDelta = Math.abs(oldHeight - aNewPane.contentHeight); - this._animateRemainder = sizeDelta % this._animateIncrement; - - this._setUpAnimationTimer(oldHeight); - ]]> - - - - - - 0 && this._currentHeight >= lastSelectedPane.contentHeight) || - (this._multiplier < 0 && this._currentHeight <= lastSelectedPane.contentHeight)) - return 0; - - if ((this._multiplier > 0 && newHeight > lastSelectedPane.contentHeight) || - (this._multiplier < 0 && newHeight < lastSelectedPane.contentHeight)) - increment = this._animateRemainder * this._multiplier; - return increment; - ]]> - - - - - - - - - - - - - - - - - - - - - - - - null - null - 15 - 40 - 5 - 0.40 - 0 - 0 - 0 - - - - - - - - - - - - - - return openDialog(aURL, "", "modal,centerscreen,resizable=no" + (aFeatures != "" ? ("," + aFeatures) : ""), aParams); - - - - - - - - - - - - - - - - - - - if (event.originalTarget.hasAttribute("pane")) { - var pane = document.getElementById(event.originalTarget.getAttribute("pane")); - this.showPane(pane); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - - - return document.getElementById(aElement.getAttribute("preference")); - - - - - - - - - - - - - - - - - - - - - new Set(); - - - - - - - - - - - - - - - - var targetHeight = parseInt(window.getComputedStyle(this._content, "").height); - targetHeight += parseInt(window.getComputedStyle(this._content, "").marginTop); - targetHeight += parseInt(window.getComputedStyle(this._content, "").marginBottom); - return targetHeight; - - - - document.getAnonymousElementByAttribute(this, "class", "content-box"); - - - - - // This "command" event handler tracks changes made to preferences by - // the user in this window. - if (event.sourceEvent) - event = event.sourceEvent; - this.userChangedValue(event.target); - - - // This "select" event handler tracks changes made to colorpicker - // preferences by the user in this window. - if (event.target.localName == "colorpicker") - this.userChangedValue(event.target); - - - // This "change" event handler tracks changes made to preferences by - // the user in this window. - this.userChangedValue(event.target); - - - // This "input" event handler tracks changes made to preferences by - // the user in this window. - this.userChangedValue(event.target); - - - - - - - - - - - - - - - - - - diff --git a/chrome/content/zotero/bindings/preferences-win.xml b/chrome/content/zotero/bindings/preferences-win.xml deleted file mode 100644 index e9afdb8758..0000000000 --- a/chrome/content/zotero/bindings/preferences-win.xml +++ /dev/null @@ -1,1358 +0,0 @@ - - - - %preferencesDTD; - - %globalKeysDTD; -]> - - - - - - - elements is constructed. Its purpose is to propagate - // the values to the associated form elements - - var elements = this.getElementsByTagName("preference"); - for (let element of elements) { - if (!element._constructed) { - return; - } - } - for (let element of elements) { - element.updateElements(); - } - ]]> - - - - - - - - - - - - - - - - - - - - Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefService); - - - Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - - - this.service.getDefaultBranch(""); - - - Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - - - - - - - - - - - - - - - - - - - - - this.preferences.rootBranchInternal - .removeObserver(this.name, this.preferences); - - false - - - if (this.getAttribute("instantApply") == "false") - return false; - return this.getAttribute("instantApply") == "true" || this.preferences.instantApply; - - - - - - - if (val == this.name) - return val; - - this.preferences.rootBranchInternal - .removeObserver(this.name, this.preferences); - this.setAttribute('name', val); - this.preferences.rootBranchInternal - .addObserver(val, this.preferences, false); - - return val; - - - - - - - null - - - - - - - - - - - return this.preferences.rootBranch.prefIsLocked(this.name); - - - - - - return this.getAttribute("disabled") == "true"; - - - - - - - - - return parseInt(this.getAttribute("tabindex")); - - - - - - - - - - - - - - - // defer reset until preference update - this.value = undefined; - - - - false - - - - - - - - - return this._useDefault ? this.preferences.defaultBranch : this.preferences.rootBranch; - - - - false - - - - with id='" + this.id + "' and name='" + - this.name + "' has unknown type '" + this.type + "'."; - consoleService.logStringMessage(msg); - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - this.updateElements(); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - false - - - - - - - - - - this.setAttribute("lastSelected", val); - document.persist(this.id, "lastSelected"); - return val; - - - - - if (!this._currentPane) - this._currentPane = this.preferencePanes[0]; - - return this._currentPane; - - - null - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - 1) - aPaneElement.removeAttribute("flex"); - // Calling sizeToContent after the first prefpane is loaded - // will size the windows contents so style information is - // available to calculate correct sizing. - if (!this._initialized && prefpanes.length > 1) { - if (this._shouldAnimate) - this.style.minHeight = 0; - window.sizeToContent(); - } - - var oldPane = this.lastSelected ? document.getElementById(this.lastSelected) : this.preferencePanes[0]; - oldPane.selected = !(aPaneElement.selected = true); - this.lastSelected = aPaneElement.id; - this.currentPane = aPaneElement; - this._initialized = true; - - // Only animate if we've switched between prefpanes - if (this._shouldAnimate && oldPane.id != aPaneElement.id) { - aPaneElement.style.opacity = 0.0; - this.animate(oldPane, aPaneElement); - } - else if (!this._shouldAnimate && prefpanes.length > 1) { - var targetHeight = parseInt(window.getComputedStyle(this._paneDeckContainer, "").height); - var verticalPadding = parseInt(window.getComputedStyle(aPaneElement, "").paddingTop); - verticalPadding += parseInt(window.getComputedStyle(aPaneElement, "").paddingBottom); - if (aPaneElement.contentHeight > targetHeight - verticalPadding) { - // To workaround the bottom border of a groupbox from being - // cutoff an hbox with a class of bottomBox may enclose it. - // This needs to include its padding to resize properly. - // See bug 394433 - var bottomPadding = 0; - var bottomBox = aPaneElement.getElementsByAttribute("class", "bottomBox")[0]; - if (bottomBox) - bottomPadding = parseInt(window.getComputedStyle(bottomBox, "").paddingBottom); - window.innerHeight += bottomPadding + verticalPadding + aPaneElement.contentHeight - targetHeight; - } - - // XXX rstrong - extend the contents of the prefpane to - // prevent elements from being cutoff (see bug 349098). - if (aPaneElement.contentHeight + verticalPadding < targetHeight) - aPaneElement._content.style.height = targetHeight - verticalPadding + "px"; - } - } - break; - } - } - ]]> - - - - - - - - - - - - - - oldHeight ? 1 : -1; - var sizeDelta = Math.abs(oldHeight - aNewPane.contentHeight); - this._animateRemainder = sizeDelta % this._animateIncrement; - - this._setUpAnimationTimer(oldHeight); - ]]> - - - - - - 0 && this._currentHeight >= lastSelectedPane.contentHeight) || - (this._multiplier < 0 && this._currentHeight <= lastSelectedPane.contentHeight)) - return 0; - - if ((this._multiplier > 0 && newHeight > lastSelectedPane.contentHeight) || - (this._multiplier < 0 && newHeight < lastSelectedPane.contentHeight)) - increment = this._animateRemainder * this._multiplier; - return increment; - ]]> - - - - - - - - - - - - - - - - - - - - - - - - null - null - 15 - 40 - 5 - 0.40 - 0 - 0 - 0 - - - - - - - - - - - - - - return openDialog(aURL, "", "modal,centerscreen,resizable=no" + (aFeatures != "" ? ("," + aFeatures) : ""), aParams); - - - - - - - - - - - - - - - - - - - if (event.originalTarget.hasAttribute("pane")) { - var pane = document.getElementById(event.originalTarget.getAttribute("pane")); - this.showPane(pane); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - - - return document.getElementById(aElement.getAttribute("preference")); - - - - - - - - - - - - - - - - - - - - - new Set(); - - - - - - - - - - - - - - - - var targetHeight = parseInt(window.getComputedStyle(this._content, "").height); - targetHeight += parseInt(window.getComputedStyle(this._content, "").marginTop); - targetHeight += parseInt(window.getComputedStyle(this._content, "").marginBottom); - return targetHeight; - - - - document.getAnonymousElementByAttribute(this, "class", "content-box"); - - - - - // This "command" event handler tracks changes made to preferences by - // the user in this window. - if (event.sourceEvent) - event = event.sourceEvent; - this.userChangedValue(event.target); - - - // This "select" event handler tracks changes made to colorpicker - // preferences by the user in this window. - if (event.target.localName == "colorpicker") - this.userChangedValue(event.target); - - - // This "change" event handler tracks changes made to preferences by - // the user in this window. - this.userChangedValue(event.target); - - - // This "input" event handler tracks changes made to preferences by - // the user in this window. - this.userChangedValue(event.target); - - - - - - - - - - - - - - - - - - diff --git a/chrome/content/zotero/bindings/text-link.xml b/chrome/content/zotero/bindings/text-link.xml deleted file mode 100644 index a42fa48120..0000000000 --- a/chrome/content/zotero/bindings/text-link.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/chrome/content/zotero/charsetMenu.js b/chrome/content/zotero/charsetMenu.js index 0d4d0a4458..51ee1b80dd 100644 --- a/chrome/content/zotero/charsetMenu.js +++ b/chrome/content/zotero/charsetMenu.js @@ -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 { + 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' }); +} diff --git a/chrome/content/zotero/locateManager.xhtml b/chrome/content/zotero/locateManager.xhtml index 9f6f68f2c5..7f5f1c153f 100644 --- a/chrome/content/zotero/locateManager.xhtml +++ b/chrome/content/zotero/locateManager.xhtml @@ -31,17 +31,6 @@ - + + + + + + + + + %prefWindow; + + %common; +]> + + + + + + + diff --git a/chrome/content/zotero/preferences/librariesToSync.xul b/chrome/content/zotero/preferences/librariesToSync.xul deleted file mode 100644 index 4b00f30e59..0000000000 --- a/chrome/content/zotero/preferences/librariesToSync.xul +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - %prefWindow; - - %common; -]> - - - - - \ No newline at end of file diff --git a/chrome/content/zotero/preferences/preferences.js b/chrome/content/zotero/preferences/preferences.js index 1aebb6db1d..9c41c9de7a 100644 --- a/chrome/content/zotero/preferences/preferences.js +++ b/chrome/content/zotero/preferences/preferences.js @@ -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 + ? ` { + return preamble + ` %_dtd-${index}; `; + }, '')}]>` + : ""} +
+${str} +
`, "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