diff --git a/docs/backend_api/BackendScriptApi.html b/docs/backend_api/BackendScriptApi.html index d99d0c219..8e1204851 100644 --- a/docs/backend_api/BackendScriptApi.html +++ b/docs/backend_api/BackendScriptApi.html @@ -131,6 +131,78 @@ +

__private :Object

+ + + + +
+ This object contains "at your risk" and "no BC guarantees" objects for advanced use cases. +
+ + + +
Type:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + +

axios

diff --git a/docs/backend_api/Note.html b/docs/backend_api/Note.html index c5eea4f2f..2afe54588 100644 --- a/docs/backend_api/Note.html +++ b/docs/backend_api/Note.html @@ -93,7 +93,7 @@
Source:
@@ -204,7 +204,7 @@
Source:
@@ -279,7 +279,7 @@
Source:
@@ -347,7 +347,7 @@
Source:
@@ -415,7 +415,7 @@
Source:
@@ -486,7 +486,7 @@
Source:
@@ -554,7 +554,7 @@
Source:
@@ -622,7 +622,7 @@
Source:
@@ -690,7 +690,7 @@
Source:
@@ -758,7 +758,7 @@
Source:
@@ -833,7 +833,7 @@
Source:
@@ -901,7 +901,7 @@
Source:
@@ -969,7 +969,7 @@
Source:
@@ -1037,7 +1037,7 @@
Source:
@@ -1112,7 +1112,7 @@
Source:
@@ -1180,7 +1180,7 @@
Source:
@@ -1248,7 +1248,7 @@
Source:
@@ -1316,7 +1316,7 @@
Source:
@@ -1384,7 +1384,7 @@
Source:
@@ -1452,7 +1452,7 @@
Source:
@@ -1528,7 +1528,7 @@
Source:
@@ -1630,7 +1630,7 @@
Source:
@@ -1830,7 +1830,7 @@
Source:
@@ -1914,7 +1914,7 @@
Source:
@@ -2020,7 +2020,7 @@
Source:
@@ -2194,7 +2194,7 @@
Source:
@@ -2394,7 +2394,7 @@
Source:
@@ -2572,7 +2572,7 @@
Source:
@@ -2683,7 +2683,7 @@
Source:
@@ -2785,7 +2785,7 @@
Source:
@@ -2887,7 +2887,7 @@
Source:
@@ -2989,7 +2989,7 @@
Source:
@@ -3091,7 +3091,7 @@
Source:
@@ -3199,7 +3199,7 @@
Source:
@@ -3305,7 +3305,7 @@
Source:
@@ -3456,7 +3456,7 @@
Source:
@@ -3626,7 +3626,7 @@
Source:
@@ -3781,7 +3781,7 @@
Source:
@@ -3951,7 +3951,7 @@
Source:
@@ -4057,7 +4057,7 @@
Source:
@@ -4259,7 +4259,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -4437,7 +4437,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -4595,7 +4595,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -4765,7 +4765,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -4920,7 +4920,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -5090,7 +5090,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -5245,7 +5245,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -5415,7 +5415,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -5570,7 +5570,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -5679,7 +5679,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -5781,7 +5781,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -5932,7 +5932,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6102,7 +6102,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6257,7 +6257,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6366,7 +6366,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6475,7 +6475,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6577,7 +6577,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6679,7 +6679,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6781,7 +6781,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6888,7 +6888,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6990,7 +6990,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7141,7 +7141,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7319,7 +7319,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7474,7 +7474,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7629,7 +7629,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7784,7 +7784,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7934,7 +7934,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8040,7 +8040,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8146,7 +8146,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8252,7 +8252,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8358,7 +8358,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8464,7 +8464,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8856,7 +8856,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9036,7 +9036,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9216,7 +9216,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9363,6 +9363,111 @@ This is a low level method, for notes and branches use `note.deleteNote()` and ' +

saveNoteRevision() → {NoteRevision|null}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +NoteRevision +| + +null + + +
+
+ + + + + + + + + + + + +

setAttribute(type, name, valueopt)

@@ -9538,7 +9643,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9718,7 +9823,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9878,7 +9983,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -10120,7 +10225,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -10331,7 +10436,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -10542,7 +10647,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/becca_entities_note.js.html b/docs/backend_api/becca_entities_note.js.html index 3af1da710..57d0527e7 100644 --- a/docs/backend_api/becca_entities_note.js.html +++ b/docs/backend_api/becca_entities_note.js.html @@ -37,6 +37,8 @@ const entityChangesService = require('../../services/entity_changes'); const AbstractEntity = require("./abstract_entity"); const NoteRevision = require("./note_revision"); const TaskContext = require("../../services/task_context.js"); +const optionService = require("../../services/options.js"); +const noteRevisionService = require("../../services/note_revisions.js"); const LABEL = 'label'; const RELATION = 'relation'; @@ -1192,6 +1194,41 @@ class Note extends AbstractEntity { return !(this.noteId in this.becca.notes); } + /** + * @return {NoteRevision|null} + */ + saveNoteRevision() { + const content = this.getContent(); + + if (!content || (Buffer.isBuffer(content) && content.byteLength === 0)) { + return null; + } + + const contentMetadata = this.getContentMetadata(); + + const noteRevision = new NoteRevision({ + noteId: this.noteId, + // title and text should be decrypted now + title: this.title, + type: this.type, + mime: this.mime, + isProtected: false, // will be fixed in the protectNoteRevisions() call + utcDateLastEdited: this.utcDateModified > contentMetadata.utcDateModified + ? this.utcDateModified + : contentMetadata.utcDateModified, + utcDateCreated: dateUtils.utcNowDateTime(), + utcDateModified: dateUtils.utcNowDateTime(), + dateLastEdited: this.dateModified > contentMetadata.dateModified + ? this.dateModified + : contentMetadata.dateModified, + dateCreated: dateUtils.localNowDateTime() + }).save(); + + noteRevision.setContent(content); + + return noteRevision; + } + beforeSaving() { super.beforeSaving(); diff --git a/docs/backend_api/services_backend_script_api.js.html b/docs/backend_api/services_backend_script_api.js.html index 3c73eee9f..23c98b39e 100644 --- a/docs/backend_api/services_backend_script_api.js.html +++ b/docs/backend_api/services_backend_script_api.js.html @@ -454,6 +454,15 @@ function BackendScriptApi(currentNote, apiParams) { * @return {{syncVersion, appVersion, buildRevision, dbVersion, dataDirectory, buildDate}|*} - object representing basic info about running Trilium version */ this.getAppInfo = () => appInfo + + /** + * This object contains "at your risk" and "no BC guarantees" objects for advanced use cases. + * + * @type {{becca: Becca}} + */ + this.__private = { + becca + } } module.exports = BackendScriptApi; diff --git a/docs/frontend_api/FrontendScriptApi.html b/docs/frontend_api/FrontendScriptApi.html index 9ac977093..a6b3044b7 100644 --- a/docs/frontend_api/FrontendScriptApi.html +++ b/docs/frontend_api/FrontendScriptApi.html @@ -1635,7 +1635,144 @@
Source:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

addTextToActiveContextEditor(text)

+ + + + + + +
+ Adds given text to the editor cursor +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
text + + +string + + + + this must be clear text, HTML is not supported.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -1760,6 +1897,8 @@ +
Deprecated:
+ @@ -1772,7 +1911,7 @@
Source:
@@ -1928,7 +2067,7 @@
Source:
@@ -2288,7 +2427,7 @@
Source:
@@ -2421,7 +2560,7 @@
Source:
@@ -2479,6 +2618,438 @@ +

getActiveContextCodeEditor() → {Promise.<CodeMirror>}

+ + + + + + +
+ See https://codemirror.net/doc/manual.html#api +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ instance of CodeMirror +
+ + + +
+
+ Type +
+
+ +Promise.<CodeMirror> + + +
+
+ + + + + + + + + + + + + +

getActiveContextNote() → {NoteShort}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ active note (loaded into right pane) +
+ + + +
+
+ Type +
+
+ +NoteShort + + +
+
+ + + + + + + + + + + + + +

getActiveContextNotePath() → {Promise.<(string|null)>}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ returns note path of active note or null if there isn't active note +
+ + + +
+
+ Type +
+
+ +Promise.<(string|null)> + + +
+
+ + + + + + + + + + + + + +

getActiveContextTextEditor() → {Promise.<CKEditor>}

+ + + + + + +
+ See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for a documentation on the returned instance. +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ instance of CKEditor +
+ + + +
+
+ Type +
+
+ +Promise.<CKEditor> + + +
+
+ + + + + + + + + + + + +

getActiveNoteDetailWidget() → {Promise.<NoteDetailWidget>}

@@ -2532,7 +3103,7 @@ implementation of actual widget type.
Source:
@@ -2586,116 +3157,6 @@ implementation of actual widget type. -

getActiveTabCodeEditor() → {Promise.<CodeMirror>}

- - - - - - -
- See https://codemirror.net/doc/manual.html#api -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- instance of CodeMirror -
- - - -
-
- Type -
-
- -Promise.<CodeMirror> - - -
-
- - - - - - - - - - - - -

getActiveTabNote() → {NoteShort}

@@ -2732,6 +3193,8 @@ implementation of actual widget type. +
Deprecated:
+ @@ -2744,7 +3207,7 @@ implementation of actual widget type.
Source:
@@ -2838,6 +3301,8 @@ implementation of actual widget type. +
Deprecated:
+ @@ -2850,7 +3315,7 @@ implementation of actual widget type.
Source:
@@ -2908,7 +3373,7 @@ implementation of actual widget type. -

getActiveTabTextEditor(callbackopt) → {Promise.<CKEditor>}

+

getActiveTabTextEditor(callbackopt)

@@ -2975,7 +3440,7 @@ implementation of actual widget type. - deprecated (use returned promise): callback receiving "textEditor" instance + callback receiving "textEditor" instance @@ -3004,6 +3469,8 @@ implementation of actual widget type. +
Deprecated:
+ @@ -3016,7 +3483,7 @@ implementation of actual widget type.
Source:
@@ -3041,28 +3508,6 @@ implementation of actual widget type. -
Returns:
- - -
- instance of CKEditor -
- - - -
-
- Type -
-
- -Promise.<CKEditor> - - -
-
- - @@ -3175,7 +3620,7 @@ implementation of actual widget type.
Source:
@@ -3332,7 +3777,7 @@ implementation of actual widget type.
Source:
@@ -3487,7 +3932,7 @@ implementation of actual widget type.
Source:
@@ -3594,7 +4039,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3749,7 +4194,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -3905,7 +4350,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -4106,7 +4551,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -4212,7 +4657,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -4367,7 +4812,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -4522,7 +4967,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -4576,6 +5021,184 @@ otherwise (by e.g. createNoteLink()) +

openSplitWithNote(notePath, activate) → {Promise.<void>}

+ + + + + + +
+ Open a note in a new split. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
notePath + + +string + + + + (or noteId)
activate + + +boolean + + + + set to true to activate the new split, false to stay on the current split
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<void> + + +
+
+ + + + + + + + + + + + +

openTabWithNote(notePath, activate) → {Promise.<void>}

@@ -4851,7 +5474,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -4959,7 +5582,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -5115,7 +5738,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -5271,7 +5894,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -5408,7 +6031,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -5562,7 +6185,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -5648,7 +6271,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -5785,7 +6408,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -5946,7 +6569,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -6054,7 +6677,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -6192,7 +6815,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -6348,7 +6971,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -6503,7 +7126,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -6654,7 +7277,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -6791,7 +7414,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -6928,7 +7551,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -7088,7 +7711,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -7248,7 +7871,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -7340,7 +7963,7 @@ Typical use case is when new note has been created, we should wait until it is s
Source:
diff --git a/docs/frontend_api/global.html b/docs/frontend_api/global.html index e3bb5cbf0..8879721e8 100644 --- a/docs/frontend_api/global.html +++ b/docs/frontend_api/global.html @@ -395,7 +395,7 @@
Source:
diff --git a/docs/frontend_api/services_frontend_script_api.js.html b/docs/frontend_api/services_frontend_script_api.js.html index fe896a184..da00296e1 100644 --- a/docs/frontend_api/services_frontend_script_api.js.html +++ b/docs/frontend_api/services_frontend_script_api.js.html @@ -129,6 +129,26 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain } }; + /** + * Open a note in a new split. + * + * @param {string} notePath (or noteId) + * @param {boolean} activate - set to true to activate the new split, false to stay on the current split + * @return {Promise<void>} + */ + this.openSplitWithNote = async (notePath, activate) => { + await ws.waitForMaxKnownEntityChangeId(); + + const subContexts = appContext.tabManager.getActiveContext().getSubContexts(); + const {ntxId} = subContexts[subContexts.length - 1]; + + appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath}); + + if (activate) { + appContext.triggerEvent('focusAndSelectTitle'); + } + }; + /** * @typedef {Object} ToolbarButtonOptions * @property {string} title @@ -412,7 +432,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain this.getActiveTabTextEditor = callback => { console.warn("api.getActiveTabTextEditor() is deprecated, use getActiveContextTextEditor() instead."); - return appContext.tabManager.getActiveContextTextEditor(callback); + return appContext.tabManager.getActiveContext()?.getTextEditor(callback); }; /** @@ -421,7 +441,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain * @method * @returns {Promise<CKEditor>} instance of CKEditor */ - this.getActiveContextTextEditor = () => appContext.tabManager.getActiveContextTextEditor(); + this.getActiveContextTextEditor = () => appContext.tabManager.getActiveContext()?.getTextEditor(); /** * See https://codemirror.net/doc/manual.html#api @@ -429,7 +449,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain * @method * @returns {Promise<CodeMirror>} instance of CodeMirror */ - this.getActiveContextCodeEditor = () => appContext.tabManager.getActiveContextCodeEditor(); + this.getActiveContextCodeEditor = () => appContext.tabManager.getActiveContext()?.getCodeEditor(); /** * Get access to the widget handling note detail. Methods like `getWidgetType()` and `getTypeWidget()` to get to the diff --git a/src/becca/entities/note.js b/src/becca/entities/note.js index 595e41052..a815df1c3 100644 --- a/src/becca/entities/note.js +++ b/src/becca/entities/note.js @@ -9,6 +9,8 @@ const entityChangesService = require('../../services/entity_changes'); const AbstractEntity = require("./abstract_entity"); const NoteRevision = require("./note_revision"); const TaskContext = require("../../services/task_context.js"); +const optionService = require("../../services/options.js"); +const noteRevisionService = require("../../services/note_revisions.js"); const LABEL = 'label'; const RELATION = 'relation'; @@ -1164,6 +1166,41 @@ class Note extends AbstractEntity { return !(this.noteId in this.becca.notes); } + /** + * @return {NoteRevision|null} + */ + saveNoteRevision() { + const content = this.getContent(); + + if (!content || (Buffer.isBuffer(content) && content.byteLength === 0)) { + return null; + } + + const contentMetadata = this.getContentMetadata(); + + const noteRevision = new NoteRevision({ + noteId: this.noteId, + // title and text should be decrypted now + title: this.title, + type: this.type, + mime: this.mime, + isProtected: false, // will be fixed in the protectNoteRevisions() call + utcDateLastEdited: this.utcDateModified > contentMetadata.utcDateModified + ? this.utcDateModified + : contentMetadata.utcDateModified, + utcDateCreated: dateUtils.utcNowDateTime(), + utcDateModified: dateUtils.utcNowDateTime(), + dateLastEdited: this.dateModified > contentMetadata.dateModified + ? this.dateModified + : contentMetadata.dateModified, + dateCreated: dateUtils.localNowDateTime() + }).save(); + + noteRevision.setContent(content); + + return noteRevision; + } + beforeSaving() { super.beforeSaving(); diff --git a/src/public/app/services/frontend_script_api.js b/src/public/app/services/frontend_script_api.js index b2eabdc13..5ae0eaa05 100644 --- a/src/public/app/services/frontend_script_api.js +++ b/src/public/app/services/frontend_script_api.js @@ -101,6 +101,26 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain } }; + /** + * Open a note in a new split. + * + * @param {string} notePath (or noteId) + * @param {boolean} activate - set to true to activate the new split, false to stay on the current split + * @return {Promise} + */ + this.openSplitWithNote = async (notePath, activate) => { + await ws.waitForMaxKnownEntityChangeId(); + + const subContexts = appContext.tabManager.getActiveContext().getSubContexts(); + const {ntxId} = subContexts[subContexts.length - 1]; + + appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath}); + + if (activate) { + appContext.triggerEvent('focusAndSelectTitle'); + } + }; + /** * @typedef {Object} ToolbarButtonOptions * @property {string} title diff --git a/src/public/app/services/tab_manager.js b/src/public/app/services/tab_manager.js index 15f939bfe..59318d6e3 100644 --- a/src/public/app/services/tab_manager.js +++ b/src/public/app/services/tab_manager.js @@ -306,7 +306,8 @@ export default class TabManager extends Component { const mainNoteContexts = this.getNoteContexts().filter(nc => nc.isMainContext()); if (mainNoteContexts.length === 1) { - mainNoteContexts[0].setEmpty(); + await this.clearLastMainNoteContext(noteContextToRemove); + return; } } @@ -317,7 +318,7 @@ export default class TabManager extends Component { const noteContextsToRemove = noteContextToRemove.getSubContexts(); const ntxIdsToRemove = noteContextsToRemove.map(nc => nc.ntxId); - await this.triggerEvent('beforeTabRemove', { ntxIds: ntxIdsToRemove }); + await this.triggerEvent('beforeNoteContextRemove', { ntxIds: ntxIdsToRemove }); if (!noteContextToRemove.isMainContext()) { await this.activateNoteContext(noteContextToRemove.getMainContext().ntxId); @@ -336,16 +337,39 @@ export default class TabManager extends Component { } } - this.children = this.children.filter(nc => !ntxIdsToRemove.includes(nc.ntxId)); - - this.recentlyClosedTabs.push(noteContextsToRemove); - - this.triggerEvent('noteContextRemoved', {ntxIds: ntxIdsToRemove}); - - this.tabsUpdate.scheduleUpdate(); + this.removeNoteContexts(noteContextsToRemove); }); } + async clearLastMainNoteContext(noteContextToClear) { + noteContextToClear.setEmpty(); + + // activate main split + await this.activateNoteContext(noteContextToClear.ntxId); + + // remove all other splits + const noteContextsToRemove = noteContextToClear.getSubContexts() + .filter(ntx => ntx.ntxId !== noteContextToClear.ntxId); + + const ntxIdsToRemove = noteContextsToRemove.map(ntx => ntx.ntxId); + + await this.triggerEvent('beforeNoteContextRemove', {ntxIds: ntxIdsToRemove}); + + this.removeNoteContexts(noteContextsToRemove); + } + + removeNoteContexts(noteContextsToRemove) { + const ntxIdsToRemove = noteContextsToRemove.map(nc => nc.ntxId); + + this.children = this.children.filter(nc => !ntxIdsToRemove.includes(nc.ntxId)); + + this.recentlyClosedTabs.push(noteContextsToRemove); + + this.triggerEvent('noteContextRemoved', {ntxIds: ntxIdsToRemove}); + + this.tabsUpdate.scheduleUpdate(); + } + tabReorderEvent({ntxIdsInOrder}) { const order = {}; diff --git a/src/public/app/widgets/note_detail.js b/src/public/app/widgets/note_detail.js index f5dc0093b..d6bf8fe16 100644 --- a/src/public/app/widgets/note_detail.js +++ b/src/public/app/widgets/note_detail.js @@ -219,7 +219,7 @@ export default class NoteDetailWidget extends NoteContextAwareWidget { } } - async beforeTabRemoveEvent({ntxIds}) { + async beforeNoteContextRemoveEvent({ntxIds}) { if (this.isNoteContext(ntxIds)) { await this.spacedUpdate.updateNowIfNecessary(); } diff --git a/src/public/app/widgets/note_title.js b/src/public/app/widgets/note_title.js index 59007faa6..2cbd9b5a1 100644 --- a/src/public/app/widgets/note_title.js +++ b/src/public/app/widgets/note_title.js @@ -87,7 +87,7 @@ export default class NoteTitleWidget extends NoteContextAwareWidget { } } - async beforeTabRemoveEvent({ntxIds}) { + async beforeNoteContextRemoveEvent({ntxIds}) { if (this.isNoteContext(ntxIds)) { await this.spacedUpdate.updateNowIfNecessary(); } diff --git a/src/routes/api/notes.js b/src/routes/api/notes.js index 2b7ccf595..a2aef1dfa 100644 --- a/src/routes/api/notes.js +++ b/src/routes/api/notes.js @@ -206,7 +206,7 @@ function changeTitle(req) { const noteTitleChanged = note.title !== title; if (noteTitleChanged) { - noteService.saveNoteRevision(note); + noteService.saveNoteRevisionIfNeeded(note); } note.title = title; diff --git a/src/services/note_revisions.js b/src/services/note_revisions.js index 3ff9b692a..3759d2d2e 100644 --- a/src/services/note_revisions.js +++ b/src/services/note_revisions.js @@ -30,46 +30,6 @@ function protectNoteRevisions(note) { } } -/** - * @param {Note} note - * @return {NoteRevision|null} - */ -function createNoteRevision(note) { - if (note.hasLabel("disableVersioning")) { - return null; - } - - const content = note.getContent(); - - if (!content || (Buffer.isBuffer(content) && content.byteLength === 0)) { - return null; - } - - const contentMetadata = note.getContentMetadata(); - - const noteRevision = new NoteRevision({ - noteId: note.noteId, - // title and text should be decrypted now - title: note.title, - type: note.type, - mime: note.mime, - isProtected: false, // will be fixed in the protectNoteRevisions() call - utcDateLastEdited: note.utcDateModified > contentMetadata.utcDateModified - ? note.utcDateModified - : contentMetadata.utcDateModified, - utcDateCreated: dateUtils.utcNowDateTime(), - utcDateModified: dateUtils.utcNowDateTime(), - dateLastEdited: note.dateModified > contentMetadata.dateModified - ? note.dateModified - : contentMetadata.dateModified, - dateCreated: dateUtils.localNowDateTime() - }).save(); - - noteRevision.setContent(content); - - return noteRevision; -} - function eraseNoteRevisions(noteRevisionIdsToErase) { if (noteRevisionIdsToErase.length === 0) { return; @@ -86,6 +46,5 @@ function eraseNoteRevisions(noteRevisionIdsToErase) { module.exports = { protectNoteRevisions, - createNoteRevision, eraseNoteRevisions }; diff --git a/src/services/notes.js b/src/services/notes.js index 8168dc0de..69633c681 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -499,7 +499,7 @@ function saveLinks(note, content) { return content; } -function saveNoteRevision(note) { +function saveNoteRevisionIfNeeded(note) { // files and images are versioned separately if (note.type === 'file' || note.type === 'image' || note.hasLabel('disableVersioning')) { return; @@ -516,7 +516,7 @@ function saveNoteRevision(note) { const msSinceDateCreated = now.getTime() - dateUtils.parseDateTime(note.utcDateCreated).getTime(); if (!existingNoteRevisionId && msSinceDateCreated >= noteRevisionSnapshotTimeInterval * 1000) { - noteRevisionService.createNoteRevision(note); + note.saveNoteRevision(); } } @@ -527,7 +527,7 @@ function updateNote(noteId, noteUpdates) { throw new Error(`Note '${noteId}' is not available for change!`); } - saveNoteRevision(note); + saveNoteRevisionIfNeeded(note); // if protected status changed, then we need to encrypt/decrypt the content anyway if (['file', 'image'].includes(note.type) && note.isProtected !== noteUpdates.isProtected) { @@ -918,6 +918,6 @@ module.exports = { triggerNoteTitleChanged, eraseDeletedNotesNow, eraseNotesWithDeleteId, - saveNoteRevision, + saveNoteRevisionIfNeeded, downloadImages }; diff --git a/src/services/search/services/lex.js b/src/services/search/services/lex.js index c6bdc2dfd..470ba5526 100644 --- a/src/services/search/services/lex.js +++ b/src/services/search/services/lex.js @@ -83,7 +83,7 @@ function lex(str) { continue; } else if (!quotes) { - if (!fulltextEnded && currentWord === 'note' && chr === '.') { + if (!fulltextEnded && currentWord === 'note' && chr === '.' && i + 1 < str.length) { fulltextEnded = true; }