trilium/docs/backend_api/becca_entities_branch.js.html

329 lines
10 KiB
HTML
Raw Normal View History

2021-09-30 18:26:13 +08:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: becca/entities/branch.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: becca/entities/branch.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>"use strict";
2022-01-11 02:54:38 +08:00
const Note = require('./note');
const AbstractEntity = require("./abstract_entity");
const dateUtils = require("../../services/date_utils");
2022-12-15 06:51:28 +08:00
const utils = require("../../services/utils");
const TaskContext = require("../../services/task_context");
const cls = require("../../services/cls");
const log = require("../../services/log");
2021-09-30 18:26:13 +08:00
/**
* Branch represents a relationship between a child note and its parent note. Trilium allows a note to have multiple
* parents.
2022-04-16 06:17:32 +08:00
*
* Note that you should not rely on the branch's identity, since it can change easily with a note's move.
* Always check noteId instead.
*
2022-04-16 06:17:32 +08:00
* @extends AbstractEntity
*/
2021-09-30 18:26:13 +08:00
class Branch extends AbstractEntity {
static get entityName() { return "branches"; }
static get primaryKeyName() { return "branchId"; }
// notePosition is not part of hash because it would produce a lot of updates in case of reordering
static get hashedProperties() { return ["branchId", "noteId", "parentNoteId", "prefix"]; }
constructor(row) {
super();
if (!row) {
return;
}
this.updateFromRow(row);
this.init();
}
updateFromRow(row) {
this.update([
row.branchId,
row.noteId,
row.parentNoteId,
row.prefix,
row.notePosition,
row.isExpanded,
row.utcDateModified
]);
}
update([branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified]) {
/** @type {string} */
2021-09-30 18:26:13 +08:00
this.branchId = branchId;
/** @type {string} */
2021-09-30 18:26:13 +08:00
this.noteId = noteId;
/** @type {string} */
2021-09-30 18:26:13 +08:00
this.parentNoteId = parentNoteId;
/** @type {string} */
2021-09-30 18:26:13 +08:00
this.prefix = prefix;
/** @type {int} */
2021-09-30 18:26:13 +08:00
this.notePosition = notePosition;
/** @type {boolean} */
2021-09-30 18:26:13 +08:00
this.isExpanded = !!isExpanded;
/** @type {string} */
2021-09-30 18:26:13 +08:00
this.utcDateModified = utcDateModified;
return this;
}
init() {
2022-01-06 03:31:21 +08:00
if (this.branchId) {
this.becca.branches[this.branchId] = this;
}
this.becca.childParentToBranch[`${this.noteId}-${this.parentNoteId}`] = this;
const childNote = this.childNote;
if (!childNote.parentBranches.includes(this)) {
childNote.parentBranches.push(this);
}
2022-12-30 04:15:34 +08:00
if (this.noteId === 'root') {
2021-09-30 18:26:13 +08:00
return;
}
const parentNote = this.parentNote;
if (!childNote.parents.includes(parentNote)) {
childNote.parents.push(parentNote);
}
if (!parentNote.children.includes(childNote)) {
parentNote.children.push(childNote);
}
2021-09-30 18:26:13 +08:00
}
/** @returns {Note} */
2021-09-30 18:26:13 +08:00
get childNote() {
if (!(this.noteId in this.becca.notes)) {
2022-01-06 03:31:21 +08:00
// entities can come out of order in sync/import, create skeleton which will be filled later
this.becca.addNote(this.noteId, new Note({noteId: this.noteId}));
2021-09-30 18:26:13 +08:00
}
return this.becca.notes[this.noteId];
}
getNote() {
return this.childNote;
}
/** @returns {Note|undefined} - root branch will have undefined parent, all other branches have to have a parent note */
2021-09-30 18:26:13 +08:00
get parentNote() {
if (!(this.parentNoteId in this.becca.notes) &amp;&amp; this.parentNoteId !== 'none') {
2022-01-06 03:31:21 +08:00
// entities can come out of order in sync/import, create skeleton which will be filled later
this.becca.addNote(this.parentNoteId, new Note({noteId: this.parentNoteId}));
2021-09-30 18:26:13 +08:00
}
return this.becca.notes[this.parentNoteId];
}
get isDeleted() {
return !(this.branchId in this.becca.branches);
}
2022-12-15 06:51:28 +08:00
/**
* Branch is weak when its existence should not hinder deletion of its note.
* As a result, note with only weak branches should be immediately deleted.
* An example is shared or bookmarked clones - they are created automatically and exist for technical reasons,
* not as user-intended actions. From user perspective, they don't count as real clones and for the purpose
* of deletion should not act as a clone.
*
* @returns {boolean}
*/
get isWeak() {
return ['_share', '_lbBookmarks'].includes(this.parentNoteId);
2022-12-15 06:51:28 +08:00
}
/**
* Delete a branch. If this is a last note's branch, delete the note as well.
*
* @param {string} [deleteId] - optional delete identified
* @param {TaskContext} [taskContext]
*
* @return {boolean} - true if note has been deleted, false otherwise
*/
deleteBranch(deleteId, taskContext) {
if (!deleteId) {
deleteId = utils.randomString(10);
}
if (!taskContext) {
taskContext = new TaskContext('no-progress-reporting');
}
taskContext.increaseProgressCount();
const note = this.getNote();
if (!taskContext.noteDeletionHandlerTriggered) {
const parentBranches = note.getParentBranches();
if (parentBranches.length === 1 &amp;&amp; parentBranches[0] === this) {
// needs to be run before branches and attributes are deleted and thus attached relations disappear
const handlers = require("../../services/handlers");
handlers.runAttachedRelations(note, 'runOnNoteDeletion', note);
}
}
2022-12-30 04:15:34 +08:00
if (this.noteId === 'root'
|| this.noteId === cls.getHoistedNoteId()) {
throw new Error("Can't delete root or hoisted branch/note");
}
this.markAsDeleted(deleteId);
2022-12-15 06:51:28 +08:00
const notDeletedBranches = note.getStrongParentBranches();
if (notDeletedBranches.length === 0) {
2022-12-15 06:51:28 +08:00
for (const weakBranch of note.getParentBranches()) {
weakBranch.markAsDeleted(deleteId);
}
for (const childBranch of note.getChildBranches()) {
childBranch.deleteBranch(deleteId, taskContext);
}
// first delete children and then parent - this will show up better in recent changes
2022-12-22 21:57:00 +08:00
log.info(`Deleting note ${note.noteId}`);
2022-12-15 06:51:28 +08:00
this.becca.notes[note.noteId].isBeingDeleted = true;
2022-11-08 04:26:13 +08:00
for (const attribute of note.getOwnedAttributes()) {
attribute.markAsDeleted(deleteId);
}
for (const relation of note.getTargetRelations()) {
relation.markAsDeleted(deleteId);
}
note.markAsDeleted(deleteId);
return true;
}
else {
return false;
}
}
2021-09-30 18:26:13 +08:00
beforeSaving() {
2022-12-30 04:15:34 +08:00
if (!this.noteId || !this.parentNoteId) {
throw new Error(`noteId and parentNoteId are mandatory properties for Branch`);
}
this.branchId = `${this.parentNoteId}_${this.noteId}`;
2021-09-30 18:26:13 +08:00
if (this.notePosition === undefined || this.notePosition === null) {
2022-11-30 23:57:51 +08:00
let maxNotePos = 0;
for (const childBranch of this.parentNote.getChildBranches()) {
2022-12-30 04:15:34 +08:00
if (maxNotePos &lt; childBranch.notePosition
&amp;&amp; childBranch.noteId !== '_hidden' // hidden has very large notePosition to always stay last
) {
2022-11-30 23:57:51 +08:00
maxNotePos = childBranch.notePosition;
}
}
this.notePosition = maxNotePos + 10;
2021-09-30 18:26:13 +08:00
}
if (!this.isExpanded) {
this.isExpanded = false;
}
2022-12-30 04:15:34 +08:00
if (!this.prefix?.trim()) {
this.prefix = null;
}
2021-09-30 18:26:13 +08:00
this.utcDateModified = dateUtils.utcNowDateTime();
super.beforeSaving();
this.becca.branches[this.branchId] = this;
}
getPojo() {
return {
branchId: this.branchId,
noteId: this.noteId,
parentNoteId: this.parentNoteId,
prefix: this.prefix,
notePosition: this.notePosition,
isExpanded: this.isExpanded,
isDeleted: false,
2022-01-06 03:31:21 +08:00
utcDateModified: this.utcDateModified
2021-09-30 18:26:13 +08:00
};
}
createClone(parentNoteId, notePosition) {
2022-12-30 04:15:34 +08:00
const existingBranch = this.becca.getBranchFromChildAndParent(this.noteId, parentNoteId);
if (existingBranch) {
existingBranch.notePosition = notePosition;
return existingBranch;
} else {
return new Branch({
noteId: this.noteId,
parentNoteId: parentNoteId,
notePosition: notePosition,
prefix: this.prefix,
isExpanded: this.isExpanded
});
}
2021-09-30 18:26:13 +08:00
}
}
module.exports = Branch;
</code></pre>
</article>
</section>
</div>
<nav>
2022-12-25 20:03:22 +08:00
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractEntity.html">AbstractEntity</a></li><li><a href="Attribute.html">Attribute</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li><li><a href="Branch.html">Branch</a></li><li><a href="EtapiToken.html">EtapiToken</a></li><li><a href="Note.html">Note</a></li><li><a href="NoteRevision.html">NoteRevision</a></li><li><a href="Option.html">Option</a></li><li><a href="RecentNote.html">RecentNote</a></li></ul><h3><a href="global.html">Global</a></h3>
2021-09-30 18:26:13 +08:00
</nav>
<br class="clear">
<footer>
2022-11-08 04:26:13 +08:00
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.0</a>
2021-09-30 18:26:13 +08:00
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>