itemBox creator names fixes

- Instead of setting default name as the value of the field when a
creator name is empty, set the default names as a placeholder so that
it shows up only when the field is empty.
- Have the creator options show up before the creator is saved so that
the mode can be switches before saving the creator.
- Re-do of capitalizeCreatorName to not break when one of the names is focused.

Fixes: #3610
This commit is contained in:
Bogdan Abaev 2024-01-31 13:13:48 -05:00 committed by Dan Stillman
parent 147ed028df
commit 15d5dcaaee
2 changed files with 26 additions and 75 deletions

View file

@ -153,7 +153,7 @@
sizeToContent = () => {
// Add a temp span, fetch its width with current paddings and set max-width based on that
let span = document.createElement("span");
span.innerText = this.value;
span.innerText = this.value || this.placeholder;
this.append(span);
let size = span.getBoundingClientRect();
this.style['max-width'] = `calc(${size.width}px)`;

View file

@ -135,13 +135,7 @@
var index = parseInt(typeBox.getAttribute('fieldname').split('-')[1]);
var item = this.item;
var exists = item.hasCreatorAt(index);
if (exists) {
var fieldMode = item.getCreator(index).name !== undefined ? 1 : 0;
}
var hideTransforms = !exists || !!fieldMode;
if (hideTransforms) {
event.preventDefault();
}
var fieldMode = row.querySelector("[fieldMode]").getAttribute("fieldMode");
var moreCreators = item.numCreators() > index + 1;
@ -149,7 +143,10 @@
var hideMoveUp = !exists || index == 0;
var hideMoveDown = !exists || !moreCreators;
var hideMoveSep = hideMoveUp && hideMoveDown;
var hideNameSwap = fieldMode == '1' || !exists;
this._id('creator-transform-swap-names').hidden = hideNameSwap;
this._id('creator-transform-capitalize').disabled = !this.canCapitalizeCreatorName(row);
this._id('zotero-creator-move-sep').setAttribute('hidden', hideMoveSep);
this._id('zotero-creator-move-to-top').setAttribute('hidden', hideMoveToTop);
this._id('zotero-creator-move-up').setAttribute('hidden', hideMoveUp);
@ -877,6 +874,10 @@
this.querySelectorAll("[ztabindex]").forEach((node) =>{
node.setAttribute("tabindex", 0);
});
// Make sure that any opened popup closes
this.querySelectorAll("menupopup").forEach((popup) => {
popup.hidePopup();
});
}
addItemTypeMenu() {
@ -954,21 +955,6 @@
lastName = creatorData.lastName;
}
// Sub in placeholder text for empty fields
if (fieldMode == 1) {
if (lastName === "") {
lastName = this._defaultFullName;
}
}
else {
if (firstName === "") {
firstName = this._defaultFirstName;
}
if (lastName === "") {
lastName = this._defaultLastName;
}
}
// Use the first entry in the drop-down for the default type if none specified
var typeID = creatorTypeIDOrName
? Zotero.CreatorTypes.getID(creatorTypeIDOrName)
@ -1037,6 +1023,7 @@
)
);
lastNameElem.placeholder = this._defaultLastName;
fieldName = 'creator-' + rowIndex + '-firstName';
var firstNameElem = firstlast.appendChild(
this.createValueElement(
@ -1045,6 +1032,7 @@
++this._ztabindex
)
);
firstNameElem.placeholder = this._defaultFirstName;
if (fieldMode > 0) {
firstlast.lastChild.hidden = true;
}
@ -1081,12 +1069,9 @@
}
rowData.appendChild(addButton);
let realName = (firstName && firstName != this._defaultFirstName)
|| (lastName && lastName != this._defaultLastName);
// Options button that opens creator transform menu
let optionsButton = document.createXULElement("toolbarbutton");
if (!realName || !this.editable) {
if (!this.editable) {
optionsButton.style.visibility = "hidden";
this.disableButton(optionsButton);
}
@ -1099,8 +1084,6 @@
let menupopup = this._id('zotero-creator-transform-menu');
Zotero.Utilities.Internal.updateEditContextMenu(menupopup, e.target.closest('input'));
this._id('creator-transform-swap-names').hidden = fieldMode > 0;
this._id('creator-transform-capitalize').disabled = !this.canCapitalizeCreatorName(rowData.parentNode);
this.handlePopupOpening(e, menupopup);
};
rowData.appendChild(optionsButton);
@ -1264,6 +1247,7 @@
if (fieldMode == 1) {
creatorNameBox.setAttribute('switch-mode-label', Zotero.getString('pane.item.switchFieldMode.two'));
lastName.setAttribute('fieldMode', '1');
lastName.placeholder = this._defaultFullName;
delete lastName.style.width;
delete lastName.style.maxWidth;
@ -1276,15 +1260,13 @@
if (!initial) {
var first = firstName.value;
if (first && first != this._defaultFirstName) {
if (first) {
let last = lastName.value;
lastName.value = first + ' ' + last;
}
}
if (lastName.value == this._defaultLastName) {
lastName.value = this._defaultFullName;
}
// Clear first name value after it was moved to the full name field
firstName.value = "";
// If one of the creator fields is open, leave it open after swap
let activeField = this.getFocusedTextArea();
@ -1298,6 +1280,7 @@
creatorNameBox.setAttribute('switch-mode-label', Zotero.getString('pane.item.switchFieldMode.one'));
lastName.setAttribute('fieldMode', '0');
lastName.placeholder = this._defaultLastName;
// Add firstname field to tabindex
tab = parseInt(lastName.getAttribute('ztabindex'));
firstName.setAttribute('ztabindex', tab + 1);
@ -1305,7 +1288,7 @@
if (!initial) {
// Move all but last word to first name field and show it
let last = lastName.value;
if (last && last != this._defaultFullName) {
if (last) {
var lastNameRE = /(.*?)[ ]*([^ ]+[ ]*)$/;
var parts = lastNameRE.exec(last);
if (parts[2] && parts[2] != last) {
@ -1315,14 +1298,6 @@
}
}
if (!firstName.value) {
firstName.value = this._defaultFirstName;
}
if (lastName.value == this._defaultFullName) {
lastName.value = this._defaultLastName;
}
firstName.hidden = false;
}
@ -1335,6 +1310,8 @@
if (!initial) {
var fields = this.getCreatorFields(row);
fields.fieldMode = fieldMode;
firstName.sizeToContent();
lastName.sizeToContent();
this.modifyCreator(rowIndex, fields);
if (this.saveOnEdit) {
let activeField = this.getFocusedTextArea();
@ -1962,7 +1939,7 @@
}
async hideEditor(textbox) {
if (this.ignoreBlur) {
if (this.ignoreBlur || !textbox) {
return;
}
// Handle cases where creator autocomplete doesn't trigger
@ -1998,23 +1975,6 @@
otherFields[creatorField] = value;
this.modifyCreator(creatorIndex, otherFields);
var val = this.item.getCreator(creatorIndex);
val = val ? val[creatorField] : null;
if (!val) {
// Reset to '(first)'/'(last)'/'(name)'
if (creatorField == 'lastName') {
val = otherFields.fieldMode
? this._defaultFullName
: this._defaultLastName;
}
else if (creatorField == 'firstName') {
val = this._defaultFirstName;
}
textbox.value = val;
}
if (Zotero.ItemTypes.getName(this.item.itemTypeID) === "bookSection") {
this._showCreatorTypeGuidance = true;
}
@ -2128,16 +2088,6 @@
fieldMode: fieldMode ? parseInt(fieldMode) : 0,
creatorTypeID: parseInt(typeID),
};
// Ignore '(first)'
if (fields.fieldMode == 1 || fields.firstName == this._defaultFirstName) {
fields.firstName = '';
}
// Ignore '(last)' or '(name)'
if (fields.lastName == this._defaultFullName
|| fields.lastName == this._defaultLastName) {
fields.lastName = '';
}
return fields;
}
@ -2193,11 +2143,12 @@
*/
async capitalizeCreatorName(_event) {
var row = document.popupNode.closest('.meta-row');
var typeBox = row.querySelector('.creator-type-label').parentNode;
var creatorIndex = parseInt(typeBox.getAttribute('fieldname').split('-')[1]);
let label = row.querySelector('.meta-label');
var creatorIndex = parseInt(label.getAttribute('fieldname').split('-')[1]);
let [lastName, firstName] = [...row.querySelectorAll("editable-text")];
lastName.value = Zotero.Utilities.capitalizeName(lastName.value);
firstName.value = Zotero.Utilities.capitalizeName(firstName.value);
var fields = this.getCreatorFields(row);
fields.firstName = fields.firstName && Zotero.Utilities.capitalizeName(fields.firstName);
fields.lastName = fields.lastName && Zotero.Utilities.capitalizeName(fields.lastName);
this.modifyCreator(creatorIndex, fields);
if (this.saveOnEdit) {
// If a field is open, blur it, which will trigger a save and cause