mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
Allow marking code (JavaScript) notes for execution after application loads, closes #19
This commit is contained in:
parent
a42fd9b090
commit
9f3d46ddb1
@ -203,3 +203,11 @@ window.onerror = function (msg, url, lineNo, columnNo, error) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$("#logout-button").toggle(!isElectron());
|
$("#logout-button").toggle(!isElectron());
|
||||||
|
|
||||||
|
$(document).ready(() => {
|
||||||
|
server.get("script/startup").then(scripts => {
|
||||||
|
for (const script of scripts) {
|
||||||
|
executeScript(script);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -214,14 +214,14 @@ const noteEditor = (function() {
|
|||||||
return currentNote ? currentNote.detail.type : null;
|
return currentNote ? currentNote.detail.type : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function executeScript() {
|
async function executeCurrentNote() {
|
||||||
if (getCurrentNoteType() === 'code') {
|
if (getCurrentNoteType() === 'code') {
|
||||||
// make sure note is saved so we load latest changes
|
// make sure note is saved so we load latest changes
|
||||||
await saveNoteIfChanged();
|
await saveNoteIfChanged();
|
||||||
|
|
||||||
const subTreeScripts = await server.get('script/subtree/' + getCurrentNoteId());
|
const script = await server.get('script/subtree/' + getCurrentNoteId());
|
||||||
|
|
||||||
eval("(async function() {" + subTreeScripts + "})()");
|
executeScript(script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ const noteEditor = (function() {
|
|||||||
noteDetailEl.attr("tabindex", 2);
|
noteDetailEl.attr("tabindex", 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).bind('keydown', "ctrl+return", executeScript);
|
$(document).bind('keydown', "ctrl+return", executeCurrentNote);
|
||||||
|
|
||||||
setInterval(saveNoteIfChanged, 5000);
|
setInterval(saveNoteIfChanged, 5000);
|
||||||
|
|
||||||
@ -281,6 +281,6 @@ const noteEditor = (function() {
|
|||||||
newNoteCreated,
|
newNoteCreated,
|
||||||
getEditor,
|
getEditor,
|
||||||
focus,
|
focus,
|
||||||
executeScript
|
executeCurrentNote
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -114,3 +114,7 @@ async function stopWatch(what, func) {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function executeScript(script) {
|
||||||
|
eval("(async function() {" + script + "})()");
|
||||||
|
}
|
@ -8,6 +8,7 @@ const log = require('../../services/log');
|
|||||||
const sql = require('../../services/sql');
|
const sql = require('../../services/sql');
|
||||||
const notes = require('../../services/notes');
|
const notes = require('../../services/notes');
|
||||||
const protected_session = require('../../services/protected_session');
|
const protected_session = require('../../services/protected_session');
|
||||||
|
const attributes = require('../../services/attributes');
|
||||||
|
|
||||||
router.post('/exec', auth.checkApiAuth, wrap(async (req, res, next) => {
|
router.post('/exec', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||||
log.info('Executing script: ' + req.body.script);
|
log.info('Executing script: ' + req.body.script);
|
||||||
@ -19,6 +20,18 @@ router.post('/exec', auth.checkApiAuth, wrap(async (req, res, next) => {
|
|||||||
res.send(ret);
|
res.send(ret);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
router.get('/startup', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||||
|
const noteIds = await attributes.getNoteIdsWithAttribute("run_on_startup");
|
||||||
|
|
||||||
|
const scripts = [];
|
||||||
|
|
||||||
|
for (const noteId of noteIds) {
|
||||||
|
scripts.push(await getNoteWithSubtreeScript(noteId, req));
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send(scripts);
|
||||||
|
}));
|
||||||
|
|
||||||
router.get('/subtree/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
router.get('/subtree/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
|
|
||||||
@ -29,6 +42,14 @@ router.get('/subtree/:noteId', auth.checkApiAuth, wrap(async (req, res, next) =>
|
|||||||
res.send(subTreeScripts + noteScript);
|
res.send(subTreeScripts + noteScript);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
async function getNoteWithSubtreeScript(noteId, req) {
|
||||||
|
const noteScript = (await notes.getNoteById(noteId, req)).note_text;
|
||||||
|
|
||||||
|
const subTreeScripts = await getSubTreeScripts(noteId, [noteId], req);
|
||||||
|
|
||||||
|
return subTreeScripts + noteScript;
|
||||||
|
}
|
||||||
|
|
||||||
async function getSubTreeScripts(parentId, includedNoteIds, dataKey) {
|
async function getSubTreeScripts(parentId, includedNoteIds, dataKey) {
|
||||||
const children = await sql.getAll(`SELECT notes.note_id, notes.note_title, notes.note_text, notes.is_protected
|
const children = await sql.getAll(`SELECT notes.note_id, notes.note_title, notes.note_text, notes.is_protected
|
||||||
FROM notes JOIN notes_tree USING(note_id)
|
FROM notes JOIN notes_tree USING(note_id)
|
||||||
|
@ -9,10 +9,15 @@ async function getNoteAttributeMap(noteId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getNoteIdWithAttribute(name, value) {
|
async function getNoteIdWithAttribute(name, value) {
|
||||||
return await sql.getFirstValue(`SELECT notes.note_id FROM notes JOIN attributes USING(note_id)
|
return await sql.getFirstValue(`SELECT DISTINCT notes.note_id FROM notes JOIN attributes USING(note_id)
|
||||||
WHERE notes.is_deleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, value]);
|
WHERE notes.is_deleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getNoteIdsWithAttribute(name) {
|
||||||
|
return await sql.getFirstColumn(`SELECT DISTINCT notes.note_id FROM notes JOIN attributes USING(note_id)
|
||||||
|
WHERE notes.is_deleted = 0 AND attributes.name = ?`, [name]);
|
||||||
|
}
|
||||||
|
|
||||||
async function createAttribute(noteId, name, value = null, sourceId = null) {
|
async function createAttribute(noteId, name, value = null, sourceId = null) {
|
||||||
const now = utils.nowDate();
|
const now = utils.nowDate();
|
||||||
const attributeId = utils.newAttributeId();
|
const attributeId = utils.newAttributeId();
|
||||||
@ -32,5 +37,6 @@ async function createAttribute(noteId, name, value = null, sourceId = null) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
getNoteAttributeMap,
|
getNoteAttributeMap,
|
||||||
getNoteIdWithAttribute,
|
getNoteIdWithAttribute,
|
||||||
|
getNoteIdsWithAttribute,
|
||||||
createAttribute
|
createAttribute
|
||||||
};
|
};
|
@ -98,7 +98,7 @@
|
|||||||
<button class="btn btn-sm"
|
<button class="btn btn-sm"
|
||||||
style="display: none; margin-right: 10px"
|
style="display: none; margin-right: 10px"
|
||||||
id="execute-script-button"
|
id="execute-script-button"
|
||||||
onclick="noteEditor.executeScript()">Execute <kbd>Ctrl+Enter</kbd></button>
|
onclick="noteEditor.executeCurrentNote()">Execute <kbd>Ctrl+Enter</kbd></button>
|
||||||
|
|
||||||
<div class="dropdown" id="note-type">
|
<div class="dropdown" id="note-type">
|
||||||
<button id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="btn btn-sm">
|
<button id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="btn btn-sm">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user