After new item creation, focus title in itemBox (#4113)

When item is created manually, title field in itemBox
will be focused instead of the title in the itemPane as before.
If the itemBox is collapsed, it will be opened.

Added 'open' setter to item pane section for brevity

Fixes #4111
This commit is contained in:
Bogdan Abaev 2024-05-10 17:46:31 -04:00 committed by Dan Stillman
parent c01b3ae270
commit be1c890051
4 changed files with 21 additions and 15 deletions

View file

@ -755,13 +755,12 @@
// Place, in order of preference, after title, after type, // Place, in order of preference, after title, after type,
// or at beginning // or at beginning
var titleFieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(this.item.itemTypeID, 'title'); var field = this.getTitleField();
var field = this._infoTable.querySelector(`[fieldname="${Zotero.ItemFields.getName(titleFieldID)}"]`);
if (!field) { if (!field) {
field = this._infoTable.querySelector('[fieldName="itemType"]'); field = this._infoTable.querySelector('[fieldName="itemType"]');
} }
if (field) { if (field) {
this._beforeRow = field.parentNode.nextSibling; this._beforeRow = field.closest(".meta-row").nextSibling;
} }
else { else {
this._beforeRow = this._infoTable.firstChild; this._beforeRow = this._infoTable.firstChild;
@ -2289,6 +2288,11 @@
return this._focusNextField(field.getAttribute('ztabindex')); return this._focusNextField(field.getAttribute('ztabindex'));
} }
getTitleField() {
var titleFieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(this.item.itemTypeID, 'title');
return this._infoTable.querySelector(`editable-text[fieldname="${Zotero.ItemFields.getName(titleFieldID)}"]`);
}
getFocusedTextArea() { getFocusedTextArea() {
let input = this._infoTable.querySelector('input[data-initial-value], textarea[data-initial-value]'); let input = this._infoTable.querySelector('input[data-initial-value], textarea[data-initial-value]');
if (input) { if (input) {

View file

@ -56,6 +56,12 @@ class ItemPaneSectionElementBase extends XULElementBase {
return this._section?.open || false; return this._section?.open || false;
} }
set open(val) {
if (this._section) {
this._section.open = val;
}
}
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
if (!this.render && !this.asyncRender) { if (!this.render && !this.asyncRender) {

View file

@ -1305,11 +1305,8 @@ var ZoteroPane = new function()
var type = mru ? mru.split(',')[0] : 'book'; var type = mru ? mru.split(',')[0] : 'book';
await ZoteroPane.newItem(Zotero.ItemTypes.getID(type)); await ZoteroPane.newItem(Zotero.ItemTypes.getID(type));
let itemBox = document.getElementById('zotero-editpane-item-box'); let itemBox = document.getElementById('zotero-editpane-item-box');
// If the info pane is collapsed, focus the title in the header // Ensure itemBox is opened
if (!itemBox.open) { itemBox.open = true;
document.querySelector("#zotero-item-pane-header editable-text").focus();
return;
}
var menu = itemBox.itemTypeMenu; var menu = itemBox.itemTypeMenu;
// If the new item's type is changed immediately, update the MRU // If the new item's type is changed immediately, update the MRU
var handleTypeChange = function () { var handleTypeChange = function () {
@ -1320,9 +1317,6 @@ var ZoteroPane = new function()
var removeTypeChangeHandler = function () { var removeTypeChangeHandler = function () {
itemBox.removeHandler('itemtypechange', handleTypeChange); itemBox.removeHandler('itemtypechange', handleTypeChange);
itemBox.itemTypeMenu.firstChild.removeEventListener('popuphiding', removeTypeChangeHandler); itemBox.itemTypeMenu.firstChild.removeEventListener('popuphiding', removeTypeChangeHandler);
// Focus the title field after menu closes
let title = document.querySelector("#zotero-item-pane-header").querySelector("editable-text");
title.focus();
}; };
itemBox.addHandler('itemtypechange', handleTypeChange); itemBox.addHandler('itemtypechange', handleTypeChange);
itemBox.itemTypeMenu.firstChild.addEventListener('popuphiding', removeTypeChangeHandler); itemBox.itemTypeMenu.firstChild.addEventListener('popuphiding', removeTypeChangeHandler);
@ -1452,8 +1446,11 @@ var ZoteroPane = new function()
if (manual) { if (manual) {
// Update most-recently-used list for New Item menu // Update most-recently-used list for New Item menu
this.addItemTypeToNewItemTypeMRU(Zotero.ItemTypes.getName(typeID)); this.addItemTypeToNewItemTypeMRU(Zotero.ItemTypes.getName(typeID));
let itemBox = ZoteroPane.itemPane.querySelector("item-box");
// Make sure the item box is opened
itemBox.open = true;
// Focus the title field // Focus the title field
document.getElementById('zotero-item-pane-header').querySelector("editable-text").focus(); itemBox.getTitleField().focus();
} }
return Zotero.Items.getAsync(itemID); return Zotero.Items.getAsync(itemID);

View file

@ -18,9 +18,8 @@ describe("ZoteroPane", function() {
describe("#newItem", function () { describe("#newItem", function () {
it("should create an item and focus the title field", function* () { it("should create an item and focus the title field", function* () {
yield zp.newItem(Zotero.ItemTypes.getID('book'), {}, null, true); yield zp.newItem(Zotero.ItemTypes.getID('book'), {}, null, true);
let title = doc.getElementById('zotero-item-pane-header').querySelector("editable-text"); assert.equal(doc.activeElement.closest("editable-text").id, "itembox-field-value-title");
assert.equal(doc.activeElement.getAttribute("aria-label"), title.getAttribute("aria-label")); doc.activeElement.blur();
title.blur();
yield Zotero.Promise.delay(1); yield Zotero.Promise.delay(1);
}) })