Quick-format: do not hide reference panel (#3816)
Citation dialog: keep reference panel open without selection - Reference panel remains opened while the focus is on an input - The first item from the reference panel is no longer selected by default to avoid unwanted items being added as a bubble - The first item from the reference panel is selected only when the dialog has no bubbles or when a search for a non-empty input has ran - Shift-Enter from input or reference panel will accept the dialog's state instead of creating a bubble - Ensure that the reference panel reloads when a bubble is deleted - Added button to accept the citation dialog Some other changes: - Z-icon and spinner/accept icon occupy the same amount of space - Ensure that window's width is 800px - Set the editor's width dynamically when DOM is loaded - Remove not used css classes and css adding margins to z-icon. - Do not accept/bubbleize while loading
This commit is contained in:
parent
3dc37183b4
commit
1eaff8110c
7 changed files with 86 additions and 78 deletions
|
@ -3,10 +3,6 @@ body {
|
|||
font-size: 15px;
|
||||
}
|
||||
|
||||
body[multiline="true"] {
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
window.citation-dialog {
|
||||
background: transparent;
|
||||
-moz-appearance: none;
|
||||
|
@ -18,13 +14,6 @@ window.citation-dialog {
|
|||
height: 37px;
|
||||
}
|
||||
|
||||
.citation-dialog.search {
|
||||
padding: 2px 2px 0 2px;
|
||||
margin: 2.5px 3.5px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
-moz-appearance: none;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
|
||||
.citation-dialog.entry {
|
||||
|
@ -36,10 +25,6 @@ window.citation-dialog {
|
|||
background: -moz-linear-gradient(-90deg, rgb(249, 231, 179) 0, rgb(228, 193, 94) 50%, rgb(221, 184, 81) 50%);
|
||||
}
|
||||
|
||||
#zotero-icon {
|
||||
margin: -1px 0 0 4px;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
#citation-properties menulist {
|
||||
-moz-appearance: none; color: #fff;
|
||||
|
|
|
@ -2,23 +2,7 @@ body {
|
|||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.citation-dialog.search:not([multiline="true"]) {
|
||||
height: 29px !important;
|
||||
}
|
||||
|
||||
.citation-dialog.search {
|
||||
padding: 0 2px 0 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
window.citation-dialog {
|
||||
-moz-appearance: none;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#zotero-icon {
|
||||
padding: 4px 4px 6px 4px !important;
|
||||
margin: 2px 0;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
|
|
@ -4,16 +4,6 @@ window.citation-dialog {
|
|||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
.citation-dialog.search {
|
||||
padding: 2px 2px 2px 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
border-radius: 10px;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
.citation-dialog.search:not([multiline="true"]) {
|
||||
height: 28px !important;
|
||||
}
|
||||
|
||||
.citation-dialog.entry {
|
||||
background: -moz-linear-gradient(-90deg, rgb(243,123,119) 0, rgb(180,47,38) 50%, rgb(156,36,27) 50%);
|
||||
|
@ -29,10 +19,6 @@ window.citation-dialog {
|
|||
border-radius: 15px;
|
||||
}
|
||||
|
||||
#zotero-icon {
|
||||
margin: -1px 0 0 4px;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
body {
|
||||
line-height: 1.65em;
|
||||
|
|
|
@ -42,7 +42,6 @@ var Zotero_QuickFormat = new function () {
|
|||
isPaste = false, _itemPopoverClosed, skipInputRefocus;
|
||||
var locatorNode = null;
|
||||
var _searchPromise;
|
||||
var inputIsPristine = true;
|
||||
|
||||
var _lastFocusedInput = null;
|
||||
var _bubbleMouseDown = false;
|
||||
|
@ -85,6 +84,7 @@ var Zotero_QuickFormat = new function () {
|
|||
|
||||
dialog = document.querySelector(".citation-dialog.entry");
|
||||
editor = document.querySelector(".citation-dialog.editor");
|
||||
_resizeEditor();
|
||||
dialog.addEventListener("click", _onQuickSearchClick, false);
|
||||
dialog.addEventListener("keypress", _onQuickSearchKeyPress, false);
|
||||
editor.addEventListener("dragover", _onEditorDragOver);
|
||||
|
@ -94,7 +94,7 @@ var Zotero_QuickFormat = new function () {
|
|||
// Navigation within the reference panel
|
||||
referenceBox.addEventListener("keypress", (event) => {
|
||||
// Enter or ; selects the reference
|
||||
if (event.key == "Enter" || event.charCode == 59) {
|
||||
if ((event.key == "Enter" && !event.shiftKey) || event.charCode == 59) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.target.closest("richlistitem").click();
|
||||
|
@ -118,7 +118,14 @@ var Zotero_QuickFormat = new function () {
|
|||
_lastFocusedInput.focus();
|
||||
}
|
||||
else if (["ArrowDown", "ArrowUp"].includes(event.key)) {
|
||||
handleItemSelection(event);
|
||||
// ArrowUp from first item focuses the input
|
||||
if (referenceBox.selectedIndex == 1 && event.key == "ArrowUp") {
|
||||
_lastFocusedInput.focus();
|
||||
referenceBox.selectedIndex = -1;
|
||||
}
|
||||
else {
|
||||
handleItemSelection(event);
|
||||
}
|
||||
}
|
||||
// Right/Left arrow will hide ref panel and move focus to the previour/next element
|
||||
else if ("ArrowLeft" == event.key) {
|
||||
|
@ -858,10 +865,14 @@ var Zotero_QuickFormat = new function () {
|
|||
});
|
||||
}
|
||||
|
||||
referenceBox.selectedIndex = selectedIndex;
|
||||
let currentInput = _getCurrentInput();
|
||||
// Do not select the item in reference panel if the editor
|
||||
// is non-empty and nothing has been typed yet
|
||||
if (selectedIndex > 1 || isEditorCleared() || !isInputEmpty(currentInput)) {
|
||||
referenceBox.selectedIndex = selectedIndex;
|
||||
}
|
||||
referenceBox.ensureIndexIsVisible(selectedIndex);
|
||||
// Record the last input used for a search
|
||||
let currentInput = _getCurrentInput();
|
||||
if (currentInput) {
|
||||
_lastFocusedInput = currentInput;
|
||||
}
|
||||
|
@ -1102,7 +1113,7 @@ var Zotero_QuickFormat = new function () {
|
|||
this._bubbleizeSelected = Zotero.Promise.coroutine(function* () {
|
||||
const panelShowing = referencePanel.state === "open" || referencePanel.state === "showing";
|
||||
let inputExists = _lastFocusedInput || _getCurrentInput()
|
||||
if(!panelShowing || !referenceBox.hasChildNodes() || !referenceBox.selectedItem) return false;
|
||||
if(!panelShowing || !referenceBox.hasChildNodes() || !referenceBox.selectedItem || _searchPromise?.isPending()) return false;
|
||||
|
||||
if(!referenceBox.hasChildNodes() || !referenceBox.selectedItem || !inputExists) return false;
|
||||
var citationItem = {"id":referenceBox.selectedItem.getAttribute("zotero-item")};
|
||||
|
@ -1154,9 +1165,6 @@ var Zotero_QuickFormat = new function () {
|
|||
let newBubble = _insertBubble(citationItem, input);
|
||||
isPaste = false;
|
||||
_clearEntryList();
|
||||
// After the first bubble was made, the next input should not display the panel
|
||||
// even if there were no searches yet
|
||||
inputIsPristine = false;
|
||||
clearLastFocused(input);
|
||||
input.remove();
|
||||
|
||||
|
@ -1174,6 +1182,19 @@ var Zotero_QuickFormat = new function () {
|
|||
e.preventDefault();
|
||||
}
|
||||
|
||||
// Set the editor's width so that it fills up all remaining space in the window.
|
||||
// It should be window.width - padding - icon wrappers width. The is needed to be explicitly set
|
||||
// so that the editor's height expands/shrinks vertically without going outside of the
|
||||
// window boundaries.
|
||||
function _resizeEditor() {
|
||||
let editorParentWidth = editor.parentNode.getBoundingClientRect().width;
|
||||
let iconWrapperWidth = document.querySelector(".citation-dialog.icons").getBoundingClientRect().width;
|
||||
let editorDesiredWidth = editorParentWidth - iconWrapperWidth * 2;
|
||||
// Sanity check: editor width should never be that small
|
||||
if (editorDesiredWidth > 700) {
|
||||
editor.style.width = `${editorDesiredWidth}px`;
|
||||
}
|
||||
}
|
||||
function _resizeWindow() {
|
||||
let box = document.querySelector(".citation-dialog.entry");
|
||||
let contentHeight = box.getBoundingClientRect().height;
|
||||
|
@ -1217,13 +1238,8 @@ var Zotero_QuickFormat = new function () {
|
|||
break;
|
||||
}
|
||||
}
|
||||
let inputNode = _getCurrentInput() || _lastFocusedInput;
|
||||
// References should be shown if:
|
||||
// - there are matching items and the input is non-empty
|
||||
// - the dialog just opened
|
||||
// - everything but the last, non-removable, input has been cleared.
|
||||
// Otherwise, the panel is hidden.
|
||||
let showReferencePanel = visibleNodes.length > 0 && (!isInputEmpty(inputNode) || inputIsPristine || isEditorCleared());
|
||||
// References should be shown whenever there are matching items
|
||||
let showReferencePanel = visibleNodes.length > 0;
|
||||
if (!showReferencePanel) {
|
||||
referencePanel.hidePopup();
|
||||
return;
|
||||
|
@ -1428,8 +1444,8 @@ var Zotero_QuickFormat = new function () {
|
|||
/**
|
||||
* Accepts current selection and adds citation
|
||||
*/
|
||||
this._accept = function() {
|
||||
if(accepted) return;
|
||||
this.accept = function() {
|
||||
if (accepted || _searchPromise?.isPending()) return;
|
||||
accepted = true;
|
||||
try {
|
||||
_updateCitationObject();
|
||||
|
@ -1464,7 +1480,7 @@ var Zotero_QuickFormat = new function () {
|
|||
}
|
||||
else if (event.key == "Enter") {
|
||||
event.preventDefault();
|
||||
Zotero_QuickFormat._accept();
|
||||
Zotero_QuickFormat.accept();
|
||||
}
|
||||
// In rare circumstances, the focus can get lost (e.g. if the focus is on an item
|
||||
// in reference panel when it is refreshed and all nodes are deleted).
|
||||
|
@ -1567,7 +1583,8 @@ var Zotero_QuickFormat = new function () {
|
|||
*/
|
||||
function _resetSearchTimer() {
|
||||
// Show spinner
|
||||
var spinner = document.querySelector('.citation-dialog.spinner image');
|
||||
var spinner = document.querySelector('.citation-dialog.icons.end image');
|
||||
spinner.nextElementSibling.style.display = "none";
|
||||
spinner.setAttribute("status", "animate");
|
||||
// Cancel current search if active
|
||||
if (_searchPromise && _searchPromise.isPending()) {
|
||||
|
@ -1577,9 +1594,9 @@ var Zotero_QuickFormat = new function () {
|
|||
_searchPromise = Zotero.Promise.delay(SEARCH_TIMEOUT)
|
||||
.then(() => _quickFormat())
|
||||
.then(() => {
|
||||
inputIsPristine = false;
|
||||
_searchPromise = null;
|
||||
spinner.removeAttribute("status");
|
||||
spinner.nextElementSibling.style.removeProperty("display");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1697,7 +1714,7 @@ var Zotero_QuickFormat = new function () {
|
|||
|
||||
var onInputPress = function (event) {
|
||||
if (accepted) return;
|
||||
if ((event.charCode === 59 /* ; */ || event.key === "Enter") && referencePanel.state === "open") {
|
||||
if ((event.charCode === 59 /* ; */ || (event.key === "Enter" && !event.shiftKey)) && referenceBox.selectedIndex >= 1) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
Zotero_QuickFormat._bubbleizeSelected();
|
||||
|
@ -1723,19 +1740,30 @@ var Zotero_QuickFormat = new function () {
|
|||
this.previousElementSibling.remove();
|
||||
_combineNeighboringInputs();
|
||||
}
|
||||
// If this removed the last bubble, make sure the reference panel is open
|
||||
if (isEditorCleared()) {
|
||||
_resetSearchTimer();
|
||||
}
|
||||
// Rerun search to update opened documents section if needed
|
||||
_resetSearchTimer();
|
||||
}
|
||||
else if (["ArrowDown", "ArrowUp"].includes(event.key) && referencePanel.state === "open") {
|
||||
// Arrow up/down from wherever will navigate the references panel if that's opened
|
||||
handleItemSelection(event);
|
||||
// ArrowUp when item is selected does nothing
|
||||
if (referenceBox.selectedIndex < 1 && event.key == "ArrowUp") {
|
||||
return;
|
||||
}
|
||||
// Arrow up/down will navigate the references panel if that's opened
|
||||
if (referenceBox.selectedIndex < 1) {
|
||||
referenceBox.selectedIndex = 1;
|
||||
referenceBox.selectedItem.focus();
|
||||
}
|
||||
else {
|
||||
handleItemSelection(event);
|
||||
}
|
||||
}
|
||||
else if (event.key == "Tab" && !event.shiftKey && referencePanel.state === "open") {
|
||||
// Tab from the input will focus the selected item in the references list
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (referenceBox.selectedIndex < 1) {
|
||||
referenceBox.selectedIndex = 1;
|
||||
}
|
||||
referenceBox.selectedItem.focus();
|
||||
}
|
||||
};
|
||||
|
@ -1803,6 +1831,9 @@ var Zotero_QuickFormat = new function () {
|
|||
moveFocusForward(this);
|
||||
}
|
||||
this.remove();
|
||||
// Removed item bubble may belong to opened documents section. Reference panel
|
||||
// needs to be reset so that it appears among other items.
|
||||
_clearEntryList();
|
||||
_combineNeighboringInputs();
|
||||
// If all bubbles are removed, add and focus an input
|
||||
if (getAllBubbles().length == 0) {
|
||||
|
@ -1880,6 +1911,12 @@ var Zotero_QuickFormat = new function () {
|
|||
|
||||
event.preventDefault();
|
||||
}
|
||||
// Shift-Enter will accept the existing dialog's state
|
||||
else if (keyCode == "Enter" && event.shiftKey) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.accept();
|
||||
}
|
||||
else {
|
||||
isPaste = false;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<deck class="citation-dialog deck" selectedIndex="0" flex="1">
|
||||
<hbox class="citation-dialog main" flex="1" align="start">
|
||||
<hbox flex="1">
|
||||
<vbox flex="1" align="center" style="display: flex;align-items: center;max-width: 38px;justify-content: center;">
|
||||
<vbox class="citation-dialog icons start">
|
||||
<toolbarbutton id="zotero-icon" type="menu" tabindex="0" disabled="true">
|
||||
<menupopup>
|
||||
<menuitem id="keep-sorted" label="&zotero.citation.keepSorted.label;"
|
||||
|
@ -70,8 +70,9 @@
|
|||
</toolbarbutton>
|
||||
</vbox>
|
||||
<html:div flex="1" spellcheck="false" class="citation-dialog editor" role="application"></html:div>
|
||||
<vbox class="citation-dialog spinner">
|
||||
<image class="zotero-spinner-16"/>
|
||||
<vbox class="citation-dialog icons end">
|
||||
<image class="icon zotero-spinner-16"/>
|
||||
<toolbarbutton class="icon accept-button" onclick="Zotero_QuickFormat.accept()" data-l10n-id="quickformat-accept"></toolbarbutton>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</hbox>
|
||||
|
|
|
@ -437,3 +437,5 @@ toggle-preview =
|
|||
quickformat-aria-bubble = Press Down Arrow to open citation properties.
|
||||
quickformat-aria-input = Type your search term. Use Down Arrow and Up Arrow to navigate the search results.
|
||||
quickformat-aria-item = Press { return-or-enter } to select this item. Press Tab to return to the search field.
|
||||
quickformat-accept =
|
||||
.tooltiptext = Save edits to this citation
|
|
@ -185,7 +185,7 @@
|
|||
font: -moz-field;
|
||||
outline: none;
|
||||
line-height: 2em;
|
||||
width: 710px;
|
||||
width: 700px; /* initial editor width - adjusted after dom load */
|
||||
height: 28px;
|
||||
font-size: 13px;
|
||||
background: white;
|
||||
|
@ -201,9 +201,22 @@
|
|||
background: var(--color-accent);
|
||||
}
|
||||
|
||||
.citation-dialog.spinner {
|
||||
.citation-dialog.icons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
.citation-dialog.entry {
|
||||
max-width: 800px;
|
||||
min-width: 800px;
|
||||
}
|
||||
|
||||
.citation-dialog .accept-button {
|
||||
list-style-image: url("chrome://zotero/skin/20/universal/arrow-right.svg");
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.citation-dialog.item {
|
||||
|
|
Loading…
Reference in a new issue