diff --git a/docs/backend_api/Attribute.html b/docs/backend_api/Attribute.html
index 5349663eb..434612be7 100644
--- a/docs/backend_api/Attribute.html
+++ b/docs/backend_api/Attribute.html
@@ -1176,7 +1176,7 @@ and relation (representing named relationship between source and target note)Source:
@@ -1370,7 +1370,7 @@ and relation (representing named relationship between source and target note)Source:
@@ -1564,7 +1564,7 @@ and relation (representing named relationship between source and target note)Source:
diff --git a/docs/backend_api/Branch.html b/docs/backend_api/Branch.html
index b5b4fc21b..85a98fb5c 100644
--- a/docs/backend_api/Branch.html
+++ b/docs/backend_api/Branch.html
@@ -412,6 +412,72 @@ parents.
+isWeak
+
+
+
+
+
+ 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.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
noteId :string
@@ -1144,7 +1210,7 @@ parents.
Source:
diff --git a/docs/backend_api/Note.html b/docs/backend_api/Note.html
index 6761aef35..292a16dbf 100644
--- a/docs/backend_api/Note.html
+++ b/docs/backend_api/Note.html
@@ -93,7 +93,7 @@
Source:
@@ -267,7 +267,7 @@
Source:
@@ -335,7 +335,7 @@
Source:
@@ -406,7 +406,79 @@
Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+isBeingDeleted :boolean
+
+
+
+
+
+ - set during the deletion operation, before it is completed (removed from becca completely)
+
+
+
+
+ Type:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
@@ -474,7 +546,7 @@
- Source:
@@ -542,7 +614,7 @@
- Source:
@@ -610,7 +682,7 @@
- Source:
@@ -678,7 +750,7 @@
- Source:
@@ -746,7 +818,7 @@
- Source:
@@ -814,7 +886,7 @@
- Source:
@@ -882,7 +954,7 @@
- Source:
@@ -950,7 +1022,7 @@
- Source:
@@ -1154,7 +1226,7 @@ See addLabel, addRelation for more specific methods.
- Source:
@@ -1441,7 +1513,7 @@ See addLabel, addRelation for more specific methods.
- Source:
@@ -1620,7 +1692,7 @@ returned.
- Source:
@@ -1855,7 +1927,7 @@ returned.
- Source:
@@ -2055,7 +2127,7 @@ returned.
- Source:
@@ -2317,7 +2389,7 @@ returned.
- Source:
@@ -2423,7 +2495,7 @@ returned.
- Source:
@@ -2597,7 +2669,7 @@ returned.
- Source:
@@ -2775,7 +2847,7 @@ returned.
- Source:
@@ -2978,7 +3050,7 @@ returned.
- Source:
@@ -3086,7 +3158,7 @@ returned.
- Source:
@@ -3188,7 +3260,7 @@ returned.
- Source:
@@ -3290,7 +3362,7 @@ returned.
- Source:
@@ -3392,7 +3464,7 @@ returned.
- Source:
@@ -3494,7 +3566,7 @@ returned.
- Source:
@@ -3602,7 +3674,7 @@ returned.
- Source:
@@ -3708,7 +3780,7 @@ returned.
- Source:
@@ -3859,7 +3931,7 @@ returned.
- Source:
@@ -4017,7 +4089,7 @@ returned.
- Source:
@@ -4187,7 +4259,7 @@ returned.
- Source:
@@ -4354,7 +4426,7 @@ returned.
- Source:
@@ -4460,7 +4532,7 @@ returned.
- Source:
@@ -4640,7 +4712,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -4733,6 +4805,8 @@ This method can be significantly faster than the getAttribute()
+ Default |
+
Description |
@@ -4750,6 +4824,9 @@ This method can be significantly faster than the getAttribute()
string
+|
+
+null
@@ -4768,6 +4845,12 @@ This method can be significantly faster than the getAttribute()
+
+
+ null
+
+ |
+
(optional) attribute type to filter |
@@ -4783,6 +4866,9 @@ This method can be significantly faster than the getAttribute()
string
+|
+
+null
@@ -4801,6 +4887,12 @@ This method can be significantly faster than the getAttribute()
+
+
+ null
+
+ |
+
(optional) attribute name to filter |
@@ -4816,6 +4908,9 @@ This method can be significantly faster than the getAttribute()
string
+|
+
+null
@@ -4834,6 +4929,12 @@ This method can be significantly faster than the getAttribute()
+
+
+ null
+
+ |
+
(optional) attribute value to filter |
@@ -4876,7 +4977,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -5031,7 +5132,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -5189,7 +5290,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -5359,7 +5460,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -5526,7 +5627,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -5681,7 +5782,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -5839,7 +5940,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -6009,7 +6110,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -6115,7 +6216,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -6217,7 +6318,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -6457,7 +6558,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -6615,7 +6716,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -6785,7 +6886,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -6891,7 +6992,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -7000,7 +7101,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -7054,6 +7155,112 @@ This method can be significantly faster than the getAttribute()
+ getStrongParentBranches() → {Array.<Branch>}
+
+
+
+
+
+
+
+ Returns strong (as opposed to weak) parent branches. See isWeak for details.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+
+
+ -
+ Type
+
+ -
+
+Array.<Branch>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
getSubtree() → {Object}
@@ -7102,7 +7309,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -7204,7 +7411,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -7306,7 +7513,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -7408,7 +7615,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -7604,7 +7811,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -7690,6 +7897,8 @@ This method can be significantly faster than the getAttribute()
+ Default |
+
Description |
@@ -7718,6 +7927,10 @@ This method can be significantly faster than the getAttribute()
+
+
+ |
+
|
@@ -7744,6 +7957,10 @@ This method can be significantly faster than the getAttribute()
+
+
+ |
+
|
@@ -7772,6 +7989,12 @@ This method can be significantly faster than the getAttribute()
+
+
+ null
+
+ |
+
|
@@ -7814,7 +8037,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -7916,7 +8139,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -8110,7 +8333,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -8339,7 +8562,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -8537,7 +8760,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -8735,7 +8958,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -8933,7 +9156,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -9083,7 +9306,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -9189,7 +9412,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -9295,7 +9518,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -9401,7 +9624,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -9507,7 +9730,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -9613,7 +9836,7 @@ This method can be significantly faster than the getAttribute()
- Source:
@@ -10005,7 +10228,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
@@ -10185,7 +10408,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
@@ -10365,7 +10588,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
@@ -10560,7 +10783,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
@@ -10792,7 +11015,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
@@ -10972,7 +11195,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
@@ -11132,7 +11355,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
@@ -11374,7 +11597,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
@@ -11585,7 +11808,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
@@ -11796,7 +12019,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
- Source:
diff --git a/docs/backend_api/becca_entities_attribute.js.html b/docs/backend_api/becca_entities_attribute.js.html
index 76d06856f..fb653b6d2 100644
--- a/docs/backend_api/becca_entities_attribute.js.html
+++ b/docs/backend_api/becca_entities_attribute.js.html
@@ -90,8 +90,9 @@ class Attribute extends AbstractEntity {
return this;
}
-
init() {
+ this.validate();
+
if (this.attributeId) {
this.becca.attributes[this.attributeId] = this;
}
@@ -114,6 +115,16 @@ class Attribute extends AbstractEntity {
}
}
+ validate() {
+ if (!["label", "relation"].includes(this.type)) {
+ throw new Error(`Invalid attribute type '${this.type}' in attribute '${this.attributeId}'`);
+ }
+
+ if (!this.name?.trim()) {
+ throw new Error(`Invalid empty name in attribute '${this.attributeId}'`);
+ }
+ }
+
get isAffectingSubtree() {
return this.isInheritable
|| (this.type === 'relation' && this.name === 'template');
@@ -141,7 +152,13 @@ class Attribute extends AbstractEntity {
* @returns {Note|null}
*/
getNote() {
- return this.becca.getNote(this.noteId);
+ const note = this.becca.getNote(this.noteId);
+
+ if (!note) {
+ throw new Error(`Note '${this.noteId}' of attribute '${this.attributeId}', type '${this.type}', name '${this.name}' does not exist.`);
+ }
+
+ return note;
}
/**
@@ -185,11 +202,13 @@ class Attribute extends AbstractEntity {
}
beforeSaving() {
- if (!this.value) {
- if (this.type === 'relation') {
- throw new Error(`Cannot save relation ${this.name} since it does not target any note.`);
- }
+ this.validate();
+ if (this.type === 'relation') {
+ if (!(this.value in this.becca.notes)) {
+ throw new Error(`Cannot save relation '${this.name}' since it target not existing note '${this.value}'.`);
+ }
+ } else if (!this.value) {
// null value isn't allowed
this.value = "";
}
diff --git a/docs/backend_api/becca_entities_note.js.html b/docs/backend_api/becca_entities_note.js.html
index ac417b226..a7da74aec 100644
--- a/docs/backend_api/becca_entities_note.js.html
+++ b/docs/backend_api/becca_entities_note.js.html
@@ -39,7 +39,6 @@ const NoteRevision = require("./note_revision");
const TaskContext = require("../../services/task_context");
const dayjs = require("dayjs");
const utc = require('dayjs/plugin/utc');
-const searchService = require("../../services/search/services/search.js");
dayjs.extend(utc)
const LABEL = 'label';
@@ -101,6 +100,8 @@ class Note extends AbstractEntity {
this.utcDateCreated = utcDateCreated || dateUtils.utcNowDateTime();
/** @type {string} */
this.utcDateModified = utcDateModified;
+ /** @type {boolean} - set during the deletion operation, before it is completed (removed from becca completely) */
+ this.isBeingDeleted = false;
// ------ Derived attributes ------
@@ -183,6 +184,15 @@ class Note extends AbstractEntity {
return this.parentBranches;
}
+ /**
+ * Returns <i>strong</i> (as opposed to <i>weak</i>) parent branches. See isWeak for details.
+ *
+ * @returns {Branch[]}
+ */
+ getStrongParentBranches() {
+ return this.getParentBranches().filter(branch => !branch.isWeak);
+ }
+
/**
* @returns {Branch[]}
* @deprecated use getParentBranches() instead
@@ -402,7 +412,8 @@ class Note extends AbstractEntity {
return this.__attributeCache.filter(attr => attr.name === name);
}
else {
- return this.__attributeCache.slice();
+ // a bit unsafe to return the original array, but defensive copy would be costly
+ return this.__attributeCache;
}
}
@@ -484,7 +495,7 @@ class Note extends AbstractEntity {
* @param [value]
* @returns {boolean}
*/
- hasAttribute(type, name, value) {
+ hasAttribute(type, name, value = null) {
return !!this.getAttributes().find(attr =>
attr.type === type
&& attr.name === name
@@ -676,12 +687,12 @@ class Note extends AbstractEntity {
}
/**
- * @param {string} [type] - (optional) attribute type to filter
- * @param {string} [name] - (optional) attribute name to filter
- * @param {string} [value] - (optional) attribute value to filter
+ * @param {string|null} [type] - (optional) attribute type to filter
+ * @param {string|null} [name] - (optional) attribute name to filter
+ * @param {string|null} [value] - (optional) attribute value to filter
* @returns {Attribute[]} note's "owned" attributes - excluding inherited ones
*/
- getOwnedAttributes(type, name, value) {
+ getOwnedAttributes(type = null, name = null, value = null) {
// it's a common mistake to include # or ~ into attribute name
if (name && ["#", "~"].includes(name[0])) {
name = name.substr(1);
@@ -709,7 +720,7 @@ class Note extends AbstractEntity {
*
* This method can be significantly faster than the getAttribute()
*/
- getOwnedAttribute(type, name, value) {
+ getOwnedAttribute(type, name, value = null) {
const attrs = this.getOwnedAttributes(type, name, value);
return attrs.length > 0 ? attrs[0] : null;
@@ -1346,8 +1357,16 @@ class Note extends AbstractEntity {
}
}
+ isLaunchBarConfig() {
+ return this.type === 'launcher' || ['lbRoot', 'lbAvailableLaunchers', 'lbVisibleLaunchers'].includes(this.noteId);
+ }
+
+ isOptions() {
+ return this.noteId.startsWith("options");
+ }
+
get isDeleted() {
- return !(this.noteId in this.becca.notes);
+ return !(this.noteId in this.becca.notes) || this.isBeingDeleted;
}
/**
diff --git a/docs/backend_api/global.html b/docs/backend_api/global.html
index e6c91e6a8..571777ef8 100644
--- a/docs/backend_api/global.html
+++ b/docs/backend_api/global.html
@@ -237,7 +237,7 @@
- text, code, file, image, search, book, relation-map, canvas - MANDATORY |
+ text, code, file, image, search, book, relationMap, canvas - MANDATORY |
diff --git a/docs/backend_api/services_backend_script_api.js.html b/docs/backend_api/services_backend_script_api.js.html
index f2aff4847..b74145bd8 100644
--- a/docs/backend_api/services_backend_script_api.js.html
+++ b/docs/backend_api/services_backend_script_api.js.html
@@ -240,7 +240,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @property {string} parentNoteId - MANDATORY
* @property {string} title - MANDATORY
* @property {string|buffer} content - MANDATORY
- * @property {string} type - text, code, file, image, search, book, relation-map, canvas - MANDATORY
+ * @property {string} type - text, code, file, image, search, book, relationMap, canvas - MANDATORY
* @property {string} mime - value is derived from default mimes for type
* @property {boolean} isProtected - default is false
* @property {boolean} isExpanded - default is false