fx-compat: Fix feed Add To button
And make accessible by keyboard
This commit is contained in:
parent
730677a918
commit
53ace4876e
6 changed files with 142 additions and 21 deletions
|
@ -33,26 +33,9 @@
|
|||
constructor() {
|
||||
super();
|
||||
this.addEventListener('mousedown', (event) => {
|
||||
let popup = this.querySelector(':scope > menupopup');
|
||||
if (popup && this.getAttribute('nonnativepopup') != 'true') {
|
||||
if (this.getAttribute('nonnativepopup') != 'true'
|
||||
&& Zotero.Utilities.Internal.showNativeElementPopup(this)) {
|
||||
event.preventDefault();
|
||||
|
||||
let rect = this.getBoundingClientRect();
|
||||
let dir = getComputedStyle(this).direction;
|
||||
popup.openPopupAtScreen(
|
||||
window.screenX + (dir == 'rtl' ? rect.right : rect.left),
|
||||
window.screenY + rect.bottom,
|
||||
true
|
||||
);
|
||||
this.setAttribute('open', true);
|
||||
|
||||
let handler = (event) => {
|
||||
if (event.target == popup) {
|
||||
this.setAttribute('open', false);
|
||||
popup.removeEventListener('popuphiding', handler);
|
||||
}
|
||||
};
|
||||
popup.addEventListener('popuphiding', handler);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
95
chrome/content/zotero/elements/splitMenuButton.js
Normal file
95
chrome/content/zotero/elements/splitMenuButton.js
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright © 2022 Corporation for Digital Scholarship
|
||||
Vienna, Virginia, USA
|
||||
https://www.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";
|
||||
|
||||
{
|
||||
/**
|
||||
* Extends MozButton to provide a split menubutton with a clickable left side and a dropmarker that opens a menu.
|
||||
*/
|
||||
class SplitMenuButton extends customElements.get('button') {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// Just in case, make sure this button does NOT appear as a standard <button type="menu">
|
||||
// We don't want the entire button to open the menu and we don't want the standard dropmarker
|
||||
this.removeAttribute('type');
|
||||
|
||||
// For easier CSS targeting
|
||||
this.classList.add('split-menu-button');
|
||||
|
||||
// Pointer events don't reach the button's children, so check mousedown positions manually and open
|
||||
// the popup if over the end side of the button
|
||||
this.addEventListener('mousedown', (event) => {
|
||||
let rect = this.querySelector('[anonid="dropmarker-box"]').getBoundingClientRect();
|
||||
if (event.x >= rect.left && event.x <= rect.right
|
||||
&& Zotero.Utilities.Internal.showNativeElementPopup(this)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
this.addEventListener('keydown', (event) => {
|
||||
if (event.key == 'ArrowDown' && Zotero.Utilities.Internal.showNativeElementPopup(this)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (this.delayConnectedCallback() || this._hasConnected) {
|
||||
return;
|
||||
}
|
||||
super.connectedCallback();
|
||||
|
||||
this.querySelector('[anonid="button-box"]').after(this.constructor.dropmarkerFragment);
|
||||
}
|
||||
|
||||
static get dropmarkerFragment() {
|
||||
// Zotero.hiDPI[Suffix] may not have been initialized yet, so calculate it ourselves
|
||||
let hiDPISuffix = window.devicePixelRatio > 1 ? '@2x' : '';
|
||||
let frag = document.importNode(
|
||||
MozXULElement.parseXULToFragment(`
|
||||
<hbox align="center" anonid="dropmarker-box">
|
||||
<image src="chrome://zotero/skin/searchbar-dropmarker${hiDPISuffix}.png" width="7" height="4" class="split-menu-button-dropmarker"/>
|
||||
</hbox>
|
||||
`),
|
||||
true
|
||||
);
|
||||
Object.defineProperty(this, "dropmarkerFragment", { value: frag });
|
||||
return frag;
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
super._handleClick();
|
||||
if (!this.disabled) {
|
||||
this.doCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("split-menu-button", SplitMenuButton, {
|
||||
extends: "button",
|
||||
});
|
||||
}
|
|
@ -2339,6 +2339,39 @@ Zotero.Utilities.Internal = {
|
|||
}
|
||||
}
|
||||
return html;
|
||||
},
|
||||
|
||||
/**
|
||||
* Open an element's <menupopup> child as a native context menu.
|
||||
*
|
||||
* @param {XULElement} element
|
||||
* @return {Boolean} If a <menupopup> child was found and opened
|
||||
*/
|
||||
showNativeElementPopup(element) {
|
||||
let popup = element.querySelector(':scope > menupopup');
|
||||
if (popup) {
|
||||
let rect = element.getBoundingClientRect();
|
||||
let win = element.ownerDocument.defaultView;
|
||||
let dir = win.getComputedStyle(element).direction;
|
||||
popup.openPopupAtScreen(
|
||||
win.screenX + (dir == 'rtl' ? rect.right : rect.left),
|
||||
win.screenY + rect.bottom,
|
||||
true
|
||||
);
|
||||
element.setAttribute('open', true);
|
||||
|
||||
let handler = (event) => {
|
||||
if (event.target == popup) {
|
||||
element.setAttribute('open', false);
|
||||
popup.removeEventListener('popuphiding', handler);
|
||||
}
|
||||
};
|
||||
popup.addEventListener('popuphiding', handler);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/attachmentBox.js", this);
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/menuToolbarbutton.js", this);
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/quickSearchTextbox.js", this);
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/splitMenuButton.js", this);
|
||||
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/tabs.js", this);
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/zoteroPane.js", this);
|
||||
|
@ -1054,7 +1055,7 @@
|
|||
<hbox id="zotero-item-pane-top-buttons-feed" class="zotero-item-pane-top-buttons" hidden="true">
|
||||
<button id="zotero-feed-item-toggleRead-button"
|
||||
oncommand="ZoteroPane_Local.toggleSelectedItemsRead();"/>
|
||||
<button id="zotero-feed-item-addTo-button" type="menu-button"
|
||||
<button is="split-menu-button" id="zotero-feed-item-addTo-button"
|
||||
oncommand="ZoteroItemPane.translateSelectedItems()">
|
||||
<menupopup id="zotero-item-addTo-menu" onpopupshowing="ZoteroItemPane.buildTranslateSelectContextMenu(event);"/>
|
||||
</button>
|
||||
|
|
|
@ -100,6 +100,6 @@
|
|||
}
|
||||
|
||||
#zotero-feed-item-addTo-button .button-icon {
|
||||
margin-right: 5px;
|
||||
margin-inline-end: 5px;
|
||||
height: 16px;
|
||||
}
|
||||
|
|
|
@ -703,6 +703,15 @@
|
|||
color: HighlightText;
|
||||
}
|
||||
|
||||
.split-menu-button, .split-menu-button [anonid="dropmarker-box"] {
|
||||
/* Hide the dropmarker if the button overflows */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.split-menu-button .split-menu-button-dropmarker {
|
||||
margin-inline: 5px;
|
||||
}
|
||||
|
||||
|
||||
/* BEGIN 2X BLOCK -- DO NOT EDIT MANUALLY -- USE 2XIZE */
|
||||
@media (min-resolution: 1.25dppx) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue