Implement pane header, non-tabbed layout, collapsible sections, and new abstract box

This commit is contained in:
Abe Jellinek 2023-10-04 09:27:02 -04:00 committed by Dan Stillman
parent d2694bfba7
commit 810402c9c7
58 changed files with 1358 additions and 441 deletions

View file

@ -1,17 +1,4 @@
/* Use standard tab appearance for item pane tabs */
.zotero-view-tabbox > tabs > tab {
-moz-appearance: tab;
}
/* Active tab label color in item pane and elsewhere */
tabs.zotero-editpane-tabs > tab[visuallyselected="true"][selected="true"] hbox > .tab-text,
#zotero-prefs tab[visuallyselected="true"]:not(:-moz-window-inactive),
tabs > tab[visuallyselected="true"] hbox > .tab-text {
color: black !important;
text-shadow: none;
}
/* Quick Format dialog, which is based on window corners, which are different on Big Sur */
#quick-format-iframe {
margin-top: 2px;
}
}

View file

@ -120,11 +120,6 @@
margin: 0;
}
.zotero-view-tabbox {
background-color: #fff;
padding: 0;
}
.zotero-item-pane-content .groupbox-body {
-moz-appearance: none;
background-color: #ffffff;
@ -134,56 +129,6 @@
color: #7f7f7f;
}
.zotero-view-tabbox > tabpanels {
margin: 12px 0 0 0;
padding: 0;
-moz-appearance: none;
}
.zotero-editpane-tabs {
-moz-appearance: none;
background: -moz-linear-gradient(top, #ededed, #cccccc);
border-style: solid;
border-width: 0 0 1px 0;
border-color: #bdbdbd;
padding: 2px 0 2px 0;
}
.zotero-editpane-tabs > tab > hbox {
padding: 0;
}
.zotero-editpane-tabs > tab > hbox > .tab-icon {
display: none;
}
.zotero-editpane-tabs > tab {
-moz-box-orient: vertical;
-moz-box-align: center;
-moz-appearance: toolbarbutton;
text-align: center;
margin: 0;
padding: 3px 1px 3px 1px;
}
.zotero-editpane-tabs > tab > hbox .tab-text {
font-size: 11px;
font-weight: bold;
margin: 2px 7px 2px 9px !important;
text-shadow: 0 1px rgba(255, 255, 255, .4);
}
/* This seems to be necessary to center the tabs. Not sure why. */
.zotero-editpane-tabs > tab:last-of-type > hbox .tab-text {
margin-left: 9px !important;
margin-right: 9px !important;
}
.zotero-editpane-tabs > tab[selected=true] > hbox .tab-text {
color: #FFF !important;
text-shadow: rgba(0, 0, 0, 0.4) 0 1px;
}
#zotero-collections-splitter:not([state=collapsed]),
#zotero-items-splitter:not([state=collapsed])[orient=horizontal],
#zotero-context-splitter:not([state=collapsed])[orient=horizontal]

View file

@ -6,17 +6,3 @@
.zotero-item-pane-content {
margin-right: 6px;
}
/* Make the item pane appear white (same colour as treeview), making the UI more consistent */
.zotero-item-pane-content tab, .zotero-item-pane-content tabpanels {
background-color: -moz-Field; /* Same as background colour for treeview */
}
/* Possibly irrelevant if mozilla fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1306425 */
.zotero-view-tabbox tabs tab[visuallyselected=true] {
margin-top: 0px !important; /* Importanter than ./itemPane.css:20 */
margin-bottom: -2px !important; /* Importanter than skin/itemPane.css:12 */
}
.zotero-view-tabbox tabs tab {
margin-top: 2px !important; /* Importanter than skin/itemPane.css:11 */
}

View file

@ -38,11 +38,6 @@
padding-top: 4px;
}
.zotero-view-tabbox tab {
padding-left: .7em;
padding-right: .7em;
}
.zotero-toolbar {
-moz-appearance: toolbox !important;
padding-left: 2px;
@ -119,10 +114,6 @@ tree {
padding-left: 0.05em;
}
.zotero-editpane-tabs spacer {
border: 0;
}
.zotero-view-item {
padding: 0 !important;
-moz-appearance: none;
@ -131,10 +122,6 @@ tree {
border-color: var(--theme-border-color);
}
.zotero-editpane-tabs {
margin-top: 2px;
}
#zotero-item-pane-groupbox {
-moz-appearance: none !important;
border-width: 0;

View file

@ -310,7 +310,7 @@ var ZoteroContextPane = new function () {
if (splitter.getAttribute('state') != 'collapsed') {
if (_panesDeck.selectedIndex == 0) {
var node = _itemPaneDeck.selectedPanel;
node.querySelector('tab[selected]').focus();
node.focus();
return true;
}
else {
@ -903,7 +903,7 @@ var ZoteroContextPane = new function () {
_itemContexts.push(context);
if (!parentID) {
var vbox = document.createXULElement('vbox');
let vbox = document.createXULElement('vbox');
vbox.setAttribute('flex', '1');
vbox.setAttribute('align', 'center');
vbox.setAttribute('pack', 'center');
@ -915,73 +915,84 @@ var ZoteroContextPane = new function () {
}
var parentItem = Zotero.Items.get(item.parentID);
// Dynamically create item pane tabs and panels as in itemPane.xul.
// Keep the code below in sync with itemPane.xul
// Dynamically create item pane tabs and panels as in zoteroPane.xhtml.
// Keep the code below in sync with zoteroPane.xhtml
// tabbox
var tabbox = document.createXULElement('tabbox');
tabbox.setAttribute('flex', '1');
tabbox.className = 'zotero-view-tabbox';
// hbox
var hbox = document.createXULElement('hbox');
hbox.setAttribute('flex', '1');
hbox.className = 'zotero-view-item-container';
container.append(hbox);
// main
var main = document.createElement('div');
main.className = 'zotero-view-item-main';
hbox.append(main);
// pane-header
var paneHeader = document.createXULElement('pane-header');
main.append(paneHeader);
container.append(tabbox);
// div
var div = document.createElement('div');
div.className = 'zotero-view-item';
main.append(div);
let createSection = (pane, showAdd = false) => {
let section = document.createXULElement('collapsible-section');
section.dataset.pane = pane;
section.setAttribute('data-l10n-id', 'section-' + pane);
section.toggleAttribute('show-add', showAdd);
return section;
};
// tabs
var tabs = document.createXULElement('tabs');
tabs.className = 'zotero-editpane-tabs';
// tabpanels
var tabpanels = document.createXULElement('tabpanels');
tabpanels.setAttribute('flex', '1');
tabpanels.className = 'zotero-view-item';
tabpanels.addEventListener('select', () => {
_updateAddToNote();
});
// Info tab
var tabInfo = document.createXULElement('tab');
tabInfo.setAttribute('label', Zotero.getString('zotero.tabs.info.label'));
// Tags tab
var tabTags = document.createXULElement('tab');
tabTags.setAttribute('label', Zotero.getString('zotero.tabs.tags.label'));
// Related tab
var tabRelated = document.createXULElement('tab');
tabRelated.setAttribute('label', Zotero.getString('zotero.tabs.related.label'));
tabs.append(tabInfo, tabTags, tabRelated);
tabbox.append(tabs, tabpanels);
// Info panel
var panelInfo = document.createXULElement('tabpanel');
panelInfo.setAttribute('flex', '1');
panelInfo.className = 'zotero-editpane-item-box';
// Info
var itemBoxContainer = createSection('info');
var itemBox = new (customElements.get('item-box'));
itemBox.setAttribute('flex', '1');
panelInfo.append(itemBox);
// Tags panel
var panelTags = document.createXULElement('tabpanel');
var tagsBox = new (customElements.get('tags-box'));
tagsBox.setAttribute('flex', '1');
tagsBox.className = 'zotero-editpane-tags';
panelTags.append(tagsBox);
itemBoxContainer.append(itemBox);
// Abstract
var abstractBoxContainer = createSection('abstract');
var abstractBox = new (customElements.get('abstract-box'));
abstractBox.className = 'zotero-editpane-abstract';
abstractBoxContainer.append(abstractBox);
// TODO: Attachments
// Related panel
var panelRelated = document.createXULElement('tabpanel');
// Tags
var tagsBoxContainer = createSection('tags', true);
var tagsBox = new (customElements.get('tags-box'));
tagsBox.className = 'zotero-editpane-tags';
tagsBoxContainer.append(tagsBox);
// Related
var relatedBoxContainer = createSection('related', true);
var relatedBox = new (customElements.get('related-box'));
relatedBox.setAttribute('flex', '1');
relatedBox.className = 'zotero-editpane-related';
panelRelated.addEventListener('click', (event) => {
relatedBox.addEventListener('click', (event) => {
if (event.originalTarget.closest('.zotero-clicky')) {
Zotero_Tabs.select('zotero-pane');
}
});
panelRelated.append(relatedBox);
relatedBoxContainer.append(relatedBox);
tabpanels.append(panelInfo, panelTags, panelRelated);
tabbox.selectedIndex = 0;
div.append(itemBoxContainer, abstractBoxContainer, tagsBoxContainer, relatedBoxContainer);
// item-pane-sidenav
var sidenav = document.createXULElement('item-pane-sidenav');
sidenav.className = 'zotero-view-item-sidenav';
hbox.append(sidenav);
sidenav.container = div;
paneHeader.mode = readOnly ? 'view' : 'edit';
paneHeader.item = parentItem;
itemBox.mode = readOnly ? 'view' : 'edit';
itemBox.item = parentItem;
abstractBox.mode = readOnly ? 'view' : 'edit';
abstractBox.item = parentItem;
tagsBox.mode = readOnly ? 'view' : 'edit';
tagsBox.item = parentItem;

View file

@ -43,6 +43,11 @@ Services.scriptloader.loadSubScript("chrome://zotero/content/elements/splitMenuB
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/tagsBox.js', this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/textLink.js', this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/zoteroSearch.js', this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/paneHeader.js', this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/editableText.js', this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/itemPaneSidenav.js', this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/abstractBox.js', this);
Services.scriptloader.loadSubScript('chrome://zotero/content/elements/collapsibleSection.js', this);
// Fix missing property bug that breaks arrow key navigation between <tab>s
{
@ -59,4 +64,27 @@ Services.scriptloader.loadSubScript('chrome://zotero/content/elements/zoteroSear
}
});
}
let isMac = AppConstants.platform == 'macosx';
if (isMac) {
// Monkey-patch the toolbarbutton CE so it shows a native menu popup
let MozToolbarbuttonPrototype = customElements.get('toolbarbutton').prototype;
if (MozToolbarbuttonPrototype) {
let originalRender = MozToolbarbuttonPrototype.render;
MozToolbarbuttonPrototype.render = function () {
originalRender.apply(this);
if (!this._zoteroMouseDownListenerAdded) {
this.addEventListener('mousedown', (event) => {
if (!event.defaultPrevented
&& !this.disabled
&& this.getAttribute('nonnativepopup') != 'true'
&& Zotero.Utilities.Internal.showNativeElementPopup(this)) {
event.preventDefault();
}
});
this._zoteroMouseDownListenerAdded = true;
}
};
}
}
}

View file

@ -0,0 +1,104 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2020 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";
{
class AbstractBox extends XULElementBase {
content = MozXULElement.parseXULToFragment(`
<editable-text multiline="true" data-l10n-id="abstract-field" />
`);
_item = null;
_mode = null;
get item() {
return this._item;
}
set item(item) {
this.blurOpenField();
this._item = item;
this.render();
}
get mode() {
return this._mode;
}
set mode(mode) {
this._mode = mode;
this.render();
}
init() {
this._notifierID = Zotero.Notifier.registerObserver(this, ['item'], 'abstractBox');
this.abstractField = this.querySelector('editable-text');
this.abstractField.addEventListener('change', () => this.save());
this.abstractField.ariaLabel = Zotero.getString('itemFields.abstractNote');
this.render();
}
destroy() {
Zotero.Notifier.unregisterObserver(this._notifierID);
}
notify(action, type, ids) {
if (action == 'modify' && this.item && ids.includes(this.item.id)) {
this.render();
}
}
async save() {
if (this.item) {
this.item.setField('abstractNote', this.abstractField.value);
await this.item.saveTx();
}
this.render();
}
async blurOpenField() {
this.abstractField.blur();
await this.save();
}
render() {
if (!this.item) {
return;
}
let title = this.item.getField('abstractNote');
if (this.abstractField.initialValue !== title) {
this.abstractField.value = title;
}
this.abstractField.readOnly = this._mode == 'view';
this.abstractField.setAttribute('aria-label', Zotero.ItemFields.getLocalizedString('abstractNote'));
}
}
customElements.define("abstract-box", AbstractBox);
}

View file

@ -24,6 +24,8 @@
*/
class XULElementBase extends XULElement {
initialized = false;
/**
* @return {DocumentFragment | null}
*/
@ -49,10 +51,12 @@ class XULElementBase extends XULElement {
}
this.init();
this.initialized = true;
}
disconnectedCallback() {
this.replaceChildren();
this.destroy();
this.initialized = false;
}
}

View file

@ -0,0 +1,170 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2020 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";
{
class CollapsibleSection extends XULElementBase {
_head = null;
_title = null;
_addButton = null;
_listenerAdded = false;
get open() {
return this.hasAttribute('open');
}
set open(val) {
val = !!val;
let open = this.open;
if (open === val) return;
this.render();
let openHeight = this._head?.nextSibling?.scrollHeight;
if (openHeight) {
this.style.setProperty('--open-height', `${openHeight}px`);
}
else {
this.style.setProperty('--open-height', 'auto');
}
// eslint-disable-next-line no-void
void getComputedStyle(this).maxHeight; // Force style calculation! Without this the animation doesn't work
this.toggleAttribute('open', val);
if (!this.dispatchEvent(new CustomEvent('toggle', { bubbles: false, cancelable: true }))) {
// Revert
this.toggleAttribute('open', open);
}
this._saveOpenState();
}
get label() {
return this.getAttribute('label');
}
set label(val) {
this.setAttribute('label', val);
}
get showAdd() {
return this.hasAttribute('show-add');
}
set showAdd(val) {
this.toggleAttribute('show-add', !!val);
}
static get observedAttributes() {
return ['open', 'label', 'show-add'];
}
attributeChangedCallback() {
this.render();
}
init() {
if (!this.dataset.pane) {
throw new Error('data-pane is required');
}
this._restoreOpenState();
this.tabIndex = 0;
this._head = document.createElement('div');
this._head.role = 'button';
this._head.className = 'head';
this._head.addEventListener('click', this._handleClick);
this._head.addEventListener('keydown', this._handleKeyDown);
this._title = document.createElement('span');
this._title.className = 'title';
this._head.append(this._title);
this._addButton = document.createXULElement('toolbarbutton');
this._addButton.className = 'add';
this._addButton.addEventListener('command', (event) => {
// TODO: Is this the best approach?
this._head.nextSibling?.dispatchEvent(new CustomEvent('add', { ...event, bubbles: true }));
});
this._head.append(this._addButton);
let twisty = document.createXULElement('toolbarbutton');
twisty.className = 'twisty';
this._head.append(twisty);
this.prepend(this._head);
this.render();
this._notifierID = Zotero.Prefs.registerObserver(`panes.${this.dataset.pane}.open`, this._restoreOpenState.bind(this));
}
destroy() {
this._head.removeEventListener('click', this._handleClick);
this._head.removeEventListener('keydown', this._handleKeyDown);
Zotero.Prefs.unregisterObserver(this._notifierID);
}
_saveOpenState() {
Zotero.Prefs.set(`panes.${this.dataset.pane}.open`, this.open);
}
_restoreOpenState() {
this.open = Zotero.Prefs.get(`panes.${this.dataset.pane}.open`) ?? true;
}
_handleClick = (event) => {
if (event.target.closest('.add')) return;
this.open = !this.open;
};
_handleKeyDown = (event) => {
if (event.target.closest('.add')) return;
if (event.key === 'Enter' || event.key === ' ') {
this.open = !this.open;
event.preventDefault();
}
};
render() {
if (!this.initialized) return;
if (!this._listenerAdded && this._head?.nextSibling) {
this._head.nextSibling.addEventListener('transitionend', () => {
this.style.setProperty('--open-height', 'auto');
});
this._listenerAdded = true;
}
this._head.setAttribute('aria-expanded', this.open);
this._title.textContent = this.label;
this._addButton.hidden = !this.showAdd;
}
}
customElements.define("collapsible-section", CollapsibleSection);
}

View file

@ -0,0 +1,142 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2020 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";
{
class EditableText extends XULElementBase {
content = MozXULElement.parseXULToFragment(`
<html:textarea rows="1" />
`);
_textarea;
static observedAttributes = ['multiline', 'readonly', 'label'];
get multiline() {
return this.hasAttribute('multiline');
}
set multiline(multiline) {
this.toggleAttribute('multiline', multiline);
}
get readOnly() {
return this.hasAttribute('readonly');
}
set readOnly(readOnly) {
this.toggleAttribute('readonly', readOnly);
}
get placeholder() {
return this._textarea.placeholder;
}
set placeholder(placeholder) {
this._textarea.placeholder = placeholder;
}
// Fluent won't set placeholder on an editable-text for some reason, so we use the label property to store
// the placeholder that will be set on the child <textarea>
get label() {
return this.getAttribute('label');
}
set label(label) {
this.setAttribute('label', label);
}
get ariaLabel() {
return this._textarea.getAttribute('aria-label');
}
set ariaLabel(ariaLabel) {
this._textarea.setAttribute('aria-label', ariaLabel);
}
get value() {
return this._textarea.value;
}
set value(value) {
this._textarea.value = value;
this.dataset.value = value;
this.render();
}
get initialValue() {
return this._textarea.dataset.initialValue;
}
attributeChangedCallback() {
this.render();
}
init() {
this._textarea = this.querySelector('textarea');
this._textarea.addEventListener('input', () => {
if (!this.multiline) {
this._textarea.value = this._textarea.value.replace(/\n/g, ' ');
}
this.dataset.value = this._textarea.value;
});
this._textarea.addEventListener('focus', () => {
this._textarea.dataset.initialValue = this._textarea.value;
});
this._textarea.addEventListener('blur', () => {
delete this._textarea.dataset.initialValue;
});
this._textarea.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
if (!this.multiline || event.shiftKey) {
event.preventDefault();
this._textarea.blur();
}
}
else if (event.key === 'Escape') {
this._textarea.value = this._textarea.dataset.initialValue;
this._textarea.blur();
}
});
this.render();
}
render() {
if (!this._textarea) return;
this._textarea.readOnly = this.readOnly;
this._textarea.placeholder = this.label;
}
focus() {
this._textarea.focus();
}
blur() {
this._textarea.blur();
}
}
customElements.define("editable-text", EditableText);
}

View file

@ -0,0 +1,158 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2020 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";
{
class ItemPaneSidenav extends XULElementBase {
content = MozXULElement.parseXULToFragment(`
<toolbarbutton
data-l10n-id="sidenav-info"
data-pane="info"/>
<toolbarbutton
data-l10n-id="sidenav-abstract"
data-pane="abstract"/>
<toolbarbutton
data-l10n-id="sidenav-attachments"
data-pane="attachments"/>
<toolbarbutton
data-l10n-id="sidenav-notes"
data-pane="notes"/>
<toolbarbutton
data-l10n-id="sidenav-tags"
data-pane="tags"/>
<toolbarbutton
data-l10n-id="sidenav-related"
data-pane="related"/>
`, ['chrome://zotero/locale/zotero.dtd']);
_container = null;
_currentSmoothScrollTarget = null;
_smoothScrollTargetTimeout = null;
get container() {
return this._container;
}
set container(val) {
if (this._container == val) return;
this._container?.removeEventListener('scroll', this._updateSelectedPane.bind(this), { passive: true });
this._container = val;
this._container.addEventListener('scroll', this._updateSelectedPane.bind(this), { passive: true });
this._updateSelectedPane();
this.render();
}
get selectedPane() {
return this.getAttribute('selectedPane');
}
set selectedPane(val) {
this.setAttribute('selectedPane', val);
this.render();
}
static get observedAttributes() {
return ['selectedPane'];
}
attributeChangedCallback() {
this.render();
}
scrollToPane(id, behavior = 'smooth') {
let pane = this._getPane(id);
if (pane) {
this._currentSmoothScrollTarget = id;
pane.scrollIntoView({ block: 'start', behavior });
if (this._smoothScrollTargetTimeout) {
clearTimeout(this._smoothScrollTargetTimeout);
}
this._smoothScrollTargetTimeout = setTimeout(() => {
this._currentSmoothScrollTarget = null;
}, 1000);
}
}
_updateSelectedPane() {
let topPane = null;
let containerBoundingRect = this.container.getBoundingClientRect();
for (let box of this._getPanes()) {
// Allow a little padding to deal with floating-point imprecision
if (box.getBoundingClientRect().top > containerBoundingRect.top + 5) {
break;
}
topPane = box.dataset.pane;
}
if (this._currentSmoothScrollTarget) {
if (this._currentSmoothScrollTarget == topPane) {
this._currentSmoothScrollTarget = null;
}
else {
return;
}
}
this.selectedPane = topPane || 'info';
}
_getPanes() {
return Array.from(this.container.querySelectorAll('[data-pane]'));
}
_getPane(id) {
return this.container.querySelector(':scope > [data-pane="' + id + '"]');
}
init() {
if (!this.container) {
this.container = document.getElementById('zotero-view-item');
}
for (let toolbarbutton of this.children) {
toolbarbutton.addEventListener('command', () => {
this.selectedPane = toolbarbutton.dataset.pane;
this.scrollToPane(toolbarbutton.dataset.pane);
});
}
this.render();
}
render() {
let currentPane = this.selectedPane;
for (let toolbarbutton of this.children) {
let pane = toolbarbutton.dataset.pane;
toolbarbutton.hidden = !this._getPane(pane);
toolbarbutton.toggleAttribute('selected', pane == currentPane);
toolbarbutton.setAttribute('aria-selected', pane == currentPane);
}
}
}
customElements.define("item-pane-sidenav", ItemPaneSidenav);
}

View file

@ -58,6 +58,7 @@ import { getCSSItemTypeIcon } from 'components/icons';
this.append(content);
this._id('notes-add').addEventListener('click', this._handleAdd);
this.addEventListener('add', this._handleAdd);
this._notifierID = Zotero.Notifier.registerObserver(this, ['item'], 'notesBox');
}

View file

@ -0,0 +1,126 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2020 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";
{
class PaneHeader extends XULElementBase {
content = MozXULElement.parseXULToFragment(`
<html:div class="head">
<html:div class="title">
<editable-text />
</html:div>
<html:div class="menu-button">
<toolbarbutton
class="expand-button"
tooltiptext="&zotero.toolbar.openURL.label;"
type="menu"
wantdropmarker="true"
tabindex="0">
<menupopup onpopupshowing="Zotero_LocateMenu.buildLocateMenu(this)"/>
</toolbarbutton>
</html:div>
</html:div>
`, ['chrome://zotero/locale/zotero.dtd']);
_item = null;
_titleFieldID = null;
_mode = null;
get item() {
return this._item;
}
set item(item) {
this.blurOpenField();
this._item = item;
this.render();
}
get mode() {
return this._mode;
}
set mode(mode) {
this._mode = mode;
this.render();
}
init() {
this._notifierID = Zotero.Notifier.registerObserver(this, ['item'], 'paneHeader');
this.titleField = this.querySelector('.title editable-text');
this.menuButton = this.querySelector('.menu-button');
this.titleField.addEventListener('change', () => this.save());
this.titleField.ariaLabel = Zotero.getString('itemFields.title');
this.render();
}
destroy() {
Zotero.Notifier.unregisterObserver(this._notifierID);
}
notify(action, type, ids) {
if (action == 'modify' && this.item && ids.includes(this.item.id)) {
this.render();
}
}
async save() {
if (this.item) {
this.item.setField(this._titleFieldID, this.titleField.value);
await this.item.saveTx();
}
this.render();
}
async blurOpenField() {
this.titleField.blur();
await this.save();
}
render() {
if (!this.item) {
return;
}
this._titleFieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(this.item.itemTypeID, 'title');
let title = this.item.getField(this._titleFieldID);
if (this.titleField.initialValue !== title) {
this.titleField.value = title;
}
this.titleField.readOnly = this._mode == 'view';
this.titleField.placeholder = Zotero.ItemFields.getLocalizedString(this._titleFieldID);
this.menuButton.hidden = !this.item.isRegularItem() && !this.item.isAttachment();
}
}
customElements.define("pane-header", PaneHeader);
}

View file

@ -55,6 +55,7 @@
this.append(content);
this._id('related-add').addEventListener('click', this.add);
this.addEventListener('add', this.add);
this._notifierID = Zotero.Notifier.registerObserver(this, ['item'], 'relatedbox');
}

View file

@ -80,6 +80,7 @@
this.append(content);
this._id("tags-box-add-button").addEventListener('click', this._handleAddButtonClick);
this.addEventListener('add', this._handleAddButtonClick);
this._id("tags-box-add-button").addEventListener('keydown', this._handleAddButtonKeyDown);
this._id('tags-box').addEventListener('click', (event) => {
if (event.target.id == 'tags-box') {

View file

@ -23,12 +23,11 @@
***** END LICENSE BLOCK *****
*/
import React from 'react';
import ReactDOM from 'react-dom';
import TagsBoxContainer from 'containers/tagsBoxContainer';
var ZoteroItemPane = new function() {
var _lastItem, _itemBox, _tagsBox, _notesBox, _relatedBox;
var _container;
var _header, _sidenav, _scrollParent, _itemBox, _abstractBox, _tagsBox, _notesBox, _relatedBox, _boxes;
var _deck;
var _lastItem;
var _selectedNoteID;
var _translationTarget;
@ -37,17 +36,19 @@ var ZoteroItemPane = new function() {
return;
}
// Not in item pane, so skip the introductions
//
// DEBUG: remove?
if (!document.getElementById('zotero-view-tabbox')) {
return;
}
_container = document.getElementById('zotero-view-item-container');
_header = document.getElementById('zotero-item-pane-header');
_sidenav = document.getElementById('zotero-view-item-sidenav');
_scrollParent = document.getElementById('zotero-view-item');
_itemBox = document.getElementById('zotero-editpane-item-box');
_abstractBox = document.getElementById('zotero-editpane-abstract');
_notesBox = document.getElementById('zotero-editpane-notes');
_tagsBox = document.getElementById('zotero-editpane-tags');
_relatedBox = document.getElementById('zotero-editpane-related');
_boxes = [_itemBox, _abstractBox, _notesBox, _tagsBox, _relatedBox];
_deck = document.getElementById('zotero-item-pane-content');
this._unregisterID = Zotero.Notifier.registerObserver(this, ['item'], 'itemPane');
}
@ -60,80 +61,36 @@ var ZoteroItemPane = new function() {
/*
* Load a top-level item
*/
this.viewItem = Zotero.Promise.coroutine(function* (item, mode, index) {
if (!index) {
index = 0;
this.viewItem = Zotero.Promise.coroutine(function* (item, mode, pane) {
if (!pane) {
pane = 'info';
}
Zotero.debug('Viewing item in pane ' + index);
switch (index) {
case 0: {
if (!_itemBox) {
_itemBox = new (customElements.get('item-box'));
_itemBox.id = 'zotero-editpane-item-box';
document.getElementById('item-box-container').appendChild(_itemBox);
}
var box = _itemBox;
break;
}
case 1:
var box = _notesBox;
box.parentItem = item;
break;
Zotero.debug('Viewing item in pane ' + pane);
case 2:
var box = _tagsBox;
break;
case 3:
var box = _relatedBox;
break;
}
// Force blur() when clicking off a textbox to another item in middle
// pane, since for some reason it's not being called automatically
if (_lastItem && _lastItem != item) {
switch (index) {
case 0:
// TEMP
//yield box.blurOpenField();
// DEBUG: Currently broken
//box.scrollToTop();
break;
}
}
_notesBox.parentItem = item;
_lastItem = item;
var viewBox = document.getElementById('zotero-view-item');
viewBox.classList.remove('no-tabs');
if (index == 0) {
document.getElementById('zotero-editpane-tabs').setAttribute('hidden', item.isFeedItem);
if (item.isFeedItem) {
viewBox.classList.add('no-tabs');
let lastTranslationTarget = Zotero.Prefs.get('feeds.lastTranslationTarget');
if (lastTranslationTarget) {
let id = parseInt(lastTranslationTarget.substr(1));
if (lastTranslationTarget[0] == "L") {
_translationTarget = Zotero.Libraries.get(id);
}
else if (lastTranslationTarget[0] == "C") {
_translationTarget = Zotero.Collections.get(id);
}
_container.classList.toggle('feed-item', !!item.isFeedItem);
if (item.isFeedItem) {
let lastTranslationTarget = Zotero.Prefs.get('feeds.lastTranslationTarget');
if (lastTranslationTarget) {
let id = parseInt(lastTranslationTarget.substr(1));
if (lastTranslationTarget[0] == "L") {
_translationTarget = Zotero.Libraries.get(id);
}
else if (lastTranslationTarget[0] == "C") {
_translationTarget = Zotero.Collections.get(id);
}
if (!_translationTarget) {
_translationTarget = Zotero.Libraries.userLibrary;
}
this.setTranslateButton();
}
if (!_translationTarget) {
_translationTarget = Zotero.Libraries.userLibrary;
}
this.setTranslateButton();
}
if (box) {
for (let box of [_header, ..._boxes]) {
if (mode) {
box.mode = mode;
@ -147,49 +104,33 @@ var ZoteroItemPane = new function() {
box.item = item;
}
_sidenav.selectedPane = pane;
_sidenav.scrollToPane(pane, 'instant');
});
this.notify = Zotero.Promise.coroutine(function* (action, type, ids, extraData) {
var viewBox = document.getElementById('zotero-view-item');
if (viewBox.selectedIndex == 0 && action == 'refresh' && _lastItem) {
if (action == 'refresh' && _lastItem) {
yield this.viewItem(_lastItem, null, 0);
}
});
this.blurOpenField = Zotero.Promise.coroutine(function* () {
var tabBox = document.getElementById('zotero-view-tabbox');
switch (tabBox.selectedIndex) {
case 0:
var box = _itemBox;
if (box) {
yield box.blurOpenField();
}
break;
case 2:
var box = _tagsBox;
if (box) {
box.blurOpenField();
}
break;
this.blurOpenField = async function () {
if (_itemBox.contains(document.activeElement)) {
await _itemBox.blurOpenField();
}
});
function focusItemsList() {
var tree = document.getElementById('zotero-items-tree');
if (tree) {
tree.focus();
else if (_header.contains(document.activeElement)) {
await _header.blurOpenField();
}
}
_scrollParent.focus();
};
this.onNoteSelected = function (item, editable) {
_selectedNoteID = item.id;
var type = Zotero.Libraries.get(item.libraryID).libraryType;
var noteEditor = document.getElementById('zotero-note-editor');
noteEditor.mode = editable ? 'edit' : 'view';
noteEditor.viewMode = 'library';
@ -205,27 +146,10 @@ var ZoteroItemPane = new function() {
*/
this.openNoteWindow = async function () {
var selectedNote = Zotero.Items.get(_selectedNoteID);
var type = Zotero.Libraries.get(selectedNote.libraryID).libraryType;
ZoteroPane.openNoteWindow(selectedNote.id);
};
this.onTagsContextPopupShowing = function () {
if (!_lastItem.isEditable()) {
return false;
}
}
this.removeAllTags = async function () {
if (Services.prompt.confirm(null, "", Zotero.getString('pane.item.tags.removeAll'))) {
_lastItem.setTags([]);
await _lastItem.saveTx();
}
}
this.translateSelectedItems = Zotero.Promise.coroutine(function* () {
var collectionID = _translationTarget.objectType == 'collection' ? _translationTarget.id : undefined;
var items = ZoteroPane_Local.itemsView.getSelectedItems();
@ -321,7 +245,12 @@ var ZoteroItemPane = new function() {
var tooltip = label + (Zotero.rtl ? ' \u202B' : ' ') + '(' + key + ')'
elem.title = tooltip;
};
}
this.getSidenavSelectedPane = function () {
return _sidenav.selectedPane;
};
};
addEventListener("load", function(e) { ZoteroItemPane.onLoad(e); }, false);
addEventListener("unload", function(e) { ZoteroItemPane.onUnload(e); }, false);

View file

@ -774,8 +774,7 @@ var ItemTree = class ItemTree extends LibraryTree {
if (singleSelect) {
if (!extraData[singleSelect] || !extraData[singleSelect].skipSelect) {
// Reset to Info tab
this._ownerDocument.getElementById('zotero-view-tabbox').selectedIndex = 0;
this._ownerDocument.getElementById('zotero-view-item').scrollTop = 0;
await this.selectItem(singleSelect);
reselect = true;
}

View file

@ -34,9 +34,7 @@ var Zotero_LocateMenu = new function() {
/**
* Clear and build the locate menu
*/
this.buildLocateMenu = function() {
var locateMenu = document.getElementById('zotero-tb-locate-menu');
this.buildLocateMenu = function (locateMenu) {
// clear menu
while(locateMenu.childElementCount > 0) {
locateMenu.removeChild(locateMenu.firstChild);
@ -636,4 +634,4 @@ var Zotero_LocateMenu = new function() {
ZoteroPane_Local.loadURI(urls, event);
});
};
}
}

View file

@ -40,26 +40,6 @@ window.addEventListener('DOMContentLoaded', () => {
if (fileQuitItemUnix) fileQuitItemUnix.hidden = true;
if (editPreferencesSeparator) editPreferencesSeparator.hidden = true;
if (editPreferencesItem) editPreferencesItem.hidden = true;
// Monkey-patch the toolbarbutton CE so it shows a native menu popup
let MozToolbarbutton = customElements.get('toolbarbutton');
if (MozToolbarbutton) {
let originalRender = MozToolbarbutton.prototype.render;
MozToolbarbutton.prototype.render = function () {
originalRender.apply(this);
if (!this._zoteroMouseDownListenerAdded) {
this.addEventListener('mousedown', (event) => {
if (!event.defaultPrevented
&& !this.disabled
&& this.getAttribute('nonnativepopup') != 'true'
&& Zotero.Utilities.Internal.showNativeElementPopup(this)) {
event.preventDefault();
}
});
this._zoteroMouseDownListenerAdded = true;
}
};
}
}
else {
// Set behavior on all non-macOS platforms

View file

@ -826,7 +826,7 @@ var ZoteroPane = new function()
else if (event.key === 'Tab' && event.shiftKey) {
let node = document.activeElement;
if (node && node.nodeType === Node.ELEMENT_NODE && (
node.parentNode.classList.contains('zotero-editpane-tabs')
node.parentNode.classList.contains('zotero-view-item')
|| node.getAttribute('type') === 'search'
|| node.getAttribute('anonid') === 'editor-view'
&& node.contentWindow.document.activeElement.classList.contains('toolbar-button-return'))) {
@ -1757,8 +1757,6 @@ var ZoteroPane = new function()
}
_lastSelectedItems = ids;
var tabs = document.getElementById('zotero-view-tabbox');
var collectionTreeRow = this.getCollectionTreeRow();
// I don't think this happens in normal usage, but it can happen during tests
if (!collectionTreeRow) {
@ -1785,16 +1783,15 @@ var ZoteroPane = new function()
else {
var isCommons = collectionTreeRow.isBucket();
document.getElementById('zotero-item-pane-content').selectedIndex = 1;
var tabBox = document.getElementById('zotero-view-tabbox');
// Reset tab when viewing a feed item, which only has the info tab
if (item.isFeedItem) {
tabBox.selectedIndex = 0;
let deck = document.getElementById('zotero-item-pane-content');
let pane;
if (deck.selectedIndex == 1) {
pane = ZoteroItemPane.getSidenavSelectedPane();
}
else {
deck.selectedIndex = 1;
pane = ZoteroItemPane.getSidenavSelectedPane();
}
var pane = tabBox.selectedIndex;
tabBox.firstChild.hidden = isCommons;
var button = document.getElementById('zotero-item-show-original');
if (isCommons) {
@ -1807,11 +1804,9 @@ var ZoteroPane = new function()
if (this.collectionsView.editable) {
yield ZoteroItemPane.viewItem(item, null, pane);
tabs.selectedIndex = document.getElementById('zotero-view-item').selectedIndex;
}
else {
yield ZoteroItemPane.viewItem(item, 'view', pane);
tabs.selectedIndex = document.getElementById('zotero-view-item').selectedIndex;
}
if (item.isFeedItem) {

View file

@ -734,17 +734,6 @@
<hbox>
<div xmlns="http://www.w3.org/1999/xhtml" id="tab-bar-container" style="-moz-box-flex: 1;"/>
<hbox id="zotero-tabs-toolbar" align="center">
<hbox align="center" pack="start">
<toolbarbutton
id="zotero-tb-locate"
class="zotero-tb-button"
tooltiptext="&zotero.toolbar.openURL.label;"
type="menu"
tabindex="-1"
wantdropmarker="true">
<menupopup id="zotero-tb-locate-menu" onpopupshowing="Zotero_LocateMenu.buildLocateMenu()"/>
</toolbarbutton>
</hbox>
<toolbarbutton id="zotero-tb-opened-tabs" class="zotero-tb-button" tabindex="-1" data-l10n-id="zotero-toolbar-opened-tabs-menu" type="panel" />
<hbox id="zotero-tb-sync-progress-box" align="center" pack="end">
<toolbarbutton id="zotero-tb-sync-stop"
@ -1100,29 +1089,39 @@
Keep in sync with contextPane.js (_addItemContext function) which
dynamically creates this itemPane part for each tab
-->
<tabbox id="zotero-view-tabbox" class="zotero-view-tabbox" flex="1" onselect="if (!ZoteroPane_Local.getCollectionTreeRow() || event.originalTarget.localName != 'tabpanels') { return; }; ZoteroItemPane.viewItem(ZoteroPane_Local.getSelectedItems()[0], ZoteroPane_Local.collectionsView.editable ? 'edit' : 'view', this.selectedIndex)">
<tabs id="zotero-editpane-tabs" class="zotero-editpane-tabs">
<tab id="zotero-editpane-info-tab" label="&zotero.tabs.info.label;"/>
<tab id="zotero-editpane-notes-tab" label="&zotero.tabs.notes.label;"/>
<tab id="zotero-editpane-tags-tab" label="&zotero.tabs.tags.label;"/>
<tab id="zotero-editpane-related-tab" label="&zotero.tabs.related.label;"/>
</tabs>
<tabpanels id="zotero-view-item" class="zotero-view-item" flex="1">
<tabpanel id="item-box-container"/>
<hbox id="zotero-view-item-container" class="zotero-view-item-container">
<html:div class="zotero-view-item-main">
<pane-header id="zotero-item-pane-header" />
<tabpanel>
<notes-box id="zotero-editpane-notes" class="zotero-editpane-notes" flex="1"/>
</tabpanel>
<tabpanel>
<tags-box id="zotero-editpane-tags" class="zotero-editpane-tags" flex="1"/>
</tabpanel>
<tabpanel>
<related-box id="zotero-editpane-related" class="zotero-editpane-related" flex="1"/>
</tabpanel>
</tabpanels>
</tabbox>
<html:div id="zotero-view-item" class="zotero-view-item">
<collapsible-section data-l10n-id="section-info" data-pane="info">
<item-box id="zotero-editpane-item-box"/>
</collapsible-section>
<collapsible-section data-l10n-id="section-abstract" data-pane="abstract">
<abstract-box id="zotero-editpane-abstract" class="zotero-editpane-abstract"/>
</collapsible-section>
<collapsible-section data-l10n-id="section-attachments" data-pane="attachments" show-add="true">
<html:span>[placeholder for attachments section]</html:span>
</collapsible-section>
<collapsible-section data-l10n-id="section-notes" data-pane="notes" show-add="true">
<notes-box id="zotero-editpane-notes" class="zotero-editpane-notes"/>
</collapsible-section>
<collapsible-section data-l10n-id="section-tags" data-pane="tags" show-add="true">
<tags-box id="zotero-editpane-tags" class="zotero-editpane-tags"/>
</collapsible-section>
<collapsible-section data-l10n-id="section-related" data-pane="related" show-add="true">
<related-box id="zotero-editpane-related" class="zotero-editpane-related"/>
</collapsible-section>
</html:div>
</html:div>
<item-pane-sidenav id="zotero-view-item-sidenav" class="zotero-view-item-sidenav"/>
</hbox>
<!-- Note item -->
<groupbox id="zotero-view-note" flex="1">

View file

@ -46,12 +46,6 @@
<!ENTITY zotero.upgrade.changeLogLink "the changelog">
<!ENTITY zotero.upgrade.changeLogAfterLink "to find out what's new.">
<!ENTITY zotero.tabs.info.label "Info">
<!ENTITY zotero.tabs.notes.label "Notes">
<!ENTITY zotero.tabs.attachments.label "Attachments">
<!ENTITY zotero.tabs.tags.label "Tags">
<!ENTITY zotero.tabs.related.label "Related">
<!ENTITY zotero.toolbar.duplicate.label "Show Duplicates">
<!ENTITY zotero.collections.showUnfiledItems "Show Unfiled Items">
<!ENTITY zotero.collections.showRetractedItems "Show Retracted Items">

View file

@ -204,3 +204,39 @@ menu-ui-density-comfortable =
.label = Comfortable
menu-ui-density-compact =
.label = Compact
pane-info = Info
pane-abstract = Abstract
pane-attachments = Attachments
pane-notes = Notes
pane-tags = Tags
pane-related = Related
section-info =
.label = { pane-info }
section-abstract =
.label = { pane-abstract }
section-attachments =
.label = { pane-attachments }
section-notes =
.label = { pane-notes }
section-tags =
.label = { pane-tags }
section-related =
.label = { pane-related }
sidenav-info =
.tooltiptext = { pane-info }
sidenav-abstract =
.tooltiptext = { pane-abstract }
sidenav-attachments =
.tooltiptext = { pane-attachments }
sidenav-notes =
.tooltiptext = { pane-notes }
sidenav-tags =
.tooltiptext = { pane-tags }
sidenav-related =
.tooltiptext = { pane-related }
abstract-field =
.label = Add abstract…

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon">
<path id="Vector" d="M2 5.70711L8 11.7071L14 5.70711L13.2929 5L8 10.2929L2.70711 5L2 5.70711Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 239 B

View file

@ -0,0 +1,5 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="chevron-6">
<path id="Vector" d="M1.70711 2L1 2.70711L4 5.70711L7 2.70711L6.29289 2L4 4.29289L1.70711 2Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 239 B

View file

@ -2,59 +2,53 @@
padding: 0 2em;
}
.zotero-view-tabbox, .zotero-item-pane-content > groupbox, .zotero-item-pane-content > groupbox > .groupbox-body
.zotero-item-pane-content > groupbox, .zotero-item-pane-content > groupbox > .groupbox-body
{
margin: 0 !important;
padding: 0 !important;
}
.zotero-view-tabbox tabs tab
{
margin-top: 0 !important;
margin-bottom: 0 !important;
}
.zotero-view-tabbox tabs tab .tab-text
{
margin-top: .2em !important;
margin-bottom: .25em !important;
}
.zotero-item-pane-content {
background: -moz-Field; /* Same as background colour for treeview */
}
.zotero-view-item
{
padding: 0;
}
.zotero-view-item.no-tabs
{
margin-top: 0;
}
.zotero-view-item > tabpanel > *
{
overflow: auto;
min-width: 0;
min-height: 0;
}
.zotero-view-item:not([selectedIndex="0"]) > tabpanel > * {
padding-top: .25em;
.zotero-view-item-container {
display: flex;
flex-direction: row;
}
.zotero-view-item-main {
flex: 1;
display: flex;
flex-direction: column;
}
.zotero-view-item {
flex: 1;
overflow-y: auto;
padding: 0 8px;
}
.zotero-view-item-container.feed-item .zotero-view-item > :is(notes-box, tags-box, related-box),
.zotero-view-item-container.feed-item .zotero-view-item-sidenav {
display: none;
}
.zotero-view-item > * {
box-sizing: border-box;
width: 100%;
padding-block: 4px;
}
.zotero-view-item > :last-child {
min-height: 100%;
}
.zotero-view-item > vbox
{
overflow: auto;
margin-left: 5px;
}
/*.zotero-editpane-tabs {*/
/* background: #ececec;*/
/*}*/
/* Buttons in trash and feed views */
.zotero-item-pane-top-buttons {
-moz-appearance: toolbar;

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="abstract">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M0 2H16V14H0V2ZM1 3V13H15V3H1ZM6 6H2V5H6V6ZM14 9H2V8H14V9ZM12 11H2V10H12V11Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 287 B

View file

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="attachment" clip-path="url(#clip0_380_16189)">
<path id="Vector" d="M4.5 10.5L11.25 3.75C11.6642 3.33579 12.3358 3.33579 12.75 3.75V3.75C13.1642 4.16421 13.1642 4.83579 12.75 5.25L4.5 13.5C3.67157 14.3284 2.32843 14.3284 1.5 13.5V13.5C0.671573 12.6716 0.671573 11.3284 1.5 10.5L9.75 2.25C10.9926 1.00736 13.0074 1.00736 14.25 2.25V2.25C15.4926 3.49264 15.4926 5.50736 14.25 6.75L7.5 13.5" stroke="context-stroke" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_380_16189">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 656 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="info">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M2 0H9.70711L14 4.29289V7.75777C15.206 8.56504 16 9.93979 16 11.5C16 13.9853 13.9853 16 11.5 16C10.4284 16 9.4442 15.6254 8.67133 15H2V0ZM7.75777 14C7.27914 13.285 7 12.4251 7 11.5C7 9.01472 9.01472 7 11.5 7C12.026 7 12.5308 7.09023 13 7.25606V5H9V1H3V14H7.75777ZM10 1.70711L12.2929 4H10V1.70711ZM15 11.5C15 13.433 13.433 15 11.5 15C9.567 15 8 13.433 8 11.5C8 9.567 9.567 8 11.5 8C13.433 8 15 9.567 15 11.5ZM10.875 9.625C10.875 9.27982 11.1548 9 11.5 9C11.8452 9 12.125 9.27982 12.125 9.625C12.125 9.97018 11.8452 10.25 11.5 10.25C11.1548 10.25 10.875 9.97018 10.875 9.625ZM12 14V11H11V14H12Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 799 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="note">
<path id="Vector" d="M2 0V16H9.707L15 10.707V0H2ZM3 1H14V2H3V1ZM10 14.293V11H13.293L10 14.293ZM14 10H9V15H3V3H14V10Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 262 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="link">
<path id="Vector" d="M12.5 13H8.5C7.57174 13 6.6815 12.6313 6.02513 11.9749C5.36875 11.3185 5 10.4283 5 9.5C5 8.57174 5.36875 7.6815 6.02513 7.02513C6.6815 6.36875 7.57174 6 8.5 6H8.908C9.03111 6.32197 9.03111 6.67803 8.908 7H8.5C7.83696 7 7.20107 7.26339 6.73223 7.73223C6.26339 8.20107 6 8.83696 6 9.5C6 10.163 6.26339 10.7989 6.73223 11.2678C7.20107 11.7366 7.83696 12 8.5 12H12.5C13.163 12 13.7989 11.7366 14.2678 11.2678C14.7366 10.7989 15 10.163 15 9.5C15 8.83696 14.7366 8.20107 14.2678 7.73223C13.7989 7.26339 13.163 7 12.5 7H11.953C11.9778 6.83432 11.9935 6.6674 12 6.5C11.9935 6.3326 11.9778 6.16568 11.953 6H12.5C13.4283 6 14.3185 6.36875 14.9749 7.02513C15.6313 7.6815 16 8.57174 16 9.5C16 10.4283 15.6313 11.3185 14.9749 11.9749C14.3185 12.6313 13.4283 13 12.5 13ZM0 6.5C0 7.42826 0.368749 8.3185 1.02513 8.97487C1.6815 9.63125 2.57174 10 3.5 10H4.047C4.02219 9.83432 4.0065 9.6674 4 9.5C4.0065 9.3326 4.02219 9.16568 4.047 9H3.5C2.83696 9 2.20107 8.73661 1.73223 8.26777C1.26339 7.79893 1 7.16304 1 6.5C1 5.83696 1.26339 5.20107 1.73223 4.73223C2.20107 4.26339 2.83696 4 3.5 4H7.5C8.16304 4 8.79893 4.26339 9.26777 4.73223C9.73661 5.20107 10 5.83696 10 6.5C10 7.16304 9.73661 7.79893 9.26777 8.26777C8.79893 8.73661 8.16304 9 7.5 9H7.092C6.96889 9.32197 6.96889 9.67803 7.092 10H7.5C8.42826 10 9.3185 9.63125 9.97487 8.97487C10.6313 8.3185 11 7.42826 11 6.5C11 5.57174 10.6313 4.6815 9.97487 4.02513C9.3185 3.36875 8.42826 3 7.5 3H3.5C2.57174 3 1.6815 3.36875 1.02513 4.02513C0.368749 4.6815 0 5.57174 0 6.5Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="tag" clip-path="url(#clip0_188_882)">
<path id="Vector" d="M6.086 1L14.586 9.5L9.5 14.586L1 6.086V1H6.086ZM6.5 0H0.5C0.367392 0 0.240215 0.0526784 0.146447 0.146447C0.0526784 0.240215 0 0.367392 0 0.5L0 6.5L9.146 15.646C9.23976 15.7397 9.36692 15.7924 9.4995 15.7924C9.63208 15.7924 9.75924 15.7397 9.853 15.646L15.646 9.853C15.7397 9.75924 15.7924 9.63208 15.7924 9.4995C15.7924 9.36692 15.7397 9.23976 15.646 9.146L6.5 0ZM4 2.75C3.75277 2.75 3.5111 2.82331 3.30554 2.96066C3.09998 3.09801 2.93976 3.29324 2.84515 3.52165C2.75054 3.75005 2.72579 4.00139 2.77402 4.24386C2.82225 4.48634 2.9413 4.70907 3.11612 4.88388C3.29093 5.0587 3.51366 5.17775 3.75614 5.22598C3.99861 5.27421 4.24995 5.24946 4.47835 5.15485C4.70676 5.06024 4.90199 4.90002 5.03934 4.69446C5.17669 4.4889 5.25 4.24723 5.25 4C5.25 3.66848 5.1183 3.35054 4.88388 3.11612C4.64946 2.8817 4.33152 2.75 4 2.75Z" fill="context-fill"/>
</g>
<defs>
<clipPath id="clip0_188_882">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="abstract">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M1 3H19V17H1V3ZM2.25 4.25V15.75H17.75V4.25H2.25ZM8 8H4V6.75H8V8ZM16 11H4V9.75H16V11ZM14 13.25H4V12H14V13.25Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 319 B

View file

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="attachment">
<path id="Vector" d="M6.5 12.5L13 6C13.5523 5.44772 14.4477 5.44772 15 6V6C15.5523 6.55228 15.5523 7.44772 15 8L6.5 16.5C5.39543 17.6046 3.60457 17.6046 2.5 16.5V16.5C1.39543 15.3954 1.39543 13.6046 2.5 12.5L11 4C12.6569 2.34315 15.3431 2.34315 17 4V4C18.6569 5.65685 18.6569 8.34315 17 10L10.5 16.5" stroke="context-stroke" stroke-width="1.25" stroke-linecap="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 498 B

View file

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="info">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M3.625 1H3V1.625V18.375V19H3.625H12.5024C13.2914 19.6261 14.2895 20 15.375 20C17.9293 20 20 17.9293 20 15.375C20 13.7955 19.2083 12.401 18 11.5666V6.625V6.36612L17.8169 6.18306L12.8169 1.18306L12.6339 1H12.375H3.625ZM16.75 10.9578V7.25H12.375H11.75V6.625V2.25H4.25V17.75H11.4056C10.9893 17.0558 10.75 16.2433 10.75 15.375C10.75 12.8207 12.8207 10.75 15.375 10.75C15.8538 10.75 16.3156 10.8228 16.75 10.9578ZM13 17.7729V17.75H12.9771C12.373 17.1402 12 16.3012 12 15.375C12 13.511 13.511 12 15.375 12C17.239 12 18.75 13.511 18.75 15.375C18.75 17.239 17.239 18.75 15.375 18.75C14.4488 18.75 13.6098 18.377 13 17.7729ZM15.8661 6L13 3.13388V6H15.8661ZM14.625 13.75C14.625 13.3358 14.9608 13 15.375 13C15.7892 13 16.125 13.3358 16.125 13.75C16.125 14.1642 15.7892 14.5 15.375 14.5C14.9608 14.5 14.625 14.1642 14.625 13.75ZM14.75 15V17.75H16V15H14.75Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="note">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M3.625 1H3V1.625V3.75V5V18.375V19H3.625H12.375H12.6339L12.8169 18.8169L17.8169 13.8169L18 13.6339V13.375V1.625V1H17.375H3.625ZM4.25 5V17.75H11.75V13.375V12.75H12.375H16.75V5H4.25ZM16.75 3.75V2.25H4.25V3.75H16.75ZM13 14H15.8661L13 16.8661V14Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 448 B

View file

@ -0,0 +1,10 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="link" clip-path="url(#clip0_1132_37385)">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M0 8.125C0 5.70875 1.95875 3.75 4.375 3.75H9.625C12.0412 3.75 14 5.70875 14 8.125C14 10.5412 12.0412 12.5 9.625 12.5H8.60669C8.5376 12.3045 8.5 12.0941 8.5 11.875C8.5 11.6559 8.5376 11.4455 8.60669 11.25H9.625C11.3509 11.25 12.75 9.85089 12.75 8.125C12.75 6.39911 11.3509 5 9.625 5H4.375C2.64911 5 1.25 6.39911 1.25 8.125C1.25 9.85089 2.64911 11.25 4.375 11.25H4.78433C4.76165 11.4552 4.75 11.6637 4.75 11.875C4.75 12.0863 4.76165 12.2948 4.78433 12.5H4.375C1.95875 12.5 0 10.5412 0 8.125ZM10.3751 7.49999H11.3934C11.4625 7.69547 11.5001 7.90584 11.5001 8.12499C11.5001 8.34413 11.4625 8.5545 11.3934 8.74999H10.3751C8.64919 8.74999 7.25008 10.1491 7.25008 11.875C7.25008 13.6009 8.64919 15 10.3751 15H15.6251C17.351 15 18.7501 13.6009 18.7501 11.875C18.7501 10.1491 17.351 8.74999 15.6251 8.74999H15.2157C15.2384 8.54478 15.2501 8.33624 15.2501 8.12499C15.2501 7.91373 15.2384 7.7052 15.2157 7.49999H15.6251C18.0413 7.49999 20.0001 9.45874 20.0001 11.875C20.0001 14.2912 18.0413 16.25 15.6251 16.25H10.3751C7.95883 16.25 6.00008 14.2912 6.00008 11.875C6.00008 9.45874 7.95883 7.49999 10.3751 7.49999Z" fill="context-fill"/>
</g>
<defs>
<clipPath id="clip0_1132_37385">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="tag">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M1.9375 1C1.41973 1 1 1.41973 1 1.9375V8.625V8.88388L1.18306 9.06694L10.8371 18.721C11.2032 19.0871 11.7968 19.0871 12.1629 18.721L18.721 12.1629C19.0871 11.7968 19.0871 11.2032 18.721 10.8371L9.06694 1.18306L8.88388 1H8.625H1.9375ZM2.25 8.36612V2.25H8.36612L17.6161 11.5L11.5 17.6161L2.25 8.36612ZM5.125 6.375C5.81536 6.375 6.375 5.81536 6.375 5.125C6.375 4.43464 5.81536 3.875 5.125 3.875C4.43464 3.875 3.875 4.43464 3.875 5.125C3.875 5.81536 4.43464 6.375 5.125 6.375Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 677 B

View file

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M3.625 1H3V1.625V18.375V19H3.625H14.9698L13.7198 17.75H4.25V2.25H11.75V6.625V7.25H12.375H16.75V9.95176L18 11.2018V6.625V6.36612L17.8169 6.18306L12.8169 1.18306L12.6339 1H12.375H3.625ZM15.8661 6L13 3.13388V6H15.8661ZM17.4911 15.125H10V13.875H17.4911L15 11.3839L15.8839 10.5L19.8838 14.5L15.8839 18.5L15 17.6161L17.4911 15.125Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 536 B

View file

@ -514,11 +514,6 @@
list-style-image: url('chrome://zotero/skin/toolbar-advanced-search.png');
}
#zotero-tb-locate
{
list-style-image: url('chrome://zotero/skin/toolbar-go-arrow.png');
}
#zotero-tb-sync-stop
{
list-style-image: url(chrome://zotero/skin/control_stop_blue.png);
@ -661,12 +656,6 @@
margin-inline-start: 3px !important;
}
#item-box-container {
display: flex;
min-width: 0;
min-height: 0;
}
#retracted-items-banner, #sync-reminder-banner {
display: flex;
justify-content: center;
@ -820,7 +809,6 @@
.zotero-menuitem-find-pdf { list-style-image: url('chrome://zotero/skin/treeitem-attachment-pdf@2x.png'); }
.zotero-menuitem-create-report { list-style-image: url('chrome://zotero/skin/treeitem-report@2x.png'); }
#zotero-tb-advanced-search { list-style-image: url('chrome://zotero/skin/toolbar-advanced-search@2x.png'); }
#zotero-tb-locate { list-style-image: url('chrome://zotero/skin/toolbar-go-arrow@2x.png'); }
#zotero-tb-sync-stop { list-style-image: url(chrome://zotero/skin/control_stop_blue@2x.png); }
#zotero-tb-pq-recognize { list-style-image: url(chrome://zotero/skin/pdf-search@2x.png); }
#zotero-tb-sync-error { list-style-image: url(chrome://zotero/skin/error@2x.png); }

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="plus">
<path id="Vector" d="M14 8H9V3H8V8H3V9H8V14H9V9H14V8Z" fill="context-fill"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 591 B

View file

@ -44,6 +44,7 @@
@import "components/tagSelector";
@import "components/textLink";
@import "components/virtualized-table";
@import "components/expand-button";
// Elements
// --------------------------------------------------
@ -60,3 +61,8 @@
@import "elements/styleConfigurator";
@import "elements/tagsBox";
@import "elements/zoteroSearch";
@import "elements/paneHeader";
@import "elements/editableText";
@import "elements/itemPaneSidenav";
@import "elements/abstractBox";
@import "elements/collapsibleSection";

View file

@ -78,3 +78,13 @@ $z-index-modal: 40;
$z-index-drag-layer: 50;
$z-index-loading-cover: 60;
// Item pane
// --------------------------------------------------
$item-pane-sections: (
"info": var(--accent-blue),
"abstract": var(--accent-teal),
"attachments": var(--accent-green),
"notes": var(--accent-yellow),
"tags": var(--accent-orange),
"related": var(--accent-wood),
);

View file

@ -0,0 +1,41 @@
.expand-button {
min-width: 0;
width: 40px;
height: 28px;
margin: 0;
padding: 4px;
border-radius: 5px;
background-color: transparent;
-moz-context-properties: fill, fill-opacity;
fill: var(--fill-secondary);
&:hover {
background-color: var(--fill-quinary);
}
&[open="true"] {
background-color: var(--fill-quarternary);
}
&:disabled {
background-color: transparent;
fill: var(--fill-tertiary);
.toolbarbutton-menu-dropmarker {
fill: var(--fill-tertiary);
}
}
.toolbarbutton-menu-dropmarker {
display: block;
visibility: visible;
background-image: url("chrome://zotero/skin/chevron-6.svg");
background-repeat: no-repeat;
background-position: center;
fill: var(--fill-secondary);
width: 8px;
height: 8px;
}
}

View file

@ -139,4 +139,8 @@
background: var(--material-tabbar);
border-bottom: var(--material-panedivider);
}
}
#zotero-collections-tree > div, #zotero-item-pane {
background: var(--material-sidepane);
}
}

View file

@ -0,0 +1,7 @@
abstract-box {
display: flex;
editable-text {
flex: 1;
}
}

View file

@ -0,0 +1,85 @@
collapsible-section {
display: flex;
flex-direction: column;
gap: 2px;
border-bottom: 1px solid var(--fill-quinary);
& > .head {
@include comfortable {
padding-block: 2px;
}
display: flex;
align-items: center;
.title {
flex: 1;
display: flex;
align-items: center;
gap: 4px;
color: var(--fill-secondary);
font-weight: 590;
&::before {
content: '';
width: 16px;
height: 16px;
}
}
toolbarbutton {
flex-shrink: 0;
width: 20px;
height: 20px;
padding: 2px;
-moz-context-properties: fill, fill-opacity, stroke, stroke-opacity;
fill: var(--fill-secondary);
stroke: var(--fill-secondary);
}
toolbarbutton.add {
list-style-image: icon-url("plus.svg");
}
toolbarbutton.twisty .toolbarbutton-icon {
list-style-image: icon-url("chevron-12.svg");
transform: rotate(0deg);
transform-origin: center;
transition: transform 0.2s ease-in-out;
}
}
&[open] > .head {
toolbarbutton.twisty .toolbarbutton-icon {
transform: rotate(-180deg);
}
}
@each $pane, $color in $item-pane-sections {
&[data-pane="#{$pane}"] {
& > .head > .title::before {
background: icon-url("itempane/16/#{$pane}.svg") no-repeat center;
-moz-context-properties: fill, fill-opacity, stroke, stroke-opacity;
fill: $color;
stroke: $color;
}
}
}
& > :not(.head) {
overflow: hidden;
max-height: var(--open-height, auto);
opacity: 1;
transition: max-height 0.2s ease-in-out, opacity 0.2s ease-in-out;
}
&:not([open]) {
& > :not(.head) {
max-height: 0;
opacity: 0;
visibility: hidden;
transition: max-height 0.2s ease-in-out, opacity 0.2s ease-in-out, visibility 0s 0.2s;
}
}
}

View file

@ -0,0 +1,66 @@
@include comfortable {
--editable-text-padding-inline: 4px;
--editable-text-padding-block: 4px;
}
@include compact {
--editable-text-padding-inline: 4px;
--editable-text-padding-block: 1px;
}
editable-text {
// Fun auto-sizing approach from CSSTricks:
// https://css-tricks.com/the-cleanest-trick-for-autogrowing-textareas/
display: grid;
&::after {
content: attr(data-value) ' ';
visibility: hidden;
margin: 1px;
}
&::after, textarea {
grid-area: 1 / 1 / 2 / 2;
padding: var(--editable-text-padding-block) var(--editable-text-padding-inline);
font: inherit;
line-height: inherit;
color: inherit;
overflow-y: hidden;
white-space: pre-wrap;
}
textarea {
min-height: 0;
margin: 0;
&:read-only, &:not(:focus) {
appearance: none;
border: none;
outline: none;
background: transparent;
margin: 1px;
}
&:hover:not(:read-only, :focus) {
border-radius: 5px;
border: 1px solid var(--fill-tertiary);
box-shadow: 0 0 0 1px var(--fill-quinary);
margin: 0;
}
::placeholder {
color: var(--fill-tertiary);
}
}
&[multiline] {
&::after, textarea {
overflow-y: auto;
}
textarea {
min-height: 5em;
}
}
}

View file

@ -0,0 +1,40 @@
item-pane-sidenav {
display: flex;
flex-direction: column;
padding: 6px 4px;
align-items: flex-start;
gap: 6px;
border-left: var(--material-panedivider);
toolbarbutton {
// TODO: Extract button styles?
width: 28px;
height: 28px;
padding: 4px;
flex-shrink: 0;
border-radius: 5px;
-moz-context-properties: fill, fill-opacity, stroke, stroke-opacity;
&:hover {
background-color: var(--fill-quinary);
}
&:active, &[selected] {
background-color: var(--fill-quarternary);
}
&:disabled {
background-color: transparent;
fill: var(--fill-tertiary);
}
@each $pane, $color in $item-pane-sections {
&[data-pane="#{$pane}"] {
list-style-image: url("chrome://zotero/skin/itempane/20/#{$pane}.svg");
fill: $color;
stroke: $color;
}
}
}
}

View file

@ -4,6 +4,10 @@ notes-box, related-box {
display: flex;
padding-left: 10px;
align-items: center;
@include comfortable {
padding-block: 2px;
}
label {
margin-right: 5px;

View file

@ -0,0 +1,36 @@
pane-header {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 6px 8px 0 8px;
.head {
display: flex;
align-self: stretch;
gap: 4px;
padding-bottom: 6px;
border-bottom: 1px solid var(--fill-quinary);
}
.title {
align-self: center;
margin-top: calc(0px - var(--editable-text-padding-block));
padding: 1px 4px;
flex: 1 1 0;
font-weight: 590;
line-height: 1.333;
editable-text {
flex: 1;
}
}
.menu-button {
align-self: start;
}
.menu-button toolbarbutton {
list-style-image: icon-url('locate.svg');
}
}

View file

@ -60,4 +60,4 @@
--material-border50: 1px solid var(--color-border50);
--material-panedivider: 1px solid var(--color-panedivider);
}
}
}

View file

@ -179,10 +179,7 @@ describe("Item pane", function () {
await note2.save();
});
var tabs = doc.getElementById('zotero-editpane-tabs');
var notesTab = doc.getElementById('zotero-editpane-notes-tab');
var grid = doc.querySelector('#zotero-editpane-notes #notes-grid');
tabs.selectedItem = notesTab;
// Wait for note list to update
do {
yield Zotero.Promise.delay(1);
@ -219,10 +216,7 @@ describe("Item pane", function () {
await note2.save();
});
var tabs = doc.getElementById('zotero-editpane-tabs');
var notesTab = doc.getElementById('zotero-editpane-notes-tab');
var grid = doc.querySelector('#zotero-editpane-notes #notes-grid');
tabs.selectedItem = notesTab;
// Wait for note list to update
do {
yield Zotero.Promise.delay(1);
@ -260,10 +254,7 @@ describe("Item pane", function () {
await note2.save();
});
var tabs = doc.getElementById('zotero-editpane-tabs');
var notesTab = doc.getElementById('zotero-editpane-notes-tab');
var grid = doc.querySelector('#zotero-editpane-notes #notes-grid');
tabs.selectedItem = notesTab;
// Wait for note list to update
do {
yield Zotero.Promise.delay(1);

View file

@ -22,9 +22,6 @@ describe("Related Box", function () {
item2.addRelatedItem(item1);
await item2.saveTx();
// Select the Related pane
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 3;
var relatedbox = doc.getElementById('zotero-editpane-related');
// Wait for relations list to populate
@ -56,9 +53,6 @@ describe("Related Box", function () {
item2.addRelatedItem(item1);
await item2.saveTx();
// Select the Related pane
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 3;
var relatedbox = doc.getElementById('zotero-editpane-related');
// Wait for relations list to populate
@ -83,9 +77,6 @@ describe("Related Box", function () {
var item1 = yield createDataObject('item');
var item2 = yield createDataObject('item');
// Select the Related pane
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 3;
var relatedbox = doc.getElementById('zotero-editpane-related');
assert.lengthOf(relatedbox.querySelectorAll('#related-grid div'), 0);
@ -136,9 +127,6 @@ describe("Related Box", function () {
item2.addRelatedItem(item1);
yield item2.saveTx();
// Select the Related pane
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 3;
var relatedbox = doc.getElementById('zotero-editpane-related');
// Wait for relations list to populate

View file

@ -20,13 +20,8 @@ describe("Item Tags Box", function () {
var tag = Zotero.Utilities.randomString();
var newTag = Zotero.Utilities.randomString();
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 0;
var item = await createDataObject('item', { tags: [{ tag }] });
tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2;
var tagsbox = doc.querySelector('tags-box');
var rows = tagsbox.querySelectorAll('li');
assert.equal(rows.length, 1);
@ -60,9 +55,6 @@ describe("Item Tags Box", function () {
var tag = Zotero.Utilities.randomString();
var newTag = Zotero.Utilities.randomString();
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 0;
var item = createUnsavedDataObject('item');
item.setTags([
{
@ -71,8 +63,6 @@ describe("Item Tags Box", function () {
]);
yield item.saveTx();
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2;
var tagsbox = doc.querySelector('tags-box');
var rows = tagsbox.querySelectorAll('li');
assert.equal(rows.length, 1);
@ -89,8 +79,6 @@ describe("Item Tags Box", function () {
var libraryID = Zotero.Libraries.userLibraryID;
var tag = Zotero.Utilities.randomString();
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 0;
yield Zotero.Tags.setColor(libraryID, tag, "#990000");
var item = createUnsavedDataObject('item');
@ -104,8 +92,6 @@ describe("Item Tags Box", function () {
]);
yield item.saveTx();
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2;
var tagsbox = doc.querySelector('tags-box');
var rows = tagsbox.querySelectorAll('li');
@ -124,9 +110,6 @@ describe("Item Tags Box", function () {
it("should update when a tag is removed from the library", function* () {
var tag = Zotero.Utilities.randomString();
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 0;
var item = createUnsavedDataObject('item');
item.setTags([
{
@ -135,8 +118,6 @@ describe("Item Tags Box", function () {
]);
yield item.saveTx();
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2;
var tagsbox = doc.querySelector('tags-box');
var rows = tagsbox.querySelectorAll('li');
assert.equal(rows.length, 1);