mirror of
https://github.com/zadam/trilium.git
synced 2024-09-20 23:55:59 +08:00
refactored note creation methods into a separate service
This commit is contained in:
parent
822a8509b3
commit
66204811cf
|
@ -103,6 +103,11 @@ class NoteShort {
|
|||
}
|
||||
}
|
||||
|
||||
/** @returns {string[]} */
|
||||
getBranchIds() {
|
||||
return Object.values(this.parentToBranch);
|
||||
}
|
||||
|
||||
/** @returns {Promise<Branch[]>} */
|
||||
async getBranches() {
|
||||
const branchIds = Object.values(this.parentToBranch);
|
||||
|
|
|
@ -5,6 +5,7 @@ import contextMenuWidget from "./services/context_menu.js";
|
|||
import treeChangesService from "./services/branches.js";
|
||||
import utils from "./services/utils.js";
|
||||
import appContext from "./services/app_context.js";
|
||||
import noteCreateService from "./services/note_create.js";
|
||||
|
||||
window.glob.isDesktop = utils.isDesktop;
|
||||
window.glob.isMobile = utils.isMobile;
|
||||
|
@ -111,10 +112,14 @@ $detail.on("click", ".note-menu-button", async e => {
|
|||
const parentNoteId = node.data.parentNoteId;
|
||||
const isProtected = await treeService.getParentProtectedStatus(node);
|
||||
|
||||
treeService.createNote(node, parentNoteId, 'after', { isProtected: isProtected });
|
||||
noteCreateService.createNote(parentNoteId, {
|
||||
isProtected: isProtected,
|
||||
target: 'after',
|
||||
targetBranchId: node.data.branchId
|
||||
});
|
||||
}
|
||||
else if (cmd === "insertChildNote") {
|
||||
treeService.createNote(node, node.data.noteId, 'into');
|
||||
noteCreateService.createNote(node.data.noteId);
|
||||
}
|
||||
else if (cmd === "delete") {
|
||||
if (await treeChangesService.deleteNodes([node])) {
|
||||
|
|
|
@ -495,4 +495,26 @@ $(window).on('beforeunload', () => {
|
|||
appContext.trigger('beforeUnload');
|
||||
});
|
||||
|
||||
function isNotePathInAddress() {
|
||||
const [notePath, tabId] = getHashValueFromAddress();
|
||||
|
||||
return notePath.startsWith("root")
|
||||
// empty string is for empty/uninitialized tab
|
||||
|| (notePath === '' && !!tabId);
|
||||
}
|
||||
|
||||
function getHashValueFromAddress() {
|
||||
const str = document.location.hash ? document.location.hash.substr(1) : ""; // strip initial #
|
||||
|
||||
return str.split("-");
|
||||
}
|
||||
|
||||
$(window).on('hashchange', function() {
|
||||
if (isNotePathInAddress()) {
|
||||
const [notePath, tabId] = getHashValueFromAddress();
|
||||
|
||||
appContext.switchToTab(tabId, notePath);
|
||||
}
|
||||
});
|
||||
|
||||
export default appContext;
|
89
src/public/javascripts/services/note_create.js
Normal file
89
src/public/javascripts/services/note_create.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
import hoistedNoteService from "./hoisted_note.js";
|
||||
import appContext from "./app_context.js";
|
||||
import utils from "./utils.js";
|
||||
import protectedSessionHolder from "./protected_session_holder.js";
|
||||
import server from "./server.js";
|
||||
import ws from "./ws.js";
|
||||
import treeCache from "./tree_cache.js";
|
||||
import toastService from "./toast.js";
|
||||
|
||||
async function createNewTopLevelNote() {
|
||||
const hoistedNoteId = await hoistedNoteService.getHoistedNoteId();
|
||||
|
||||
await createNote(hoistedNoteId);
|
||||
}
|
||||
|
||||
async function createNote(parentNoteId, options = {}) {
|
||||
options = Object.assign({
|
||||
activate: true,
|
||||
target: 'into'
|
||||
}, options);
|
||||
|
||||
// if isProtected isn't available (user didn't enter password yet), then note is created as unencrypted
|
||||
// but this is quite weird since user doesn't see WHERE the note is being created so it shouldn't occur often
|
||||
if (!options.isProtected || !protectedSessionHolder.isProtectedSessionAvailable()) {
|
||||
options.isProtected = false;
|
||||
}
|
||||
|
||||
if (appContext.getActiveTabNoteType() !== 'text') {
|
||||
options.saveSelection = false;
|
||||
}
|
||||
|
||||
if (options.saveSelection && utils.isCKEditorInitialized()) {
|
||||
[options.title, options.content] = parseSelectedHtml(window.cutToNote.getSelectedHtml());
|
||||
}
|
||||
|
||||
const newNoteName = options.title || "new note";
|
||||
|
||||
const {note, branch} = await server.post(`notes/${parentNoteId}/children?target=${options.target}&targetBranchId=${options.targetBranchId}`, {
|
||||
title: newNoteName,
|
||||
content: options.content || "",
|
||||
isProtected: options.isProtected,
|
||||
type: options.type
|
||||
});
|
||||
|
||||
if (options.saveSelection && utils.isCKEditorInitialized()) {
|
||||
// we remove the selection only after it was saved to server to make sure we don't lose anything
|
||||
window.cutToNote.removeSelection();
|
||||
}
|
||||
|
||||
if (options.activate) {
|
||||
const activeTabContext = appContext.getActiveTabContext();
|
||||
activeTabContext.setNote(note.noteId);
|
||||
}
|
||||
|
||||
return {note, branch};
|
||||
}
|
||||
|
||||
/* If first element is heading, parse it out and use it as a new heading. */
|
||||
function parseSelectedHtml(selectedHtml) {
|
||||
const dom = $.parseHTML(selectedHtml);
|
||||
|
||||
if (dom.length > 0 && dom[0].tagName && dom[0].tagName.match(/h[1-6]/i)) {
|
||||
const title = $(dom[0]).text();
|
||||
// remove the title from content (only first occurence)
|
||||
const content = selectedHtml.replace(dom[0].outerHTML, "");
|
||||
|
||||
return [title, content];
|
||||
}
|
||||
else {
|
||||
return [null, selectedHtml];
|
||||
}
|
||||
}
|
||||
|
||||
async function duplicateNote(noteId, parentNoteId) {
|
||||
const {note} = await server.post(`notes/${noteId}/duplicate/${parentNoteId}`);
|
||||
|
||||
await ws.waitForMaxKnownSyncId();
|
||||
|
||||
await appContext.activateOrOpenNote(note.noteId);
|
||||
|
||||
const origNote = await treeCache.getNote(noteId);
|
||||
toastService.showMessage(`Note "${origNote.title}" has been duplicated`);
|
||||
}
|
||||
|
||||
export default {
|
||||
createNote,
|
||||
createNewTopLevelNote,
|
||||
duplicateNote
|
||||
};
|
|
@ -133,85 +133,6 @@ async function getSomeNotePath(note) {
|
|||
return path.reverse().join('/');
|
||||
}
|
||||
|
||||
function isNotePathInAddress() {
|
||||
const [notePath, tabId] = getHashValueFromAddress();
|
||||
|
||||
return notePath.startsWith("root")
|
||||
// empty string is for empty/uninitialized tab
|
||||
|| (notePath === '' && !!tabId);
|
||||
}
|
||||
|
||||
function getHashValueFromAddress() {
|
||||
const str = document.location.hash ? document.location.hash.substr(1) : ""; // strip initial #
|
||||
|
||||
return str.split("-");
|
||||
}
|
||||
|
||||
async function createNewTopLevelNote() {
|
||||
const hoistedNoteId = await hoistedNoteService.getHoistedNoteId();
|
||||
|
||||
const rootNode = appContext.getMainNoteTree().getNodesByNoteId(hoistedNoteId)[0];
|
||||
|
||||
await createNote(rootNode, hoistedNoteId, "into");
|
||||
}
|
||||
|
||||
async function createNote(node, parentNoteId, target, extraOptions = {}) {
|
||||
utils.assertArguments(node, parentNoteId, target);
|
||||
|
||||
extraOptions.activate = extraOptions.activate === undefined ? true : !!extraOptions.activate;
|
||||
|
||||
// if isProtected isn't available (user didn't enter password yet), then note is created as unencrypted
|
||||
// but this is quite weird since user doesn't see WHERE the note is being created so it shouldn't occur often
|
||||
if (!extraOptions.isProtected || !protectedSessionHolder.isProtectedSessionAvailable()) {
|
||||
extraOptions.isProtected = false;
|
||||
}
|
||||
|
||||
if (appContext.getActiveTabNoteType() !== 'text') {
|
||||
extraOptions.saveSelection = false;
|
||||
}
|
||||
|
||||
if (extraOptions.saveSelection && utils.isCKEditorInitialized()) {
|
||||
[extraOptions.title, extraOptions.content] = parseSelectedHtml(window.cutToNote.getSelectedHtml());
|
||||
}
|
||||
|
||||
const newNoteName = extraOptions.title || "new note";
|
||||
|
||||
const {note, branch} = await server.post(`notes/${parentNoteId}/children?target=${target}&targetBranchId=${node.data.branchId}`, {
|
||||
title: newNoteName,
|
||||
content: extraOptions.content || "",
|
||||
isProtected: extraOptions.isProtected,
|
||||
type: extraOptions.type
|
||||
});
|
||||
|
||||
if (extraOptions.saveSelection && utils.isCKEditorInitialized()) {
|
||||
// we remove the selection only after it was saved to server to make sure we don't lose anything
|
||||
window.cutToNote.removeSelection();
|
||||
}
|
||||
|
||||
if (extraOptions.activate) {
|
||||
const activeTabContext = appContext.getActiveTabContext();
|
||||
activeTabContext.setNote(note.noteId);
|
||||
}
|
||||
|
||||
return {note, branch};
|
||||
}
|
||||
|
||||
/* If first element is heading, parse it out and use it as a new heading. */
|
||||
function parseSelectedHtml(selectedHtml) {
|
||||
const dom = $.parseHTML(selectedHtml);
|
||||
|
||||
if (dom.length > 0 && dom[0].tagName && dom[0].tagName.match(/h[1-6]/i)) {
|
||||
const title = $(dom[0]).text();
|
||||
// remove the title from content (only first occurence)
|
||||
const content = selectedHtml.replace(dom[0].outerHTML, "");
|
||||
|
||||
return [title, content];
|
||||
}
|
||||
else {
|
||||
return [null, selectedHtml];
|
||||
}
|
||||
}
|
||||
|
||||
async function sortAlphabetically(noteId) {
|
||||
await server.put('notes/' + noteId + '/sort');
|
||||
}
|
||||
|
@ -228,25 +149,6 @@ ws.subscribeToMessages(message => {
|
|||
}
|
||||
});
|
||||
|
||||
$(window).on('hashchange', function() {
|
||||
if (isNotePathInAddress()) {
|
||||
const [notePath, tabId] = getHashValueFromAddress();
|
||||
|
||||
appContext.switchToTab(tabId, notePath);
|
||||
}
|
||||
});
|
||||
|
||||
async function duplicateNote(noteId, parentNoteId) {
|
||||
const {note} = await server.post(`notes/${noteId}/duplicate/${parentNoteId}`);
|
||||
|
||||
await ws.waitForMaxKnownSyncId();
|
||||
|
||||
await appContext.activateOrOpenNote(note.noteId);
|
||||
|
||||
const origNote = await treeCache.getNote(noteId);
|
||||
toastService.showMessage(`Note "${origNote.title}" has been duplicated`);
|
||||
}
|
||||
|
||||
async function getParentProtectedStatus(node) {
|
||||
return await hoistedNoteService.isRootNode(node) ? 0 : node.getParent().data.isProtected;
|
||||
}
|
||||
|
@ -361,12 +263,9 @@ async function getNotePathTitle(notePath) {
|
|||
}
|
||||
|
||||
export default {
|
||||
createNote,
|
||||
sortAlphabetically,
|
||||
resolveNotePath,
|
||||
getSomeNotePath,
|
||||
createNewTopLevelNote,
|
||||
duplicateNote,
|
||||
getRunPath,
|
||||
getParentProtectedStatus,
|
||||
getNotePath,
|
||||
|
|
|
@ -8,6 +8,7 @@ import hoistedNoteService from './hoisted_note.js';
|
|||
import clipboard from './clipboard.js';
|
||||
import protectedSessionHolder from "./protected_session_holder.js";
|
||||
import appContext from "./app_context.js";
|
||||
import noteCreateService from "./note_create.js";
|
||||
|
||||
class TreeContextMenu {
|
||||
/**
|
||||
|
@ -110,7 +111,9 @@ class TreeContextMenu {
|
|||
const isProtected = await treeService.getParentProtectedStatus(this.node);
|
||||
const type = cmd.split("_")[1];
|
||||
|
||||
treeService.createNote(this.node, parentNoteId, 'after', {
|
||||
noteCreateService.createNote(parentNoteId, {
|
||||
target: 'after',
|
||||
targetBranchId: this.node.data.branchId,
|
||||
type: type,
|
||||
isProtected: isProtected
|
||||
});
|
||||
|
@ -118,7 +121,7 @@ class TreeContextMenu {
|
|||
else if (cmd.startsWith("insertChildNote")) {
|
||||
const type = cmd.split("_")[1];
|
||||
|
||||
treeService.createNote(this.node, this.node.data.noteId, 'into', {
|
||||
noteCreateService.createNote(noteId, {
|
||||
type: type,
|
||||
isProtected: this.node.data.isProtected
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@ import ws from "../services/ws.js";
|
|||
import appContext from "../services/app_context.js";
|
||||
import TabAwareWidget from "./tab_aware_widget.js";
|
||||
import server from "../services/server.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="tree">
|
||||
|
@ -545,7 +546,9 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
return;
|
||||
}
|
||||
|
||||
await treeService.createNote(node, parentNoteId, 'after', {
|
||||
await noteCreateService.createNote(parentNoteId, {
|
||||
target: 'after',
|
||||
targetBranchId: node.data.branchId,
|
||||
isProtected: isProtected,
|
||||
saveSelection: true
|
||||
});
|
||||
|
@ -555,7 +558,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
const node = this.getActiveNode();
|
||||
|
||||
if (node) {
|
||||
await treeService.createNote(node, node.data.noteId, 'into', {
|
||||
await noteCreateService.createNote(node.data.noteId, {
|
||||
isProtected: node.data.isProtected,
|
||||
saveSelection: false
|
||||
});
|
||||
|
@ -566,7 +569,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||
const node = this.getActiveNode();
|
||||
|
||||
if (node) {
|
||||
await treeService.createNote(node, node.data.noteId, 'into', {
|
||||
await noteCreateService.createNote(node.data.noteId, {
|
||||
isProtected: node.data.isProtected,
|
||||
saveSelection: true
|
||||
});
|
||||
|
|
|
@ -3,6 +3,7 @@ import treeService from "../services/tree.js";
|
|||
import treeCache from "../services/tree_cache.js";
|
||||
import toastService from "../services/toast.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
|
||||
const helpText = `
|
||||
<strong>Search tips</strong> - also see <button class="btn btn-sm" type="button" data-help-page="Search">complete help on search</button>
|
||||
|
@ -128,7 +129,7 @@ export default class SearchBoxWidget extends BasicWidget {
|
|||
activeNode = activeNode.getParent();
|
||||
}
|
||||
|
||||
await treeService.createNote(activeNode, activeNode.data.noteId, 'into', {
|
||||
await noteCreateService.createNote(activeNode.data.noteId, {
|
||||
type: "search",
|
||||
mime: "application/json",
|
||||
title: searchString,
|
||||
|
|
|
@ -485,11 +485,12 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED
|
|||
delete childParentToBranchId[branch.noteId + '-' + branch.parentNoteId];
|
||||
}
|
||||
else {
|
||||
// ... and then we create new records
|
||||
if (branch.prefix) {
|
||||
prefixes[branch.noteId + '-' + branch.parentNoteId] = branch.prefix;
|
||||
}
|
||||
|
||||
childToParent[branch.noteId] = childToParent[branch.noteId] || [];
|
||||
|
||||
if (!childToParent[branch.noteId].includes(branch.parentNoteId)) {
|
||||
childToParent[branch.noteId].push(branch.parentNoteId);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue