added library tab to tabs menu, minor refactoring
- library tab appears in the tabs menu without the close button and no drag functionality - minor refactoring to simplify how the tabs icons are fetched for items with item.getItemTypeIconName() - added focus-ring to tabs and filter field via @focus-ring mixin so that the focus outline looks the same for the input field and buttons - removed default margin from the <description> component of the tab titles that moved titles up by a bit
This commit is contained in:
parent
ef062b9a8d
commit
d8a00610da
2 changed files with 56 additions and 32 deletions
|
@ -823,12 +823,9 @@ var Zotero_Tabs = new function () {
|
||||||
this.refreshTabsMenuList = () => {
|
this.refreshTabsMenuList = () => {
|
||||||
// Empty existing nodes
|
// Empty existing nodes
|
||||||
this.tabsMenuList.replaceChildren();
|
this.tabsMenuList.replaceChildren();
|
||||||
|
this._tabsMenuFocusedIndex = 0;
|
||||||
let index = 1;
|
let index = 1;
|
||||||
for (let tab of this._tabs) {
|
for (let tab of this._tabs) {
|
||||||
// Skip tabs when we have no itemID, like library
|
|
||||||
if (!tab.data?.itemID) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Skip tabs whose title wasn't added yet
|
// Skip tabs whose title wasn't added yet
|
||||||
if (tab.title == "") {
|
if (tab.title == "") {
|
||||||
continue;
|
continue;
|
||||||
|
@ -841,6 +838,14 @@ var Zotero_Tabs = new function () {
|
||||||
let row = document.createXULElement('toolbaritem');
|
let row = document.createXULElement('toolbaritem');
|
||||||
let rowIndex = this._tabs.findIndex(x => x.id === tab.id);
|
let rowIndex = this._tabs.findIndex(x => x.id === tab.id);
|
||||||
row.setAttribute("index", rowIndex);
|
row.setAttribute("index", rowIndex);
|
||||||
|
|
||||||
|
// Title of the tab
|
||||||
|
let tabName = document.createXULElement('toolbarbutton');
|
||||||
|
tabName.setAttribute('flex', '1');
|
||||||
|
tabName.setAttribute('class', 'zotero-tabs-menu-entry title');
|
||||||
|
tabName.setAttribute('tabindex', `${index++}`);
|
||||||
|
tabName.setAttribute('aria-label', tab.title);
|
||||||
|
|
||||||
// Cross button to close a tab
|
// Cross button to close a tab
|
||||||
let closeButton = document.createXULElement('toolbarbutton');
|
let closeButton = document.createXULElement('toolbarbutton');
|
||||||
closeButton.setAttribute('class', 'zotero-tabs-menu-entry zotero-clicky-cross close');
|
closeButton.setAttribute('class', 'zotero-tabs-menu-entry zotero-clicky-cross close');
|
||||||
|
@ -852,35 +857,33 @@ var Zotero_Tabs = new function () {
|
||||||
}
|
}
|
||||||
this.close(tab.id);
|
this.close(tab.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Title of the tab
|
// Library tab has no close button
|
||||||
let tabName = document.createXULElement('toolbarbutton');
|
if (tab.id == "zotero-pane") {
|
||||||
tabName.setAttribute('flex', '1');
|
closeButton.hidden = true;
|
||||||
tabName.setAttribute('class', 'zotero-tabs-menu-entry title');
|
closeButton.disabled = true;
|
||||||
tabName.setAttribute('tabindex', `${index++}`);
|
}
|
||||||
tabName.setAttribute('aria-label', tab.title);
|
|
||||||
|
|
||||||
closeButton.setAttribute('tabindex', `${index++}`);
|
closeButton.setAttribute('tabindex', `${index++}`);
|
||||||
|
|
||||||
// Item type icon
|
// Item type icon
|
||||||
let span = document.createElement("span");
|
let span = document.createElement("span");
|
||||||
span.className = "icon icon-css cell-icon";
|
span.className = "icon icon-css tab-icon";
|
||||||
span.classList.add("icon-item-type");
|
if (tab.id == 'zotero-pane') {
|
||||||
let item = Zotero.Items.get(tab.data.itemID);
|
// Determine which icon from the collection view rows to use (same as in _update())
|
||||||
let dataTypeLabel = "";
|
let index = ZoteroPane.collectionsView?.selection?.focused;
|
||||||
if (item.isPDFAttachment()) {
|
if (typeof index !== 'undefined' && ZoteroPane.collectionsView.getRow(index)) {
|
||||||
dataTypeLabel = "attachmentPDF";
|
let iconName = ZoteroPane.collectionsView.getIconName(index);
|
||||||
|
span.classList.add(`icon-${iconName}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (item.isEPUBAttachment()) {
|
else {
|
||||||
dataTypeLabel = "attachmentEPUB";
|
span.classList.add("icon-item-type");
|
||||||
|
let item = Zotero.Items.get(tab.data.itemID);
|
||||||
|
let dataTypeLabel = item.getItemTypeIconName();
|
||||||
|
span.setAttribute("data-item-type", dataTypeLabel);
|
||||||
}
|
}
|
||||||
else if (item.isSnapshotAttachment()) {
|
|
||||||
dataTypeLabel = "attachmentSnapshot";
|
|
||||||
}
|
|
||||||
else if (item.isFileAttachment()) {
|
|
||||||
dataTypeLabel = "attachmentFile";
|
|
||||||
}
|
|
||||||
span.setAttribute("data-item-type", dataTypeLabel);
|
|
||||||
tabName.appendChild(span);
|
tabName.appendChild(span);
|
||||||
// Actual label with bolded substrings matching the filter
|
// Actual label with bolded substrings matching the filter
|
||||||
let tabLabel = createTabsMenuLabel(tab.title, this._tabsMenuFilter);
|
let tabLabel = createTabsMenuLabel(tab.title, this._tabsMenuFilter);
|
||||||
|
@ -920,8 +923,8 @@ var Zotero_Tabs = new function () {
|
||||||
row.appendChild(closeButton);
|
row.appendChild(closeButton);
|
||||||
|
|
||||||
row.addEventListener("dragstart", (e) => {
|
row.addEventListener("dragstart", (e) => {
|
||||||
// No drag-drop on the cross button
|
// No drag-drop on the cross button or the library tab
|
||||||
if (e.target.classList.contains("close")) {
|
if (tab.id == 'zotero-pane' || e.target.classList.contains("close")) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
return;
|
return;
|
||||||
|
@ -959,7 +962,9 @@ var Zotero_Tabs = new function () {
|
||||||
|
|
||||||
row.addEventListener('drop', (e) => {
|
row.addEventListener('drop', (e) => {
|
||||||
let tabId = e.dataTransfer.getData("zotero/tab");
|
let tabId = e.dataTransfer.getData("zotero/tab");
|
||||||
this.move(tabId, parseInt(row.getAttribute("index")));
|
let rowIndex = parseInt(row.getAttribute("index"));
|
||||||
|
if (rowIndex == 0) return;
|
||||||
|
this.move(tabId, rowIndex);
|
||||||
});
|
});
|
||||||
|
|
||||||
row.addEventListener('dragend', (_) => {
|
row.addEventListener('dragend', (_) => {
|
||||||
|
@ -1050,11 +1055,15 @@ var Zotero_Tabs = new function () {
|
||||||
if (event.key == "Tab") {
|
if (event.key == "Tab") {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let isShift = event.shiftKey;
|
let isShift = event.shiftKey;
|
||||||
|
let moveTabIndex = () => tabindex++;
|
||||||
if (isShift) {
|
if (isShift) {
|
||||||
tabindex -= 1;
|
moveTabIndex = () => tabindex--;
|
||||||
}
|
}
|
||||||
else {
|
moveTabIndex();
|
||||||
tabindex += 1;
|
let candidate = this.tabsMenuList.parentElement.querySelector(`[tabindex="${tabindex}"]`);
|
||||||
|
// If the candidate is disabled (e.g. close button of library tab), skip it
|
||||||
|
if (candidate && candidate.disabled) {
|
||||||
|
moveTabIndex();
|
||||||
}
|
}
|
||||||
focusTabsMenuEntry(tabindex);
|
focusTabsMenuEntry(tabindex);
|
||||||
}
|
}
|
||||||
|
@ -1078,6 +1087,12 @@ var Zotero_Tabs = new function () {
|
||||||
else {
|
else {
|
||||||
tabindex -= step;
|
tabindex -= step;
|
||||||
}
|
}
|
||||||
|
// If the candidate is a disabled element (e.g. close button of the library tab),
|
||||||
|
// move focus to the element before it
|
||||||
|
let candidate = this.tabsMenuList.parentElement.querySelector(`[tabindex="${tabindex}"]`);
|
||||||
|
if (candidate && candidate.disabled) {
|
||||||
|
tabindex--;
|
||||||
|
}
|
||||||
if (tabindex <= 0) {
|
if (tabindex <= 0) {
|
||||||
// ArrowUp from the first tab or the first close button focuses the filter field.
|
// ArrowUp from the first tab or the first close button focuses the filter field.
|
||||||
// ArrowUp from the filter field focuses the last tab
|
// ArrowUp from the filter field focuses the last tab
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
padding-inline-start: 5px !important;
|
padding-inline-start: 5px !important;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
@include focus-ring(3px, 5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-tabs-menu-list {
|
#zotero-tabs-menu-list {
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
.zotero-tabs-menu-entry {
|
.zotero-tabs-menu-entry {
|
||||||
|
@include focus-ring(3px, 5px);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -32,6 +34,13 @@
|
||||||
}
|
}
|
||||||
description {
|
description {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
// override default description margins
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-block-start: 0;
|
||||||
|
}
|
||||||
|
.tab-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue