diff --git a/chrome/content/zotero/bindings/noteeditor.xml b/chrome/content/zotero/bindings/noteeditor.xml
index 8dc4d400cc..f5b98dea63 100644
--- a/chrome/content/zotero/bindings/noteeditor.xml
+++ b/chrome/content/zotero/bindings/noteeditor.xml
@@ -353,15 +353,16 @@
{
- let n = 0;
- while (!this._editorInstance && n++ < 100) {
- await Zotero.Promise.delay(10);
- }
- await this._editorInstance._initPromise;
- this._iframe.focus();
try {
+ let n = 0;
+ while (!this._editorInstance && n++ < 100) {
+ await Zotero.Promise.delay(10);
+ }
+ await this._editorInstance._initPromise;
+ this._iframe.focus();
this._editorInstance._iframeWindow.document.querySelector('.toolbar-button-return').focus();
- } catch(e) {
+ }
+ catch (e) {
}
})();
]]>
diff --git a/chrome/content/zotero/contextPane.js b/chrome/content/zotero/contextPane.js
index 24d6b5493d..b355a6facb 100644
--- a/chrome/content/zotero/contextPane.js
+++ b/chrome/content/zotero/contextPane.js
@@ -51,7 +51,10 @@ var ZoteroContextPane = new function () {
var _itemContexts = [];
var _notesContexts = [];
-
+
+ var _globalDeckIndex = [];
+ var _preventGlobalDeckChange = false;
+
// Using attribute instead of property to set 'selectedIndex'
// is more reliable
@@ -176,6 +179,20 @@ var ZoteroContextPane = new function () {
if (Zotero_Tabs.deck.children.length == 1) {
_notesContexts.forEach(x => x.notesListRef.current.setExpanded(false));
}
+ // Close tab specific notes if tab id no longer exists, but
+ // do that only when unloaded tab is reloaded
+ setTimeout(() => {
+ var contextNodes = Array.from(_notesPaneDeck.children);
+ for (let contextNode of contextNodes) {
+ var nodes = Array.from(contextNode.children[2].children);
+ for (let node of nodes) {
+ var tabID = node.getAttribute('data-tab-id');
+ if (!document.getElementById(tabID)) {
+ node.remove();
+ }
+ }
+ }
+ });
}
else if (action == 'select') {
// It seems that changing `hidden` or `collapsed` values might
@@ -188,6 +205,14 @@ var ZoteroContextPane = new function () {
_tabCover.hidden = true;
}
else if (Zotero_Tabs.selectedType == 'reader') {
+ if (_panesDeck.selectedIndex == 1
+ && _notesPaneDeck.selectedPanel.selectedIndex != 2
+ && !_preventGlobalDeckChange) {
+ let libraryID = _notesPaneDeck.selectedPanel.getAttribute('data-library-id');
+ _globalDeckIndex[libraryID] = _notesPaneDeck.selectedPanel.selectedIndex;
+ }
+ _preventGlobalDeckChange = false;
+
var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
if (reader) {
_tabCover.hidden = false;
@@ -207,6 +232,17 @@ var ZoteroContextPane = new function () {
var notesContext = _getNotesContext(attachment.libraryID);
notesContext.updateFromCache();
}
+
+ let tabNotesDeck = _notesPaneDeck.selectedPanel.children[2];
+ let selectedIndex = Array.from(tabNotesDeck.children).findIndex(x => x.getAttribute('data-tab-id') == ids[0]);
+ if (selectedIndex != -1) {
+ tabNotesDeck.setAttribute('selectedIndex', selectedIndex);
+ _notesPaneDeck.selectedPanel.setAttribute('selectedIndex', 2);
+ }
+ else {
+ let libraryID = _notesPaneDeck.selectedPanel.getAttribute('data-library-id');
+ _notesPaneDeck.selectedPanel.setAttribute('selectedIndex', _globalDeckIndex[libraryID]);
+ }
})();
}
@@ -419,12 +455,17 @@ var ZoteroContextPane = new function () {
editor.className = 'zotero-context-pane-pinned-note';
editor.setAttribute('flex', 1);
noteContainer.append(title, editor);
+
+ let tabNotesDeck = document.createElement('deck');
+ tabNotesDeck.className = 'zotero-context-pane-tab-notes-deck';
+ tabNotesDeck.setAttribute('flex', 1);
let contextNode = document.createElement('deck');
- contextNode.append(list, noteContainer);
+ contextNode.append(list, noteContainer, tabNotesDeck);
_notesPaneDeck.append(contextNode);
contextNode.className = 'context-node';
+ contextNode.setAttribute('data-library-id', libraryID);
contextNode.setAttribute('selectedIndex', 0);
editor.returnHandler = () => {
@@ -451,7 +492,7 @@ var ZoteroContextPane = new function () {
input.value = '';
_updateNotesList();
- _setPinnedNote(note.id);
+ _setPinnedNote(note);
}
function _createNote(child) {
@@ -465,10 +506,7 @@ var ZoteroContextPane = new function () {
}
item.parentID = attachment.parentID;
}
- editor.mode = 'edit';
- editor.item = item;
- editor.parentItem = null;
- editor.focus();
+ _setPinnedNote(item);
_updateAddToNote();
input.value = '';
@@ -674,7 +712,10 @@ var ZoteroContextPane = new function () {
{
- _setPinnedNote(id);
+ let item = Zotero.Items.get(id);
+ if (item) {
+ _setPinnedNote(item);
+ }
}}
onContextMenu={(id, event) => {
document.getElementById('context-pane-list-move-to-trash').setAttribute('disabled', readOnly);
@@ -729,19 +770,56 @@ var ZoteroContextPane = new function () {
return !Zotero.Libraries.get(libraryID).editable;
}
- function _setPinnedNote(itemID) {
- var item = Zotero.Items.get(itemID);
- if (!item) {
- return;
- }
+ function _setPinnedNote(item) {
var readOnly = _isLibraryReadOnly(item.libraryID);
var context = _getNotesContext(item.libraryID);
if (context) {
var { editor, node } = context;
- node.setAttribute('selectedIndex', 1);
- editor.mode = readOnly ? 'view' : 'edit';
- editor.item = item;
- editor.parentItem = null;
+
+ let isChild = false;
+ var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
+ if (reader) {
+ let attachment = Zotero.Items.get(reader.itemID);
+ if (attachment.parentItemID == item.parentItemID) {
+ isChild = true;
+ }
+ }
+
+ var tabNotesDeck = _notesPaneDeck.selectedPanel.children[2];
+ if (isChild) {
+ var vbox = document.createElement('vbox');
+ vbox.setAttribute('data-tab-id', Zotero_Tabs.selectedID);
+ vbox.style.display = 'flex';
+
+ editor = document.createElement('zoteronoteeditor');
+ editor.style.display = 'flex';
+ editor.style.width = '100%';
+ vbox.append(editor);
+
+ tabNotesDeck.append(vbox);
+
+ editor.mode = readOnly ? 'view' : 'edit';
+ editor.item = item;
+ editor.parentItem = null;
+ editor.returnHandler = () => {
+ _panesDeck.setAttribute('selectedIndex', 1);
+ _notesPaneDeck.selectedPanel.setAttribute('selectedIndex', 0);
+ vbox.remove();
+ _updateAddToNote();
+ _preventGlobalDeckChange = true;
+ };
+
+ _notesPaneDeck.selectedPanel.setAttribute('selectedIndex', 2);
+ tabNotesDeck.setAttribute('selectedIndex', tabNotesDeck.children.length - 1);
+ }
+ else {
+ node.setAttribute('selectedIndex', 1);
+ editor.mode = readOnly ? 'view' : 'edit';
+ editor.item = item;
+ editor.parentItem = null;
+ }
+
+ editor.focus();
node.querySelector('.zotero-context-pane-editor-parent-line').innerHTML = '';
var parentItem = item.parentItem;
diff --git a/chrome/content/zotero/tabs.js b/chrome/content/zotero/tabs.js
index 12878a7cb9..b9e107b518 100644
--- a/chrome/content/zotero/tabs.js
+++ b/chrome/content/zotero/tabs.js
@@ -152,7 +152,7 @@ var Zotero_Tabs = new function () {
* @param {Function} onClose
* @return {{ id: string, container: XULElement}} id - tab id, container - a new tab container created in the deck
*/
- this.add = function ({ type, data, title, index, select, onClose }) {
+ this.add = function ({ id, type, data, title, index, select, onClose }) {
if (typeof type != 'string') {
}
if (typeof title != 'string') {
@@ -164,7 +164,7 @@ var Zotero_Tabs = new function () {
if (onClose !== undefined && typeof onClose != 'function') {
throw new Error(`'onClose' should be a function (was ${typeof onClose})`);
}
- var id = 'tab-' + Zotero.Utilities.randomString();
+ id = id || 'tab-' + Zotero.Utilities.randomString();
var container = document.createElement('vbox');
container.id = id;
this.deck.appendChild(container);
@@ -251,7 +251,7 @@ var Zotero_Tabs = new function () {
closedIDs.push(id);
}
this._history.push(historyEntry);
- Zotero.Notifier.trigger('close', 'tab', [closedIDs]);
+ Zotero.Notifier.trigger('close', 'tab', [closedIDs], true);
this._update();
};
@@ -333,6 +333,7 @@ var Zotero_Tabs = new function () {
if (tab.type === 'reader-unloaded') {
this.close(tab.id);
Zotero.Reader.open(tab.data.itemID, null, {
+ tabID: tab.id,
title: tab.title,
tabIndex,
allowDuplicate: true
@@ -385,6 +386,7 @@ var Zotero_Tabs = new function () {
}
this.close(tab.id);
this.add({
+ id: tab.id,
type: 'reader-unloaded',
title: tab.title,
index: tabIndex,
diff --git a/chrome/content/zotero/xpcom/reader.js b/chrome/content/zotero/xpcom/reader.js
index d7734cafdd..2293492a56 100644
--- a/chrome/content/zotero/xpcom/reader.js
+++ b/chrome/content/zotero/xpcom/reader.js
@@ -1010,7 +1010,7 @@ class ReaderInstance {
}
class ReaderTab extends ReaderInstance {
- constructor({ itemID, title, sidebarWidth, sidebarOpen, bottomPlaceholderHeight, index, background }) {
+ constructor({ itemID, title, sidebarWidth, sidebarOpen, bottomPlaceholderHeight, index, tabID, background }) {
super();
this._itemID = itemID;
this._sidebarWidth = sidebarWidth;
@@ -1019,6 +1019,7 @@ class ReaderTab extends ReaderInstance {
this._showItemPaneToggle = true;
this._window = Services.wm.getMostRecentWindow('navigator:browser');
let { id, container } = this._window.Zotero_Tabs.add({
+ id: tabID,
type: 'reader',
title: title || '',
index,
@@ -1053,20 +1054,24 @@ class ReaderTab extends ReaderInstance {
// events in PDF reader iframe when mouse up happens over another iframe
// i.e. note-editor. There should be a better way to solve this
this._window.addEventListener('pointerup', (event) => {
- if (this._window.Zotero_Tabs.selectedID === this.tabID
- && this._iframeWindow
- && event.target
- && event.target.closest
- && !event.target.closest('#outerContainer')) {
- let evt = new this._iframeWindow.CustomEvent('mouseup', { bubbles: false });
- evt.clientX = event.clientX;
- evt.clientY = event.clientY;
- this._iframeWindow.dispatchEvent(evt);
+ try {
+ if (this._window.Zotero_Tabs.selectedID === this.tabID
+ && this._iframeWindow
+ && event.target
+ && event.target.closest
+ && !event.target.closest('#outerContainer')) {
+ let evt = new this._iframeWindow.CustomEvent('mouseup', { bubbles: false });
+ evt.clientX = event.clientX;
+ evt.clientY = event.clientY;
+ this._iframeWindow.dispatchEvent(evt);
- evt = new this._iframeWindow.CustomEvent('pointerup', { bubbles: false });
- evt.clientX = event.clientX;
- evt.clientY = event.clientY;
- this._iframeWindow.dispatchEvent(evt);
+ evt = new this._iframeWindow.CustomEvent('pointerup', { bubbles: false });
+ evt.clientX = event.clientX;
+ evt.clientY = event.clientY;
+ this._iframeWindow.dispatchEvent(evt);
+ }
+ }
+ catch(e) {
}
});
}
@@ -1355,7 +1360,7 @@ class Reader {
await this.open(item.id, location, options);
}
- async open(itemID, location, { title, tabIndex, openInBackground, openInWindow, allowDuplicate } = {}) {
+ async open(itemID, location, { title, tabIndex, tabID, openInBackground, openInWindow, allowDuplicate } = {}) {
this._loadSidebarState();
this.triggerAnnotationsImportCheck(itemID);
let reader;
@@ -1397,6 +1402,7 @@ class Reader {
itemID,
title,
index: tabIndex,
+ tabID,
background: openInBackground,
sidebarWidth: this._sidebarWidth,
sidebarOpen: this._sidebarOpen,