mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	Compare commits
	
		
			73 Commits
		
	
	
		
			v0.46.0-be
			...
			v0.46.3-be
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 50c84e0f5f | ||
|  | f27370d44f | ||
|  | c6c9202c00 | ||
|  | 2cafda5f66 | ||
|  | 873953cbaf | ||
|  | d51744ce19 | ||
|  | 7df8c940b6 | ||
|  | 9bac2a4819 | ||
|  | 88147f7a0a | ||
|  | ca77211b38 | ||
|  | 4606e8d118 | ||
|  | 9f002fa802 | ||
|  | 060d4fc27b | ||
|  | bf0fbe201e | ||
|  | 721e5da672 | ||
|  | 8192b51b8a | ||
|  | 73514a63d8 | ||
|  | f8c310eb8f | ||
|  | b9422b0efd | ||
|  | 14ced949a9 | ||
|  | 5b5c2a2dbb | ||
|  | 2c958eaacb | ||
|  | 4aa27b6033 | ||
|  | 89a0c5a1c9 | ||
|  | 78e48095e6 | ||
|  | 02016ed031 | ||
|  | cb91dadeca | ||
|  | 2c755bcc38 | ||
|  | 3c7a6bc1e4 | ||
|  | 3fe87259e2 | ||
|  | d476dfc53b | ||
|  | 19821b634f | ||
|  | cde41b268e | ||
|  | 1c59bc4d3c | ||
|  | cb6d35236c | ||
|  | 7572ee284b | ||
|  | d0eaf623a8 | ||
|  | 25c2db6c3a | ||
|  | 5a173ff14e | ||
|  | 7fab75b085 | ||
|  | 0f065536d0 | ||
|  | d0747abded | ||
|  | f62b4a581e | ||
|  | dcf1c62ec1 | ||
|  | 93d55b3e7b | ||
|  | 90c6852423 | ||
|  | 208baa56e9 | ||
|  | ddf8438b22 | ||
|  | 6008dc891f | ||
|  | cc887a00f2 | ||
|  | fbbd51d0b1 | ||
|  | 081b8b126a | ||
|  | 7a6bb81345 | ||
|  | 1d5714c411 | ||
|  | 56506d33a7 | ||
|  | c94fb7a62d | ||
|  | 4160da70be | ||
|  | 2cfd093cae | ||
|  | 859465841d | ||
|  | 0c9a11db6f | ||
|  | 4cbf9c2e86 | ||
|  | 1f7997eeed | ||
|  | 8e730c6ecf | ||
|  | 600a312b2a | ||
|  | ec2e973165 | ||
|  | faeb55bc90 | ||
|  | 23ebe360a6 | ||
|  | d905335935 | ||
|  | f49f510459 | ||
|  | e78b495bd3 | ||
|  | 5542c9dc57 | ||
|  | 2388da7cfb | ||
|  | 3b4fa0c5fc | 
| @@ -55,3 +55,7 @@ npm run start-server | |||||||
| * [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. Trilium Notes would not be the same without it. | * [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. Trilium Notes would not be the same without it. | ||||||
| * [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages | * [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages | ||||||
| * [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://github.com/zadam/trilium/wiki/Relation-map) and [link maps](https://github.com/zadam/trilium/wiki/Link-map) | * [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://github.com/zadam/trilium/wiki/Relation-map) and [link maps](https://github.com/zadam/trilium/wiki/Link-map) | ||||||
|  |  | ||||||
|  | ## License | ||||||
|  |  | ||||||
|  | This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. | ||||||
|   | |||||||
| @@ -15,6 +15,8 @@ module.exports = () => { | |||||||
| 
 | 
 | ||||||
|             note.mime = 'text/plain'; |             note.mime = 'text/plain'; | ||||||
|             note.save(); |             note.save(); | ||||||
|  | 
 | ||||||
|  |             console.log(`Migrated search note ${note.noteId}`); | ||||||
|         } |         } | ||||||
|         catch (e) { |         catch (e) { | ||||||
|             console.log(`Changing note content for note ${note.noteId} failed with: ${e.message} ${e.stack}`); |             console.log(`Changing note content for note ${note.noteId} failed with: ${e.message} ${e.stack}`); | ||||||
| @@ -298,29 +298,6 @@ | |||||||
|  |  | ||||||
|      |      | ||||||
|  |  | ||||||
|         <tr> |  | ||||||
|              |  | ||||||
|                 <td class="name"><code>utcDateCreated</code></td> |  | ||||||
|              |  | ||||||
|  |  | ||||||
|             <td class="type"> |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <span class="param-type">string</span> |  | ||||||
|  |  | ||||||
|  |  | ||||||
|              |  | ||||||
|             </td> |  | ||||||
|  |  | ||||||
|              |  | ||||||
|  |  | ||||||
|              |  | ||||||
|  |  | ||||||
|             <td class="description last"></td> |  | ||||||
|         </tr> |  | ||||||
|  |  | ||||||
|      |  | ||||||
|  |  | ||||||
|         <tr> |         <tr> | ||||||
|              |              | ||||||
|                 <td class="name"><code>utcDateModified</code></td> |                 <td class="name"><code>utcDateModified</code></td> | ||||||
| @@ -378,7 +355,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line26">line 26</a> |         <a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line25">line 25</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -493,7 +470,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line40">line 40</a> |         <a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line43">line 43</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -598,7 +575,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line47">line 47</a> |         <a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line50">line 50</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -703,7 +680,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line62">line 62</a> |         <a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line65">line 65</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -619,7 +619,7 @@ JSON MIME type. See also createNewNote() for more options. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line205">line 205</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line207">line 207</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -782,7 +782,7 @@ JSON MIME type. See also createNewNote() for more options. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line232">line 232</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line234">line 234</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1068,7 +1068,7 @@ JSON MIME type. See also createNewNote() for more options. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line260">line 260</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line262">line 262</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1273,7 +1273,7 @@ JSON MIME type. See also createNewNote() for more options. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line189">line 189</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line191">line 191</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1451,7 +1451,7 @@ JSON MIME type. See also createNewNote() for more options. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line160">line 160</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line162">line 162</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1652,7 +1652,7 @@ JSON MIME type. See also createNewNote() for more options. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line150">line 150</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line152">line 152</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1754,7 +1754,7 @@ JSON MIME type. See also createNewNote() for more options. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line397">line 397</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line399">line 399</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2224,7 +2224,7 @@ JSON MIME type. See also createNewNote() for more options. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line318">line 318</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line320">line 320</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2847,7 +2847,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line345">line 345</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line347">line 347</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3202,7 +3202,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line129">line 129</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line131">line 131</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3400,7 +3400,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line139">line 139</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line141">line 141</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3509,7 +3509,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line309">line 309</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line311">line 311</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3618,7 +3618,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line326">line 326</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line328">line 328</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3799,7 +3799,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line336">line 336</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line338">line 338</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3957,7 +3957,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line354">line 354</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line356">line 356</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4110,7 +4110,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line301">line 301</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line303">line 303</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4196,7 +4196,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line392">line 392</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line394">line 394</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4334,7 +4334,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line115">line 115</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line117">line 117</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4391,7 +4391,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|  |  | ||||||
|      |      | ||||||
|     <h4 class="name" id="searchForNotes"><span class="type-signature"></span>searchForNotes<span class="signature">(query, searchContext<span class="signature-attributes">opt</span>)</span><span class="type-signature"> → {Array.<<a href="Note.html">Note</a>>}</span></h4> |     <h4 class="name" id="searchForNotes"><span class="type-signature"></span>searchForNotes<span class="signature">(query, searchParams<span class="signature-attributes">opt</span>)</span><span class="type-signature"> → {Array.<<a href="Note.html">Note</a>>}</span></h4> | ||||||
|      |      | ||||||
|  |  | ||||||
|      |      | ||||||
| @@ -4469,13 +4469,13 @@ if some action needs to happen on only one specific instance. | |||||||
|  |  | ||||||
|         <tr> |         <tr> | ||||||
|              |              | ||||||
|                 <td class="name"><code>searchContext</code></td> |                 <td class="name"><code>searchParams</code></td> | ||||||
|              |              | ||||||
|  |  | ||||||
|             <td class="type"> |             <td class="type"> | ||||||
|              |              | ||||||
|                  |                  | ||||||
| <span class="param-type">SearchContext</span> | <span class="param-type">Object</span> | ||||||
|  |  | ||||||
|  |  | ||||||
|              |              | ||||||
| @@ -4745,7 +4745,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line374">line 374</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line376">line 376</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4878,7 +4878,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line360">line 360</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line362">line 362</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5084,7 +5084,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line172">line 172</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line174">line 174</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5240,7 +5240,7 @@ exists, then we'll use that transaction. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line384">line 384</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line386">line 386</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -296,29 +296,6 @@ | |||||||
|  |  | ||||||
|      |      | ||||||
|  |  | ||||||
|         <tr> |  | ||||||
|              |  | ||||||
|                 <td class="name"><code>isErased</code></td> |  | ||||||
|              |  | ||||||
|  |  | ||||||
|             <td class="type"> |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <span class="param-type">boolean</span> |  | ||||||
|  |  | ||||||
|  |  | ||||||
|              |  | ||||||
|             </td> |  | ||||||
|  |  | ||||||
|              |  | ||||||
|  |  | ||||||
|              |  | ||||||
|  |  | ||||||
|             <td class="description last">true if note's content is erased after it has been deleted</td> |  | ||||||
|         </tr> |  | ||||||
|  |  | ||||||
|      |  | ||||||
|  |  | ||||||
|         <tr> |         <tr> | ||||||
|              |              | ||||||
|                 <td class="name"><code>dateCreated</code></td> |                 <td class="name"><code>dateCreated</code></td> | ||||||
| @@ -445,7 +422,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line32">line 32</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line31">line 31</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -560,7 +537,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line531">line 531</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line537">line 537</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -662,7 +639,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line855">line 855</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line861">line 861</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -840,7 +817,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line430">line 430</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line436">line 436</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1040,7 +1017,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line268">line 268</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line274">line 274</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1218,7 +1195,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line441">line 441</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line447">line 447</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1327,7 +1304,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line801">line 801</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line807">line 807</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1429,7 +1406,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line829">line 829</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line835">line 835</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1535,7 +1512,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line815">line 815</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line821">line 821</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1641,7 +1618,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line71">line 71</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line70">line 70</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1743,7 +1720,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line107">line 107</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line106">line 106</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1845,7 +1822,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line701">line 701</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line707">line 707</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2078,7 +2055,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line724">line 724</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line730">line 730</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2276,7 +2253,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line762">line 762</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line768">line 768</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2474,7 +2451,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line771">line 771</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line777">line 777</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2576,7 +2553,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line118">line 118</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line117">line 117</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2727,7 +2704,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line584">line 584</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line590">line 590</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2897,7 +2874,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line291">line 291</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line297">line 297</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3052,7 +3029,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line608">line 608</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line614">line 614</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3167,7 +3144,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line788">line 788</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line794">line 794</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3269,7 +3246,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line250">line 250</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line256">line 256</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3476,7 +3453,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line226">line 226</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line232">line 232</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3654,7 +3631,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line452">line 452</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line458">line 458</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3812,7 +3789,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line590">line 590</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line596">line 596</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3982,7 +3959,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line299">line 299</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line305">line 305</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4137,7 +4114,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line614">line 614</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line620">line 620</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4295,7 +4272,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line602">line 602</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line608">line 608</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4465,7 +4442,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line315">line 315</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line321">line 321</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4620,7 +4597,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line642">line 642</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line648">line 648</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4778,7 +4755,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line626">line 626</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line632">line 632</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4887,7 +4864,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line841">line 841</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line847">line 847</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5042,7 +5019,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line596">line 596</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line602">line 602</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5212,7 +5189,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line307">line 307</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line313">line 313</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5367,7 +5344,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line632">line 632</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line638">line 638</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5537,7 +5514,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line323">line 323</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line329">line 329</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5688,7 +5665,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line620">line 620</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line626">line 626</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5801,7 +5778,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line778">line 778</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line784">line 784</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5903,7 +5880,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line197">line 197</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line203">line 203</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6009,7 +5986,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line259">line 259</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line265">line 265</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6187,7 +6164,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line412">line 412</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line418">line 418</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6293,7 +6270,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line808">line 808</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line814">line 814</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6448,7 +6425,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line560">line 560</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line566">line 566</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6626,7 +6603,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line421">line 421</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line427">line 427</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6781,7 +6758,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line566">line 566</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line572">line 572</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6936,7 +6913,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line578">line 578</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line584">line 584</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -7091,7 +7068,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line572">line 572</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line578">line 578</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -7202,7 +7179,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line338">line 338</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line344">line 344</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -7330,7 +7307,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line886">line 886</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line892">line 892</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -7436,7 +7413,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line187">line 187</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line193">line 193</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -7542,7 +7519,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line179">line 179</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line185">line 185</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -7648,7 +7625,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line174">line 174</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line180">line 180</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -7754,7 +7731,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line169">line 169</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line175">line 175</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -7860,7 +7837,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line192">line 192</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line198">line 198</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -8093,7 +8070,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line515">line 515</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line521">line 521</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -8273,7 +8250,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line688">line 688</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line694">line 694</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -8453,7 +8430,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line696">line 696</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line702">line 702</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -8664,7 +8641,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line482">line 482</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line488">line 488</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -8844,7 +8821,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line672">line 672</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line678">line 678</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -9024,7 +9001,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line680">line 680</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line686">line 686</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -9266,7 +9243,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line466">line 466</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line472">line 472</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -9477,7 +9454,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line655">line 655</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line661">line 661</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -9688,7 +9665,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line664">line 664</a> |         <a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line670">line 670</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -198,29 +198,6 @@ | |||||||
|  |  | ||||||
|              |              | ||||||
|  |  | ||||||
|             <td class="description last"></td> |  | ||||||
|         </tr> |  | ||||||
|  |  | ||||||
|      |  | ||||||
|  |  | ||||||
|         <tr> |  | ||||||
|              |  | ||||||
|                 <td class="name"><code>isErased</code></td> |  | ||||||
|              |  | ||||||
|  |  | ||||||
|             <td class="type"> |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <span class="param-type">boolean</span> |  | ||||||
|  |  | ||||||
|  |  | ||||||
|              |  | ||||||
|             </td> |  | ||||||
|  |  | ||||||
|              |  | ||||||
|  |  | ||||||
|              |  | ||||||
|  |  | ||||||
|             <td class="description last"></td> |             <td class="description last"></td> | ||||||
|         </tr> |         </tr> | ||||||
|  |  | ||||||
| @@ -398,7 +375,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line28">line 28</a> |         <a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line27">line 27</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -513,7 +490,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line68">line 68</a> |         <a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line66">line 66</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -615,7 +592,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line54">line 54</a> |         <a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line52">line 52</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -136,30 +136,7 @@ | |||||||
|  |  | ||||||
|         <tr> |         <tr> | ||||||
|              |              | ||||||
|                 <td class="name"><code>isDeleted</code></td> |                 <td class="name"><code>utcDateCreated</code></td> | ||||||
|              |  | ||||||
|  |  | ||||||
|             <td class="type"> |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <span class="param-type">boolean</span> |  | ||||||
|  |  | ||||||
|  |  | ||||||
|              |  | ||||||
|             </td> |  | ||||||
|  |  | ||||||
|              |  | ||||||
|  |  | ||||||
|              |  | ||||||
|  |  | ||||||
|             <td class="description last"></td> |  | ||||||
|         </tr> |  | ||||||
|  |  | ||||||
|      |  | ||||||
|  |  | ||||||
|         <tr> |  | ||||||
|              |  | ||||||
|                 <td class="name"><code>utcDateModified</code></td> |  | ||||||
|              |              | ||||||
|  |  | ||||||
|             <td class="type"> |             <td class="type"> | ||||||
| @@ -214,7 +191,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_recent_note.js.html">entities/recent_note.js</a>, <a href="entities_recent_note.js.html#line16">line 16</a> |         <a href="entities_recent_note.js.html">entities/recent_note.js</a>, <a href="entities_recent_note.js.html#line15">line 15</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -46,7 +46,6 @@ const promotedAttributeDefinitionParser = require("../services/promoted_attribut | |||||||
|  * @property {boolean} isInheritable - immutable |  * @property {boolean} isInheritable - immutable | ||||||
|  * @property {boolean} isDeleted |  * @property {boolean} isDeleted | ||||||
|  * @property {string|null} deleteId - ID identifying delete transaction |  * @property {string|null} deleteId - ID identifying delete transaction | ||||||
|  * @property {string} utcDateCreated |  | ||||||
|  * @property {string} utcDateModified |  * @property {string} utcDateModified | ||||||
|  * |  * | ||||||
|  * @extends Entity |  * @extends Entity | ||||||
| @@ -54,7 +53,7 @@ const promotedAttributeDefinitionParser = require("../services/promoted_attribut | |||||||
| class Attribute extends Entity { | class Attribute extends Entity { | ||||||
|     static get entityName() { return "attributes"; } |     static get entityName() { return "attributes"; } | ||||||
|     static get primaryKeyName() { return "attributeId"; } |     static get primaryKeyName() { return "attributeId"; } | ||||||
|     static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable", "isDeleted", "utcDateCreated"]; } |     static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable", "isDeleted"]; } | ||||||
|  |  | ||||||
|     constructor(row) { |     constructor(row) { | ||||||
|         super(row); |         super(row); | ||||||
| @@ -62,6 +61,10 @@ class Attribute extends Entity { | |||||||
|         this.isInheritable = !!this.isInheritable; |         this.isInheritable = !!this.isInheritable; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     isAutoLink() { | ||||||
|  |         return this.type === 'relation' && ['internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'].includes(this.name); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @returns {Note|null} |      * @returns {Note|null} | ||||||
|      */ |      */ | ||||||
| @@ -127,15 +130,9 @@ class Attribute extends Entity { | |||||||
|             this.isDeleted = false; |             this.isDeleted = false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!this.utcDateCreated) { |  | ||||||
|             this.utcDateCreated = dateUtils.utcNowDateTime(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         super.beforeSaving(); |         super.beforeSaving(); | ||||||
|  |  | ||||||
|         if (this.isChanged) { |         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||||
|             this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     createClone(type, name, value, isInheritable) { |     createClone(type, name, value, isInheritable) { | ||||||
| @@ -147,7 +144,6 @@ class Attribute extends Entity { | |||||||
|             position: this.position, |             position: this.position, | ||||||
|             isInheritable: isInheritable, |             isInheritable: isInheritable, | ||||||
|             isDeleted: false, |             isDeleted: false, | ||||||
|             utcDateCreated: this.utcDateCreated, |  | ||||||
|             utcDateModified: this.utcDateModified |             utcDateModified: this.utcDateModified | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -66,7 +66,7 @@ class Branch extends Entity { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     beforeSaving() { |     beforeSaving() { | ||||||
|         if (this.notePosition === undefined) { |         if (this.notePosition === undefined || this.notePosition === null) { | ||||||
|             const maxNotePos = sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [this.parentNoteId]); |             const maxNotePos = sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [this.parentNoteId]); | ||||||
|             this.notePosition = maxNotePos === null ? 0 : maxNotePos + 10; |             this.notePosition = maxNotePos === null ? 0 : maxNotePos + 10; | ||||||
|         } |         } | ||||||
| @@ -85,9 +85,7 @@ class Branch extends Entity { | |||||||
|  |  | ||||||
|         super.beforeSaving(); |         super.beforeSaving(); | ||||||
|  |  | ||||||
|         if (this.isChanged) { |         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||||
|             this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     createClone(parentNoteId, notePosition) { |     createClone(parentNoteId, notePosition) { | ||||||
|   | |||||||
| @@ -43,18 +43,13 @@ class Entity { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if ('isDeleted' in this) { |         if ('isDeleted' in this && this.constructor.entityName !== 'recent_notes') { | ||||||
|             this.isDeleted = !!this.isDeleted; |             this.isDeleted = !!this.isDeleted; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     beforeSaving() { |     beforeSaving() { | ||||||
|         this.generateIdIfNecessary(); |         this.generateIdIfNecessary(); | ||||||
|  |  | ||||||
|         const origHash = this.hash; |  | ||||||
|  |  | ||||||
|         this.hash = this.generateHash(); |  | ||||||
|         this.isChanged = origHash !== this.hash; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     generateIdIfNecessary() { |     generateIdIfNecessary() { | ||||||
| @@ -73,6 +68,10 @@ class Entity { | |||||||
|         return utils.hash(contentToHash).substr(0, 10); |         return utils.hash(contentToHash).substr(0, 10); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     getUtcDateChanged() { | ||||||
|  |         return this.utcDateModified; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     get repository() { |     get repository() { | ||||||
|         if (!repo) { |         if (!repo) { | ||||||
|             repo = require('../services/repository'); |             repo = require('../services/repository'); | ||||||
|   | |||||||
| @@ -49,7 +49,6 @@ const RELATION = 'relation'; | |||||||
|  * @property {boolean} isProtected - true if note is protected |  * @property {boolean} isProtected - true if note is protected | ||||||
|  * @property {boolean} isDeleted - true if note is deleted |  * @property {boolean} isDeleted - true if note is deleted | ||||||
|  * @property {string|null} deleteId - ID identifying delete transaction |  * @property {string|null} deleteId - ID identifying delete transaction | ||||||
|  * @property {boolean} isErased - true if note's content is erased after it has been deleted |  | ||||||
|  * @property {string} dateCreated - local date time (with offset) |  * @property {string} dateCreated - local date time (with offset) | ||||||
|  * @property {string} dateModified - local date time (with offset) |  * @property {string} dateModified - local date time (with offset) | ||||||
|  * @property {string} utcDateCreated |  * @property {string} utcDateCreated | ||||||
| @@ -98,9 +97,9 @@ class Note extends Entity { | |||||||
|     /** @returns {*} */ |     /** @returns {*} */ | ||||||
|     getContent(silentNotFoundError = false) { |     getContent(silentNotFoundError = false) { | ||||||
|         if (this.content === undefined) { |         if (this.content === undefined) { | ||||||
|             const res = sql.getRow(`SELECT content, hash FROM note_contents WHERE noteId = ?`, [this.noteId]); |             const row = sql.getRow(`SELECT content FROM note_contents WHERE noteId = ?`, [this.noteId]); | ||||||
|  |  | ||||||
|             if (!res) { |             if (!row) { | ||||||
|                 if (silentNotFoundError) { |                 if (silentNotFoundError) { | ||||||
|                     return undefined; |                     return undefined; | ||||||
|                 } |                 } | ||||||
| @@ -109,7 +108,7 @@ class Note extends Entity { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             this.content = res.content; |             this.content = row.content; | ||||||
|  |  | ||||||
|             if (this.isProtected) { |             if (this.isProtected) { | ||||||
|                 if (this.isContentAvailable) { |                 if (this.isContentAvailable) { | ||||||
| @@ -171,8 +170,7 @@ class Note extends Entity { | |||||||
|             noteId: this.noteId, |             noteId: this.noteId, | ||||||
|             content: content, |             content: content, | ||||||
|             dateModified: dateUtils.localNowDateTime(), |             dateModified: dateUtils.localNowDateTime(), | ||||||
|             utcDateModified: dateUtils.utcNowDateTime(), |             utcDateModified: dateUtils.utcNowDateTime() | ||||||
|             hash: utils.hash(this.noteId + "|" + content.toString()) |  | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         if (this.isProtected) { |         if (this.isProtected) { | ||||||
| @@ -186,7 +184,15 @@ class Note extends Entity { | |||||||
|  |  | ||||||
|         sql.upsert("note_contents", "noteId", pojo); |         sql.upsert("note_contents", "noteId", pojo); | ||||||
|  |  | ||||||
|         entityChangesService.addNoteContentEntityChange(this.noteId); |         const hash = utils.hash(this.noteId + "|" + content.toString()); | ||||||
|  |  | ||||||
|  |         entityChangesService.addEntityChange({ | ||||||
|  |             entityName: 'note_contents', | ||||||
|  |             entityId: this.noteId, | ||||||
|  |             hash: hash, | ||||||
|  |             isErased: false, | ||||||
|  |             utcDateChanged: this.getUtcDateChanged() | ||||||
|  |         }, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     setJsonContent(content) { |     setJsonContent(content) { | ||||||
| @@ -834,7 +840,7 @@ class Note extends Entity { | |||||||
|      * @returns {boolean} - true if note has children |      * @returns {boolean} - true if note has children | ||||||
|      */ |      */ | ||||||
|     hasChildren() { |     hasChildren() { | ||||||
|         return (this.getChildNotes()).length > 0; |         return this.getChildNotes().length > 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -932,10 +938,8 @@ class Note extends Entity { | |||||||
|  |  | ||||||
|         super.beforeSaving(); |         super.beforeSaving(); | ||||||
|  |  | ||||||
|         if (this.isChanged) { |         this.dateModified = dateUtils.localNowDateTime(); | ||||||
|             this.dateModified = dateUtils.localNowDateTime(); |         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||||
|             this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // cannot be static! |     // cannot be static! | ||||||
|   | |||||||
| @@ -43,7 +43,6 @@ const entityChangesService = require('../services/entity_changes.js'); | |||||||
|  * @property {string} type |  * @property {string} type | ||||||
|  * @property {string} mime |  * @property {string} mime | ||||||
|  * @property {string} title |  * @property {string} title | ||||||
|  * @property {boolean} isErased |  | ||||||
|  * @property {boolean} isProtected |  * @property {boolean} isProtected | ||||||
|  * @property {string} dateLastEdited |  * @property {string} dateLastEdited | ||||||
|  * @property {string} dateCreated |  * @property {string} dateCreated | ||||||
| @@ -56,12 +55,11 @@ const entityChangesService = require('../services/entity_changes.js'); | |||||||
| class NoteRevision extends Entity { | class NoteRevision extends Entity { | ||||||
|     static get entityName() { return "note_revisions"; } |     static get entityName() { return "note_revisions"; } | ||||||
|     static get primaryKeyName() { return "noteRevisionId"; } |     static get primaryKeyName() { return "noteRevisionId"; } | ||||||
|     static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "isErased", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; } |     static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; } | ||||||
|  |  | ||||||
|     constructor(row) { |     constructor(row) { | ||||||
|         super(row); |         super(row); | ||||||
|  |  | ||||||
|         this.isErased = !!this.isErased; |  | ||||||
|         this.isProtected = !!this.isProtected; |         this.isProtected = !!this.isProtected; | ||||||
|  |  | ||||||
|         if (this.isProtected) { |         if (this.isProtected) { | ||||||
| @@ -95,7 +93,7 @@ class NoteRevision extends Entity { | |||||||
|     /** @returns {*} */ |     /** @returns {*} */ | ||||||
|     getContent(silentNotFoundError = false) { |     getContent(silentNotFoundError = false) { | ||||||
|         if (this.content === undefined) { |         if (this.content === undefined) { | ||||||
|             const res = sql.getRow(`SELECT content, hash FROM note_revision_contents WHERE noteRevisionId = ?`, [this.noteRevisionId]); |             const res = sql.getRow(`SELECT content FROM note_revision_contents WHERE noteRevisionId = ?`, [this.noteRevisionId]); | ||||||
|  |  | ||||||
|             if (!res) { |             if (!res) { | ||||||
|                 if (silentNotFoundError) { |                 if (silentNotFoundError) { | ||||||
| @@ -107,7 +105,6 @@ class NoteRevision extends Entity { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             this.content = res.content; |             this.content = res.content; | ||||||
|  |  | ||||||
|             if (this.isProtected) { |             if (this.isProtected) { | ||||||
|                 if (protectedSessionService.isProtectedSessionAvailable()) { |                 if (protectedSessionService.isProtectedSessionAvailable()) { | ||||||
|                     this.content = protectedSessionService.decrypt(this.content); |                     this.content = protectedSessionService.decrypt(this.content); | ||||||
| @@ -134,8 +131,7 @@ class NoteRevision extends Entity { | |||||||
|         const pojo = { |         const pojo = { | ||||||
|             noteRevisionId: this.noteRevisionId, |             noteRevisionId: this.noteRevisionId, | ||||||
|             content: content, |             content: content, | ||||||
|             utcDateModified: dateUtils.utcNowDateTime(), |             utcDateModified: dateUtils.utcNowDateTime() | ||||||
|             hash: utils.hash(this.noteRevisionId + "|" + content) |  | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         if (this.isProtected) { |         if (this.isProtected) { | ||||||
| @@ -149,15 +145,21 @@ class NoteRevision extends Entity { | |||||||
|  |  | ||||||
|         sql.upsert("note_revision_contents", "noteRevisionId", pojo); |         sql.upsert("note_revision_contents", "noteRevisionId", pojo); | ||||||
|  |  | ||||||
|         entityChangesService.addNoteRevisionContentEntityChange(this.noteRevisionId); |         const hash = utils.hash(this.noteRevisionId + "|" + content); | ||||||
|  |  | ||||||
|  |         entityChangesService.addEntityChange({ | ||||||
|  |             entityName: 'note_revision_contents', | ||||||
|  |             entityId: this.noteRevisionId, | ||||||
|  |             hash: hash, | ||||||
|  |             isErased: false, | ||||||
|  |             utcDateChanged: this.getUtcDateChanged() | ||||||
|  |         }, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     beforeSaving() { |     beforeSaving() { | ||||||
|         super.beforeSaving(); |         super.beforeSaving(); | ||||||
|  |  | ||||||
|         if (this.isChanged) { |         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||||
|             this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // cannot be static! |     // cannot be static! | ||||||
|   | |||||||
| @@ -60,13 +60,12 @@ class Option extends Entity { | |||||||
|  |  | ||||||
|         super.beforeSaving(); |         super.beforeSaving(); | ||||||
|  |  | ||||||
|         if (this.isChanged) { |         this.utcDateModified = dateUtils.utcNowDateTime(); | ||||||
|             this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = Option;</code></pre> | module.exports = Option; | ||||||
|  | </code></pre> | ||||||
|         </article> |         </article> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,21 +36,15 @@ const dateUtils = require('../services/date_utils'); | |||||||
|  * |  * | ||||||
|  * @property {string} noteId |  * @property {string} noteId | ||||||
|  * @property {string} notePath |  * @property {string} notePath | ||||||
|  * @property {boolean} isDeleted |  * @property {string} utcDateCreated | ||||||
|  * @property {string} utcDateModified |  | ||||||
|  * |  * | ||||||
|  * @extends Entity |  * @extends Entity | ||||||
|  */ |  */ | ||||||
| class RecentNote extends Entity { | class RecentNote extends Entity { | ||||||
|     static get entityName() { return "recent_notes"; } |     static get entityName() { return "recent_notes"; } | ||||||
|     static get primaryKeyName() { return "noteId"; } |     static get primaryKeyName() { return "noteId"; } | ||||||
|     static get hashedProperties() { return ["noteId", "notePath", "utcDateCreated", "isDeleted"]; } |  | ||||||
|  |  | ||||||
|     beforeSaving() { |     beforeSaving() { | ||||||
|         if (!this.isDeleted) { |  | ||||||
|             this.isDeleted = false; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (!this.utcDateCreated) { |         if (!this.utcDateCreated) { | ||||||
|             this.utcDateCreated = dateUtils.utcNowDateTime(); |             this.utcDateCreated = dateUtils.utcNowDateTime(); | ||||||
|         } |         } | ||||||
| @@ -59,7 +53,8 @@ class RecentNote extends Entity { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = RecentNote;</code></pre> | module.exports = RecentNote; | ||||||
|  | </code></pre> | ||||||
|         </article> |         </article> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -391,7 +391,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line213">line 213</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line215">line 215</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -579,7 +579,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line174">line 174</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line176">line 176</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -767,7 +767,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line234">line 234</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line236">line 236</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1053,7 +1053,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line241">line 241</a> |         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line243">line 243</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -120,13 +120,15 @@ function BackendScriptApi(currentNote, apiParams) { | |||||||
|      * |      * | ||||||
|      * @method |      * @method | ||||||
|      * @param {string} query |      * @param {string} query | ||||||
|      * @param {SearchContext} [searchContext] |      * @param {Object} [searchParams] | ||||||
|      * @returns {Note[]} |      * @returns {Note[]} | ||||||
|      */ |      */ | ||||||
|     this.searchForNotes = (query, searchContext) => { |     this.searchForNotes = (query, searchParams = {}) => { | ||||||
|         searchContext = searchContext || new SearchContext(); |         if (searchParams.includeArchivedNotes === undefined) { | ||||||
|  |             searchParams.includeArchivedNotes = true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         const noteIds = searchService.findNotesWithQuery(query, searchContext) |         const noteIds = searchService.findNotesWithQuery(query, new SearchContext(searchParams)) | ||||||
|             .map(sr => sr.noteId); |             .map(sr => sr.noteId); | ||||||
|  |  | ||||||
|         return repository.getNotes(noteIds); |         return repository.getNotes(noteIds); | ||||||
|   | |||||||
| @@ -201,7 +201,7 @@ | |||||||
|  |  | ||||||
|          |          | ||||||
|              |              | ||||||
| <h4 class="name" id="isDeleted"><span class="type-signature"></span>isDeleted<span class="type-signature"></span></h4> | <h4 class="name" id="fromSearchNote"><span class="type-signature"></span>fromSearchNote<span class="type-signature"></span></h4> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -259,6 +259,64 @@ | |||||||
|  |  | ||||||
|          |          | ||||||
|              |              | ||||||
|  | <h4 class="name" id="isDeleted"><span class="type-signature"></span>isDeleted<span class="type-signature"></span></h4> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | <dl class="details"> | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     <dt class="tag-source">Source:</dt> | ||||||
|  |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|  |         <a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line25">line 25</a> | ||||||
|  |     </li></ul></dd> | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  | </dl> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |          | ||||||
|  |              | ||||||
| <h4 class="name" id="isExpanded"><span class="type-signature"></span>isExpanded<span class="type-signature"></span></h4> | <h4 class="name" id="isExpanded"><span class="type-signature"></span>isExpanded<span class="type-signature"></span></h4> | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -607,7 +665,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line27">line 27</a> |         <a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line29">line 29</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -709,7 +767,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line32">line 32</a> |         <a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line34">line 34</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -811,7 +869,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line37">line 37</a> |         <a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line39">line 39</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -913,7 +971,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line42">line 42</a> |         <a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line44">line 44</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -81,7 +81,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line24">line 24</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line22">line 22</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -223,7 +223,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line28">line 28</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line26">line 26</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -329,7 +329,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line50">line 50</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line48">line 48</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -435,7 +435,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line41">line 41</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line39">line 39</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -545,7 +545,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line33">line 33</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line31">line 31</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -658,7 +658,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line35">line 35</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line33">line 33</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -768,7 +768,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line31">line 31</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line29">line 29</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -874,7 +874,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line44">line 44</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line42">line 42</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -980,7 +980,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line47">line 47</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line45">line 45</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1109,7 +1109,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line69">line 69</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line67">line 67</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1264,7 +1264,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line59">line 59</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line57">line 57</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1419,7 +1419,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line89">line 89</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line101">line 101</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1556,7 +1556,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line287">line 287</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line302">line 302</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1712,7 +1712,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line392">line 392</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line413">line 413</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1748,7 +1748,7 @@ | |||||||
|      |      | ||||||
|  |  | ||||||
|      |      | ||||||
|     <h4 class="name" id="createNoteLink"><span class="type-signature"></span>createNoteLink<span class="signature">(notePath, noteTitle<span class="signature-attributes">opt</span>)</span><span class="type-signature"></span></h4> |     <h4 class="name" id="createNoteLink"><span class="type-signature"></span>createNoteLink<span class="signature">(notePath, params<span class="signature-attributes">opt</span>, title=<span class="signature-attributes">opt</span>)</span><span class="type-signature"></span></h4> | ||||||
|      |      | ||||||
|  |  | ||||||
|      |      | ||||||
| @@ -1825,7 +1825,148 @@ | |||||||
|  |  | ||||||
|         <tr> |         <tr> | ||||||
|              |              | ||||||
|                 <td class="name"><code>noteTitle</code></td> |                 <td class="name"><code>params</code></td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="type"> | ||||||
|  |              | ||||||
|  |                  | ||||||
|  | <span class="param-type">object</span> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |              | ||||||
|  |             </td> | ||||||
|  |  | ||||||
|  |              | ||||||
|  |                 <td class="attributes"> | ||||||
|  |                  | ||||||
|  |                     <optional><br> | ||||||
|  |                  | ||||||
|  |  | ||||||
|  |                  | ||||||
|  |  | ||||||
|  |                  | ||||||
|  |                 </td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="description last"> | ||||||
|  |                 <h6>Properties</h6> | ||||||
|  |                  | ||||||
|  |  | ||||||
|  | <table class="params"> | ||||||
|  |     <thead> | ||||||
|  |     <tr> | ||||||
|  |          | ||||||
|  |         <th>Name</th> | ||||||
|  |          | ||||||
|  |  | ||||||
|  |         <th>Type</th> | ||||||
|  |  | ||||||
|  |          | ||||||
|  |         <th>Attributes</th> | ||||||
|  |          | ||||||
|  |  | ||||||
|  |          | ||||||
|  |         <th>Default</th> | ||||||
|  |          | ||||||
|  |  | ||||||
|  |         <th class="last">Description</th> | ||||||
|  |     </tr> | ||||||
|  |     </thead> | ||||||
|  |  | ||||||
|  |     <tbody> | ||||||
|  |      | ||||||
|  |  | ||||||
|  |         <tr> | ||||||
|  |              | ||||||
|  |                 <td class="name"><code>showTooltip</code></td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="type"> | ||||||
|  |              | ||||||
|  |                  | ||||||
|  | <span class="param-type">boolean</span> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |              | ||||||
|  |             </td> | ||||||
|  |  | ||||||
|  |              | ||||||
|  |                 <td class="attributes"> | ||||||
|  |                  | ||||||
|  |                     <optional><br> | ||||||
|  |                  | ||||||
|  |  | ||||||
|  |                  | ||||||
|  |  | ||||||
|  |                  | ||||||
|  |                 </td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |              | ||||||
|  |                 <td class="default"> | ||||||
|  |                  | ||||||
|  |                     true | ||||||
|  |                  | ||||||
|  |                 </td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="description last">enable/disable tooltip on the link</td> | ||||||
|  |         </tr> | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |         <tr> | ||||||
|  |              | ||||||
|  |                 <td class="name"><code>showNotePath</code></td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="type"> | ||||||
|  |              | ||||||
|  |                  | ||||||
|  | <span class="param-type">boolean</span> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |              | ||||||
|  |             </td> | ||||||
|  |  | ||||||
|  |              | ||||||
|  |                 <td class="attributes"> | ||||||
|  |                  | ||||||
|  |                     <optional><br> | ||||||
|  |                  | ||||||
|  |  | ||||||
|  |                  | ||||||
|  |  | ||||||
|  |                  | ||||||
|  |                 </td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |              | ||||||
|  |                 <td class="default"> | ||||||
|  |                  | ||||||
|  |                     false | ||||||
|  |                  | ||||||
|  |                 </td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="description last">show also whole note's path as part of the link</td> | ||||||
|  |         </tr> | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     </tbody> | ||||||
|  | </table> | ||||||
|  |  | ||||||
|  |             </td> | ||||||
|  |         </tr> | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |         <tr> | ||||||
|  |              | ||||||
|  |                 <td class="name"><code>title=</code></td> | ||||||
|              |              | ||||||
|  |  | ||||||
|             <td class="type"> |             <td class="type"> | ||||||
| @@ -1851,7 +1992,7 @@ | |||||||
|  |  | ||||||
|              |              | ||||||
|  |  | ||||||
|             <td class="description last">if not present we'll use note title</td> |             <td class="description last">custom link tile with note's title as default</td> | ||||||
|         </tr> |         </tr> | ||||||
|  |  | ||||||
|      |      | ||||||
| @@ -1892,7 +2033,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line279">line 279</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line294">line 294</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2025,7 +2166,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line241">line 241</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line253">line 253</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2131,7 +2272,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line293">line 293</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line308">line 308</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2237,7 +2378,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line307">line 307</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line322">line 322</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2391,7 +2532,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line301">line 301</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line316">line 316</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2528,7 +2669,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line358">line 358</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line373">line 373</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2635,7 +2776,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line234">line 234</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line246">line 246</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2790,7 +2931,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line367">line 367</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line382">line 382</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2946,7 +3087,7 @@ if some action needs to happen on only one specific instance. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line206">line 206</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line218">line 218</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3147,7 +3288,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line218">line 218</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line230">line 230</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3253,7 +3394,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line349">line 349</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line364">line 364</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3408,7 +3549,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line376">line 376</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line391">line 391</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3462,6 +3603,184 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|  |  | ||||||
|      |      | ||||||
|  |     <h4 class="name" id="openTabWithNote"><span class="type-signature"></span>openTabWithNote<span class="signature">(notePath, activate)</span><span class="type-signature"> → {Promise.<void>}</span></h4> | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | <div class="description"> | ||||||
|  |     Open a note in a new tab. | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     <h5>Parameters:</h5> | ||||||
|  |      | ||||||
|  |  | ||||||
|  | <table class="params"> | ||||||
|  |     <thead> | ||||||
|  |     <tr> | ||||||
|  |          | ||||||
|  |         <th>Name</th> | ||||||
|  |          | ||||||
|  |  | ||||||
|  |         <th>Type</th> | ||||||
|  |  | ||||||
|  |          | ||||||
|  |  | ||||||
|  |          | ||||||
|  |  | ||||||
|  |         <th class="last">Description</th> | ||||||
|  |     </tr> | ||||||
|  |     </thead> | ||||||
|  |  | ||||||
|  |     <tbody> | ||||||
|  |      | ||||||
|  |  | ||||||
|  |         <tr> | ||||||
|  |              | ||||||
|  |                 <td class="name"><code>notePath</code></td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="type"> | ||||||
|  |              | ||||||
|  |                  | ||||||
|  | <span class="param-type">string</span> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |              | ||||||
|  |             </td> | ||||||
|  |  | ||||||
|  |              | ||||||
|  |  | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="description last">(or noteId)</td> | ||||||
|  |         </tr> | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |         <tr> | ||||||
|  |              | ||||||
|  |                 <td class="name"><code>activate</code></td> | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="type"> | ||||||
|  |              | ||||||
|  |                  | ||||||
|  | <span class="param-type">boolean</span> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |              | ||||||
|  |             </td> | ||||||
|  |  | ||||||
|  |              | ||||||
|  |  | ||||||
|  |              | ||||||
|  |  | ||||||
|  |             <td class="description last">set to true to activate the new tab, false to stay on the current tab</td> | ||||||
|  |         </tr> | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     </tbody> | ||||||
|  | </table> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | <dl class="details"> | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     <dt class="tag-source">Source:</dt> | ||||||
|  |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|  |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line81">line 81</a> | ||||||
|  |     </li></ul></dd> | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|  | </dl> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | <h5>Returns:</h5> | ||||||
|  |  | ||||||
|  |          | ||||||
|  |  | ||||||
|  |  | ||||||
|  | <dl> | ||||||
|  |     <dt> | ||||||
|  |         Type | ||||||
|  |     </dt> | ||||||
|  |     <dd> | ||||||
|  |          | ||||||
|  | <span class="param-type">Promise.<void></span> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     </dd> | ||||||
|  | </dl> | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |          | ||||||
|  |              | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  |      | ||||||
|     <h4 class="name" id="parseDate"><span class="type-signature"></span>parseDate<span class="signature">(str)</span><span class="type-signature"> → {Date}</span></h4> |     <h4 class="name" id="parseDate"><span class="type-signature"></span>parseDate<span class="signature">(str)</span><span class="type-signature"> → {Date}</span></h4> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3559,7 +3878,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line248">line 248</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line260">line 260</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3667,7 +3986,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line319">line 319</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line334">line 334</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3823,7 +4142,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line330">line 330</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line345">line 345</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3979,7 +4298,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line339">line 339</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line354">line 354</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4111,7 +4430,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line410">line 410</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line431">line 431</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4197,7 +4516,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line270">line 270</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line282">line 282</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4334,7 +4653,7 @@ otherwise (by e.g. createNoteLink()) | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line226">line 226</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line238">line 238</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4495,7 +4814,7 @@ Internally this serializes the anonymous function into string and sends it to ba | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line139">line 139</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line151">line 151</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4603,7 +4922,7 @@ Internally this serializes the anonymous function into string and sends it to ba | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line168">line 168</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line180">line 180</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4741,7 +5060,7 @@ Internally this serializes the anonymous function into string and sends it to ba | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line194">line 194</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line206">line 206</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4897,7 +5216,7 @@ Internally this serializes the anonymous function into string and sends it to ba | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line178">line 178</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line190">line 190</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4959,7 +5278,7 @@ Internally this serializes the anonymous function into string and sends it to ba | |||||||
|  |  | ||||||
|  |  | ||||||
| <div class="description"> | <div class="description"> | ||||||
|     Hoist note. See https://github.com/zadam/trilium/wiki/Note-hoisting |     Hoist note in the current tab. See https://github.com/zadam/trilium/wiki/Note-hoisting | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -5052,7 +5371,7 @@ Internally this serializes the anonymous function into string and sends it to ba | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line385">line 385</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line400">line 400</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5203,7 +5522,7 @@ Internally this serializes the anonymous function into string and sends it to ba | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line313">line 313</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line328">line 328</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5340,7 +5659,7 @@ Internally this serializes the anonymous function into string and sends it to ba | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line264">line 264</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line276">line 276</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5477,7 +5796,7 @@ Internally this serializes the anonymous function into string and sends it to ba | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line256">line 256</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line268">line 268</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5569,7 +5888,7 @@ Typical use case is when new note has been created, we should wait until it is s | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line403">line 403</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line424">line 424</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -167,7 +167,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line13">line 13</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line24">line 24</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -267,7 +267,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line22">line 22</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line33">line 33</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -335,7 +335,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line30">line 30</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line41">line 41</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -403,7 +403,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line36">line 36</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line47">line 47</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -461,7 +461,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line53">line 53</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line64">line 64</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -519,7 +519,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line47">line 47</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line58">line 58</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -577,7 +577,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line51">line 51</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line62">line 62</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -635,7 +635,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line43">line 43</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line54">line 54</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -703,7 +703,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line28">line 28</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line39">line 39</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -771,7 +771,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line33">line 33</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line44">line 44</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -839,7 +839,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line25">line 25</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line36">line 36</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -897,7 +897,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line45">line 45</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line56">line 56</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -955,7 +955,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line49">line 49</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line60">line 60</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1103,7 +1103,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line307">line 307</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line377">line 377</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1303,7 +1303,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line176">line 176</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line189">line 189</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1481,7 +1481,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line329">line 329</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line399">line 399</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1587,7 +1587,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line119">line 119</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line132">line 132</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1689,7 +1689,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line114">line 114</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line127">line 127</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1791,7 +1791,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line131">line 131</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line144">line 144</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1893,7 +1893,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line149">line 149</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line162">line 162</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -1995,7 +1995,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line154">line 154</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line167">line 167</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2146,7 +2146,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line369">line 369</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line439">line 439</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2313,7 +2313,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line253">line 253</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line266">line 266</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2468,7 +2468,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line393">line 393</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line463">line 463</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2578,7 +2578,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line495">line 495</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line588">line 588</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2752,7 +2752,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line296">line 296</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line366">line 366</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -2952,7 +2952,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line163">line 163</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line176">line 176</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3130,7 +3130,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line318">line 318</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line388">line 388</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3285,7 +3285,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line363">line 363</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line433">line 433</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3452,7 +3452,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line245">line 245</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line258">line 258</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3607,7 +3607,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line387">line 387</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line457">line 457</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3762,7 +3762,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line375">line 375</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line445">line 445</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -3929,7 +3929,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line261">line 261</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line331">line 331</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4084,7 +4084,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line399">line 399</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line469">line 469</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4190,7 +4190,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line139">line 139</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line152">line 152</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4292,7 +4292,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line144">line 144</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line157">line 157</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4443,7 +4443,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line381">line 381</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line451">line 451</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4610,7 +4610,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line269">line 269</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line339">line 339</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4765,7 +4765,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line411">line 411</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line481">line 481</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -4935,7 +4935,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line421">line 421</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line491">line 491</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5086,7 +5086,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line405">line 405</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line475">line 475</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5196,7 +5196,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line474">line 474</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line567">line 567</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5302,7 +5302,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line484">line 484</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line577">line 577</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5404,7 +5404,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line435">line 435</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line505">line 505</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5578,7 +5578,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line278">line 278</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line348">line 348</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5684,7 +5684,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line126">line 126</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line139">line 139</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -5835,7 +5835,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line345">line 345</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line415">line 415</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6013,7 +6013,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line287">line 287</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line357">line 357</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6168,7 +6168,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line339">line 339</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line409">line 409</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6323,7 +6323,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line351">line 351</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line421">line 421</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6478,7 +6478,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div> | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line357">line 357</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line427">line 427</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6589,7 +6589,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line465">line 465</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line558">line 558</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -6673,7 +6673,7 @@ Cache is note instance scoped. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line89">line 89</a> |         <a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line102">line 102</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -50,6 +50,8 @@ class Attribute { | |||||||
|         this.position = row.position; |         this.position = row.position; | ||||||
|         /** @param {boolean} isInheritable */ |         /** @param {boolean} isInheritable */ | ||||||
|         this.isInheritable = !!row.isInheritable; |         this.isInheritable = !!row.isInheritable; | ||||||
|  |         /** @param {boolean} */ | ||||||
|  |         this.isDeleted = !!row.isDeleted; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** @returns {NoteShort} */ |     /** @returns {NoteShort} */ | ||||||
| @@ -114,6 +116,17 @@ class Attribute { | |||||||
|     getDefinition() { |     getDefinition() { | ||||||
|         return promotedAttributeDefinitionParser.parse(this.value); |         return promotedAttributeDefinitionParser.parse(this.value); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     isDefinitionFor(attr) { | ||||||
|  |         return this.type === 'label' && this.name === `${attr.type}:${attr.name}`; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     get dto() { | ||||||
|  |         const dto = Object.assign({}, this); | ||||||
|  |         delete dto.treeCache; | ||||||
|  |  | ||||||
|  |         return dto; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| export default Attribute; | export default Attribute; | ||||||
|   | |||||||
| @@ -48,6 +48,8 @@ class Branch { | |||||||
|         /** @param {boolean} */ |         /** @param {boolean} */ | ||||||
|         this.isExpanded = !!row.isExpanded; |         this.isExpanded = !!row.isExpanded; | ||||||
|         /** @param {boolean} */ |         /** @param {boolean} */ | ||||||
|  |         this.fromSearchNote = !!row.fromSearchNote; | ||||||
|  |         /** @param {boolean} */ | ||||||
|         this.isDeleted = !!row.isDeleted; |         this.isDeleted = !!row.isDeleted; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -76,7 +78,8 @@ class Branch { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| export default Branch;</code></pre> | export default Branch; | ||||||
|  | </code></pre> | ||||||
|         </article> |         </article> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,12 +27,23 @@ | |||||||
|     <section> |     <section> | ||||||
|         <article> |         <article> | ||||||
|             <pre class="prettyprint source linenums"><code>import server from '../services/server.js'; |             <pre class="prettyprint source linenums"><code>import server from '../services/server.js'; | ||||||
| import Attribute from './attribute.js'; |  | ||||||
| import noteAttributeCache from "../services/note_attribute_cache.js"; | import noteAttributeCache from "../services/note_attribute_cache.js"; | ||||||
|  | import ws from "../services/ws.js"; | ||||||
|  | import options from "../services/options.js"; | ||||||
|  |  | ||||||
| const LABEL = 'label'; | const LABEL = 'label'; | ||||||
| const RELATION = 'relation'; | const RELATION = 'relation'; | ||||||
|  |  | ||||||
|  | const NOTE_TYPE_ICONS = { | ||||||
|  |     "file": "bx bx-file", | ||||||
|  |     "image": "bx bx-image", | ||||||
|  |     "code": "bx bx-code", | ||||||
|  |     "render": "bx bx-extension", | ||||||
|  |     "search": "bx bx-file-find", | ||||||
|  |     "relation-map": "bx bx-map-alt", | ||||||
|  |     "book": "bx bx-book" | ||||||
|  | }; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * FIXME: since there's no "full note" anymore we can rename this to Note |  * FIXME: since there's no "full note" anymore we can rename this to Note | ||||||
|  * |  * | ||||||
| @@ -78,7 +89,7 @@ class NoteShort { | |||||||
|         /** @param {string} content-type, e.g. "application/json" */ |         /** @param {string} content-type, e.g. "application/json" */ | ||||||
|         this.mime = row.mime; |         this.mime = row.mime; | ||||||
|         /** @param {boolean} */ |         /** @param {boolean} */ | ||||||
|         this.isDeleted = row.isDeleted; |         this.isDeleted = !!row.isDeleted; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     addParent(parentNoteId, branchId) { |     addParent(parentNoteId, branchId) { | ||||||
| @@ -93,14 +104,16 @@ class NoteShort { | |||||||
|         this.parentToBranch[parentNoteId] = branchId; |         this.parentToBranch[parentNoteId] = branchId; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     addChild(childNoteId, branchId) { |     addChild(childNoteId, branchId, sort = true) { | ||||||
|         if (!this.children.includes(childNoteId)) { |         if (!(childNoteId in this.childToBranch)) { | ||||||
|             this.children.push(childNoteId); |             this.children.push(childNoteId); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.childToBranch[childNoteId] = branchId; |         this.childToBranch[childNoteId] = branchId; | ||||||
|  |  | ||||||
|         this.sortChildren(); |         if (sort) { | ||||||
|  |             this.sortChildren(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     sortChildren() { |     sortChildren() { | ||||||
| @@ -282,6 +295,63 @@ class NoteShort { | |||||||
|         return this.getAttributes(LABEL, name); |         return this.getAttributes(LABEL, name); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     getIcon() { | ||||||
|  |         const iconClassLabels = this.getLabels('iconClass'); | ||||||
|  |         const workspaceIconClass = this.getWorkspaceIconClass(); | ||||||
|  |  | ||||||
|  |         if (iconClassLabels.length > 0) { | ||||||
|  |             return iconClassLabels.map(l => l.value).join(' '); | ||||||
|  |         } | ||||||
|  |         else if (workspaceIconClass) { | ||||||
|  |             return workspaceIconClass; | ||||||
|  |         } | ||||||
|  |         else if (this.noteId === 'root') { | ||||||
|  |             return "bx bx-chevrons-right"; | ||||||
|  |         } | ||||||
|  |         else if (this.type === 'text') { | ||||||
|  |             if (this.isFolder()) { | ||||||
|  |                 return "bx bx-folder"; | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 return "bx bx-note"; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (this.type === 'code' && this.mime.startsWith('text/x-sql')) { | ||||||
|  |             return "bx bx-data"; | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             return NOTE_TYPE_ICONS[this.type]; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     isFolder() { | ||||||
|  |         return this.type === 'search' | ||||||
|  |             || this.getFilteredChildBranches().length > 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     getFilteredChildBranches() { | ||||||
|  |         let childBranches = this.getChildBranches(); | ||||||
|  |  | ||||||
|  |         if (!childBranches) { | ||||||
|  |             ws.logError(`No children for ${parentNote}. This shouldn't happen.`); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (options.is("hideIncludedImages_main")) { | ||||||
|  |             const imageLinks = this.getRelations('imageLink'); | ||||||
|  |  | ||||||
|  |             // image is already visible in the parent note so no need to display it separately in the book | ||||||
|  |             childBranches = childBranches.filter(branch => !imageLinks.find(rel => rel.value === branch.noteId)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // we're not checking hideArchivedNotes since that would mean we need to lazy load the child notes | ||||||
|  |         // which would seriously slow down everything. | ||||||
|  |         // we check this flag only once user chooses to expand the parent. This has the negative consequence that | ||||||
|  |         // note may appear as folder but not contain any children when all of them are archived | ||||||
|  |  | ||||||
|  |         return childBranches; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param {string} [name] - relation name to filter |      * @param {string} [name] - relation name to filter | ||||||
|      * @returns {Attribute[]} all note's relations (attributes with type relation), including inherited ones |      * @returns {Attribute[]} all note's relations (attributes with type relation), including inherited ones | ||||||
| @@ -466,19 +536,42 @@ class NoteShort { | |||||||
|         return relations.map(rel => this.treeCache.notes[rel.value]); |         return relations.map(rel => this.treeCache.notes[rel.value]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     hasAncestor(ancestorNote) { |     getPromotedDefinitionAttributes() { | ||||||
|  |         if (this.hasLabel('hidePromotedAttributes')) { | ||||||
|  |             return []; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return this.getAttributes() | ||||||
|  |             .filter(attr => attr.isDefinition()) | ||||||
|  |             .filter(attr => { | ||||||
|  |                 const def = attr.getDefinition(); | ||||||
|  |  | ||||||
|  |                 return def && def.isPromoted; | ||||||
|  |             }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     hasAncestor(ancestorNote, visitedNoteIds) { | ||||||
|         if (this.noteId === ancestorNote.noteId) { |         if (this.noteId === ancestorNote.noteId) { | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (!visitedNoteIds) { | ||||||
|  |             visitedNoteIds = new Set(); | ||||||
|  |         } else if (visitedNoteIds.has(this.noteId)) { | ||||||
|  |             // to avoid infinite cycle when template is descendent of the instance | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         visitedNoteIds.add(this.noteId); | ||||||
|  |  | ||||||
|         for (const templateNote of this.getTemplateNotes()) { |         for (const templateNote of this.getTemplateNotes()) { | ||||||
|             if (templateNote.hasAncestor(ancestorNote)) { |             if (templateNote.hasAncestor(ancestorNote, visitedNoteIds)) { | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         for (const parentNote of this.getParentNotes()) { |         for (const parentNote of this.getParentNotes()) { | ||||||
|             if (parentNote.hasAncestor(ancestorNote)) { |             if (parentNote.hasAncestor(ancestorNote, visitedNoteIds)) { | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -539,6 +632,16 @@ class NoteShort { | |||||||
|         const labels = this.getLabels('cssClass'); |         const labels = this.getLabels('cssClass'); | ||||||
|         return labels.map(l => l.value).join(' '); |         return labels.map(l => l.value).join(' '); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     getWorkspaceIconClass() { | ||||||
|  |         const labels = this.getLabels('workspaceIconClass'); | ||||||
|  |         return labels.length > 0 ? labels[0].value : ""; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     getWorkspaceTabBackgroundColor() { | ||||||
|  |         const labels = this.getLabels('workspaceTabBackgroundColor'); | ||||||
|  |         return labels.length > 0 ? labels[0].value : ""; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| export default NoteShort; | export default NoteShort; | ||||||
|   | |||||||
| @@ -156,7 +156,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line93">line 93</a> |         <a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line124">line 124</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -244,7 +244,7 @@ | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line96">line 96</a> |         <a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line127">line 127</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -333,7 +333,7 @@ separately but should behave uniformly for the user. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line86">line 86</a> |         <a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line117">line 117</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
| @@ -572,7 +572,7 @@ separately but should behave uniformly for the user. | |||||||
|      |      | ||||||
|     <dt class="tag-source">Source:</dt> |     <dt class="tag-source">Source:</dt> | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |     <dd class="tag-source"><ul class="dummy"><li> | ||||||
|         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line76">line 76</a> |         <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line88">line 88</a> | ||||||
|     </li></ul></dd> |     </li></ul></dd> | ||||||
|      |      | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,8 +26,7 @@ | |||||||
|      |      | ||||||
|     <section> |     <section> | ||||||
|         <article> |         <article> | ||||||
|             <pre class="prettyprint source linenums"><code>import treeService from './tree.js'; |             <pre class="prettyprint source linenums"><code>import server from './server.js'; | ||||||
| import server from './server.js'; |  | ||||||
| import utils from './utils.js'; | import utils from './utils.js'; | ||||||
| import toastService from './toast.js'; | import toastService from './toast.js'; | ||||||
| import linkService from './link.js'; | import linkService from './link.js'; | ||||||
| @@ -37,7 +36,6 @@ import protectedSessionService from './protected_session.js'; | |||||||
| import dateNotesService from './date_notes.js'; | import dateNotesService from './date_notes.js'; | ||||||
| import CollapsibleWidget from '../widgets/collapsible_widget.js'; | import CollapsibleWidget from '../widgets/collapsible_widget.js'; | ||||||
| import ws from "./ws.js"; | import ws from "./ws.js"; | ||||||
| import hoistedNoteService from "./hoisted_note.js"; |  | ||||||
| import appContext from "./app_context.js"; | import appContext from "./app_context.js"; | ||||||
| import TabAwareWidget from "../widgets/tab_aware_widget.js"; | import TabAwareWidget from "../widgets/tab_aware_widget.js"; | ||||||
| import TabCachingWidget from "../widgets/tab_caching_widget.js"; | import TabCachingWidget from "../widgets/tab_caching_widget.js"; | ||||||
| @@ -101,6 +99,20 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | |||||||
|         appContext.triggerEvent('focusAndSelectTitle'); |         appContext.triggerEvent('focusAndSelectTitle'); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Open a note in a new tab. | ||||||
|  |      * | ||||||
|  |      * @param {string} notePath (or noteId) | ||||||
|  |      * @param {boolean} activate - set to true to activate the new tab, false to stay on the current tab | ||||||
|  |      * @return {Promise<void>} | ||||||
|  |      */ | ||||||
|  |     this.openTabWithNote = async (notePath, activate) => { | ||||||
|  |         await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|  |         await appContext.tabManager.openTabWithNote(notePath, activate); | ||||||
|  |         appContext.triggerEvent('focusAndSelectTitle'); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @typedef {Object} ToolbarButtonOptions |      * @typedef {Object} ToolbarButtonOptions | ||||||
|      * @property {string} title |      * @property {string} title | ||||||
| @@ -117,7 +129,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | |||||||
|     this.addButtonToToolbar = opts => { |     this.addButtonToToolbar = opts => { | ||||||
|         const buttonId = "toolbar-button-" + opts.title.replace(/\s/g, "-"); |         const buttonId = "toolbar-button-" + opts.title.replace(/\s/g, "-"); | ||||||
|  |  | ||||||
|         const button = $('<button>') |         const button = $('<button class="noborder">') | ||||||
|             .addClass("btn btn-sm") |             .addClass("btn btn-sm") | ||||||
|             .on('click', opts.action); |             .on('click', opts.action); | ||||||
|  |  | ||||||
| @@ -302,7 +314,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | |||||||
|      * |      * | ||||||
|      * @method |      * @method | ||||||
|      * @param {string} notePath (or noteId) |      * @param {string} notePath (or noteId) | ||||||
|      * @param {string} [noteTitle] - if not present we'll use note title |      * @param {object} [params] | ||||||
|  |      * @param {boolean} [params.showTooltip=true] - enable/disable tooltip on the link | ||||||
|  |      * @param {boolean} [params.showNotePath=false] - show also whole note's path as part of the link | ||||||
|  |      * @param {string} [title=] - custom link tile with note's title as default | ||||||
|      */ |      */ | ||||||
|     this.createNoteLink = linkService.createNoteLink; |     this.createNoteLink = linkService.createNoteLink; | ||||||
|  |  | ||||||
| @@ -404,13 +419,19 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | |||||||
|     this.getYearNote = dateNotesService.getYearNote; |     this.getYearNote = dateNotesService.getYearNote; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Hoist note. See https://github.com/zadam/trilium/wiki/Note-hoisting |      * Hoist note in the current tab. See https://github.com/zadam/trilium/wiki/Note-hoisting | ||||||
|      * |      * | ||||||
|      * @method |      * @method | ||||||
|      * @param {string} noteId - set hoisted note. 'root' will effectively unhoist |      * @param {string} noteId - set hoisted note. 'root' will effectively unhoist | ||||||
|      * @return {Promise} |      * @return {Promise} | ||||||
|      */ |      */ | ||||||
|     this.setHoistedNoteId = hoistedNoteService.setHoistedNoteId; |     this.setHoistedNoteId = (noteId) => { | ||||||
|  |         const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||||
|  |  | ||||||
|  |         if (activeTabContext) { | ||||||
|  |             activeTabContext.setHoistedNoteId(noteId); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @method |      * @method | ||||||
|   | |||||||
| @@ -31,16 +31,25 @@ import options from "../services/options.js"; | |||||||
|  |  | ||||||
| const WIDGET_TPL = ` | const WIDGET_TPL = ` | ||||||
| <div class="card widget"> | <div class="card widget"> | ||||||
|     <div class="card-header"> |     <div class="card-header">     | ||||||
|         <div>            |         <div>            | ||||||
|             <button class="btn btn-sm widget-title" data-toggle="collapse" data-target="#[to be set]"> |             <a class="widget-toggle-button no-arrow"  | ||||||
|                 Collapsible Group Item |                 title="Minimize/maximize widget" | ||||||
|             </button> |                 data-toggle="collapse" data-target="#[to be set]"> | ||||||
|              |                  | ||||||
|             <a class="widget-help external no-arrow bx bx-info-circle"></a> |                 <span class="widget-toggle-icon bx"></span> | ||||||
|  |                  | ||||||
|  |                 <span class="widget-title"> | ||||||
|  |                     Collapsible Group Item | ||||||
|  |                 </span>     | ||||||
|  |             </a> | ||||||
|  |          | ||||||
|  |             <span class="widget-header-actions"></span> | ||||||
|         </div> |         </div> | ||||||
|          |          | ||||||
|         <div class="widget-header-actions"></div> |         <div> | ||||||
|  |             <a class="widget-help external no-arrow bx bx-info-circle"></a> | ||||||
|  |         </div> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <div id="[to be set]" class="collapse body-wrapper" style="transition: none; "> |     <div id="[to be set]" class="collapse body-wrapper" style="transition: none; "> | ||||||
| @@ -66,13 +75,19 @@ export default class CollapsibleWidget extends TabAwareWidget { | |||||||
|         // not using constructor name because of webpack mangling class names ... |         // not using constructor name because of webpack mangling class names ... | ||||||
|         this.widgetName = this.widgetTitle.replace(/[^[a-zA-Z0-9]/g, "_"); |         this.widgetName = this.widgetTitle.replace(/[^[a-zA-Z0-9]/g, "_"); | ||||||
|  |  | ||||||
|         if (!options.is(this.widgetName + 'Collapsed')) { |         this.$toggleButton = this.$widget.find('.widget-toggle-button'); | ||||||
|  |         this.$toggleIcon = this.$widget.find('.widget-toggle-icon'); | ||||||
|  |  | ||||||
|  |         const collapsed = options.is(this.widgetName + 'Collapsed'); | ||||||
|  |         if (!collapsed) { | ||||||
|             this.$bodyWrapper.collapse("show"); |             this.$bodyWrapper.collapse("show"); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         this.updateToggleIcon(collapsed); | ||||||
|  |  | ||||||
|         // using immediate variants of the event so that the previous collapse is not caught |         // using immediate variants of the event so that the previous collapse is not caught | ||||||
|         this.$bodyWrapper.on('hide.bs.collapse', () => this.saveCollapsed(true)); |         this.$bodyWrapper.on('hide.bs.collapse', () => this.toggleCollapsed(true)); | ||||||
|         this.$bodyWrapper.on('show.bs.collapse', () => this.saveCollapsed(false)); |         this.$bodyWrapper.on('show.bs.collapse', () => this.toggleCollapsed(false)); | ||||||
|  |  | ||||||
|         this.$body = this.$bodyWrapper.find('.card-body'); |         this.$body = this.$bodyWrapper.find('.card-body'); | ||||||
|  |  | ||||||
| @@ -94,19 +109,35 @@ export default class CollapsibleWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.$headerActions = this.$widget.find('.widget-header-actions'); |         this.$headerActions = this.$widget.find('.widget-header-actions'); | ||||||
|         this.$headerActions.append(...this.headerActions); |         this.$headerActions.append(this.headerActions); | ||||||
|  |  | ||||||
|         this.initialized = this.doRenderBody(); |         this.initialized = this.doRenderBody(); | ||||||
|  |  | ||||||
|         this.decorateWidget(); |         this.decorateWidget(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     saveCollapsed(collapse) { |     toggleCollapsed(collapse) { | ||||||
|  |         this.updateToggleIcon(collapse); | ||||||
|  |  | ||||||
|         options.save(this.widgetName + 'Collapsed', collapse.toString()); |         options.save(this.widgetName + 'Collapsed', collapse.toString()); | ||||||
|  |  | ||||||
|         this.triggerEvent(`widgetCollapsedStateChanged`, {widgetName: this.widgetName, collapse}); |         this.triggerEvent(`widgetCollapsedStateChanged`, {widgetName: this.widgetName, collapse}); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     updateToggleIcon(collapse) { | ||||||
|  |         if (collapse) { | ||||||
|  |             this.$toggleIcon | ||||||
|  |                 .addClass("bx-chevron-right") | ||||||
|  |                 .removeClass("bx-chevron-down") | ||||||
|  |                 .attr("title", "Show"); | ||||||
|  |         } else { | ||||||
|  |             this.$toggleIcon | ||||||
|  |                 .addClass("bx-chevron-down") | ||||||
|  |                 .removeClass("bx-chevron-right") | ||||||
|  |                 .attr("title", "Hide"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * This event is used to synchronize collapsed state of all the tab-cached widgets since they are all rendered |      * This event is used to synchronize collapsed state of all the tab-cached widgets since they are all rendered | ||||||
|      * separately but should behave uniformly for the user. |      * separately but should behave uniformly for the user. | ||||||
|   | |||||||
							
								
								
									
										986
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										986
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										24
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								package.json
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ | |||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "productName": "Trilium Notes", |   "productName": "Trilium Notes", | ||||||
|   "description": "Trilium Notes", |   "description": "Trilium Notes", | ||||||
|   "version": "0.46.0-beta", |   "version": "0.46.3-beta", | ||||||
|   "license": "AGPL-3.0-only", |   "license": "AGPL-3.0-only", | ||||||
|   "main": "electron.js", |   "main": "electron.js", | ||||||
|   "bin": { |   "bin": { | ||||||
| @@ -24,7 +24,7 @@ | |||||||
|     "test-all": "npm run test && npm run test-es6" |     "test-all": "npm run test && npm run test-es6" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "async-mutex": "0.3.0", |     "async-mutex": "0.3.1", | ||||||
|     "axios": "0.21.1", |     "axios": "0.21.1", | ||||||
|     "better-sqlite3": "7.1.2", |     "better-sqlite3": "7.1.2", | ||||||
|     "body-parser": "1.19.0", |     "body-parser": "1.19.0", | ||||||
| @@ -35,7 +35,7 @@ | |||||||
|     "dayjs": "1.10.4", |     "dayjs": "1.10.4", | ||||||
|     "ejs": "3.1.6", |     "ejs": "3.1.6", | ||||||
|     "electron-debug": "3.2.0", |     "electron-debug": "3.2.0", | ||||||
|     "electron-dl": "3.0.3", |     "electron-dl": "3.2.0", | ||||||
|     "electron-find": "1.0.6", |     "electron-find": "1.0.6", | ||||||
|     "electron-window-state": "5.0.3", |     "electron-window-state": "5.0.3", | ||||||
|     "express": "4.17.1", |     "express": "4.17.1", | ||||||
| @@ -51,11 +51,11 @@ | |||||||
|     "is-animated": "^2.0.1", |     "is-animated": "^2.0.1", | ||||||
|     "is-svg": "4.2.1", |     "is-svg": "4.2.1", | ||||||
|     "jimp": "0.16.1", |     "jimp": "0.16.1", | ||||||
|     "jsdom": "^16.4.0", |     "jsdom": "16.5.0", | ||||||
|     "mime-types": "2.1.28", |     "mime-types": "2.1.29", | ||||||
|     "multer": "1.4.2", |     "multer": "1.4.2", | ||||||
|     "node-abi": "2.19.3", |     "node-abi": "2.21.0", | ||||||
|     "open": "7.4.1", |     "open": "7.4.2", | ||||||
|     "portscanner": "2.2.0", |     "portscanner": "2.2.0", | ||||||
|     "rand-token": "1.0.1", |     "rand-token": "1.0.1", | ||||||
|     "request": "^2.88.2", |     "request": "^2.88.2", | ||||||
| @@ -70,16 +70,16 @@ | |||||||
|     "striptags": "3.1.1", |     "striptags": "3.1.1", | ||||||
|     "tmp": "^0.2.1", |     "tmp": "^0.2.1", | ||||||
|     "turndown": "7.0.0", |     "turndown": "7.0.0", | ||||||
|     "turndown-plugin-gfm": "1.0.2", |     "joplin-turndown-plugin-gfm": "1.0.12", | ||||||
|     "unescape": "1.0.1", |     "unescape": "1.0.1", | ||||||
|     "ws": "7.4.3", |     "ws": "7.4.4", | ||||||
|     "yauzl": "2.10.0", |     "yauzl": "2.10.0", | ||||||
|     "yazl": "2.5.1" |     "yazl": "2.5.1" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "cross-env": "7.0.3", |     "cross-env": "7.0.3", | ||||||
|     "electron": "9.4.3", |     "electron": "9.4.4", | ||||||
|     "electron-builder": "22.9.1", |     "electron-builder": "22.10.5", | ||||||
|     "electron-packager": "15.2.0", |     "electron-packager": "15.2.0", | ||||||
|     "electron-rebuild": "2.3.5", |     "electron-rebuild": "2.3.5", | ||||||
|     "esm": "3.2.25", |     "esm": "3.2.25", | ||||||
| @@ -87,7 +87,7 @@ | |||||||
|     "jsdoc": "3.6.6", |     "jsdoc": "3.6.6", | ||||||
|     "lorem-ipsum": "2.0.3", |     "lorem-ipsum": "2.0.3", | ||||||
|     "rcedit": "3.0.0", |     "rcedit": "3.0.0", | ||||||
|     "webpack": "5.21.2", |     "webpack": "5.24.4", | ||||||
|     "webpack-cli": "4.5.0" |     "webpack-cli": "4.5.0" | ||||||
|   }, |   }, | ||||||
|   "optionalDependencies": { |   "optionalDependencies": { | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ class Entity { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     getUtcDateChanged() { |     getUtcDateChanged() { | ||||||
|         return this.utcDateModified; |         return this.utcDateModified || this.utcDateCreated; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     get repository() { |     get repository() { | ||||||
|   | |||||||
| @@ -681,7 +681,7 @@ class Note extends Entity { | |||||||
|      * Update's given relation's value or creates it if it doesn't exist |      * Update's given relation's value or creates it if it doesn't exist | ||||||
|      * |      * | ||||||
|      * @param {string} name - relation name |      * @param {string} name - relation name | ||||||
|      * @param {string} [value] - relation value (noteId) |      * @param {string} value - relation value (noteId) | ||||||
|      */ |      */ | ||||||
|     setRelation(name, value) { return this.setAttribute(RELATION, name, value); } |     setRelation(name, value) { return this.setAttribute(RELATION, name, value); } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,7 +41,10 @@ export async function showDialog(widget, text = '') { | |||||||
|         $linkTitle.val(noteTitle); |         $linkTitle.val(noteTitle); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     noteAutocompleteService.initNoteAutocomplete($autoComplete, { allowExternalLinks: true }); |     noteAutocompleteService.initNoteAutocomplete($autoComplete, { | ||||||
|  |         allowExternalLinks: true, | ||||||
|  |         allowCreatingNotes: true | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     $autoComplete.on('autocomplete:noteselected', (event, suggestion, dataset) => { |     $autoComplete.on('autocomplete:noteselected', (event, suggestion, dataset) => { | ||||||
|         if (!suggestion.notePath) { |         if (!suggestion.notePath) { | ||||||
|   | |||||||
| @@ -129,7 +129,7 @@ ws.subscribeToMessages(async message => { | |||||||
|         toastService.showPersistent(makeToast(message.taskId, "Export in progress: " + message.progressCount)); |         toastService.showPersistent(makeToast(message.taskId, "Export in progress: " + message.progressCount)); | ||||||
|     } |     } | ||||||
|     else if (message.type === 'task-succeeded') { |     else if (message.type === 'task-succeeded') { | ||||||
|         const toast = makeToast(message.taskId, "Import finished successfully."); |         const toast = makeToast(message.taskId, "Export finished successfully."); | ||||||
|         toast.closeAfter = 5000; |         toast.closeAfter = 5000; | ||||||
|  |  | ||||||
|         toastService.showPersistent(toast); |         toastService.showPersistent(toast); | ||||||
|   | |||||||
| @@ -17,7 +17,10 @@ export async function showDialog(widget) { | |||||||
|  |  | ||||||
|     utils.openDialog($dialog); |     utils.openDialog($dialog); | ||||||
|  |  | ||||||
|     noteAutocompleteService.initNoteAutocomplete($autoComplete, { hideGoToSelectedNoteButton: true }); |     noteAutocompleteService.initNoteAutocomplete($autoComplete, { | ||||||
|  |         hideGoToSelectedNoteButton: true, | ||||||
|  |         allowCreatingNotes: true | ||||||
|  |     }); | ||||||
|     noteAutocompleteService.showRecentNotes($autoComplete); |     noteAutocompleteService.showRecentNotes($autoComplete); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ const TPL = ` | |||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <p>Zooming can be controlled with CTRL-+ and CTRL-= shortcuts as well.</p> |     <p>Zooming can be controlled with CTRL+- and CTRL+= shortcuts as well.</p> | ||||||
|  |  | ||||||
|     <h4>Font sizes</h4> |     <h4>Font sizes</h4> | ||||||
|  |  | ||||||
| @@ -169,4 +169,4 @@ export default class ApperanceOptions { | |||||||
|         this.$body.get(0).style.setProperty("--tree-font-size", this.$treeFontSize.val() + "%"); |         this.$body.get(0).style.setProperty("--tree-font-size", this.$treeFontSize.val() + "%"); | ||||||
|         this.$body.get(0).style.setProperty("--detail-font-size", this.$detailFontSize.val() + "%"); |         this.$body.get(0).style.setProperty("--detail-font-size", this.$detailFontSize.val() + "%"); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								src/public/app/dialogs/sort_child_notes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/public/app/dialogs/sort_child_notes.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | import server from "../services/server.js"; | ||||||
|  | import utils from "../services/utils.js"; | ||||||
|  |  | ||||||
|  | const $dialog = $("#sort-child-notes-dialog"); | ||||||
|  | const $form = $("#sort-child-notes-form"); | ||||||
|  |  | ||||||
|  | let parentNoteId = null; | ||||||
|  |  | ||||||
|  | $form.on('submit', async () => { | ||||||
|  |     const sortBy = $form.find("input[name='sort-by']:checked").val(); | ||||||
|  |     const sortDirection = $form.find("input[name='sort-direction']:checked").val(); | ||||||
|  |  | ||||||
|  |     await server.put(`notes/${parentNoteId}/sort-children`, {sortBy, sortDirection}); | ||||||
|  |  | ||||||
|  |     utils.closeActiveDialog(); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | export async function showDialog(noteId) { | ||||||
|  |     parentNoteId = noteId; | ||||||
|  |  | ||||||
|  |     utils.openDialog($dialog); | ||||||
|  |  | ||||||
|  |     $form.find('input:first').focus(); | ||||||
|  | } | ||||||
| @@ -2,6 +2,7 @@ import server from '../services/server.js'; | |||||||
| import noteAttributeCache from "../services/note_attribute_cache.js"; | import noteAttributeCache from "../services/note_attribute_cache.js"; | ||||||
| import ws from "../services/ws.js"; | import ws from "../services/ws.js"; | ||||||
| import options from "../services/options.js"; | import options from "../services/options.js"; | ||||||
|  | import treeCache from "../services/tree_cache.js"; | ||||||
|  |  | ||||||
| const LABEL = 'label'; | const LABEL = 'label'; | ||||||
| const RELATION = 'relation'; | const RELATION = 'relation'; | ||||||
| @@ -158,6 +159,26 @@ class NoteShort { | |||||||
|         return this.treeCache.getNotesFromCache(this.parents); |         return this.treeCache.getNotesFromCache(this.parents); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // will sort the parents so that non-search & non-archived are first and archived at the end | ||||||
|  |     // this is done so that non-search & non-archived paths are always explored as first when looking for note path | ||||||
|  |     resortParents() { | ||||||
|  |         this.parents.sort((aNoteId, bNoteId) => { | ||||||
|  |             const aBranchId = this.parentToBranch[aNoteId]; | ||||||
|  |  | ||||||
|  |             if (aBranchId && aBranchId.startsWith('virt-')) { | ||||||
|  |                 return 1; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             const aNote = this.treeCache.getNoteFromCache([aNoteId]); | ||||||
|  |  | ||||||
|  |             if (aNote.hasLabel('archived')) { | ||||||
|  |                 return 1; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return -1; | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** @returns {string[]} */ |     /** @returns {string[]} */ | ||||||
|     getChildNoteIds() { |     getChildNoteIds() { | ||||||
|         return this.children; |         return this.children; | ||||||
| @@ -233,6 +254,55 @@ class NoteShort { | |||||||
|         return noteAttributeCache.attributes[this.noteId]; |         return noteAttributeCache.attributes[this.noteId]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     getAllNotePaths() { | ||||||
|  |         if (this.noteId === 'root') { | ||||||
|  |             return [['root']]; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         const parentNotes = this.getParentNotes(); | ||||||
|  |         let paths; | ||||||
|  |  | ||||||
|  |         if (parentNotes.length === 1) { // optimization for the most common case | ||||||
|  |             paths = parentNotes[0].getAllNotePaths(); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             paths = []; | ||||||
|  |  | ||||||
|  |             for (const parentNote of parentNotes) { | ||||||
|  |                 paths.push(...parentNote.getAllNotePaths()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         for (const path of paths) { | ||||||
|  |             path.push(this.noteId); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return paths; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     getSortedNotePaths(hoistedNotePath = 'root') { | ||||||
|  |         const notePaths = this.getAllNotePaths().map(path => ({ | ||||||
|  |             notePath: path, | ||||||
|  |             isInHoistedSubTree: path.includes(hoistedNotePath), | ||||||
|  |             isArchived: path.find(noteId => treeCache.notes[noteId].hasLabel('archived')), | ||||||
|  |             isSearch: path.find(noteId => treeCache.notes[noteId].type === 'search') | ||||||
|  |         })); | ||||||
|  |  | ||||||
|  |         notePaths.sort((a, b) => { | ||||||
|  |             if (a.isInHoistedSubTree !== b.isInHoistedSubTree) { | ||||||
|  |                 return a.isInHoistedSubTree ? -1 : 1; | ||||||
|  |             } else if (a.isSearch !== b.isSearch) { | ||||||
|  |                 return a.isSearch ? 1 : -1; | ||||||
|  |             } else if (a.isArchived !== b.isArchived) { | ||||||
|  |                 return a.isArchived ? 1 : -1; | ||||||
|  |             } else { | ||||||
|  |                 return a.notePath.length - b.notePath.length; | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         return notePaths; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     __filterAttrs(attributes, type, name) { |     __filterAttrs(attributes, type, name) { | ||||||
|         if (!type && !name) { |         if (!type && !name) { | ||||||
|             return attributes; |             return attributes; | ||||||
| @@ -522,7 +592,7 @@ class NoteShort { | |||||||
|             }); |             }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     hasAncestor(ancestorNote, visitedNoteIds) { |     hasAncestor(ancestorNote, visitedNoteIds = null) { | ||||||
|         if (this.noteId === ancestorNote.noteId) { |         if (this.noteId === ancestorNote.noteId) { | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ import ImagePropertiesWidget from "../widgets/type_property_widgets/image_proper | |||||||
| import NotePropertiesWidget from "../widgets/type_property_widgets/note_properties.js"; | import NotePropertiesWidget from "../widgets/type_property_widgets/note_properties.js"; | ||||||
| import NoteIconWidget from "../widgets/note_icon.js"; | import NoteIconWidget from "../widgets/note_icon.js"; | ||||||
| import NotePathsWidget from "../widgets/note_paths.js"; | import NotePathsWidget from "../widgets/note_paths.js"; | ||||||
|  | import SearchResultWidget from "../widgets/search_result.js"; | ||||||
|  |  | ||||||
| export default class DesktopExtraWindowLayout { | export default class DesktopExtraWindowLayout { | ||||||
|     constructor(customWidgets) { |     constructor(customWidgets) { | ||||||
| @@ -69,6 +70,7 @@ export default class DesktopExtraWindowLayout { | |||||||
|                         .child(new TabCachingWidget(() => new SqlTableSchemasWidget())) |                         .child(new TabCachingWidget(() => new SqlTableSchemasWidget())) | ||||||
|                         .child(new TabCachingWidget(() => new NoteDetailWidget())) |                         .child(new TabCachingWidget(() => new NoteDetailWidget())) | ||||||
|                         .child(new TabCachingWidget(() => new NoteListWidget())) |                         .child(new TabCachingWidget(() => new NoteListWidget())) | ||||||
|  |                         .child(new TabCachingWidget(() => new SearchResultWidget())) | ||||||
|                         .child(new TabCachingWidget(() => new SqlResultWidget())) |                         .child(new TabCachingWidget(() => new SqlResultWidget())) | ||||||
|                     ) |                     ) | ||||||
|                     .child(...this.customWidgets.get('center-pane')) |                     .child(...this.customWidgets.get('center-pane')) | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ import FilePropertiesWidget from "../widgets/type_property_widgets/file_properti | |||||||
| import ImagePropertiesWidget from "../widgets/type_property_widgets/image_properties.js"; | import ImagePropertiesWidget from "../widgets/type_property_widgets/image_properties.js"; | ||||||
| import NotePropertiesWidget from "../widgets/type_property_widgets/note_properties.js"; | import NotePropertiesWidget from "../widgets/type_property_widgets/note_properties.js"; | ||||||
| import NoteIconWidget from "../widgets/note_icon.js"; | import NoteIconWidget from "../widgets/note_icon.js"; | ||||||
|  | import SearchResultWidget from "../widgets/search_result.js"; | ||||||
|  |  | ||||||
| const RIGHT_PANE_CSS = ` | const RIGHT_PANE_CSS = ` | ||||||
| <style> | <style> | ||||||
| @@ -179,6 +180,7 @@ export default class DesktopMainWindowLayout { | |||||||
|                         .child(new TabCachingWidget(() => new SqlTableSchemasWidget())) |                         .child(new TabCachingWidget(() => new SqlTableSchemasWidget())) | ||||||
|                         .child(new TabCachingWidget(() => new NoteDetailWidget())) |                         .child(new TabCachingWidget(() => new NoteDetailWidget())) | ||||||
|                         .child(new TabCachingWidget(() => new NoteListWidget())) |                         .child(new TabCachingWidget(() => new NoteListWidget())) | ||||||
|  |                         .child(new TabCachingWidget(() => new SearchResultWidget())) | ||||||
|                         .child(new TabCachingWidget(() => new SqlResultWidget())) |                         .child(new TabCachingWidget(() => new SqlResultWidget())) | ||||||
|                     ) |                     ) | ||||||
|                     .child(new TabCachingWidget(() => new SimilarNotesWidget())) |                     .child(new TabCachingWidget(() => new SimilarNotesWidget())) | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import keyboardActionsService from "./keyboard_actions.js"; | |||||||
| import MobileScreenSwitcherExecutor from "../widgets/mobile_widgets/mobile_screen_switcher.js"; | import MobileScreenSwitcherExecutor from "../widgets/mobile_widgets/mobile_screen_switcher.js"; | ||||||
| import MainTreeExecutors from "./main_tree_executors.js"; | import MainTreeExecutors from "./main_tree_executors.js"; | ||||||
| import protectedSessionHolder from "./protected_session_holder.js"; | import protectedSessionHolder from "./protected_session_holder.js"; | ||||||
|  | import toast from "./toast.js"; | ||||||
|  |  | ||||||
| class AppContext extends Component { | class AppContext extends Component { | ||||||
|     constructor(isMainWindow) { |     constructor(isMainWindow) { | ||||||
| @@ -19,6 +20,7 @@ class AppContext extends Component { | |||||||
|  |  | ||||||
|         this.isMainWindow = isMainWindow; |         this.isMainWindow = isMainWindow; | ||||||
|         this.executors = []; |         this.executors = []; | ||||||
|  |         this.beforeUnloadListeners = []; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     setLayout(layout) { |     setLayout(layout) { | ||||||
| @@ -104,6 +106,15 @@ class AppContext extends Component { | |||||||
|     getComponentByEl(el) { |     getComponentByEl(el) { | ||||||
|         return $(el).closest(".component").prop('component'); |         return $(el).closest(".component").prop('component'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     addBeforeUnloadListener(obj) { | ||||||
|  |         if (typeof WeakRef !== "function") { | ||||||
|  |             // older browsers don't support WeakRef | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.beforeUnloadListeners.push(new WeakRef(obj)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| const appContext = new AppContext(window.glob.isMainWindow); | const appContext = new AppContext(window.glob.isMainWindow); | ||||||
| @@ -112,7 +123,29 @@ const appContext = new AppContext(window.glob.isMainWindow); | |||||||
| $(window).on('beforeunload', () => { | $(window).on('beforeunload', () => { | ||||||
|     protectedSessionHolder.resetSessionCookie(); |     protectedSessionHolder.resetSessionCookie(); | ||||||
|  |  | ||||||
|     appContext.triggerEvent('beforeUnload'); |     let allSaved = true; | ||||||
|  |  | ||||||
|  |     appContext.beforeUnloadListeners = appContext.beforeUnloadListeners.filter(wr => !!wr.deref()); | ||||||
|  |  | ||||||
|  |     for (const weakRef of appContext.beforeUnloadListeners) { | ||||||
|  |         const component = weakRef.deref(); | ||||||
|  |  | ||||||
|  |         if (!component) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!component.beforeUnloadEvent()) { | ||||||
|  |             console.log(`Component ${component.componentId} is not finished saving its state.`); | ||||||
|  |  | ||||||
|  |             toast.showMessage("Please wait for a couple of seconds for the save to finish, then you can try again.", 10000); | ||||||
|  |  | ||||||
|  |             allSaved = false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!allSaved) { | ||||||
|  |         return "some string"; | ||||||
|  |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| function isNotePathInAddress() { | function isNotePathInAddress() { | ||||||
|   | |||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | import utils from "./utils.js"; | ||||||
|  |  | ||||||
| function lex(str) { | function lex(str) { | ||||||
|     str = str.trim(); |     str = str.trim(); | ||||||
|  |  | ||||||
| @@ -105,14 +107,12 @@ function lex(str) { | |||||||
|     return tokens; |     return tokens; | ||||||
| } | } | ||||||
|  |  | ||||||
| const attrNameMatcher = new RegExp("^[\\p{L}\\p{N}_:]+$", "u"); |  | ||||||
|  |  | ||||||
| function checkAttributeName(attrName) { | function checkAttributeName(attrName) { | ||||||
|     if (attrName.length === 0) { |     if (attrName.length === 0) { | ||||||
|         throw new Error("Attribute name is empty, please fill the name."); |         throw new Error("Attribute name is empty, please fill the name."); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!attrNameMatcher.test(attrName)) { |     if (!utils.isValidAttributeName(attrName)) { | ||||||
|         throw new Error(`Attribute name "${attrName}" contains disallowed characters, only alphanumeric characters, colon and underscore are allowed.`); |         throw new Error(`Attribute name "${attrName}" contains disallowed characters, only alphanumeric characters, colon and underscore are allowed.`); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ import ws from "./ws.js"; | |||||||
|  |  | ||||||
| async function moveBeforeBranch(branchIdsToMove, beforeBranchId) { | async function moveBeforeBranch(branchIdsToMove, beforeBranchId) { | ||||||
|     branchIdsToMove = filterRootNote(branchIdsToMove); |     branchIdsToMove = filterRootNote(branchIdsToMove); | ||||||
|  |     branchIdsToMove = filterSearchBranches(branchIdsToMove); | ||||||
|  |  | ||||||
|     if (beforeBranchId === 'root') { |     if (beforeBranchId === 'root') { | ||||||
|         alert('Cannot move notes before root note.'); |         alert('Cannot move notes before root note.'); | ||||||
| @@ -25,6 +26,7 @@ async function moveBeforeBranch(branchIdsToMove, beforeBranchId) { | |||||||
|  |  | ||||||
| async function moveAfterBranch(branchIdsToMove, afterBranchId) { | async function moveAfterBranch(branchIdsToMove, afterBranchId) { | ||||||
|     branchIdsToMove = filterRootNote(branchIdsToMove); |     branchIdsToMove = filterRootNote(branchIdsToMove); | ||||||
|  |     branchIdsToMove = filterSearchBranches(branchIdsToMove); | ||||||
|  |  | ||||||
|     const afterNote = await treeCache.getBranch(afterBranchId).getNote(); |     const afterNote = await treeCache.getBranch(afterBranchId).getNote(); | ||||||
|  |  | ||||||
| @@ -123,7 +125,7 @@ async function deleteNotes(branchIdsToDelete) { | |||||||
| } | } | ||||||
|  |  | ||||||
| async function moveNodeUpInHierarchy(node) { | async function moveNodeUpInHierarchy(node) { | ||||||
|     if (hoistedNoteService.isRootNode(node) |     if (hoistedNoteService.isHoistedNode(node) | ||||||
|         || hoistedNoteService.isTopLevelNode(node) |         || hoistedNoteService.isTopLevelNode(node) | ||||||
|         || node.getParent().data.noteType === 'search') { |         || node.getParent().data.noteType === 'search') { | ||||||
|         return; |         return; | ||||||
| @@ -142,6 +144,10 @@ async function moveNodeUpInHierarchy(node) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function filterSearchBranches(branchIds) { | ||||||
|  |     return branchIds.filter(branchId => !branchId.startsWith('virt-')); | ||||||
|  | } | ||||||
|  |  | ||||||
| function filterRootNote(branchIds) { | function filterRootNote(branchIds) { | ||||||
|     const hoistedNoteId = hoistedNoteService.getHoistedNoteId(); |     const hoistedNoteId = hoistedNoteService.getHoistedNoteId(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,6 +18,8 @@ async function getTodayNote() { | |||||||
| async function getDateNote(date) { | async function getDateNote(date) { | ||||||
|     const note = await server.get('date-notes/date/' + date, "date-note"); |     const note = await server.get('date-notes/date/' + date, "date-note"); | ||||||
|  |  | ||||||
|  |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|     return await treeCache.getNote(note.noteId); |     return await treeCache.getNote(note.noteId); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -25,6 +27,8 @@ async function getDateNote(date) { | |||||||
| async function getMonthNote(month) { | async function getMonthNote(month) { | ||||||
|     const note = await server.get('date-notes/month/' + month, "date-note"); |     const note = await server.get('date-notes/month/' + month, "date-note"); | ||||||
|  |  | ||||||
|  |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|     return await treeCache.getNote(note.noteId); |     return await treeCache.getNote(note.noteId); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -32,6 +36,8 @@ async function getMonthNote(month) { | |||||||
| async function getYearNote(year) { | async function getYearNote(year) { | ||||||
|     const note = await server.get('date-notes/year/' + year, "date-note"); |     const note = await server.get('date-notes/year/' + year, "date-note"); | ||||||
|  |  | ||||||
|  |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|     return await treeCache.getNote(note.noteId); |     return await treeCache.getNote(note.noteId); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -39,21 +45,14 @@ async function getYearNote(year) { | |||||||
| async function createSqlConsole() { | async function createSqlConsole() { | ||||||
|     const note = await server.post('sql-console'); |     const note = await server.post('sql-console'); | ||||||
|  |  | ||||||
|  |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|     return await treeCache.getNote(note.noteId); |     return await treeCache.getNote(note.noteId); | ||||||
| } | } | ||||||
|  |  | ||||||
| /** @return {NoteShort} */ | /** @return {NoteShort} */ | ||||||
| async function createSearchNote(opts = {}) { | async function createSearchNote(opts = {}) { | ||||||
|     const note = await server.post('search-note'); |     const note = await server.post('search-note', opts); | ||||||
|  |  | ||||||
|     const attrsToUpdate = [ |  | ||||||
|         opts.ancestorNoteId ? { type: 'relation', name: 'ancestor', value: opts.ancestorNoteId } : undefined, |  | ||||||
|         { type: 'label', name: 'searchString', value: opts.searchString } |  | ||||||
|     ].filter(attr => !!attr); |  | ||||||
|  |  | ||||||
|     if (attrsToUpdate.length > 0) { |  | ||||||
|         await server.put(`notes/${note.noteId}/attributes`, attrsToUpdate); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     await ws.waitForMaxKnownEntityChangeId(); |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -182,8 +182,6 @@ export default class Entrypoints extends Component { | |||||||
|         utils.reloadApp(); |         utils.reloadApp(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     createTopLevelNoteCommand() { noteCreateService.createNewTopLevelNote(); } |  | ||||||
|  |  | ||||||
|     async openInWindowCommand({notePath, hoistedNoteId}) { |     async openInWindowCommand({notePath, hoistedNoteId}) { | ||||||
|         if (!hoistedNoteId) { |         if (!hoistedNoteId) { | ||||||
|             hoistedNoteId = 'root'; |             hoistedNoteId = 'root'; | ||||||
|   | |||||||
| @@ -71,6 +71,23 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | |||||||
|         appContext.triggerEvent('focusAndSelectTitle'); |         appContext.triggerEvent('focusAndSelectTitle'); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Open a note in a new tab. | ||||||
|  |      * | ||||||
|  |      * @param {string} notePath (or noteId) | ||||||
|  |      * @param {boolean} activate - set to true to activate the new tab, false to stay on the current tab | ||||||
|  |      * @return {Promise<void>} | ||||||
|  |      */ | ||||||
|  |     this.openTabWithNote = async (notePath, activate) => { | ||||||
|  |         await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|  |         await appContext.tabManager.openTabWithNote(notePath, activate); | ||||||
|  |  | ||||||
|  |         if (activate) { | ||||||
|  |             appContext.triggerEvent('focusAndSelectTitle'); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @typedef {Object} ToolbarButtonOptions |      * @typedef {Object} ToolbarButtonOptions | ||||||
|      * @property {string} title |      * @property {string} title | ||||||
| @@ -149,8 +166,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | |||||||
|         }, "script"); |         }, "script"); | ||||||
|  |  | ||||||
|         if (ret.success) { |         if (ret.success) { | ||||||
|             // wait until all the changes done in the script has been synced to frontend before continuing |             await ws.waitForMaxKnownEntityChangeId(); | ||||||
|             await ws.waitForEntityChangeId(ret.maxEntityChangeId); |  | ||||||
|  |  | ||||||
|             return ret.executionResult; |             return ret.executionResult; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -16,10 +16,10 @@ async function unhoist() { | |||||||
| } | } | ||||||
|  |  | ||||||
| function isTopLevelNode(node) { | function isTopLevelNode(node) { | ||||||
|     return isRootNode(node.getParent()); |     return isHoistedNode(node.getParent()); | ||||||
| } | } | ||||||
|  |  | ||||||
| function isRootNode(node) { | function isHoistedNode(node) { | ||||||
|     // even though check for 'root' should not be necessary, we keep it just in case |     // even though check for 'root' should not be necessary, we keep it just in case | ||||||
|     return node.data.noteId === "root" |     return node.data.noteId === "root" | ||||||
|         || node.data.noteId === getHoistedNoteId(); |         || node.data.noteId === getHoistedNoteId(); | ||||||
| @@ -55,6 +55,6 @@ export default { | |||||||
|     getHoistedNoteId, |     getHoistedNoteId, | ||||||
|     unhoist, |     unhoist, | ||||||
|     isTopLevelNode, |     isTopLevelNode, | ||||||
|     isRootNode, |     isHoistedNode, | ||||||
|     checkNoteAccess |     checkNoteAccess | ||||||
| } | } | ||||||
|   | |||||||
| @@ -117,7 +117,8 @@ export default class LinkMap { | |||||||
|  |  | ||||||
|             const $noteBox = $("<div>") |             const $noteBox = $("<div>") | ||||||
|                 .addClass("note-box") |                 .addClass("note-box") | ||||||
|                 .prop("id", noteBoxId); |                 .prop("id", noteBoxId) | ||||||
|  |                 .addClass(note.getCssClass()); | ||||||
|  |  | ||||||
|             const $link = $linkTitles[noteId]; |             const $link = $linkTitles[noteId]; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,28 +27,28 @@ export default class MainTreeExecutors extends Component { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async createNoteIntoCommand() { |     async createNoteIntoCommand() { | ||||||
|         const activeNote = appContext.tabManager.getActiveTabNote(); |         const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||||
|  |  | ||||||
|         if (!activeNote) { |         if (!activeTabContext) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         await noteCreateService.createNote(activeNote.noteId, { |         await noteCreateService.createNote(activeTabContext.notePath, { | ||||||
|             isProtected: activeNote.isProtected, |             isProtected: activeTabContext.note.isProtected, | ||||||
|             saveSelection: false |             saveSelection: false | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async createNoteAfterCommand() { |     async createNoteAfterCommand() { | ||||||
|         const node = this.tree.getActiveNode(); |         const node = this.tree.getActiveNode(); | ||||||
|         const parentNoteId = node.data.parentNoteId; |         const parentNotePath = treeService.getNotePath(node.getParent()); | ||||||
|         const isProtected = await treeService.getParentProtectedStatus(node); |         const isProtected = await treeService.getParentProtectedStatus(node); | ||||||
|  |  | ||||||
|         if (node.data.noteId === 'root' || node.data.noteId === hoistedNoteService.getHoistedNoteId()) { |         if (node.data.noteId === 'root' || node.data.noteId === hoistedNoteService.getHoistedNoteId()) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         await noteCreateService.createNote(parentNoteId, { |         await noteCreateService.createNote(parentNotePath, { | ||||||
|             target: 'after', |             target: 'after', | ||||||
|             targetBranchId: node.data.branchId, |             targetBranchId: node.data.branchId, | ||||||
|             isProtected: isProtected, |             isProtected: isProtected, | ||||||
|   | |||||||
| @@ -1,19 +1,13 @@ | |||||||
| import hoistedNoteService from "./hoisted_note.js"; |  | ||||||
| import appContext from "./app_context.js"; | import appContext from "./app_context.js"; | ||||||
| import utils from "./utils.js"; | import utils from "./utils.js"; | ||||||
| import protectedSessionHolder from "./protected_session_holder.js"; | import protectedSessionHolder from "./protected_session_holder.js"; | ||||||
| import server from "./server.js"; | import server from "./server.js"; | ||||||
| import ws from "./ws.js"; | import ws from "./ws.js"; | ||||||
| import treeCache from "./tree_cache.js"; | import treeCache from "./tree_cache.js"; | ||||||
|  | import treeService from "./tree.js"; | ||||||
| import toastService from "./toast.js"; | import toastService from "./toast.js"; | ||||||
|  |  | ||||||
| async function createNewTopLevelNote() { | async function createNote(parentNotePath, options = {}) { | ||||||
|     const hoistedNoteId = hoistedNoteService.getHoistedNoteId(); |  | ||||||
|  |  | ||||||
|     await createNote(hoistedNoteId); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| async function createNote(parentNoteId, options = {}) { |  | ||||||
|     options = Object.assign({ |     options = Object.assign({ | ||||||
|         activate: true, |         activate: true, | ||||||
|         focus: 'title', |         focus: 'title', | ||||||
| @@ -36,6 +30,8 @@ async function createNote(parentNoteId, options = {}) { | |||||||
|  |  | ||||||
|     const newNoteName = options.title || "new note"; |     const newNoteName = options.title || "new note"; | ||||||
|  |  | ||||||
|  |     const parentNoteId = treeService.getNoteIdFromNotePath(parentNotePath); | ||||||
|  |  | ||||||
|     const {note, branch} = await server.post(`notes/${parentNoteId}/children?target=${options.target}&targetBranchId=${options.targetBranchId}`, { |     const {note, branch} = await server.post(`notes/${parentNoteId}/children?target=${options.target}&targetBranchId=${options.targetBranchId}`, { | ||||||
|         title: newNoteName, |         title: newNoteName, | ||||||
|         content: options.content || "", |         content: options.content || "", | ||||||
| @@ -53,7 +49,7 @@ async function createNote(parentNoteId, options = {}) { | |||||||
|  |  | ||||||
|     if (options.activate) { |     if (options.activate) { | ||||||
|         const activeTabContext = appContext.tabManager.getActiveTabContext(); |         const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||||
|         await activeTabContext.setNote(note.noteId); |         await activeTabContext.setNote(`${parentNotePath}/${note.noteId}`); | ||||||
|  |  | ||||||
|         if (options.focus === 'title') { |         if (options.focus === 'title') { | ||||||
|             appContext.triggerEvent('focusAndSelectTitle'); |             appContext.triggerEvent('focusAndSelectTitle'); | ||||||
| @@ -88,12 +84,13 @@ function parseSelectedHtml(selectedHtml) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| async function duplicateSubtree(noteId, parentNoteId) { | async function duplicateSubtree(noteId, parentNotePath) { | ||||||
|  |     const parentNoteId = treeService.getNoteIdFromNotePath(parentNotePath); | ||||||
|     const {note} = await server.post(`notes/${noteId}/duplicate/${parentNoteId}`); |     const {note} = await server.post(`notes/${noteId}/duplicate/${parentNoteId}`); | ||||||
|  |  | ||||||
|     await ws.waitForMaxKnownEntityChangeId(); |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|     await appContext.tabManager.activateOrOpenNote(note.noteId); |     await appContext.tabManager.activateOrOpenNote(`${parentNotePath}/${note.noteId}`); | ||||||
|  |  | ||||||
|     const origNote = await treeCache.getNote(noteId); |     const origNote = await treeCache.getNote(noteId); | ||||||
|     toastService.showMessage(`Note "${origNote.title}" has been duplicated`); |     toastService.showMessage(`Note "${origNote.title}" has been duplicated`); | ||||||
| @@ -101,6 +98,5 @@ async function duplicateSubtree(noteId, parentNoteId) { | |||||||
|  |  | ||||||
| export default { | export default { | ||||||
|     createNote, |     createNote, | ||||||
|     createNewTopLevelNote, |  | ||||||
|     duplicateSubtree |     duplicateSubtree | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -56,6 +56,14 @@ const TPL = ` | |||||||
|      |      | ||||||
|     .note-book-title { |     .note-book-title { | ||||||
|         margin-bottom: 0; |         margin-bottom: 0; | ||||||
|  |         word-break: break-all; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* not-expanded title is limited to one line only */ | ||||||
|  |     .note-book-card:not(.expanded) .note-book-title { | ||||||
|  |         overflow: hidden; | ||||||
|  |         white-space: nowrap; | ||||||
|  |         text-overflow: ellipsis; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     .note-book-title .rendered-note-attributes { |     .note-book-title .rendered-note-attributes { | ||||||
| @@ -148,7 +156,7 @@ class NoteListRenderer { | |||||||
|     /* |     /* | ||||||
|      * We're using noteIds so that it's not necessary to load all notes at once when paging |      * We're using noteIds so that it's not necessary to load all notes at once when paging | ||||||
|      */ |      */ | ||||||
|     constructor($parent, parentNote, noteIds) { |     constructor($parent, parentNote, noteIds, showNotePath = false) { | ||||||
|         this.$noteList = $(TPL); |         this.$noteList = $(TPL); | ||||||
|  |  | ||||||
|         // note list must be added to the DOM immediatelly, otherwise some functionality scripting (canvas) won't work |         // note list must be added to the DOM immediatelly, otherwise some functionality scripting (canvas) won't work | ||||||
| @@ -200,6 +208,8 @@ class NoteListRenderer { | |||||||
|  |  | ||||||
|             await this.renderList(); |             await this.renderList(); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|  |         this.showNotePath = showNotePath; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** @return {Set<string>} list of noteIds included (images, included notes) into a parent note and which |     /** @return {Set<string>} list of noteIds included (images, included notes) into a parent note and which | ||||||
| @@ -298,7 +308,7 @@ class NoteListRenderer { | |||||||
|             .append( |             .append( | ||||||
|                 $('<h5 class="note-book-title">') |                 $('<h5 class="note-book-title">') | ||||||
|                     .append($expander) |                     .append($expander) | ||||||
|                     .append(await linkService.createNoteLink(note.noteId, {showTooltip: false})) |                     .append(await linkService.createNoteLink(note.noteId, {showTooltip: false, showNotePath: this.showNotePath})) | ||||||
|                     .append($renderedAttributes) |                     .append($renderedAttributes) | ||||||
|             ); |             ); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,11 +15,27 @@ export default class SpacedUpdate { | |||||||
|  |  | ||||||
|     async updateNowIfNecessary() { |     async updateNowIfNecessary() { | ||||||
|         if (this.changed) { |         if (this.changed) { | ||||||
|             this.changed = false; |             this.changed = false; // optimistic... | ||||||
|             await this.updater(); |  | ||||||
|  |             try { | ||||||
|  |                 await this.updater(); | ||||||
|  |             } | ||||||
|  |             catch (e) { | ||||||
|  |                 this.changed = true; | ||||||
|  |  | ||||||
|  |                 throw e; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     isAllSavedAndTriggerUpdate() { | ||||||
|  |         const allSaved = !this.changed; | ||||||
|  |  | ||||||
|  |         this.updateNowIfNecessary(); | ||||||
|  |  | ||||||
|  |         return allSaved; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     triggerUpdate() { |     triggerUpdate() { | ||||||
|         if (!this.changed) { |         if (!this.changed) { | ||||||
|             return; |             return; | ||||||
|   | |||||||
| @@ -79,7 +79,7 @@ class TabContext extends Component { | |||||||
|             return inputNotePath; |             return inputNotePath; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         const resolvedNotePath = await treeService.resolveNotePath(inputNotePath); |         const resolvedNotePath = await treeService.resolveNotePath(inputNotePath, this.hoistedNoteId); | ||||||
|  |  | ||||||
|         if (!resolvedNotePath) { |         if (!resolvedNotePath) { | ||||||
|             logError(`Cannot resolve note path ${inputNotePath}`); |             logError(`Cannot resolve note path ${inputNotePath}`); | ||||||
|   | |||||||
| @@ -27,6 +27,8 @@ export default class TabManager extends Component { | |||||||
|                 openTabs: JSON.stringify(openTabs) |                 openTabs: JSON.stringify(openTabs) | ||||||
|             }); |             }); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|  |         appContext.addBeforeUnloadListener(this); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** @type {TabContext[]} */ |     /** @type {TabContext[]} */ | ||||||
| @@ -203,7 +205,7 @@ export default class TabManager extends Component { | |||||||
|         let hoistedNoteId = 'root'; |         let hoistedNoteId = 'root'; | ||||||
|  |  | ||||||
|         if (tabContext) { |         if (tabContext) { | ||||||
|             const resolvedNotePath = await treeService.resolveNotePath(notePath); |             const resolvedNotePath = await treeService.resolveNotePath(notePath, tabContext.hoistedNoteId); | ||||||
|  |  | ||||||
|             if (resolvedNotePath.includes(tabContext.hoistedNoteId)) { |             if (resolvedNotePath.includes(tabContext.hoistedNoteId)) { | ||||||
|                 hoistedNoteId = tabContext.hoistedNoteId; |                 hoistedNoteId = tabContext.hoistedNoteId; | ||||||
| @@ -329,6 +331,8 @@ export default class TabManager extends Component { | |||||||
|  |  | ||||||
|     beforeUnloadEvent() { |     beforeUnloadEvent() { | ||||||
|         this.tabsUpdate.updateNowIfNecessary(); |         this.tabsUpdate.updateNowIfNecessary(); | ||||||
|  |  | ||||||
|  |         return true; // don't block closing the tab, this metadata is not that important | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     openNewTabCommand() { |     openNewTabCommand() { | ||||||
|   | |||||||
| @@ -8,8 +8,8 @@ import appContext from "./app_context.js"; | |||||||
| /** | /** | ||||||
|  * @return {string|null} |  * @return {string|null} | ||||||
|  */ |  */ | ||||||
| async function resolveNotePath(notePath) { | async function resolveNotePath(notePath, hoistedNoteId = 'root') { | ||||||
|     const runPath = await resolveNotePathToSegments(notePath); |     const runPath = await resolveNotePathToSegments(notePath, hoistedNoteId); | ||||||
|  |  | ||||||
|     return runPath ? runPath.join("/") : null; |     return runPath ? runPath.join("/") : null; | ||||||
| } | } | ||||||
| @@ -21,7 +21,7 @@ async function resolveNotePath(notePath) { | |||||||
|  * |  * | ||||||
|  * @return {string[]} |  * @return {string[]} | ||||||
|  */ |  */ | ||||||
| async function resolveNotePathToSegments(notePath, logErrors = true) { | async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logErrors = true) { | ||||||
|     utils.assertArguments(notePath); |     utils.assertArguments(notePath); | ||||||
|  |  | ||||||
|     // we might get notePath with the tabId suffix, remove it if present |     // we might get notePath with the tabId suffix, remove it if present | ||||||
| @@ -56,6 +56,8 @@ async function resolveNotePathToSegments(notePath, logErrors = true) { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             child.resortParents(); | ||||||
|  |  | ||||||
|             const parents = child.getParentNotes(); |             const parents = child.getParentNotes(); | ||||||
|  |  | ||||||
|             if (!parents.length) { |             if (!parents.length) { | ||||||
| @@ -73,10 +75,10 @@ async function resolveNotePathToSegments(notePath, logErrors = true) { | |||||||
|                     console.log(utils.now(), `Did not find parent ${parentNoteId} (${parent ? parent.title : 'n/a'}) for child ${childNoteId} (${child.title}), available parents: ${parents.map(p => `${p.noteId} (${p.title})`)}`); |                     console.log(utils.now(), `Did not find parent ${parentNoteId} (${parent ? parent.title : 'n/a'}) for child ${childNoteId} (${child.title}), available parents: ${parents.map(p => `${p.noteId} (${p.title})`)}`); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 const someNotePath = getSomeNotePath(parents[0]); |                 const someNotePath = getSomeNotePath(child, hoistedNoteId); | ||||||
|  |  | ||||||
|                 if (someNotePath) { // in case it's root the path may be empty |                 if (someNotePath) { // in case it's root the path may be empty | ||||||
|                     const pathToRoot = someNotePath.split("/").reverse(); |                     const pathToRoot = someNotePath.split("/").reverse().slice(1); | ||||||
|  |  | ||||||
|                     for (const noteId of pathToRoot) { |                     for (const noteId of pathToRoot) { | ||||||
|                         effectivePath.push(noteId); |                         effectivePath.push(noteId); | ||||||
| @@ -94,29 +96,18 @@ async function resolveNotePathToSegments(notePath, logErrors = true) { | |||||||
|     return effectivePath.reverse(); |     return effectivePath.reverse(); | ||||||
| } | } | ||||||
|  |  | ||||||
| function getSomeNotePath(note) { | function getSomeNotePathSegments(note, hoistedNotePath = 'root') { | ||||||
|     utils.assertArguments(note); |     utils.assertArguments(note); | ||||||
|  |  | ||||||
|     const path = []; |     const notePaths = note.getSortedNotePaths(hoistedNotePath); | ||||||
|  |  | ||||||
|     let cur = note; |     return notePaths[0].notePath; | ||||||
|  | } | ||||||
|  |  | ||||||
|     while (cur.noteId !== 'root') { | function getSomeNotePath(note, hoistedNotePath = 'root') { | ||||||
|         path.push(cur.noteId); |     const notePath = getSomeNotePathSegments(note, hoistedNotePath); | ||||||
|  |  | ||||||
|         const parents = cur.getParentNotes().filter(note => note.type !== 'search'); |     return notePath.join('/'); | ||||||
|  |  | ||||||
|         if (!parents.length) { |  | ||||||
|             logError(`Can't find parents for note ${cur.noteId}`); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         cur = parents[0]; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     path.push('root'); |  | ||||||
|  |  | ||||||
|     return path.reverse().join('/'); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| async function sortAlphabetically(noteId) { | async function sortAlphabetically(noteId) { | ||||||
| @@ -136,7 +127,7 @@ ws.subscribeToMessages(message => { | |||||||
| }); | }); | ||||||
|  |  | ||||||
| function getParentProtectedStatus(node) { | function getParentProtectedStatus(node) { | ||||||
|     return hoistedNoteService.isRootNode(node) ? 0 : node.getParent().data.isProtected; |     return hoistedNoteService.isHoistedNode(node) ? 0 : node.getParent().data.isProtected; | ||||||
| } | } | ||||||
|  |  | ||||||
| function getNoteIdFromNotePath(notePath) { | function getNoteIdFromNotePath(notePath) { | ||||||
| @@ -196,7 +187,7 @@ function getNotePath(node) { | |||||||
|  |  | ||||||
|     const path = []; |     const path = []; | ||||||
|  |  | ||||||
|     while (node && !hoistedNoteService.isRootNode(node)) { |     while (node) { | ||||||
|         if (node.data.noteId) { |         if (node.data.noteId) { | ||||||
|             path.push(node.data.noteId); |             path.push(node.data.noteId); | ||||||
|         } |         } | ||||||
| @@ -204,10 +195,6 @@ function getNotePath(node) { | |||||||
|         node = node.getParent(); |         node = node.getParent(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (node) { // null node can happen directly after unhoisting when tree is still hoisted but option has been changed already |  | ||||||
|         path.push(node.data.noteId); // root or hoisted noteId |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return path.reverse().join("/"); |     return path.reverse().join("/"); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -311,6 +298,7 @@ export default { | |||||||
|     resolveNotePath, |     resolveNotePath, | ||||||
|     resolveNotePathToSegments, |     resolveNotePathToSegments, | ||||||
|     getSomeNotePath, |     getSomeNotePath, | ||||||
|  |     getSomeNotePathSegments, | ||||||
|     getParentProtectedStatus, |     getParentProtectedStatus, | ||||||
|     getNotePath, |     getNotePath, | ||||||
|     getNoteIdFromNotePath, |     getNoteIdFromNotePath, | ||||||
|   | |||||||
| @@ -195,6 +195,8 @@ class TreeCache { | |||||||
|                     branches, |                     branches, | ||||||
|                     attributes: [] |                     attributes: [] | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  |                 treeCache.notes[note.noteId].searchResultsLoaded = true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -75,7 +75,7 @@ class TreeContextMenu { | |||||||
|                     { title: 'Expand subtree <kbd data-command="expandSubtree"></kbd>', command: "expandSubtree", uiIcon: "expand", enabled: noSelectedNotes }, |                     { title: 'Expand subtree <kbd data-command="expandSubtree"></kbd>', command: "expandSubtree", uiIcon: "expand", enabled: noSelectedNotes }, | ||||||
|                     { title: 'Collapse subtree <kbd data-command="collapseSubtree"></kbd>', command: "collapseSubtree", uiIcon: "collapse", enabled: noSelectedNotes }, |                     { title: 'Collapse subtree <kbd data-command="collapseSubtree"></kbd>', command: "collapseSubtree", uiIcon: "collapse", enabled: noSelectedNotes }, | ||||||
|                     { title: "Force note sync", command: "forceNoteSync", uiIcon: "refresh", enabled: noSelectedNotes }, |                     { title: "Force note sync", command: "forceNoteSync", uiIcon: "refresh", enabled: noSelectedNotes }, | ||||||
|                     { title: 'Sort alphabetically <kbd data-command="sortChildNotes"></kbd>', command: "sortChildNotes", uiIcon: "empty", enabled: noSelectedNotes && notSearch }, |                     { title: 'Sort by ... <kbd data-command="sortChildNotes"></kbd>', command: "sortChildNotes", uiIcon: "empty", enabled: noSelectedNotes && notSearch }, | ||||||
|                     { title: 'Recent changes in subtree', command: "recentChangesInSubtree", uiIcon: "history", enabled: noSelectedNotes } |                     { title: 'Recent changes in subtree', command: "recentChangesInSubtree", uiIcon: "history", enabled: noSelectedNotes } | ||||||
|                 ] }, |                 ] }, | ||||||
|             { title: "----" }, |             { title: "----" }, | ||||||
| @@ -112,10 +112,10 @@ class TreeContextMenu { | |||||||
|             appContext.tabManager.openTabWithNoteWithHoisting(notePath); |             appContext.tabManager.openTabWithNoteWithHoisting(notePath); | ||||||
|         } |         } | ||||||
|         else if (command === "insertNoteAfter") { |         else if (command === "insertNoteAfter") { | ||||||
|             const parentNoteId = this.node.data.parentNoteId; |             const parentNotePath = treeService.getNotePath(this.node.getParent()); | ||||||
|             const isProtected = await treeService.getParentProtectedStatus(this.node); |             const isProtected = await treeService.getParentProtectedStatus(this.node); | ||||||
|  |  | ||||||
|             noteCreateService.createNote(parentNoteId, { |             noteCreateService.createNote(parentNotePath, { | ||||||
|                 target: 'after', |                 target: 'after', | ||||||
|                 targetBranchId: this.node.data.branchId, |                 targetBranchId: this.node.data.branchId, | ||||||
|                 type: type, |                 type: type, | ||||||
| @@ -123,14 +123,14 @@ class TreeContextMenu { | |||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|         else if (command === "insertChildNote") { |         else if (command === "insertChildNote") { | ||||||
|             noteCreateService.createNote(noteId, { |             const parentNotePath = treeService.getNotePath(this.node); | ||||||
|  |  | ||||||
|  |             noteCreateService.createNote(parentNotePath, { | ||||||
|                 type: type, |                 type: type, | ||||||
|                 isProtected: this.node.data.isProtected |                 isProtected: this.node.data.isProtected | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             console.log("Triggering", command, notePath); |  | ||||||
|  |  | ||||||
|             this.treeWidget.triggerCommand(command, {node: this.node, notePath: notePath}); |             this.treeWidget.triggerCommand(command, {node: this.node, notePath: notePath}); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -193,6 +193,10 @@ function getNoteTypeClass(type) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function getMimeTypeClass(mime) { | function getMimeTypeClass(mime) { | ||||||
|  |     if (!mime) { | ||||||
|  |         return ""; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const semicolonIdx = mime.indexOf(';'); |     const semicolonIdx = mime.indexOf(';'); | ||||||
|  |  | ||||||
|     if (semicolonIdx !== -1) { |     if (semicolonIdx !== -1) { | ||||||
| @@ -296,9 +300,13 @@ function dynamicRequire(moduleName) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function timeLimit(promise, limitMs) { | function timeLimit(promise, limitMs, errorMessage) { | ||||||
|  |     if (!promise || !promise.then) { // it's not actually a promise | ||||||
|  |         return promise; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // better stack trace if created outside of promise |     // better stack trace if created outside of promise | ||||||
|     const error = new Error('Process exceeded time limit ' + limitMs); |     const error = new Error(errorMessage || `Process exceeded time limit ${limitMs}`); | ||||||
|  |  | ||||||
|     return new Promise((res, rej) => { |     return new Promise((res, rej) => { | ||||||
|         let resolved = false; |         let resolved = false; | ||||||
| @@ -334,6 +342,16 @@ function initHelpButtons($el) { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function filterAttributeName(name) { | ||||||
|  |     return name.replace(/[^\p{L}\p{N}_:]/ug, ""); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const ATTR_NAME_MATCHER = new RegExp("^[\\p{L}\\p{N}_:]+$", "u"); | ||||||
|  |  | ||||||
|  | function isValidAttributeName(name) { | ||||||
|  |     return ATTR_NAME_MATCHER.test(name); | ||||||
|  | } | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|     reloadApp, |     reloadApp, | ||||||
|     parseDate, |     parseDate, | ||||||
| @@ -374,5 +392,7 @@ export default { | |||||||
|     dynamicRequire, |     dynamicRequire, | ||||||
|     timeLimit, |     timeLimit, | ||||||
|     initHelpDropdown, |     initHelpDropdown, | ||||||
|     initHelpButtons |     initHelpButtons, | ||||||
|  |     filterAttributeName, | ||||||
|  |     isValidAttributeName | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -43,7 +43,6 @@ const processedEntityChangeIds = new Set(); | |||||||
| function logRows(entityChanges) { | function logRows(entityChanges) { | ||||||
|     const filteredRows = entityChanges.filter(row => |     const filteredRows = entityChanges.filter(row => | ||||||
|         !processedEntityChangeIds.has(row.id) |         !processedEntityChangeIds.has(row.id) | ||||||
|         && row.entityName !== 'recent_notes' |  | ||||||
|         && (row.entityName !== 'options' || row.entityId !== 'openTabs')); |         && (row.entityName !== 'options' || row.entityId !== 'openTabs')); | ||||||
|  |  | ||||||
|     if (filteredRows.length > 0) { |     if (filteredRows.length > 0) { | ||||||
| @@ -103,7 +102,7 @@ function waitForEntityChangeId(desiredEntityChangeId) { | |||||||
|         return Promise.resolve(); |         return Promise.resolve(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     console.debug("Waiting for", desiredEntityChangeId, 'current is', lastProcessedEntityChangeId); |     console.debug(`Waiting for ${desiredEntityChangeId}, last processed is ${lastProcessedEntityChangeId}, last accepted ${lastAcceptedEntityChangeId}`); | ||||||
|  |  | ||||||
|     return new Promise((res, rej) => { |     return new Promise((res, rej) => { | ||||||
|         entityChangeIdReachedListeners.push({ |         entityChangeIdReachedListeners.push({ | ||||||
| @@ -127,7 +126,7 @@ function checkEntityChangeIdListeners() { | |||||||
|         .filter(l => l.desiredEntityChangeId > lastProcessedEntityChangeId); |         .filter(l => l.desiredEntityChangeId > lastProcessedEntityChangeId); | ||||||
|  |  | ||||||
|     entityChangeIdReachedListeners.filter(l => Date.now() > l.start - 60000) |     entityChangeIdReachedListeners.filter(l => Date.now() > l.start - 60000) | ||||||
|         .forEach(l => console.log(`Waiting for entityChangeId ${l.desiredEntityChangeId} while current is ${lastProcessedEntityChangeId} for ${Math.floor((Date.now() - l.start) / 1000)}s`)); |         .forEach(l => console.log(`Waiting for entityChangeId ${l.desiredEntityChangeId} while last processed is ${lastProcessedEntityChangeId} (last accepted ${lastAcceptedEntityChangeId}) for ${Math.floor((Date.now() - l.start) / 1000)}s`)); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function runSafely(syncHandler, syncData) { | async function runSafely(syncHandler, syncData) { | ||||||
| @@ -230,25 +229,6 @@ subscribeToMessages(message => { | |||||||
| }); | }); | ||||||
|  |  | ||||||
| async function processEntityChanges(entityChanges) { | async function processEntityChanges(entityChanges) { | ||||||
|     const missingNoteIds = []; |  | ||||||
|  |  | ||||||
|     for (const {entityName, entity} of entityChanges) { |  | ||||||
|         if (entityName === 'branches' && !(entity.parentNoteId in treeCache.notes)) { |  | ||||||
|             missingNoteIds.push(entity.parentNoteId); |  | ||||||
|         } |  | ||||||
|         else if (entityName === 'attributes' |  | ||||||
|               && entity.type === 'relation' |  | ||||||
|               && entity.name === 'template' |  | ||||||
|               && !(entity.noteId in treeCache.notes)) { |  | ||||||
|  |  | ||||||
|             missingNoteIds.push(entity.value); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (missingNoteIds.length > 0) { |  | ||||||
|         await treeCache.reloadNotes(missingNoteIds); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const loadResults = new LoadResults(treeCache); |     const loadResults = new LoadResults(treeCache); | ||||||
|  |  | ||||||
|     for (const ec of entityChanges.filter(ec => ec.entityName === 'notes')) { |     for (const ec of entityChanges.filter(ec => ec.entityName === 'notes')) { | ||||||
| @@ -391,6 +371,25 @@ async function processEntityChanges(entityChanges) { | |||||||
|         loadResults.addOption(ec.entity.name); |         loadResults.addOption(ec.entity.name); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     const missingNoteIds = []; | ||||||
|  |  | ||||||
|  |     for (const {entityName, entity} of entityChanges) { | ||||||
|  |         if (entityName === 'branches' && !(entity.parentNoteId in treeCache.notes)) { | ||||||
|  |             missingNoteIds.push(entity.parentNoteId); | ||||||
|  |         } | ||||||
|  |         else if (entityName === 'attributes' | ||||||
|  |             && entity.type === 'relation' | ||||||
|  |             && entity.name === 'template' | ||||||
|  |             && !(entity.value in treeCache.notes)) { | ||||||
|  |  | ||||||
|  |             missingNoteIds.push(entity.value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (missingNoteIds.length > 0) { | ||||||
|  |         await treeCache.reloadNotes(missingNoteIds); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (!loadResults.isEmpty()) { |     if (!loadResults.isEmpty()) { | ||||||
|         if (loadResults.hasAttributeRelatedChanges()) { |         if (loadResults.hasAttributeRelatedChanges()) { | ||||||
|             noteAttributeCache.invalidate(); |             noteAttributeCache.invalidate(); | ||||||
|   | |||||||
| @@ -172,8 +172,6 @@ const ATTR_TITLES = { | |||||||
|     "relation-definition": "Relation definition detail" |     "relation-definition": "Relation definition detail" | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const ATTR_NAME_MATCHER = new RegExp("^[\\p{L}\\p{N}_:]+$", "u"); |  | ||||||
|  |  | ||||||
| const ATTR_HELP = { | const ATTR_HELP = { | ||||||
|     "label": { |     "label": { | ||||||
|         "disableVersioning": "disables auto-versioning. Useful for e.g. large, but unimportant notes - e.g. large JS libraries used for scripting", |         "disableVersioning": "disables auto-versioning. Useful for e.g. large, but unimportant notes - e.g. large JS libraries used for scripting", | ||||||
| @@ -281,7 +279,7 @@ export default class AttributeDetailWidget extends TabAwareWidget { | |||||||
|         this.$rowTargetNote = this.$widget.find('.attr-row-target-note'); |         this.$rowTargetNote = this.$widget.find('.attr-row-target-note'); | ||||||
|         this.$inputTargetNote = this.$widget.find('.attr-input-target-note'); |         this.$inputTargetNote = this.$widget.find('.attr-input-target-note'); | ||||||
|  |  | ||||||
|         noteAutocompleteService.initNoteAutocomplete(this.$inputTargetNote) |         noteAutocompleteService.initNoteAutocomplete(this.$inputTargetNote, {allowCreatingNotes: true}) | ||||||
|             .on('autocomplete:noteselected', (event, suggestion, dataset) => { |             .on('autocomplete:noteselected', (event, suggestion, dataset) => { | ||||||
|                 if (!suggestion.notePath) { |                 if (!suggestion.notePath) { | ||||||
|                     return false; |                     return false; | ||||||
| @@ -573,9 +571,9 @@ export default class AttributeDetailWidget extends TabAwareWidget { | |||||||
|     updateAttributeInEditor() { |     updateAttributeInEditor() { | ||||||
|         let attrName = this.$inputName.val(); |         let attrName = this.$inputName.val(); | ||||||
|  |  | ||||||
|         if (!ATTR_NAME_MATCHER.test(attrName)) { |         if (!utils.isValidAttributeName(attrName)) { | ||||||
|             // invalid characters are simply ignored (from user perspective they are not even entered) |             // invalid characters are simply ignored (from user perspective they are not even entered) | ||||||
|             attrName = attrName.replace(/[^\p{L}\p{N}_:]/ug, ""); |             attrName = utils.filterAttributeName(attrName); | ||||||
|  |  | ||||||
|             this.$inputName.val(attrName); |             this.$inputName.val(attrName); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -491,7 +491,7 @@ export default class AttributeEditorWidget extends TabAwareWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async createNoteForReferenceLink(title) { |     async createNoteForReferenceLink(title) { | ||||||
|         const {note} = await noteCreateService.createNote(this.noteId, { |         const {note} = await noteCreateService.createNote(this.notePath, { | ||||||
|             activate: false, |             activate: false, | ||||||
|             title: title |             title: title | ||||||
|         }); |         }); | ||||||
|   | |||||||
| @@ -122,7 +122,7 @@ export default class CollapsibleSectionContainer extends TabAwareWidget { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async refreshWithNote(note) { |     async refreshWithNote(note, noExplicitActivation = false) { | ||||||
|         let $sectionToActivate, $lastActiveSection; |         let $sectionToActivate, $lastActiveSection; | ||||||
|  |  | ||||||
|         this.$titleContainer.empty().append('<div class="section-title section-title-empty">'); |         this.$titleContainer.empty().append('<div class="section-title section-title-empty">'); | ||||||
| @@ -141,7 +141,7 @@ export default class CollapsibleSectionContainer extends TabAwareWidget { | |||||||
|             this.$titleContainer.append($sectionTitle); |             this.$titleContainer.append($sectionTitle); | ||||||
|             this.$titleContainer.append('<div class="section-title section-title-empty">'); |             this.$titleContainer.append('<div class="section-title section-title-empty">'); | ||||||
|  |  | ||||||
|             if (ret.activate && !$sectionToActivate) { |             if (ret.activate && !$sectionToActivate && !noExplicitActivation) { | ||||||
|                 $sectionToActivate = $sectionTitle; |                 $sectionToActivate = $sectionTitle; | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -161,4 +161,8 @@ export default class CollapsibleSectionContainer extends TabAwareWidget { | |||||||
|             this.$bodyContainer.find('.section-body').removeClass("active"); |             this.$bodyContainer.find('.section-body').removeClass("active"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     refreshSectionContainerCommand() { | ||||||
|  |         this.refreshWithNote(this.note, true); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,6 +12,10 @@ const TPL = ` | |||||||
|             text-overflow: ellipsis; |             text-overflow: ellipsis; | ||||||
|         } |         } | ||||||
|     </style> |     </style> | ||||||
|  |      | ||||||
|  |     <div class="no-edited-notes-found">No edited notes on this day yet ...</div> | ||||||
|  |      | ||||||
|  |     <div class="edited-notes-list"></div> | ||||||
| </div> | </div> | ||||||
| `; | `; | ||||||
|  |  | ||||||
| @@ -31,18 +35,20 @@ export default class EditedNotesWidget extends CollapsibleWidget { | |||||||
|  |  | ||||||
|     async doRenderBody() { |     async doRenderBody() { | ||||||
|         this.$body.html(TPL); |         this.$body.html(TPL); | ||||||
|         this.$editedNotes = this.$body.find('.edited-notes-widget'); |         this.$list = this.$body.find('.edited-notes-list'); | ||||||
|  |         this.$noneFound = this.$body.find('.no-edited-notes-found'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async refreshWithNote(note) { |     async refreshWithNote(note) { | ||||||
|         // remember which title was when we found the similar notes |  | ||||||
|         this.title = note.title; |  | ||||||
|         let editedNotes = await server.get('edited-notes/' + note.getLabelValue("dateNote")); |         let editedNotes = await server.get('edited-notes/' + note.getLabelValue("dateNote")); | ||||||
|  |  | ||||||
|         editedNotes = editedNotes.filter(n => n.noteId !== note.noteId); |         editedNotes = editedNotes.filter(n => n.noteId !== note.noteId); | ||||||
|  |  | ||||||
|  |         this.$list.empty(); | ||||||
|  |         this.$noneFound.hide(); | ||||||
|  |  | ||||||
|         if (editedNotes.length === 0) { |         if (editedNotes.length === 0) { | ||||||
|             this.$body.text("No edited notes on this day yet ..."); |             this.$noneFound.show(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -50,8 +56,6 @@ export default class EditedNotesWidget extends CollapsibleWidget { | |||||||
|  |  | ||||||
|         await treeCache.getNotes(noteIds, true); // preload all at once |         await treeCache.getNotes(noteIds, true); // preload all at once | ||||||
|  |  | ||||||
|         const $list = $('<div>'); // not using <ul> because it's difficult to style correctly with text-overflow |  | ||||||
|  |  | ||||||
|         for (const editedNote of editedNotes) { |         for (const editedNote of editedNotes) { | ||||||
|             const $item = $('<div class="edited-note-line">'); |             const $item = $('<div class="edited-note-line">'); | ||||||
|  |  | ||||||
| @@ -67,9 +71,7 @@ export default class EditedNotesWidget extends CollapsibleWidget { | |||||||
|                 $item.append(editedNote.notePath ? await linkService.createNoteLink(editedNote.notePath.join("/"), {showNotePath: true}) : editedNote.title); |                 $item.append(editedNote.notePath ? await linkService.createNoteLink(editedNote.notePath.join("/"), {showNotePath: true}) : editedNote.title); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             $list.append($item); |             this.$list.append($item); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.$editedNotes.empty().append($list); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -91,7 +91,13 @@ export default class Component { | |||||||
|             console.log(`Call to ${fun.name} in ${this.componentId} took ${took}ms`); |             console.log(`Call to ${fun.name} in ${this.componentId} took ${took}ms`); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         await promise; |         if (glob.isDev) { | ||||||
|  |             await utils.timeLimit(promise, 20000, `Time limit failed on ${this.constructor.name} with ${fun.name}`); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             // cheaper and in non-dev the extra reporting is lost anyway through reload | ||||||
|  |             await promise; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ class MobileDetailMenuWidget extends BasicWidget { | |||||||
|                 ], |                 ], | ||||||
|                 selectMenuItemHandler: async ({command}) => { |                 selectMenuItemHandler: async ({command}) => { | ||||||
|                     if (command === "insertChildNote") { |                     if (command === "insertChildNote") { | ||||||
|                         noteCreateService.createNote(note.noteId); |                         noteCreateService.createNote(appContext.tabManager.getActiveTabNotePath()); | ||||||
|                     } |                     } | ||||||
|                     else if (command === "delete") { |                     else if (command === "delete") { | ||||||
|                         const notePath = appContext.tabManager.getActiveTabNotePath(); |                         const notePath = appContext.tabManager.getActiveTabNotePath(); | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ const WIDGET_TPL = ` | |||||||
|     } |     } | ||||||
|     </style> |     </style> | ||||||
|  |  | ||||||
|     <a data-trigger-command="createTopLevelNote" title="Create new top level note" class="icon-action bx bx-folder-plus"></a> |     <a data-trigger-command="createNoteIntoInbox" title="New note" class="icon-action bx bx-folder-plus"></a> | ||||||
|  |  | ||||||
|     <a data-trigger-command="collapseTree" title="Collapse note tree" class="icon-action bx bx-layer-minus"></a> |     <a data-trigger-command="collapseTree" title="Collapse note tree" class="icon-action bx bx-layer-minus"></a> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -65,6 +65,8 @@ export default class NoteDetailWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|             await server.put('notes/' + noteId, dto, this.componentId); |             await server.put('notes/' + noteId, dto, this.componentId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|  |         appContext.addBeforeUnloadListener(this); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     isEnabled() { |     isEnabled() { | ||||||
| @@ -276,7 +278,7 @@ export default class NoteDetailWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|             const label = attrs.find(attr => |             const label = attrs.find(attr => | ||||||
|                 attr.type === 'label' |                 attr.type === 'label' | ||||||
|                 && ['readOnly', 'autoReadOnlyDisabled', 'cssClass', 'bookZoomLevel'].includes(attr.name) |                 && ['readOnly', 'autoReadOnlyDisabled', 'cssClass', 'bookZoomLevel', 'displayRelations'].includes(attr.name) | ||||||
|                 && attr.isAffecting(this.note)); |                 && attr.isAffecting(this.note)); | ||||||
|  |  | ||||||
|             const relation = attrs.find(attr => |             const relation = attrs.find(attr => | ||||||
| @@ -293,7 +295,7 @@ export default class NoteDetailWidget extends TabAwareWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     beforeUnloadEvent() { |     beforeUnloadEvent() { | ||||||
|         this.spacedUpdate.updateNowIfNecessary(); |         return this.spacedUpdate.isAllSavedAndTriggerUpdate(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     textPreviewDisabledEvent({tabContext}) { |     textPreviewDisabledEvent({tabContext}) { | ||||||
| @@ -316,7 +318,7 @@ export default class NoteDetailWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // without await as this otherwise causes deadlock through component mutex |         // without await as this otherwise causes deadlock through component mutex | ||||||
|         noteCreateService.createNote(note.noteId, { |         noteCreateService.createNote(appContext.tabManager.getActiveTabNotePath(), { | ||||||
|             isProtected: note.isProtected, |             isProtected: note.isProtected, | ||||||
|             saveSelection: true |             saveSelection: true | ||||||
|         }); |         }); | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| import TabAwareWidget from "./tab_aware_widget.js"; | import TabAwareWidget from "./tab_aware_widget.js"; | ||||||
| import server from "../services/server.js"; |  | ||||||
| import attributeService from "../services/attributes.js"; | import attributeService from "../services/attributes.js"; | ||||||
|  |  | ||||||
| const TPL = ` | const TPL = ` | ||||||
| @@ -11,14 +10,16 @@ const TPL = ` | |||||||
|         margin-right: 0; |         margin-right: 0; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     .note-icon-container button { |     .note-icon-container button.note-icon { | ||||||
|         font-size: 180%; |         font-size: 180%; | ||||||
|         background: transparent; |         background: transparent; | ||||||
|         border: 1px solid transparent; |         border: 1px solid transparent; | ||||||
|         cursor: pointer; |         cursor: pointer; | ||||||
|  |         padding: 6px; | ||||||
|  |         color: var(--main-text-color); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     .note-icon-container button:hover { |     .note-icon-container button.note-icon:hover { | ||||||
|         border: 1px solid var(--main-border-color); |         border: 1px solid var(--main-border-color); | ||||||
|     } |     } | ||||||
|      |      | ||||||
| @@ -47,7 +48,6 @@ const TPL = ` | |||||||
|     .note-icon-container .icon-list { |     .note-icon-container .icon-list { | ||||||
|         height: 500px; |         height: 500px; | ||||||
|         overflow: auto; |         overflow: auto; | ||||||
|         font-size: 180%; |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     .note-icon-container .icon-list span { |     .note-icon-container .icon-list span { | ||||||
| @@ -55,6 +55,7 @@ const TPL = ` | |||||||
|         padding: 10px; |         padding: 10px; | ||||||
|         cursor: pointer; |         cursor: pointer; | ||||||
|         border: 1px solid transparent; |         border: 1px solid transparent; | ||||||
|  |         font-size: 180%; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     .note-icon-container .icon-list span:hover { |     .note-icon-container .icon-list span:hover { | ||||||
| @@ -62,7 +63,7 @@ const TPL = ` | |||||||
|     } |     } | ||||||
|     </style> |     </style> | ||||||
|      |      | ||||||
|     <button class="btn dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Change note icon"></button> |     <button class="btn dropdown-toggle note-icon" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Change note icon"></button> | ||||||
|     <div class="dropdown-menu" aria-labelledby="note-path-list-button" style="width: 610px;"> |     <div class="dropdown-menu" aria-labelledby="note-path-list-button" style="width: 610px;"> | ||||||
|         <div class="filter-row"> |         <div class="filter-row"> | ||||||
|             <span>Category:</span> <select name="icon-category" class="form-control"></select> |             <span>Category:</span> <select name="icon-category" class="form-control"></select> | ||||||
| @@ -74,14 +75,11 @@ const TPL = ` | |||||||
|     </div> |     </div> | ||||||
| </div>`; | </div>`; | ||||||
|  |  | ||||||
| let icons = []; |  | ||||||
| let categories = []; |  | ||||||
|  |  | ||||||
| export default class NoteIconWidget extends TabAwareWidget { | export default class NoteIconWidget extends TabAwareWidget { | ||||||
|     doRender() { |     doRender() { | ||||||
|         this.$widget = $(TPL); |         this.$widget = $(TPL); | ||||||
|         this.overflowing(); |         this.overflowing(); | ||||||
|         this.$icon = this.$widget.find('button'); |         this.$icon = this.$widget.find('button.note-icon'); | ||||||
|         this.$iconList = this.$widget.find('.icon-list'); |         this.$iconList = this.$widget.find('.icon-list'); | ||||||
|         this.$iconList.on('click', 'span', async e => { |         this.$iconList.on('click', 'span', async e => { | ||||||
|             const clazz = $(e.target).attr('class'); |             const clazz = $(e.target).attr('class'); | ||||||
| @@ -120,7 +118,7 @@ export default class NoteIconWidget extends TabAwareWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async refreshWithNote(note) { |     async refreshWithNote(note) { | ||||||
|         this.$icon.removeClass().addClass(note.getIcon()); |         this.$icon.removeClass().addClass(note.getIcon() + " note-icon"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async entitiesReloadedEvent({loadResults}) { |     async entitiesReloadedEvent({loadResults}) { | ||||||
| @@ -145,6 +143,18 @@ export default class NoteIconWidget extends TabAwareWidget { | |||||||
|     async renderDropdown(categoryId, search) { |     async renderDropdown(categoryId, search) { | ||||||
|         this.$iconList.empty(); |         this.$iconList.empty(); | ||||||
|  |  | ||||||
|  |         if (this.getIconLabels().length > 0) { | ||||||
|  |             this.$iconList.append( | ||||||
|  |                 $(`<div style="text-align: center">`) | ||||||
|  |                     .append( | ||||||
|  |                         $('<button class="btn btn-sm">Reset to default icon</button>') | ||||||
|  |                             .on('click', () => this.getIconLabels() | ||||||
|  |                                 .forEach(label => attributeService.removeAttributeById(this.noteId, label.attributeId)) | ||||||
|  |                             ) | ||||||
|  |                     ) | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         const {icons} = (await import('./icon_list.js')).default; |         const {icons} = (await import('./icon_list.js')).default; | ||||||
|  |  | ||||||
|         for (const icon of icons) { |         for (const icon of icons) { | ||||||
| @@ -164,6 +174,11 @@ export default class NoteIconWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     getIconLabels() { | ||||||
|  |         return this.note.getOwnedLabels() | ||||||
|  |             .filter(label => ['workspaceIconClass', 'iconClass'].includes(label.name)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     getIconClass(icon) { |     getIconClass(icon) { | ||||||
|         if (icon.type_of_icon === 'LOGO') { |         if (icon.type_of_icon === 'LOGO') { | ||||||
|             return "bx bxl-" + icon.name; |             return "bx bxl-" + icon.name; | ||||||
|   | |||||||
| @@ -23,11 +23,9 @@ const TPL = ` | |||||||
| export default class NoteListWidget extends TabAwareWidget { | export default class NoteListWidget extends TabAwareWidget { | ||||||
|     isEnabled() { |     isEnabled() { | ||||||
|         return super.isEnabled() |         return super.isEnabled() | ||||||
|  |             && ['book', 'text', 'code'].includes(this.note.type) | ||||||
|             && this.note.mime !== 'text/x-sqlite;schema=trilium' |             && this.note.mime !== 'text/x-sqlite;schema=trilium' | ||||||
|             && ( |             && this.note.hasChildren() | ||||||
|                 ['book', 'search', 'code'].includes(this.note.type) |  | ||||||
|                 || (this.note.type === 'text' && this.note.hasChildren()) |  | ||||||
|             ) |  | ||||||
|             && !this.note.hasLabel('hideChildrenOverview'); |             && !this.note.hasLabel('hideChildrenOverview'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -89,17 +87,6 @@ export default class NoteListWidget extends TabAwareWidget { | |||||||
|         setTimeout(() => this.checkRenderStatus(), 100); |         setTimeout(() => this.checkRenderStatus(), 100); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     searchRefreshedEvent({tabId}) { |  | ||||||
|         if (!this.isTab(tabId)) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.noteIdRefreshed = this.noteId; |  | ||||||
|         this.shownNoteId = null; |  | ||||||
|  |  | ||||||
|         this.checkRenderStatus(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     notesReloadedEvent({noteIds}) { |     notesReloadedEvent({noteIds}) { | ||||||
|         if (noteIds.includes(this.noteId)) { |         if (noteIds.includes(this.noteId)) { | ||||||
|             this.refresh(); |             this.refresh(); | ||||||
|   | |||||||
| @@ -15,9 +15,21 @@ const TPL = ` | |||||||
|     } |     } | ||||||
|      |      | ||||||
|     .note-path-list { |     .note-path-list { | ||||||
|         max-height: 600px; |         max-height: 700px; | ||||||
|         overflow-y: auto; |         overflow-y: auto; | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     .note-path-list .path-current { | ||||||
|  |         font-weight: bold; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     .note-path-list .path-archived { | ||||||
|  |         color: var(--muted-text-color) !important; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     .note-path-list .path-search { | ||||||
|  |         font-style: italic; | ||||||
|  |     } | ||||||
|     </style> |     </style> | ||||||
|      |      | ||||||
|     <button class="btn dropdown-toggle note-path-list-button bx bx-collection" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Note paths"></button> |     <button class="btn dropdown-toggle note-path-list-button bx bx-collection" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Note paths"></button> | ||||||
| @@ -43,20 +55,12 @@ export default class NotePathsWidget extends TabAwareWidget { | |||||||
|         ); |         ); | ||||||
|  |  | ||||||
|         if (this.noteId === 'root') { |         if (this.noteId === 'root') { | ||||||
|             await this.addPath('root', true); |             await this.addPath('root'); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         const pathSegments = treeService.parseNotePath(this.notePath); |         for (const notePathRecord of this.note.getSortedNotePaths(this.hoistedNoteId)) { | ||||||
|         const activeNoteParentNoteId = pathSegments[pathSegments.length - 2]; // we know this is not root so there must be a parent |             await this.addPath(notePathRecord); | ||||||
|  |  | ||||||
|         for (const parentNote of this.note.getParentNotes()) { |  | ||||||
|             const parentNotePath = treeService.getSomeNotePath(parentNote); |  | ||||||
|             // this is to avoid having root notes leading '/' |  | ||||||
|             const notePath = parentNotePath ? (parentNotePath + '/' + this.noteId) : this.noteId; |  | ||||||
|             const isCurrent = activeNoteParentNoteId === parentNote.noteId; |  | ||||||
|  |  | ||||||
|             await this.addPath(notePath, isCurrent); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         const cloneLink = $("<div>") |         const cloneLink = $("<div>") | ||||||
| @@ -70,7 +74,9 @@ export default class NotePathsWidget extends TabAwareWidget { | |||||||
|         this.$notePathList.append(cloneLink); |         this.$notePathList.append(cloneLink); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async addPath(notePath, isCurrent) { |     async addPath(notePathRecord) { | ||||||
|  |         const notePath = notePathRecord.notePath.join('/'); | ||||||
|  |  | ||||||
|         const title = await treeService.getNotePathTitle(notePath); |         const title = await treeService.getNotePathTitle(notePath); | ||||||
|  |  | ||||||
|         const $noteLink = await linkService.createNoteLink(notePath, {title}); |         const $noteLink = await linkService.createNoteLink(notePath, {title}); | ||||||
| @@ -82,8 +88,33 @@ export default class NotePathsWidget extends TabAwareWidget { | |||||||
|             .find('a') |             .find('a') | ||||||
|             .addClass("no-tooltip-preview"); |             .addClass("no-tooltip-preview"); | ||||||
|  |  | ||||||
|         if (isCurrent) { |         const comments = []; | ||||||
|             $noteLink.addClass("current"); |  | ||||||
|  |         if (this.notePath === notePath) { | ||||||
|  |             $noteLink.addClass("path-current"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (notePathRecord.isInHoistedSubTree) { | ||||||
|  |             $noteLink.addClass("path-in-hoisted-subtree"); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             comments.push("outside of hoisting"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (notePathRecord.isArchived) { | ||||||
|  |             $noteLink.addClass("path-archived"); | ||||||
|  |  | ||||||
|  |             comments.push("archived"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (notePathRecord.isSearch) { | ||||||
|  |             $noteLink.addClass("path-search"); | ||||||
|  |  | ||||||
|  |             comments.push("search"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (comments.length > 0) { | ||||||
|  |             $noteLink.append(` (${comments.join(', ')})`); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.$notePathList.append($noteLink); |         this.$notePathList.append($noteLink); | ||||||
| @@ -96,4 +127,10 @@ export default class NotePathsWidget extends TabAwareWidget { | |||||||
|             this.refresh(); |             this.refresh(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     async refresh() { | ||||||
|  |         await super.refresh(); | ||||||
|  |  | ||||||
|  |         this.$widget.find('.dropdown-toggle').dropdown('hide'); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ import utils from "../services/utils.js"; | |||||||
| import protectedSessionHolder from "../services/protected_session_holder.js"; | import protectedSessionHolder from "../services/protected_session_holder.js"; | ||||||
| import server from "../services/server.js"; | import server from "../services/server.js"; | ||||||
| import SpacedUpdate from "../services/spaced_update.js"; | import SpacedUpdate from "../services/spaced_update.js"; | ||||||
|  | import appContext from "../services/app_context.js"; | ||||||
|  |  | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="note-title-container"> | <div class="note-title-container"> | ||||||
| @@ -37,6 +38,8 @@ export default class NoteTitleWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|             await server.put(`notes/${this.noteId}/change-title`, {title}); |             await server.put(`notes/${this.noteId}/change-title`, {title}); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|  |         appContext.addBeforeUnloadListener(this); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     doRender() { |     doRender() { | ||||||
| @@ -101,6 +104,6 @@ export default class NoteTitleWidget extends TabAwareWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     beforeUnloadEvent() { |     beforeUnloadEvent() { | ||||||
|         this.spacedUpdate.updateNowIfNecessary(); |         return this.spacedUpdate.isAllSavedAndTriggerUpdate(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -203,8 +203,9 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         this.$tree.on("mousedown", ".refresh-search-button", e => this.refreshSearch(e)); |         this.$tree.on("mousedown", ".refresh-search-button", e => this.refreshSearch(e)); | ||||||
|         this.$tree.on("mousedown", ".add-note-button", e => { |         this.$tree.on("mousedown", ".add-note-button", e => { | ||||||
|             const node = $.ui.fancytree.getNode(e); |             const node = $.ui.fancytree.getNode(e); | ||||||
|  |             const parentNotePath = treeService.getNotePath(node); | ||||||
|  |  | ||||||
|             noteCreateService.createNote(node.data.noteId, { |             noteCreateService.createNote(parentNotePath, { | ||||||
|                 isProtected: node.data.isProtected |                 isProtected: node.data.isProtected | ||||||
|             }); |             }); | ||||||
|         }); |         }); | ||||||
| @@ -392,12 +393,6 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|                 autoExpandMS: 600, |                 autoExpandMS: 600, | ||||||
|                 preventLazyParents: false, |                 preventLazyParents: false, | ||||||
|                 dragStart: (node, data) => { |                 dragStart: (node, data) => { | ||||||
|                     // don't allow dragging root node |  | ||||||
|                     if (node.data.noteId === hoistedNoteService.getHoistedNoteId() |  | ||||||
|                         || node.getParent().data.noteType === 'search') { |  | ||||||
|                         return false; |  | ||||||
|                     } |  | ||||||
|  |  | ||||||
|                     const notes = this.getSelectedOrActiveNodes(node).map(node => ({ |                     const notes = this.getSelectedOrActiveNodes(node).map(node => ({ | ||||||
|                         noteId: node.data.noteId, |                         noteId: node.data.noteId, | ||||||
|                         branchId: node.data.branchId, |                         branchId: node.data.branchId, | ||||||
| @@ -482,7 +477,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|                         let childNoteIds = note.getChildNoteIds(); |                         let childNoteIds = note.getChildNoteIds(); | ||||||
|  |  | ||||||
|                         if (childNoteIds.length > MAX_SEARCH_RESULTS_IN_TREE) { |                         if (note.type === 'search' && childNoteIds.length > MAX_SEARCH_RESULTS_IN_TREE) { | ||||||
|                             childNoteIds = childNoteIds.slice(0, MAX_SEARCH_RESULTS_IN_TREE); |                             childNoteIds = childNoteIds.slice(0, MAX_SEARCH_RESULTS_IN_TREE); | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
| @@ -600,7 +595,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|         let childBranches = parentNote.getFilteredChildBranches(); |         let childBranches = parentNote.getFilteredChildBranches(); | ||||||
|  |  | ||||||
|         if (childBranches.length > MAX_SEARCH_RESULTS_IN_TREE) { |         if (parentNote.type === 'search' && childBranches.length > MAX_SEARCH_RESULTS_IN_TREE) { | ||||||
|             childBranches = childBranches.slice(0, MAX_SEARCH_RESULTS_IN_TREE); |             childBranches = childBranches.slice(0, MAX_SEARCH_RESULTS_IN_TREE); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -624,6 +619,17 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|     updateNode(node) { |     updateNode(node) { | ||||||
|         const note = treeCache.getNoteFromCache(node.data.noteId); |         const note = treeCache.getNoteFromCache(node.data.noteId); | ||||||
|         const branch = treeCache.getBranch(node.data.branchId); |         const branch = treeCache.getBranch(node.data.branchId); | ||||||
|  |  | ||||||
|  |         if (!note) { | ||||||
|  |             console.log(`Node update not possible because note ${node.data.noteId} was not found.`); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!branch) { | ||||||
|  |             console.log(`Node update not possible because branch ${node.data.branchId} was not found.`); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         const title = (branch.prefix ? (branch.prefix + " - ") : "") + note.title; |         const title = (branch.prefix ? (branch.prefix + " - ") : "") + note.title; | ||||||
|  |  | ||||||
|         node.data.isProtected = note.isProtected; |         node.data.isProtected = note.isProtected; | ||||||
| @@ -759,7 +765,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         await this.setExpandedStatusForSubtree(node, false); |         await this.setExpandedStatusForSubtree(node, false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     collapseTreeCommand() { this.collapseTree(); } |     collapseTreeEvent() { this.collapseTree(); } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @return {FancytreeNode|null} |      * @return {FancytreeNode|null} | ||||||
| @@ -783,7 +789,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async scrollToActiveNoteCommand() { |     async scrollToActiveNoteEvent() { | ||||||
|         const activeContext = appContext.tabManager.getActiveTabContext(); |         const activeContext = appContext.tabManager.getActiveTabContext(); | ||||||
|  |  | ||||||
|         if (activeContext && activeContext.notePath) { |         if (activeContext && activeContext.notePath) { | ||||||
| @@ -792,19 +798,17 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|             const node = await this.expandToNote(activeContext.notePath); |             const node = await this.expandToNote(activeContext.notePath); | ||||||
|  |  | ||||||
|             await node.makeVisible({scrollIntoView: true}); |             await node.makeVisible({scrollIntoView: true}); | ||||||
|             node.setFocus(true); |             node.setActive(true, {noEvents: true, noFocus: false}); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** @return {FancytreeNode} */ |     /** @return {FancytreeNode} */ | ||||||
|     async getNodeFromPath(notePath, expand = false, logErrors = true) { |     async getNodeFromPath(notePath, expand = false, logErrors = true) { | ||||||
|         utils.assertArguments(notePath); |         utils.assertArguments(notePath); | ||||||
|  |         /** @let {FancytreeNode} */ | ||||||
|  |         let parentNode = this.getNodesByNoteId('root')[0]; | ||||||
|  |  | ||||||
|         const hoistedNoteId = hoistedNoteService.getHoistedNoteId(); |         let resolvedNotePathSegments = await treeService.resolveNotePathToSegments(notePath, this.hoistedNoteId, logErrors); | ||||||
|         /** @const {FancytreeNode} */ |  | ||||||
|         let parentNode = null; |  | ||||||
|  |  | ||||||
|         const resolvedNotePathSegments = await treeService.resolveNotePathToSegments(notePath, logErrors); |  | ||||||
|  |  | ||||||
|         if (!resolvedNotePathSegments) { |         if (!resolvedNotePathSegments) { | ||||||
|             if (logErrors) { |             if (logErrors) { | ||||||
| @@ -814,14 +818,9 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         resolvedNotePathSegments = resolvedNotePathSegments.slice(1); | ||||||
|  |  | ||||||
|         for (const childNoteId of resolvedNotePathSegments) { |         for (const childNoteId of resolvedNotePathSegments) { | ||||||
|             if (childNoteId === hoistedNoteId) { |  | ||||||
|                 // there must be exactly one node with given hoistedNoteId |  | ||||||
|                 parentNode = this.getNodesByNoteId(childNoteId)[0]; |  | ||||||
|  |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             // we expand only after hoisted note since before then nodes are not actually present in the tree |             // we expand only after hoisted note since before then nodes are not actually present in the tree | ||||||
|             if (parentNode) { |             if (parentNode) { | ||||||
|                 if (!parentNode.isLoaded()) { |                 if (!parentNode.isLoaded()) { | ||||||
| @@ -852,7 +851,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|                             // these are real notes with real notePath, user can display them in a detail |                             // these are real notes with real notePath, user can display them in a detail | ||||||
|                             // but they don't have a node in the tree |                             // but they don't have a node in the tree | ||||||
|  |  | ||||||
|                             ws.logError(`Can't find node for child node of noteId=${childNoteId} for parent of noteId=${parentNode.data.noteId} and hoistedNoteId=${hoistedNoteId}, requested path is ${notePath}`); |                             ws.logError(`Can't find node for child node of noteId=${childNoteId} for parent of noteId=${parentNode.data.noteId} and hoistedNoteId=${hoistedNoteService.getHoistedNoteId()}, requested path is ${notePath}`); | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                         return; |                         return; | ||||||
| @@ -994,6 +993,9 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         const activeNodeFocused = activeNode && activeNode.hasFocus(); |         const activeNodeFocused = activeNode && activeNode.hasFocus(); | ||||||
|         const nextNode = activeNode ? (activeNode.getNextSibling() || activeNode.getPrevSibling() || activeNode.getParent()) : null; |         const nextNode = activeNode ? (activeNode.getNextSibling() || activeNode.getPrevSibling() || activeNode.getParent()) : null; | ||||||
|         const activeNotePath = activeNode ? treeService.getNotePath(activeNode) : null; |         const activeNotePath = activeNode ? treeService.getNotePath(activeNode) : null; | ||||||
|  |  | ||||||
|  |         console.log(activeNotePath, activeNodeFocused); | ||||||
|  |  | ||||||
|         const nextNotePath = nextNode ? treeService.getNotePath(nextNode) : null; |         const nextNotePath = nextNode ? treeService.getNotePath(nextNode) : null; | ||||||
|         const activeNoteId = activeNode ? activeNode.data.noteId : null; |         const activeNoteId = activeNode ? activeNode.data.noteId : null; | ||||||
|  |  | ||||||
| @@ -1025,6 +1027,9 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         for (const branch of loadResults.getBranches()) { |         for (const branch of loadResults.getBranches()) { | ||||||
|  |             // adding noteId itself to update all potential clones | ||||||
|  |             noteIdsToUpdate.add(branch.noteId); | ||||||
|  |  | ||||||
|             for (const node of this.getNodesByBranchId(branch.branchId)) { |             for (const node of this.getNodesByBranchId(branch.branchId)) { | ||||||
|                 if (branch.isDeleted) { |                 if (branch.isDeleted) { | ||||||
|                     if (node.isActive()) { |                     if (node.isActive()) { | ||||||
| @@ -1043,9 +1048,6 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|                     noteIdsToUpdate.add(branch.parentNoteId); |                     noteIdsToUpdate.add(branch.parentNoteId); | ||||||
|                 } |                 } | ||||||
|                 else { |  | ||||||
|                     noteIdsToUpdate.add(branch.noteId); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (!branch.isDeleted) { |             if (!branch.isDeleted) { | ||||||
| @@ -1114,23 +1116,28 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (node) { |             if (node) { | ||||||
|                 node.setActive(true, {noEvents: true, noFocus: true}); |                 node.setActive(true, {noEvents: true, noFocus: !activeNodeFocused}); | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|                 // this is used when original note has been deleted and we want to move the focus to the note above/below |                 // this is used when original note has been deleted and we want to move the focus to the note above/below | ||||||
|                 node = await this.expandToNote(nextNotePath, false); |                 node = await this.expandToNote(nextNotePath, false); | ||||||
|  |  | ||||||
|                 if (node) { |                 if (node) { | ||||||
|                     await appContext.tabManager.getActiveTabContext().setNote(nextNotePath); |                     // FIXME: this is conceptually wrong | ||||||
|  |                     //        here note tree is responsible for updating global state of the application | ||||||
|  |                     //        this should be done by tabcontext / tabmanager and note tree should only listen to | ||||||
|  |                     //        changes in active note and just set the "active" state | ||||||
|  |                     // We don't await since that can bring up infinite cycles when e.g. custom widget does some backend requests which wait for max sync ID processed | ||||||
|  |                     appContext.tabManager.getActiveTabContext().setNote(nextNotePath).then(() => { | ||||||
|  |                         const newActiveNode = this.getActiveNode(); | ||||||
|  |  | ||||||
|  |                         // return focus if the previously active node was also focused | ||||||
|  |                         if (newActiveNode && activeNodeFocused) {console.log("FOCUSING!!!"); | ||||||
|  |                             newActiveNode.setFocus(true); | ||||||
|  |                         } | ||||||
|  |                     }); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             const newActiveNode = this.getActiveNode(); |  | ||||||
|  |  | ||||||
|             // return focus if the previously active node was also focused |  | ||||||
|             if (newActiveNode && activeNodeFocused) { |  | ||||||
|                 await newActiveNode.setFocus(true); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (noteIdsToReload.size > 0 || noteIdsToUpdate.size > 0) { |         if (noteIdsToReload.size > 0 || noteIdsToUpdate.size > 0) { | ||||||
| @@ -1197,13 +1204,20 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     filterHoistedBranch() { |     async filterHoistedBranch() { | ||||||
|         if (this.tabContext) { |         if (this.tabContext) { | ||||||
|  |             // make sure the hoisted node is loaded (can be unloaded e.g. after tree collapse in another tab) | ||||||
|  |             const hoistedNotePath = await treeService.resolveNotePath(this.tabContext.hoistedNoteId); | ||||||
|  |             await this.getNodeFromPath(hoistedNotePath); | ||||||
|  |  | ||||||
|             if (this.tabContext.hoistedNoteId === 'root') { |             if (this.tabContext.hoistedNoteId === 'root') { | ||||||
|                 this.tree.clearFilter(); |                 this.tree.clearFilter(); | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|                 this.tree.filterBranches(node => node.data.noteId === this.tabContext.hoistedNoteId); |                 // hack when hoisted note is cloned then it could be filtered multiple times while we want only 1 | ||||||
|  |                 this.tree.filterBranches(node => | ||||||
|  |                     node.data.noteId === this.tabContext.hoistedNoteId // optimization to not having always resolve the node path | ||||||
|  |                     && treeService.getNotePath(node) === hoistedNotePath); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -1241,7 +1255,12 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async deleteNotesCommand({node}) { |     async deleteNotesCommand({node}) { | ||||||
|         const branchIds = this.getSelectedOrActiveBranchIds(node); |         const branchIds = this.getSelectedOrActiveBranchIds(node) | ||||||
|  |             .filter(branchId => !branchId.startsWith('virt-')); // search results can't be deleted | ||||||
|  |  | ||||||
|  |         if (!branchIds.length) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         await branchService.deleteNotes(branchIds); |         await branchService.deleteNotes(branchIds); | ||||||
|  |  | ||||||
| @@ -1355,7 +1374,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     sortChildNotesCommand({node}) { |     sortChildNotesCommand({node}) { | ||||||
|         treeService.sortAlphabetically(node.data.noteId); |         import("../dialogs/sort_child_notes.js").then(d => d.showDialog(node.data.noteId)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async recentChangesInSubtreeCommand({node}) { |     async recentChangesInSubtreeCommand({node}) { | ||||||
|   | |||||||
| @@ -49,7 +49,11 @@ export default class QuickSearchWidget extends BasicWidget { | |||||||
|         this.$widget.find('.input-group-append').on('shown.bs.dropdown', () => this.search()); |         this.$widget.find('.input-group-append').on('shown.bs.dropdown', () => this.search()); | ||||||
|  |  | ||||||
|         utils.bindElShortcut(this.$searchString, 'return', () => { |         utils.bindElShortcut(this.$searchString, 'return', () => { | ||||||
|             this.$dropdownToggle.dropdown('show'); |             if (this.$dropdownMenu.is(":visible")) { | ||||||
|  |                 this.search(); // just update already visible dropdown | ||||||
|  |             } else { | ||||||
|  |                 this.$dropdownToggle.dropdown('show'); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             this.$searchString.focus(); |             this.$searchString.focus(); | ||||||
|         }); |         }); | ||||||
| @@ -90,12 +94,18 @@ export default class QuickSearchWidget extends BasicWidget { | |||||||
|             const $link = await linkService.createNoteLink(note.noteId, {showNotePath: true}); |             const $link = await linkService.createNoteLink(note.noteId, {showNotePath: true}); | ||||||
|             $link.addClass('dropdown-item'); |             $link.addClass('dropdown-item'); | ||||||
|             $link.attr("tabIndex", "0"); |             $link.attr("tabIndex", "0"); | ||||||
|             $link.on('click', () => this.$dropdownToggle.dropdown("hide")); |             $link.on('click', e => { | ||||||
|  |                 this.$dropdownToggle.dropdown("hide"); | ||||||
|  |  | ||||||
|  |                 if (!e.target || e.target.nodeName !== 'A') { | ||||||
|  |                     // click on the link is handled by link handling but we want the whole item clickable | ||||||
|  |                     appContext.tabManager.getActiveTabContext().setNote(note.noteId); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|             utils.bindElShortcut($link, 'return', () => { |             utils.bindElShortcut($link, 'return', () => { | ||||||
|                 $link.find('a').trigger({ |                 this.$dropdownToggle.dropdown("hide"); | ||||||
|                     type: 'click', |  | ||||||
|                     which: 1 // left click |                 appContext.tabManager.getActiveTabContext().setNote(note.noteId); | ||||||
|                 }); |  | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|             this.$dropdownMenu.append($link); |             this.$dropdownMenu.append($link); | ||||||
| @@ -110,17 +120,21 @@ export default class QuickSearchWidget extends BasicWidget { | |||||||
|  |  | ||||||
|         this.$dropdownMenu.append($showInFullButton); |         this.$dropdownMenu.append($showInFullButton); | ||||||
|  |  | ||||||
|         utils.bindElShortcut($showInFullButton, 'return', async () => { |         $showInFullButton.on('click', () => this.showInFullSearch()); | ||||||
|             const searchNote = await dateNotesService.createSearchNote({searchString: this.$searchString.val()}); |  | ||||||
|  |  | ||||||
|             await appContext.tabManager.getActiveTabContext().setNote(searchNote.noteId); |         utils.bindElShortcut($showInFullButton, 'return', () => this.showInFullSearch()); | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         utils.bindElShortcut(this.$dropdownMenu.find('.dropdown-item:first'), 'up', () => this.$searchString.focus()); |         utils.bindElShortcut(this.$dropdownMenu.find('.dropdown-item:first'), 'up', () => this.$searchString.focus()); | ||||||
|  |  | ||||||
|         this.$dropdownToggle.dropdown('update'); |         this.$dropdownToggle.dropdown('update'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     async showInFullSearch() { | ||||||
|  |         const searchNote = await dateNotesService.createSearchNote({searchString: this.$searchString.val()}); | ||||||
|  |  | ||||||
|  |         await appContext.tabManager.getActiveTabContext().setNote(searchNote.noteId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     quickSearchEvent() { |     quickSearchEvent() { | ||||||
|         this.$searchString.focus(); |         this.$searchString.focus(); | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								src/public/app/widgets/search_options/debug.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/public/app/widgets/search_options/debug.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | import AbstractSearchOption from "./abstract_search_option.js"; | ||||||
|  |  | ||||||
|  | const TPL = ` | ||||||
|  | <tr data-search-option-conf="debug"> | ||||||
|  |     <td colSpan="2"> | ||||||
|  |         <span class="bx bx-bug"></span> | ||||||
|  |  | ||||||
|  |         Debug | ||||||
|  |     </td> | ||||||
|  |     <td class="button-column"> | ||||||
|  |         <div class="dropdown help-dropdown"> | ||||||
|  |             <span class="bx bx-help-circle icon-action" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span> | ||||||
|  |             <div class="dropdown-menu dropdown-menu-right p-4"> | ||||||
|  |                 <p>Debug will print extra debugging information into the console to aid in debugging complex queries.</p> | ||||||
|  |                  | ||||||
|  |                 <p>To access the debug information, execute query and click on "Show backend log" in top left corner.</p>  | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |      | ||||||
|  |         <span class="bx bx-x icon-action search-option-del"></span> | ||||||
|  |     </td> | ||||||
|  | </tr>`; | ||||||
|  |  | ||||||
|  | export default class Debug extends AbstractSearchOption { | ||||||
|  |     static get optionName() { return "debug" }; | ||||||
|  |     static get attributeType() { return "label" }; | ||||||
|  |  | ||||||
|  |     static async create(noteId) { | ||||||
|  |         await AbstractSearchOption.setAttribute(noteId,'label', 'debug'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     doRender() { | ||||||
|  |         return $(TPL); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -16,6 +16,11 @@ const TPL = ` | |||||||
|             <option value="contentSize">Note content size</option> |             <option value="contentSize">Note content size</option> | ||||||
|             <option value="noteSize">Note content size including revisions</option> |             <option value="noteSize">Note content size including revisions</option> | ||||||
|             <option value="revisionCount">Number of revisions</option> |             <option value="revisionCount">Number of revisions</option> | ||||||
|  |             <option value="childrenCount">Number of children notes</option> | ||||||
|  |             <option value="parentCount">Number of clones</option> | ||||||
|  |             <option value="ownedLabelCount">Number of labels</option> | ||||||
|  |             <option value="ownedRelationCount">Number of relations</option> | ||||||
|  |             <option value="targetRelationCount">Number of relations targeting the note</option> | ||||||
|         </select> |         </select> | ||||||
|          |          | ||||||
|         <select name="orderDirection" class="form-control w-auto d-inline"> |         <select name="orderDirection" class="form-control w-auto d-inline"> | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ export default class SearchScript extends AbstractSearchOption { | |||||||
|     doRender() { |     doRender() { | ||||||
|         const $option = $(TPL); |         const $option = $(TPL); | ||||||
|         const $searchScript = $option.find('.search-script'); |         const $searchScript = $option.find('.search-script'); | ||||||
|         noteAutocompleteService.initNoteAutocomplete($searchScript); |         noteAutocompleteService.initNoteAutocomplete($searchScript, {allowCreatingNotes: true}); | ||||||
|  |  | ||||||
|         $searchScript.on('autocomplete:closed', async () => { |         $searchScript.on('autocomplete:closed', async () => { | ||||||
|             const searchScriptNoteId = $searchScript.getSelectedNoteId(); |             const searchScriptNoteId = $searchScript.getSelectedNoteId(); | ||||||
|   | |||||||
							
								
								
									
										72
									
								
								src/public/app/widgets/search_result.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/public/app/widgets/search_result.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | import TabAwareWidget from "./tab_aware_widget.js"; | ||||||
|  | import NoteListRenderer from "../services/note_list_renderer.js"; | ||||||
|  |  | ||||||
|  | const TPL = ` | ||||||
|  | <div class="search-result-widget"> | ||||||
|  |     <style> | ||||||
|  |     .search-result-widget { | ||||||
|  |         flex-grow: 100000; | ||||||
|  |         flex-shrink: 100000; | ||||||
|  |         min-height: 0; | ||||||
|  |         overflow: auto; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     .search-result-widget .note-list { | ||||||
|  |         padding: 10px; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     .search-no-results, .search-not-executed-yet { | ||||||
|  |         margin: 20px; | ||||||
|  |         padding: 20px; | ||||||
|  |     } | ||||||
|  |     </style> | ||||||
|  |      | ||||||
|  |     <div class="search-no-results alert alert-info"> | ||||||
|  |         No notes have been found for given search parameters. | ||||||
|  |     </div> | ||||||
|  |      | ||||||
|  |     <div class="search-not-executed-yet alert alert-info"> | ||||||
|  |         Search has not been executed yet. Click on "Search" button above to see the results. | ||||||
|  |     </div> | ||||||
|  |      | ||||||
|  |     <div class="search-result-widget-content"> | ||||||
|  |     </div> | ||||||
|  | </div>`; | ||||||
|  |  | ||||||
|  | export default class SearchResultWidget extends TabAwareWidget { | ||||||
|  |     isEnabled() { | ||||||
|  |         return super.isEnabled() | ||||||
|  |             && this.note.type === 'search'; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     doRender() { | ||||||
|  |         this.$widget = $(TPL); | ||||||
|  |         this.$content = this.$widget.find('.search-result-widget-content'); | ||||||
|  |         this.$noResults = this.$widget.find('.search-no-results'); | ||||||
|  |         this.$notExecutedYet = this.$widget.find('.search-not-executed-yet'); | ||||||
|  |         this.contentSized(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async refreshWithNote(note) { | ||||||
|  |         this.$content.empty(); | ||||||
|  |         this.$noResults.toggle(note.getChildNoteIds().length === 0 && !!note.searchResultsLoaded); | ||||||
|  |         this.$notExecutedYet.toggle(!note.searchResultsLoaded); | ||||||
|  |  | ||||||
|  |         const noteListRenderer = new NoteListRenderer(this.$content, note, note.getChildNoteIds(), true); | ||||||
|  |         await noteListRenderer.renderList(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     searchRefreshedEvent({tabId}) { | ||||||
|  |         if (!this.isTab(tabId)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.refresh(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     notesReloadedEvent({noteIds}) { | ||||||
|  |         if (noteIds.includes(this.noteId)) { | ||||||
|  |             this.refresh(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -22,6 +22,10 @@ export default class TabAwareWidget extends BasicWidget { | |||||||
|         return this.tabContext && this.tabContext.notePath; |         return this.tabContext && this.tabContext.notePath; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     get hoistedNoteId() { | ||||||
|  |         return this.tabContext && this.tabContext.hoistedNoteId; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     isEnabled() { |     isEnabled() { | ||||||
|         return !!this.note; |         return !!this.note; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -83,4 +83,10 @@ export default class InheritedAttributesWidget extends TabAwareWidget { | |||||||
|     getInheritedAttributes(note) { |     getInheritedAttributes(note) { | ||||||
|         return note.getAttributes().filter(attr => attr.noteId !== this.noteId); |         return note.getAttributes().filter(attr => attr.noteId !== this.noteId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     entitiesReloadedEvent({loadResults}) { | ||||||
|  |         if (loadResults.getAttributes(this.componentId).find(attr => attr.isAffecting(this.note))) { | ||||||
|  |             this.refresh(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -210,7 +210,7 @@ export default class PromotedAttributesWidget extends TabAwareWidget { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             // no need to wait for this |             // no need to wait for this | ||||||
|             noteAutocompleteService.initNoteAutocomplete($input); |             noteAutocompleteService.initNoteAutocomplete($input, {allowCreatingNotes: true}); | ||||||
|  |  | ||||||
|             $input.on('autocomplete:noteselected', (event, suggestion, dataset) => { |             $input.on('autocomplete:noteselected', (event, suggestion, dataset) => { | ||||||
|                 this.promotedAttributeChanged(event); |                 this.promotedAttributeChanged(event); | ||||||
| @@ -293,6 +293,7 @@ export default class PromotedAttributesWidget extends TabAwareWidget { | |||||||
|             this.refresh(); |             this.refresh(); | ||||||
|  |  | ||||||
|             this.renderTitle(this.note); |             this.renderTitle(this.note); | ||||||
|  |             this.triggerCommand('refreshSectionContainer'); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ import OrderBy from "../search_options/order_by.js"; | |||||||
| import SearchScript from "../search_options/search_script.js"; | import SearchScript from "../search_options/search_script.js"; | ||||||
| import Limit from "../search_options/limit.js"; | import Limit from "../search_options/limit.js"; | ||||||
| import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js"; | import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js"; | ||||||
|  | import Debug from "../search_options/debug.js"; | ||||||
|  |  | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="search-definition-widget"> | <div class="search-definition-widget"> | ||||||
| @@ -113,6 +114,11 @@ const TPL = ` | |||||||
|                         limit |                         limit | ||||||
|                     </button> |                     </button> | ||||||
|                      |                      | ||||||
|  |                     <button type="button" class="btn btn-sm" data-search-option-add="debug" title="Debug will print extra debugging information into the console to aid in debugging complex queries"> | ||||||
|  |                         <span class="bx bx-bug"></span> | ||||||
|  |                         debug | ||||||
|  |                     </button> | ||||||
|  |                      | ||||||
|                     <div class="dropdown" style="display: inline-block;"> |                     <div class="dropdown" style="display: inline-block;"> | ||||||
|                       <button class="btn btn-sm dropdown-toggle action-add-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |                       <button class="btn btn-sm dropdown-toggle action-add-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||||||
|                         <span class="bx bxs-zap"></span> |                         <span class="bx bxs-zap"></span> | ||||||
| @@ -173,7 +179,8 @@ const OPTION_CLASSES = [ | |||||||
|     FastSearch, |     FastSearch, | ||||||
|     IncludeArchivedNotes, |     IncludeArchivedNotes, | ||||||
|     OrderBy, |     OrderBy, | ||||||
|     Limit |     Limit, | ||||||
|  |     Debug | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| const ACTION_CLASSES = {}; | const ACTION_CLASSES = {}; | ||||||
|   | |||||||
| @@ -274,7 +274,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async createNoteForReferenceLink(title) { |     async createNoteForReferenceLink(title) { | ||||||
|         const {note} = await noteCreateService.createNote(this.noteId, { |         const {note} = await noteCreateService.createNote(this.notePath, { | ||||||
|             activate: false, |             activate: false, | ||||||
|             title: title |             title: title | ||||||
|         }); |         }); | ||||||
|   | |||||||
| @@ -22,7 +22,10 @@ export default class EmptyTypeWidget extends TypeWidget { | |||||||
|         this.contentSized(); |         this.contentSized(); | ||||||
|         this.$autoComplete = this.$widget.find(".note-autocomplete"); |         this.$autoComplete = this.$widget.find(".note-autocomplete"); | ||||||
|  |  | ||||||
|         noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, { hideGoToSelectedNoteButton: true }) |         noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, { | ||||||
|  |             hideGoToSelectedNoteButton: true, | ||||||
|  |             allowCreatingNotes: true | ||||||
|  |         }) | ||||||
|             .on('autocomplete:noteselected', function(event, suggestion, dataset) { |             .on('autocomplete:noteselected', function(event, suggestion, dataset) { | ||||||
|                 if (!suggestion.notePath) { |                 if (!suggestion.notePath) { | ||||||
|                     return false; |                     return false; | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ import attributeAutocompleteService from "../../services/attribute_autocomplete. | |||||||
| import TypeWidget from "./type_widget.js"; | import TypeWidget from "./type_widget.js"; | ||||||
| import appContext from "../../services/app_context.js"; | import appContext from "../../services/app_context.js"; | ||||||
| import utils from "../../services/utils.js"; | import utils from "../../services/utils.js"; | ||||||
|  | import treeCache from "../../services/tree_cache.js"; | ||||||
|  |  | ||||||
| const uniDirectionalOverlays = [ | const uniDirectionalOverlays = [ | ||||||
|     [ "Arrow", { |     [ "Arrow", { | ||||||
| @@ -285,7 +286,7 @@ export default class RelationMapTypeWidget extends TypeWidget { | |||||||
|  |  | ||||||
|     async loadNotesAndRelations() { |     async loadNotesAndRelations() { | ||||||
|         const noteIds = this.mapData.notes.map(note => note.noteId); |         const noteIds = this.mapData.notes.map(note => note.noteId); | ||||||
|         const data = await server.post("notes/relation-map", {noteIds}); |         const data = await server.post("notes/relation-map", {noteIds, relationMapNoteId: this.noteId}); | ||||||
|  |  | ||||||
|         this.relations = []; |         this.relations = []; | ||||||
|  |  | ||||||
| @@ -471,14 +472,22 @@ export default class RelationMapTypeWidget extends TypeWidget { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         const promptDialog = await import("../../dialogs/prompt.js"); |         const promptDialog = await import("../../dialogs/prompt.js"); | ||||||
|         const name = await promptDialog.ask({ |         let name = await promptDialog.ask({ | ||||||
|             message: "Specify new relation name:", |             message: "Specify new relation name (allowed characters: alphanumeric, colon and underscore):", | ||||||
|             shown: ({ $answer }) => |             shown: ({ $answer }) => { | ||||||
|  |                 $answer.on('keyup', () => { | ||||||
|  |                     // invalid characters are simply ignored (from user perspective they are not even entered) | ||||||
|  |                     const attrName = utils.filterAttributeName($answer.val()); | ||||||
|  |  | ||||||
|  |                     $answer.val(attrName); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|                 attributeAutocompleteService.initAttributeNameAutocomplete({ |                 attributeAutocompleteService.initAttributeNameAutocomplete({ | ||||||
|                     $el: $answer, |                     $el: $answer, | ||||||
|                     attributeType: "relation", |                     attributeType: "relation", | ||||||
|                     open: true |                     open: true | ||||||
|                 }) |                 }); | ||||||
|  |             } | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         if (!name || !name.trim()) { |         if (!name || !name.trim()) { | ||||||
| @@ -487,6 +496,8 @@ export default class RelationMapTypeWidget extends TypeWidget { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         name = utils.filterAttributeName(name); | ||||||
|  |  | ||||||
|         const targetNoteId = this.idToNoteId(connection.target.id); |         const targetNoteId = this.idToNoteId(connection.target.id); | ||||||
|         const sourceNoteId = this.idToNoteId(connection.source.id); |         const sourceNoteId = this.idToNoteId(connection.source.id); | ||||||
|  |  | ||||||
| @@ -521,8 +532,11 @@ export default class RelationMapTypeWidget extends TypeWidget { | |||||||
|             linkService.goToLink(e); |             linkService.goToLink(e); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|  |         const note = await treeCache.getNote(noteId); | ||||||
|  |  | ||||||
|         const $noteBox = $("<div>") |         const $noteBox = $("<div>") | ||||||
|             .addClass("note-box") |             .addClass("note-box") | ||||||
|  |             .addClass(note.getCssClass()) | ||||||
|             .prop("id", this.noteIdToId(noteId)) |             .prop("id", this.noteIdToId(noteId)) | ||||||
|             .append($("<span>").addClass("title").append($link)) |             .append($("<span>").addClass("title").append($link)) | ||||||
|             .append($("<div>").addClass("endpoint").attr("title", "Start dragging relations from here and drop them on another note.")) |             .append($("<div>").addClass("endpoint").attr("title", "Start dragging relations from here and drop them on another note.")) | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| .note-detail-relation-map { | .note-detail-relation-map { | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     overflow: hidden !important; |     overflow: hidden !important; | ||||||
|     padding-top: 10px; |     padding: 10px; | ||||||
|     position: relative; |     position: relative; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -54,9 +54,17 @@ function moveBranchBeforeNote(req) { | |||||||
|     const {branchId, beforeBranchId} = req.params; |     const {branchId, beforeBranchId} = req.params; | ||||||
|  |  | ||||||
|     const branchToMove = repository.getBranch(branchId); |     const branchToMove = repository.getBranch(branchId); | ||||||
|     const beforeNote = repository.getBranch(beforeBranchId); |     const beforeBranch = repository.getBranch(beforeBranchId); | ||||||
|  |  | ||||||
|     const validationResult = treeService.validateParentChild(beforeNote.parentNoteId, branchToMove.noteId, branchId); |     if (!branchToMove) { | ||||||
|  |         return [404, `Can't find branch ${branchId}`]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!beforeBranch) { | ||||||
|  |         return [404, `Can't find branch ${beforeBranchId}`]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const validationResult = treeService.validateParentChild(beforeBranch.parentNoteId, branchToMove.noteId, branchId); | ||||||
|  |  | ||||||
|     if (!validationResult.success) { |     if (!validationResult.success) { | ||||||
|         return [200, validationResult]; |         return [200, validationResult]; | ||||||
| @@ -65,16 +73,16 @@ function moveBranchBeforeNote(req) { | |||||||
|     // we don't change utcDateModified so other changes are prioritized in case of conflict |     // we don't change utcDateModified so other changes are prioritized in case of conflict | ||||||
|     // also we would have to sync all those modified branches otherwise hash checks would fail |     // also we would have to sync all those modified branches otherwise hash checks would fail | ||||||
|     sql.execute("UPDATE branches SET notePosition = notePosition + 10 WHERE parentNoteId = ? AND notePosition >= ? AND isDeleted = 0", |     sql.execute("UPDATE branches SET notePosition = notePosition + 10 WHERE parentNoteId = ? AND notePosition >= ? AND isDeleted = 0", | ||||||
|         [beforeNote.parentNoteId, beforeNote.notePosition]); |         [beforeBranch.parentNoteId, beforeBranch.notePosition]); | ||||||
|  |  | ||||||
|     entityChangesService.addNoteReorderingEntityChange(beforeNote.parentNoteId); |     entityChangesService.addNoteReorderingEntityChange(beforeBranch.parentNoteId); | ||||||
|  |  | ||||||
|     if (branchToMove.parentNoteId === beforeNote.parentNoteId) { |     if (branchToMove.parentNoteId === beforeBranch.parentNoteId) { | ||||||
|         branchToMove.notePosition = beforeNote.notePosition; |         branchToMove.notePosition = beforeBranch.notePosition; | ||||||
|         branchToMove.save(); |         branchToMove.save(); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         const newBranch = branchToMove.createClone(beforeNote.parentNoteId, beforeNote.notePosition); |         const newBranch = branchToMove.createClone(beforeBranch.parentNoteId, beforeBranch.notePosition); | ||||||
|         newBranch.save(); |         newBranch.save(); | ||||||
|  |  | ||||||
|         branchToMove.isDeleted = true; |         branchToMove.isDeleted = true; | ||||||
|   | |||||||
| @@ -5,6 +5,8 @@ const sql = require('../../services/sql'); | |||||||
| const dateUtils = require('../../services/date_utils'); | const dateUtils = require('../../services/date_utils'); | ||||||
| const noteService = require('../../services/notes'); | const noteService = require('../../services/notes'); | ||||||
| const attributeService = require('../../services/attributes'); | const attributeService = require('../../services/attributes'); | ||||||
|  | const cls = require('../../services/cls'); | ||||||
|  | const repository = require('../../services/repository'); | ||||||
|  |  | ||||||
| function getInboxNote(req) { | function getInboxNote(req) { | ||||||
|     return attributeService.getNoteWithLabel('inbox') |     return attributeService.getNoteWithLabel('inbox') | ||||||
| @@ -59,21 +61,54 @@ function createSqlConsole() { | |||||||
|     return note; |     return note; | ||||||
| } | } | ||||||
|  |  | ||||||
| function createSearchNote() { | function createSearchNote(req) { | ||||||
|     const today = dateUtils.localNowDate(); |     const params = req.body; | ||||||
|  |     const searchString = params.searchString || ""; | ||||||
|  |     let ancestorNoteId = params.ancestorNoteId; | ||||||
|  |  | ||||||
|     const searchHome = |     const hoistedNote = cls.getHoistedNoteId() && cls.getHoistedNoteId() !== 'root' | ||||||
|         attributeService.getNoteWithLabel('searchHome') |         ? repository.getNote(cls.getHoistedNoteId()) | ||||||
|         || dateNoteService.getDateNote(today); |         : null; | ||||||
|  |  | ||||||
|  |     let searchHome; | ||||||
|  |  | ||||||
|  |     if (hoistedNote) { | ||||||
|  |         ([searchHome] = hoistedNote.getDescendantNotesWithLabel('hoistedSearchHome')); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!searchHome) { | ||||||
|  |         const today = dateUtils.localNowDate(); | ||||||
|  |  | ||||||
|  |         searchHome = attributeService.getNoteWithLabel('searchHome') | ||||||
|  |                   || dateNoteService.getDateNote(today); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (hoistedNote) { | ||||||
|  |  | ||||||
|  |         if (!hoistedNote.getDescendantNoteIds().includes(searchHome.noteId)) { | ||||||
|  |             // otherwise the note would be saved outside of the hoisted context which is weird | ||||||
|  |             searchHome = hoistedNote; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!ancestorNoteId) { | ||||||
|  |             ancestorNoteId = hoistedNote.noteId; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const {note} = noteService.createNewNote({ |     const {note} = noteService.createNewNote({ | ||||||
|         parentNoteId: searchHome.noteId, |         parentNoteId: searchHome.noteId, | ||||||
|         title: 'Search: ', |         title: 'Search: ' + searchString, | ||||||
|         content: "", |         content: "", | ||||||
|         type: 'search', |         type: 'search', | ||||||
|         mime: 'application/json' |         mime: 'application/json' | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     note.setLabel('searchString', searchString); | ||||||
|  |  | ||||||
|  |     if (ancestorNoteId) { | ||||||
|  |         note.setRelation('ancestor', ancestorNoteId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     return note; |     return note; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -42,6 +42,9 @@ async function importToBranch(req) { | |||||||
|     // and may produce unintended consequences |     // and may produce unintended consequences | ||||||
|     cls.disableEntityEvents(); |     cls.disableEntityEvents(); | ||||||
|  |  | ||||||
|  |     // eliminate flickering during import | ||||||
|  |     cls.ignoreEntityChanges(); | ||||||
|  |  | ||||||
|     let note; // typically root of the import - client can show it after finishing the import |     let note; // typically root of the import - client can show it after finishing the import | ||||||
|  |  | ||||||
|     const taskContext = TaskContext.getInstance(taskId, 'import', options); |     const taskContext = TaskContext.getInstance(taskId, 'import', options); | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ const noteService = require('../../services/notes'); | |||||||
| const treeService = require('../../services/tree'); | const treeService = require('../../services/tree'); | ||||||
| const repository = require('../../services/repository'); | const repository = require('../../services/repository'); | ||||||
| const utils = require('../../services/utils'); | const utils = require('../../services/utils'); | ||||||
|  | const log = require('../../services/log'); | ||||||
| const TaskContext = require('../../services/task_context'); | const TaskContext = require('../../services/task_context'); | ||||||
|  |  | ||||||
| function getNote(req) { | function getNote(req) { | ||||||
| @@ -85,10 +86,20 @@ function undeleteNote(req) { | |||||||
|     taskContext.taskSucceeded(); |     taskContext.taskSucceeded(); | ||||||
| } | } | ||||||
|  |  | ||||||
| function sortNotes(req) { | function sortChildNotes(req) { | ||||||
|     const noteId = req.params.noteId; |     const noteId = req.params.noteId; | ||||||
|  |     const {sortBy, sortDirection} = req.body; | ||||||
|  |  | ||||||
|     treeService.sortNotesAlphabetically(noteId); |     log.info(`Sorting ${noteId} children with ${sortBy} ${sortDirection}`); | ||||||
|  |  | ||||||
|  |     const reverse = sortDirection === 'desc'; | ||||||
|  |  | ||||||
|  |     if (sortBy === 'title') { | ||||||
|  |         treeService.sortNotesByTitle(noteId, false, reverse); | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         treeService.sortNotes(noteId, sortBy, reverse); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function protectNote(req) { | function protectNote(req) { | ||||||
| @@ -117,7 +128,8 @@ function setNoteTypeMime(req) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function getRelationMap(req) { | function getRelationMap(req) { | ||||||
|     const noteIds = req.body.noteIds; |     const {relationMapNoteId, noteIds} = req.body; | ||||||
|  |  | ||||||
|     const resp = { |     const resp = { | ||||||
|         // noteId => title |         // noteId => title | ||||||
|         noteTitles: {}, |         noteTitles: {}, | ||||||
| @@ -134,12 +146,23 @@ function getRelationMap(req) { | |||||||
|  |  | ||||||
|     const questionMarks = noteIds.map(noteId => '?').join(','); |     const questionMarks = noteIds.map(noteId => '?').join(','); | ||||||
|  |  | ||||||
|  |     const relationMapNote = repository.getNote(relationMapNoteId); | ||||||
|  |  | ||||||
|  |     const displayRelationsVal = relationMapNote.getLabelValue('displayRelations'); | ||||||
|  |     const displayRelations = !displayRelationsVal ? [] : displayRelationsVal | ||||||
|  |         .split(",") | ||||||
|  |         .map(token => token.trim()); | ||||||
|  |  | ||||||
|  |     console.log("displayRelations", displayRelations); | ||||||
|  |  | ||||||
|     const notes = repository.getEntities(`SELECT * FROM notes WHERE isDeleted = 0 AND noteId IN (${questionMarks})`, noteIds); |     const notes = repository.getEntities(`SELECT * FROM notes WHERE isDeleted = 0 AND noteId IN (${questionMarks})`, noteIds); | ||||||
|  |  | ||||||
|     for (const note of notes) { |     for (const note of notes) { | ||||||
|         resp.noteTitles[note.noteId] = note.title; |         resp.noteTitles[note.noteId] = note.title; | ||||||
|  |  | ||||||
|         resp.relations = resp.relations.concat(note.getRelations() |         resp.relations = resp.relations.concat(note.getRelations() | ||||||
|  |             .filter(relation => !relation.isAutoLink() || displayRelations.includes(relation.name)) | ||||||
|  |             .filter(relation => displayRelations.length === 0 || displayRelations.includes(relation.name)) | ||||||
|             .filter(relation => noteIds.includes(relation.value)) |             .filter(relation => noteIds.includes(relation.value)) | ||||||
|             .map(relation => ({ |             .map(relation => ({ | ||||||
|                 attributeId: relation.attributeId, |                 attributeId: relation.attributeId, | ||||||
| @@ -203,7 +226,7 @@ module.exports = { | |||||||
|     deleteNote, |     deleteNote, | ||||||
|     undeleteNote, |     undeleteNote, | ||||||
|     createNote, |     createNote, | ||||||
|     sortNotes, |     sortChildNotes, | ||||||
|     protectNote, |     protectNote, | ||||||
|     setNoteTypeMime, |     setNoteTypeMime, | ||||||
|     getRelationMap, |     getRelationMap, | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ async function search(note) { | |||||||
|             orderBy: note.getLabelValue('orderBy'), |             orderBy: note.getLabelValue('orderBy'), | ||||||
|             orderDirection: note.getLabelValue('orderDirection'), |             orderDirection: note.getLabelValue('orderDirection'), | ||||||
|             limit: note.getLabelValue('limit'), |             limit: note.getLabelValue('limit'), | ||||||
|  |             debug: note.hasLabel('debug'), | ||||||
|             fuzzyAttributeSearch: false |             fuzzyAttributeSearch: false | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
| @@ -232,7 +233,9 @@ function getRelatedNotes(req) { | |||||||
|  |  | ||||||
|     const results = []; |     const results = []; | ||||||
|  |  | ||||||
|     for (const record of matchingNameAndValue.concat(matchingName)) { |     const allResults = matchingNameAndValue.concat(matchingName); | ||||||
|  |  | ||||||
|  |     for (const record of allResults) { | ||||||
|         if (results.length >= 20) { |         if (results.length >= 20) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| @@ -245,7 +248,7 @@ function getRelatedNotes(req) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|         count: matchingName.length, |         count: allResults.length, | ||||||
|         results |         results | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| @@ -266,6 +269,10 @@ function formatAttrForSearch(attr, searchWithValue) { | |||||||
|     searchStr += attr.name; |     searchStr += attr.name; | ||||||
|  |  | ||||||
|     if (searchWithValue && attr.value) { |     if (searchWithValue && attr.value) { | ||||||
|  |         if (attr.type === 'relation') { | ||||||
|  |             searchStr += ".noteId"; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         searchStr += '='; |         searchStr += '='; | ||||||
|         searchStr += formatValue(attr.value); |         searchStr += formatValue(attr.value); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| "use strict"; | "use strict"; | ||||||
|  |  | ||||||
| const noteCache = require('../../services/note_cache/note_cache'); | const noteCache = require('../../services/note_cache/note_cache'); | ||||||
|  | const log = require('../../services/log'); | ||||||
|  |  | ||||||
| function getNotesAndBranchesAndAttributes(noteIds) { | function getNotesAndBranchesAndAttributes(noteIds) { | ||||||
|     noteIds = new Set(noteIds); |     noteIds = new Set(noteIds); | ||||||
| @@ -76,6 +77,11 @@ function getNotesAndBranchesAndAttributes(noteIds) { | |||||||
|     for (const branchId of collectedBranchIds) { |     for (const branchId of collectedBranchIds) { | ||||||
|         const branch = noteCache.branches[branchId]; |         const branch = noteCache.branches[branchId]; | ||||||
|  |  | ||||||
|  |         if (!branch) { | ||||||
|  |             log.error(`Could not find branch for branchId=${branchId}`); | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         branches.push({ |         branches.push({ | ||||||
|             branchId: branch.branchId, |             branchId: branch.branchId, | ||||||
|             noteId: branch.noteId, |             noteId: branch.noteId, | ||||||
| @@ -129,6 +135,10 @@ function getTree(req) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (!(subTreeNoteId in noteCache.notes)) { | ||||||
|  |         return [404, `Note ${subTreeNoteId} not found in the cache`]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     collect(noteCache.notes[subTreeNoteId]); |     collect(noteCache.notes[subTreeNoteId]); | ||||||
|  |  | ||||||
|     return getNotesAndBranchesAndAttributes(collectedNoteIds); |     return getNotesAndBranchesAndAttributes(collectedNoteIds); | ||||||
|   | |||||||
| @@ -150,7 +150,7 @@ function register(app) { | |||||||
|     apiRoute(DELETE, '/api/notes/:noteId', notesApiRoute.deleteNote); |     apiRoute(DELETE, '/api/notes/:noteId', notesApiRoute.deleteNote); | ||||||
|     apiRoute(PUT, '/api/notes/:noteId/undelete', notesApiRoute.undeleteNote); |     apiRoute(PUT, '/api/notes/:noteId/undelete', notesApiRoute.undeleteNote); | ||||||
|     apiRoute(POST, '/api/notes/:parentNoteId/children', notesApiRoute.createNote); |     apiRoute(POST, '/api/notes/:parentNoteId/children', notesApiRoute.createNote); | ||||||
|     apiRoute(PUT, '/api/notes/:noteId/sort', notesApiRoute.sortNotes); |     apiRoute(PUT, '/api/notes/:noteId/sort-children', notesApiRoute.sortChildNotes); | ||||||
|     apiRoute(PUT, '/api/notes/:noteId/protect/:isProtected', notesApiRoute.protectNote); |     apiRoute(PUT, '/api/notes/:noteId/protect/:isProtected', notesApiRoute.protectNote); | ||||||
|     apiRoute(PUT, /\/api\/notes\/(.*)\/type\/(.*)\/mime\/(.*)/, notesApiRoute.setNoteTypeMime); |     apiRoute(PUT, /\/api\/notes\/(.*)\/type\/(.*)\/mime\/(.*)/, notesApiRoute.setNoteTypeMime); | ||||||
|     apiRoute(GET, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.getNoteRevisions); |     apiRoute(GET, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.getNoteRevisions); | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ const build = require('./build'); | |||||||
| const packageJson = require('../../package'); | const packageJson = require('../../package'); | ||||||
| const {TRILIUM_DATA_DIR} = require('./data_dir'); | const {TRILIUM_DATA_DIR} = require('./data_dir'); | ||||||
|  |  | ||||||
| const APP_DB_VERSION = 182; | const APP_DB_VERSION = 183; | ||||||
| const SYNC_VERSION = 20; | const SYNC_VERSION = 20; | ||||||
| const CLIPPER_PROTOCOL_VERSION = "1.0"; | const CLIPPER_PROTOCOL_VERSION = "1.0"; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -38,6 +38,7 @@ const BUILTIN_ATTRIBUTES = [ | |||||||
|     { type: 'label', name: 'workspaceIconClass' }, |     { type: 'label', name: 'workspaceIconClass' }, | ||||||
|     { type: 'label', name: 'workspaceTabBackgroundColor' }, |     { type: 'label', name: 'workspaceTabBackgroundColor' }, | ||||||
|     { type: 'label', name: 'searchHome' }, |     { type: 'label', name: 'searchHome' }, | ||||||
|  |     { type: 'label', name: 'hoistedSearchHome' }, | ||||||
|     { type: 'label', name: 'sqlConsoleHome' }, |     { type: 'label', name: 'sqlConsoleHome' }, | ||||||
|     { type: 'label', name: 'datePattern' }, |     { type: 'label', name: 'datePattern' }, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -359,7 +359,7 @@ function BackendScriptApi(currentNote, apiParams) { | |||||||
|      * @method |      * @method | ||||||
|      * @param {string} parentNoteId - this note's child notes will be sorted |      * @param {string} parentNoteId - this note's child notes will be sorted | ||||||
|      */ |      */ | ||||||
|     this.sortNotesAlphabetically = treeService.sortNotesAlphabetically; |     this.sortNotesByTitle = treeService.sortNotesByTitle; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * This method finds note by its noteId and prefix and either sets it to the given parentNoteId |      * This method finds note by its noteId and prefix and either sets it to the given parentNoteId | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| module.exports = { buildDate:"2021-02-15T22:29:35+01:00", buildRevision: "c0edcc1bfe621eff7fbc976172fd0897bc065f6c" }; | module.exports = { buildDate:"2021-03-08T23:11:11+01:00", buildRevision: "f27370d44f08afaa22d4cd86cba489584f9c878b" }; | ||||||
|   | |||||||
| @@ -53,6 +53,10 @@ function getAndClearEntityChanges() { | |||||||
| } | } | ||||||
|  |  | ||||||
| function addEntityChange(entityChange) { | function addEntityChange(entityChange) { | ||||||
|  |     if (namespace.get('ignoreEntityChanges')) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const entityChanges = namespace.get('entityChanges') || []; |     const entityChanges = namespace.get('entityChanges') || []; | ||||||
|  |  | ||||||
|     entityChanges.push(entityChange); |     entityChanges.push(entityChange); | ||||||
| @@ -69,7 +73,11 @@ function getEntityFromCache(entityName, entityId) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function setEntityToCache(entityName, entityId, entity) { | function setEntityToCache(entityName, entityId, entity) { | ||||||
|     return namespace.set(entityName + '-' + entityId, entity); |     namespace.set(entityName + '-' + entityId, entity); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function ignoreEntityChanges() { | ||||||
|  |     namespace.set('ignoreEntityChanges', true); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
| @@ -87,5 +95,6 @@ module.exports = { | |||||||
|     getAndClearEntityChanges, |     getAndClearEntityChanges, | ||||||
|     addEntityChange, |     addEntityChange, | ||||||
|     getEntityFromCache, |     getEntityFromCache, | ||||||
|     setEntityToCache |     setEntityToCache, | ||||||
|  |     ignoreEntityChanges | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -152,12 +152,11 @@ function getDateNoteTitle(rootNote, dayNumber, dateObj) { | |||||||
| function getDateNote(dateStr) { | function getDateNote(dateStr) { | ||||||
|     const rootNote = getRootCalendarNote(); |     const rootNote = getRootCalendarNote(); | ||||||
|  |  | ||||||
|     const dayNumber = dateStr.substr(8, 2); |  | ||||||
|  |  | ||||||
|     let dateNote = attributeService.getNoteWithLabel(DATE_LABEL, dateStr); |     let dateNote = attributeService.getNoteWithLabel(DATE_LABEL, dateStr); | ||||||
|  |  | ||||||
|     if (!dateNote) { |     if (!dateNote) { | ||||||
|         const monthNote = getMonthNote(dateStr, rootNote); |         const monthNote = getMonthNote(dateStr, rootNote); | ||||||
|  |         const dayNumber = dateStr.substr(8, 2); | ||||||
|  |  | ||||||
|         dateNote = getNoteStartingWith(monthNote.noteId, dayNumber); |         dateNote = getNoteStartingWith(monthNote.noteId, dayNumber); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,6 +30,23 @@ function addEntityChange(entityChange, sourceId, isSynced) { | |||||||
|     cls.addEntityChange(localEntityChange); |     cls.addEntityChange(localEntityChange); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function addNoteReorderingEntityChange(parentNoteId, sourceId) { | ||||||
|  |     addEntityChange({ | ||||||
|  |         entityName: "note_reordering", | ||||||
|  |         entityId: parentNoteId, | ||||||
|  |         hash: 'N/A', | ||||||
|  |         isErased: false, | ||||||
|  |         utcDateChanged: dateUtils.utcNowDateTime() | ||||||
|  |     }, sourceId); | ||||||
|  |  | ||||||
|  |     const eventService = require('./events'); | ||||||
|  |  | ||||||
|  |     eventService.emit(eventService.ENTITY_CHANGED, { | ||||||
|  |         entityName: 'note_reordering', | ||||||
|  |         entity: sql.getMap(`SELECT branchId, notePosition FROM branches WHERE isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]) | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
| function moveEntityChangeToTop(entityName, entityId) { | function moveEntityChangeToTop(entityName, entityId) { | ||||||
|     const [hash, isSynced] = sql.getRow(`SELECT * FROM entity_changes WHERE entityName = ? AND entityId = ?`, [entityName, entityId]); |     const [hash, isSynced] = sql.getRow(`SELECT * FROM entity_changes WHERE entityName = ? AND entityId = ?`, [entityName, entityId]); | ||||||
|  |  | ||||||
| @@ -121,13 +138,7 @@ function fillAllEntityChanges() { | |||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     addNoteReorderingEntityChange: (parentNoteId, sourceId) => addEntityChange({ |     addNoteReorderingEntityChange, | ||||||
|         entityName: "note_reordering", |  | ||||||
|         entityId: parentNoteId, |  | ||||||
|         hash: 'N/A', |  | ||||||
|         isErased: false, |  | ||||||
|         utcDateChanged: dateUtils.utcNowDateTime() |  | ||||||
|     }, sourceId), |  | ||||||
|     moveEntityChangeToTop, |     moveEntityChangeToTop, | ||||||
|     addEntityChange, |     addEntityChange, | ||||||
|     fillAllEntityChanges, |     fillAllEntityChanges, | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| "use strict"; | "use strict"; | ||||||
|  |  | ||||||
| const TurndownService = require('turndown'); | const TurndownService = require('turndown'); | ||||||
| const turndownPluginGfm = require('turndown-plugin-gfm'); | const turndownPluginGfm = require('joplin-turndown-plugin-gfm'); | ||||||
|  |  | ||||||
| let instance = null; | let instance = null; | ||||||
|  |  | ||||||
| @@ -16,4 +16,4 @@ function toMarkdown(content) { | |||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     toMarkdown |     toMarkdown | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ eventService.subscribe(eventService.NOTE_TITLE_CHANGED, note => { | |||||||
|  |  | ||||||
|         for (const parentNote of noteFromCache.parents) { |         for (const parentNote of noteFromCache.parents) { | ||||||
|             if (parentNote.hasLabel("sorted")) { |             if (parentNote.hasLabel("sorted")) { | ||||||
|                 treeService.sortNotesAlphabetically(parentNote.noteId); |                 treeService.sortNotesByTitle(parentNote.noteId); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -53,23 +53,19 @@ eventService.subscribe(eventService.ENTITY_CREATED, ({ entityName, entity }) => | |||||||
|         if (entity.type === 'relation' && entity.name === 'template') { |         if (entity.type === 'relation' && entity.name === 'template') { | ||||||
|             const note = repository.getNote(entity.noteId); |             const note = repository.getNote(entity.noteId); | ||||||
|  |  | ||||||
|             if (!note.isStringNote()) { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             const content = note.getContent(); |  | ||||||
|  |  | ||||||
|             if (content && content.trim().length > 0) { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             const templateNote = repository.getNote(entity.value); |             const templateNote = repository.getNote(entity.value); | ||||||
|  |  | ||||||
|             if (!templateNote) { |             if (!templateNote) { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (templateNote.isStringNote()) { |             const content = note.getContent(); | ||||||
|  |  | ||||||
|  |             if (!["text", "code"].includes(note.type) | ||||||
|  |                 // if the note has already content we're not going to overwrite it with template's one | ||||||
|  |                 && (!content || content.trim().length === 0) | ||||||
|  |                 && templateNote.isStringNote()) { | ||||||
|  |  | ||||||
|                 const templateNoteContent = templateNote.getContent(); |                 const templateNoteContent = templateNote.getContent(); | ||||||
|  |  | ||||||
|                 if (templateNoteContent) { |                 if (templateNoteContent) { | ||||||
| @@ -81,17 +77,21 @@ eventService.subscribe(eventService.ENTITY_CREATED, ({ entityName, entity }) => | |||||||
|                 note.save(); |                 note.save(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             noteService.duplicateSubtreeWithoutRoot(templateNote.noteId, note.noteId); |             // we'll copy the children notes only if there's none so far | ||||||
|  |             // this protects against e.g. multiple assignment of template relation resulting in having multiple copies of the subtree | ||||||
|  |             if (note.getChildNotes().length === 0 && !note.isDescendantOfNote(templateNote.noteId)) { | ||||||
|  |                 noteService.duplicateSubtreeWithoutRoot(templateNote.noteId, note.noteId); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         else if (entity.type === 'label' && entity.name === 'sorted') { |         else if (entity.type === 'label' && entity.name === 'sorted') { | ||||||
|             treeService.sortNotesAlphabetically(entity.noteId); |             treeService.sortNotesByTitle(entity.noteId); | ||||||
|  |  | ||||||
|             if (entity.isInheritable) { |             if (entity.isInheritable) { | ||||||
|                 const note = noteCache.notes[entity.noteId]; |                 const note = noteCache.notes[entity.noteId]; | ||||||
|  |  | ||||||
|                 if (note) { |                 if (note) { | ||||||
|                     for (const noteId of note.subtreeNoteIds) { |                     for (const noteId of note.subtreeNoteIds) { | ||||||
|                         treeService.sortNotesAlphabetically(noteId); |                         treeService.sortNotesByTitle(noteId); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -148,19 +148,15 @@ eventService.subscribe(eventService.ENTITY_DELETED, ({ entityName, entity }) => | |||||||
|     processInverseRelations(entityName, entity, (definition, note, targetNote) => { |     processInverseRelations(entityName, entity, (definition, note, targetNote) => { | ||||||
|         // if one inverse attribute is deleted then the other should be deleted as well |         // if one inverse attribute is deleted then the other should be deleted as well | ||||||
|         const relations = targetNote.getOwnedRelations(definition.inverseRelation); |         const relations = targetNote.getOwnedRelations(definition.inverseRelation); | ||||||
|         let deletedSomething = false; |  | ||||||
|  |  | ||||||
|         for (const relation of relations) { |         for (const relation of relations) { | ||||||
|             if (relation.value === note.noteId) { |             if (relation.value === note.noteId) { | ||||||
|  |                 note.invalidateAttributeCache(); | ||||||
|  |                 targetNote.invalidateAttributeCache(); | ||||||
|  |  | ||||||
|                 relation.isDeleted = true; |                 relation.isDeleted = true; | ||||||
|                 relation.save(); |                 relation.save(); | ||||||
|  |  | ||||||
|                 deletedSomething = true; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (deletedSomething) { |  | ||||||
|             targetNote.invalidateAttributeCache(); |  | ||||||
|         } |  | ||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -355,7 +355,9 @@ async function importZip(taskContext, fileBuffer, importRootNote) { | |||||||
|                 mime, |                 mime, | ||||||
|                 prefix: noteMeta ? noteMeta.prefix : '', |                 prefix: noteMeta ? noteMeta.prefix : '', | ||||||
|                 isExpanded: noteMeta ? noteMeta.isExpanded : false, |                 isExpanded: noteMeta ? noteMeta.isExpanded : false, | ||||||
|                 notePosition: noteMeta ? noteMeta.notePosition : false, |                 // root notePosition should be ignored since it relates to original document | ||||||
|  |                 // now import root should be placed after existing notes into new parent | ||||||
|  |                 notePosition: (noteMeta && firstNote) ? noteMeta.notePosition : undefined, | ||||||
|                 isProtected: importRootNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), |                 isProtected: importRootNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), | ||||||
|             })); |             })); | ||||||
|  |  | ||||||
| @@ -461,7 +463,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) { | |||||||
|         if (!metaFile) { |         if (!metaFile) { | ||||||
|             // if there's no meta file then the notes are created based on the order in that tar file but that |             // if there's no meta file then the notes are created based on the order in that tar file but that | ||||||
|             // is usually quite random so we sort the notes in the way they would appear in the file manager |             // is usually quite random so we sort the notes in the way they would appear in the file manager | ||||||
|             treeService.sortNotesAlphabetically(noteId, true); |             treeService.sortNotesByTitle(noteId, true); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         taskContext.increaseProgressCount(); |         taskContext.increaseProgressCount(); | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user