mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	separated text and code handling out of note detail service
This commit is contained in:
		
							
								
								
									
										2
									
								
								src/public/javascripts/services/bootstrap.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								src/public/javascripts/services/bootstrap.js
									
									
									
									
										vendored
									
									
								
							| @@ -13,7 +13,7 @@ import contextMenu from './context_menu.js'; | |||||||
| import dragAndDropSetup from './drag_and_drop.js'; | import dragAndDropSetup from './drag_and_drop.js'; | ||||||
| import exportService from './export.js'; | import exportService from './export.js'; | ||||||
| import link from './link.js'; | import link from './link.js'; | ||||||
| import messaging from './messaging.js'; | import messagingService from './messaging.js'; | ||||||
| import noteDetailService from './note_detail.js'; | import noteDetailService from './note_detail.js'; | ||||||
| import noteType from './note_type.js'; | import noteType from './note_type.js'; | ||||||
| import protected_session from './protected_session.js'; | import protected_session from './protected_session.js'; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import treeService from './tree.js'; | import treeService from './tree.js'; | ||||||
| import noteDetailService from './note_detail.js'; | import noteDetailText from './note_detail_text.js'; | ||||||
| import treeUtils from './tree_utils.js'; | import treeUtils from './tree_utils.js'; | ||||||
|  |  | ||||||
| function getNotePathFromLink(url) { | function getNotePathFromLink(url) { | ||||||
| @@ -75,14 +75,14 @@ function goToLink(e) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function addLinkToEditor(linkTitle, linkHref) { | function addLinkToEditor(linkTitle, linkHref) { | ||||||
|     const editor = noteDetailService.getEditor(); |     const editor = noteDetailText.getEditor(); | ||||||
|     const doc = editor.document; |     const doc = editor.document; | ||||||
|  |  | ||||||
|     doc.enqueueChanges(() => editor.data.insertLink(linkTitle, linkHref), doc.selection); |     doc.enqueueChanges(() => editor.data.insertLink(linkTitle, linkHref), doc.selection); | ||||||
| } | } | ||||||
|  |  | ||||||
| function addTextToEditor(text) { | function addTextToEditor(text) { | ||||||
|     const editor = noteDetailService.getEditor(); |     const editor = noteDetailText.getEditor(); | ||||||
|     const doc = editor.document; |     const doc = editor.document; | ||||||
|  |  | ||||||
|     doc.enqueueChanges(() => editor.data.insertText(text), doc.selection); |     doc.enqueueChanges(() => editor.data.insertText(text), doc.selection); | ||||||
|   | |||||||
| @@ -9,11 +9,12 @@ import bundleService from "./bundle.js"; | |||||||
| import infoService from "./info.js"; | import infoService from "./info.js"; | ||||||
| import treeCache from "./tree_cache.js"; | import treeCache from "./tree_cache.js"; | ||||||
| import NoteFull from "../entities/note_full.js"; | import NoteFull from "../entities/note_full.js"; | ||||||
|  | import noteDetailCode from './note_detail_code.js'; | ||||||
|  | import noteDetailText from './note_detail_text.js'; | ||||||
|  |  | ||||||
| const $noteTitle = $("#note-title"); | const $noteTitle = $("#note-title"); | ||||||
|  |  | ||||||
| const $noteDetailText = $('#note-detail-text'); | const $noteDetailComponents = $(".note-detail-component"); | ||||||
| const $noteDetailCode = $('#note-detail-code'); |  | ||||||
| const $noteDetailSearch = $('#note-detail-search'); | const $noteDetailSearch = $('#note-detail-search'); | ||||||
| const $noteDetailRender = $('#note-detail-render'); | const $noteDetailRender = $('#note-detail-render'); | ||||||
| const $noteDetailAttachment = $('#note-detail-attachment'); | const $noteDetailAttachment = $('#note-detail-attachment'); | ||||||
| @@ -31,11 +32,6 @@ const $attachmentDownload = $("#attachment-download"); | |||||||
| const $attachmentOpen = $("#attachment-open"); | const $attachmentOpen = $("#attachment-open"); | ||||||
| const $searchString = $("#search-string"); | const $searchString = $("#search-string"); | ||||||
|  |  | ||||||
| const $executeScriptButton = $("#execute-script-button"); |  | ||||||
|  |  | ||||||
| let textEditor = null; |  | ||||||
| let codeEditor = null; |  | ||||||
|  |  | ||||||
| let currentNote = null; | let currentNote = null; | ||||||
|  |  | ||||||
| let noteChangeDisabled = false; | let noteChangeDisabled = false; | ||||||
| @@ -50,6 +46,12 @@ function getCurrentNoteId() { | |||||||
|     return currentNote ? currentNote.noteId : null; |     return currentNote ? currentNote.noteId : null; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function getCurrentNoteType() { | ||||||
|  |     const currentNote = getCurrentNote(); | ||||||
|  |  | ||||||
|  |     return currentNote ? currentNote.type : null; | ||||||
|  | } | ||||||
|  |  | ||||||
| function noteChanged() { | function noteChanged() { | ||||||
|     if (noteChangeDisabled) { |     if (noteChangeDisabled) { | ||||||
|         return; |         return; | ||||||
| @@ -90,18 +92,10 @@ async function saveNoteIfChanged() { | |||||||
|  |  | ||||||
| function updateNoteFromInputs(note) { | function updateNoteFromInputs(note) { | ||||||
|     if (note.type === 'text') { |     if (note.type === 'text') { | ||||||
|         let content = textEditor.getData(); |         note.content = noteDetailText.getContent(); | ||||||
|  |  | ||||||
|         // if content is only tags/whitespace (typically <p> </p>), then just make it empty |  | ||||||
|         // this is important when setting new note to code |  | ||||||
|         if (jQuery(content).text().trim() === '' && !content.includes("<img")) { |  | ||||||
|             content = ''; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         note.content = content; |  | ||||||
|     } |     } | ||||||
|     else if (note.type === 'code') { |     else if (note.type === 'code') { | ||||||
|         note.content = codeEditor.getValue(); |         note.content = noteDetailCode.getContent(); | ||||||
|     } |     } | ||||||
|     else if (note.type === 'search') { |     else if (note.type === 'search') { | ||||||
|         note.content = JSON.stringify({ |         note.content = JSON.stringify({ | ||||||
| @@ -151,7 +145,7 @@ async function showRenderNote() { | |||||||
|  |  | ||||||
|     $noteDetailRender.html(bundle.html); |     $noteDetailRender.html(bundle.html); | ||||||
|  |  | ||||||
|     bundleService.executeBundle(bundle); |     await bundleService.executeBundle(bundle); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function showFileNote() { | async function showFileNote() { | ||||||
| @@ -165,60 +159,6 @@ async function showFileNote() { | |||||||
|     $attachmentFileType.text(currentNote.mime); |     $attachmentFileType.text(currentNote.mime); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function showTextNote() { |  | ||||||
|     if (!textEditor) { |  | ||||||
|         await utils.requireLibrary(utils.CKEDITOR); |  | ||||||
|  |  | ||||||
|         textEditor = await BalloonEditor.create($noteDetailText[0], {}); |  | ||||||
|  |  | ||||||
|         textEditor.document.on('change', noteChanged); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // temporary workaround for https://github.com/ckeditor/ckeditor5-enter/issues/49 |  | ||||||
|     textEditor.setData(currentNote.content || "<p></p>"); |  | ||||||
|  |  | ||||||
|     $noteDetailText.show(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| async function showCodeNote() { |  | ||||||
|     if (!codeEditor) { |  | ||||||
|         await utils.requireLibrary(utils.CODE_MIRROR); |  | ||||||
|  |  | ||||||
|         CodeMirror.keyMap.default["Shift-Tab"] = "indentLess"; |  | ||||||
|         CodeMirror.keyMap.default["Tab"] = "indentMore"; |  | ||||||
|  |  | ||||||
|         CodeMirror.modeURL = 'libraries/codemirror/mode/%N/%N.js'; |  | ||||||
|  |  | ||||||
|         codeEditor = CodeMirror($("#note-detail-code")[0], { |  | ||||||
|             value: "", |  | ||||||
|             viewportMargin: Infinity, |  | ||||||
|             indentUnit: 4, |  | ||||||
|             matchBrackets: true, |  | ||||||
|             matchTags: {bothTags: true}, |  | ||||||
|             highlightSelectionMatches: {showToken: /\w/, annotateScrollbar: false}, |  | ||||||
|             lint: true, |  | ||||||
|             gutters: ["CodeMirror-lint-markers"], |  | ||||||
|             lineNumbers: true |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         codeEditor.on('change', noteChanged); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $noteDetailCode.show(); |  | ||||||
|  |  | ||||||
|     // this needs to happen after the element is shown, otherwise the editor won't be refresheds |  | ||||||
|     codeEditor.setValue(currentNote.content); |  | ||||||
|  |  | ||||||
|     const info = CodeMirror.findModeByMIME(currentNote.mime); |  | ||||||
|  |  | ||||||
|     if (info) { |  | ||||||
|         codeEditor.setOption("mode", info.mime); |  | ||||||
|         CodeMirror.autoLoadMode(codeEditor, info.mode); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     codeEditor.refresh(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function showSearchNote() { | function showSearchNote() { | ||||||
|     $noteDetailSearch.show(); |     $noteDetailSearch.show(); | ||||||
|  |  | ||||||
| @@ -235,6 +175,18 @@ function showSearchNote() { | |||||||
|     $searchString.on('input', noteChanged); |     $searchString.on('input', noteChanged); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | async function handleProtectedSession() { | ||||||
|  |     await protectedSessionService.ensureProtectedSession(currentNote.isProtected, false); | ||||||
|  |  | ||||||
|  |     if (currentNote.isProtected) { | ||||||
|  |         protectedSessionHolder.touchProtectedSession(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // this might be important if we focused on protected note when not in protected note and we got a dialog | ||||||
|  |     // to login, but we chose instead to come to another node - at that point the dialog is still visible and this will close it. | ||||||
|  |     protectedSessionService.ensureDialogIsClosed(); | ||||||
|  | } | ||||||
|  |  | ||||||
| async function loadNoteToEditor(noteId) { | async function loadNoteToEditor(noteId) { | ||||||
|     currentNote = await loadNote(noteId); |     currentNote = await loadNote(noteId); | ||||||
|  |  | ||||||
| @@ -246,48 +198,39 @@ async function loadNoteToEditor(noteId) { | |||||||
|  |  | ||||||
|     $noteIdDisplay.html(noteId); |     $noteIdDisplay.html(noteId); | ||||||
|  |  | ||||||
|     await protectedSessionService.ensureProtectedSession(currentNote.isProtected, false); |     await handleProtectedSession(); | ||||||
|  |  | ||||||
|     if (currentNote.isProtected) { |  | ||||||
|         protectedSessionHolder.touchProtectedSession(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // this might be important if we focused on protected note when not in protected note and we got a dialog |  | ||||||
|     // to login, but we chose instead to come to another node - at that point the dialog is still visible and this will close it. |  | ||||||
|     protectedSessionService.ensureDialogIsClosed(); |  | ||||||
|  |  | ||||||
|     $noteDetailWrapper.show(); |     $noteDetailWrapper.show(); | ||||||
|  |  | ||||||
|     noteChangeDisabled = true; |     noteChangeDisabled = true; | ||||||
|  |  | ||||||
|     $noteTitle.val(currentNote.title); |     try { | ||||||
|  |         $noteTitle.val(currentNote.title); | ||||||
|  |  | ||||||
|     noteTypeService.setNoteType(currentNote.type); |         noteTypeService.setNoteType(currentNote.type); | ||||||
|     noteTypeService.setNoteMime(currentNote.mime); |         noteTypeService.setNoteMime(currentNote.mime); | ||||||
|  |  | ||||||
|     $noteDetailText.hide(); |         $noteDetailComponents.hide(); | ||||||
|     $noteDetailSearch.hide(); |  | ||||||
|     $noteDetailCode.hide(); |  | ||||||
|     $noteDetailRender.html('').hide(); |  | ||||||
|     $noteDetailAttachment.hide(); |  | ||||||
|  |  | ||||||
|     if (currentNote.type === 'render') { |         if (currentNote.type === 'render') { | ||||||
|         await showRenderNote(); |             await showRenderNote(); | ||||||
|  |         } | ||||||
|  |         else if (currentNote.type === 'file') { | ||||||
|  |             await showFileNote(); | ||||||
|  |         } | ||||||
|  |         else if (currentNote.type === 'text') { | ||||||
|  |             await noteDetailText.showTextNote(); | ||||||
|  |         } | ||||||
|  |         else if (currentNote.type === 'code') { | ||||||
|  |             await noteDetailCode.showCodeNote(); | ||||||
|  |         } | ||||||
|  |         else if (currentNote.type === 'search') { | ||||||
|  |             showSearchNote(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     else if (currentNote.type === 'file') { |     finally { | ||||||
|         await showFileNote(); |         noteChangeDisabled = false; | ||||||
|     } |     } | ||||||
|     else if (currentNote.type === 'text') { |  | ||||||
|         await showTextNote(); |  | ||||||
|     } |  | ||||||
|     else if (currentNote.type === 'code') { |  | ||||||
|         await showCodeNote(); |  | ||||||
|     } |  | ||||||
|     else if (currentNote.type === 'search') { |  | ||||||
|         showSearchNote(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     noteChangeDisabled = false; |  | ||||||
|  |  | ||||||
|     setNoteBackgroundIfProtected(currentNote); |     setNoteBackgroundIfProtected(currentNote); | ||||||
|     treeService.setBranchBackgroundBasedOnProtectedStatus(noteId); |     treeService.setBranchBackgroundBasedOnProtectedStatus(noteId); | ||||||
| @@ -295,7 +238,7 @@ async function loadNoteToEditor(noteId) { | |||||||
|     // after loading new note make sure editor is scrolled to the top |     // after loading new note make sure editor is scrolled to the top | ||||||
|     $noteDetailWrapper.scrollTop(0); |     $noteDetailWrapper.scrollTop(0); | ||||||
|  |  | ||||||
|     loadLabelList(); |     await loadLabelList(); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function loadLabelList() { | async function loadLabelList() { | ||||||
| @@ -323,18 +266,14 @@ async function loadNote(noteId) { | |||||||
|     return new NoteFull(treeCache, row); |     return new NoteFull(treeCache, row); | ||||||
| } | } | ||||||
|  |  | ||||||
| function getEditor() { |  | ||||||
|     return textEditor; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function focus() { | function focus() { | ||||||
|     const note = getCurrentNote(); |     const note = getCurrentNote(); | ||||||
|  |  | ||||||
|     if (note.type === 'text') { |     if (note.type === 'text') { | ||||||
|         $noteDetailText.focus(); |         noteDetailText.focus(); | ||||||
|     } |     } | ||||||
|     else if (note.type === 'code') { |     else if (note.type === 'code') { | ||||||
|         codeEditor.focus(); |         noteDetailCode.focus(); | ||||||
|     } |     } | ||||||
|     else if (note.type === 'render' || note.type === 'file' || note.type === 'search') { |     else if (note.type === 'render' || note.type === 'file' || note.type === 'search') { | ||||||
|         // do nothing |         // do nothing | ||||||
| @@ -344,31 +283,6 @@ function focus() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function getCurrentNoteType() { |  | ||||||
|     const currentNote = getCurrentNote(); |  | ||||||
|  |  | ||||||
|     return currentNote ? currentNote.type : null; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| async function executeCurrentNote() { |  | ||||||
|     if (getCurrentNoteType() === 'code') { |  | ||||||
|         // make sure note is saved so we load latest changes |  | ||||||
|         await saveNoteIfChanged(); |  | ||||||
|  |  | ||||||
|         if (currentNote.mime.endsWith("env=frontend")) { |  | ||||||
|             const bundle = await server.get('script/bundle/' + getCurrentNoteId()); |  | ||||||
|  |  | ||||||
|             bundleService.executeBundle(bundle); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (currentNote.mime.endsWith("env=backend")) { |  | ||||||
|             await server.post('script/run/' + getCurrentNoteId()); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         infoService.showMessage("Note executed"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $attachmentDownload.click(() => utils.download(getAttachmentUrl())); | $attachmentDownload.click(() => utils.download(getAttachmentUrl())); | ||||||
|  |  | ||||||
| $attachmentOpen.click(() => { | $attachmentOpen.click(() => { | ||||||
| @@ -405,18 +319,13 @@ $(document).ready(() => { | |||||||
|         treeService.setNoteTitle(getCurrentNoteId(), title); |         treeService.setNoteTitle(getCurrentNoteId(), title); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     // so that tab jumps from note title (which has tabindex 1) |     noteDetailText.focus(); | ||||||
|     $noteDetailText.attr("tabindex", 2); |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // this makes sure that when user e.g. reloads the page or navigates away from the page, the note's content is saved | // 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 | // this sends the request asynchronously and doesn't wait for result | ||||||
| $(window).on('beforeunload', saveNoteIfChanged); | $(window).on('beforeunload', saveNoteIfChanged); | ||||||
|  |  | ||||||
| $(document).bind('keydown', "ctrl+return", executeCurrentNote); |  | ||||||
|  |  | ||||||
| $executeScriptButton.click(executeCurrentNote()); |  | ||||||
|  |  | ||||||
| setInterval(saveNoteIfChanged, 5000); | setInterval(saveNoteIfChanged, 5000); | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
| @@ -430,7 +339,8 @@ export default { | |||||||
|     getCurrentNoteType, |     getCurrentNoteType, | ||||||
|     getCurrentNoteId, |     getCurrentNoteId, | ||||||
|     newNoteCreated, |     newNoteCreated, | ||||||
|     getEditor, |  | ||||||
|     focus, |     focus, | ||||||
|     loadLabelList |     loadLabelList, | ||||||
|  |     saveNoteIfChanged, | ||||||
|  |     noteChanged | ||||||
| }; | }; | ||||||
							
								
								
									
										90
									
								
								src/public/javascripts/services/note_detail_code.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/public/javascripts/services/note_detail_code.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | |||||||
|  | import utils from "./utils.js"; | ||||||
|  | import bundleService from "./bundle.js"; | ||||||
|  | import infoService from "./info.js"; | ||||||
|  | import server from "./server.js"; | ||||||
|  | import noteDetailService from "./note_detail.js"; | ||||||
|  |  | ||||||
|  | let codeEditor = null; | ||||||
|  |  | ||||||
|  | const $noteDetailCode = $('#note-detail-code'); | ||||||
|  | const $executeScriptButton = $("#execute-script-button"); | ||||||
|  |  | ||||||
|  | async function showCodeNote() { | ||||||
|  |     if (!codeEditor) { | ||||||
|  |         await utils.requireLibrary(utils.CODE_MIRROR); | ||||||
|  |  | ||||||
|  |         CodeMirror.keyMap.default["Shift-Tab"] = "indentLess"; | ||||||
|  |         CodeMirror.keyMap.default["Tab"] = "indentMore"; | ||||||
|  |  | ||||||
|  |         CodeMirror.modeURL = 'libraries/codemirror/mode/%N/%N.js'; | ||||||
|  |  | ||||||
|  |         codeEditor = CodeMirror($("#note-detail-code")[0], { | ||||||
|  |             value: "", | ||||||
|  |             viewportMargin: Infinity, | ||||||
|  |             indentUnit: 4, | ||||||
|  |             matchBrackets: true, | ||||||
|  |             matchTags: {bothTags: true}, | ||||||
|  |             highlightSelectionMatches: {showToken: /\w/, annotateScrollbar: false}, | ||||||
|  |             lint: true, | ||||||
|  |             gutters: ["CodeMirror-lint-markers"], | ||||||
|  |             lineNumbers: true | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         codeEditor.on('change', noteDetailService.noteChanged); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $noteDetailCode.show(); | ||||||
|  |  | ||||||
|  |     const currentNote = noteDetailService.getCurrentNote(); | ||||||
|  |  | ||||||
|  |     // this needs to happen after the element is shown, otherwise the editor won't be refresheds | ||||||
|  |     codeEditor.setValue(currentNote.content); | ||||||
|  |  | ||||||
|  |     const info = CodeMirror.findModeByMIME(currentNote.mime); | ||||||
|  |  | ||||||
|  |     if (info) { | ||||||
|  |         codeEditor.setOption("mode", info.mime); | ||||||
|  |         CodeMirror.autoLoadMode(codeEditor, info.mode); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     codeEditor.refresh(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function getContent() { | ||||||
|  |     return codeEditor.getValue(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function focus() { | ||||||
|  |     codeEditor.focus(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function executeCurrentNote() { | ||||||
|  |     if (noteDetailService.getCurrentNoteType() === 'code') { | ||||||
|  |         // make sure note is saved so we load latest changes | ||||||
|  |         await noteDetailService.saveNoteIfChanged(); | ||||||
|  |  | ||||||
|  |         const currentNote = noteDetailService.getCurrentNote(); | ||||||
|  |  | ||||||
|  |         if (currentNote.mime.endsWith("env=frontend")) { | ||||||
|  |             const bundle = await server.get('script/bundle/' + getCurrentNoteId()); | ||||||
|  |  | ||||||
|  |             bundleService.executeBundle(bundle); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (currentNote.mime.endsWith("env=backend")) { | ||||||
|  |             await server.post('script/run/' + getCurrentNoteId()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         infoService.showMessage("Note executed"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $(document).bind('keydown', "ctrl+return", executeCurrentNote); | ||||||
|  |  | ||||||
|  | $executeScriptButton.click(executeCurrentNote); | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |     showCodeNote, | ||||||
|  |     getContent, | ||||||
|  |     focus | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								src/public/javascripts/services/note_detail_text.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/public/javascripts/services/note_detail_text.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | import utils from "./utils.js"; | ||||||
|  | import noteDetailService from './note_detail.js'; | ||||||
|  |  | ||||||
|  | const $noteDetailText = $('#note-detail-text'); | ||||||
|  |  | ||||||
|  | let textEditor = null; | ||||||
|  |  | ||||||
|  | async function showTextNote() { | ||||||
|  |     if (!textEditor) { | ||||||
|  |         await utils.requireLibrary(utils.CKEDITOR); | ||||||
|  |  | ||||||
|  |         textEditor = await BalloonEditor.create($noteDetailText[0], {}); | ||||||
|  |  | ||||||
|  |         textEditor.document.on('change', noteDetailService.noteChanged); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // temporary workaround for https://github.com/ckeditor/ckeditor5-enter/issues/49 | ||||||
|  |     textEditor.setData(noteDetailService.getCurrentNote().content || "<p></p>"); | ||||||
|  |  | ||||||
|  |     $noteDetailText.show(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function getContent() { | ||||||
|  |     let content = textEditor.getData(); | ||||||
|  |  | ||||||
|  |     // if content is only tags/whitespace (typically <p> </p>), then just make it empty | ||||||
|  |     // this is important when setting new note to code | ||||||
|  |     if (jQuery(content).text().trim() === '' && !content.includes("<img")) { | ||||||
|  |         content = ''; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return content; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function focus() { | ||||||
|  |     $noteDetailText.focus(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function getEditor() { | ||||||
|  |     return textEditor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |     showTextNote, | ||||||
|  |     getEditor, | ||||||
|  |     getContent, | ||||||
|  |     focus | ||||||
|  | } | ||||||
| @@ -28,6 +28,10 @@ | |||||||
|     align-items: center; |     align-items: center; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .note-detail-component { | ||||||
|  |     display: none; | ||||||
|  | } | ||||||
|  |  | ||||||
| #note-detail-text { | #note-detail-text { | ||||||
|     border: 0 !important; |     border: 0 !important; | ||||||
|     box-shadow: none !important; |     box-shadow: none !important; | ||||||
|   | |||||||
| @@ -133,9 +133,9 @@ | |||||||
|       </div> |       </div> | ||||||
|  |  | ||||||
|       <div style="position: relative; overflow: auto; grid-area: note-content; padding-left: 10px; padding-top: 10px;" id="note-detail-wrapper"> |       <div style="position: relative; overflow: auto; grid-area: note-content; padding-left: 10px; padding-top: 10px;" id="note-detail-wrapper"> | ||||||
|         <div id="note-detail-text" style="display: none;"></div> |         <div id="note-detail-text" class="note-detail-component"></div> | ||||||
|  |  | ||||||
|         <div id="note-detail-search" style="display: none;"> |         <div id="note-detail-search" class="note-detail-component"> | ||||||
|           <div style="display: flex; align-items: center;"> |           <div style="display: flex; align-items: center;"> | ||||||
|             <strong>Search string:    </strong> |             <strong>Search string:    </strong> | ||||||
|             <textarea rows="4" cols="50" id="search-string"></textarea> |             <textarea rows="4" cols="50" id="search-string"></textarea> | ||||||
| @@ -173,11 +173,11 @@ | |||||||
|           </p> |           </p> | ||||||
|         </div> |         </div> | ||||||
|  |  | ||||||
|         <div id="note-detail-code" style="display: none;"></div> |         <div id="note-detail-code" class="note-detail-component"></div> | ||||||
|  |  | ||||||
|         <div id="note-detail-render" style="display: none;"></div> |         <div id="note-detail-render" class="note-detail-component"></div> | ||||||
|  |  | ||||||
|         <div id="note-detail-attachment" style="display: none;"> |         <div id="note-detail-attachment" class="note-detail-component"> | ||||||
|           <table id="attachment-table"> |           <table id="attachment-table"> | ||||||
|             <tr> |             <tr> | ||||||
|               <th>File name:</th> |               <th>File name:</th> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user