Merge branch 'Highlighted-Text' of https://github.com/SiriusXT/trilium into Highlighted-Text

This commit is contained in:
SiriusXT 2023-06-03 11:55:59 +08:00
commit 463d145cb7
43 changed files with 2131 additions and 819 deletions

View File

@ -991,7 +991,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -1904,7 +1904,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -1916,7 +1916,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -1461,7 +1461,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

File diff suppressed because it is too large Load Diff

View File

@ -2174,7 +2174,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -267,7 +267,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="becca_entities_boption.js.html">becca/entities/boption.js</a>, <a href="becca_entities_boption.js.html#line24">line 24</a> <a href="becca_entities_boption.js.html">becca/entities/boption.js</a>, <a href="becca_entities_boption.js.html#line29">line 29</a>
</li></ul></dd> </li></ul></dd>
@ -335,7 +335,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="becca_entities_boption.js.html">becca/entities/boption.js</a>, <a href="becca_entities_boption.js.html#line20">line 20</a> <a href="becca_entities_boption.js.html">becca/entities/boption.js</a>, <a href="becca_entities_boption.js.html#line25">line 25</a>
</li></ul></dd> </li></ul></dd>
@ -403,7 +403,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="becca_entities_boption.js.html">becca/entities/boption.js</a>, <a href="becca_entities_boption.js.html#line26">line 26</a> <a href="becca_entities_boption.js.html">becca/entities/boption.js</a>, <a href="becca_entities_boption.js.html#line31">line 31</a>
</li></ul></dd> </li></ul></dd>
@ -471,7 +471,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="becca_entities_boption.js.html">becca/entities/boption.js</a>, <a href="becca_entities_boption.js.html#line22">line 22</a> <a href="becca_entities_boption.js.html">becca/entities/boption.js</a>, <a href="becca_entities_boption.js.html#line27">line 27</a>
</li></ul></dd> </li></ul></dd>
@ -1319,7 +1319,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -1251,7 +1251,7 @@ This is a low level method, for notes and branches use `note.deleteNote()` and '
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -3254,7 +3254,7 @@ JSON MIME type. See also createNewNote() for more options.
<h4 class="name" id="ensureNoteIsPresentInParent"><span class="type-signature"></span>ensureNoteIsPresentInParent<span class="signature">(noteId, parentNoteId, prefix)</span><span class="type-signature"> &rarr; {void}</span></h4> <h4 class="name" id="ensureNoteIsPresentInParent"><span class="type-signature"></span>ensureNoteIsPresentInParent<span class="signature">(noteId, parentNoteId, prefix)</span><span class="type-signature"> &rarr; {Object}</span></h4>
@ -3262,7 +3262,7 @@ JSON MIME type. See also createNewNote() for more options.
<div class="description"> <div class="description">
If there's no branch between note and parent note, create one. Otherwise, do nothing. If there's no branch between note and parent note, create one. Otherwise, do nothing. Returns the new or existing branch.
</div> </div>
@ -3437,7 +3437,7 @@ JSON MIME type. See also createNewNote() for more options.
</dt> </dt>
<dd> <dd>
<span class="param-type">void</span> <span class="param-type">Object</span>
</dd> </dd>
@ -7889,7 +7889,7 @@ exists, then we'll use that transaction.
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -212,7 +212,7 @@ module.exports = AbstractBeccaEntity;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -124,7 +124,7 @@ class BAttribute extends AbstractBeccaEntity {
} }
if (this.type === 'relation' &amp;&amp; !(this.value in this.becca.notes)) { if (this.type === 'relation' &amp;&amp; !(this.value in this.becca.notes)) {
throw new Error(`Cannot save relation '${this.name}' of note '${this.noteId}' since it target not existing note '${this.value}'.`); throw new Error(`Cannot save relation '${this.name}' of note '${this.noteId}' since it targets not existing note '${this.value}'.`);
} }
} }
@ -276,7 +276,7 @@ module.exports = BAttribute;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -319,7 +319,7 @@ module.exports = BBranch;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -120,7 +120,7 @@ module.exports = BEtapiToken;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -125,7 +125,7 @@ class BNote extends AbstractBeccaEntity {
* @private */ * @private */
this.parents = []; this.parents = [];
/** @type {BNote[]} /** @type {BNote[]}
* @private*/ * @private */
this.children = []; this.children = [];
/** @type {BAttribute[]} /** @type {BAttribute[]}
* @private */ * @private */
@ -135,11 +135,11 @@ class BNote extends AbstractBeccaEntity {
* @private */ * @private */
this.__attributeCache = null; this.__attributeCache = null;
/** @type {BAttribute[]|null} /** @type {BAttribute[]|null}
* @private*/ * @private */
this.inheritableAttributeCache = null; this.inheritableAttributeCache = null;
/** @type {BAttribute[]} /** @type {BAttribute[]}
* @private*/ * @private */
this.targetRelations = []; this.targetRelations = [];
this.becca.addNote(this.noteId, this); this.becca.addNote(this.noteId, this);
@ -560,6 +560,20 @@ class BNote extends AbstractBeccaEntity {
*/ */
hasLabel(name, value) { return this.hasAttribute(LABEL, name, value); } hasLabel(name, value) { return this.hasAttribute(LABEL, name, value); }
/**
* @param {string} name - label name
* @returns {boolean} true if label exists (including inherited) and does not have "false" value.
*/
isLabelTruthy(name) {
const label = this.getLabel(name);
if (!label) {
return false;
}
return label &amp;&amp; label.value !== 'false';
}
/** /**
* @param {string} name - label name * @param {string} name - label name
* @param {string} [value] - label value * @param {string} [value] - label value
@ -761,6 +775,21 @@ class BNote extends AbstractBeccaEntity {
return this.hasAttribute('label', 'archived'); return this.hasAttribute('label', 'archived');
} }
areAllNotePathsArchived() {
// there's a slight difference between note being itself archived and all its note paths being archived
// - note is archived when it itself has an archived label or inherits it
// - note does not have or inherit archived label, but each note paths contains a note with (non-inheritable)
// archived label
const bestNotePathRecord = this.getSortedNotePathRecords()[0];
if (!bestNotePathRecord) {
throw new Error(`No note path available for note '${this.noteId}'`);
}
return bestNotePathRecord.isArchived;
}
hasInheritableArchivedLabel() { hasInheritableArchivedLabel() {
for (const attr of this.getAttributes()) { for (const attr of this.getAttributes()) {
if (attr.name === 'archived' &amp;&amp; attr.type === LABEL &amp;&amp; attr.isInheritable) { if (attr.name === 'archived' &amp;&amp; attr.type === LABEL &amp;&amp; attr.isInheritable) {
@ -1164,6 +1193,8 @@ class BNote extends AbstractBeccaEntity {
} }
/** /**
* Gives all possible note paths leading to this note. Paths containing search note are ignored (could form cycles)
*
* @returns {string[][]} - array of notePaths (each represented by array of noteIds constituting the particular note path) * @returns {string[][]} - array of notePaths (each represented by array of noteIds constituting the particular note path)
*/ */
getAllNotePaths() { getAllNotePaths() {
@ -1171,18 +1202,73 @@ class BNote extends AbstractBeccaEntity {
return [['root']]; return [['root']];
} }
const notePaths = []; const parentNotes = this.getParentNotes();
let notePaths = [];
for (const parentNote of this.getParentNotes()) { if (parentNotes.length === 1) { // optimization for most common case
for (const parentPath of parentNote.getAllNotePaths()) { notePaths = parentNotes[0].getAllNotePaths();
parentPath.push(this.noteId); } else {
notePaths.push(parentPath); notePaths = parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
} }
for (const notePath of notePaths) {
notePath.push(this.noteId);
} }
return notePaths; return notePaths;
} }
/**
* @param {string} [hoistedNoteId='root']
* @return {Array&lt;{isArchived: boolean, isInHoistedSubTree: boolean, notePath: Array&lt;string>, isHidden: boolean}>}
*/
getSortedNotePathRecords(hoistedNoteId = 'root') {
const isHoistedRoot = hoistedNoteId === 'root';
const notePaths = this.getAllNotePaths().map(path => ({
notePath: path,
isInHoistedSubTree: isHoistedRoot || path.includes(hoistedNoteId),
isArchived: path.some(noteId => this.becca.notes[noteId].isArchived),
isHidden: path.includes('_hidden')
}));
notePaths.sort((a, b) => {
if (a.isInHoistedSubTree !== b.isInHoistedSubTree) {
return a.isInHoistedSubTree ? -1 : 1;
} else if (a.isArchived !== b.isArchived) {
return a.isArchived ? 1 : -1;
} else if (a.isHidden !== b.isHidden) {
return a.isHidden ? 1 : -1;
} else {
return a.notePath.length - b.notePath.length;
}
});
return notePaths;
}
/**
* Returns note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @return {string[]} array of noteIds constituting the particular note path
*/
getBestNotePath(hoistedNoteId = 'root') {
return this.getSortedNotePathRecords(hoistedNoteId)[0]?.notePath;
}
/**
* Returns note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @return {string} serialized note path (e.g. 'root/a1h315/js725h')
*/
getBestNotePathString(hoistedNoteId = 'root') {
const notePath = this.getBestNotePath(hoistedNoteId);
return notePath?.join("/");
}
/** /**
* @return boolean - true if there's no non-hidden path, note is not cloned to the visible tree * @return boolean - true if there's no non-hidden path, note is not cloned to the visible tree
*/ */
@ -1196,9 +1282,7 @@ class BNote extends AbstractBeccaEntity {
return false; return false;
} else if (parentNote.noteId === '_hidden') { } else if (parentNote.noteId === '_hidden') {
continue; continue;
} } else if (!parentNote.isHiddenCompletely()) {
if (!parentNote.isHiddenCompletely()) {
return false; return false;
} }
} }
@ -1392,7 +1476,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param parentNoteId * @param parentNoteId
* @returns {{success: boolean, message: string}} * @returns {{success: boolean, message: string, branchId: string, notePath: string}}
*/ */
cloneTo(parentNoteId) { cloneTo(parentNoteId) {
const cloningService = require("../../services/cloning"); const cloningService = require("../../services/cloning");
@ -1550,7 +1634,7 @@ module.exports = BNote;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -194,12 +194,14 @@ class BNoteRevision extends AbstractBeccaEntity {
utcDateLastEdited: this.utcDateLastEdited, utcDateLastEdited: this.utcDateLastEdited,
utcDateCreated: this.utcDateCreated, utcDateCreated: this.utcDateCreated,
utcDateModified: this.utcDateModified, utcDateModified: this.utcDateModified,
content: this.content, // used when retrieving full note revision to frontend
contentLength: this.contentLength contentLength: this.contentLength
}; };
} }
getPojoToSave() { getPojoToSave() {
const pojo = this.getPojo(); const pojo = this.getPojo();
delete pojo.content; // not getting persisted
delete pojo.contentLength; // not getting persisted delete pojo.contentLength; // not getting persisted
if (pojo.isProtected) { if (pojo.isProtected) {
@ -233,7 +235,7 @@ module.exports = BNoteRevision;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -44,6 +44,11 @@ class BOption extends AbstractBeccaEntity {
constructor(row) { constructor(row) {
super(); super();
this.updateFromRow(row);
this.becca.options[this.name] = this;
}
updateFromRow(row) {
/** @type {string} */ /** @type {string} */
this.name = row.name; this.name = row.name;
/** @type {string} */ /** @type {string} */
@ -52,8 +57,6 @@ class BOption extends AbstractBeccaEntity {
this.isSynced = !!row.isSynced; this.isSynced = !!row.isSynced;
/** @type {string} */ /** @type {string} */
this.utcDateModified = row.utcDateModified; this.utcDateModified = row.utcDateModified;
this.becca.options[this.name] = this;
} }
beforeSaving() { beforeSaving() {
@ -89,7 +92,7 @@ module.exports = BOption;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -77,7 +77,7 @@ module.exports = BRecentNote;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -56,7 +56,7 @@
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -1300,7 +1300,7 @@
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -165,13 +165,13 @@ function BackendScriptApi(currentNote, apiParams) {
this.getNoteWithLabel = attributeService.getNoteWithLabel; this.getNoteWithLabel = attributeService.getNoteWithLabel;
/** /**
* If there's no branch between note and parent note, create one. Otherwise, do nothing. * If there's no branch between note and parent note, create one. Otherwise, do nothing. Returns the new or existing branch.
* *
* @method * @method
* @param {string} noteId * @param {string} noteId
* @param {string} parentNoteId * @param {string} parentNoteId
* @param {string} prefix - if branch will be created between note and parent note, set this prefix * @param {string} prefix - if branch will be created between note and parent note, set this prefix
* @returns {void} * @returns {{branch: BBranch|null}}
*/ */
this.ensureNoteIsPresentInParent = cloningService.ensureNoteIsPresentInParent; this.ensureNoteIsPresentInParent = cloningService.ensureNoteIsPresentInParent;
@ -499,11 +499,11 @@ function BackendScriptApi(currentNote, apiParams) {
if (opts.type === 'script' &amp;&amp; !opts.scriptNoteId) { throw new Error("scriptNoteId is mandatory for launchers of type 'script'"); } if (opts.type === 'script' &amp;&amp; !opts.scriptNoteId) { throw new Error("scriptNoteId is mandatory for launchers of type 'script'"); }
if (opts.type === 'customWidget' &amp;&amp; !opts.widgetNoteId) { throw new Error("widgetNoteId is mandatory for launchers of type 'customWidget'"); } if (opts.type === 'customWidget' &amp;&amp; !opts.widgetNoteId) { throw new Error("widgetNoteId is mandatory for launchers of type 'customWidget'"); }
const parentNoteId = !!opts.isVisible ? '_lbVisibleLaunchers' : '_lbAvailableLaunchers'; const parentNoteId = opts.isVisible ? '_lbVisibleLaunchers' : '_lbAvailableLaunchers';
const noteId = 'al_' + opts.id; const noteId = 'al_' + opts.id;
const launcherNote = const launcherNote =
becca.getNote(opts.id) || becca.getNote(noteId) ||
specialNotesService.createLauncher({ specialNotesService.createLauncher({
noteId: noteId, noteId: noteId,
parentNoteId: parentNoteId, parentNoteId: parentNoteId,
@ -542,7 +542,7 @@ function BackendScriptApi(currentNote, apiParams) {
if (opts.icon) { if (opts.icon) {
launcherNote.setLabel('iconClass', `bx ${opts.icon}`); launcherNote.setLabel('iconClass', `bx ${opts.icon}`);
} else { } else {
launcherNote.removeLabel('keyboardShortcut'); launcherNote.removeLabel('iconClass');
} }
return {note: launcherNote}; return {note: launcherNote};
@ -584,7 +584,7 @@ module.exports = BackendScriptApi;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -245,7 +245,7 @@ function wrap(query, func) {
// in these cases error should be simply ignored. // in these cases error should be simply ignored.
console.log(e.message); console.log(e.message);
return null return null;
} }
throw e; throw e;
@ -309,7 +309,7 @@ function fillParamList(paramIds, truncate = true) {
} }
// doing it manually to avoid this showing up on the sloq query list // doing it manually to avoid this showing up on the sloq query list
const s = stmt(`INSERT INTO param_list VALUES ${paramIds.map(paramId => `(?)`).join(',')}`, paramIds); const s = stmt(`INSERT INTO param_list VALUES ${paramIds.map(paramId => `(?)`).join(',')}`);
s.run(paramIds); s.run(paramIds);
} }
@ -413,7 +413,7 @@ module.exports = {
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -850,7 +850,7 @@ and relation (representing named relationship between source and target note)</d
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -1062,7 +1062,7 @@ parents.</div>
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

File diff suppressed because it is too large Load Diff

View File

@ -781,7 +781,7 @@
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -342,115 +342,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#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#line45">line 45</a>
</li></ul></dd>
</dl>
<h4 class="name" id="CollapsibleWidget"><span class="type-signature"></span>CollapsibleWidget<span class="type-signature"></span></h4>
<h5 class="subsection-title">Properties:</h5>
<table class="props">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
<span class="param-type">RightPanelWidget</span>
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="important tag-deprecated">Deprecated:</dt><dd><ul class="dummy"><li>use api.RightPanelWidget instead</li></ul></dd>
<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#line42">line 42</a>
</li></ul></dd> </li></ul></dd>
@ -556,115 +448,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line48">line 48</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>
</dl>
<h4 class="name" id="NoteContextCachingWidget"><span class="type-signature"></span>NoteContextCachingWidget<span class="type-signature"></span></h4>
<h5 class="subsection-title">Properties:</h5>
<table class="props">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
<span class="param-type">NoteContextAwareWidget</span>
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="important tag-deprecated">Deprecated:</dt><dd><ul class="dummy"><li>use NoteContextAwareWidget instead</li></ul></dd>
<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#line66">line 66</a>
</li></ul></dd> </li></ul></dd>
@ -770,223 +554,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line45">line 45</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>
</dl>
<h4 class="name" id="TabAwareWidget"><span class="type-signature"></span>TabAwareWidget<span class="type-signature"></span></h4>
<h5 class="subsection-title">Properties:</h5>
<table class="props">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
<span class="param-type">NoteContextAwareWidget</span>
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="important tag-deprecated">Deprecated:</dt><dd><ul class="dummy"><li>use NoteContextAwareWidget instead</li></ul></dd>
<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#line54">line 54</a>
</li></ul></dd>
</dl>
<h4 class="name" id="TabCachingWidget"><span class="type-signature"></span>TabCachingWidget<span class="type-signature"></span></h4>
<h5 class="subsection-title">Properties:</h5>
<table class="props">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
<span class="param-type">NoteContextAwareWidget</span>
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="important tag-deprecated">Deprecated:</dt><dd><ul class="dummy"><li>use NoteContextAwareWidget instead</li></ul></dd>
<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#line60">line 60</a>
</li></ul></dd> </li></ul></dd>
@ -1558,7 +1126,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line88">line 88</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line64">line 64</a>
</li></ul></dd> </li></ul></dd>
@ -1713,7 +1281,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line78">line 78</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line54">line 54</a>
</li></ul></dd> </li></ul></dd>
@ -2054,7 +1622,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line148">line 148</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line124">line 124</a>
</li></ul></dd> </li></ul></dd>
@ -2191,7 +1759,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line337">line 337</a> <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>
</li></ul></dd> </li></ul></dd>
@ -2399,7 +1967,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line479">line 479</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line455">line 455</a>
</li></ul></dd> </li></ul></dd>
@ -2781,7 +2349,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line329">line 329</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line305">line 305</a>
</li></ul></dd> </li></ul></dd>
@ -2914,7 +2482,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line275">line 275</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line251">line 251</a>
</li></ul></dd> </li></ul></dd>
@ -3024,7 +2592,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line359">line 359</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line335">line 335</a>
</li></ul></dd> </li></ul></dd>
@ -3130,7 +2698,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line343">line 343</a> <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>
</li></ul></dd> </li></ul></dd>
@ -3236,7 +2804,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line374">line 374</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line350">line 350</a>
</li></ul></dd> </li></ul></dd>
@ -3346,7 +2914,7 @@ available in the JS frontend notes. You can use e.g. <code>api.showMessage(api.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#line351">line 351</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line327">line 327</a>
</li></ul></dd> </li></ul></dd>
@ -3457,7 +3025,7 @@ implementation of actual widget type.
<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#line368">line 368</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line344">line 344</a>
</li></ul></dd> </li></ul></dd>
@ -3612,7 +3180,7 @@ implementation of actual widget type.
<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#line383">line 383</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line359">line 359</a>
</li></ul></dd> </li></ul></dd>
@ -3767,7 +3335,7 @@ implementation of actual widget type.
<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#line427">line 427</a> <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>
</li></ul></dd> </li></ul></dd>
@ -3874,7 +3442,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#line268">line 268</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line244">line 244</a>
</li></ul></dd> </li></ul></dd>
@ -4029,7 +3597,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#line445">line 445</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line421">line 421</a>
</li></ul></dd> </li></ul></dd>
@ -4185,7 +3753,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#line238">line 238</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line214">line 214</a>
</li></ul></dd> </li></ul></dd>
@ -4386,7 +3954,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#line251">line 251</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line227">line 227</a>
</li></ul></dd> </li></ul></dd>
@ -4492,7 +4060,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#line418">line 418</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line394">line 394</a>
</li></ul></dd> </li></ul></dd>
@ -4647,7 +4215,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#line436">line 436</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line412">line 412</a>
</li></ul></dd> </li></ul></dd>
@ -4802,7 +4370,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#line454">line 454</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line430">line 430</a>
</li></ul></dd> </li></ul></dd>
@ -4952,7 +4520,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#line519">line 519</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line495">line 495</a>
</li></ul></dd> </li></ul></dd>
@ -5130,7 +4698,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#line121">line 121</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line97">line 97</a>
</li></ul></dd> </li></ul></dd>
@ -5308,7 +4876,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#line103">line 103</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line79">line 79</a>
</li></ul></dd> </li></ul></dd>
@ -5459,7 +5027,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#line282">line 282</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line258">line 258</a>
</li></ul></dd> </li></ul></dd>
@ -5637,7 +5205,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#line398">line 398</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line374">line 374</a>
</li></ul></dd> </li></ul></dd>
@ -5811,7 +5379,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#line408">line 408</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line384">line 384</a>
</li></ul></dd> </li></ul></dd>
@ -5966,7 +5534,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#line508">line 508</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line484">line 484</a>
</li></ul></dd> </li></ul></dd>
@ -6120,7 +5688,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#line499">line 499</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line475">line 475</a>
</li></ul></dd> </li></ul></dd>
@ -6275,7 +5843,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#line259">line 259</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line235">line 235</a>
</li></ul></dd> </li></ul></dd>
@ -6436,7 +6004,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#line181">line 181</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line157">line 157</a>
</li></ul></dd> </li></ul></dd>
@ -6596,7 +6164,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#line225">line 225</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line201">line 201</a>
</li></ul></dd> </li></ul></dd>
@ -6752,7 +6320,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#line213">line 213</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line189">line 189</a>
</li></ul></dd> </li></ul></dd>
@ -6907,7 +6475,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#line463">line 463</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line439">line 439</a>
</li></ul></dd> </li></ul></dd>
@ -7058,7 +6626,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#line390">line 390</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line366">line 366</a>
</li></ul></dd> </li></ul></dd>
@ -7213,7 +6781,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#line298">line 298</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line274">line 274</a>
</li></ul></dd> </li></ul></dd>
@ -7350,7 +6918,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#line290">line 290</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line266">line 266</a>
</li></ul></dd> </li></ul></dd>
@ -7510,7 +7078,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#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#line283">line 283</a>
</li></ul></dd> </li></ul></dd>
@ -7670,7 +7238,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#line316">line 316</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line292">line 292</a>
</li></ul></dd> </li></ul></dd>
@ -7762,7 +7330,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#line491">line 491</a> <a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line467">line 467</a>
</li></ul></dd> </li></ul></dd>
@ -7832,7 +7400,7 @@ Typical use case is when new note has been created, we should wait until it is s
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -121,7 +121,7 @@ export default FAttribute;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -105,7 +105,7 @@ export default FBranch;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -101,7 +101,7 @@ class FNote {
this.mime = row.mime; this.mime = row.mime;
} }
addParent(parentNoteId, branchId) { addParent(parentNoteId, branchId, sort = true) {
if (parentNoteId === 'none') { if (parentNoteId === 'none') {
return; return;
} }
@ -111,6 +111,10 @@ class FNote {
} }
this.parentToBranch[parentNoteId] = branchId; this.parentToBranch[parentNoteId] = branchId;
if (sort) {
this.sortParents();
}
} }
addChild(childNoteId, branchId, sort = true) { addChild(childNoteId, branchId, sort = true) {
@ -217,7 +221,7 @@ class FNote {
// will sort the parents so that non-search &amp; non-archived are first and archived at the end // will sort the parents so that non-search &amp; non-archived are first and archived at the end
// this is done so that non-search &amp; non-archived paths are always explored as first when looking for note path // this is done so that non-search &amp; non-archived paths are always explored as first when looking for note path
resortParents() { sortParents() {
this.parents.sort((aNoteId, bNoteId) => { this.parents.sort((aNoteId, bNoteId) => {
const aBranchId = this.parentToBranch[aNoteId]; const aBranchId = this.parentToBranch[aNoteId];
@ -225,7 +229,7 @@ class FNote {
return 1; return 1;
} }
const aNote = this.froca.getNoteFromCache([aNoteId]); const aNote = this.froca.getNoteFromCache(aNoteId);
if (aNote.isArchived || aNote.isHiddenCompletely()) { if (aNote.isArchived || aNote.isHiddenCompletely()) {
return 1; return 1;
@ -271,6 +275,11 @@ class FNote {
return this.__filterAttrs(this.__getCachedAttributes([]), type, name); return this.__filterAttrs(this.__getCachedAttributes([]), type, name);
} }
/**
* @param {string[]} path
* @return {FAttribute[]}
* @private
*/
__getCachedAttributes(path) { __getCachedAttributes(path) {
// notes/clones cannot form tree cycles, it is possible to create attribute inheritance cycle via templates // notes/clones cannot form tree cycles, it is possible to create attribute inheritance cycle via templates
// when template instance is a parent of template itself // when template instance is a parent of template itself
@ -323,63 +332,49 @@ class FNote {
return this.noteId === 'root'; return this.noteId === 'root';
} }
getAllNotePaths(encounteredNoteIds = null) { /**
* Gives all possible note paths leading to this note. Paths containing search note are ignored (could form cycles)
*
* @returns {string[][]} - array of notePaths (each represented by array of noteIds constituting the particular note path)
*/
getAllNotePaths() {
if (this.noteId === 'root') { if (this.noteId === 'root') {
return [['root']]; return [['root']];
} }
if (!encounteredNoteIds) { const parentNotes = this.getParentNotes().filter(note => note.type !== 'search');
encounteredNoteIds = new Set(); let notePaths = [];
if (parentNotes.length === 1) { // optimization for most common case
notePaths = parentNotes[0].getAllNotePaths();
} else {
notePaths = parentNotes.flatMap(parentNote => parentNote.getAllNotePaths());
} }
encounteredNoteIds.add(this.noteId); for (const notePath of notePaths) {
notePath.push(this.noteId);
const parentNotes = this.getParentNotes();
let paths;
if (parentNotes.length === 1) { // optimization for the most common case
if (encounteredNoteIds.has(parentNotes[0].noteId)) {
return [];
}
else {
paths = parentNotes[0].getAllNotePaths(encounteredNoteIds);
}
}
else {
paths = [];
for (const parentNote of parentNotes) {
if (encounteredNoteIds.has(parentNote.noteId)) {
continue;
}
const newSet = new Set(encounteredNoteIds);
paths.push(...parentNote.getAllNotePaths(newSet));
}
} }
for (const path of paths) { return notePaths;
path.push(this.noteId);
}
return paths;
} }
getSortedNotePaths(hoistedNotePath = 'root') { /**
* @param {string} [hoistedNoteId='root']
* @return {Array&lt;{isArchived: boolean, isInHoistedSubTree: boolean, notePath: Array&lt;string>, isHidden: boolean}>}
*/
getSortedNotePathRecords(hoistedNoteId = 'root') {
const isHoistedRoot = hoistedNoteId === 'root';
const notePaths = this.getAllNotePaths().map(path => ({ const notePaths = this.getAllNotePaths().map(path => ({
notePath: path, notePath: path,
isInHoistedSubTree: path.includes(hoistedNotePath), isInHoistedSubTree: isHoistedRoot || path.includes(hoistedNoteId),
isArchived: path.find(noteId => froca.notes[noteId].isArchived), isArchived: path.some(noteId => froca.notes[noteId].isArchived),
isSearch: path.find(noteId => froca.notes[noteId].type === 'search'),
isHidden: path.includes('_hidden') isHidden: path.includes('_hidden')
})); }));
notePaths.sort((a, b) => { notePaths.sort((a, b) => {
if (a.isInHoistedSubTree !== b.isInHoistedSubTree) { if (a.isInHoistedSubTree !== b.isInHoistedSubTree) {
return a.isInHoistedSubTree ? -1 : 1; return a.isInHoistedSubTree ? -1 : 1;
} else if (a.isSearch !== b.isSearch) {
return a.isSearch ? 1 : -1;
} else if (a.isArchived !== b.isArchived) { } else if (a.isArchived !== b.isArchived) {
return a.isArchived ? 1 : -1; return a.isArchived ? 1 : -1;
} else if (a.isHidden !== b.isHidden) { } else if (a.isHidden !== b.isHidden) {
@ -392,6 +387,28 @@ class FNote {
return notePaths; return notePaths;
} }
/**
* Returns note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @return {string[]} array of noteIds constituting the particular note path
*/
getBestNotePath(hoistedNoteId = 'root') {
return this.getSortedNotePathRecords(hoistedNoteId)[0]?.notePath;
}
/**
* Returns note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @return {string} serialized note path (e.g. 'root/a1h315/js725h')
*/
getBestNotePathString(hoistedNoteId = 'root') {
const notePath = this.getBestNotePath(hoistedNoteId);
return notePath?.join("/");
}
/** /**
* @return boolean - true if there's no non-hidden path, note is not cloned to the visible tree * @return boolean - true if there's no non-hidden path, note is not cloned to the visible tree
*/ */
@ -403,7 +420,7 @@ class FNote {
for (const parentNote of this.getParentNotes()) { for (const parentNote of this.getParentNotes()) {
if (parentNote.noteId === 'root') { if (parentNote.noteId === 'root') {
return false; return false;
} else if (parentNote.noteId === '_hidden') { } else if (parentNote.noteId === '_hidden' || parentNote.type === 'search') {
continue; continue;
} }
@ -415,6 +432,13 @@ class FNote {
return true; return true;
} }
/**
* @param {FAttribute[]} attributes
* @param {string} type
* @param {string} name
* @return {FAttribute[]}
* @private
*/
__filterAttrs(attributes, type, name) { __filterAttrs(attributes, type, name) {
this.__validateTypeName(type, name); this.__validateTypeName(type, name);
@ -551,7 +575,9 @@ class FNote {
* @returns {boolean} true if note has an attribute with given type and name (including inherited) * @returns {boolean} true if note has an attribute with given type and name (including inherited)
*/ */
hasAttribute(type, name) { hasAttribute(type, name) {
return !!this.getAttribute(type, name); const attributes = this.getAttributes();
return attributes.some(attr => attr.name === name &amp;&amp; attr.type === type);
} }
/** /**
@ -619,6 +645,20 @@ class FNote {
*/ */
hasLabel(name) { return this.hasAttribute(LABEL, name); } hasLabel(name) { return this.hasAttribute(LABEL, name); }
/**
* @param {string} name - label name
* @returns {boolean} true if label exists (including inherited) and does not have "false" value.
*/
isLabelTruthy(name) {
const label = this.getLabel(name);
if (!label) {
return false;
}
return label &amp;&amp; label.value !== 'false';
}
/** /**
* @param {string} name - relation name * @param {string} name - relation name
* @returns {boolean} true if relation exists (excluding inherited) * @returns {boolean} true if relation exists (excluding inherited)
@ -730,7 +770,14 @@ class FNote {
}); });
// attrs are not resorted if position changes after initial load // attrs are not resorted if position changes after initial load
promotedAttrs.sort((a, b) => a.position &lt; b.position ? -1 : 1); promotedAttrs.sort((a, b) => {
if (a.noteId === b.noteId) {
return a.position &lt; b.position ? -1 : 1;
} else {
// inherited promoted attributes should stay grouped: https://github.com/zadam/trilium/issues/3761
return a.noteId &lt; b.noteId ? -1 : 1;
}
});
return promotedAttrs; return promotedAttrs;
} }
@ -930,7 +977,7 @@ export default FNote;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -82,7 +82,7 @@ export default FNoteComplement;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -56,7 +56,7 @@
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

View File

@ -63,36 +63,12 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/** @property {dayjs} day.js library for date manipulation. See {@link https://day.js.org} for documentation */ /** @property {dayjs} day.js library for date manipulation. See {@link https://day.js.org} for documentation */
this.dayjs = dayjs; this.dayjs = dayjs;
/**
* @property {RightPanelWidget}
* @deprecated use api.RightPanelWidget instead
*/
this.CollapsibleWidget = RightPanelWidget;
/** @property {RightPanelWidget} */ /** @property {RightPanelWidget} */
this.RightPanelWidget = RightPanelWidget; this.RightPanelWidget = RightPanelWidget;
/** @property {NoteContextAwareWidget} */ /** @property {NoteContextAwareWidget} */
this.NoteContextAwareWidget = NoteContextAwareWidget; this.NoteContextAwareWidget = NoteContextAwareWidget;
/**
* @property {NoteContextAwareWidget}
* @deprecated use NoteContextAwareWidget instead
*/
this.TabAwareWidget = NoteContextAwareWidget;
/**
* @property {NoteContextAwareWidget}
* @deprecated use NoteContextAwareWidget instead
*/
this.TabCachingWidget = NoteContextAwareWidget;
/**
* @property {NoteContextAwareWidget}
* @deprecated use NoteContextAwareWidget instead
*/
this.NoteContextCachingWidget = NoteContextAwareWidget;
/** @property {BasicWidget} */ /** @property {BasicWidget} */
this.BasicWidget = BasicWidget; this.BasicWidget = BasicWidget;
@ -117,7 +93,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
await ws.waitForMaxKnownEntityChangeId(); await ws.waitForMaxKnownEntityChangeId();
await appContext.tabManager.getActiveContext().setNote(notePath); await appContext.tabManager.getActiveContext().setNote(notePath);
appContext.triggerEvent('focusAndSelectTitle'); await appContext.triggerEvent('focusAndSelectTitle');
}; };
/** /**
@ -134,7 +110,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
await appContext.tabManager.openContextWithNote(notePath, { activate }); await appContext.tabManager.openContextWithNote(notePath, { activate });
if (activate) { if (activate) {
appContext.triggerEvent('focusAndSelectTitle'); await appContext.triggerEvent('focusAndSelectTitle');
} }
}; };
@ -152,10 +128,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
const subContexts = appContext.tabManager.getActiveContext().getSubContexts(); const subContexts = appContext.tabManager.getActiveContext().getSubContexts();
const {ntxId} = subContexts[subContexts.length - 1]; const {ntxId} = subContexts[subContexts.length - 1];
appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath}); await appContext.triggerCommand("openNewNoteSplit", {ntxId, notePath});
if (activate) { if (activate) {
appContext.triggerEvent('focusAndSelectTitle'); await appContext.triggerEvent('focusAndSelectTitle');
} }
}; };
@ -581,7 +557,7 @@ export default FrontendScriptApi;
<br class="clear"> <br class="clear">
<footer> <footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.1</a> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a>
</footer> </footer>
<script> prettyPrint(); </script> <script> prettyPrint(); </script>

14
package-lock.json generated
View File

@ -12,7 +12,7 @@
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "6.0.2", "@braintree/sanitize-url": "6.0.2",
"@electron/remote": "2.0.9", "@electron/remote": "2.0.9",
"@excalidraw/excalidraw": "0.15.2", "@excalidraw/excalidraw": "0.14.2",
"archiver": "5.3.1", "archiver": "5.3.1",
"async-mutex": "0.4.0", "async-mutex": "0.4.0",
"axios": "1.4.0", "axios": "1.4.0",
@ -462,9 +462,9 @@
} }
}, },
"node_modules/@excalidraw/excalidraw": { "node_modules/@excalidraw/excalidraw": {
"version": "0.15.2", "version": "0.14.2",
"resolved": "https://registry.npmjs.org/@excalidraw/excalidraw/-/excalidraw-0.15.2.tgz", "resolved": "https://registry.npmjs.org/@excalidraw/excalidraw/-/excalidraw-0.14.2.tgz",
"integrity": "sha512-rTI02kgWSTXiUdIkBxt9u/581F3eXcqQgJdIxmz54TFtG3ughoxO5fr4t7Fr2LZIturBPqfocQHGKZ0t2KLKgw==", "integrity": "sha512-8LdjpTBWEK5waDWB7Bt/G9YBI4j0OxkstUhvaDGz7dwQGfzF6FW5CXBoYHNEoX0qmb+Fg/NPOlZ7FrKsrSVCqg==",
"peerDependencies": { "peerDependencies": {
"react": "^17.0.2 || ^18.2.0", "react": "^17.0.2 || ^18.2.0",
"react-dom": "^17.0.2 || ^18.2.0" "react-dom": "^17.0.2 || ^18.2.0"
@ -13591,9 +13591,9 @@
"dev": true "dev": true
}, },
"@excalidraw/excalidraw": { "@excalidraw/excalidraw": {
"version": "0.15.2", "version": "0.14.2",
"resolved": "https://registry.npmjs.org/@excalidraw/excalidraw/-/excalidraw-0.15.2.tgz", "resolved": "https://registry.npmjs.org/@excalidraw/excalidraw/-/excalidraw-0.14.2.tgz",
"integrity": "sha512-rTI02kgWSTXiUdIkBxt9u/581F3eXcqQgJdIxmz54TFtG3ughoxO5fr4t7Fr2LZIturBPqfocQHGKZ0t2KLKgw==", "integrity": "sha512-8LdjpTBWEK5waDWB7Bt/G9YBI4j0OxkstUhvaDGz7dwQGfzF6FW5CXBoYHNEoX0qmb+Fg/NPOlZ7FrKsrSVCqg==",
"requires": {} "requires": {}
}, },
"@gar/promisify": { "@gar/promisify": {

View File

@ -33,7 +33,7 @@
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "6.0.2", "@braintree/sanitize-url": "6.0.2",
"@electron/remote": "2.0.9", "@electron/remote": "2.0.9",
"@excalidraw/excalidraw": "0.15.2", "@excalidraw/excalidraw": "0.14.2",
"archiver": "5.3.1", "archiver": "5.3.1",
"async-mutex": "0.4.0", "async-mutex": "0.4.0",
"axios": "1.4.0", "axios": "1.4.0",

View File

@ -69,18 +69,6 @@ function reload() {
require('../services/ws').reloadFrontend(); require('../services/ws').reloadFrontend();
} }
function postProcessEntityUpdate(entityName, entity) {
if (entityName === 'notes') {
noteUpdated(entity);
} else if (entityName === 'branches') {
branchUpdated(entity);
} else if (entityName === 'attributes') {
attributeUpdated(entity);
} else if (entityName === 'note_reordering') {
noteReorderingUpdated(entity);
}
}
eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED], ({entityName, entityRow}) => { eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED], ({entityName, entityRow}) => {
if (!becca.loaded) { if (!becca.loaded) {
return; return;
@ -112,6 +100,25 @@ eventService.subscribeBeccaLoader(eventService.ENTITY_CHANGED, ({entityName, en
postProcessEntityUpdate(entityName, entity); postProcessEntityUpdate(entityName, entity);
}); });
/**
* This gets run on entity being created or updated.
*
* @param entityName
* @param entityRow - can be a becca entity (change comes from this trilium instance) or just a row (from sync).
* Should be therefore treated as a row.
*/
function postProcessEntityUpdate(entityName, entityRow) {
if (entityName === 'notes') {
noteUpdated(entityRow);
} else if (entityName === 'branches') {
branchUpdated(entityRow);
} else if (entityName === 'attributes') {
attributeUpdated(entityRow);
} else if (entityName === 'note_reordering') {
noteReorderingUpdated(entityRow);
}
}
eventService.subscribeBeccaLoader([eventService.ENTITY_DELETED, eventService.ENTITY_DELETE_SYNCED], ({entityName, entityId}) => { eventService.subscribeBeccaLoader([eventService.ENTITY_DELETED, eventService.ENTITY_DELETE_SYNCED], ({entityName, entityId}) => {
if (!becca.loaded) { if (!becca.loaded) {
return; return;
@ -149,6 +156,7 @@ function branchDeleted(branchId) {
.filter(parentBranch => parentBranch.branchId !== branch.branchId); .filter(parentBranch => parentBranch.branchId !== branch.branchId);
if (childNote.parents.length > 0) { if (childNote.parents.length > 0) {
// subtree notes might lose some inherited attributes
childNote.invalidateSubTree(); childNote.invalidateSubTree();
} }
} }
@ -163,8 +171,8 @@ function branchDeleted(branchId) {
delete becca.branches[branch.branchId]; delete becca.branches[branch.branchId];
} }
function noteUpdated(entity) { function noteUpdated(entityRow) {
const note = becca.notes[entity.noteId]; const note = becca.notes[entityRow.noteId];
if (note) { if (note) {
// type / mime could have been changed, and they are present in flatTextCache // type / mime could have been changed, and they are present in flatTextCache
@ -172,15 +180,19 @@ function noteUpdated(entity) {
} }
} }
function branchUpdated(branch) { function branchUpdated(branchRow) {
const childNote = becca.notes[branch.noteId]; const childNote = becca.notes[branchRow.noteId];
if (childNote) { if (childNote) {
childNote.flatTextCache = null; childNote.flatTextCache = null;
childNote.sortParents(); childNote.sortParents();
// notes in the subtree can get new inherited attributes
// this is in theory needed upon branch creation, but there's no create event for sync changes
childNote.invalidateSubTree();
} }
const parentNote = becca.notes[branch.parentNoteId]; const parentNote = becca.notes[branchRow.parentNoteId];
if (parentNote) { if (parentNote) {
parentNote.sortChildren(); parentNote.sortChildren();
@ -222,8 +234,10 @@ function attributeDeleted(attributeId) {
} }
} }
function attributeUpdated(attribute) { /** @param {BAttribute} attributeRow */
const note = becca.notes[attribute.noteId]; function attributeUpdated(attributeRow) {
const attribute = becca.attributes[attributeRow.attributeId];
const note = becca.notes[attributeRow.noteId];
if (note) { if (note) {
if (attribute.isAffectingSubtree || note.isInherited()) { if (attribute.isAffectingSubtree || note.isInherited()) {

View File

@ -12,6 +12,7 @@ const TaskContext = require("../../services/task_context");
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const utc = require('dayjs/plugin/utc'); const utc = require('dayjs/plugin/utc');
const eventService = require("../../services/events"); const eventService = require("../../services/events");
const cls = require("../../services/cls.js");
dayjs.extend(utc); dayjs.extend(utc);
const LABEL = 'label'; const LABEL = 'label';
@ -84,7 +85,7 @@ class BNote extends AbstractBeccaEntity {
this.decrypt(); this.decrypt();
/** @type {string|null} */ /** @type {string|null} */
this.flatTextCache = null; this.__flatTextCache = null;
return this; return this;
} }
@ -108,7 +109,7 @@ class BNote extends AbstractBeccaEntity {
this.__attributeCache = null; this.__attributeCache = null;
/** @type {BAttribute[]|null} /** @type {BAttribute[]|null}
* @private */ * @private */
this.inheritableAttributeCache = null; this.__inheritableAttributeCache = null;
/** @type {BAttribute[]} /** @type {BAttribute[]}
* @private */ * @private */
@ -118,7 +119,7 @@ class BNote extends AbstractBeccaEntity {
/** @type {BNote[]|null} /** @type {BNote[]|null}
* @private */ * @private */
this.ancestorCache = null; this.__ancestorCache = null;
// following attributes are filled during searching from database // following attributes are filled during searching from database
@ -316,10 +317,12 @@ class BNote extends AbstractBeccaEntity {
isSynced: true isSynced: true
}); });
eventService.emit(eventService.ENTITY_CHANGED, { if (!cls.isEntityEventsDisabled()) {
entityName: 'note_contents', eventService.emit(eventService.ENTITY_CHANGED, {
entity: this entityName: 'note_contents',
}); entity: this
});
}
} }
setJsonContent(content) { setJsonContent(content) {
@ -454,11 +457,11 @@ class BNote extends AbstractBeccaEntity {
} }
} }
this.inheritableAttributeCache = []; this.__inheritableAttributeCache = [];
for (const attr of this.__attributeCache) { for (const attr of this.__attributeCache) {
if (attr.isInheritable) { if (attr.isInheritable) {
this.inheritableAttributeCache.push(attr); this.__inheritableAttributeCache.push(attr);
} }
} }
} }
@ -475,11 +478,11 @@ class BNote extends AbstractBeccaEntity {
return []; return [];
} }
if (!this.inheritableAttributeCache) { if (!this.__inheritableAttributeCache) {
this.__getAttributes(path); // will refresh also this.inheritableAttributeCache this.__getAttributes(path); // will refresh also this.__inheritableAttributeCache
} }
return this.inheritableAttributeCache; return this.__inheritableAttributeCache;
} }
__validateTypeName(type, name) { __validateTypeName(type, name) {
@ -813,40 +816,40 @@ class BNote extends AbstractBeccaEntity {
* @returns {string} - returns flattened textual representation of note, prefixes and attributes * @returns {string} - returns flattened textual representation of note, prefixes and attributes
*/ */
getFlatText() { getFlatText() {
if (!this.flatTextCache) { if (!this.__flatTextCache) {
this.flatTextCache = `${this.noteId} ${this.type} ${this.mime} `; this.__flatTextCache = `${this.noteId} ${this.type} ${this.mime} `;
for (const branch of this.parentBranches) { for (const branch of this.parentBranches) {
if (branch.prefix) { if (branch.prefix) {
this.flatTextCache += `${branch.prefix} `; this.__flatTextCache += `${branch.prefix} `;
} }
} }
this.flatTextCache += `${this.title} `; this.__flatTextCache += `${this.title} `;
for (const attr of this.getAttributes()) { for (const attr of this.getAttributes()) {
// it's best to use space as separator since spaces are filtered from the search string by the tokenization into words // it's best to use space as separator since spaces are filtered from the search string by the tokenization into words
this.flatTextCache += `${attr.type === 'label' ? '#' : '~'}${attr.name}`; this.__flatTextCache += `${attr.type === 'label' ? '#' : '~'}${attr.name}`;
if (attr.value) { if (attr.value) {
this.flatTextCache += `=${attr.value}`; this.__flatTextCache += `=${attr.value}`;
} }
this.flatTextCache += ' '; this.__flatTextCache += ' ';
} }
this.flatTextCache = utils.normalize(this.flatTextCache); this.__flatTextCache = utils.normalize(this.__flatTextCache);
} }
return this.flatTextCache; return this.__flatTextCache;
} }
invalidateThisCache() { invalidateThisCache() {
this.flatTextCache = null; this.__flatTextCache = null;
this.__attributeCache = null; this.__attributeCache = null;
this.inheritableAttributeCache = null; this.__inheritableAttributeCache = null;
this.ancestorCache = null; this.__ancestorCache = null;
} }
invalidateSubTree(path = []) { invalidateSubTree(path = []) {
@ -875,24 +878,6 @@ class BNote extends AbstractBeccaEntity {
} }
} }
invalidateSubtreeFlatText() {
this.flatTextCache = null;
for (const childNote of this.children) {
childNote.invalidateSubtreeFlatText();
}
for (const targetRelation of this.targetRelations) {
if (targetRelation.name === 'template' || targetRelation.name === 'inherit') {
const note = targetRelation.note;
if (note) {
note.invalidateSubtreeFlatText();
}
}
}
}
getRelationDefinitions() { getRelationDefinitions() {
return this.getLabels() return this.getLabels()
.filter(l => l.name.startsWith("relation:")); .filter(l => l.name.startsWith("relation:"));
@ -1083,28 +1068,28 @@ class BNote extends AbstractBeccaEntity {
/** @returns {BNote[]} */ /** @returns {BNote[]} */
getAncestors() { getAncestors() {
if (!this.ancestorCache) { if (!this.__ancestorCache) {
const noteIds = new Set(); const noteIds = new Set();
this.ancestorCache = []; this.__ancestorCache = [];
for (const parent of this.parents) { for (const parent of this.parents) {
if (noteIds.has(parent.noteId)) { if (noteIds.has(parent.noteId)) {
continue; continue;
} }
this.ancestorCache.push(parent); this.__ancestorCache.push(parent);
noteIds.add(parent.noteId); noteIds.add(parent.noteId);
for (const ancestorNote of parent.getAncestors()) { for (const ancestorNote of parent.getAncestors()) {
if (!noteIds.has(ancestorNote.noteId)) { if (!noteIds.has(ancestorNote.noteId)) {
this.ancestorCache.push(ancestorNote); this.__ancestorCache.push(ancestorNote);
noteIds.add(ancestorNote.noteId); noteIds.add(ancestorNote.noteId);
} }
} }
} }
} }
return this.ancestorCache; return this.__ancestorCache;
} }
/** @returns {boolean} */ /** @returns {boolean} */
@ -1192,7 +1177,7 @@ class BNote extends AbstractBeccaEntity {
/** /**
* @param {string} [hoistedNoteId='root'] * @param {string} [hoistedNoteId='root']
* @return {{isArchived: boolean, isInHoistedSubTree: boolean, notePath: string[], isHidden: boolean}[]} * @return {Array<{isArchived: boolean, isInHoistedSubTree: boolean, notePath: Array<string>, isHidden: boolean}>}
*/ */
getSortedNotePathRecords(hoistedNoteId = 'root') { getSortedNotePathRecords(hoistedNoteId = 'root') {
const isHoistedRoot = hoistedNoteId === 'root'; const isHoistedRoot = hoistedNoteId === 'root';
@ -1491,7 +1476,7 @@ class BNote extends AbstractBeccaEntity {
if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) { if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
try { try {
this.title = protectedSessionService.decryptString(this.title); this.title = protectedSessionService.decryptString(this.title);
this.flatTextCache = null; this.__flatTextCache = null;
this.isDecrypted = true; this.isDecrypted = true;
} }

View File

@ -1,3 +1,4 @@
/** @param {BNote} note */
function mapNoteToPojo(note) { function mapNoteToPojo(note) {
return { return {
noteId: note.noteId, noteId: note.noteId,
@ -17,6 +18,7 @@ function mapNoteToPojo(note) {
}; };
} }
/** @param {BBranch} branch */
function mapBranchToPojo(branch) { function mapBranchToPojo(branch) {
return { return {
branchId: branch.branchId, branchId: branch.branchId,
@ -29,6 +31,7 @@ function mapBranchToPojo(branch) {
}; };
} }
/** @param {BAttribute} attr */
function mapAttributeToPojo(attr) { function mapAttributeToPojo(attr) {
return { return {
attributeId: attr.attributeId, attributeId: attr.attributeId,
@ -46,4 +49,4 @@ module.exports = {
mapNoteToPojo, mapNoteToPojo,
mapBranchToPojo, mapBranchToPojo,
mapAttributeToPojo mapAttributeToPojo
}; };

View File

@ -332,7 +332,7 @@ class FNote {
/** /**
* @param {string} [hoistedNoteId='root'] * @param {string} [hoistedNoteId='root']
* @return {{isArchived: boolean, isInHoistedSubTree: boolean, notePath: string[], isHidden: boolean}[]} * @return {Array<{isArchived: boolean, isInHoistedSubTree: boolean, notePath: Array<string>, isHidden: boolean}>}
*/ */
getSortedNotePathRecords(hoistedNoteId = 'root') { getSortedNotePathRecords(hoistedNoteId = 'root') {
const isHoistedRoot = hoistedNoteId === 'root'; const isHoistedRoot = hoistedNoteId === 'root';

View File

@ -56,13 +56,15 @@ export default class TitleBarButtonsWidget extends BasicWidget {
const $maximizeBtn = this.$widget.find(".maximize-btn"); const $maximizeBtn = this.$widget.find(".maximize-btn");
const $closeBtn = this.$widget.find(".close-btn"); const $closeBtn = this.$widget.find(".close-btn");
//When the window is restarted, the window will not be reset when it is set to the top, so get the window status and set the icon background // When the window is restarted, the window will not be reset when it is set to the top,
(function () { // so get the window status and set the icon background
setTimeout(() => {
const remote = utils.dynamicRequire('@electron/remote'); const remote = utils.dynamicRequire('@electron/remote');
if (remote.BrowserWindow.getFocusedWindow().isAlwaysOnTop()) { if (remote.BrowserWindow.getFocusedWindow()?.isAlwaysOnTop()) {
$topBtn.addClass('active'); $topBtn.addClass('active');
} }
}()); }, 1000);
$topBtn.on('click', () => { $topBtn.on('click', () => {
$topBtn.trigger('blur'); $topBtn.trigger('blur');
const remote = utils.dynamicRequire('@electron/remote'); const remote = utils.dynamicRequire('@electron/remote');

View File

@ -54,11 +54,10 @@ function deriveMime(type, mime) {
} }
function copyChildAttributes(parentNote, childNote) { function copyChildAttributes(parentNote, childNote) {
const hasAlreadyTemplate = childNote.hasRelation('template');
for (const attr of parentNote.getAttributes()) { for (const attr of parentNote.getAttributes()) {
if (attr.name.startsWith("child:")) { if (attr.name.startsWith("child:")) {
const name = attr.name.substr(6); const name = attr.name.substr(6);
const hasAlreadyTemplate = childNote.hasRelation('template');
if (hasAlreadyTemplate && attr.type === 'relation' && name === 'template') { if (hasAlreadyTemplate && attr.type === 'relation' && name === 'template') {
// if the note already has a template, it means the template was chosen by the user explicitly // if the note already has a template, it means the template was chosen by the user explicitly
@ -174,7 +173,7 @@ function createNewNote(params) {
// TODO: think about what can happen if the note already exists with the forced ID // TODO: think about what can happen if the note already exists with the forced ID
// I guess on DB it's going to be fine, but becca references between entities // I guess on DB it's going to be fine, but becca references between entities
// might get messed up (two Note instance for the same ID existing in the references) // might get messed up (two note instances for the same ID existing in the references)
note = new BNote({ note = new BNote({
noteId: params.noteId, // optionally can force specific noteId noteId: params.noteId, // optionally can force specific noteId
title: params.title, title: params.title,
@ -195,7 +194,7 @@ function createNewNote(params) {
} }
finally { finally {
if (!isEntityEventsDisabled) { if (!isEntityEventsDisabled) {
// re-enable entity events only if there were previously enabled // re-enable entity events only if they were previously enabled
// (they can be disabled in case of import) // (they can be disabled in case of import)
cls.enableEntityEvents(); cls.enableEntityEvents();
} }
@ -215,27 +214,14 @@ function createNewNote(params) {
copyChildAttributes(parentNote, note); copyChildAttributes(parentNote, note);
eventService.emit(eventService.ENTITY_CREATED, { entityName: 'notes', entity: note });
eventService.emit(eventService.ENTITY_CHANGED, { entityName: 'notes', entity: note });
triggerNoteTitleChanged(note); triggerNoteTitleChanged(note);
// note_contents doesn't use "created" event
eventService.emit(eventService.ENTITY_CREATED, { eventService.emit(eventService.ENTITY_CHANGED, { entityName: 'note_contents', entity: note });
entityName: 'notes', eventService.emit(eventService.ENTITY_CREATED, { entityName: 'branches', entity: branch });
entity: note eventService.emit(eventService.ENTITY_CHANGED, { entityName: 'branches', entity: branch });
}); eventService.emit(eventService.CHILD_NOTE_CREATED, { childNote: note, parentNote: parentNote });
eventService.emit(eventService.ENTITY_CREATED, {
entityName: 'note_contents',
entity: note
});
eventService.emit(eventService.ENTITY_CREATED, {
entityName: 'branches',
entity: branch
});
eventService.emit(eventService.CHILD_NOTE_CREATED, {
childNote: note,
parentNote: parentNote
});
log.info(`Created new note '${note.noteId}', branch '${branch.branchId}' of type '${note.type}', mime '${note.mime}'`); log.info(`Created new note '${note.noteId}', branch '${branch.branchId}' of type '${note.type}', mime '${note.mime}'`);

View File

@ -40,7 +40,7 @@ class SNote extends AbstractShacaEntity {
/** @param {SAttribute[]|null} */ /** @param {SAttribute[]|null} */
this.__attributeCache = null; this.__attributeCache = null;
/** @param {SAttribute[]|null} */ /** @param {SAttribute[]|null} */
this.inheritableAttributeCache = null; this.__inheritableAttributeCache = null;
/** @param {SAttribute[]} */ /** @param {SAttribute[]} */
this.targetRelations = []; this.targetRelations = [];
@ -190,11 +190,11 @@ class SNote extends AbstractShacaEntity {
} }
} }
this.inheritableAttributeCache = []; this.__inheritableAttributeCache = [];
for (const attr of this.__attributeCache) { for (const attr of this.__attributeCache) {
if (attr.isInheritable) { if (attr.isInheritable) {
this.inheritableAttributeCache.push(attr); this.__inheritableAttributeCache.push(attr);
} }
} }
} }
@ -208,11 +208,11 @@ class SNote extends AbstractShacaEntity {
return []; return [];
} }
if (!this.inheritableAttributeCache) { if (!this.__inheritableAttributeCache) {
this.__getAttributes(path); // will refresh also this.inheritableAttributeCache this.__getAttributes(path); // will refresh also this.__inheritableAttributeCache
} }
return this.inheritableAttributeCache; return this.__inheritableAttributeCache;
} }
/** @returns {boolean} */ /** @returns {boolean} */

View File

@ -0,0 +1,116 @@
POST {{triliumHost}}/etapi/create-note
Authorization: {{authToken}}
Content-Type: application/json
{
"parentNoteId": "root",
"title": "Hello parent",
"type": "text",
"content": "Hi there!"
}
> {%
client.assert(response.status === 201);
client.global.set("parentNoteId", response.body.note.noteId);
client.global.set("parentBranchId", response.body.branch.branchId);
%}
### Create inheritable parent attribute
POST {{triliumHost}}/etapi/attributes
Authorization: {{authToken}}
Content-Type: application/json
{
"noteId": "{{parentNoteId}}",
"type": "label",
"name": "mylabel",
"value": "",
"isInheritable": true,
"position": 10
}
> {%
client.assert(response.status === 201);
client.global.set("parentAttributeId", response.body.attributeId);
%}
### Create child note under root
POST {{triliumHost}}/etapi/create-note
Authorization: {{authToken}}
Content-Type: application/json
{
"parentNoteId": "root",
"title": "Hello child",
"type": "text",
"content": "Hi there!"
}
> {%
client.assert(response.status === 201);
client.global.set("childNoteId", response.body.note.noteId);
client.global.set("childBranchId", response.body.branch.branchId);
%}
### Create child attribute
POST {{triliumHost}}/etapi/attributes
Authorization: {{authToken}}
Content-Type: application/json
{
"noteId": "{{childNoteId}}",
"type": "label",
"name": "mylabel",
"value": "val",
"isInheritable": false,
"position": 10
}
> {%
client.assert(response.status === 201);
client.global.set("childAttributeId", response.body.attributeId);
%}
### Clone child to parent
POST {{triliumHost}}/etapi/branches
Authorization: {{authToken}}
Content-Type: application/json
{
"noteId": "{{childNoteId}}",
"parentNoteId": "{{parentNoteId}}"
}
> {%
client.assert(response.status === 201);
client.assert(response.body.parentNoteId == client.global.get("parentNoteId"));
%}
###
GET {{triliumHost}}/etapi/notes/{{childNoteId}}
Authorization: {{authToken}}
> {%
function hasAttribute(list, attributeId) {
for (let i = 0; i < list.length; i++) {
if (list[i]["attributeId"] === attributeId) {
return true;
}
}
return false;
}
client.assert(response.status === 200);
client.assert(response.body.noteId == client.global.get("childNoteId"));
client.assert(response.body.attributes.length == 2);
client.assert(hasAttribute(response.body.attributes,
client.global.get("parentAttributeId")));
client.assert(hasAttribute(response.body.attributes,
client.global.get("childAttributeId")));
%}

View File

@ -0,0 +1,44 @@
POST {{triliumHost}}/etapi/attributes
Authorization: {{authToken}}
Content-Type: application/json
{
"noteId": "root",
"type": "label",
"name": "mylabel",
"value": "val",
"isInheritable": true
}
> {% client.global.set("createdAttributeId", response.body.attributeId); %}
###
POST {{triliumHost}}/etapi/create-note
Authorization: {{authToken}}
Content-Type: application/json
{
"parentNoteId": "root",
"title": "Hello",
"type": "text",
"content": "Hi there!"
}
> {%
client.global.set("createdNoteId", response.body.note.noteId);
client.global.set("createdBranchId", response.body.branch.branchId);
%}
###
GET {{triliumHost}}/etapi/notes/{{createdNoteId}}
Authorization: {{authToken}}
> {%
client.assert(response.status === 200);
client.assert(response.body.noteId == client.global.get("createdNoteId"));
client.assert(response.body.attributes.length == 1);
client.assert(response.body.attributes[0].attributeId ==
client.global.get("createdAttributeId"));
%}