diff --git a/docs/backend_api/BAttachment.html b/docs/backend_api/BAttachment.html
index 26cf922cb..42441d846 100644
--- a/docs/backend_api/BAttachment.html
+++ b/docs/backend_api/BAttachment.html
@@ -1388,7 +1388,7 @@ larger amounts of data and generally not accessible to the user.
Source:
@@ -1770,7 +1770,7 @@ larger amounts of data and generally not accessible to the user.
Source:
@@ -2815,7 +2815,7 @@ This is a low-level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/becca_entities_battachment.js.html b/docs/backend_api/becca_entities_battachment.js.html
index 9e9b5f380..676ebd455 100644
--- a/docs/backend_api/becca_entities_battachment.js.html
+++ b/docs/backend_api/becca_entities_battachment.js.html
@@ -132,7 +132,12 @@ class BAttachment extends AbstractBeccaEntity {
}
decrypt() {
- if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
+ if (!this.isProtected || !this.attachmentId) {
+ this.isDecrypted = true;
+ return;
+ }
+
+ if (!this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
try {
this.title = protectedSessionService.decryptString(this.title);
this.isDecrypted = true;
diff --git a/docs/frontend_api/FrontendScriptApi.html b/docs/frontend_api/FrontendScriptApi.html
index 0d31af9d8..dfa5d1e70 100644
--- a/docs/frontend_api/FrontendScriptApi.html
+++ b/docs/frontend_api/FrontendScriptApi.html
@@ -1738,7 +1738,7 @@ See https://day.js.org for documentation
Source:
@@ -2469,7 +2469,7 @@ See https://day.js.org for documentation
Source:
@@ -2624,7 +2624,7 @@ See https://day.js.org for documentation
Source:
@@ -2682,6 +2682,112 @@ See https://day.js.org for documentation
+ getActiveContext() → {NoteContext}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+ - returns active context (split)
+
+
+
+
+
+ -
+ Type
+
+ -
+
+NoteContext
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
getActiveContextCodeEditor() → {Promise.<CodeMirror>}
@@ -2734,7 +2840,7 @@ See https://day.js.org for documentation
Source:
@@ -2869,7 +2975,7 @@ See https://day.js.org for documentation
- active note (loaded into right pane)
+ active note (loaded into center pane)
@@ -2946,7 +3052,7 @@ See https://day.js.org for documentation
Source:
@@ -3056,7 +3162,7 @@ See https://day.js.org for documentation
Source:
@@ -3114,6 +3220,112 @@ See https://day.js.org for documentation
+ getActiveMainContext() → {NoteContext}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+ - returns active main context (first split in a tab, represents the tab as a whole)
+
+
+
+
+
+ -
+ Type
+
+ -
+
+NoteContext
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3167,7 +3379,7 @@ implementation of actual widget type.
Source:
@@ -3322,7 +3534,7 @@ implementation of actual widget type.
Source:
@@ -3477,7 +3689,7 @@ implementation of actual widget type.
Source:
@@ -3638,6 +3850,112 @@ if some action needs to happen on only one specific instance.
+ getMainNoteContexts() → {Array.<NoteContext>}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+ - returns all main contexts representing tabs
+
+
+
+
+
+ -
+ Type
+
+ -
+
+Array.<NoteContext>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
getMonthNote(month) → {Promise.<FNote>}
@@ -3739,7 +4057,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3949,6 +4267,112 @@ if some action needs to happen on only one specific instance.
+ getNoteContexts() → {Array.<NoteContext>}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+ - returns all note contexts (splits) in all tabs
+
+
+
+
+
+ -
+ Type
+
+ -
+
+Array.<NoteContext>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
getNotes(noteIds, silentNotFoundErroropt) → {Promise.<Array.<FNote>>}
@@ -4202,7 +4626,7 @@ otherwise (by e.g. createLink())
Source:
@@ -4357,7 +4781,7 @@ otherwise (by e.g. createLink())
Source:
@@ -4512,7 +4936,7 @@ otherwise (by e.g. createLink())
Source:
@@ -4662,7 +5086,7 @@ otherwise (by e.g. createLink())
Source:
@@ -5347,7 +5771,7 @@ otherwise (by e.g. createLink())
Source:
@@ -5521,7 +5945,7 @@ otherwise (by e.g. createLink())
Source:
@@ -5676,7 +6100,7 @@ otherwise (by e.g. createLink())
Source:
@@ -5830,7 +6254,7 @@ otherwise (by e.g. createLink())
Source:
@@ -6620,7 +7044,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -6771,7 +7195,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -7475,7 +7899,7 @@ Typical use case is when a new note has been created, we should wait until it is
Source:
diff --git a/docs/frontend_api/services_frontend_script_api.js.html b/docs/frontend_api/services_frontend_script_api.js.html
index 22934874b..328ab4125 100644
--- a/docs/frontend_api/services_frontend_script_api.js.html
+++ b/docs/frontend_api/services_frontend_script_api.js.html
@@ -377,10 +377,34 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/**
* @method
- * @returns {FNote} active note (loaded into right pane)
+ * @returns {FNote} active note (loaded into center pane)
*/
this.getActiveContextNote = () => appContext.tabManager.getActiveContextNote();
+ /**
+ * @method
+ * @returns {NoteContext} - returns active context (split)
+ */
+ this.getActiveContext = () => appContext.tabManager.getActiveContext();
+
+ /**
+ * @method
+ * @returns {NoteContext} - returns active main context (first split in a tab, represents the tab as a whole)
+ */
+ this.getActiveMainContext = () => appContext.tabManager.getActiveMainContext();
+
+ /**
+ * @method
+ * @returns {NoteContext[]} - returns all note contexts (splits) in all tabs
+ */
+ this.getNoteContexts = () => appContext.tabManager.getNoteContexts();
+
+ /**
+ * @method
+ * @returns {NoteContext[]} - returns all main contexts representing tabs
+ */
+ this.getMainNoteContexts = () => appContext.tabManager.getMainNoteContexts();
+
/**
* See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for documentation on the returned instance.
*
diff --git a/src/public/app/components/note_context.js b/src/public/app/components/note_context.js
index 5dd0d7bc9..559e534bb 100644
--- a/src/public/app/components/note_context.js
+++ b/src/public/app/components/note_context.js
@@ -105,11 +105,24 @@ class NoteContext extends Component {
return appContext.tabManager.noteContexts.filter(nc => nc.ntxId === this.ntxId || nc.mainNtxId === this.ntxId);
}
+ /**
+ * A main context represents a tab and also the first split. Further splits are the children contexts of the main context.
+ * Imagine you have a tab with 3 splits, each showing notes A, B, C (in this order).
+ * In such a scenario, A context is the main context (also representing the tab as a whole), and B, C are the children
+ * of context A.
+ *
+ * @returns {boolean} true if the context is main (= tab)
+ */
isMainContext() {
// if null, then this is a main context
return !this.mainNtxId;
}
+ /**
+ * See docs for isMainContext() for better explanation.
+ *
+ * @returns {NoteContext}
+ */
getMainContext() {
if (this.mainNtxId) {
try {
diff --git a/src/public/app/components/root_command_executor.js b/src/public/app/components/root_command_executor.js
index 29c3aab1d..e8c7fc5b4 100644
--- a/src/public/app/components/root_command_executor.js
+++ b/src/public/app/components/root_command_executor.js
@@ -154,4 +154,24 @@ export default class RootCommandExecutor extends Component {
});
}
}
+
+ firstTabCommand() {this.#goToTab(1);}
+ secondTabCommand() {this.#goToTab(2);}
+ thirdTabCommand() {this.#goToTab(3);}
+ fourthTabCommand() {this.#goToTab(4);}
+ fifthTabCommand() {this.#goToTab(5);}
+ sixthTabCommand() {this.#goToTab(6);}
+ seventhTabCommand() {this.#goToTab(7);}
+ eigthTabCommand() {this.#goToTab(8);}
+ ninthTabCommand() {this.#goToTab(9);}
+ lastTabCommand() {this.#goToTab(Number.POSITIVE_INFINITY);}
+
+ #goToTab(tabNumber) {
+ const mainNoteContexts = appContext.tabManager.getMainNoteContexts();
+
+ const index = tabNumber === Number.POSITIVE_INFINITY ? mainNoteContexts.length - 1 : tabNumber - 1;
+ const tab = mainNoteContexts[index];
+
+ appContext.tabManager.activateNoteContext(tab.ntxId);
+ }
}
diff --git a/src/public/app/components/tab_manager.js b/src/public/app/components/tab_manager.js
index feacc23d4..57c9c8c5c 100644
--- a/src/public/app/components/tab_manager.js
+++ b/src/public/app/components/tab_manager.js
@@ -173,7 +173,10 @@ export default class TabManager extends Component {
return this.noteContexts;
}
- /** @returns {NoteContext[]} */
+ /**
+ * Main context is essentially a tab (children are splits), so this returns tabs.
+ * @returns {NoteContext[]}
+ */
getMainNoteContexts() {
return this.noteContexts.filter(nc => nc.isMainContext());
}
@@ -189,14 +192,22 @@ export default class TabManager extends Component {
return noteContext;
}
- /** @returns {NoteContext} */
+ /**
+ * Get active context which represents the visible split with focus. Active context can, but doesn't have to be "main".
+ *
+ * @returns {NoteContext}
+ */
getActiveContext() {
return this.activeNtxId
? this.getNoteContextById(this.activeNtxId)
: null;
}
- /** @returns {NoteContext} */
+ /**
+ * Get active main context which corresponds to the active tab.
+ *
+ * @returns {NoteContext}
+ */
getActiveMainContext() {
return this.activeNtxId
? this.getNoteContextById(this.activeNtxId).getMainContext()
diff --git a/src/public/app/services/frontend_script_api.js b/src/public/app/services/frontend_script_api.js
index 6c9ef8636..c5a7084f9 100644
--- a/src/public/app/services/frontend_script_api.js
+++ b/src/public/app/services/frontend_script_api.js
@@ -349,10 +349,34 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/**
* @method
- * @returns {FNote} active note (loaded into right pane)
+ * @returns {FNote} active note (loaded into center pane)
*/
this.getActiveContextNote = () => appContext.tabManager.getActiveContextNote();
+ /**
+ * @method
+ * @returns {NoteContext} - returns active context (split)
+ */
+ this.getActiveContext = () => appContext.tabManager.getActiveContext();
+
+ /**
+ * @method
+ * @returns {NoteContext} - returns active main context (first split in a tab, represents the tab as a whole)
+ */
+ this.getActiveMainContext = () => appContext.tabManager.getActiveMainContext();
+
+ /**
+ * @method
+ * @returns {NoteContext[]} - returns all note contexts (splits) in all tabs
+ */
+ this.getNoteContexts = () => appContext.tabManager.getNoteContexts();
+
+ /**
+ * @method
+ * @returns {NoteContext[]} - returns all main contexts representing tabs
+ */
+ this.getMainNoteContexts = () => appContext.tabManager.getMainNoteContexts();
+
/**
* See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for documentation on the returned instance.
*
diff --git a/src/public/app/widgets/tab_row.js b/src/public/app/widgets/tab_row.js
index 4172052d5..288dd0229 100644
--- a/src/public/app/widgets/tab_row.js
+++ b/src/public/app/widgets/tab_row.js
@@ -267,28 +267,8 @@ export default class TabRowWidget extends BasicWidget {
}
});
});
-
- keyboardActionService.setupActionsForElement('window', $(document), this);
}
- goToTab(tabNumber) {
- const index = tabNumber === Number.POSITIVE_INFINITY ? this.tabEls.length - 1 : tabNumber - 1;
- const tab = this.tabEls[index];
- if (!tab) return;
- appContext.tabManager.activateNoteContext(tab.getAttribute('data-ntx-id'));
- }
-
- firstTabCommand() {this.goToTab(1);}
- secondTabCommand() {this.goToTab(2);}
- thirdTabCommand() {this.goToTab(3);}
- fourthTabCommand() {this.goToTab(4);}
- fifthTabCommand() {this.goToTab(5);}
- sixthTabCommand() {this.goToTab(6);}
- seventhTabCommand() {this.goToTab(7);}
- eigthTabCommand() {this.goToTab(8);}
- ninthTabCommand() {this.goToTab(9);}
- lastTabCommand() {this.goToTab(Number.POSITIVE_INFINITY);}
-
setupStyle() {
this.$style = $("