From 3cd4be4e4870c725ae05dc42bc2bc242aae1773b Mon Sep 17 00:00:00 2001 From: zadam Date: Sun, 2 Feb 2020 10:41:43 +0100 Subject: [PATCH] removed note detail service --- src/public/javascripts/desktop.js | 9 +++- src/public/javascripts/dialogs/add_link.js | 29 ++---------- .../javascripts/dialogs/markdown_import.js | 14 +++--- .../javascripts/services/app_context.js | 5 ++ src/public/javascripts/services/branches.js | 3 +- .../javascripts/services/entrypoints.js | 3 +- .../services/frontend_script_api.js | 15 ++---- .../javascripts/services/hoisted_note.js | 2 - .../javascripts/services/note_detail.js | 28 +---------- .../javascripts/services/note_tooltip.js | 2 - .../javascripts/services/protected_session.js | 3 -- .../javascripts/services/tab_context.js | 1 - src/public/javascripts/services/tree.js | 4 +- .../javascripts/services/tree_keybindings.js | 4 +- src/public/javascripts/widgets/note_detail.js | 5 +- src/public/javascripts/widgets/note_title.js | 4 ++ src/public/javascripts/widgets/note_type.js | 4 -- .../javascripts/widgets/type_widgets/code.js | 1 - .../javascripts/widgets/type_widgets/file.js | 3 +- .../javascripts/widgets/type_widgets/image.js | 6 +-- .../widgets/type_widgets/search.js | 1 - .../javascripts/widgets/type_widgets/text.js | 47 +++++++++++++++++++ .../widgets/type_widgets/type_widget.js | 4 ++ 23 files changed, 100 insertions(+), 97 deletions(-) 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 = `
@@ -221,4 +220,8 @@ export default class NoteDetailWidget extends TabAwareWidget { this.refreshWithNote(this.note, this.notePath); } } + + beforeUnloadListener() { + this.spacedUpdate.updateNowIfNecessary(); + } } \ No newline at end of file diff --git a/src/public/javascripts/widgets/note_title.js b/src/public/javascripts/widgets/note_title.js index a284b43fd..c5249f785 100644 --- a/src/public/javascripts/widgets/note_title.js +++ b/src/public/javascripts/widgets/note_title.js @@ -102,4 +102,8 @@ export default class NoteTitleWidget extends TabAwareWidget { .trigger('select'); } } + + beforeUnloadListener() { + this.spacedUpdate.updateNowIfNecessary(); + } } \ No newline at end of file diff --git a/src/public/javascripts/widgets/note_type.js b/src/public/javascripts/widgets/note_type.js index 48ced5399..a1e693442 100644 --- a/src/public/javascripts/widgets/note_type.js +++ b/src/public/javascripts/widgets/note_type.js @@ -1,5 +1,3 @@ -import treeService from '../services/tree.js'; -import noteDetailService from '../services/note_detail.js'; import server from '../services/server.js'; import mimeTypesService from '../services/mime_types.js'; import TabAwareWidget from "./tab_aware_widget.js"; @@ -128,8 +126,6 @@ export default class NoteTypeWidget extends TabAwareWidget { + '/type/' + encodeURIComponent(type) + '/mime/' + encodeURIComponent(mime)); - await noteDetailService.reload(); - this.update(); } diff --git a/src/public/javascripts/widgets/type_widgets/code.js b/src/public/javascripts/widgets/type_widgets/code.js index 1ade09b26..c08db8bf8 100644 --- a/src/public/javascripts/widgets/type_widgets/code.js +++ b/src/public/javascripts/widgets/type_widgets/code.js @@ -2,7 +2,6 @@ import libraryLoader from "../../services/library_loader.js"; import bundleService from "../../services/bundle.js"; import toastService from "../../services/toast.js"; import server from "../../services/server.js"; -import noteDetailService from "../../services/note_detail.js"; import keyboardActionService from "../../services/keyboard_actions.js"; import TypeWidget from "./type_widget.js"; diff --git a/src/public/javascripts/widgets/type_widgets/file.js b/src/public/javascripts/widgets/type_widgets/file.js index 1542b124d..e8113119f 100644 --- a/src/public/javascripts/widgets/type_widgets/file.js +++ b/src/public/javascripts/widgets/type_widgets/file.js @@ -1,7 +1,6 @@ import utils from "../../services/utils.js"; import server from "../../services/server.js"; import toastService from "../../services/toast.js"; -import noteDetailService from "../../services/note_detail.js"; import TypeWidget from "./type_widget.js"; const TPL = ` @@ -107,7 +106,7 @@ export default class FileTypeWidget extends TypeWidget { if (result.uploaded) { toastService.showMessage("New file revision has been uploaded."); - await noteDetailService.reload(); + // FIXME reload } else { toastService.showError("Upload of a new file revision failed."); diff --git a/src/public/javascripts/widgets/type_widgets/image.js b/src/public/javascripts/widgets/type_widgets/image.js index 5fd314461..6e5261078 100644 --- a/src/public/javascripts/widgets/type_widgets/image.js +++ b/src/public/javascripts/widgets/type_widgets/image.js @@ -1,7 +1,6 @@ import utils from "../../services/utils.js"; import toastService from "../../services/toast.js"; import server from "../../services/server.js"; -import noteDetailService from "../../services/note_detail.js"; import TypeWidget from "./type_widget.js"; const TPL = ` @@ -48,7 +47,7 @@ const TPL = `
`; -class NoteDetailImage extends TypeWidget { +class ImageTypeWidget extends TypeWidget { static getType() { return "image"; } doRender() { @@ -112,6 +111,7 @@ class NoteDetailImage extends TypeWidget { await utils.clearBrowserCache(); + // FIXME await noteDetailService.reload(); } else { @@ -160,4 +160,4 @@ class NoteDetailImage extends TypeWidget { } } -export default NoteDetailImage \ No newline at end of file +export default ImageTypeWidget \ No newline at end of file diff --git a/src/public/javascripts/widgets/type_widgets/search.js b/src/public/javascripts/widgets/type_widgets/search.js index 10386f277..1cb506879 100644 --- a/src/public/javascripts/widgets/type_widgets/search.js +++ b/src/public/javascripts/widgets/type_widgets/search.js @@ -1,4 +1,3 @@ -import noteDetailService from "../../services/note_detail.js"; import searchNotesService from "../../services/search_notes.js"; import TypeWidget from "./type_widget.js"; diff --git a/src/public/javascripts/widgets/type_widgets/text.js b/src/public/javascripts/widgets/type_widgets/text.js index 303fac754..80cf14da6 100644 --- a/src/public/javascripts/widgets/type_widgets/text.js +++ b/src/public/javascripts/widgets/type_widgets/text.js @@ -185,6 +185,10 @@ export default class TextTypeWidget extends TypeWidget { } insertDateTimeToTextListener() { + if (!this.isActive()) { + return; + } + const date = new Date(); const dateString = utils.formatDateTime(date); @@ -208,4 +212,47 @@ export default class TextTypeWidget extends TypeWidget { writer.insertText(text, insertPosition); }); } + + addTextToActiveEditorListener(text) { + if (!this.isActive()) { + return; + } + + this.addTextToEditor(text); + } + + async addLinkToActiveEditorListener({linkTitle, linkHref}) { + if (!this.isActive()) { + return; + } + + await this.initialized; + + if (this.hasSelection()) { + this.textEditor.execute('link', linkHref); + } + else { + await this.addLinkToEditor(linkTitle, linkHref); + } + + this.textEditor.editing.view.focus(); + } + + // returns true if user selected some text, false if there's no selection + hasSelection() { + const model = this.textEditor.model; + const selection = model.document.selection; + + return !selection.isCollapsed; + } + + async executeInActiveEditorListener({callback}) { + if (!this.isActive()) { + return; + } + + await this.initialized; + + callback(this.textEditor); + } } \ No newline at end of file diff --git a/src/public/javascripts/widgets/type_widgets/type_widget.js b/src/public/javascripts/widgets/type_widgets/type_widget.js index 428395f91..429da3d49 100644 --- a/src/public/javascripts/widgets/type_widgets/type_widget.js +++ b/src/public/javascripts/widgets/type_widgets/type_widget.js @@ -24,4 +24,8 @@ export default class TypeWidget extends TabAwareWidget { this.doRefresh(note); } + + isActive() { + return this.$widget.is(":visible"); + } } \ No newline at end of file