diff --git a/db/demo.zip b/db/demo.zip
index a2327ff33..e4740b49b 100644
Binary files a/db/demo.zip and b/db/demo.zip differ
diff --git a/docs/backend_api/AbstractEntity.html b/docs/backend_api/AbstractEntity.html
index ab08501ce..b39f717a3 100644
--- a/docs/backend_api/AbstractEntity.html
+++ b/docs/backend_api/AbstractEntity.html
@@ -139,10 +139,576 @@
+
Members
+
+
+
+(protected) becca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+
+ (protected) addEntityChange()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) beforeSaving()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) generateHash()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) generateIdIfNecessary()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getPojoToSave()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getUtcDateChanged()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -267,7 +833,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -355,7 +921,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/Attribute.html b/docs/backend_api/Attribute.html
index 8633da77b..3b7696898 100644
--- a/docs/backend_api/Attribute.html
+++ b/docs/backend_api/Attribute.html
@@ -223,6 +223,69 @@ and relation (representing named relationship between source and target note)(protected) becca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
isInheritable :boolean
@@ -709,7 +772,7 @@ and relation (representing named relationship between source and target note) getNote() → {Note |null}
+ (protected) addEntityChange()
@@ -737,6 +800,11 @@ and relation (representing named relationship between source and target note)Overrides:
+
+
@@ -757,7 +825,7 @@ and relation (representing named relationship between source and target note)Source:
@@ -782,27 +850,95 @@ and relation (representing named relationship between source and target note)Returns:
-
-
-
- Type
-
-
+
+
-Note
-|
+
-null
+
+
+
+ (protected) beforeSaving()
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -814,7 +950,7 @@ and relation (representing named relationship between source and target note) getTargetNote() → {Note |null}
+ (protected) generateHash()
@@ -842,6 +978,11 @@ and relation (representing named relationship between source and target note)Overrides:
+
+
@@ -862,7 +1003,7 @@ and relation (representing named relationship between source and target note)Source:
@@ -887,27 +1028,483 @@ and relation (representing named relationship between source and target note)Returns:
-
-
-
- Type
-
-
+
+
-Note
-|
+
-null
+
+
+ (protected) generateIdIfNecessary()
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getNote() → {Note |null}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+
+
+
+ Type
+
+
+
+Note
+|
+
+null
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getPojoToSave()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getTargetNote() → {Note |null}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+
+
+
+ Type
+
+
+
+Note
+|
+
+null
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getUtcDateChanged()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -967,7 +1564,7 @@ and relation (representing named relationship between source and target note)Source:
@@ -1144,7 +1741,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -1237,7 +1834,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/Branch.html b/docs/backend_api/Branch.html
index f89ff45ad..db8e9e0c6 100644
--- a/docs/backend_api/Branch.html
+++ b/docs/backend_api/Branch.html
@@ -155,6 +155,69 @@ parents.
+(protected) becca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
branchId :string
@@ -751,6 +814,184 @@ parents.
Methods
+
+
+
+
+
+
+ (protected) addEntityChange()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) beforeSaving()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -955,6 +1196,362 @@ parents.
+
+
+
+
+
+
+ (protected) generateHash()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) generateIdIfNecessary()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getPojoToSave()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getUtcDateChanged()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1084,7 +1681,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -1177,7 +1774,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/EtapiToken.html b/docs/backend_api/EtapiToken.html
index b675d8cdc..da6e56f2f 100644
--- a/docs/backend_api/EtapiToken.html
+++ b/docs/backend_api/EtapiToken.html
@@ -160,6 +160,69 @@ from tokenHash and token.
+(protected) becca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
etapiTokenId :string
@@ -572,6 +635,540 @@ from tokenHash and token.
Methods
+
+
+
+
+
+
+ (protected) addEntityChange()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) beforeSaving()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) generateHash()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) generateIdIfNecessary()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getPojoToSave()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getUtcDateChanged()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -701,7 +1298,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -794,7 +1391,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/Note.html b/docs/backend_api/Note.html
index 2afe54588..b8f53d2d9 100644
--- a/docs/backend_api/Note.html
+++ b/docs/backend_api/Note.html
@@ -93,7 +93,7 @@
Source:
@@ -154,23 +154,13 @@
- children :Array.<Note >
+(protected) becca
- Type:
-
-
-
-Array.<Note >
-
-
-
-
-
@@ -184,27 +174,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Source:
-
-
-
-
-
-
-
-
-
- contentSize :int|null
-
-
-
-
-
- size of the content in bytes
-
-
-
-
- Type:
-
-
-
-int
-|
-
-null
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -279,7 +199,7 @@
Source:
@@ -347,7 +267,7 @@
Source:
@@ -415,7 +335,7 @@
Source:
@@ -486,7 +406,7 @@
Source:
@@ -554,7 +474,7 @@
Source:
@@ -622,7 +542,7 @@
Source:
@@ -690,7 +610,7 @@
Source:
@@ -758,7 +678,7 @@
Source:
@@ -776,14 +696,10 @@
- noteSize :int|null
-
+ title :string
-
- size of the content and note revision contents in bytes
-
@@ -791,10 +707,7 @@
-int
-|
-
-null
+string
@@ -833,7 +746,7 @@
Source:
@@ -851,7 +764,7 @@
- ownedAttributes :Array.<Attribute >
+ type :string
@@ -862,7 +775,7 @@
-Array.<Attribute >
+string
@@ -901,7 +814,7 @@
Source:
@@ -919,7 +832,7 @@
- parentBranches :Array.<Branch >
+ utcDateCreated :string
@@ -930,7 +843,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+
+
+
+ Type
+
+
+
+Array.<Note >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getSubtreeNotesIncludingTemplated() → {Array.<Note >}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
@@ -6631,7 +6607,7 @@ This method can be significantly faster than the getAttribute()
- getSubtreeNotesIncludingTemplated() → {Array.<Note >}
+ getTemplatedNotes() → {Array.<Note >}
@@ -6679,7 +6655,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6707,6 +6683,11 @@ This method can be significantly faster than the getAttribute()
Returns:
+
+ - returns only notes which are templated, does not include their subtrees
+ in effect returns notes which are influenced by note's non-inheritable attributes
+
+
@@ -6733,7 +6714,7 @@ This method can be significantly faster than the getAttribute()
- getTemplatedNotes() → {Array.<Note >}
+ (protected) getUtcDateChanged()
@@ -6761,6 +6742,11 @@ This method can be significantly faster than the getAttribute()
+ Overrides:
+
+
@@ -6781,7 +6767,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6806,29 +6792,6 @@ This method can be significantly faster than the getAttribute()
-Returns:
-
-
-
- - returns only notes which are templated, does not include their subtrees
- in effect returns notes which are influenced by note's non-inheritable attributes
-
-
-
-
-
-
- Type
-
-
-
-Array.<Note >
-
-
-
-
-
-
@@ -6888,7 +6851,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -6990,7 +6953,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7044,7 +7007,7 @@ This method can be significantly faster than the getAttribute()
- hasLabel(name) → {boolean}
+ hasLabel(name, valueopt ) → {boolean}
@@ -7072,6 +7035,8 @@ This method can be significantly faster than the getAttribute()
Type
+ Attributes
+
@@ -7097,6 +7062,14 @@ This method can be significantly faster than the getAttribute()
+
+
+
+
+
+
+
+
@@ -7104,6 +7077,39 @@ This method can be significantly faster than the getAttribute()
+
+
+
+ value
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+ label value
+
+
+
@@ -7141,7 +7147,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7199,7 +7205,7 @@ This method can be significantly faster than the getAttribute()
- hasOwnedAttribute(type, name) → {boolean}
+ hasOwnedAttribute(type, name, valueopt ) → {boolean}
@@ -7227,6 +7233,8 @@ This method can be significantly faster than the getAttribute()
Type
+ Attributes
+
@@ -7252,6 +7260,14 @@ This method can be significantly faster than the getAttribute()
+
+
+
+
+
+
+
+
@@ -7275,6 +7291,14 @@ This method can be significantly faster than the getAttribute()
+
+
+
+
+
+
+
+
@@ -7282,6 +7306,39 @@ This method can be significantly faster than the getAttribute()
+
+
+
+ value
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+ attribute value
+
+
+
@@ -7319,7 +7376,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7377,7 +7434,7 @@ This method can be significantly faster than the getAttribute()
- hasOwnedLabel(name) → {boolean}
+ hasOwnedLabel(name, valueopt ) → {boolean}
@@ -7405,6 +7462,8 @@ This method can be significantly faster than the getAttribute()
Type
+ Attributes
+
@@ -7430,6 +7489,14 @@ This method can be significantly faster than the getAttribute()
+
+
+
+
+
+
+
+
@@ -7437,6 +7504,39 @@ This method can be significantly faster than the getAttribute()
+
+
+
+ value
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+ label value
+
+
+
@@ -7474,7 +7574,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7532,7 +7632,7 @@ This method can be significantly faster than the getAttribute()
- hasOwnedRelation(name) → {boolean}
+ hasOwnedRelation(name, valueopt ) → {boolean}
@@ -7560,6 +7660,8 @@ This method can be significantly faster than the getAttribute()
Type
+ Attributes
+
@@ -7585,6 +7687,14 @@ This method can be significantly faster than the getAttribute()
+
+
+
+
+
+
+
+
@@ -7592,6 +7702,39 @@ This method can be significantly faster than the getAttribute()
+
+
+
+ value
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+ relation value
+
+
+
@@ -7629,7 +7772,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7687,7 +7830,7 @@ This method can be significantly faster than the getAttribute()
- hasRelation(name) → {boolean}
+ hasRelation(name, valueopt ) → {boolean}
@@ -7715,6 +7858,8 @@ This method can be significantly faster than the getAttribute()
Type
+ Attributes
+
@@ -7740,6 +7885,14 @@ This method can be significantly faster than the getAttribute()
+
+
+
+
+
+
+
+
@@ -7747,6 +7900,39 @@ This method can be significantly faster than the getAttribute()
+
+
+
+ value
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+ relation value
+
+
+
@@ -7784,7 +7970,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -7934,7 +8120,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8040,7 +8226,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8146,7 +8332,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8252,7 +8438,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8358,7 +8544,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8464,7 +8650,7 @@ This method can be significantly faster than the getAttribute()
Source:
@@ -8645,7 +8831,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -8856,7 +9042,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9036,7 +9222,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9216,7 +9402,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9309,7 +9495,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9411,7 +9597,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9643,7 +9829,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9823,7 +10009,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -9983,7 +10169,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -10225,7 +10411,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -10436,7 +10622,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -10647,7 +10833,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/NoteRevision.html b/docs/backend_api/NoteRevision.html
index ad8b80285..ca0fb5b83 100644
--- a/docs/backend_api/NoteRevision.html
+++ b/docs/backend_api/NoteRevision.html
@@ -155,6 +155,69 @@ It's used for seamless note versioning.
+(protected) becca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
contentLength :number
@@ -981,7 +1044,7 @@ It's used for seamless note versioning.
- getContent() → {*}
+ (protected) addEntityChange()
@@ -1009,6 +1072,11 @@ It's used for seamless note versioning.
+ Overrides:
+
+
@@ -1029,7 +1097,7 @@ It's used for seamless note versioning.
Source:
@@ -1054,24 +1122,95 @@ It's used for seamless note versioning.
-Returns:
-
-
-
- Type
-
-
+
+
-*
+
+
-
-
+
+ (protected) beforeSaving()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1083,7 +1222,7 @@ It's used for seamless note versioning.
- getContentMetadata() → {Object}
+ (protected) generateHash()
@@ -1111,6 +1250,11 @@ It's used for seamless note versioning.
+ Overrides:
+
+
@@ -1131,7 +1275,7 @@ It's used for seamless note versioning.
Source:
@@ -1156,24 +1300,477 @@ It's used for seamless note versioning.
-Returns:
-
-
-
- Type
-
-
+
+
-Object
+
+
+
+
+ (protected) generateIdIfNecessary()
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getContent() → {*}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+
+
+
+ Type
+
+
+
+*
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getContentMetadata() → {Object}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+
+
+
+
+ Type
+
+
+
+Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getPojoToSave()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getUtcDateChanged()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1414,7 +2011,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -1507,7 +2104,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/Option.html b/docs/backend_api/Option.html
index c812d8ea6..bd356c359 100644
--- a/docs/backend_api/Option.html
+++ b/docs/backend_api/Option.html
@@ -154,6 +154,69 @@
+(protected) becca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
isSynced :boolean
@@ -430,6 +493,540 @@
Methods
+
+
+
+
+
+
+ (protected) addEntityChange()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) beforeSaving()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) generateHash()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) generateIdIfNecessary()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getPojoToSave()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getUtcDateChanged()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -559,7 +1156,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -652,7 +1249,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/RecentNote.html b/docs/backend_api/RecentNote.html
index 621598ed2..39babc507 100644
--- a/docs/backend_api/RecentNote.html
+++ b/docs/backend_api/RecentNote.html
@@ -154,6 +154,69 @@
+(protected) becca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
noteId :string
@@ -362,6 +425,540 @@
Methods
+
+
+
+
+
+
+ (protected) addEntityChange()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) beforeSaving()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) generateHash()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) generateIdIfNecessary()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getPojoToSave()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (protected) getUtcDateChanged()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -491,7 +1088,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
@@ -584,7 +1181,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
Source:
diff --git a/docs/backend_api/becca_entities_abstract_entity.js.html b/docs/backend_api/becca_entities_abstract_entity.js.html
index a66b5654a..5b8a48e51 100644
--- a/docs/backend_api/becca_entities_abstract_entity.js.html
+++ b/docs/backend_api/becca_entities_abstract_entity.js.html
@@ -42,16 +42,19 @@ let becca = null;
* Base class for all backend entities.
*/
class AbstractEntity {
+ /** @protected */
beforeSaving() {
this.generateIdIfNecessary();
}
+ /** @protected */
generateIdIfNecessary() {
if (!this[this.constructor.primaryKeyName]) {
this[this.constructor.primaryKeyName] = utils.newEntityId();
}
}
+ /** @protected */
generateHash(isDeleted = false) {
let contentToHash = "";
@@ -66,10 +69,12 @@ class AbstractEntity {
return utils.hash(contentToHash).substr(0, 10);
}
+ /** @protected */
getUtcDateChanged() {
return this.utcDateModified || this.utcDateCreated;
}
+ /** @protected */
get becca() {
if (!becca) {
becca = require('../becca');
@@ -78,6 +83,7 @@ class AbstractEntity {
return becca;
}
+ /** @protected */
addEntityChange(isDeleted = false) {
entityChangesService.addEntityChange({
entityName: this.constructor.entityName,
@@ -89,6 +95,7 @@ class AbstractEntity {
});
}
+ /** @protected */
getPojoToSave() {
return this.getPojo();
}
diff --git a/docs/backend_api/becca_entities_attribute.js.html b/docs/backend_api/becca_entities_attribute.js.html
index 10515c065..ac020be8e 100644
--- a/docs/backend_api/becca_entities_attribute.js.html
+++ b/docs/backend_api/becca_entities_attribute.js.html
@@ -90,6 +90,7 @@ class Attribute extends AbstractEntity {
return this;
}
+
init() {
if (this.attributeId) {
this.becca.attributes[this.attributeId] = this;
diff --git a/docs/backend_api/becca_entities_branch.js.html b/docs/backend_api/becca_entities_branch.js.html
index 73fd62a3b..d02cd4fb7 100644
--- a/docs/backend_api/becca_entities_branch.js.html
+++ b/docs/backend_api/becca_entities_branch.js.html
@@ -33,9 +33,9 @@ const AbstractEntity = require("./abstract_entity");
const sql = require("../../services/sql");
const dateUtils = require("../../services/date_utils");
const utils = require("../../services/utils.js");
-const TaskContext = require("../../services/task_context.js");
-const cls = require("../../services/cls.js");
-const log = require("../../services/log.js");
+const TaskContext = require("../../services/task_context");
+const cls = require("../../services/cls");
+const log = require("../../services/log");
/**
* Branch represents a relationship between a child note and its parent note. Trilium allows a note to have multiple
@@ -165,6 +165,18 @@ class Branch extends AbstractEntity {
taskContext.increaseProgressCount();
+ const note = this.getNote();
+
+ if (!taskContext.noteDeletionHandlerTriggered) {
+ const parentBranches = note.getParentBranches();
+
+ if (parentBranches.length === 1 && 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);
+ }
+ }
+
if (this.branchId === 'root'
|| this.noteId === 'root'
|| this.noteId === cls.getHoistedNoteId()) {
@@ -174,7 +186,6 @@ class Branch extends AbstractEntity {
this.markAsDeleted(deleteId);
- const note = this.getNote();
const notDeletedBranches = note.getParentBranches();
if (notDeletedBranches.length === 0) {
diff --git a/docs/backend_api/becca_entities_note.js.html b/docs/backend_api/becca_entities_note.js.html
index 57d0527e7..c73b7e304 100644
--- a/docs/backend_api/becca_entities_note.js.html
+++ b/docs/backend_api/becca_entities_note.js.html
@@ -36,9 +36,10 @@ const dateUtils = require('../../services/date_utils');
const entityChangesService = require('../../services/entity_changes');
const AbstractEntity = require("./abstract_entity");
const NoteRevision = require("./note_revision");
-const TaskContext = require("../../services/task_context.js");
-const optionService = require("../../services/options.js");
-const noteRevisionService = require("../../services/note_revisions.js");
+const TaskContext = require("../../services/task_context");
+const dayjs = require("dayjs");
+const utc = require('dayjs/plugin/utc')
+dayjs.extend(utc)
const LABEL = 'label';
const RELATION = 'relation';
@@ -114,13 +115,17 @@ class Note extends AbstractEntity {
}
init() {
- /** @type {Branch[]} */
+ /** @type {Branch[]}
+ * @private */
this.parentBranches = [];
- /** @type {Note[]} */
+ /** @type {Note[]}
+ * @private */
this.parents = [];
- /** @type {Note[]} */
+ /** @type {Note[]}
+ * @private*/
this.children = [];
- /** @type {Attribute[]} */
+ /** @type {Attribute[]}
+ * @private */
this.ownedAttributes = [];
/** @type {Attribute[]|null}
@@ -130,7 +135,8 @@ class Note extends AbstractEntity {
* @private*/
this.inheritableAttributeCache = null;
- /** @type {Attribute[]} */
+ /** @type {Attribute[]}
+ * @private*/
this.targetRelations = [];
this.becca.addNote(this.noteId, this);
@@ -144,16 +150,19 @@ class Note extends AbstractEntity {
/**
* size of the content in bytes
* @type {int|null}
+ * @private
*/
this.contentSize = null;
/**
* size of the content and note revision contents in bytes
* @type {int|null}
+ * @private
*/
this.noteSize = null;
/**
* number of note revisions for this note
* @type {int|null}
+ * @private
*/
this.revisionCount = null;
}
@@ -255,6 +264,22 @@ class Note extends AbstractEntity {
WHERE noteId = ?`, [this.noteId]);
}
+ get dateCreatedObj() {
+ return this.dateCreated === null ? null : dayjs(this.dateCreated);
+ }
+
+ get utcDateCreatedObj() {
+ return this.utcDateCreated === null ? null : dayjs.utc(this.utcDateCreated);
+ }
+
+ get dateModifiedObj() {
+ return this.dateModified === null ? null : dayjs(this.dateModified);
+ }
+
+ get utcDateModifiedObj() {
+ return this.utcDateModified === null ? null : dayjs.utc(this.utcDateModified);
+ }
+
/** @returns {*} */
getJsonContent() {
const content = this.getContent();
@@ -380,6 +405,7 @@ class Note extends AbstractEntity {
}
}
+ /** @private */
__getAttributes(path) {
if (path.includes(this.noteId)) {
return [];
@@ -402,7 +428,11 @@ class Note extends AbstractEntity {
const templateNote = this.becca.notes[ownedAttr.value];
if (templateNote) {
- templateAttributes.push(...templateNote.__getAttributes(newPath));
+ templateAttributes.push(
+ ...templateNote.__getAttributes(newPath)
+ // template attr is used as a marker for templates, but it's not meant to be inherited
+ .filter(attr => !(attr.type === 'label' && attr.name === 'template'))
+ );
}
}
}
@@ -431,7 +461,10 @@ class Note extends AbstractEntity {
return this.__attributeCache;
}
- /** @returns {Attribute[]} */
+ /**
+ * @private
+ * @returns {Attribute[]}
+ */
__getInheritableAttributes(path) {
if (path.includes(this.noteId)) {
return [];
@@ -444,8 +477,12 @@ class Note extends AbstractEntity {
return this.inheritableAttributeCache;
}
- hasAttribute(type, name) {
- return !!this.getAttributes().find(attr => attr.type === type && attr.name === name);
+ hasAttribute(type, name, value) {
+ return !!this.getAttributes().find(attr =>
+ attr.type === type
+ && attr.name === name
+ && (value === undefined || value === null || attr.value === value)
+ );
}
getAttributeCaseInsensitive(type, name, value) {
@@ -466,27 +503,31 @@ class Note extends AbstractEntity {
/**
* @param {string} name - label name
+ * @param {string} [value] - label value
* @returns {boolean} true if label exists (including inherited)
*/
- hasLabel(name) { return this.hasAttribute(LABEL, name); }
+ hasLabel(name, value) { return this.hasAttribute(LABEL, name, value); }
/**
* @param {string} name - label name
+ * @param {string} [value] - label value
* @returns {boolean} true if label exists (excluding inherited)
*/
- hasOwnedLabel(name) { return this.hasOwnedAttribute(LABEL, name); }
+ hasOwnedLabel(name, value) { return this.hasOwnedAttribute(LABEL, name, value); }
/**
* @param {string} name - relation name
+ * @param {string} [value] - relation value
* @returns {boolean} true if relation exists (including inherited)
*/
- hasRelation(name) { return this.hasAttribute(RELATION, name); }
+ hasRelation(name, value) { return this.hasAttribute(RELATION, name, value); }
/**
* @param {string} name - relation name
+ * @param {string} [value] - relation value
* @returns {boolean} true if relation exists (excluding inherited)
*/
- hasOwnedRelation(name) { return this.hasOwnedAttribute(RELATION, name); }
+ hasOwnedRelation(name, value) { return this.hasOwnedAttribute(RELATION, name, value); }
/**
* @param {string} name - label name
@@ -539,10 +580,11 @@ class Note extends AbstractEntity {
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
+ * @param {string} [value] - attribute value
* @returns {boolean} true if note has an attribute with given type and name (excluding inherited)
*/
- hasOwnedAttribute(type, name) {
- return !!this.getOwnedAttribute(type, name);
+ hasOwnedAttribute(type, name, value) {
+ return !!this.getOwnedAttribute(type, name, value);
}
/**
@@ -629,15 +671,19 @@ 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
* @returns {Attribute[]} note's "owned" attributes - excluding inherited ones
*/
- getOwnedAttributes(type, name) {
+ getOwnedAttributes(type, name, value) {
// it's a common mistake to include # or ~ into attribute name
if (name && ["#", "~"].includes(name[0])) {
name = name.substr(1);
}
- if (type && name) {
+ if (type && name && value !== undefined && value !== null) {
+ return this.ownedAttributes.filter(attr => attr.type === type && attr.name === name && attr.value === value);
+ }
+ else if (type && name) {
return this.ownedAttributes.filter(attr => attr.type === type && attr.name === name);
}
else if (type) {
@@ -656,8 +702,8 @@ class Note extends AbstractEntity {
*
* This method can be significantly faster than the getAttribute()
*/
- getOwnedAttribute(type, name) {
- const attrs = this.getOwnedAttributes(type, name);
+ getOwnedAttribute(type, name, value) {
+ const attrs = this.getOwnedAttributes(type, name, value);
return attrs.length > 0 ? attrs[0] : null;
}
@@ -1163,6 +1209,10 @@ class Note extends AbstractEntity {
* @param {TaskContext} [taskContext]
*/
deleteNote(deleteId, taskContext) {
+ if (this.isDeleted) {
+ return;
+ }
+
if (!deleteId) {
deleteId = utils.randomString(10);
}
@@ -1171,6 +1221,11 @@ class Note extends AbstractEntity {
taskContext = new TaskContext('no-progress-reporting');
}
+ // needs to be run before branches and attributes are deleted and thus attached relations disappear
+ const handlers = require("../../services/handlers");
+ handlers.runAttachedRelations(this, 'runOnNoteDeletion', this);
+ taskContext.noteDeletionHandlerTriggered = true;
+
for (const branch of this.getParentBranches()) {
branch.deleteBranch(deleteId, taskContext);
}
@@ -1212,7 +1267,7 @@ class Note extends AbstractEntity {
title: this.title,
type: this.type,
mime: this.mime,
- isProtected: false, // will be fixed in the protectNoteRevisions() call
+ isProtected: this.isProtected,
utcDateLastEdited: this.utcDateModified > contentMetadata.utcDateModified
? this.utcDateModified
: contentMetadata.utcDateModified,
diff --git a/docs/backend_api/services_sql.js.html b/docs/backend_api/services_sql.js.html
index ccfeaa984..7af2575ee 100644
--- a/docs/backend_api/services_sql.js.html
+++ b/docs/backend_api/services_sql.js.html
@@ -270,9 +270,9 @@ function transactional(func) {
return ret;
}
catch (e) {
- const entityChanges = cls.getAndClearEntityChangeIds();
+ const entityChangeIds = cls.getAndClearEntityChangeIds();
- if (entityChanges.length > 0) {
+ if (entityChangeIds.length > 0) {
log.info("Transaction rollback dirtied the becca, forcing reload.");
require('../becca/becca_loader').load();
diff --git a/docs/frontend_api/Attribute.html b/docs/frontend_api/Attribute.html
index 2dd81757d..27344c376 100644
--- a/docs/frontend_api/Attribute.html
+++ b/docs/frontend_api/Attribute.html
@@ -742,7 +742,7 @@ and relation (representing named relationship between source and target note)
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/Branch.html b/docs/frontend_api/Branch.html
index 62f0c7722..00f7dbb78 100644
--- a/docs/frontend_api/Branch.html
+++ b/docs/frontend_api/Branch.html
@@ -1056,7 +1056,7 @@ parents.
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/FrontendScriptApi.html b/docs/frontend_api/FrontendScriptApi.html
index a6b3044b7..becbb6eae 100644
--- a/docs/frontend_api/FrontendScriptApi.html
+++ b/docs/frontend_api/FrontendScriptApi.html
@@ -8009,7 +8009,7 @@ Typical use case is when new note has been created, we should wait until it is s
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/NoteComplement.html b/docs/frontend_api/NoteComplement.html
index 53a162fef..d922a07ae 100644
--- a/docs/frontend_api/NoteComplement.html
+++ b/docs/frontend_api/NoteComplement.html
@@ -775,7 +775,7 @@
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/NoteShort.html b/docs/frontend_api/NoteShort.html
index 9796f8771..1e7dd6ff4 100644
--- a/docs/frontend_api/NoteShort.html
+++ b/docs/frontend_api/NoteShort.html
@@ -167,7 +167,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -267,7 +267,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -335,7 +335,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -403,7 +403,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -471,7 +471,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -543,7 +543,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -611,7 +611,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -679,7 +679,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -747,7 +747,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -815,7 +815,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -883,7 +883,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -955,7 +955,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -1103,7 +1103,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -1303,7 +1303,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -1481,7 +1481,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -1589,7 +1589,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -1693,7 +1693,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -1795,7 +1795,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -1897,7 +1897,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -1999,7 +1999,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -2150,7 +2150,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -2317,7 +2317,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -2472,7 +2472,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -2582,7 +2582,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -2756,7 +2756,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -2956,7 +2956,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -3134,7 +3134,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -3289,7 +3289,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -3456,7 +3456,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -3611,7 +3611,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -3766,7 +3766,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -3933,7 +3933,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -4088,7 +4088,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -4194,7 +4194,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -4296,7 +4296,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -4398,7 +4398,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -4500,7 +4500,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -4651,7 +4651,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -4818,7 +4818,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -4973,7 +4973,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -5143,7 +5143,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -5294,7 +5294,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -5400,7 +5400,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -5513,7 +5513,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -5619,7 +5619,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -5721,7 +5721,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -5895,7 +5895,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -6001,7 +6001,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -6152,7 +6152,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -6330,7 +6330,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -6485,7 +6485,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -6640,7 +6640,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -6795,7 +6795,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -6903,7 +6903,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -6987,7 +6987,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -7093,7 +7093,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -7199,7 +7199,7 @@ This note's representation is used in note tree and is kept in Froca.
Source:
@@ -7263,7 +7263,7 @@ This note's representation is used in note tree and is kept in Froca.
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/entities_attribute.js.html b/docs/frontend_api/entities_attribute.js.html
index 387d4eb2e..e43585495 100644
--- a/docs/frontend_api/entities_attribute.js.html
+++ b/docs/frontend_api/entities_attribute.js.html
@@ -104,7 +104,7 @@ export default Attribute;
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/entities_branch.js.html b/docs/frontend_api/entities_branch.js.html
index 0ef296b32..abf328ead 100644
--- a/docs/frontend_api/entities_branch.js.html
+++ b/docs/frontend_api/entities_branch.js.html
@@ -93,7 +93,7 @@ export default Branch;
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/entities_note_complement.js.html b/docs/frontend_api/entities_note_complement.js.html
index eb5f6203a..93cd2ef27 100644
--- a/docs/frontend_api/entities_note_complement.js.html
+++ b/docs/frontend_api/entities_note_complement.js.html
@@ -76,7 +76,7 @@ export default NoteComplement;
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/entities_note_short.js.html b/docs/frontend_api/entities_note_short.js.html
index 8e27a11a8..323a0ef60 100644
--- a/docs/frontend_api/entities_note_short.js.html
+++ b/docs/frontend_api/entities_note_short.js.html
@@ -45,7 +45,8 @@ const NOTE_TYPE_ICONS = {
"book": "bx bx-book",
"note-map": "bx bx-map-alt",
"mermaid": "bx bx-selection",
- "canvas": "bx bx-pen"
+ "canvas": "bx bx-pen",
+ "web-view": "bx bx-globe-alt"
};
/**
@@ -290,7 +291,11 @@ class NoteShort {
const templateNote = this.froca.notes[templateAttr.value];
if (templateNote && templateNote.noteId !== this.noteId) {
- attrArrs.push(templateNote.__getCachedAttributes(newPath));
+ attrArrs.push(
+ templateNote.__getCachedAttributes(newPath)
+ // template attr is used as a marker for templates, but it's not meant to be inherited
+ .filter(attr => !(attr.type === 'label' && attr.name === 'template'))
+ );
}
}
@@ -663,13 +668,18 @@ class NoteShort {
return [];
}
- return this.getAttributes()
+ const promotedAttrs = this.getAttributes()
.filter(attr => attr.isDefinition())
.filter(attr => {
const def = attr.getDefinition();
return def && def.isPromoted;
});
+
+ // attrs are not resorted if position changes after initial load
+ promotedAttrs.sort((a, b) => a.position < b.position ? -1 : 1);
+
+ return promotedAttrs;
}
hasAncestor(ancestorNoteId, visitedNoteIds = null) {
@@ -843,7 +853,7 @@ export default NoteShort;
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/global.html b/docs/frontend_api/global.html
index 8879721e8..30e91a656 100644
--- a/docs/frontend_api/global.html
+++ b/docs/frontend_api/global.html
@@ -156,7 +156,7 @@
Source:
@@ -425,7 +425,7 @@
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/index.html b/docs/frontend_api/index.html
index 590530faa..0eb4b2332 100644
--- a/docs/frontend_api/index.html
+++ b/docs/frontend_api/index.html
@@ -50,7 +50,7 @@
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/services_frontend_script_api.js.html b/docs/frontend_api/services_frontend_script_api.js.html
index da00296e1..e27c5db16 100644
--- a/docs/frontend_api/services_frontend_script_api.js.html
+++ b/docs/frontend_api/services_frontend_script_api.js.html
@@ -635,7 +635,7 @@ export default FrontendScriptApi;
- Classes Global
+ Classes Global
diff --git a/docs/frontend_api/widgets_collapsible_widget.js.html b/docs/frontend_api/widgets_collapsible_widget.js.html
index ed31ad9b3..0411406f7 100644
--- a/docs/frontend_api/widgets_collapsible_widget.js.html
+++ b/docs/frontend_api/widgets_collapsible_widget.js.html
@@ -37,6 +37,9 @@ const WIDGET_TPL = `
</div>
</div>`;
+/**
+ * TODO: rename, it's not collapsible anymore
+ */
export default class CollapsibleWidget extends NoteContextAwareWidget {
get widgetTitle() { return "Untitled widget"; }
@@ -60,10 +63,6 @@ export default class CollapsibleWidget extends NoteContextAwareWidget {
/** for overriding */
async doRenderBody() {}
-
- isExpanded() {
- return this.$bodyWrapper.hasClass("show");
- }
}
@@ -75,7 +74,7 @@ export default class CollapsibleWidget extends NoteContextAwareWidget {
- Classes Global
+ Classes Global
diff --git a/src/becca/entities/note.js b/src/becca/entities/note.js
index d562b5e5d..2c6e49df5 100644
--- a/src/becca/entities/note.js
+++ b/src/becca/entities/note.js
@@ -449,8 +449,18 @@ class Note extends AbstractEntity {
return this.inheritableAttributeCache;
}
- hasAttribute(type, name) {
- return !!this.getAttributes().find(attr => attr.type === type && attr.name === name);
+ /**
+ * @param type
+ * @param name
+ * @param [value]
+ * @returns {boolean}
+ */
+ hasAttribute(type, name, value) {
+ return !!this.getAttributes().find(attr =>
+ attr.type === type
+ && attr.name === name
+ && (value === undefined || value === null || attr.value === value)
+ );
}
getAttributeCaseInsensitive(type, name, value) {
@@ -471,27 +481,31 @@ class Note extends AbstractEntity {
/**
* @param {string} name - label name
+ * @param {string} [value] - label value
* @returns {boolean} true if label exists (including inherited)
*/
- hasLabel(name) { return this.hasAttribute(LABEL, name); }
+ hasLabel(name, value) { return this.hasAttribute(LABEL, name, value); }
/**
* @param {string} name - label name
+ * @param {string} [value] - label value
* @returns {boolean} true if label exists (excluding inherited)
*/
- hasOwnedLabel(name) { return this.hasOwnedAttribute(LABEL, name); }
+ hasOwnedLabel(name, value) { return this.hasOwnedAttribute(LABEL, name, value); }
/**
* @param {string} name - relation name
+ * @param {string} [value] - relation value
* @returns {boolean} true if relation exists (including inherited)
*/
- hasRelation(name) { return this.hasAttribute(RELATION, name); }
+ hasRelation(name, value) { return this.hasAttribute(RELATION, name, value); }
/**
* @param {string} name - relation name
+ * @param {string} [value] - relation value
* @returns {boolean} true if relation exists (excluding inherited)
*/
- hasOwnedRelation(name) { return this.hasOwnedAttribute(RELATION, name); }
+ hasOwnedRelation(name, value) { return this.hasOwnedAttribute(RELATION, name, value); }
/**
* @param {string} name - label name
@@ -544,10 +558,11 @@ class Note extends AbstractEntity {
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
+ * @param {string} [value] - attribute value
* @returns {boolean} true if note has an attribute with given type and name (excluding inherited)
*/
- hasOwnedAttribute(type, name) {
- return !!this.getOwnedAttribute(type, name);
+ hasOwnedAttribute(type, name, value) {
+ return !!this.getOwnedAttribute(type, name, value);
}
/**
@@ -634,15 +649,19 @@ 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
* @returns {Attribute[]} note's "owned" attributes - excluding inherited ones
*/
- getOwnedAttributes(type, name) {
+ getOwnedAttributes(type, name, value) {
// it's a common mistake to include # or ~ into attribute name
if (name && ["#", "~"].includes(name[0])) {
name = name.substr(1);
}
- if (type && name) {
+ if (type && name && value !== undefined && value !== null) {
+ return this.ownedAttributes.filter(attr => attr.type === type && attr.name === name && attr.value === value);
+ }
+ else if (type && name) {
return this.ownedAttributes.filter(attr => attr.type === type && attr.name === name);
}
else if (type) {
@@ -661,8 +680,8 @@ class Note extends AbstractEntity {
*
* This method can be significantly faster than the getAttribute()
*/
- getOwnedAttribute(type, name) {
- const attrs = this.getOwnedAttributes(type, name);
+ getOwnedAttribute(type, name, value) {
+ const attrs = this.getOwnedAttributes(type, name, value);
return attrs.length > 0 ? attrs[0] : null;
}
diff --git a/src/services/notes.js b/src/services/notes.js
index e3b14de22..25239e4a0 100644
--- a/src/services/notes.js
+++ b/src/services/notes.js
@@ -155,16 +155,19 @@ function createNewNote(params) {
scanForLinks(note);
+ copyChildAttributes(parentNote, note);
+
if (params.templateNoteId) {
if (!becca.getNote(params.templateNoteId)) {
throw new Error(`Template note '${params.templateNoteId}' does not exist.`);
}
- note.addRelation('template', params.templateNoteId);
+ // could be already copied from the parent via `child:`, no need to have 2
+ if (!note.hasOwnedRelation('template', params.templateNoteId)) {
+ note.addRelation('template', params.templateNoteId);
+ }
}
- copyChildAttributes(parentNote, note);
-
triggerNoteTitleChanged(note);
triggerChildNoteCreated(note, parentNote);