mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
convert more note details to new style
This commit is contained in:
parent
39093cbc4c
commit
ff41904d72
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user