mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +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; |     let ctx; | ||||||
|  |  | ||||||
|     if (noteContexts.length === 0 || newTab) { |     if (noteContexts.length === 0 || newTab) { | ||||||
|         const tabContent = $("#note-tab-content-template").clone(); |         const $tabContent = $(".note-tab-content-template").clone(); | ||||||
|  |  | ||||||
|         tabContent.removeAttr('id'); |         $tabContent.removeClass('note-tab-content-template'); | ||||||
|         tabContent.attr('data-note-id', noteId); |         $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 |         // if it's a new tab explicitly by user then it's in background | ||||||
|         ctx = new NoteContext(loadedNote, newTab); |         ctx = new NoteContext(loadedNote, newTab); | ||||||
|   | |||||||
| @@ -5,109 +5,112 @@ import server from "./server.js"; | |||||||
| import noteDetailService from "./note_detail.js"; | import noteDetailService from "./note_detail.js"; | ||||||
| import utils from "./utils.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() { |         utils.bindShortcut("ctrl+return", this.executeCurrentNote); | ||||||
|     await libraryLoader.requireLibrary(libraryLoader.CODE_MIRROR); |  | ||||||
|  |  | ||||||
|     if (!codeEditor) { |         this.$executeScriptButton.click(this.executeCurrentNote); | ||||||
|         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); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $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 |             // these conflict with backward/forward navigation shortcuts | ||||||
|     // CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check) |             delete CodeMirror.keyMap.default["Alt-Left"]; | ||||||
|     // we provide fallback |             delete CodeMirror.keyMap.default["Alt-Right"]; | ||||||
|     codeEditor.setValue(activeNote.content || ""); |  | ||||||
|  |  | ||||||
|     const info = CodeMirror.findModeByMIME(activeNote.mime); |             CodeMirror.modeURL = 'libraries/codemirror/mode/%N/%N.js'; | ||||||
|  |  | ||||||
|     if (info) { |             this.codeEditor = CodeMirror(this.$component[0], { | ||||||
|         codeEditor.setOption("mode", info.mime); |                 value: "", | ||||||
|         CodeMirror.autoLoadMode(codeEditor, info.mode); |                 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(); |             this.onNoteChange(noteDetailService.noteChanged); | ||||||
| } |  | ||||||
|  |  | ||||||
| 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(''); |  | ||||||
|         } |         } | ||||||
|     }, |  | ||||||
|     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 noteDetailService from "./note_detail.js"; | ||||||
| import attributeService from "./attributes.js"; | import attributeService from "./attributes.js"; | ||||||
|  |  | ||||||
| const $component = $('#note-detail-render'); | class NoteDetailRender { | ||||||
| const $noteDetailRenderHelp = $('#note-detail-render-help'); |     /** | ||||||
| const $noteDetailRenderContent = $('#note-detail-render-content'); |      * @param {NoteContext} ctx | ||||||
| const $renderButton = $('#render-button'); |      */ | ||||||
|  |     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() { |         this.$renderButton.click(this.show); | ||||||
|     const attributes = await attributeService.getAttributes(); |     } | ||||||
|     const renderNotes = attributes.filter(attr => |  | ||||||
|         attr.type === 'relation' |  | ||||||
|         && attr.name === 'renderNote' |  | ||||||
|         && !!attr.value); |  | ||||||
|  |  | ||||||
|     $component.show(); |     async show() { | ||||||
|  |         const attributes = await attributeService.getAttributes(); | ||||||
|  |         const renderNotes = attributes.filter(attr => | ||||||
|  |             attr.type === 'relation' | ||||||
|  |             && attr.name === 'renderNote' | ||||||
|  |             && !!attr.value); | ||||||
|  |  | ||||||
|     $noteDetailRenderContent.empty(); |         this.$component.show(); | ||||||
|     $noteDetailRenderContent.toggle(renderNotes.length > 0); |  | ||||||
|     $noteDetailRenderHelp.toggle(renderNotes.length === 0); |  | ||||||
|  |  | ||||||
|     for (const renderNote of renderNotes) { |         this.$noteDetailRenderContent.empty(); | ||||||
|         const bundle = await server.get('script/bundle/' + renderNote.value); |         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 NoteDetailRender; | ||||||
|  |  | ||||||
| export default { |  | ||||||
|     show: render, |  | ||||||
|     getContent: () => "", |  | ||||||
|     focus: () => null, |  | ||||||
|     onNoteChange: () => null, |  | ||||||
|     cleanup: () => $noteDetailRenderContent.empty(), |  | ||||||
|     scrollToTop: () => $component.scrollTop(0) |  | ||||||
| } |  | ||||||
| @@ -1,46 +1,55 @@ | |||||||
| import noteDetailService from "./note_detail.js"; | import noteDetailService from "./note_detail.js"; | ||||||
| import searchNotesService from "./search_notes.js"; | import searchNotesService from "./search_notes.js"; | ||||||
|  |  | ||||||
| const $searchString = $("#search-string"); | class NoteDetailSearch { | ||||||
| const $component = $('#note-detail-search'); |     /** | ||||||
| const $refreshButton = $('#note-detail-search-refresh-results-button'); |      * @param {NoteContext} ctx | ||||||
| const $help = $("#note-detail-search-help"); |      */ | ||||||
|  |     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() { |         this.$refreshButton.click(async () => { | ||||||
|     $help.html(searchNotesService.getHelpText()); |             await noteDetailService.saveNotesIfChanged(); | ||||||
|  |  | ||||||
|     $component.show(); |             await searchNotesService.refreshSearch(); | ||||||
|  |         }); | ||||||
|     try { |  | ||||||
|         const json = JSON.parse(noteDetailService.getActiveNote().content); |  | ||||||
|  |  | ||||||
|         $searchString.val(json.searchString); |  | ||||||
|     } |  | ||||||
|     catch (e) { |  | ||||||
|         console.log(e); |  | ||||||
|         $searchString.val(''); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $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() { | export default NoteDetailSearch; | ||||||
|     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 |  | ||||||
| } |  | ||||||
| @@ -53,7 +53,7 @@ class NoteDetailText { | |||||||
|  |  | ||||||
|         this.$component.show(); |         this.$component.show(); | ||||||
|  |  | ||||||
| //        this.textEditor.setData(this.ctx.note.content); |         this.textEditor.setData(this.ctx.note.content); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     getContent() { |     getContent() { | ||||||
|   | |||||||
| @@ -103,8 +103,8 @@ ul.fancytree-container { | |||||||
|     display: none; |     display: none; | ||||||
| } | } | ||||||
|  |  | ||||||
| #note-tab-content-template { | .note-tab-content-template { | ||||||
|     display: none; |     display: none !important; | ||||||
| } | } | ||||||
|  |  | ||||||
| .note-tab-content { | .note-tab-content { | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| </div> | </div> | ||||||
|  |  | ||||||
| <div id="note-tab-container"> | <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 %> |         <% include title.ejs %> | ||||||
|  |  | ||||||
|         <div class="note-detail-script-area"></div> |         <div class="note-detail-script-area"></div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user