From 15d5dcaaee70441b9d05e9167e6c52ba01366045 Mon Sep 17 00:00:00 2001 From: Bogdan Abaev Date: Wed, 31 Jan 2024 13:13:48 -0500 Subject: [PATCH] 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 --- .../content/zotero/elements/editableText.js | 2 +- chrome/content/zotero/elements/itemBox.js | 99 +++++-------------- 2 files changed, 26 insertions(+), 75 deletions(-) diff --git a/chrome/content/zotero/elements/editableText.js b/chrome/content/zotero/elements/editableText.js index cbeba26753..e19b94df2b 100644 --- a/chrome/content/zotero/elements/editableText.js +++ b/chrome/content/zotero/elements/editableText.js @@ -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)`; diff --git a/chrome/content/zotero/elements/itemBox.js b/chrome/content/zotero/elements/itemBox.js index 9948b13d62..8366887e11 100644 --- a/chrome/content/zotero/elements/itemBox.js +++ b/chrome/content/zotero/elements/itemBox.js @@ -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