From 878f4e3bb35d242898374f2bc1efecf2811fa00b Mon Sep 17 00:00:00 2001 From: abaevbog Date: Mon, 2 Nov 2026 11:51:11 -0800 Subject: [PATCH] citation dlg: fix stuck focus on preview loading (#6085) Do not wait for preview to load cited items if io is not ready - show a loading message instead. Waiting blocks the focus from landing back in bubble-input when an item is added for the user to be able to keep typing. https://forums.zotero.org/discussion/134552/zotero-10-broke-keyboard-navigation-of-citation-dialog --- chrome/content/zotero/integration/citationDialog.js | 12 ++++++++++++ .../content/zotero/integration/citationDialog.xhtml | 1 + chrome/locale/en-US/zotero/integration.ftl | 1 + scss/components/_citationDialog.scss | 2 +- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/chrome/content/zotero/integration/citationDialog.js b/chrome/content/zotero/integration/citationDialog.js index 9972e3b36a..34c7f6e977 100644 --- a/chrome/content/zotero/integration/citationDialog.js +++ b/chrome/content/zotero/integration/citationDialog.js @@ -140,6 +140,8 @@ async function onLoad() { if (accepted) return; Zotero.debug("Citation Dialog: io loaded cited data"); await SearchHandler.refreshCitedItems(); + // Replace the loading message with the actual preview before refreshing the list + await CitationPreview.render(); currentLayout.refreshItemsList({ retainItemsState: true }); if (_id("keepSorted").checked) { IOManager._resortItems(); @@ -2089,6 +2091,7 @@ const CitationPreview = { if (isEmpty) { _id("citation-preview-content").innerHTML = ""; _id("citation-preview-error").hidden = true; + _id("citation-preview-loading").hidden = true; } // The toggle button is hidden when there's no preview and is restored to its last // state when the preview pane appears @@ -2104,6 +2107,14 @@ const CitationPreview = { if (!DIALOG_STATE.isCitingItems()) return; if (!CitationDataManager.items.length) return; if (!io.preview) return; + // io.preview() waits for all cited data to be loaded, so show a loading + // message until then. The preview is rendered once ioReadyPromise resolves. + if (!ioIsReady) { + _id("citation-preview-content").hidden = true; + _id("citation-preview-error").hidden = true; + _id("citation-preview-loading").hidden = false; + return; + } CitationDataManager.updateCitationObject(); let html; @@ -2118,6 +2129,7 @@ const CitationPreview = { // Re-check after the await in case the user cleared items if (!CitationDataManager.items.length) return; let errored = html === undefined; + _id("citation-preview-loading").hidden = true; _id("citation-preview-content").hidden = errored; _id("citation-preview-error").hidden = !errored; _id("citation-preview-content").innerHTML = errored ? "" : html; diff --git a/chrome/content/zotero/integration/citationDialog.xhtml b/chrome/content/zotero/integration/citationDialog.xhtml index 6cd90058a6..fdc07d5237 100644 --- a/chrome/content/zotero/integration/citationDialog.xhtml +++ b/chrome/content/zotero/integration/citationDialog.xhtml @@ -112,6 +112,7 @@
+
diff --git a/chrome/locale/en-US/zotero/integration.ftl b/chrome/locale/en-US/zotero/integration.ftl index cd1142ae5c..42fca34caf 100644 --- a/chrome/locale/en-US/zotero/integration.ftl +++ b/chrome/locale/en-US/zotero/integration.ftl @@ -51,6 +51,7 @@ integration-citationDialog-lib-message-annotations = { $search -> } integration-citationDialog-settings-keepSorted = Keep sources sorted integration-citationDialog-preview-error = Preview unavailable +integration-citationDialog-preview-loading = Loading preview… integration-citationDialog-btn-displayPreview = .title = Display citation preview integration-citationDialog-btn-settings = diff --git a/scss/components/_citationDialog.scss b/scss/components/_citationDialog.scss index 9abef5df43..0c7f803823 100644 --- a/scss/components/_citationDialog.scss +++ b/scss/components/_citationDialog.scss @@ -587,7 +587,7 @@ font-size: 1.1rem; } - #citation-preview-error { + #citation-preview-error, #citation-preview-loading { padding-top: 2px; color: var(--fill-secondary); font-family: $font-family-base;