diff --git a/package-lock.json b/package-lock.json index 63d2c41f3..a1737e8ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2063,14 +2063,38 @@ } }, "csurf": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.10.0.tgz", - "integrity": "sha512-fh725p0R83wA5JukCik5hdEko/LizW/Vl7pkKDa1WJUVCosg141mqaAWCScB+nkEaRMFMGbutHMOr6oBNc/j9A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.11.0.tgz", + "integrity": "sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ==", "requires": { - "cookie": "0.3.1", + "cookie": "0.4.0", "cookie-signature": "1.0.6", "csrf": "3.1.0", - "http-errors": "~1.7.2" + "http-errors": "~1.7.3" + }, + "dependencies": { + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } } }, "cuint": { diff --git a/package.json b/package.json index 26f8d8578..fece093b4 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "cls-hooked": "4.2.2", "commonmark": "0.29.1", "cookie-parser": "1.4.4", - "csurf": "1.10.0", + "csurf": "1.11.0", "dayjs": "1.8.19", "debug": "4.1.1", "ejs": "2.7.4", diff --git a/src/public/javascripts/services/app_context.js b/src/public/javascripts/services/app_context.js index 700e13184..ba4d6061a 100644 --- a/src/public/javascripts/services/app_context.js +++ b/src/public/javascripts/services/app_context.js @@ -155,6 +155,10 @@ class AppContext { } } + noteTitleChangedListener() { + this._setTitleBar(); + } + async _setTitleBar() { document.title = "Trilium Notes"; diff --git a/src/public/javascripts/services/note_detail.js b/src/public/javascripts/services/note_detail.js index 045211e1b..9f4c00b42 100644 --- a/src/public/javascripts/services/note_detail.js +++ b/src/public/javascripts/services/note_detail.js @@ -8,7 +8,6 @@ import treeUtils from "./tree_utils.js"; import tabRow from "../widgets/tab_row.js"; import appContext from "./app_context.js"; -const $tabContentsContainer = $("#note-tab-container"); const $savedIndicator = $(".saved-indicator"); let detailLoadedListeners = []; @@ -200,30 +199,6 @@ ws.subscribeToAllSyncMessages(syncData => { appContext.trigger('syncData', {data: syncData}); }); -$tabContentsContainer.on("dragover", e => e.preventDefault()); - -$tabContentsContainer.on("dragleave", e => e.preventDefault()); - -$tabContentsContainer.on("drop", async e => { - const activeNote = appContext.getActiveTabNote(); - - if (!activeNote) { - return; - } - - const files = [...e.originalEvent.dataTransfer.files]; // chrome has issue that dataTransfer.files empties after async operation - - const importService = await import("./import.js"); - - importService.uploadFiles(activeNote.noteId, files, { - safeImport: true, - shrinkImages: true, - textImportedAsText: true, - codeImportedAsCode: true, - explodeArchives: true - }); -}); - function noteChanged() { const activeTabContext = appContext.getActiveTabContext(); diff --git a/src/public/javascripts/services/tab_context.js b/src/public/javascripts/services/tab_context.js index a3a5abf65..1c8080ca7 100644 --- a/src/public/javascripts/services/tab_context.js +++ b/src/public/javascripts/services/tab_context.js @@ -109,8 +109,6 @@ class TabContext extends Component { // otherwise we might overwrite another change (especially async code) this.isNoteChanged = false; - treeService.setNoteTitle(this.note.noteId, this.note.title); - const resp = await server.put('notes/' + this.note.noteId, this.note.dto); this.note.dateModified = resp.dateModified; diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js index 41cf1658c..0c2c21a73 100644 --- a/src/public/javascripts/services/tree.js +++ b/src/public/javascripts/services/tree.js @@ -333,18 +333,6 @@ function setProtected(noteId, isProtected) { }); } -async function setNoteTitle(noteId, title) { - utils.assertArguments(noteId); - - const note = await treeCache.getNote(noteId); - - note.title = title; - - for (const clone of appContext.getMainNoteTree().getNodesByNoteId(noteId)) { - await setNodeTitleWithPrefix(clone); - } -} - async function createNewTopLevelNote() { const hoistedNoteId = await hoistedNoteService.getHoistedNoteId(); @@ -594,7 +582,6 @@ export default { reload, setProtected, activateNote, - setNoteTitle, setPrefix, createNote, sortAlphabetically, @@ -606,5 +593,6 @@ export default { getSomeNotePath, createNewTopLevelNote, duplicateNote, - getRunPath + getRunPath, + setNodeTitleWithPrefix }; \ No newline at end of file diff --git a/src/public/javascripts/widgets/note_detail.js b/src/public/javascripts/widgets/note_detail.js index fd12edd08..991ea1232 100644 --- a/src/public/javascripts/widgets/note_detail.js +++ b/src/public/javascripts/widgets/note_detail.js @@ -1,6 +1,7 @@ import TabAwareWidget from "./tab_aware_widget.js"; import utils from "../services/utils.js"; import protectedSessionHolder from "../services/protected_session_holder.js"; +import appContext from "../services/app_context.js"; const TPL = `
@@ -36,6 +37,30 @@ export default class NoteDetailWidget extends TabAwareWidget { doRender() { this.$widget = $(TPL); + this.$widget.on("dragover", e => e.preventDefault()); + + this.$widget.on("dragleave", e => e.preventDefault()); + + this.$widget.on("drop", async e => { + const activeNote = this.appContext.getActiveTabNote(); + + if (!activeNote) { + return; + } + + const files = [...e.originalEvent.dataTransfer.files]; // chrome has issue that dataTransfer.files empties after async operation + + const importService = await import("../services/import.js"); + + importService.uploadFiles(activeNote.noteId, files, { + safeImport: true, + shrinkImages: true, + textImportedAsText: true, + codeImportedAsCode: true, + explodeArchives: true + }); + }); + return this.$widget; } diff --git a/src/public/javascripts/widgets/note_title.js b/src/public/javascripts/widgets/note_title.js index 0d1c39311..3b8c65869 100644 --- a/src/public/javascripts/widgets/note_title.js +++ b/src/public/javascripts/widgets/note_title.js @@ -1,15 +1,7 @@ import TabAwareWidget from "./tab_aware_widget.js"; -import treeService from "../services/tree.js"; import utils from "../services/utils.js"; -import protectedSessionService from "../services/protected_session.js"; -import treeUtils from "../services/tree_utils.js"; -import linkService from "../services/link.js"; import protectedSessionHolder from "../services/protected_session_holder.js"; -import NoteTypeWidget from "./note_type.js"; -import NotePathsWidget from "./note_paths.js"; -import NoteActionsWidget from "./note_actions.js"; -import ProtectedNoteSwitchWidget from "./protected_note_switch.js"; -import RunScriptButtonsWidget from "./run_script_buttons.js"; +import treeCache from "../services/tree_cache.js"; const TPL = `
@@ -23,7 +15,8 @@ const TPL = ` margin-right: 10px; font-size: 150%; border: 0; - width: 5em; + min-width: 5em; + width: 100%; } @@ -35,21 +28,7 @@ export default class NoteTitleWidget extends TabAwareWidget { this.$widget = $(TPL); this.$noteTitle = this.$widget.find(".note-title"); - this.$noteTitle.on('input', () => { - if (!this.note) { - return; - } - - // FIXME event not used - this.trigger(`activeNoteChanged`); - - this.note.title = this.$noteTitle.val(); - - this.tabRow.updateTab(this.$tab[0], {title: this.note.title}); - treeService.setNoteTitle(this.note.noteId, this.note.title); - - this.setTitleBar(); - }); + this.$noteTitle.on('input', () => this.titleChanged()); if (utils.isDesktop()) { // keyboard plugin is not loaded in mobile @@ -63,6 +42,36 @@ export default class NoteTitleWidget extends TabAwareWidget { return this.$widget; } + async titleChanged() { + const {note} = this.tabContext; + + if (!note) { + return; + } + + note.title = this.$noteTitle.val(); + + const noteFromCache = await treeCache.getNote(note.noteId); + noteFromCache.title = note.title; + + this.trigger(`noteTitleChanged`, { + tabId: this.tabContext.tabId, // used to identify that the event comes from this tab so we should not update this tab's input + title: note.title, + noteId: note.noteId + }); + } + + noteTitleChangedListener({tabId, title, noteId}) { + if (tabId === this.tabContext.tabId + || !this.tabContext.note + || this.tabContext.note.noteId !== noteId) { + + return; + } + + this.$noteTitle.val(title); + } + async refreshWithNote(note) { this.$noteTitle.val(note.title); diff --git a/src/public/javascripts/widgets/note_tree.js b/src/public/javascripts/widgets/note_tree.js index a53602221..470219b7e 100644 --- a/src/public/javascripts/widgets/note_tree.js +++ b/src/public/javascripts/widgets/note_tree.js @@ -447,4 +447,12 @@ export default class NoteTreeWidget extends TabAwareWidget { } } } + + noteTitleChangedListener({noteId}) { + for (const node of this.getNodesByNoteId(noteId)) { + console.log("Setting to", node); + + treeService.setNodeTitleWithPrefix(node); + } + } } \ No newline at end of file diff --git a/src/public/javascripts/widgets/protected_note_switch.js b/src/public/javascripts/widgets/protected_note_switch.js index de81822d2..72e724b62 100644 --- a/src/public/javascripts/widgets/protected_note_switch.js +++ b/src/public/javascripts/widgets/protected_note_switch.js @@ -3,7 +3,7 @@ import protectedSessionService from "../services/protected_session.js"; import protectedSessionHolder from "../services/protected_session_holder.js"; const TPL = ` -
+