Add generic menu for all unfocused editable-texts
This commit is contained in:
parent
af79e9c405
commit
6b1940cebb
4 changed files with 96 additions and 54 deletions
|
@ -101,16 +101,16 @@ function goBuildEditContextMenu() {
|
|||
MozXULElement.parseXULToFragment(`
|
||||
<popupset>
|
||||
<menupopup id="textbox-contextmenu" class="textbox-contextmenu">
|
||||
<menuitem data-l10n-id="text-action-undo" command="cmd_undo"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-redo" command="cmd_redo"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-undo" command="cmd_undo" data-action="undo"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-redo" command="cmd_redo" data-action="redo"></menuitem>
|
||||
<menuseparator></menuseparator>
|
||||
<menuitem data-l10n-id="text-action-cut" command="cmd_cut"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-copy" command="cmd_copy"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-paste" command="cmd_paste"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-delete" command="cmd_delete"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-select-all" command="cmd_selectAll"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-cut" command="cmd_cut" data-action="cut"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-copy" command="cmd_copy" data-action="copy"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-paste" command="cmd_paste" data-action="paste"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-delete" command="cmd_delete" data-action="delete"></menuitem>
|
||||
<menuitem data-l10n-id="text-action-select-all" command="cmd_selectAll" data-action="selectAll"></menuitem>
|
||||
<menuseparator></menuseparator>
|
||||
<menuitem data-l10n-id="menu-edit-bidi-switch-text-direction" command="cmd_switchTextDirection"></menuitem>
|
||||
<menuitem data-l10n-id="menu-edit-bidi-switch-text-direction" command="cmd_switchTextDirection" data-action="switchTextDirection"></menuitem>
|
||||
</menupopup>
|
||||
</popupset>
|
||||
`)
|
||||
|
|
|
@ -224,12 +224,6 @@
|
|||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
input.addEventListener('contextmenu', (event) => {
|
||||
// Prevent the text editing context menu from opening when unfocused
|
||||
if (document.activeElement !== this._input) {
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
let focused = false;
|
||||
let selectionStart = this._input?.selectionStart;
|
||||
|
@ -298,4 +292,33 @@
|
|||
}
|
||||
}
|
||||
customElements.define("editable-text", EditableText);
|
||||
|
||||
document.addEventListener('contextmenu', (event) => {
|
||||
if (event.defaultPrevented
|
||||
|| !event.target.closest('editable-text')
|
||||
|| document.activeElement && event.target.contains(document.activeElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
let editableText = event.target.closest('editable-text');
|
||||
let menupopup = document.getElementById('zotero-editable-text-menu');
|
||||
if (!menupopup) {
|
||||
menupopup = document.createXULElement('menupopup');
|
||||
menupopup.id = 'zotero-editable-text-menu';
|
||||
|
||||
let popupset = document.querySelector('popupset');
|
||||
if (!popupset) {
|
||||
popupset = document.createXULElement('popupset');
|
||||
document.documentElement.append(popupset);
|
||||
}
|
||||
popupset.append(menupopup);
|
||||
}
|
||||
|
||||
menupopup.addEventListener('popupshowing', () => {
|
||||
Zotero.Utilities.Internal.updateEditContextMenu(menupopup, editableText);
|
||||
}, { once: true });
|
||||
menupopup.openPopupAtScreen(event.screenX + 1, event.screenY + 1, true);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
<div id="retraction-hide"><button/></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="info-table"> </div>
|
||||
<div id="info-table"></div>
|
||||
</div>
|
||||
</html:div>
|
||||
</collapsible-section>
|
||||
|
@ -207,9 +207,24 @@
|
|||
event => this.capitalizeCreatorName(event));
|
||||
|
||||
this._linkMenu.addEventListener('popupshowing', () => {
|
||||
let disabled = !this._linkMenu.dataset.link;
|
||||
this._id('zotero-link-menu-view-online').disabled = disabled;
|
||||
this._id('zotero-link-menu-copy').disabled = disabled;
|
||||
let menu = this._linkMenu;
|
||||
let link = menu.dataset.link;
|
||||
let val = menu.dataset.val;
|
||||
|
||||
let viewOnline = this._id('zotero-link-menu-view-online');
|
||||
let copy = this._id('zotero-link-menu-copy');
|
||||
|
||||
viewOnline.disabled = !link;
|
||||
copy.disabled = !link;
|
||||
copy.hidden = link === val;
|
||||
|
||||
let existingCopyMenuitem = menu.querySelector('menuitem[data-action="copy"]');
|
||||
if (existingCopyMenuitem) {
|
||||
existingCopyMenuitem.after(copy);
|
||||
}
|
||||
else {
|
||||
menu.append(copy);
|
||||
}
|
||||
});
|
||||
|
||||
this._id('zotero-link-menu-view-online').addEventListener(
|
||||
|
@ -535,12 +550,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < fieldNames.length; i++) {
|
||||
var fieldName = fieldNames[i];
|
||||
for (let fieldName of fieldNames) {
|
||||
if (this._ignoreFields.includes(fieldName)) {
|
||||
continue;
|
||||
}
|
||||
var val = '';
|
||||
let val = '';
|
||||
|
||||
if (fieldName) {
|
||||
var fieldID = Zotero.ItemFields.getID(fieldName);
|
||||
|
@ -604,13 +618,13 @@
|
|||
}
|
||||
let openLinkButton;
|
||||
let link = val;
|
||||
let addContextMenu = false;
|
||||
let addLinkContextMenu = false;
|
||||
// TEMP - NSF (homepage)
|
||||
if ((fieldName == 'url' || fieldName == 'homepage')
|
||||
// Only make plausible HTTP URLs clickable
|
||||
&& Zotero.Utilities.isHTTPURL(val, true)) {
|
||||
openLinkButton = this.createOpenLinkIcon(val);
|
||||
addContextMenu = true;
|
||||
addLinkContextMenu = true;
|
||||
}
|
||||
else if (fieldName == 'DOI' && val && typeof val == 'string') {
|
||||
// Pull out DOI, in case there's a prefix
|
||||
|
@ -625,7 +639,7 @@
|
|||
.replace(/"/g, '%22');
|
||||
openLinkButton = this.createOpenLinkIcon(doi);
|
||||
link = doi;
|
||||
addContextMenu = true;
|
||||
addLinkContextMenu = true;
|
||||
}
|
||||
}
|
||||
let rowData = document.createElement('div');
|
||||
|
@ -634,9 +648,10 @@
|
|||
if (openLinkButton) {
|
||||
rowData.appendChild(openLinkButton);
|
||||
}
|
||||
if (addContextMenu) {
|
||||
if (addLinkContextMenu) {
|
||||
rowData.oncontextmenu = (event) => {
|
||||
this._linkMenu.dataset.link = link;
|
||||
this._linkMenu.dataset.val = val;
|
||||
document.popupNode = rowLabel.parentElement;
|
||||
|
||||
let menupopup = this._id('zotero-link-menu');
|
||||
|
@ -2405,7 +2420,9 @@
|
|||
}
|
||||
|
||||
handlePopupOpening(event, popup) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let isRightClick = event.type == 'contextmenu';
|
||||
if (!isRightClick) {
|
||||
event.target.style.visibility = "visible";
|
||||
|
|
|
@ -2334,10 +2334,9 @@ Zotero.Utilities.Internal = {
|
|||
win.goUpdateGlobalEditMenuItems(true);
|
||||
|
||||
for (let menuitem of Array.from(menupopup.children)) {
|
||||
if (!menuitem.hasAttribute('data-edit-menu-item')) {
|
||||
break;
|
||||
if (menuitem.hasAttribute('data-edit-menu-item')) {
|
||||
menuitem.remove();
|
||||
}
|
||||
menuitem.remove();
|
||||
}
|
||||
|
||||
if (target && target.tagName === 'editable-text') {
|
||||
|
@ -2345,11 +2344,9 @@ Zotero.Utilities.Internal = {
|
|||
}
|
||||
let targetInput = target?.closest('input, textarea');
|
||||
let showEdit = targetInput
|
||||
&& !targetInput.readOnly
|
||||
&& targetInput.ownerDocument.activeElement
|
||||
&& targetInput.ownerDocument.activeElement === targetInput;
|
||||
let showCopyField = targetInput && !showEdit;
|
||||
let showPasteField = showCopyField && !targetInput.readOnly;
|
||||
let disablePasteField = targetInput && targetInput.readOnly;
|
||||
|
||||
let editMenuItems = [];
|
||||
if (showEdit) {
|
||||
|
@ -2360,29 +2357,34 @@ Zotero.Utilities.Internal = {
|
|||
editMenuItems.push(menuitem);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (showCopyField) {
|
||||
let copyMenuitem = win.document.createXULElement('menuitem');
|
||||
copyMenuitem.setAttribute('data-l10n-id', 'text-action-copy');
|
||||
copyMenuitem.setAttribute('data-edit-menu-item', 'true');
|
||||
copyMenuitem.disabled = !targetInput.value;
|
||||
copyMenuitem.addEventListener('command', () => {
|
||||
Zotero.Utilities.Internal.copyTextToClipboard(targetInput.value);
|
||||
});
|
||||
editMenuItems.push(copyMenuitem);
|
||||
}
|
||||
if (showPasteField) {
|
||||
let pasteMenuitem = win.document.createXULElement('menuitem');
|
||||
pasteMenuitem.setAttribute('data-l10n-id', 'text-action-paste');
|
||||
pasteMenuitem.setAttribute('data-edit-menu-item', 'true');
|
||||
pasteMenuitem.disabled = win.document.getElementById('cmd_paste')?.disabled;
|
||||
pasteMenuitem.addEventListener('command', () => {
|
||||
targetInput.focus();
|
||||
targetInput.value = Zotero.Utilities.Internal.getClipboard('text/unicode') || '';
|
||||
targetInput.dispatchEvent(new Event('input'));
|
||||
});
|
||||
editMenuItems.push(pasteMenuitem);
|
||||
}
|
||||
else if (targetInput) {
|
||||
let targetInputWeak = new WeakRef(targetInput);
|
||||
|
||||
let copyMenuitem = win.document.createXULElement('menuitem');
|
||||
copyMenuitem.setAttribute('data-l10n-id', 'text-action-copy');
|
||||
copyMenuitem.setAttribute('data-edit-menu-item', 'true');
|
||||
copyMenuitem.setAttribute('data-action', 'copy');
|
||||
copyMenuitem.disabled = !targetInput.value;
|
||||
copyMenuitem.addEventListener('command', () => {
|
||||
let targetInput = targetInputWeak.deref();
|
||||
if (!targetInput) return;
|
||||
Zotero.Utilities.Internal.copyTextToClipboard(targetInput.value);
|
||||
});
|
||||
editMenuItems.push(copyMenuitem);
|
||||
|
||||
let pasteMenuitem = win.document.createXULElement('menuitem');
|
||||
pasteMenuitem.setAttribute('data-l10n-id', 'text-action-paste');
|
||||
pasteMenuitem.setAttribute('data-edit-menu-item', 'true');
|
||||
pasteMenuitem.setAttribute('data-action', 'paste');
|
||||
pasteMenuitem.disabled = disablePasteField || win.document.getElementById('cmd_paste')?.disabled;
|
||||
pasteMenuitem.addEventListener('command', () => {
|
||||
let targetInput = targetInputWeak.deref();
|
||||
if (!targetInput) return;
|
||||
targetInput.focus();
|
||||
targetInput.value = Zotero.Utilities.Internal.getClipboard('text/unicode') || '';
|
||||
targetInput.dispatchEvent(new Event('input'));
|
||||
});
|
||||
editMenuItems.push(pasteMenuitem);
|
||||
}
|
||||
if (editMenuItems.length) {
|
||||
if (menupopup.childElementCount) {
|
||||
|
|
Loading…
Reference in a new issue