mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	convert more note details to new style
This commit is contained in:
		| @@ -121,12 +121,12 @@ async function loadNoteDetail(noteId, newTab = false) { | ||||
|     let ctx; | ||||
|  | ||||
|     if (noteContexts.length === 0 || newTab) { | ||||
|         const tabContent = $("#note-tab-content-template").clone(); | ||||
|         const $tabContent = $(".note-tab-content-template").clone(); | ||||
|  | ||||
|         tabContent.removeAttr('id'); | ||||
|         tabContent.attr('data-note-id', noteId); | ||||
|         $tabContent.removeClass('note-tab-content-template'); | ||||
|         $tabContent.attr('data-note-id', noteId); | ||||
|  | ||||
|         $noteTabContentsContainer.append(tabContent); | ||||
|         $noteTabContentsContainer.append($tabContent); | ||||
|  | ||||
|         // if it's a new tab explicitly by user then it's in background | ||||
|         ctx = new NoteContext(loadedNote, newTab); | ||||
|   | ||||
| @@ -5,109 +5,112 @@ import server from "./server.js"; | ||||
| import noteDetailService from "./note_detail.js"; | ||||
| import utils from "./utils.js"; | ||||
|  | ||||
| let codeEditor = null; | ||||
| class NoteDetailCode { | ||||
|  | ||||
| const $component = $('#note-detail-code'); | ||||
| const $executeScriptButton = $("#execute-script-button"); | ||||
|     /** | ||||
|      * @param {NoteContext} ctx | ||||
|      */ | ||||
|     constructor(ctx) { | ||||
|         this.ctx = ctx; | ||||
|         this.codeEditor = null; | ||||
|         this.$component = ctx.$noteTabContent.find('.note-detail-code'); | ||||
|         this.$executeScriptButton = ctx.$noteTabContent.find(".execute-script-button"); | ||||
|  | ||||
| async function show() { | ||||
|     await libraryLoader.requireLibrary(libraryLoader.CODE_MIRROR); | ||||
|         utils.bindShortcut("ctrl+return", this.executeCurrentNote); | ||||
|  | ||||
|     if (!codeEditor) { | ||||
|         CodeMirror.keyMap.default["Shift-Tab"] = "indentLess"; | ||||
|         CodeMirror.keyMap.default["Tab"] = "indentMore"; | ||||
|  | ||||
|         // these conflict with backward/forward navigation shortcuts | ||||
|         delete CodeMirror.keyMap.default["Alt-Left"]; | ||||
|         delete CodeMirror.keyMap.default["Alt-Right"]; | ||||
|  | ||||
|         CodeMirror.modeURL = 'libraries/codemirror/mode/%N/%N.js'; | ||||
|  | ||||
|         codeEditor = CodeMirror($component[0], { | ||||
|             value: "", | ||||
|             viewportMargin: Infinity, | ||||
|             indentUnit: 4, | ||||
|             matchBrackets: true, | ||||
|             matchTags: {bothTags: true}, | ||||
|             highlightSelectionMatches: {showToken: /\w/, annotateScrollbar: false}, | ||||
|             lint: true, | ||||
|             gutters: ["CodeMirror-lint-markers"], | ||||
|             lineNumbers: true, | ||||
|             tabindex: 100, | ||||
|             // we linewrap partly also because without it horizontal scrollbar displays only when you scroll | ||||
|             // all the way to the bottom of the note. With line wrap there's no horizontal scrollbar so no problem | ||||
|             lineWrapping: true | ||||
|         }); | ||||
|  | ||||
|         onNoteChange(noteDetailService.noteChanged); | ||||
|         this.$executeScriptButton.click(this.executeCurrentNote); | ||||
|     } | ||||
|  | ||||
|     $component.show(); | ||||
|     async show() { | ||||
|         await libraryLoader.requireLibrary(libraryLoader.CODE_MIRROR); | ||||
|  | ||||
|     const activeNote = noteDetailService.getActiveNote(); | ||||
|         if (!this.codeEditor) { | ||||
|             CodeMirror.keyMap.default["Shift-Tab"] = "indentLess"; | ||||
|             CodeMirror.keyMap.default["Tab"] = "indentMore"; | ||||
|  | ||||
|     // this needs to happen after the element is shown, otherwise the editor won't be refreshed | ||||
|     // CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check) | ||||
|     // we provide fallback | ||||
|     codeEditor.setValue(activeNote.content || ""); | ||||
|             // these conflict with backward/forward navigation shortcuts | ||||
|             delete CodeMirror.keyMap.default["Alt-Left"]; | ||||
|             delete CodeMirror.keyMap.default["Alt-Right"]; | ||||
|  | ||||
|     const info = CodeMirror.findModeByMIME(activeNote.mime); | ||||
|             CodeMirror.modeURL = 'libraries/codemirror/mode/%N/%N.js'; | ||||
|  | ||||
|     if (info) { | ||||
|         codeEditor.setOption("mode", info.mime); | ||||
|         CodeMirror.autoLoadMode(codeEditor, info.mode); | ||||
|     } | ||||
|             this.codeEditor = CodeMirror(this.$component[0], { | ||||
|                 value: "", | ||||
|                 viewportMargin: Infinity, | ||||
|                 indentUnit: 4, | ||||
|                 matchBrackets: true, | ||||
|                 matchTags: {bothTags: true}, | ||||
|                 highlightSelectionMatches: {showToken: /\w/, annotateScrollbar: false}, | ||||
|                 lint: true, | ||||
|                 gutters: ["CodeMirror-lint-markers"], | ||||
|                 lineNumbers: true, | ||||
|                 tabindex: 100, | ||||
|                 // we linewrap partly also because without it horizontal scrollbar displays only when you scroll | ||||
|                 // all the way to the bottom of the note. With line wrap there's no horizontal scrollbar so no problem | ||||
|                 lineWrapping: true | ||||
|             }); | ||||
|  | ||||
|     codeEditor.refresh(); | ||||
| } | ||||
|  | ||||
| function getContent() { | ||||
|     return codeEditor.getValue(); | ||||
| } | ||||
|  | ||||
| function focus() { | ||||
|     codeEditor.focus(); | ||||
| } | ||||
|  | ||||
| async function executeCurrentNote() { | ||||
|     // ctrl+enter is also used elsewhere so make sure we're running only when appropriate | ||||
|     if (noteDetailService.getActiveNoteType() !== 'code') { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     // make sure note is saved so we load latest changes | ||||
|     await noteDetailService.saveNotesIfChanged(); | ||||
|  | ||||
|     const activeNote = noteDetailService.getActiveNote(); | ||||
|  | ||||
|     if (activeNote.mime.endsWith("env=frontend")) { | ||||
|         await bundleService.getAndExecuteBundle(noteDetailService.getActiveNoteId()); | ||||
|     } | ||||
|  | ||||
|     if (activeNote.mime.endsWith("env=backend")) { | ||||
|         await server.post('script/run/' + noteDetailService.getActiveNoteId()); | ||||
|     } | ||||
|  | ||||
|     infoService.showMessage("Note executed"); | ||||
| } | ||||
|  | ||||
| function onNoteChange(func) { | ||||
|     codeEditor.on('change', func); | ||||
| } | ||||
|  | ||||
| utils.bindShortcut("ctrl+return", executeCurrentNote); | ||||
|  | ||||
| $executeScriptButton.click(executeCurrentNote); | ||||
|  | ||||
| export default { | ||||
|     show, | ||||
|     getContent, | ||||
|     focus, | ||||
|     onNoteChange, | ||||
|     cleanup: () => { | ||||
|         if (codeEditor) { | ||||
|             codeEditor.setValue(''); | ||||
|             this.onNoteChange(noteDetailService.noteChanged); | ||||
|         } | ||||
|     }, | ||||
|     scrollToTop: () => $component.scrollTop(0) | ||||
|  | ||||
|         this.$component.show(); | ||||
|  | ||||
|         // this needs to happen after the element is shown, otherwise the editor won't be refreshed | ||||
|         // CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check) | ||||
|         // we provide fallback | ||||
|         this.codeEditor.setValue(this.ctx.note.content || ""); | ||||
|  | ||||
|         const info = CodeMirror.findModeByMIME(this.ctx.note.mime); | ||||
|  | ||||
|         if (info) { | ||||
|             this.codeEditor.setOption("mode", info.mime); | ||||
|             CodeMirror.autoLoadMode(this.codeEditor, info.mode); | ||||
|         } | ||||
|  | ||||
|         this.codeEditor.refresh(); | ||||
|     } | ||||
|  | ||||
|     getContent() { | ||||
|         return this.codeEditor.getValue(); | ||||
|     } | ||||
|  | ||||
|     focus() { | ||||
|         this.codeEditor.focus(); | ||||
|     } | ||||
|  | ||||
|     async executeCurrentNote() { | ||||
|         // ctrl+enter is also used elsewhere so make sure we're running only when appropriate | ||||
|         if (this.ctx.note.type !== 'code') { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // make sure note is saved so we load latest changes | ||||
|         await noteDetailService.saveNotesIfChanged(); | ||||
|  | ||||
|         if (this.ctx.note.mime.endsWith("env=frontend")) { | ||||
|             await bundleService.getAndExecuteBundle(this.ctx.note.noteId); | ||||
|         } | ||||
|  | ||||
|         if (this.ctx.note.mime.endsWith("env=backend")) { | ||||
|             await server.post('script/run/' + this.ctx.note.noteId); | ||||
|         } | ||||
|  | ||||
|         infoService.showMessage("Note executed"); | ||||
|     } | ||||
|  | ||||
|     onNoteChange(func) { | ||||
|         this.codeEditor.on('change', func); | ||||
|     } | ||||
|  | ||||
|     cleanup() { | ||||
|         if (this.codeEditor) { | ||||
|             this.codeEditor.setValue(''); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     scrollToTop() { | ||||
|         this.$component.scrollTop(0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export default NoteDetailCode; | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -3,40 +3,55 @@ import server from "./server.js"; | ||||
| import noteDetailService from "./note_detail.js"; | ||||
| import attributeService from "./attributes.js"; | ||||
|  | ||||
| const $component = $('#note-detail-render'); | ||||
| const $noteDetailRenderHelp = $('#note-detail-render-help'); | ||||
| const $noteDetailRenderContent = $('#note-detail-render-content'); | ||||
| const $renderButton = $('#render-button'); | ||||
| class NoteDetailRender { | ||||
|     /** | ||||
|      * @param {NoteContext} ctx | ||||
|      */ | ||||
|     constructor(ctx) { | ||||
|         this.ctx = ctx; | ||||
|         this.$component = ctx.$noteTabContent.find('.note-detail-render'); | ||||
|         this.$noteDetailRenderHelp = ctx.$noteTabContent.find('.note-detail-render-help'); | ||||
|         this.$noteDetailRenderContent = ctx.$noteTabContent.find('.note-detail-render-content'); | ||||
|         this.$renderButton = ctx.$noteTabContent.find('.render-button'); | ||||
|  | ||||
| async function render() { | ||||
|     const attributes = await attributeService.getAttributes(); | ||||
|     const renderNotes = attributes.filter(attr => | ||||
|         attr.type === 'relation' | ||||
|         && attr.name === 'renderNote' | ||||
|         && !!attr.value); | ||||
|         this.$renderButton.click(this.show); | ||||
|     } | ||||
|  | ||||
|     $component.show(); | ||||
|     async show() { | ||||
|         const attributes = await attributeService.getAttributes(); | ||||
|         const renderNotes = attributes.filter(attr => | ||||
|             attr.type === 'relation' | ||||
|             && attr.name === 'renderNote' | ||||
|             && !!attr.value); | ||||
|  | ||||
|     $noteDetailRenderContent.empty(); | ||||
|     $noteDetailRenderContent.toggle(renderNotes.length > 0); | ||||
|     $noteDetailRenderHelp.toggle(renderNotes.length === 0); | ||||
|         this.$component.show(); | ||||
|  | ||||
|     for (const renderNote of renderNotes) { | ||||
|         const bundle = await server.get('script/bundle/' + renderNote.value); | ||||
|         this.$noteDetailRenderContent.empty(); | ||||
|         this.$noteDetailRenderContent.toggle(renderNotes.length > 0); | ||||
|         this.$noteDetailRenderHelp.toggle(renderNotes.length === 0); | ||||
|  | ||||
|         $noteDetailRenderContent.append(bundle.html); | ||||
|         for (const renderNote of renderNotes) { | ||||
|             const bundle = await server.get('script/bundle/' + renderNote.value); | ||||
|  | ||||
|         await bundleService.executeBundle(bundle, noteDetailService.getActiveNote()); | ||||
|             this.$noteDetailRenderContent.append(bundle.html); | ||||
|  | ||||
|             await bundleService.executeBundle(bundle, noteDetailService.getActiveNote()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     getContent() {} | ||||
|  | ||||
|     focus() {} | ||||
|  | ||||
|     onNoteChange() {} | ||||
|  | ||||
|     cleanup() { | ||||
|         this.$noteDetailRenderContent.empty(); | ||||
|     } | ||||
|  | ||||
|     scrollToTop() { | ||||
|         this.$component.scrollTop(0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| $renderButton.click(render); | ||||
|  | ||||
| export default { | ||||
|     show: render, | ||||
|     getContent: () => "", | ||||
|     focus: () => null, | ||||
|     onNoteChange: () => null, | ||||
|     cleanup: () => $noteDetailRenderContent.empty(), | ||||
|     scrollToTop: () => $component.scrollTop(0) | ||||
| } | ||||
| export default NoteDetailRender; | ||||
| @@ -1,46 +1,55 @@ | ||||
| import noteDetailService from "./note_detail.js"; | ||||
| import searchNotesService from "./search_notes.js"; | ||||
|  | ||||
| const $searchString = $("#search-string"); | ||||
| const $component = $('#note-detail-search'); | ||||
| const $refreshButton = $('#note-detail-search-refresh-results-button'); | ||||
| const $help = $("#note-detail-search-help"); | ||||
| class NoteDetailSearch { | ||||
|     /** | ||||
|      * @param {NoteContext} ctx | ||||
|      */ | ||||
|     constructor(ctx) { | ||||
|         this.ctx = ctx; | ||||
|         this.$searchString = ctx.$noteTabContent.find(".search-string"); | ||||
|         this.$component = ctx.$noteTabContent.find('.note-detail-search'); | ||||
|         this.$help = ctx.$noteTabContent.find(".note-detail-search-help"); | ||||
|         this.$refreshButton = ctx.$noteTabContent.find('.note-detail-search-refresh-results-button'); | ||||
|  | ||||
| function show() { | ||||
|     $help.html(searchNotesService.getHelpText()); | ||||
|         this.$refreshButton.click(async () => { | ||||
|             await noteDetailService.saveNotesIfChanged(); | ||||
|  | ||||
|     $component.show(); | ||||
|  | ||||
|     try { | ||||
|         const json = JSON.parse(noteDetailService.getActiveNote().content); | ||||
|  | ||||
|         $searchString.val(json.searchString); | ||||
|     } | ||||
|     catch (e) { | ||||
|         console.log(e); | ||||
|         $searchString.val(''); | ||||
|             await searchNotesService.refreshSearch(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     $searchString.on('input', noteDetailService.noteChanged); | ||||
|     show() { | ||||
|         this.$help.html(searchNotesService.getHelpText()); | ||||
|  | ||||
|         this.$component.show(); | ||||
|  | ||||
|         try { | ||||
|             const json = JSON.parse(this.ctx.note.content); | ||||
|  | ||||
|             this.$searchString.val(json.searchString); | ||||
|         } | ||||
|         catch (e) { | ||||
|             console.log(e); | ||||
|             this.$searchString.val(''); | ||||
|         } | ||||
|  | ||||
|         this.$searchString.on('input', noteDetailService.noteChanged); | ||||
|     } | ||||
|  | ||||
|     getContent() { | ||||
|         return JSON.stringify({ | ||||
|             searchString: this.$searchString.val() | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     focus() {} | ||||
|  | ||||
|     onNoteChange() {} | ||||
|  | ||||
|     cleanup() {} | ||||
|  | ||||
|     scrollToTop() {} | ||||
| } | ||||
|  | ||||
| function getContent() { | ||||
|     return JSON.stringify({ | ||||
|         searchString: $searchString.val() | ||||
|     }); | ||||
| } | ||||
|  | ||||
| $refreshButton.click(async () => { | ||||
|     await noteDetailService.saveNotesIfChanged(); | ||||
|  | ||||
|     await searchNotesService.refreshSearch(); | ||||
| }); | ||||
|  | ||||
| export default { | ||||
|     getContent, | ||||
|     show, | ||||
|     focus: () => null, | ||||
|     onNoteChange: () => null, | ||||
|     cleanup: () => null, | ||||
|     scrollToTop: () => null | ||||
| } | ||||
| export default NoteDetailSearch; | ||||
| @@ -53,7 +53,7 @@ class NoteDetailText { | ||||
|  | ||||
|         this.$component.show(); | ||||
|  | ||||
| //        this.textEditor.setData(this.ctx.note.content); | ||||
|         this.textEditor.setData(this.ctx.note.content); | ||||
|     } | ||||
|  | ||||
|     getContent() { | ||||
|   | ||||
| @@ -103,8 +103,8 @@ ul.fancytree-container { | ||||
|     display: none; | ||||
| } | ||||
|  | ||||
| #note-tab-content-template { | ||||
|     display: none; | ||||
| .note-tab-content-template { | ||||
|     display: none !important; | ||||
| } | ||||
|  | ||||
| .note-tab-content { | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| </div> | ||||
|  | ||||
| <div id="note-tab-container"> | ||||
|     <div id="note-tab-content-template" class="note-tab-content"> | ||||
|     <div class="note-tab-content note-tab-content-template"> | ||||
|         <% include title.ejs %> | ||||
|  | ||||
|         <div class="note-detail-script-area"></div> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user