diff --git a/src/public/javascripts/desktop.js b/src/public/javascripts/desktop.js index 12a5f99a7..e564e88d4 100644 --- a/src/public/javascripts/desktop.js +++ b/src/public/javascripts/desktop.js @@ -2,7 +2,6 @@ import cloning from './services/cloning.js'; import contextMenu from './services/tree_context_menu.js'; import link from './services/link.js'; import ws from './services/ws.js'; -import noteDetailService from './services/note_detail.js'; import noteType from './widgets/note_type.js'; import protectedSessionService from './services/protected_session.js'; import protectedSessionHolder from './services/protected_session_holder.js'; @@ -55,7 +54,13 @@ window.glob.loadIncludedNote = async (noteId, el) => { } }; // this is required by CKEditor when uploading images -window.glob.noteChanged = noteDetailService.noteChanged; +window.glob.noteChanged = () => { + const activeTabContext = appContext.getActiveTabContext(); + + if (activeTabContext) { + activeTabContext.noteChanged(); + } +}; window.glob.refreshTree = treeService.reload; // required for ESLint plugin diff --git a/src/public/javascripts/dialogs/add_link.js b/src/public/javascripts/dialogs/add_link.js index a4e59d87c..de388063d 100644 --- a/src/public/javascripts/dialogs/add_link.js +++ b/src/public/javascripts/dialogs/add_link.js @@ -1,5 +1,3 @@ -import linkService from '../services/link.js'; -import noteDetailService from '../services/note_detail.js'; import treeService from '../services/tree.js'; import noteAutocompleteService from "../services/note_autocomplete.js"; import utils from "../services/utils.js"; @@ -55,33 +53,16 @@ $form.on('submit', () => { const notePath = $autoComplete.getSelectedPath(); if (notePath) { - const linkTitle = $linkTitle.val(); - $dialog.modal('hide'); - const linkHref = '#' + notePath; - const editor = noteDetailService.getActiveEditor(); - - if (hasSelection()) { - editor.execute('link', linkHref); - } - else { - linkService.addLinkToEditor(linkTitle, linkHref); - } - - editor.editing.view.focus(); + appContext.trigger(`addLinkToActiveEditor`, { + linkTitle: $linkTitle.val(), + linkHref: '#' + notePath + }); } else { console.error("No path to add link."); } return false; -}); - -// returns true if user selected some text, false if there's no selection -function hasSelection() { - const model = noteDetailService.getActiveEditor().model; - const selection = model.document.selection; - - return !selection.isCollapsed; -} \ No newline at end of file +}); \ No newline at end of file diff --git a/src/public/javascripts/dialogs/markdown_import.js b/src/public/javascripts/dialogs/markdown_import.js index f7a1deafd..ab58f930e 100644 --- a/src/public/javascripts/dialogs/markdown_import.js +++ b/src/public/javascripts/dialogs/markdown_import.js @@ -1,7 +1,6 @@ import libraryLoader from "../services/library_loader.js"; import toastService from "../services/toast.js"; import utils from "../services/utils.js"; -import noteDetailService from "../services/note_detail.js"; import appContext from "../services/app_context.js"; const $dialog = $('#markdown-import-dialog'); @@ -17,13 +16,16 @@ async function convertMarkdownToHtml(text) { const result = writer.render(parsed); - const textEditor = noteDetailService.getActiveEditor(); - const viewFragment = textEditor.data.processor.toView(result); - const modelFragment = textEditor.data.toModel(viewFragment); + appContext.trigger('executeInActiveEditor', { + callback: textEditor => { + const viewFragment = textEditor.data.processor.toView(result); + const modelFragment = textEditor.data.toModel(viewFragment); - textEditor.model.insertContent(modelFragment, textEditor.model.document.selection); + textEditor.model.insertContent(modelFragment, textEditor.model.document.selection); - toastService.showMessage("Markdown content has been imported into the document."); + toastService.showMessage("Markdown content has been imported into the document."); + } + }); } export async function importMarkdownInline() { diff --git a/src/public/javascripts/services/app_context.js b/src/public/javascripts/services/app_context.js index fe9248d5b..daa440929 100644 --- a/src/public/javascripts/services/app_context.js +++ b/src/public/javascripts/services/app_context.js @@ -401,4 +401,9 @@ class AppContext { const appContext = new AppContext(); +// we should save all outstanding changes before the page/app is closed +$(window).on('beforeunload', () => { + appContext.trigger('beforeUnload'); +}); + export default appContext; \ No newline at end of file diff --git a/src/public/javascripts/services/branches.js b/src/public/javascripts/services/branches.js index 33fa73ed8..55f59cafa 100644 --- a/src/public/javascripts/services/branches.js +++ b/src/public/javascripts/services/branches.js @@ -4,7 +4,6 @@ import server from './server.js'; import toastService from "./toast.js"; import treeCache from "./tree_cache.js"; import hoistedNoteService from "./hoisted_note.js"; -import noteDetailService from "./note_detail.js"; import ws from "./ws.js"; import appContext from "./app_context.js"; @@ -134,12 +133,14 @@ async function deleteNodes(branchIdsToDelete) { if (deleteClones) { await server.remove(`notes/${branch.noteId}` + query); + // FIXME noteDetailService.noteDeleted(branch.noteId); } else { const {noteDeleted} = await server.remove(`branches/${branchIdToDelete}` + query); if (noteDeleted) { + // FIXME noteDetailService.noteDeleted(branch.noteId); } } diff --git a/src/public/javascripts/services/entrypoints.js b/src/public/javascripts/services/entrypoints.js index b2a4b004f..0f9f23fab 100644 --- a/src/public/javascripts/services/entrypoints.js +++ b/src/public/javascripts/services/entrypoints.js @@ -2,7 +2,6 @@ import utils from "./utils.js"; import zoomService from "./zoom.js"; import treeService from "./tree.js"; import dateNoteService from "./date_notes.js"; -import noteDetailService from "./note_detail.js"; import hoistedNoteService from "./hoisted_note.js"; import treeCache from "./tree_cache.js"; import server from "./server.js"; @@ -82,7 +81,7 @@ export default class Entrypoints extends Component { appContext.activateTab(tabContext.tabId); await tabContext.setNote(note.noteId); - noteDetailService.focusAndSelectTitle(); + appContext.trigger('focusAndSelectTitle'); } toggleNoteHoistingListener() { diff --git a/src/public/javascripts/services/frontend_script_api.js b/src/public/javascripts/services/frontend_script_api.js index 357084159..a3f6be33e 100644 --- a/src/public/javascripts/services/frontend_script_api.js +++ b/src/public/javascripts/services/frontend_script_api.js @@ -4,7 +4,6 @@ import utils from './utils.js'; import toastService from './toast.js'; import linkService from './link.js'; import treeCache from './tree_cache.js'; -import noteDetailService from './note_detail.js'; import noteTooltipService from './note_tooltip.js'; import protectedSessionService from './protected_session.js'; import dateNotesService from './date_notes.js'; @@ -67,7 +66,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte this.activateNewNote = async notePath => { await ws.waitForMaxKnownSyncId(); - await treeService.activateNote(notePath, noteDetailService.focusAndSelectTitle); + await treeService.activateNote(notePath, () => appContext.trigger('focusAndSelectTitle')); }; /** @@ -285,7 +284,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte * @param {string} text - this must be clear text, HTML is not supported. * @method */ - this.addTextToActiveTabEditor = linkService.addTextToEditor; + this.addTextToActiveTabEditor = text => appContext.trigger('addTextToActiveEditor', {text}); /** * @method @@ -297,9 +296,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte * See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html for a documentation on the returned instance. * * @method - * @returns {Editor|null} CKEditor instance or null (e.g. if active note is not a text note) + * @param callback - method receiving "textEditor" instance */ - this.getActiveTabTextEditor = noteDetailService.getActiveEditor; + this.getActiveTabTextEditor = callback => appContext.trigger('executeInActiveEditor', {callback}); /** * @method @@ -320,12 +319,6 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte return tabContext.note && this.originEntity.noteId === tabContext.note.noteId; }; - /** - * @method - * @param {function} func - callback called on note change as user is typing (not necessarily tied to save event) - */ - this.onNoteChange = noteDetailService.onNoteChange; - /** * @method * @param {object} $el - jquery object on which to setup the tooltip diff --git a/src/public/javascripts/services/hoisted_note.js b/src/public/javascripts/services/hoisted_note.js index 140d3677d..aaac4b48f 100644 --- a/src/public/javascripts/services/hoisted_note.js +++ b/src/public/javascripts/services/hoisted_note.js @@ -1,7 +1,5 @@ import optionsService from './options.js'; import server from "./server.js"; -import tree from "./tree.js"; -import noteDetailService from "./note_detail.js"; import appContext from "./app_context.js"; let hoistedNoteId = 'root'; diff --git a/src/public/javascripts/services/note_detail.js b/src/public/javascripts/services/note_detail.js index 08330aec9..9ddb3cace 100644 --- a/src/public/javascripts/services/note_detail.js +++ b/src/public/javascripts/services/note_detail.js @@ -11,32 +11,6 @@ function getActiveEditor() { } } -function focusOnTitle() { - appContext.trigger('focusOnTitle'); -} - -function focusAndSelectTitle() { - appContext.trigger('focusAndSelectTitle'); -} - -function noteChanged() { - const activeTabContext = appContext.getActiveTabContext(); - - if (activeTabContext) { - activeTabContext.noteChanged(); - } -} - -// this makes sure that when user e.g. reloads the page or navigates away from the page, the note's content is saved -// this sends the request asynchronously and doesn't wait for result -// FIXME -$(window).on('beforeunload', () => { - //saveNotesIfChanged(); - }); - export default { - focusOnTitle, - focusAndSelectTitle, - getActiveEditor, - noteChanged + getActiveEditor }; \ No newline at end of file diff --git a/src/public/javascripts/services/note_tooltip.js b/src/public/javascripts/services/note_tooltip.js index 82727b83f..799c783b2 100644 --- a/src/public/javascripts/services/note_tooltip.js +++ b/src/public/javascripts/services/note_tooltip.js @@ -1,7 +1,5 @@ -import noteDetailService from "./note_detail.js"; import treeService from "./tree.js"; import linkService from "./link.js"; -import server from "./server.js"; import treeCache from "./tree_cache.js"; function setupGlobalTooltip() { diff --git a/src/public/javascripts/services/protected_session.js b/src/public/javascripts/services/protected_session.js index b0226f0e2..ea976fbe7 100644 --- a/src/public/javascripts/services/protected_session.js +++ b/src/public/javascripts/services/protected_session.js @@ -1,5 +1,4 @@ import treeService from './tree.js'; -import noteDetailService from './note_detail.js'; import utils from './utils.js'; import server from './server.js'; import protectedSessionHolder from './protected_session_holder.js'; @@ -82,8 +81,6 @@ async function protectNoteAndSendToServer() { await appContext.getActiveTabContext().saveNote(); treeService.setProtected(note.noteId, note.isProtected); - - await noteDetailService.reload(); } async function unprotectNoteAndSendToServer() { diff --git a/src/public/javascripts/services/tab_context.js b/src/public/javascripts/services/tab_context.js index 0148cf7db..1c807833c 100644 --- a/src/public/javascripts/services/tab_context.js +++ b/src/public/javascripts/services/tab_context.js @@ -5,7 +5,6 @@ import utils from "./utils.js"; import optionsService from "./options.js"; import appContext from "./app_context.js"; import treeService from "./tree.js"; -import noteDetailService from "./note_detail.js"; import Component from "../widgets/component.js"; import treeCache from "./tree_cache.js"; diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js index b4ee5779b..c1f2b7d0a 100644 --- a/src/public/javascripts/services/tree.js +++ b/src/public/javascripts/services/tree.js @@ -1,5 +1,4 @@ import ws from './ws.js'; -import noteDetailService from './note_detail.js'; import protectedSessionHolder from './protected_session_holder.js'; import utils from './utils.js'; import server from './server.js'; @@ -69,6 +68,7 @@ async function activateNote(notePath, noteLoadedListener) { const node = await appContext.getMainNoteTree().expandToNote(notePath); if (noteLoadedListener) { + // FIXME noteDetailService.addDetailLoadedListener(node.data.noteId, noteLoadedListener); } @@ -340,7 +340,7 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) { window.cutToNote.removeSelection(); } - noteDetailService.addDetailLoadedListener(note.noteId, noteDetailService.focusAndSelectTitle); + noteDetailService.addDetailLoadedListener(note.noteId, () => appContext.trigger('focusAndSelectTitle')); const noteEntity = await treeCache.getNote(note.noteId); const branchEntity = treeCache.getBranch(branch.branchId); diff --git a/src/public/javascripts/services/tree_keybindings.js b/src/public/javascripts/services/tree_keybindings.js index a2fceb1a8..918d7326f 100644 --- a/src/public/javascripts/services/tree_keybindings.js +++ b/src/public/javascripts/services/tree_keybindings.js @@ -1,10 +1,10 @@ -import noteDetailService from "./note_detail.js"; import treeChangesService from "./branches.js"; import treeService from "./tree.js"; import hoistedNoteService from "./hoisted_note.js"; import clipboard from "./clipboard.js"; import utils from "./utils.js"; import keyboardActionService from "./keyboard_actions.js"; +import appContext from "./app_context.js"; /** * @param {NoteTreeWidget} treeWidget @@ -167,7 +167,7 @@ function getTemplates(treeWidget) { return false; }, "EditNoteTitle": node => { - noteDetailService.focusOnTitle(); + appContext.trigger('focusOnTitle'); return false; }, diff --git a/src/public/javascripts/widgets/note_detail.js b/src/public/javascripts/widgets/note_detail.js index 0753ce9b6..37c103439 100644 --- a/src/public/javascripts/widgets/note_detail.js +++ b/src/public/javascripts/widgets/note_detail.js @@ -4,7 +4,6 @@ import protectedSessionHolder from "../services/protected_session_holder.js"; import SpacedUpdate from "../services/spaced_update.js"; import server from "../services/server.js"; import libraryLoader from "../services/library_loader.js"; -import noteDetailService from "../services/note_detail.js"; const TPL = `