mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
Merge branch 'next58'
# Conflicts: # src/public/app/widgets/note_tree.js # src/services/tree.js
This commit is contained in:
commit
4026c2be4f
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -3,7 +3,7 @@
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_18" default="true" project-jdk-name="openjdk-18" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" default="true" project-jdk-name="openjdk-16" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
@ -5,13 +5,13 @@ UPDATE note_contents SET content = 'text' WHERE content IS NOT NULL;
|
||||
UPDATE note_revisions SET title = 'title';
|
||||
UPDATE note_revision_contents SET content = 'text' WHERE content IS NOT NULL;
|
||||
|
||||
UPDATE attributes SET name = 'name', value = 'value' WHERE type = 'label' AND name NOT IN('inbox', 'disableVersioning', 'calendarRoot', 'archived', 'excludeFromExport', 'disableInclusion', 'appCss', 'appTheme', 'hidePromotedAttributes', 'readOnly', 'autoReadOnlyDisabled', 'hoistedCssClass', 'cssClass', 'iconClass', 'keyboardShortcut', 'run', 'runOnInstance', 'runAtHour', 'customRequestHandler', 'customResourceProvider', 'widget', 'noteInfoWidgetDisabled', 'linkMapWidgetDisabled', 'noteRevisionsWidgetDisabled', 'whatLinksHereWidgetDisabled', 'similarNotesWidgetDisabled', 'workspace', 'workspaceIconClass', 'workspaceTabBackgroundColor', 'searchHome', 'hoistedInbox', 'hoistedSearchHome', 'sqlConsoleHome', 'datePattern', 'pageSize', 'viewType', 'mapRootNoteId', 'bookmarked', 'bookmarkFolder', 'sorted', 'top', 'fullContentWidth', 'shareHiddenFromTree', 'shareAlias', 'shareOmitDefaultCss', 'shareRoot', 'shareDescription', 'internalLink', 'imageLink', 'relationMapLink', 'includeMapLink', 'runOnNoteCreation', 'runOnNoteTitleChange', 'runOnNoteChange', 'runOnChildNoteCreation', 'runOnAttributeCreation', 'runOnAttributeChange', 'template', 'widget', 'renderNote', 'shareCss', 'shareJs', 'shareFavicon');
|
||||
UPDATE attributes SET name = 'name' WHERE type = 'relation' AND name NOT IN ('inbox', 'disableVersioning', 'calendarRoot', 'archived', 'excludeFromExport', 'disableInclusion', 'appCss', 'appTheme', 'hidePromotedAttributes', 'readOnly', 'autoReadOnlyDisabled', 'hoistedCssClass', 'cssClass', 'iconClass', 'keyboardShortcut', 'run', 'runOnInstance', 'runAtHour', 'customRequestHandler', 'customResourceProvider', 'widget', 'noteInfoWidgetDisabled', 'linkMapWidgetDisabled', 'noteRevisionsWidgetDisabled', 'whatLinksHereWidgetDisabled', 'similarNotesWidgetDisabled', 'workspace', 'workspaceIconClass', 'workspaceTabBackgroundColor', 'searchHome', 'hoistedInbox', 'hoistedSearchHome', 'sqlConsoleHome', 'datePattern', 'pageSize', 'viewType', 'mapRootNoteId', 'bookmarked', 'bookmarkFolder', 'sorted', 'top', 'fullContentWidth', 'shareHiddenFromTree', 'shareAlias', 'shareOmitDefaultCss', 'shareRoot', 'shareDescription', 'internalLink', 'imageLink', 'relationMapLink', 'includeMapLink', 'runOnNoteCreation', 'runOnNoteTitleChange', 'runOnNoteChange', 'runOnChildNoteCreation', 'runOnAttributeCreation', 'runOnAttributeChange', 'template', 'widget', 'renderNote', 'shareCss', 'shareJs', 'shareFavicon');
|
||||
UPDATE attributes SET name = 'name', value = 'value' WHERE type = 'label' AND name NOT IN('inbox', 'disableVersioning', 'calendarRoot', 'archived', 'excludeFromExport', 'disableInclusion', 'appCss', 'appTheme', 'hidePromotedAttributes', 'readOnly', 'autoReadOnlyDisabled', 'hoistedCssClass', 'cssClass', 'iconClass', 'keyboardShortcut', 'run', 'runOnInstance', 'runAtHour', 'customRequestHandler', 'customResourceProvider', 'widget', 'noteInfoWidgetDisabled', 'linkMapWidgetDisabled', 'noteRevisionsWidgetDisabled', 'whatLinksHereWidgetDisabled', 'similarNotesWidgetDisabled', 'workspace', 'workspaceIconClass', 'workspaceTabBackgroundColor', 'searchHome', 'hoistedInbox', 'hoistedSearchHome', 'sqlConsoleHome', 'datePattern', 'pageSize', 'viewType', 'mapRootNoteId', 'bookmarkFolder', 'sorted', 'top', 'fullContentWidth', 'shareHiddenFromTree', 'shareAlias', 'shareOmitDefaultCss', 'shareRoot', 'shareDescription', 'internalLink', 'imageLink', 'relationMapLink', 'includeMapLink', 'runOnNoteCreation', 'runOnNoteTitleChange', 'runOnNoteChange', 'runOnChildNoteCreation', 'runOnAttributeCreation', 'runOnAttributeChange', 'template', 'widget', 'renderNote', 'shareCss', 'shareJs', 'shareFavicon');
|
||||
UPDATE attributes SET name = 'name' WHERE type = 'relation' AND name NOT IN ('inbox', 'disableVersioning', 'calendarRoot', 'archived', 'excludeFromExport', 'disableInclusion', 'appCss', 'appTheme', 'hidePromotedAttributes', 'readOnly', 'autoReadOnlyDisabled', 'hoistedCssClass', 'cssClass', 'iconClass', 'keyboardShortcut', 'run', 'runOnInstance', 'runAtHour', 'customRequestHandler', 'customResourceProvider', 'widget', 'noteInfoWidgetDisabled', 'linkMapWidgetDisabled', 'noteRevisionsWidgetDisabled', 'whatLinksHereWidgetDisabled', 'similarNotesWidgetDisabled', 'workspace', 'workspaceIconClass', 'workspaceTabBackgroundColor', 'searchHome', 'hoistedInbox', 'hoistedSearchHome', 'sqlConsoleHome', 'datePattern', 'pageSize', 'viewType', 'mapRootNoteId', 'bookmarkFolder', 'sorted', 'top', 'fullContentWidth', 'shareHiddenFromTree', 'shareAlias', 'shareOmitDefaultCss', 'shareRoot', 'shareDescription', 'internalLink', 'imageLink', 'relationMapLink', 'includeMapLink', 'runOnNoteCreation', 'runOnNoteTitleChange', 'runOnNoteChange', 'runOnChildNoteCreation', 'runOnAttributeCreation', 'runOnAttributeChange', 'template', 'widget', 'renderNote', 'shareCss', 'shareJs', 'shareFavicon');
|
||||
UPDATE branches SET prefix = 'prefix' WHERE prefix IS NOT NULL AND prefix != 'recovered';
|
||||
UPDATE options SET value = 'anonymized' WHERE name IN
|
||||
('documentId', 'documentSecret', 'encryptedDataKey',
|
||||
'passwordVerificationHash', 'passwordVerificationSalt',
|
||||
'passwordDerivedKeySalt', 'username', 'syncServerHost', 'syncProxy')
|
||||
('documentId', 'documentSecret', 'encryptedDataKey',
|
||||
'passwordVerificationHash', 'passwordVerificationSalt',
|
||||
'passwordDerivedKeySalt', 'username', 'syncServerHost', 'syncProxy')
|
||||
AND value != '';
|
||||
|
||||
VACUUM;
|
||||
|
3
db/migrations/0198__set_branch_id_in_hidden_subtree.sql
Normal file
3
db/migrations/0198__set_branch_id_in_hidden_subtree.sql
Normal file
@ -0,0 +1,3 @@
|
||||
UPDATE branches SET branchId = 'search' WHERE parentNoteId = 'hidden' AND noteId = 'search';
|
||||
UPDATE branches SET branchId = 'globalnotemap' WHERE parentNoteId = 'singles' AND noteId = 'globalnotemap';
|
||||
UPDATE branches SET branchId = 'sqlconsole' WHERE parentNoteId = 'hidden' AND noteId = 'sqlconsole';
|
35
db/migrations/0199__rename_noteIds.sql
Normal file
35
db/migrations/0199__rename_noteIds.sql
Normal file
@ -0,0 +1,35 @@
|
||||
UPDATE notes SET noteId = 'globalNoteMap' WHERE noteId = 'globalnotemap';
|
||||
UPDATE notes SET noteId = 'bulkAction' WHERE noteId = 'bulkaction';
|
||||
UPDATE notes SET noteId = 'sqlConsole' WHERE noteId = 'sqlconsole';
|
||||
|
||||
UPDATE note_contents SET noteId = 'globalNoteMap' WHERE noteId = 'globalnotemap';
|
||||
UPDATE note_contents SET noteId = 'bulkAction' WHERE noteId = 'bulkaction';
|
||||
UPDATE note_contents SET noteId = 'sqlConsole' WHERE noteId = 'sqlconsole';
|
||||
|
||||
UPDATE note_revisions SET noteId = 'globalNoteMap' WHERE noteId = 'globalnotemap';
|
||||
UPDATE note_revisions SET noteId = 'bulkAction' WHERE noteId = 'bulkaction';
|
||||
UPDATE note_revisions SET noteId = 'sqlConsole' WHERE noteId = 'sqlconsole';
|
||||
|
||||
UPDATE branches SET branchId = 'globalNoteMap' WHERE branchId = 'globalnotemap';
|
||||
UPDATE branches SET branchId = 'bulkAction' WHERE branchId = 'bulkaction';
|
||||
UPDATE branches SET branchId = 'sqlConsole' WHERE branchId = 'sqlconsole';
|
||||
|
||||
UPDATE branches SET noteId = 'globalNoteMap' WHERE noteId = 'globalnotemap';
|
||||
UPDATE branches SET noteId = 'bulkAction' WHERE noteId = 'bulkaction';
|
||||
UPDATE branches SET noteId = 'sqlConsole' WHERE noteId = 'sqlconsole';
|
||||
|
||||
UPDATE branches SET parentNoteId = 'globalNoteMap' WHERE parentNoteId = 'globalnotemap';
|
||||
UPDATE branches SET parentNoteId = 'bulkAction' WHERE parentNoteId = 'bulkaction';
|
||||
UPDATE branches SET parentNoteId = 'sqlConsole' WHERE parentNoteId = 'sqlconsole';
|
||||
|
||||
UPDATE attributes SET noteId = 'globalNoteMap' WHERE noteId = 'globalnotemap';
|
||||
UPDATE attributes SET noteId = 'bulkAction' WHERE noteId = 'bulkaction';
|
||||
UPDATE attributes SET noteId = 'sqlConsole' WHERE noteId = 'sqlconsole';
|
||||
|
||||
UPDATE attributes SET value = 'globalNoteMap' WHERE type = 'relation' AND value = 'globalnotemap';
|
||||
UPDATE attributes SET value = 'bulkAction' WHERE type = 'relation' AND value = 'bulkaction';
|
||||
UPDATE attributes SET value = 'sqlConsole' WHERE type = 'relation' AND value = 'sqlconsole';
|
||||
|
||||
UPDATE entity_changes SET entityId = 'globalNoteMap' WHERE entityId = 'globalnotemap';
|
||||
UPDATE entity_changes SET entityId = 'bulkAction' WHERE entityId = 'bulkaction';
|
||||
UPDATE entity_changes SET entityId = 'sqlConsole' WHERE entityId = 'sqlconsole';
|
11
db/migrations/0200__create_hidden_subtree.js
Normal file
11
db/migrations/0200__create_hidden_subtree.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = () => {
|
||||
const hiddenSubtreeService = require('../../src/services/hidden_subtree');
|
||||
const cls = require("../../src/services/cls");
|
||||
const beccaLoader = require("../../src/becca/becca_loader");
|
||||
|
||||
cls.init(() => {
|
||||
beccaLoader.load();
|
||||
// create it because it subsequent migrations we will move some existing notes into it (share...)
|
||||
hiddenSubtreeService.checkHiddenSubtree();
|
||||
});
|
||||
};
|
1
db/migrations/0201__move_share_under_hidden.sql
Normal file
1
db/migrations/0201__move_share_under_hidden.sql
Normal file
@ -0,0 +1 @@
|
||||
UPDATE branches SET parentNoteId = 'hidden' WHERE branchId = 'share';
|
@ -0,0 +1 @@
|
||||
UPDATE branches SET parentNoteId = 'hidden' WHERE noteId = 'globalNoteMap';
|
6
db/migrations/0203__delete_singles_special_note.sql
Normal file
6
db/migrations/0203__delete_singles_special_note.sql
Normal file
@ -0,0 +1,6 @@
|
||||
DELETE FROM branches WHERE noteId = 'singles';
|
||||
DELETE FROM notes WHERE noteId = 'singles';
|
||||
DELETE FROM note_contents WHERE noteId = 'singles';
|
||||
DELETE FROM note_revisions WHERE noteId = 'singles';
|
||||
DELETE FROM attributes WHERE noteId = 'singles';
|
||||
DELETE FROM entity_changes WHERE entityId = 'singles';
|
16
db/migrations/0204__migrate_bookmarks_to_clones.js
Normal file
16
db/migrations/0204__migrate_bookmarks_to_clones.js
Normal file
@ -0,0 +1,16 @@
|
||||
module.exports = () => {
|
||||
const cls = require("../../src/services/cls");
|
||||
const cloningService = require("../../src/services/cloning");
|
||||
const beccaLoader = require("../../src/becca/becca_loader");
|
||||
const becca = require("../../src/becca/becca");
|
||||
|
||||
cls.init(() => {
|
||||
beccaLoader.load();
|
||||
|
||||
for (const attr of becca.findAttributes('label','bookmarked')) {
|
||||
cloningService.toggleNoteInParent(true, attr.noteId, 'lbBookmarks');
|
||||
|
||||
attr.markAsDeleted("0204__migrate_bookmarks_to_clones");
|
||||
}
|
||||
});
|
||||
};
|
3
db/migrations/0205__rename_note_types.sql
Normal file
3
db/migrations/0205__rename_note_types.sql
Normal file
@ -0,0 +1,3 @@
|
||||
UPDATE notes SET type = 'relationMap' WHERE type = 'relation-map';
|
||||
UPDATE notes SET type = 'noteMap' WHERE type = 'note-map';
|
||||
UPDATE notes SET type = 'webView' WHERE type = 'web-view';
|
@ -221,9 +221,15 @@ class Branch extends AbstractEntity {
|
||||
|
||||
beforeSaving() {
|
||||
if (this.notePosition === undefined || this.notePosition === null) {
|
||||
// TODO finding new position can be refactored into becca
|
||||
const maxNotePos = sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [this.parentNoteId]);
|
||||
this.notePosition = maxNotePos === null ? 0 : maxNotePos + 10;
|
||||
let maxNotePos = 0;
|
||||
|
||||
for (const childBranch of this.parentNote.getChildBranches()) {
|
||||
if (maxNotePos < childBranch.notePosition && childBranch.branchId !== 'hidden') {
|
||||
maxNotePos = childBranch.notePosition;
|
||||
}
|
||||
}
|
||||
|
||||
this.notePosition = maxNotePos + 10;
|
||||
}
|
||||
|
||||
if (!this.isExpanded) {
|
||||
|
@ -81,7 +81,7 @@
|
||||
|
||||
<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#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#line23">line 23</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -223,7 +223,7 @@
|
||||
|
||||
<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#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#line27">line 27</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -329,7 +329,7 @@
|
||||
|
||||
<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#line62">line 62</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line46">line 46</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -435,7 +435,7 @@
|
||||
|
||||
<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#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#line40">line 40</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -541,329 +541,7 @@
|
||||
|
||||
<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#line50">line 50</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="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#line59">line 59</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#line47">line 47</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">NoteContextCachingWidget</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 NoteContextCachingWidget 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#line56">line 56</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line43">line 43</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -973,7 +651,7 @@
|
||||
|
||||
<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#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#line32">line 32</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1086,7 +764,7 @@
|
||||
|
||||
<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#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#line34">line 34</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1196,7 +874,7 @@
|
||||
|
||||
<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#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#line30">line 30</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1325,7 +1003,7 @@
|
||||
|
||||
<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>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line65">line 65</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1480,7 +1158,7 @@
|
||||
|
||||
<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#line71">line 71</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line55">line 55</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1534,16 +1212,13 @@
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id="addButtonToToolbar"><span class="type-signature"></span>addButtonToToolbar<span class="signature">(opts)</span><span class="type-signature"></span></h4>
|
||||
<h4 class="name" id="addButtonToToolbar"><span class="type-signature"></span>addButtonToToolbar<span class="signature">()</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="description">
|
||||
Adds new button to the plugin area.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -1553,56 +1228,6 @@
|
||||
|
||||
|
||||
|
||||
<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>opts</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type"><a href="global.html#ToolbarButtonOptions">ToolbarButtonOptions</a></span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last"></td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1623,6 +1248,8 @@
|
||||
|
||||
|
||||
|
||||
<dt class="important tag-deprecated">Deprecated:</dt><dd><ul class="dummy"><li>this API has no effect anymore. Use bookmarks or launchpad shortcuts instead.</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1635,7 +1262,7 @@
|
||||
|
||||
<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#line138">line 138</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line120">line 120</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1772,7 +1399,7 @@
|
||||
|
||||
<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#line379">line 379</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line323">line 323</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1911,7 +1538,7 @@
|
||||
|
||||
<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#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#line311">line 311</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2067,7 +1694,7 @@
|
||||
|
||||
<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#line570">line 570</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line514">line 514</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2431,7 +2058,7 @@
|
||||
|
||||
<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#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#line302">line 302</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2564,7 +2191,7 @@
|
||||
|
||||
<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#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#line242">line 242</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2674,7 +2301,7 @@
|
||||
|
||||
<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#line425">line 425</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line369">line 369</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2780,7 +2407,7 @@
|
||||
|
||||
<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#line396">line 396</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line340">line 340</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2886,7 +2513,7 @@
|
||||
|
||||
<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#line451">line 451</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line395">line 395</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2996,7 +2623,7 @@
|
||||
|
||||
<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#line417">line 417</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line361">line 361</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3107,7 +2734,7 @@ implementation of actual widget type.
|
||||
|
||||
<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#line434">line 434</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line378">line 378</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3211,7 +2838,7 @@ implementation of actual widget type.
|
||||
|
||||
<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#line386">line 386</a>
|
||||
<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>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3319,7 +2946,7 @@ implementation of actual widget type.
|
||||
|
||||
<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#line441">line 441</a>
|
||||
<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>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3487,7 +3114,7 @@ implementation of actual widget type.
|
||||
|
||||
<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#line405">line 405</a>
|
||||
<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>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3624,7 +3251,7 @@ implementation of actual widget type.
|
||||
|
||||
<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#line460">line 460</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line404">line 404</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3781,7 +3408,7 @@ implementation of actual widget type.
|
||||
|
||||
<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#line512">line 512</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line456">line 456</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3936,7 +3563,7 @@ implementation of actual widget type.
|
||||
|
||||
<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#line521">line 521</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line465">line 465</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4043,7 +3670,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<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#line291">line 291</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>
|
||||
|
||||
|
||||
@ -4198,7 +3825,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<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#line539">line 539</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line483">line 483</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4354,7 +3981,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<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#line263">line 263</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line207">line 207</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4555,7 +4182,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#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#line219">line 219</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4661,7 +4288,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line502">line 502</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line446">line 446</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4816,7 +4443,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line530">line 530</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line474">line 474</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4971,7 +4598,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line548">line 548</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line492">line 492</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5121,7 +4748,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line607">line 607</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line551">line 551</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5281,7 +4908,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line112">line 112</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line96">line 96</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5459,7 +5086,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line95">line 95</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>
|
||||
|
||||
|
||||
@ -5610,7 +5237,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line305">line 305</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line249">line 249</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5718,7 +5345,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line472">line 472</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line416">line 416</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5874,7 +5501,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line483">line 483</a>
|
||||
<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>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6030,7 +5657,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line492">line 492</a>
|
||||
<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>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6167,7 +5794,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line597">line 597</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line541">line 541</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6321,7 +5948,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line588">line 588</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line532">line 532</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6407,7 +6034,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line345">line 345</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line289">line 289</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6544,7 +6171,7 @@ otherwise (by e.g. createNoteLink())
|
||||
|
||||
<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#line283">line 283</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>
|
||||
|
||||
|
||||
@ -6705,7 +6332,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#line201">line 201</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line145">line 145</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6813,7 +6440,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#line229">line 229</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line173">line 173</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6951,7 +6578,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#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#line195">line 195</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -7107,7 +6734,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#line239">line 239</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line183">line 183</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -7262,7 +6889,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#line557">line 557</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line501">line 501</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -7413,7 +7040,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#line466">line 466</a>
|
||||
<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>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -7550,7 +7177,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#line321">line 321</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line265">line 265</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -7687,7 +7314,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#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#line257">line 257</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -7847,7 +7474,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#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#line274">line 274</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -8007,7 +7634,7 @@ Internally this serializes the anonymous function into string and sends it to ba
|
||||
|
||||
<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#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#line283">line 283</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -8099,7 +7726,7 @@ Typical use case is when new note has been created, we should wait until it is s
|
||||
|
||||
<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#line581">line 581</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line525">line 525</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
@ -167,7 +167,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line31">line 31</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>
|
||||
|
||||
|
||||
@ -267,7 +267,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line40">line 40</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line42">line 42</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -335,7 +335,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line54">line 54</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>
|
||||
|
||||
|
||||
@ -403,7 +403,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line48">line 48</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line50">line 50</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -471,7 +471,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line65">line 65</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line67">line 67</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -543,7 +543,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line75">line 75</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line77">line 77</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -611,7 +611,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line61">line 61</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line63">line 63</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -679,7 +679,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line53">line 53</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -747,7 +747,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line46">line 46</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line48">line 48</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -815,7 +815,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line45">line 45</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -883,7 +883,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line63">line 63</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line65">line 65</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -955,7 +955,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line70">line 70</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line72">line 72</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1103,7 +1103,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line511">line 511</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line513">line 513</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1281,7 +1281,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line533">line 533</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line535">line 535</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1481,7 +1481,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line240">line 240</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line242">line 242</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1589,7 +1589,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line148">line 148</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line150">line 150</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1693,7 +1693,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line165">line 165</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>
|
||||
|
||||
|
||||
@ -1795,7 +1795,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line175">line 175</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line177">line 177</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1897,7 +1897,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line213">line 213</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line215">line 215</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -1999,7 +1999,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line218">line 218</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line220">line 220</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2150,7 +2150,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line573">line 573</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line575">line 575</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2305,7 +2305,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line597">line 597</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line599">line 599</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2472,7 +2472,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line392">line 392</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line394">line 394</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2582,7 +2582,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line724">line 724</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line726">line 726</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2756,7 +2756,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line500">line 500</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line502">line 502</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -2934,7 +2934,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line522">line 522</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line524">line 524</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3134,7 +3134,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line227">line 227</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line229">line 229</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3289,7 +3289,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line567">line 567</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line569">line 569</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3444,7 +3444,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line591">line 591</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line593">line 593</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3611,7 +3611,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line384">line 384</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line386">line 386</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3766,7 +3766,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line579">line 579</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line581">line 581</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -3921,7 +3921,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line603">line 603</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line605">line 605</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4088,7 +4088,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line467">line 467</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4194,7 +4194,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line140">line 140</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line142">line 142</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4296,7 +4296,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line155">line 155</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>
|
||||
|
||||
|
||||
@ -4398,7 +4398,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line183">line 183</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line185">line 185</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4500,7 +4500,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line188">line 188</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line190">line 190</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4651,7 +4651,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line585">line 585</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line587">line 587</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4806,7 +4806,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line615">line 615</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line617">line 617</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -4976,7 +4976,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line625">line 625</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line627">line 627</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5127,7 +5127,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line609">line 609</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line611">line 611</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5294,7 +5294,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line473">line 473</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>
|
||||
|
||||
|
||||
@ -5400,7 +5400,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line768">line 768</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line770">line 770</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5513,7 +5513,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line713">line 713</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line715">line 715</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5619,7 +5619,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line703">line 703</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line705">line 705</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5721,7 +5721,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line639">line 639</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line641">line 641</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -5895,7 +5895,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line482">line 482</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line484">line 484</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6001,7 +6001,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line170">line 170</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line172">line 172</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6152,7 +6152,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line549">line 549</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line551">line 551</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6330,7 +6330,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line491">line 491</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line493">line 493</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6485,7 +6485,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line543">line 543</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line545">line 545</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6640,7 +6640,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line555">line 555</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line557">line 557</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6795,7 +6795,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line561">line 561</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line563">line 563</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6903,7 +6903,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line696">line 696</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line698">line 698</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -6987,7 +6987,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line763">line 763</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line765">line 765</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -7093,7 +7093,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line755">line 755</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line757">line 757</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@ -7199,7 +7199,7 @@ This note's representation is used in note tree and is kept in Froca.</div>
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<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#line113">line 113</a>
|
||||
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line115">line 115</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
@ -48,7 +48,9 @@ const NOTE_TYPE_ICONS = {
|
||||
"note-map": "bx bx-map-alt",
|
||||
"mermaid": "bx bx-selection",
|
||||
"canvas": "bx bx-pen",
|
||||
"web-view": "bx bx-globe-alt"
|
||||
"web-view": "bx bx-globe-alt",
|
||||
"shortcut": "bx bx-link",
|
||||
"doc": "bx bxs-file-doc"
|
||||
};
|
||||
|
||||
/**
|
||||
@ -818,10 +820,10 @@ class NoteShort {
|
||||
|
||||
if (env === "frontend") {
|
||||
const bundleService = (await import("../services/bundle.js")).default;
|
||||
await bundleService.getAndExecuteBundle(this.noteId);
|
||||
return await bundleService.getAndExecuteBundle(this.noteId);
|
||||
}
|
||||
else if (env === "backend") {
|
||||
await server.post('script/run/' + this.noteId);
|
||||
return await server.post('script/run/' + this.noteId);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unrecognized env type ${env} for note ${this.noteId}`);
|
||||
@ -851,6 +853,10 @@ class NoteShort {
|
||||
isContentAvailable() {
|
||||
return !this.isProtected || protectedSessionHolder.isProtectedSessionAvailable()
|
||||
}
|
||||
|
||||
isLaunchBarConfig() {
|
||||
return this.type === 'shortcut' || this.noteId.startsWith("lb_");
|
||||
}
|
||||
}
|
||||
|
||||
export default NoteShort;
|
||||
|
@ -395,7 +395,7 @@
|
||||
|
||||
<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#line125">line 125</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line109">line 109</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
@ -39,7 +39,6 @@ import CollapsibleWidget from '../widgets/collapsible_widget.js';
|
||||
import ws from "./ws.js";
|
||||
import appContext from "./app_context.js";
|
||||
import NoteContextAwareWidget from "../widgets/note_context_aware_widget.js";
|
||||
import NoteContextCachingWidget from "../widgets/note_context_caching_widget.js";
|
||||
import BasicWidget from "../widgets/basic_widget.js";
|
||||
import SpacedUpdate from "./spaced_update.js";
|
||||
|
||||
@ -68,24 +67,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
|
||||
/** @property {CollapsibleWidget} */
|
||||
this.CollapsibleWidget = CollapsibleWidget;
|
||||
|
||||
/**
|
||||
* @property {NoteContextAwareWidget}
|
||||
* @deprecated use NoteContextAwareWidget instead
|
||||
*/
|
||||
this.TabAwareWidget = NoteContextAwareWidget;
|
||||
|
||||
/** @property {NoteContextAwareWidget} */
|
||||
this.NoteContextAwareWidget = NoteContextAwareWidget;
|
||||
|
||||
/**
|
||||
* @property {NoteContextCachingWidget}
|
||||
* @deprecated use NoteContextCachingWidget instead
|
||||
*/
|
||||
this.TabCachingWidget = NoteContextCachingWidget;
|
||||
|
||||
/** @property {NoteContextAwareWidget} */
|
||||
this.NoteContextCachingWidget = NoteContextCachingWidget;
|
||||
|
||||
/** @property {BasicWidget} */
|
||||
this.BasicWidget = BasicWidget;
|
||||
|
||||
@ -159,49 +143,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds new button to the plugin area.
|
||||
*
|
||||
* @param {ToolbarButtonOptions} opts
|
||||
* @deprecated this API has no effect anymore. Use bookmarks or launchpad shortcuts instead.
|
||||
*/
|
||||
this.addButtonToToolbar = opts => {
|
||||
const buttonId = "toolbar-button-" + opts.title.replace(/\s/g, "-");
|
||||
|
||||
let button;
|
||||
if (utils.isMobile()) {
|
||||
$('#plugin-buttons-placeholder').remove();
|
||||
button = $('<a class="dropdown-item" href="#">')
|
||||
.on('click', () => {
|
||||
setTimeout(() => $pluginButtons.dropdown('hide'), 0);
|
||||
});
|
||||
|
||||
if (opts.icon) {
|
||||
button.append($("<span>").addClass("bx bx-" + opts.icon))
|
||||
.append("&nbsp;");
|
||||
}
|
||||
|
||||
button.append($("<span>").text(opts.title));
|
||||
} else {
|
||||
button = $('<span class="button-widget icon-action bx" data-toggle="tooltip" title="" data-placement="right"></span>')
|
||||
.addClass("bx bx-" + (opts.icon || "question-mark"));
|
||||
|
||||
button.attr("title", opts.title);
|
||||
button.tooltip({html: true});
|
||||
}
|
||||
|
||||
button = button.on('click', opts.action);
|
||||
|
||||
button.attr('id', buttonId);
|
||||
|
||||
if ($("#" + buttonId).replaceWith(button).length === 0) {
|
||||
$pluginButtons.append(button);
|
||||
}
|
||||
|
||||
if (opts.shortcut) {
|
||||
utils.bindGlobalShortcut(opts.shortcut, opts.action);
|
||||
|
||||
button.attr("title", "Shortcut " + opts.shortcut);
|
||||
}
|
||||
};
|
||||
this.addButtonToToolbar = () => console.warn("api.addButtonToToolbar() calls are deprecated and have no effect");
|
||||
|
||||
function prepareParams(params) {
|
||||
if (!params) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const yargs = require('yargs/yargs')
|
||||
const { hideBin } = require('yargs/helpers')
|
||||
const dumpService = require("./inc/dump.js");
|
||||
const dumpService = require("./inc/dump");
|
||||
|
||||
yargs(hideBin(process.argv))
|
||||
.command('$0 <path_to_document> <target_directory>', 'dump the contents of document.db into the target directory', (yargs) => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
const crypto = require("crypto");
|
||||
const sql = require("./sql.js");
|
||||
const decryptService = require("./decrypt.js");
|
||||
const sql = require("./sql");
|
||||
const decryptService = require("./decrypt");
|
||||
|
||||
function getDataKey(password) {
|
||||
if (!password) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
const fs = require("fs");
|
||||
const sanitize = require("sanitize-filename");
|
||||
const sql = require("./sql.js");
|
||||
const decryptService = require("./decrypt.js");
|
||||
const dataKeyService = require("./data_key.js");
|
||||
const extensionService = require("./extension.js");
|
||||
const sql = require("./sql");
|
||||
const decryptService = require("./decrypt");
|
||||
const dataKeyService = require("./data_key");
|
||||
const extensionService = require("./extension");
|
||||
|
||||
function dumpDocument(documentPath, targetPath, options) {
|
||||
const stats = {
|
||||
|
214
libraries/jquery.js
vendored
214
libraries/jquery.js
vendored
@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* jQuery JavaScript Library v3.6.0
|
||||
* jQuery JavaScript Library v3.6.1
|
||||
* https://jquery.com/
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
@ -9,7 +9,7 @@
|
||||
* Released under the MIT license
|
||||
* https://jquery.org/license
|
||||
*
|
||||
* Date: 2021-03-02T17:08Z
|
||||
* Date: 2022-08-26T17:52Z
|
||||
*/
|
||||
( function( global, factory ) {
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
// (such as Node.js), expose a factory as module.exports.
|
||||
// This accentuates the need for the creation of a real `window`.
|
||||
// e.g. var jQuery = require("jquery")(window);
|
||||
// See ticket #14549 for more info.
|
||||
// See ticket trac-14549 for more info.
|
||||
module.exports = global.document ?
|
||||
factory( global, true ) :
|
||||
function( w ) {
|
||||
@ -151,7 +151,7 @@ function toType( obj ) {
|
||||
|
||||
|
||||
var
|
||||
version = "3.6.0",
|
||||
version = "3.6.1",
|
||||
|
||||
// Define a local copy of jQuery
|
||||
jQuery = function( selector, context ) {
|
||||
@ -3129,8 +3129,8 @@ jQuery.fn.extend( {
|
||||
var rootjQuery,
|
||||
|
||||
// A simple way to check for HTML strings
|
||||
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
|
||||
// Strict HTML recognition (#11290: must start with <)
|
||||
// Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521)
|
||||
// Strict HTML recognition (trac-11290: must start with <)
|
||||
// Shortcut simple #id case for speed
|
||||
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
|
||||
|
||||
@ -4087,7 +4087,7 @@ jQuery.extend( {
|
||||
isReady: false,
|
||||
|
||||
// A counter to track how many items to wait for before
|
||||
// the ready event fires. See #6781
|
||||
// the ready event fires. See trac-6781
|
||||
readyWait: 1,
|
||||
|
||||
// Handle when the DOM is ready
|
||||
@ -4215,7 +4215,7 @@ function fcamelCase( _all, letter ) {
|
||||
|
||||
// Convert dashed to camelCase; used by the css and data modules
|
||||
// Support: IE <=9 - 11, Edge 12 - 15
|
||||
// Microsoft forgot to hump their vendor prefix (#9572)
|
||||
// Microsoft forgot to hump their vendor prefix (trac-9572)
|
||||
function camelCase( string ) {
|
||||
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
|
||||
}
|
||||
@ -4251,7 +4251,7 @@ Data.prototype = {
|
||||
value = {};
|
||||
|
||||
// We can accept data for non-element nodes in modern browsers,
|
||||
// but we should not, see #8335.
|
||||
// but we should not, see trac-8335.
|
||||
// Always return an empty object.
|
||||
if ( acceptData( owner ) ) {
|
||||
|
||||
@ -4490,7 +4490,7 @@ jQuery.fn.extend( {
|
||||
while ( i-- ) {
|
||||
|
||||
// Support: IE 11 only
|
||||
// The attrs elements can be null (#14894)
|
||||
// The attrs elements can be null (trac-14894)
|
||||
if ( attrs[ i ] ) {
|
||||
name = attrs[ i ].name;
|
||||
if ( name.indexOf( "data-" ) === 0 ) {
|
||||
@ -4913,9 +4913,9 @@ var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
|
||||
input = document.createElement( "input" );
|
||||
|
||||
// Support: Android 4.0 - 4.3 only
|
||||
// Check state lost if the name is set (#11217)
|
||||
// Check state lost if the name is set (trac-11217)
|
||||
// Support: Windows Web Apps (WWA)
|
||||
// `name` and `type` must use .setAttribute for WWA (#14901)
|
||||
// `name` and `type` must use .setAttribute for WWA (trac-14901)
|
||||
input.setAttribute( "type", "radio" );
|
||||
input.setAttribute( "checked", "checked" );
|
||||
input.setAttribute( "name", "t" );
|
||||
@ -4939,7 +4939,7 @@ var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
|
||||
} )();
|
||||
|
||||
|
||||
// We have to close these tags to support XHTML (#13200)
|
||||
// We have to close these tags to support XHTML (trac-13200)
|
||||
var wrapMap = {
|
||||
|
||||
// XHTML parsers do not magically insert elements in the
|
||||
@ -4965,7 +4965,7 @@ if ( !support.option ) {
|
||||
function getAll( context, tag ) {
|
||||
|
||||
// Support: IE <=9 - 11 only
|
||||
// Use typeof to avoid zero-argument method invocation on host objects (#15151)
|
||||
// Use typeof to avoid zero-argument method invocation on host objects (trac-15151)
|
||||
var ret;
|
||||
|
||||
if ( typeof context.getElementsByTagName !== "undefined" ) {
|
||||
@ -5048,7 +5048,7 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
|
||||
// Remember the top-level container
|
||||
tmp = fragment.firstChild;
|
||||
|
||||
// Ensure the created nodes are orphaned (#12392)
|
||||
// Ensure the created nodes are orphaned (trac-12392)
|
||||
tmp.textContent = "";
|
||||
}
|
||||
}
|
||||
@ -5469,15 +5469,15 @@ jQuery.event = {
|
||||
|
||||
for ( ; cur !== this; cur = cur.parentNode || this ) {
|
||||
|
||||
// Don't check non-elements (#13208)
|
||||
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
|
||||
// Don't check non-elements (trac-13208)
|
||||
// Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764)
|
||||
if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
|
||||
matchedHandlers = [];
|
||||
matchedSelectors = {};
|
||||
for ( i = 0; i < delegateCount; i++ ) {
|
||||
handleObj = handlers[ i ];
|
||||
|
||||
// Don't conflict with Object.prototype properties (#13203)
|
||||
// Don't conflict with Object.prototype properties (trac-13203)
|
||||
sel = handleObj.selector + " ";
|
||||
|
||||
if ( matchedSelectors[ sel ] === undefined ) {
|
||||
@ -5731,7 +5731,7 @@ jQuery.Event = function( src, props ) {
|
||||
|
||||
// Create target properties
|
||||
// Support: Safari <=6 - 7 only
|
||||
// Target should not be a text node (#504, #13143)
|
||||
// Target should not be a text node (trac-504, trac-13143)
|
||||
this.target = ( src.target && src.target.nodeType === 3 ) ?
|
||||
src.target.parentNode :
|
||||
src.target;
|
||||
@ -5854,10 +5854,10 @@ jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateTyp
|
||||
return true;
|
||||
},
|
||||
|
||||
// Suppress native focus or blur as it's already being fired
|
||||
// in leverageNative.
|
||||
_default: function() {
|
||||
return true;
|
||||
// Suppress native focus or blur if we're currently inside
|
||||
// a leveraged native-event stack
|
||||
_default: function( event ) {
|
||||
return dataPriv.get( event.target, type );
|
||||
},
|
||||
|
||||
delegateType: delegateType
|
||||
@ -5956,7 +5956,8 @@ var
|
||||
|
||||
// checked="checked" or checked
|
||||
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
|
||||
rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
|
||||
|
||||
rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g;
|
||||
|
||||
// Prefer a tbody over its parent table for containing new rows
|
||||
function manipulationTarget( elem, content ) {
|
||||
@ -6070,7 +6071,7 @@ function domManip( collection, args, callback, ignored ) {
|
||||
|
||||
// Use the original fragment for the last item
|
||||
// instead of the first because it can end up
|
||||
// being emptied incorrectly in certain situations (#8070).
|
||||
// being emptied incorrectly in certain situations (trac-8070).
|
||||
for ( ; i < l; i++ ) {
|
||||
node = fragment;
|
||||
|
||||
@ -6111,6 +6112,12 @@ function domManip( collection, args, callback, ignored ) {
|
||||
}, doc );
|
||||
}
|
||||
} else {
|
||||
|
||||
// Unwrap a CDATA section containing script contents. This shouldn't be
|
||||
// needed as in XML documents they're already not visible when
|
||||
// inspecting element contents and in HTML documents they have no
|
||||
// meaning but we're preserving that logic for backwards compatibility.
|
||||
// This will be removed completely in 4.0. See gh-4904.
|
||||
DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
|
||||
}
|
||||
}
|
||||
@ -6393,9 +6400,12 @@ jQuery.each( {
|
||||
} );
|
||||
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
|
||||
|
||||
var rcustomProp = /^--/;
|
||||
|
||||
|
||||
var getStyles = function( elem ) {
|
||||
|
||||
// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
|
||||
// Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150)
|
||||
// IE throws on elements created in popups
|
||||
// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
|
||||
var view = elem.ownerDocument.defaultView;
|
||||
@ -6430,6 +6440,15 @@ var swap = function( elem, options, callback ) {
|
||||
|
||||
var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
|
||||
|
||||
var whitespace = "[\\x20\\t\\r\\n\\f]";
|
||||
|
||||
|
||||
var rtrimCSS = new RegExp(
|
||||
"^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$",
|
||||
"g"
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
( function() {
|
||||
@ -6495,7 +6514,7 @@ var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
|
||||
}
|
||||
|
||||
// Support: IE <=9 - 11 only
|
||||
// Style of cloned element affects source element cloned (#8908)
|
||||
// Style of cloned element affects source element cloned (trac-8908)
|
||||
div.style.backgroundClip = "content-box";
|
||||
div.cloneNode( true ).style.backgroundClip = "";
|
||||
support.clearCloneStyle = div.style.backgroundClip === "content-box";
|
||||
@ -6575,6 +6594,7 @@ var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
|
||||
|
||||
function curCSS( elem, name, computed ) {
|
||||
var width, minWidth, maxWidth, ret,
|
||||
isCustomProp = rcustomProp.test( name ),
|
||||
|
||||
// Support: Firefox 51+
|
||||
// Retrieving style before computed somehow
|
||||
@ -6585,11 +6605,22 @@ function curCSS( elem, name, computed ) {
|
||||
computed = computed || getStyles( elem );
|
||||
|
||||
// getPropertyValue is needed for:
|
||||
// .css('filter') (IE 9 only, #12537)
|
||||
// .css('--customProperty) (#3144)
|
||||
// .css('filter') (IE 9 only, trac-12537)
|
||||
// .css('--customProperty) (gh-3144)
|
||||
if ( computed ) {
|
||||
ret = computed.getPropertyValue( name ) || computed[ name ];
|
||||
|
||||
// trim whitespace for custom property (issue gh-4926)
|
||||
if ( isCustomProp ) {
|
||||
|
||||
// rtrim treats U+000D CARRIAGE RETURN and U+000C FORM FEED
|
||||
// as whitespace while CSS does not, but this is not a problem
|
||||
// because CSS preprocessing replaces them with U+000A LINE FEED
|
||||
// (which *is* CSS whitespace)
|
||||
// https://www.w3.org/TR/css-syntax-3/#input-preprocessing
|
||||
ret = ret.replace( rtrimCSS, "$1" );
|
||||
}
|
||||
|
||||
if ( ret === "" && !isAttached( elem ) ) {
|
||||
ret = jQuery.style( elem, name );
|
||||
}
|
||||
@ -6685,7 +6716,6 @@ var
|
||||
// except "table", "table-cell", or "table-caption"
|
||||
// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
|
||||
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
|
||||
rcustomProp = /^--/,
|
||||
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
|
||||
cssNormalTransform = {
|
||||
letterSpacing: "0",
|
||||
@ -6921,15 +6951,15 @@ jQuery.extend( {
|
||||
if ( value !== undefined ) {
|
||||
type = typeof value;
|
||||
|
||||
// Convert "+=" or "-=" to relative numbers (#7345)
|
||||
// Convert "+=" or "-=" to relative numbers (trac-7345)
|
||||
if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
|
||||
value = adjustCSS( elem, name, ret );
|
||||
|
||||
// Fixes bug #9237
|
||||
// Fixes bug trac-9237
|
||||
type = "number";
|
||||
}
|
||||
|
||||
// Make sure that null and NaN values aren't set (#7116)
|
||||
// Make sure that null and NaN values aren't set (trac-7116)
|
||||
if ( value == null || value !== value ) {
|
||||
return;
|
||||
}
|
||||
@ -7553,7 +7583,7 @@ function Animation( elem, properties, options ) {
|
||||
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
|
||||
|
||||
// Support: Android 2.3 only
|
||||
// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
|
||||
// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497)
|
||||
temp = remaining / animation.duration || 0,
|
||||
percent = 1 - temp,
|
||||
index = 0,
|
||||
@ -7943,7 +7973,6 @@ jQuery.fx.speeds = {
|
||||
|
||||
|
||||
// Based off of the plugin by Clint Helfers, with permission.
|
||||
// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
|
||||
jQuery.fn.delay = function( time, type ) {
|
||||
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
|
||||
type = type || "fx";
|
||||
@ -8168,8 +8197,7 @@ jQuery.extend( {
|
||||
// Support: IE <=9 - 11 only
|
||||
// elem.tabIndex doesn't always return the
|
||||
// correct value when it hasn't been explicitly set
|
||||
// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
|
||||
// Use proper attribute retrieval(#12072)
|
||||
// Use proper attribute retrieval (trac-12072)
|
||||
var tabindex = jQuery.find.attr( elem, "tabindex" );
|
||||
|
||||
if ( tabindex ) {
|
||||
@ -8273,8 +8301,7 @@ function classesToArray( value ) {
|
||||
|
||||
jQuery.fn.extend( {
|
||||
addClass: function( value ) {
|
||||
var classes, elem, cur, curValue, clazz, j, finalValue,
|
||||
i = 0;
|
||||
var classNames, cur, curValue, className, i, finalValue;
|
||||
|
||||
if ( isFunction( value ) ) {
|
||||
return this.each( function( j ) {
|
||||
@ -8282,36 +8309,35 @@ jQuery.fn.extend( {
|
||||
} );
|
||||
}
|
||||
|
||||
classes = classesToArray( value );
|
||||
classNames = classesToArray( value );
|
||||
|
||||
if ( classes.length ) {
|
||||
while ( ( elem = this[ i++ ] ) ) {
|
||||
curValue = getClass( elem );
|
||||
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||||
if ( classNames.length ) {
|
||||
return this.each( function() {
|
||||
curValue = getClass( this );
|
||||
cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||||
|
||||
if ( cur ) {
|
||||
j = 0;
|
||||
while ( ( clazz = classes[ j++ ] ) ) {
|
||||
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
|
||||
cur += clazz + " ";
|
||||
for ( i = 0; i < classNames.length; i++ ) {
|
||||
className = classNames[ i ];
|
||||
if ( cur.indexOf( " " + className + " " ) < 0 ) {
|
||||
cur += className + " ";
|
||||
}
|
||||
}
|
||||
|
||||
// Only assign if different to avoid unneeded rendering.
|
||||
finalValue = stripAndCollapse( cur );
|
||||
if ( curValue !== finalValue ) {
|
||||
elem.setAttribute( "class", finalValue );
|
||||
this.setAttribute( "class", finalValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
removeClass: function( value ) {
|
||||
var classes, elem, cur, curValue, clazz, j, finalValue,
|
||||
i = 0;
|
||||
var classNames, cur, curValue, className, i, finalValue;
|
||||
|
||||
if ( isFunction( value ) ) {
|
||||
return this.each( function( j ) {
|
||||
@ -8323,45 +8349,42 @@ jQuery.fn.extend( {
|
||||
return this.attr( "class", "" );
|
||||
}
|
||||
|
||||
classes = classesToArray( value );
|
||||
classNames = classesToArray( value );
|
||||
|
||||
if ( classes.length ) {
|
||||
while ( ( elem = this[ i++ ] ) ) {
|
||||
curValue = getClass( elem );
|
||||
if ( classNames.length ) {
|
||||
return this.each( function() {
|
||||
curValue = getClass( this );
|
||||
|
||||
// This expression is here for better compressibility (see addClass)
|
||||
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||||
cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||||
|
||||
if ( cur ) {
|
||||
j = 0;
|
||||
while ( ( clazz = classes[ j++ ] ) ) {
|
||||
for ( i = 0; i < classNames.length; i++ ) {
|
||||
className = classNames[ i ];
|
||||
|
||||
// Remove *all* instances
|
||||
while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
|
||||
cur = cur.replace( " " + clazz + " ", " " );
|
||||
while ( cur.indexOf( " " + className + " " ) > -1 ) {
|
||||
cur = cur.replace( " " + className + " ", " " );
|
||||
}
|
||||
}
|
||||
|
||||
// Only assign if different to avoid unneeded rendering.
|
||||
finalValue = stripAndCollapse( cur );
|
||||
if ( curValue !== finalValue ) {
|
||||
elem.setAttribute( "class", finalValue );
|
||||
this.setAttribute( "class", finalValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
toggleClass: function( value, stateVal ) {
|
||||
var type = typeof value,
|
||||
var classNames, className, i, self,
|
||||
type = typeof value,
|
||||
isValidValue = type === "string" || Array.isArray( value );
|
||||
|
||||
if ( typeof stateVal === "boolean" && isValidValue ) {
|
||||
return stateVal ? this.addClass( value ) : this.removeClass( value );
|
||||
}
|
||||
|
||||
if ( isFunction( value ) ) {
|
||||
return this.each( function( i ) {
|
||||
jQuery( this ).toggleClass(
|
||||
@ -8371,17 +8394,20 @@ jQuery.fn.extend( {
|
||||
} );
|
||||
}
|
||||
|
||||
return this.each( function() {
|
||||
var className, i, self, classNames;
|
||||
if ( typeof stateVal === "boolean" && isValidValue ) {
|
||||
return stateVal ? this.addClass( value ) : this.removeClass( value );
|
||||
}
|
||||
|
||||
classNames = classesToArray( value );
|
||||
|
||||
return this.each( function() {
|
||||
if ( isValidValue ) {
|
||||
|
||||
// Toggle individual class names
|
||||
i = 0;
|
||||
self = jQuery( this );
|
||||
classNames = classesToArray( value );
|
||||
|
||||
while ( ( className = classNames[ i++ ] ) ) {
|
||||
for ( i = 0; i < classNames.length; i++ ) {
|
||||
className = classNames[ i ];
|
||||
|
||||
// Check each className given, space separated list
|
||||
if ( self.hasClass( className ) ) {
|
||||
@ -8515,7 +8541,7 @@ jQuery.extend( {
|
||||
val :
|
||||
|
||||
// Support: IE <=10 - 11 only
|
||||
// option.text throws exceptions (#14686, #14858)
|
||||
// option.text throws exceptions (trac-14686, trac-14858)
|
||||
// Strip and collapse whitespace
|
||||
// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
|
||||
stripAndCollapse( jQuery.text( elem ) );
|
||||
@ -8542,7 +8568,7 @@ jQuery.extend( {
|
||||
option = options[ i ];
|
||||
|
||||
// Support: IE <=9 only
|
||||
// IE8-9 doesn't update selected after form reset (#2551)
|
||||
// IE8-9 doesn't update selected after form reset (trac-2551)
|
||||
if ( ( option.selected || i === index ) &&
|
||||
|
||||
// Don't return options that are disabled or in a disabled optgroup
|
||||
@ -8685,8 +8711,8 @@ jQuery.extend( jQuery.event, {
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine event propagation path in advance, per W3C events spec (#9951)
|
||||
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
|
||||
// Determine event propagation path in advance, per W3C events spec (trac-9951)
|
||||
// Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724)
|
||||
if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
|
||||
|
||||
bubbleType = special.delegateType || type;
|
||||
@ -8738,7 +8764,7 @@ jQuery.extend( jQuery.event, {
|
||||
acceptData( elem ) ) {
|
||||
|
||||
// Call a native DOM method on the target with the same name as the event.
|
||||
// Don't do default actions on window, that's where global variables be (#6170)
|
||||
// Don't do default actions on window, that's where global variables be (trac-6170)
|
||||
if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
|
||||
|
||||
// Don't re-trigger an onFOO event when we call its FOO() method
|
||||
@ -9012,7 +9038,7 @@ var
|
||||
rantiCache = /([?&])_=[^&]*/,
|
||||
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
|
||||
|
||||
// #7653, #8125, #8152: local protocol detection
|
||||
// trac-7653, trac-8125, trac-8152: local protocol detection
|
||||
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
|
||||
rnoContent = /^(?:GET|HEAD)$/,
|
||||
rprotocol = /^\/\//,
|
||||
@ -9035,7 +9061,7 @@ var
|
||||
*/
|
||||
transports = {},
|
||||
|
||||
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
|
||||
// Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression
|
||||
allTypes = "*/".concat( "*" ),
|
||||
|
||||
// Anchor tag for parsing the document origin
|
||||
@ -9106,7 +9132,7 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX
|
||||
|
||||
// A special extend for ajax options
|
||||
// that takes "flat" options (not to be deep extended)
|
||||
// Fixes #9887
|
||||
// Fixes trac-9887
|
||||
function ajaxExtend( target, src ) {
|
||||
var key, deep,
|
||||
flatOptions = jQuery.ajaxSettings.flatOptions || {};
|
||||
@ -9517,12 +9543,12 @@ jQuery.extend( {
|
||||
deferred.promise( jqXHR );
|
||||
|
||||
// Add protocol if not provided (prefilters might expect it)
|
||||
// Handle falsy url in the settings object (#10093: consistency with old signature)
|
||||
// Handle falsy url in the settings object (trac-10093: consistency with old signature)
|
||||
// We also use the url parameter if available
|
||||
s.url = ( ( url || s.url || location.href ) + "" )
|
||||
.replace( rprotocol, location.protocol + "//" );
|
||||
|
||||
// Alias method option to type as per ticket #12004
|
||||
// Alias method option to type as per ticket trac-12004
|
||||
s.type = options.method || options.type || s.method || s.type;
|
||||
|
||||
// Extract dataTypes list
|
||||
@ -9565,7 +9591,7 @@ jQuery.extend( {
|
||||
}
|
||||
|
||||
// We can fire global events as of now if asked to
|
||||
// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
|
||||
// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118)
|
||||
fireGlobals = jQuery.event && s.global;
|
||||
|
||||
// Watch for a new set of requests
|
||||
@ -9594,7 +9620,7 @@ jQuery.extend( {
|
||||
if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
|
||||
cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
|
||||
|
||||
// #9682: remove data so that it's not used in an eventual retry
|
||||
// trac-9682: remove data so that it's not used in an eventual retry
|
||||
delete s.data;
|
||||
}
|
||||
|
||||
@ -9867,7 +9893,7 @@ jQuery._evalUrl = function( url, options, doc ) {
|
||||
return jQuery.ajax( {
|
||||
url: url,
|
||||
|
||||
// Make this explicit, since user can override this through ajaxSetup (#11264)
|
||||
// Make this explicit, since user can override this through ajaxSetup (trac-11264)
|
||||
type: "GET",
|
||||
dataType: "script",
|
||||
cache: true,
|
||||
@ -9976,7 +10002,7 @@ var xhrSuccessStatus = {
|
||||
0: 200,
|
||||
|
||||
// Support: IE <=9 only
|
||||
// #1450: sometimes IE returns 1223 when it should be 204
|
||||
// trac-1450: sometimes IE returns 1223 when it should be 204
|
||||
1223: 204
|
||||
},
|
||||
xhrSupported = jQuery.ajaxSettings.xhr();
|
||||
@ -10048,7 +10074,7 @@ jQuery.ajaxTransport( function( options ) {
|
||||
} else {
|
||||
complete(
|
||||
|
||||
// File: protocol always yields status 0; see #8605, #14207
|
||||
// File: protocol always yields status 0; see trac-8605, trac-14207
|
||||
xhr.status,
|
||||
xhr.statusText
|
||||
);
|
||||
@ -10109,7 +10135,7 @@ jQuery.ajaxTransport( function( options ) {
|
||||
xhr.send( options.hasContent && options.data || null );
|
||||
} catch ( e ) {
|
||||
|
||||
// #14683: Only rethrow if this hasn't been notified as an error yet
|
||||
// trac-14683: Only rethrow if this hasn't been notified as an error yet
|
||||
if ( callback ) {
|
||||
throw e;
|
||||
}
|
||||
@ -10753,7 +10779,9 @@ jQuery.each(
|
||||
|
||||
// Support: Android <=4.0 only
|
||||
// Make sure we trim BOM and NBSP
|
||||
var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
|
||||
// Require that the "whitespace run" starts from a non-whitespace
|
||||
// to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position.
|
||||
var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;
|
||||
|
||||
// Bind a function to a context, optionally partially applying any
|
||||
// arguments.
|
||||
@ -10820,7 +10848,7 @@ jQuery.isNumeric = function( obj ) {
|
||||
jQuery.trim = function( text ) {
|
||||
return text == null ?
|
||||
"" :
|
||||
( text + "" ).replace( rtrim, "" );
|
||||
( text + "" ).replace( rtrim, "$1" );
|
||||
};
|
||||
|
||||
|
||||
@ -10868,8 +10896,8 @@ jQuery.noConflict = function( deep ) {
|
||||
};
|
||||
|
||||
// Expose jQuery and $ identifiers, even in AMD
|
||||
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
|
||||
// and CommonJS for browser emulators (#13566)
|
||||
// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557)
|
||||
// and CommonJS for browser emulators (trac-13566)
|
||||
if ( typeof noGlobal === "undefined" ) {
|
||||
window.jQuery = window.$ = jQuery;
|
||||
}
|
||||
|
4
libraries/jquery.min.js
vendored
4
libraries/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1103
package-lock.json
generated
1103
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
27
package.json
27
package.json
@ -27,11 +27,11 @@
|
||||
"postinstall": "rimraf ./node_modules/canvas"
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron/remote": "2.0.8",
|
||||
"@excalidraw/excalidraw": "0.12.0",
|
||||
"@electron/remote": "2.0.9",
|
||||
"@excalidraw/excalidraw": "0.13.0",
|
||||
"archiver": "5.3.1",
|
||||
"async-mutex": "0.4.0",
|
||||
"axios": "1.1.3",
|
||||
"axios": "1.2.1",
|
||||
"better-sqlite3": "7.4.5",
|
||||
"chokidar": "3.5.3",
|
||||
"cls-hooked": "4.2.2",
|
||||
@ -39,18 +39,19 @@
|
||||
"compression": "1.7.4",
|
||||
"cookie-parser": "1.4.6",
|
||||
"csurf": "1.11.0",
|
||||
"dayjs": "1.11.6",
|
||||
"dayjs": "1.11.7",
|
||||
"dayjs-plugin-utc": "^0.1.2",
|
||||
"debounce": "^1.2.1",
|
||||
"ejs": "3.1.8",
|
||||
"electron-debug": "3.2.0",
|
||||
"electron-dl": "3.4.1",
|
||||
"electron-dl": "3.5.0",
|
||||
"electron-window-state": "5.0.3",
|
||||
"express": "4.18.2",
|
||||
"express-partial-content": "1.0.2",
|
||||
"express-rate-limit": "6.6.0",
|
||||
"express-rate-limit": "6.7.0",
|
||||
"express-session": "1.17.3",
|
||||
"fs-extra": "10.1.0",
|
||||
"helmet": "6.0.0",
|
||||
"fs-extra": "11.1.0",
|
||||
"helmet": "6.0.1",
|
||||
"html": "1.0.0",
|
||||
"html2plaintext": "2.1.4",
|
||||
"http-proxy-agent": "5.0.0",
|
||||
@ -61,10 +62,10 @@
|
||||
"is-svg": "4.3.2",
|
||||
"jimp": "0.16.2",
|
||||
"joplin-turndown-plugin-gfm": "1.0.12",
|
||||
"jsdom": "20.0.2",
|
||||
"jsdom": "20.0.3",
|
||||
"mime-types": "2.1.35",
|
||||
"multer": "1.4.5-lts.1",
|
||||
"node-abi": "3.28.0",
|
||||
"node-abi": "3.30.0",
|
||||
"normalize-strings": "1.1.1",
|
||||
"open": "8.4.0",
|
||||
"rand-token": "1.0.1",
|
||||
@ -74,7 +75,7 @@
|
||||
"rimraf": "3.0.2",
|
||||
"safe-compare": "1.1.4",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"sanitize-html": "2.7.3",
|
||||
"sanitize-html": "2.8.0",
|
||||
"sax": "1.2.4",
|
||||
"semver": "7.3.8",
|
||||
"serve-favicon": "2.5.0",
|
||||
@ -98,8 +99,8 @@
|
||||
"jsdoc": "4.0.0",
|
||||
"lorem-ipsum": "2.0.8",
|
||||
"rcedit": "3.0.1",
|
||||
"webpack": "5.74.0",
|
||||
"webpack-cli": "4.10.0"
|
||||
"webpack": "5.75.0",
|
||||
"webpack-cli": "5.0.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"electron-installer-debian": "3.1.0"
|
||||
|
@ -4,7 +4,7 @@ const Branch = require('../../src/becca/entities/branch');
|
||||
const SearchContext = require('../../src/services/search/search_context');
|
||||
const dateUtils = require('../../src/services/date_utils');
|
||||
const becca = require('../../src/becca/becca');
|
||||
const {NoteBuilder, findNoteByTitle, note} = require('./becca_mocking.js');
|
||||
const {NoteBuilder, findNoteByTitle, note} = require('./becca_mocking');
|
||||
|
||||
describe("Search", () => {
|
||||
let rootNote;
|
||||
|
@ -1,4 +1,4 @@
|
||||
const {note} = require('./becca_mocking.js');
|
||||
const {note} = require('./becca_mocking');
|
||||
const ValueExtractor = require('../../src/services/search/value_extractor');
|
||||
const becca = require('../../src/becca/becca');
|
||||
const SearchContext = require("../../src/services/search/search_context");
|
||||
|
@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
const becca = require('./becca.js');
|
||||
const becca = require('./becca');
|
||||
const cls = require('../services/cls');
|
||||
const protectedSessionService = require('../services/protected_session');
|
||||
const log = require('../services/log');
|
||||
@ -83,8 +83,10 @@ function getNoteTitleArrayForPath(notePathArray) {
|
||||
throw new Error(`${notePathArray} is not an array.`);
|
||||
}
|
||||
|
||||
if (notePathArray.length === 1 && notePathArray[0] === cls.getHoistedNoteId()) {
|
||||
return [getNoteTitle(cls.getHoistedNoteId())];
|
||||
const hoistedNoteId = cls.getHoistedNoteId();
|
||||
|
||||
if (notePathArray.length === 1 && notePathArray[0] === hoistedNoteId) {
|
||||
return [getNoteTitle(hoistedNoteId)];
|
||||
}
|
||||
|
||||
const titles = [];
|
||||
@ -92,6 +94,9 @@ function getNoteTitleArrayForPath(notePathArray) {
|
||||
let parentNoteId = 'root';
|
||||
let hoistedNotePassed = false;
|
||||
|
||||
// this is a notePath from outside of hoisted subtree so full title path needs to be returned
|
||||
const outsideOfHoistedSubtree = !notePathArray.includes(hoistedNoteId);
|
||||
|
||||
for (const noteId of notePathArray) {
|
||||
// start collecting path segment titles only after hoisted note
|
||||
if (hoistedNotePassed) {
|
||||
@ -100,7 +105,7 @@ function getNoteTitleArrayForPath(notePathArray) {
|
||||
titles.push(title);
|
||||
}
|
||||
|
||||
if (noteId === cls.getHoistedNoteId()) {
|
||||
if (!hoistedNotePassed && (noteId === hoistedNoteId || outsideOfHoistedSubtree)) {
|
||||
hoistedNotePassed = true;
|
||||
}
|
||||
|
||||
@ -124,8 +129,9 @@ function getNoteTitleForPath(notePathArray) {
|
||||
*/
|
||||
function getSomePath(note, path = []) {
|
||||
// first try to find note within hoisted note, otherwise take any existing note path
|
||||
return getSomePathInner(note, path, true)
|
||||
|| getSomePathInner(note, path, false);
|
||||
// each branch needs a separate copy since it's mutable
|
||||
return getSomePathInner(note, [...path], true)
|
||||
|| getSomePathInner(note, [...path], false);
|
||||
}
|
||||
|
||||
function getSomePathInner(note, path, respectHoisting) {
|
||||
|
@ -62,8 +62,9 @@ class Attribute extends AbstractEntity {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
init() {
|
||||
this.validate();
|
||||
|
||||
if (this.attributeId) {
|
||||
this.becca.attributes[this.attributeId] = this;
|
||||
}
|
||||
@ -86,6 +87,16 @@ class Attribute extends AbstractEntity {
|
||||
}
|
||||
}
|
||||
|
||||
validate() {
|
||||
if (!["label", "relation"].includes(this.type)) {
|
||||
throw new Error(`Invalid attribute type '${this.type}' in attribute '${this.attributeId}'`);
|
||||
}
|
||||
|
||||
if (!this.name?.trim()) {
|
||||
throw new Error(`Invalid empty name in attribute '${this.attributeId}'`);
|
||||
}
|
||||
}
|
||||
|
||||
get isAffectingSubtree() {
|
||||
return this.isInheritable
|
||||
|| (this.type === 'relation' && this.name === 'template');
|
||||
@ -113,7 +124,13 @@ class Attribute extends AbstractEntity {
|
||||
* @returns {Note|null}
|
||||
*/
|
||||
getNote() {
|
||||
return this.becca.getNote(this.noteId);
|
||||
const note = this.becca.getNote(this.noteId);
|
||||
|
||||
if (!note) {
|
||||
throw new Error(`Note '${this.noteId}' of attribute '${this.attributeId}', type '${this.type}', name '${this.name}' does not exist.`);
|
||||
}
|
||||
|
||||
return note;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,11 +174,13 @@ class Attribute extends AbstractEntity {
|
||||
}
|
||||
|
||||
beforeSaving() {
|
||||
if (!this.value) {
|
||||
if (this.type === 'relation') {
|
||||
throw new Error(`Cannot save relation ${this.name} since it does not target any note.`);
|
||||
}
|
||||
this.validate();
|
||||
|
||||
if (this.type === 'relation') {
|
||||
if (!(this.value in this.becca.notes)) {
|
||||
throw new Error(`Cannot save relation '${this.name}' since it target not existing note '${this.value}'.`);
|
||||
}
|
||||
} else if (!this.value) {
|
||||
// null value isn't allowed
|
||||
this.value = "";
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ const Note = require('./note');
|
||||
const AbstractEntity = require("./abstract_entity");
|
||||
const sql = require("../../services/sql");
|
||||
const dateUtils = require("../../services/date_utils");
|
||||
const utils = require("../../services/utils.js");
|
||||
const utils = require("../../services/utils");
|
||||
const TaskContext = require("../../services/task_context");
|
||||
const cls = require("../../services/cls");
|
||||
const log = require("../../services/log");
|
||||
@ -119,6 +119,19 @@ class Branch extends AbstractEntity {
|
||||
return !(this.branchId in this.becca.branches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Branch is weak when its existence should not hinder deletion of its note.
|
||||
* As a result, note with only weak branches should be immediately deleted.
|
||||
* An example is shared or bookmarked clones - they are created automatically and exist for technical reasons,
|
||||
* not as user-intended actions. From user perspective, they don't count as real clones and for the purpose
|
||||
* of deletion should not act as a clone.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
get isWeak() {
|
||||
return ['share', 'lbBookmarks'].includes(this.parentNoteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a branch. If this is a last note's branch, delete the note as well.
|
||||
*
|
||||
@ -159,9 +172,13 @@ class Branch extends AbstractEntity {
|
||||
|
||||
this.markAsDeleted(deleteId);
|
||||
|
||||
const notDeletedBranches = note.getParentBranches();
|
||||
const notDeletedBranches = note.getStrongParentBranches();
|
||||
|
||||
if (notDeletedBranches.length === 0) {
|
||||
for (const weakBranch of note.getParentBranches()) {
|
||||
weakBranch.markAsDeleted(deleteId);
|
||||
}
|
||||
|
||||
for (const childBranch of note.getChildBranches()) {
|
||||
childBranch.deleteBranch(deleteId, taskContext);
|
||||
}
|
||||
@ -170,9 +187,7 @@ class Branch extends AbstractEntity {
|
||||
|
||||
log.info("Deleting note " + note.noteId);
|
||||
|
||||
// marking note as deleted as a signal to event handlers that the note is being deleted
|
||||
// (isDeleted is being checked against becca)
|
||||
delete this.becca.notes[note.noteId];
|
||||
this.becca.notes[note.noteId].isBeingDeleted = true;
|
||||
|
||||
for (const attribute of note.getOwnedAttributes()) {
|
||||
attribute.markAsDeleted(deleteId);
|
||||
@ -193,9 +208,15 @@ class Branch extends AbstractEntity {
|
||||
|
||||
beforeSaving() {
|
||||
if (this.notePosition === undefined || this.notePosition === null) {
|
||||
// TODO finding new position can be refactored into becca
|
||||
const maxNotePos = sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [this.parentNoteId]);
|
||||
this.notePosition = maxNotePos === null ? 0 : maxNotePos + 10;
|
||||
let maxNotePos = 0;
|
||||
|
||||
for (const childBranch of this.parentNote.getChildBranches()) {
|
||||
if (maxNotePos < childBranch.notePosition && childBranch.branchId !== 'hidden') {
|
||||
maxNotePos = childBranch.notePosition;
|
||||
}
|
||||
}
|
||||
|
||||
this.notePosition = maxNotePos + 10;
|
||||
}
|
||||
|
||||
if (!this.isExpanded) {
|
||||
|
@ -11,7 +11,6 @@ const NoteRevision = require("./note_revision");
|
||||
const TaskContext = require("../../services/task_context");
|
||||
const dayjs = require("dayjs");
|
||||
const utc = require('dayjs/plugin/utc');
|
||||
const searchService = require("../../services/search/services/search.js");
|
||||
dayjs.extend(utc)
|
||||
|
||||
const LABEL = 'label';
|
||||
@ -73,6 +72,8 @@ class Note extends AbstractEntity {
|
||||
this.utcDateCreated = utcDateCreated || dateUtils.utcNowDateTime();
|
||||
/** @type {string} */
|
||||
this.utcDateModified = utcDateModified;
|
||||
/** @type {boolean} - set during the deletion operation, before it is completed (removed from becca completely) */
|
||||
this.isBeingDeleted = false;
|
||||
|
||||
// ------ Derived attributes ------
|
||||
|
||||
@ -155,6 +156,15 @@ class Note extends AbstractEntity {
|
||||
return this.parentBranches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <i>strong</i> (as opposed to <i>weak</i>) parent branches. See isWeak for details.
|
||||
*
|
||||
* @returns {Branch[]}
|
||||
*/
|
||||
getStrongParentBranches() {
|
||||
return this.getParentBranches().filter(branch => !branch.isWeak);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Branch[]}
|
||||
* @deprecated use getParentBranches() instead
|
||||
@ -1319,8 +1329,16 @@ class Note extends AbstractEntity {
|
||||
}
|
||||
}
|
||||
|
||||
isLaunchBarConfig() {
|
||||
return this.type === 'launcher' || ['lbRoot', 'lbAvailableLaunchers', 'lbVisibleLaunchers'].includes(this.noteId);
|
||||
}
|
||||
|
||||
isOptions() {
|
||||
return this.noteId.startsWith("options");
|
||||
}
|
||||
|
||||
get isDeleted() {
|
||||
return !(this.noteId in this.becca.notes);
|
||||
return !(this.noteId in this.becca.notes) || this.isBeingDeleted;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
const becca = require('./becca');
|
||||
const log = require('../services/log');
|
||||
const beccaService = require('./becca_service.js');
|
||||
const beccaService = require('./becca_service');
|
||||
const dateUtils = require('../services/date_utils');
|
||||
const { JSDOM } = require("jsdom");
|
||||
|
||||
|
7
src/errors/not_found_error.js
Normal file
7
src/errors/not_found_error.js
Normal file
@ -0,0 +1,7 @@
|
||||
class NotFoundError {
|
||||
constructor(message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NotFoundError;
|
7
src/errors/validation_error.js
Normal file
7
src/errors/validation_error.js
Normal file
@ -0,0 +1,7 @@
|
||||
class ValidationError {
|
||||
constructor(message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ValidationError;
|
@ -1,5 +1,5 @@
|
||||
const appInfo = require('../services/app_info');
|
||||
const eu = require("./etapi_utils.js");
|
||||
const eu = require("./etapi_utils");
|
||||
|
||||
function register(router) {
|
||||
eu.route(router, 'get', '/etapi/app-info', (req, res, next) => {
|
||||
|
@ -709,7 +709,7 @@ components:
|
||||
- image
|
||||
- search
|
||||
- book
|
||||
- relation-map
|
||||
- relationMap
|
||||
- render
|
||||
mime:
|
||||
type: string
|
||||
@ -747,7 +747,7 @@ components:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
enum: [text, code, render, file, image, search, relation-map, book, note-map, mermaid]
|
||||
enum: [text, code, render, file, image, search, relationMap, book, noteMap, mermaid, webView, shortcut]
|
||||
mime:
|
||||
type: string
|
||||
isProtected:
|
||||
|
@ -1,24 +1,26 @@
|
||||
import froca from "./froca.js";
|
||||
import bundleService from "./bundle.js";
|
||||
import froca from "../services/froca.js";
|
||||
import bundleService from "../services/bundle.js";
|
||||
import RootCommandExecutor from "./root_command_executor.js";
|
||||
import Entrypoints from "./entrypoints.js";
|
||||
import options from "./options.js";
|
||||
import utils from "./utils.js";
|
||||
import zoomService from "./zoom.js";
|
||||
import options from "../services/options.js";
|
||||
import utils from "../services/utils.js";
|
||||
import zoomComponent from "./zoom.js";
|
||||
import TabManager from "./tab_manager.js";
|
||||
import treeService from "./tree.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import keyboardActionsService from "./keyboard_actions.js";
|
||||
import MobileScreenSwitcherExecutor from "../widgets/mobile_widgets/mobile_screen_switcher.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import Component from "./component.js";
|
||||
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||
import MobileScreenSwitcherExecutor from "./mobile_screen_switcher.js";
|
||||
import MainTreeExecutors from "./main_tree_executors.js";
|
||||
import toast from "./toast.js";
|
||||
import toast from "../services/toast.js";
|
||||
import ShortcutComponent from "./shortcut_component.js";
|
||||
|
||||
class AppContext extends Component {
|
||||
constructor(isMainWindow) {
|
||||
super();
|
||||
|
||||
this.isMainWindow = isMainWindow;
|
||||
this.executors = [];
|
||||
// non-widget/layout components needed for the application
|
||||
this.components = [];
|
||||
this.beforeUnloadListeners = [];
|
||||
}
|
||||
|
||||
@ -27,16 +29,42 @@ class AppContext extends Component {
|
||||
}
|
||||
|
||||
async start() {
|
||||
await Promise.all([froca.initializedPromise, options.initializedPromise]);
|
||||
this.initComponents();
|
||||
|
||||
this.showWidgets();
|
||||
this.renderWidgets();
|
||||
|
||||
await Promise.all([froca.initializedPromise, options.initializedPromise]);
|
||||
|
||||
this.tabManager.loadTabs();
|
||||
|
||||
setTimeout(() => bundleService.executeStartupBundles(), 2000);
|
||||
}
|
||||
|
||||
showWidgets() {
|
||||
initComponents() {
|
||||
this.tabManager = new TabManager();
|
||||
|
||||
this.components = [
|
||||
this.tabManager,
|
||||
new RootCommandExecutor(),
|
||||
new Entrypoints(),
|
||||
new MainTreeExecutors(),
|
||||
new ShortcutComponent()
|
||||
];
|
||||
|
||||
if (utils.isMobile()) {
|
||||
this.components.push(new MobileScreenSwitcherExecutor());
|
||||
}
|
||||
|
||||
for (const component of this.components) {
|
||||
this.child(component);
|
||||
}
|
||||
|
||||
if (utils.isElectron()) {
|
||||
this.child(zoomComponent);
|
||||
}
|
||||
}
|
||||
|
||||
renderWidgets() {
|
||||
const rootWidget = this.layout.getRootWidget(this);
|
||||
const $renderedWidget = rootWidget.render();
|
||||
|
||||
@ -52,29 +80,8 @@ class AppContext extends Component {
|
||||
component.triggerCommand(commandName, {$el: $(this)});
|
||||
});
|
||||
|
||||
this.tabManager = new TabManager();
|
||||
|
||||
this.executors = [
|
||||
this.tabManager,
|
||||
new RootCommandExecutor(),
|
||||
new Entrypoints(),
|
||||
new MainTreeExecutors()
|
||||
];
|
||||
|
||||
if (utils.isMobile()) {
|
||||
this.executors.push(new MobileScreenSwitcherExecutor());
|
||||
}
|
||||
|
||||
this.child(rootWidget);
|
||||
|
||||
for (const executor of this.executors) {
|
||||
this.child(executor);
|
||||
}
|
||||
|
||||
if (utils.isElectron()) {
|
||||
this.child(zoomService);
|
||||
}
|
||||
|
||||
this.triggerEvent('initialRenderComplete');
|
||||
}
|
||||
|
||||
@ -85,7 +92,7 @@ class AppContext extends Component {
|
||||
|
||||
/** @returns {Promise} */
|
||||
triggerCommand(name, data = {}) {
|
||||
for (const executor of this.executors) {
|
||||
for (const executor of this.components) {
|
||||
const fun = executor[name + "Command"];
|
||||
|
||||
if (fun) {
|
||||
@ -143,19 +150,11 @@ $(window).on('beforeunload', () => {
|
||||
}
|
||||
});
|
||||
|
||||
function isNotePathInAddress() {
|
||||
const [notePath, ntxId] = treeService.getHashValueFromAddress();
|
||||
|
||||
return notePath.startsWith("root")
|
||||
// empty string is for empty/uninitialized tab
|
||||
|| (notePath === '' && !!ntxId);
|
||||
}
|
||||
|
||||
$(window).on('hashchange', function() {
|
||||
if (isNotePathInAddress()) {
|
||||
if (treeService.isNotePathInAddress()) {
|
||||
const [notePath, ntxId] = treeService.getHashValueFromAddress();
|
||||
|
||||
if (!notePath) {
|
||||
if (!notePath && !ntxId) {
|
||||
console.log(`Invalid hash value "${document.location.hash}", ignoring.`);
|
||||
return;
|
||||
}
|
@ -13,7 +13,7 @@ import utils from '../services/utils.js';
|
||||
*/
|
||||
export default class Component {
|
||||
constructor() {
|
||||
this.componentId = `comp-` + this.sanitizedClassName + '-' + utils.randomString(8);
|
||||
this.componentId = this.sanitizedClassName + '-' + utils.randomString(8);
|
||||
/** @type Component[] */
|
||||
this.children = [];
|
||||
this.initialized = null;
|
||||
@ -42,16 +42,23 @@ export default class Component {
|
||||
|
||||
/** @returns {Promise} */
|
||||
handleEvent(name, data) {
|
||||
const callMethodPromise = this.initialized
|
||||
? this.initialized.then(() => this.callMethod(this[name + 'Event'], data))
|
||||
: this.callMethod(this[name + 'Event'], data);
|
||||
try {
|
||||
const callMethodPromise = this.initialized
|
||||
? this.initialized.then(() => this.callMethod(this[name + 'Event'], data))
|
||||
: this.callMethod(this[name + 'Event'], data);
|
||||
|
||||
const childrenPromise = this.handleEventInChildren(name, data);
|
||||
const childrenPromise = this.handleEventInChildren(name, data);
|
||||
|
||||
// don't create promises if not needed (optimization)
|
||||
return callMethodPromise && childrenPromise
|
||||
? Promise.all([callMethodPromise, childrenPromise])
|
||||
: (callMethodPromise || childrenPromise);
|
||||
// don't create promises if not needed (optimization)
|
||||
return callMethodPromise && childrenPromise
|
||||
? Promise.all([callMethodPromise, childrenPromise])
|
||||
: (callMethodPromise || childrenPromise);
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`Handling of event '${name}' failed in ${this.constructor.name} with error ${e.message} ${e.stack}`);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {Promise} */
|
@ -1,13 +1,13 @@
|
||||
import utils from "./utils.js";
|
||||
import dateNoteService from "./date_notes.js";
|
||||
import protectedSessionHolder from './protected_session_holder.js';
|
||||
import server from "./server.js";
|
||||
import utils from "../services/utils.js";
|
||||
import dateNoteService from "../services/date_notes.js";
|
||||
import protectedSessionHolder from '../services/protected_session_holder.js';
|
||||
import server from "../services/server.js";
|
||||
import appContext from "./app_context.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import toastService from "./toast.js";
|
||||
import ws from "./ws.js";
|
||||
import bundleService from "./bundle.js";
|
||||
import froca from "./froca.js";
|
||||
import Component from "./component.js";
|
||||
import toastService from "../services/toast.js";
|
||||
import ws from "../services/ws.js";
|
||||
import bundleService from "../services/bundle.js";
|
||||
import froca from "../services/froca.js";
|
||||
|
||||
export default class Entrypoints extends Component {
|
||||
constructor() {
|
||||
@ -86,11 +86,7 @@ export default class Entrypoints extends Component {
|
||||
if (win.isFullScreenable()) {
|
||||
win.setFullScreen(!win.isFullScreen());
|
||||
}
|
||||
}
|
||||
else {
|
||||
// outside of electron this is handled by the browser
|
||||
this.$widget.find(".toggle-fullscreen-button").hide();
|
||||
}
|
||||
} // outside of electron this is handled by the browser
|
||||
}
|
||||
|
||||
reloadFrontendAppCommand() {
|
||||
@ -190,16 +186,20 @@ export default class Entrypoints extends Component {
|
||||
toastService.showMessage("Note executed");
|
||||
}
|
||||
|
||||
hideAllTooltips() {
|
||||
hideAllPopups() {
|
||||
$(".tooltip").removeClass("show");
|
||||
|
||||
if (utils.isDesktop()) {
|
||||
$(".aa-input").autocomplete("close");
|
||||
}
|
||||
}
|
||||
|
||||
noteSwitchedEvent() {
|
||||
this.hideAllTooltips();
|
||||
this.hideAllPopups();
|
||||
}
|
||||
|
||||
activeContextChangedEvent() {
|
||||
this.hideAllTooltips();
|
||||
this.hideAllPopups();
|
||||
}
|
||||
|
||||
async forceSaveNoteRevisionCommand() {
|
@ -1,8 +1,8 @@
|
||||
import appContext from "./app_context.js";
|
||||
import noteCreateService from "./note_create.js";
|
||||
import treeService from "./tree.js";
|
||||
import hoistedNoteService from "./hoisted_note.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import Component from "./component.js";
|
||||
|
||||
/**
|
||||
* This class contains command executors which logically belong to the NoteTree widget, but for better user experience
|
||||
@ -11,7 +11,7 @@ import Component from "../widgets/component.js";
|
||||
*/
|
||||
export default class MainTreeExecutors extends Component {
|
||||
get tree() {
|
||||
return appContext.mainTreeWidget;
|
||||
return appContext.noteTreeWidget;
|
||||
}
|
||||
|
||||
async cloneNotesToCommand() {
|
@ -1,15 +1,18 @@
|
||||
import Component from "../component.js";
|
||||
import Component from "./component.js";
|
||||
import appContext from "./app_context.js";
|
||||
|
||||
export default class MobileScreenSwitcherExecutor extends Component {
|
||||
setActiveScreenCommand({screen}) {
|
||||
if (screen !== this.activeScreen) {
|
||||
this.activeScreen = screen;
|
||||
|
||||
if (screen === 'tree') {
|
||||
const activeNoteContext = appContext.tabManager.getActiveContext();
|
||||
|
||||
activeNoteContext.setEmpty();
|
||||
}
|
||||
|
||||
this.triggerEvent('activeScreenChanged', {activeScreen: screen});
|
||||
}
|
||||
}
|
||||
|
||||
initialRenderCompleteEvent() {
|
||||
this.setActiveScreenCommand({screen: 'tree'});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
import protectedSessionHolder from "./protected_session_holder.js";
|
||||
import server from "./server.js";
|
||||
import utils from "./utils.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import server from "../services/server.js";
|
||||
import utils from "../services/utils.js";
|
||||
import appContext from "./app_context.js";
|
||||
import treeService from "./tree.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import froca from "./froca.js";
|
||||
import hoistedNoteService from "./hoisted_note.js";
|
||||
import options from "./options.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import Component from "./component.js";
|
||||
import froca from "../services/froca.js";
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import options from "../services/options.js";
|
||||
|
||||
class NoteContext extends Component {
|
||||
/**
|
||||
@ -24,7 +24,7 @@ class NoteContext extends Component {
|
||||
this.notePath = null;
|
||||
this.noteId = null;
|
||||
this.parentNoteId = null;
|
||||
this.hoistedNoteId = 'root';
|
||||
// hoisted note is kept intentionally
|
||||
|
||||
this.triggerEvent('noteSwitched', {
|
||||
noteContext: this,
|
||||
@ -32,6 +32,10 @@ class NoteContext extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
isEmpty() {
|
||||
return !this.noteId;
|
||||
}
|
||||
|
||||
async setNote(inputNotePath, triggerSwitchEvent = true) {
|
||||
const resolvedNotePath = await this.getResolvedNotePath(inputNotePath);
|
||||
|
||||
@ -59,9 +63,25 @@ class NoteContext extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
if (utils.isDesktop()) {
|
||||
// close dangling autocompletes after closing the tab
|
||||
$(".aa-input").autocomplete("close");
|
||||
if (this.hoistedNoteId === 'root'
|
||||
&& this.notePath.startsWith("root/hidden")
|
||||
&& !this.note.hasLabel("keepCurrentHoisting")
|
||||
) {
|
||||
// hidden subtree displays only when hoisted so it doesn't make sense to keep root as hoisted note
|
||||
|
||||
let hoistedNoteId = 'hidden';
|
||||
|
||||
if (this.note.isLaunchBarConfig()) {
|
||||
hoistedNoteId = 'lbRoot';
|
||||
} else if (this.note.isOptions()) {
|
||||
hoistedNoteId = 'options';
|
||||
}
|
||||
|
||||
await this.setHoistedNoteId(hoistedNoteId);
|
||||
}
|
||||
|
||||
if (utils.isMobile()) {
|
||||
this.triggerCommand('setActiveScreen', {screen: 'detail'});
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +168,8 @@ class NoteContext extends Component {
|
||||
}
|
||||
|
||||
getTabState() {
|
||||
if (!this.notePath) {
|
||||
if (!this.notePath && this.hoistedNoteId === 'root') {
|
||||
// keeping empty hoisted tab is esp. important for mobile (e.g. opened launcher config)
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -166,9 +187,13 @@ class NoteContext extends Component {
|
||||
}
|
||||
|
||||
async setHoistedNoteId(noteIdToHoist) {
|
||||
if (this.hoistedNoteId === noteIdToHoist) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hoistedNoteId = noteIdToHoist;
|
||||
|
||||
if (!this.notePathArray?.includes(noteIdToHoist)) {
|
||||
if (!this.notePathArray?.includes(noteIdToHoist) && !utils.isMobile()) {
|
||||
await this.setNote(noteIdToHoist);
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import Component from "../widgets/component.js";
|
||||
import Component from "./component.js";
|
||||
import appContext from "./app_context.js";
|
||||
import dateNoteService from "../services/date_notes.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import openService from "./open.js";
|
||||
import protectedSessionService from "./protected_session.js";
|
||||
import options from "./options.js";
|
||||
import froca from "./froca.js";
|
||||
import openService from "../services/open.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import options from "../services/options.js";
|
||||
import froca from "../services/froca.js";
|
||||
|
||||
export default class RootCommandExecutor extends Component {
|
||||
editReadOnlyNoteCommand() {
|
||||
@ -46,7 +46,7 @@ export default class RootCommandExecutor extends Component {
|
||||
openNoteExternallyCommand() {
|
||||
const noteId = appContext.tabManager.getActiveContextNoteId();
|
||||
const mime = appContext.tabManager.getActiveContextNoteMime()
|
||||
|
||||
|
||||
if (noteId) {
|
||||
openService.openNoteExternally(noteId, mime);
|
||||
}
|
||||
@ -71,4 +71,20 @@ export default class RootCommandExecutor extends Component {
|
||||
toggleLeftPaneCommand() {
|
||||
options.toggle('leftPaneVisible');
|
||||
}
|
||||
|
||||
async showLaunchBarSubtreeCommand() {
|
||||
await appContext.tabManager.openContextWithNote('lbRoot', true, null, 'lbRoot');
|
||||
}
|
||||
|
||||
async showShareSubtreeCommand() {
|
||||
await appContext.tabManager.openContextWithNote('share', true, null, 'share');
|
||||
}
|
||||
|
||||
async showHiddenSubtreeCommand() {
|
||||
await appContext.tabManager.openContextWithNote('hidden', true, null, 'hidden');
|
||||
}
|
||||
|
||||
async showOptionsCommand() {
|
||||
await appContext.tabManager.openContextWithNote('options', true, null, 'options')
|
||||
}
|
||||
}
|
40
src/public/app/components/shortcut_component.js
Normal file
40
src/public/app/components/shortcut_component.js
Normal file
@ -0,0 +1,40 @@
|
||||
import appContext from "./app_context.js";
|
||||
import shortcutService from "../services/shortcuts.js";
|
||||
import server from "../services/server.js";
|
||||
import Component from "./component.js";
|
||||
import froca from "../services/froca.js";
|
||||
|
||||
export default class ShortcutComponent extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
server.get('keyboard-shortcuts-for-notes').then(shortcutAttributes => {
|
||||
for (const attr of shortcutAttributes) {
|
||||
this.bindNoteShortcutHandler(attr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bindNoteShortcutHandler(label) {
|
||||
const handler = () => appContext.tabManager.getActiveContext().setNote(label.noteId);
|
||||
const namespace = label.attributeId;
|
||||
|
||||
if (label.isDeleted) {
|
||||
shortcutService.removeGlobalShortcut(namespace);
|
||||
} else {
|
||||
shortcutService.bindGlobalShortcut(label.value, handler, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent({loadResults}) {
|
||||
for (const attr of loadResults.getAttributes()) {
|
||||
if (attr.type === 'label' && attr.name === 'keyboardShortcut') {
|
||||
const note = await froca.getNote(attr.noteId);
|
||||
// launcher shortcuts are handled specifically
|
||||
if (note && note.type !== 'launcher') {
|
||||
this.bindNoteShortcutHandler(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import Component from "../widgets/component.js";
|
||||
import SpacedUpdate from "./spaced_update.js";
|
||||
import server from "./server.js";
|
||||
import options from "./options.js";
|
||||
import froca from "./froca.js";
|
||||
import treeService from "./tree.js";
|
||||
import utils from "./utils.js";
|
||||
import Component from "./component.js";
|
||||
import SpacedUpdate from "../services/spaced_update.js";
|
||||
import server from "../services/server.js";
|
||||
import options from "../services/options.js";
|
||||
import froca from "../services/froca.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import utils from "../services/utils.js";
|
||||
import NoteContext from "./note_context.js";
|
||||
import appContext from "./app_context.js";
|
||||
import Mutex from "../utils/mutex.js";
|
||||
@ -48,69 +48,69 @@ export default class TabManager extends Component {
|
||||
}
|
||||
|
||||
async loadTabs() {
|
||||
const tabsToOpen = appContext.isMainWindow
|
||||
? (options.getJson('openTabs') || [])
|
||||
: [];
|
||||
try {
|
||||
const tabsToOpen = appContext.isMainWindow
|
||||
? (options.getJson('openTabs') || [])
|
||||
: [];
|
||||
|
||||
// if there's notePath in the URL, make sure it's open and active
|
||||
// (useful, among others, for opening clipped notes from clipper)
|
||||
if (window.location.hash) {
|
||||
const notePath = window.location.hash.substr(1);
|
||||
const noteId = treeService.getNoteIdFromNotePath(notePath);
|
||||
let filteredTabs = [];
|
||||
|
||||
if (noteId && await froca.noteExists(noteId)) {
|
||||
for (const tab of tabsToOpen) {
|
||||
tab.active = false;
|
||||
// preload all notes at once
|
||||
await froca.getNotes([
|
||||
tabsToOpen.map(tab => treeService.getNoteIdFromNotePath(tab.notePath)),
|
||||
tabsToOpen.map(tab => tab.hoistedNoteId),
|
||||
], true);
|
||||
|
||||
for (const openTab of tabsToOpen) {
|
||||
if (openTab.notePath && !(treeService.getNoteIdFromNotePath(openTab.notePath) in froca.notes)) {
|
||||
// note doesn't exist so don't try to open tab for it
|
||||
continue;
|
||||
}
|
||||
|
||||
const foundTab = tabsToOpen.find(tab => noteId === treeService.getNoteIdFromNotePath(tab.notePath));
|
||||
|
||||
if (foundTab) {
|
||||
foundTab.active = true;
|
||||
if (!(openTab.hoistedNoteId in froca.notes)) {
|
||||
openTab.hoistedNoteId = 'root';
|
||||
}
|
||||
else {
|
||||
tabsToOpen.push({
|
||||
notePath: notePath,
|
||||
active: true,
|
||||
hoistedNoteId: glob.extraHoistedNoteId || 'root'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let filteredTabs = [];
|
||||
|
||||
for (const openTab of tabsToOpen) {
|
||||
const noteId = treeService.getNoteIdFromNotePath(openTab.notePath);
|
||||
|
||||
if (await froca.noteExists(noteId)) {
|
||||
// note doesn't exist so don't try to open tab for it
|
||||
filteredTabs.push(openTab);
|
||||
}
|
||||
}
|
||||
|
||||
if (utils.isMobile()) {
|
||||
// mobile frontend doesn't have tabs so show only the active tab
|
||||
filteredTabs = filteredTabs.filter(tab => tab.active);
|
||||
}
|
||||
|
||||
if (filteredTabs.length === 0) {
|
||||
filteredTabs.push({
|
||||
notePath: this.isMainWindow ? 'root' : '',
|
||||
active: true,
|
||||
extraHoistedNoteId: glob.extraHoistedNoteId || 'root'
|
||||
});
|
||||
}
|
||||
|
||||
if (!filteredTabs.find(tab => tab.active)) {
|
||||
filteredTabs[0].active = true;
|
||||
}
|
||||
|
||||
await this.tabsUpdate.allowUpdateWithoutChange(async () => {
|
||||
for (const tab of filteredTabs) {
|
||||
await this.openContextWithNote(tab.notePath, tab.active, tab.ntxId, tab.hoistedNoteId, tab.mainNtxId);
|
||||
if (utils.isMobile()) {
|
||||
// mobile frontend doesn't have tabs so show only the active tab
|
||||
filteredTabs = filteredTabs.filter(tab => tab.active);
|
||||
}
|
||||
});
|
||||
|
||||
if (filteredTabs.length === 0) {
|
||||
filteredTabs.push({
|
||||
notePath: glob.extraHoistedNoteId || 'root',
|
||||
active: true,
|
||||
hoistedNoteId: glob.extraHoistedNoteId || 'root'
|
||||
});
|
||||
}
|
||||
|
||||
if (!filteredTabs.find(tab => tab.active)) {
|
||||
filteredTabs[0].active = true;
|
||||
}
|
||||
|
||||
await this.tabsUpdate.allowUpdateWithoutChange(async () => {
|
||||
for (const tab of filteredTabs) {
|
||||
await this.openContextWithNote(tab.notePath, tab.active, tab.ntxId, tab.hoistedNoteId, tab.mainNtxId);
|
||||
}
|
||||
});
|
||||
|
||||
// if there's notePath in the URL, make sure it's open and active
|
||||
// (useful, among others, for opening clipped notes from clipper)
|
||||
if (treeService.isNotePathInAddress()) {
|
||||
const [notePath, ntxId] = treeService.getHashValueFromAddress();
|
||||
|
||||
await appContext.tabManager.switchToNoteContext(ntxId, notePath);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
logError(`Loading tabs '${options.get('openTabs')}' failed: ${e.message}`);
|
||||
|
||||
// try to recover
|
||||
await this.openEmptyTab();
|
||||
}
|
||||
}
|
||||
|
||||
noteSwitchedEvent({noteContext}) {
|
||||
@ -208,8 +208,11 @@ export default class TabManager extends Component {
|
||||
const noteContext = this.noteContexts.find(nc => nc.ntxId === ntxId)
|
||||
|| await this.openEmptyTab();
|
||||
|
||||
this.activateNoteContext(noteContext.ntxId);
|
||||
await noteContext.setNote(notePath);
|
||||
await this.activateNoteContext(noteContext.ntxId);
|
||||
|
||||
if (notePath) {
|
||||
await noteContext.setNote(notePath);
|
||||
}
|
||||
}
|
||||
|
||||
async openAndActivateEmptyTab() {
|
||||
@ -223,9 +226,19 @@ export default class TabManager extends Component {
|
||||
async openEmptyTab(ntxId = null, hoistedNoteId = 'root', mainNtxId = null) {
|
||||
const noteContext = new NoteContext(ntxId, hoistedNoteId, mainNtxId);
|
||||
|
||||
const existingNoteContext = this.children.find(nc => nc.ntxId === noteContext.ntxId);
|
||||
let existingNoteContext
|
||||
|
||||
if (utils.isMobile()) {
|
||||
// kind of hacky way to enforce a single tab on mobile interface - all requests to create a new one
|
||||
// are forced to reuse the existing ab instead
|
||||
existingNoteContext = this.getActiveContext();
|
||||
} else {
|
||||
existingNoteContext = this.children.find(nc => nc.ntxId === noteContext.ntxId);
|
||||
}
|
||||
|
||||
if (existingNoteContext) {
|
||||
await existingNoteContext.setHoistedNoteId(hoistedNoteId);
|
||||
|
||||
return existingNoteContext;
|
||||
}
|
||||
|
||||
@ -324,14 +337,16 @@ export default class TabManager extends Component {
|
||||
}
|
||||
|
||||
if (noteContextToRemove.isMainContext()) {
|
||||
// forbid removing last main note context
|
||||
// this was previously allowed (was replaced with empty tab) but this proved to be prone to race conditions
|
||||
const mainNoteContexts = this.getNoteContexts().filter(nc => nc.isMainContext());
|
||||
|
||||
if (mainNoteContexts.length === 1) {
|
||||
await this.clearLastMainNoteContext(noteContextToRemove);
|
||||
if (noteContextToRemove.isEmpty()) {
|
||||
// this is already the empty note context, no point in closing it and replacing with another
|
||||
// empty tab
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
await this.openEmptyTab();
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,35 +381,26 @@ export default class TabManager extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
async clearLastMainNoteContext(noteContextToClear) {
|
||||
noteContextToClear.setEmpty();
|
||||
|
||||
// activate main split
|
||||
await this.activateNoteContext(noteContextToClear.ntxId);
|
||||
|
||||
// remove all other splits
|
||||
const noteContextsToRemove = noteContextToClear.getSubContexts()
|
||||
.filter(ntx => ntx.ntxId !== noteContextToClear.ntxId);
|
||||
|
||||
const ntxIdsToRemove = noteContextsToRemove.map(ntx => ntx.ntxId);
|
||||
|
||||
await this.triggerEvent('beforeNoteContextRemove', {ntxIds: ntxIdsToRemove});
|
||||
|
||||
this.removeNoteContexts(noteContextsToRemove);
|
||||
}
|
||||
|
||||
removeNoteContexts(noteContextsToRemove) {
|
||||
const ntxIdsToRemove = noteContextsToRemove.map(nc => nc.ntxId);
|
||||
|
||||
this.children = this.children.filter(nc => !ntxIdsToRemove.includes(nc.ntxId));
|
||||
|
||||
this.recentlyClosedTabs.push(noteContextsToRemove);
|
||||
this.addToRecentlyClosedTabs(noteContextsToRemove);
|
||||
|
||||
this.triggerEvent('noteContextRemoved', {ntxIds: ntxIdsToRemove});
|
||||
|
||||
this.tabsUpdate.scheduleUpdate();
|
||||
}
|
||||
|
||||
addToRecentlyClosedTabs(noteContexts) {
|
||||
if (noteContexts.length === 1 && noteContexts[0].isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.recentlyClosedTabs.push(noteContexts);console.log(this.recentlyClosedTabs);
|
||||
}
|
||||
|
||||
tabReorderEvent({ntxIdsInOrder}) {
|
||||
const order = {};
|
||||
|
||||
@ -481,7 +487,18 @@ export default class TabManager extends Component {
|
||||
}
|
||||
|
||||
async reopenLastTabCommand() {
|
||||
if (this.recentlyClosedTabs.length > 0) {
|
||||
let closeLastEmptyTab = null;
|
||||
|
||||
await this.mutex.runExclusively(async () => {
|
||||
if (this.recentlyClosedTabs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.noteContexts.length === 1 && this.noteContexts[0].isEmpty()) {
|
||||
// new empty tab is created after closing the last tab, this reverses the empty tab creation
|
||||
closeLastEmptyTab = this.noteContexts[0];
|
||||
}
|
||||
|
||||
const noteContexts = this.recentlyClosedTabs.pop();
|
||||
|
||||
for (const noteContext of noteContexts) {
|
||||
@ -494,12 +511,16 @@ export default class TabManager extends Component {
|
||||
? noteContexts[0]
|
||||
: noteContexts.find(nc => nc.isMainContext());
|
||||
|
||||
this.activateNoteContext(noteContextToActivate.ntxId);
|
||||
await this.activateNoteContext(noteContextToActivate.ntxId);
|
||||
|
||||
await this.triggerEvent('noteSwitched', {
|
||||
noteContext: noteContextToActivate,
|
||||
notePath: noteContextToActivate.notePath
|
||||
});
|
||||
});
|
||||
|
||||
if (closeLastEmptyTab) {
|
||||
await this.removeNoteContext(closeLastEmptyTab.ntxId);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import options from "./options.js";
|
||||
import Component from "../widgets/component.js";
|
||||
import options from "../services/options.js";
|
||||
import Component from "./component.js";
|
||||
import utils from "../services/utils.js";
|
||||
|
||||
const MIN_ZOOM = 0.5;
|
||||
const MAX_ZOOM = 2.0;
|
||||
|
||||
class ZoomService extends Component {
|
||||
class ZoomComponent extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@ -59,6 +59,6 @@ class ZoomService extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
const zoomService = new ZoomService();
|
||||
const zoomService = new ZoomComponent();
|
||||
|
||||
export default zoomService;
|
@ -1,13 +1,18 @@
|
||||
import appContext from "./services/app_context.js";
|
||||
import appContext from "./components/app_context.js";
|
||||
import utils from './services/utils.js';
|
||||
import noteTooltipService from './services/note_tooltip.js';
|
||||
import bundleService from "./services/bundle.js";
|
||||
import noteAutocompleteService from './services/note_autocomplete.js';
|
||||
import macInit from './services/mac_init.js';
|
||||
import contextMenu from "./services/context_menu.js";
|
||||
import contextMenu from "./menus/context_menu.js";
|
||||
import DesktopLayout from "./layouts/desktop_layout.js";
|
||||
import glob from "./services/glob.js";
|
||||
import zoomService from './services/zoom.js';
|
||||
import zoomService from './components/zoom.js';
|
||||
|
||||
bundleService.getWidgetBundlesByParent().then(widgetBundles => {
|
||||
appContext.setLayout(new DesktopLayout(widgetBundles));
|
||||
appContext.start();
|
||||
});
|
||||
|
||||
glob.setupGlobs();
|
||||
|
||||
@ -17,17 +22,8 @@ if (utils.isElectron()) {
|
||||
});
|
||||
}
|
||||
|
||||
$('[data-toggle="tooltip"]').tooltip({
|
||||
html: true
|
||||
});
|
||||
|
||||
macInit.init();
|
||||
|
||||
bundleService.getWidgetBundlesByParent().then(widgetBundles => {
|
||||
appContext.setLayout(new DesktopLayout(widgetBundles));
|
||||
appContext.start();
|
||||
});
|
||||
|
||||
noteTooltipService.setupGlobalTooltip();
|
||||
|
||||
noteAutocompleteService.init();
|
||||
|
1
src/public/app/doc_notes/hidden.html
Normal file
1
src/public/app/doc_notes/hidden.html
Normal file
@ -0,0 +1 @@
|
||||
<p>Hidden tree is used to record various application-level data which can stay most of the time hidden from the user view.</p>
|
1
src/public/app/doc_notes/launchbar_command_launcher.html
Normal file
1
src/public/app/doc_notes/launchbar_command_launcher.html
Normal file
@ -0,0 +1 @@
|
||||
<p>Keyboard shortcut for this launcher action can be configured in Options -> Shortcuts.</p>
|
11
src/public/app/doc_notes/launchbar_intro.html
Normal file
11
src/public/app/doc_notes/launchbar_intro.html
Normal file
@ -0,0 +1,11 @@
|
||||
<p>Welcome to the Launchbar configuration.</p>
|
||||
|
||||
<p>You can do the following things here:</p>
|
||||
|
||||
<ul>
|
||||
<li>Move available shortcuts to the visible list (thus putting them into the launchbar) by dragging them</li>
|
||||
<li>Move visible shortcuts to the available list (thus hiding them from the launchbar) by dragging them</li>
|
||||
<li>You can reorder the items in the lists by dragging</li>
|
||||
<li>You can create new shortcuts by right-clicking on the "Visible shortcuts" folder</li>
|
||||
<li>If you want to get back to the default setup, just delete the "Visible shortcuts" and "Available shortcuts", the default configuration will be re-created.</li>
|
||||
</ul>
|
3
src/public/app/doc_notes/launchbar_note_launcher.html
Normal file
3
src/public/app/doc_notes/launchbar_note_launcher.html
Normal file
@ -0,0 +1,3 @@
|
||||
<p>Please define the target note in the promoted attributes.</p>
|
||||
|
||||
<p>Launchbar displays the title / icon from the shortcut which does not necessarily mirrors those of the target note.</p>
|
9
src/public/app/doc_notes/launchbar_script_launcher.html
Normal file
9
src/public/app/doc_notes/launchbar_script_launcher.html
Normal file
@ -0,0 +1,9 @@
|
||||
<p>Please define the target script note in the promoted attributes. This script will be executed immediately upon clicking the launchbar icon.</p>
|
||||
|
||||
<p>Launchbar displays the title / icon from the shortcut which does not necessarily mirrors those of the target script note.</p>
|
||||
|
||||
<h4>Example script</h4>
|
||||
|
||||
<pre>
|
||||
alert("Current note is " + api.getActiveContextNote().title);
|
||||
</pre>
|
6
src/public/app/doc_notes/launchbar_spacer.html
Normal file
6
src/public/app/doc_notes/launchbar_spacer.html
Normal file
@ -0,0 +1,6 @@
|
||||
<p>Spacer allows you to visually group shortcuts. You can configure it in the promoted attributes:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>baseSize</code> - defines size in pixels (if there's enough space)</li>
|
||||
<li><code>growthFactor</code> - set to 0 if you want the spacer to be of constant <code>baseSize</code>, with positive value it will grow.</li>
|
||||
</ul>
|
34
src/public/app/doc_notes/launchbar_widget_launcher.html
Normal file
34
src/public/app/doc_notes/launchbar_widget_launcher.html
Normal file
@ -0,0 +1,34 @@
|
||||
<p>Please define the target widget note in the promoted attributes. The widget will be used to render the launchbar icon.</p>
|
||||
|
||||
<h4>Example launchbar widget</h4>
|
||||
|
||||
<pre>
|
||||
const TPL = `<div style="height: 53px; width: 53px;"></div>`;
|
||||
|
||||
class ExampleLaunchbarWidget extends api.NoteContextAwareWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
}
|
||||
|
||||
async refreshWithNote(note) {
|
||||
this.$widget.css("background-color", this.stringToColor(note.title));
|
||||
}
|
||||
|
||||
stringToColor(str) {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
|
||||
let color = '#';
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const value = (hash >> (i * 8)) & 0xFF;
|
||||
color += ('00' + value.toString(16)).substr(-2);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new ExampleLaunchbarWidget();
|
||||
</pre>
|
1
src/public/app/doc_notes/share.html
Normal file
1
src/public/app/doc_notes/share.html
Normal file
@ -0,0 +1 @@
|
||||
<p>Here you can find all shared notes.</p>
|
@ -15,12 +15,15 @@ const NOTE_TYPE_ICONS = {
|
||||
"code": "bx bx-code",
|
||||
"render": "bx bx-extension",
|
||||
"search": "bx bx-file-find",
|
||||
"relation-map": "bx bx-map-alt",
|
||||
"relationMap": "bx bx-map-alt",
|
||||
"book": "bx bx-book",
|
||||
"note-map": "bx bx-map-alt",
|
||||
"noteMap": "bx bx-map-alt",
|
||||
"mermaid": "bx bx-selection",
|
||||
"canvas": "bx bx-pen",
|
||||
"web-view": "bx bx-globe-alt"
|
||||
"webView": "bx bx-globe-alt",
|
||||
"launcher": "bx bx-link",
|
||||
"doc": "bx bxs-file-doc",
|
||||
"contentWidget": "bx bxs-widget"
|
||||
};
|
||||
|
||||
/**
|
||||
@ -790,10 +793,10 @@ class NoteShort {
|
||||
|
||||
if (env === "frontend") {
|
||||
const bundleService = (await import("../services/bundle.js")).default;
|
||||
await bundleService.getAndExecuteBundle(this.noteId);
|
||||
return await bundleService.getAndExecuteBundle(this.noteId);
|
||||
}
|
||||
else if (env === "backend") {
|
||||
await server.post('script/run/' + this.noteId);
|
||||
return await server.post('script/run/' + this.noteId);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unrecognized env type ${env} for note ${this.noteId}`);
|
||||
@ -823,6 +826,14 @@ class NoteShort {
|
||||
isContentAvailable() {
|
||||
return !this.isProtected || protectedSessionHolder.isProtectedSessionAvailable()
|
||||
}
|
||||
|
||||
isLaunchBarConfig() {
|
||||
return this.type === 'launcher' || ['lbRoot', 'lbAvailableLaunchers', 'lbVisibleLaunchers'].includes(this.noteId);
|
||||
}
|
||||
|
||||
isOptions() {
|
||||
return this.noteId.startsWith("options");
|
||||
}
|
||||
}
|
||||
|
||||
export default NoteShort;
|
||||
|
@ -20,14 +20,11 @@ import ImagePropertiesWidget from "../widgets/ribbon_widgets/image_properties.js
|
||||
import NotePropertiesWidget from "../widgets/ribbon_widgets/note_properties.js";
|
||||
import NoteIconWidget from "../widgets/note_icon.js";
|
||||
import SearchResultWidget from "../widgets/search_result.js";
|
||||
import SyncStatusWidget from "../widgets/sync_status.js";
|
||||
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
|
||||
import RootContainer from "../widgets/containers/root_container.js";
|
||||
import NoteUpdateStatusWidget from "../widgets/note_update_status.js";
|
||||
import SpacerWidget from "../widgets/spacer.js";
|
||||
import QuickSearchWidget from "../widgets/quick_search.js";
|
||||
import ButtonWidget from "../widgets/buttons/button_widget.js";
|
||||
import ProtectedSessionStatusWidget from "../widgets/buttons/protected_session_status.js";
|
||||
import SplitNoteContainer from "../widgets/containers/split_note_container.js";
|
||||
import LeftPaneToggleWidget from "../widgets/buttons/left_pane_toggle.js";
|
||||
import CreatePaneButton from "../widgets/buttons/create_pane_button.js";
|
||||
@ -40,11 +37,8 @@ import NotePathsWidget from "../widgets/ribbon_widgets/note_paths.js";
|
||||
import SimilarNotesWidget from "../widgets/ribbon_widgets/similar_notes.js";
|
||||
import RightPaneContainer from "../widgets/containers/right_pane_container.js";
|
||||
import EditButton from "../widgets/buttons/edit_button.js";
|
||||
import CalendarWidget from "../widgets/buttons/calendar.js";
|
||||
import EditedNotesWidget from "../widgets/ribbon_widgets/edited_notes.js";
|
||||
import OpenNoteButtonWidget from "../widgets/buttons/open_note_button_widget.js";
|
||||
import MermaidWidget from "../widgets/mermaid.js";
|
||||
import BookmarkButtons from "../widgets/bookmark_buttons.js";
|
||||
import NoteWrapperWidget from "../widgets/note_wrapper.js";
|
||||
import BacklinksWidget from "../widgets/floating_buttons/zpetne_odkazy.js";
|
||||
import SharedInfoWidget from "../widgets/shared_info.js";
|
||||
@ -74,25 +68,14 @@ import DeleteNotesDialog from "../widgets/dialogs/delete_notes.js";
|
||||
import InfoDialog from "../widgets/dialogs/info.js";
|
||||
import ConfirmDialog from "../widgets/dialogs/confirm.js";
|
||||
import PromptDialog from "../widgets/dialogs/prompt.js";
|
||||
import OptionsDialog from "../widgets/dialogs/options.js";
|
||||
import FloatingButtons from "../widgets/floating_buttons/floating_buttons.js";
|
||||
import RelationMapButtons from "../widgets/floating_buttons/relation_map_buttons.js";
|
||||
import MermaidExportButton from "../widgets/floating_buttons/mermaid_export_button.js";
|
||||
import LauncherContainer from "../widgets/containers/launcher_container.js";
|
||||
import NoteRevisionsButton from "../widgets/buttons/note_revisions_button.js";
|
||||
import EditableCodeButtonsWidget from "../widgets/type_widgets/editable_code_buttons.js";
|
||||
import ApiLogWidget from "../widgets/api_log.js";
|
||||
import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating_buttons_button.js";
|
||||
import AppearanceOptions from "../widgets/dialogs/options/appearance.js";
|
||||
import KeyboardShortcutsOptions from "../widgets/dialogs/options/shortcuts.js";
|
||||
import TextNotesOptions from "../widgets/dialogs/options/text_notes.js";
|
||||
import CodeNotesOptions from "../widgets/dialogs/options/code_notes.js";
|
||||
import ImageOptions from "../widgets/dialogs/options/images.js";
|
||||
import SpellcheckOptions from "../widgets/dialogs/options/spellcheck.js";
|
||||
import PasswordOptions from "../widgets/dialogs/options/password.js";
|
||||
import EtapiOptions from "../widgets/dialogs/options/etapi.js";
|
||||
import BackupOptions from "../widgets/dialogs/options/backup.js";
|
||||
import SyncOptions from "../widgets/dialogs/options/sync.js";
|
||||
import OtherOptions from "../widgets/dialogs/options/other.js";
|
||||
import AdvancedOptions from "../widgets/dialogs/options/advanced.js";
|
||||
|
||||
export default class DesktopLayout {
|
||||
constructor(customWidgets) {
|
||||
@ -100,7 +83,7 @@ export default class DesktopLayout {
|
||||
}
|
||||
|
||||
getRootWidget(appContext) {
|
||||
appContext.mainTreeWidget = new NoteTreeWidget("main");
|
||||
appContext.noteTreeWidget = new NoteTreeWidget();
|
||||
|
||||
return new RootContainer()
|
||||
.setParent(appContext)
|
||||
@ -108,38 +91,12 @@ export default class DesktopLayout {
|
||||
.id("launcher-pane")
|
||||
.css("width", "53px")
|
||||
.child(new GlobalMenuWidget())
|
||||
.child(new ButtonWidget()
|
||||
.icon("bx-file-blank")
|
||||
.title("New note")
|
||||
.command("createNoteIntoInbox"))
|
||||
.child(new ButtonWidget()
|
||||
.icon("bx-search")
|
||||
.title("Search")
|
||||
.command("searchNotes"))
|
||||
.child(new ButtonWidget()
|
||||
.icon("bx-send")
|
||||
.title("Jump to note")
|
||||
.command("jumpToNote"))
|
||||
.child(new OpenNoteButtonWidget()
|
||||
.targetNote('globalnotemap'))
|
||||
.child(new ButtonWidget()
|
||||
.icon("bx-history")
|
||||
.title("Show recent changes")
|
||||
.command("showRecentChanges"))
|
||||
.child(new CalendarWidget())
|
||||
.child(new SpacerWidget(40, 0))
|
||||
.child(new FlexContainer("column")
|
||||
.id("plugin-buttons")
|
||||
.contentSized())
|
||||
.child(new BookmarkButtons())
|
||||
.child(new SpacerWidget(0, 1000))
|
||||
.child(new ProtectedSessionStatusWidget())
|
||||
.child(new SyncStatusWidget())
|
||||
.child(new LauncherContainer())
|
||||
.child(new LeftPaneToggleWidget())
|
||||
)
|
||||
.child(new LeftPaneContainer()
|
||||
.child(new QuickSearchWidget())
|
||||
.child(appContext.mainTreeWidget)
|
||||
.child(appContext.noteTreeWidget)
|
||||
.child(...this.customWidgets.get('left-pane'))
|
||||
)
|
||||
.child(new FlexContainer('column')
|
||||
@ -158,67 +115,63 @@ export default class DesktopLayout {
|
||||
.collapsible()
|
||||
.id('center-pane')
|
||||
.child(new SplitNoteContainer(() =>
|
||||
new NoteWrapperWidget()
|
||||
.child(new FlexContainer('row').class('title-row')
|
||||
.css("height", "50px")
|
||||
.css("min-height", "50px")
|
||||
.css('align-items', "center")
|
||||
.cssBlock('.title-row > * { margin: 5px; }')
|
||||
.child(new NoteIconWidget())
|
||||
.child(new NoteTitleWidget())
|
||||
.child(new SpacerWidget(0, 1))
|
||||
.child(new ClosePaneButton())
|
||||
.child(new CreatePaneButton())
|
||||
)
|
||||
.child(
|
||||
new RibbonContainer()
|
||||
.ribbon(new SearchDefinitionWidget())
|
||||
.ribbon(new EditedNotesWidget())
|
||||
.ribbon(new BookPropertiesWidget())
|
||||
.ribbon(new NotePropertiesWidget())
|
||||
.ribbon(new FilePropertiesWidget())
|
||||
.ribbon(new ImagePropertiesWidget())
|
||||
.ribbon(new PromotedAttributesWidget())
|
||||
.ribbon(new BasicPropertiesWidget())
|
||||
.ribbon(new OwnedAttributeListWidget())
|
||||
.ribbon(new InheritedAttributesWidget())
|
||||
.ribbon(new NotePathsWidget())
|
||||
.ribbon(new NoteMapRibbonWidget())
|
||||
.ribbon(new SimilarNotesWidget())
|
||||
.ribbon(new NoteInfoWidget())
|
||||
.button(new EditButton())
|
||||
.button(new ButtonWidget()
|
||||
.icon('bx-history')
|
||||
.title("Note Revisions")
|
||||
.command("showNoteRevisions")
|
||||
.titlePlacement("bottom"))
|
||||
.button(new NoteActionsWidget())
|
||||
)
|
||||
.child(new SharedInfoWidget())
|
||||
.child(new NoteUpdateStatusWidget())
|
||||
.child(new FloatingButtons()
|
||||
.child(new RelationMapButtons())
|
||||
.child(new MermaidExportButton())
|
||||
.child(new BacklinksWidget())
|
||||
.child(new HideFloatingButtonsButton())
|
||||
)
|
||||
.child(new MermaidWidget())
|
||||
.child(
|
||||
new ScrollingContainer()
|
||||
.filling()
|
||||
.child(new SqlTableSchemasWidget())
|
||||
.child(new NoteDetailWidget())
|
||||
.child(new NoteListWidget())
|
||||
.child(new SearchResultWidget())
|
||||
.child(new SqlResultWidget())
|
||||
)
|
||||
.child(new EditableCodeButtonsWidget())
|
||||
.child(new ApiLogWidget())
|
||||
.child(new FindWidget())
|
||||
.child(
|
||||
...this.customWidgets.get('node-detail-pane'), // typo, let's keep it for a while as BC
|
||||
...this.customWidgets.get('note-detail-pane')
|
||||
)
|
||||
new NoteWrapperWidget()
|
||||
.child(new FlexContainer('row').class('title-row')
|
||||
.css("height", "50px")
|
||||
.css("min-height", "50px")
|
||||
.css('align-items', "center")
|
||||
.cssBlock('.title-row > * { margin: 5px; }')
|
||||
.child(new NoteIconWidget())
|
||||
.child(new NoteTitleWidget())
|
||||
.child(new SpacerWidget(0, 1))
|
||||
.child(new ClosePaneButton())
|
||||
.child(new CreatePaneButton())
|
||||
)
|
||||
.child(
|
||||
new RibbonContainer()
|
||||
.ribbon(new SearchDefinitionWidget())
|
||||
.ribbon(new EditedNotesWidget())
|
||||
.ribbon(new BookPropertiesWidget())
|
||||
.ribbon(new NotePropertiesWidget())
|
||||
.ribbon(new FilePropertiesWidget())
|
||||
.ribbon(new ImagePropertiesWidget())
|
||||
.ribbon(new PromotedAttributesWidget())
|
||||
.ribbon(new BasicPropertiesWidget())
|
||||
.ribbon(new OwnedAttributeListWidget())
|
||||
.ribbon(new InheritedAttributesWidget())
|
||||
.ribbon(new NotePathsWidget())
|
||||
.ribbon(new NoteMapRibbonWidget())
|
||||
.ribbon(new SimilarNotesWidget())
|
||||
.ribbon(new NoteInfoWidget())
|
||||
.button(new NoteRevisionsButton())
|
||||
.button(new NoteActionsWidget())
|
||||
)
|
||||
.child(new SharedInfoWidget())
|
||||
.child(new NoteUpdateStatusWidget())
|
||||
.child(new FloatingButtons()
|
||||
.child(new EditButton())
|
||||
.child(new RelationMapButtons())
|
||||
.child(new MermaidExportButton())
|
||||
.child(new BacklinksWidget())
|
||||
.child(new HideFloatingButtonsButton())
|
||||
)
|
||||
.child(new MermaidWidget())
|
||||
.child(
|
||||
new ScrollingContainer()
|
||||
.filling()
|
||||
.child(new SqlTableSchemasWidget())
|
||||
.child(new NoteDetailWidget())
|
||||
.child(new NoteListWidget())
|
||||
.child(new SearchResultWidget())
|
||||
.child(new SqlResultWidget())
|
||||
)
|
||||
.child(new EditableCodeButtonsWidget())
|
||||
.child(new ApiLogWidget())
|
||||
.child(new FindWidget())
|
||||
.child(
|
||||
...this.customWidgets.get('node-detail-pane'), // typo, let's keep it for a while as BC
|
||||
...this.customWidgets.get('note-detail-pane')
|
||||
)
|
||||
)
|
||||
)
|
||||
.child(...this.customWidgets.get('center-pane'))
|
||||
@ -252,20 +205,6 @@ export default class DesktopLayout {
|
||||
.child(new DeleteNotesDialog())
|
||||
.child(new InfoDialog())
|
||||
.child(new ConfirmDialog())
|
||||
.child(new PromptDialog())
|
||||
.child(new OptionsDialog()
|
||||
.child(new AppearanceOptions())
|
||||
.child(new KeyboardShortcutsOptions())
|
||||
.child(new TextNotesOptions())
|
||||
.child(new CodeNotesOptions())
|
||||
.child(new ImageOptions())
|
||||
.child(new SpellcheckOptions())
|
||||
.child(new PasswordOptions())
|
||||
.child(new EtapiOptions())
|
||||
.child(new BackupOptions())
|
||||
.child(new SyncOptions())
|
||||
.child(new OtherOptions())
|
||||
.child(new AdvancedOptions())
|
||||
);
|
||||
.child(new PromptDialog());
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ import NoteTitleWidget from "../widgets/note_title.js";
|
||||
import NoteDetailWidget from "../widgets/note_detail.js";
|
||||
import QuickSearchWidget from "../widgets/quick_search.js";
|
||||
import NoteTreeWidget from "../widgets/note_tree.js";
|
||||
import MobileGlobalButtonsWidget from "../widgets/mobile_widgets/mobile_global_buttons.js";
|
||||
import CloseDetailButtonWidget from "../widgets/mobile_widgets/close_detail_button.js";
|
||||
import MobileDetailMenuWidget from "../widgets/mobile_widgets/mobile_detail_menu.js";
|
||||
import ScreenContainer from "../widgets/mobile_widgets/screen_container.js";
|
||||
@ -11,6 +10,17 @@ import ScrollingContainer from "../widgets/containers/scrolling_container.js";
|
||||
import ProtectedSessionPasswordDialog from "../widgets/dialogs/protected_session_password.js";
|
||||
import ConfirmDialog from "../widgets/dialogs/confirm.js";
|
||||
import FilePropertiesWidget from "../widgets/ribbon_widgets/file_properties.js";
|
||||
import FloatingButtons from "../widgets/floating_buttons/floating_buttons.js";
|
||||
import EditButton from "../widgets/buttons/edit_button.js";
|
||||
import RelationMapButtons from "../widgets/floating_buttons/relation_map_buttons.js";
|
||||
import MermaidExportButton from "../widgets/floating_buttons/mermaid_export_button.js";
|
||||
import BacklinksWidget from "../widgets/floating_buttons/zpetne_odkazy.js";
|
||||
import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating_buttons_button.js";
|
||||
import MermaidWidget from "../widgets/mermaid.js";
|
||||
import NoteListWidget from "../widgets/note_list.js";
|
||||
import GlobalMenuWidget from "../widgets/buttons/global_menu.js";
|
||||
import LauncherContainer from "../widgets/containers/launcher_container.js";
|
||||
import RootContainer from "../widgets/containers/root_container.js";
|
||||
|
||||
const MOBILE_CSS = `
|
||||
<style>
|
||||
@ -32,7 +42,7 @@ kbd {
|
||||
color: var(--main-text-color);
|
||||
}
|
||||
.quick-search {
|
||||
margin: 55px 0px 0px 0px;
|
||||
margin: 0;
|
||||
}
|
||||
.quick-search .dropdown-menu {
|
||||
max-width: 350px;
|
||||
@ -91,48 +101,71 @@ span.fancytree-expander {
|
||||
margin-right: 16px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tree-wrapper .unhoist-button {
|
||||
font-size: 200%;
|
||||
}
|
||||
</style>`;
|
||||
|
||||
export default class MobileLayout {
|
||||
getRootWidget(appContext) {
|
||||
return new FlexContainer('row').cssBlock(MOBILE_CSS)
|
||||
return new RootContainer()
|
||||
.setParent(appContext)
|
||||
.id('root-widget')
|
||||
.css('height', '100%')
|
||||
.child(new ScreenContainer("tree", 'column')
|
||||
.class("d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-5 col-md-4 col-lg-4 col-xl-4")
|
||||
.css("max-height", "100%")
|
||||
.css('padding-left', 0)
|
||||
.css('contain', 'content')
|
||||
.child(new MobileGlobalButtonsWidget())
|
||||
.child(new QuickSearchWidget())
|
||||
.child(new NoteTreeWidget("main")
|
||||
.cssBlock(FANCYTREE_CSS)))
|
||||
.child(new ScreenContainer("detail", "column")
|
||||
.class("d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-7 col-md-8 col-lg-8")
|
||||
.css('max-height', '100%')
|
||||
.child(new FlexContainer('row').overflowing().contentSized()
|
||||
.css('font-size', 'larger')
|
||||
.css('align-items', 'center')
|
||||
.child(new MobileDetailMenuWidget().contentSized())
|
||||
.child(new NoteTitleWidget()
|
||||
.contentSized()
|
||||
.css("position: relative;")
|
||||
.css("top: 5px;")
|
||||
)
|
||||
.child(new CloseDetailButtonWidget().contentSized()))
|
||||
.child(
|
||||
new ScrollingContainer()
|
||||
.filling()
|
||||
.overflowing()
|
||||
.contentSized()
|
||||
.child(
|
||||
new NoteDetailWidget()
|
||||
.css('padding', '5px 20px 10px 0')
|
||||
).child(new FilePropertiesWidget().css('font-size','smaller'))
|
||||
)
|
||||
.cssBlock(MOBILE_CSS)
|
||||
.child(new FlexContainer("column")
|
||||
.id("launcher-pane")
|
||||
.css("width", "53px")
|
||||
.child(new GlobalMenuWidget())
|
||||
.child(new LauncherContainer())
|
||||
)
|
||||
.child(new ProtectedSessionPasswordDialog())
|
||||
.child(new ConfirmDialog());
|
||||
.child(new FlexContainer("row")
|
||||
.filling()
|
||||
.child(new ScreenContainer("tree", 'column')
|
||||
.class("d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-5 col-md-4 col-lg-3 col-xl-3")
|
||||
.css("max-height", "100%")
|
||||
.css('padding-left', "0")
|
||||
.css('padding-right', "0")
|
||||
.css('contain', 'content')
|
||||
.child(new QuickSearchWidget())
|
||||
.child(new NoteTreeWidget()
|
||||
.cssBlock(FANCYTREE_CSS)))
|
||||
.child(new ScreenContainer("detail", "column")
|
||||
.class("d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-7 col-md-8 col-lg-9")
|
||||
.css("padding-left", "0")
|
||||
.css("padding-right", "0")
|
||||
.css('max-height', '100%')
|
||||
.child(new FlexContainer('row').contentSized()
|
||||
.css('font-size', 'larger')
|
||||
.css('align-items', 'center')
|
||||
.child(new MobileDetailMenuWidget().contentSized())
|
||||
.child(new NoteTitleWidget()
|
||||
.contentSized()
|
||||
.css("position: relative;")
|
||||
.css("top: 5px;")
|
||||
)
|
||||
.child(new CloseDetailButtonWidget().contentSized()))
|
||||
.child(new FloatingButtons()
|
||||
.child(new EditButton())
|
||||
.child(new RelationMapButtons())
|
||||
.child(new MermaidExportButton())
|
||||
.child(new BacklinksWidget())
|
||||
.child(new HideFloatingButtonsButton())
|
||||
)
|
||||
.child(new MermaidWidget())
|
||||
.child(
|
||||
new ScrollingContainer()
|
||||
.filling()
|
||||
.contentSized()
|
||||
.child(
|
||||
new NoteDetailWidget()
|
||||
.css('padding', '5px 20px 10px 0')
|
||||
)
|
||||
.child(new NoteListWidget())
|
||||
.child(new FilePropertiesWidget().css('font-size','smaller'))
|
||||
)
|
||||
)
|
||||
.child(new ProtectedSessionPasswordDialog())
|
||||
.child(new ConfirmDialog())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import keyboardActionService from './keyboard_actions.js';
|
||||
import keyboardActionService from '../services/keyboard_actions.js';
|
||||
|
||||
class ContextMenu {
|
||||
constructor() {
|
74
src/public/app/menus/launcher_context_menu.js
Normal file
74
src/public/app/menus/launcher_context_menu.js
Normal file
@ -0,0 +1,74 @@
|
||||
import treeService from '../services/tree.js';
|
||||
import froca from "../services/froca.js";
|
||||
import contextMenu from "./context_menu.js";
|
||||
import dialogService from "../services/dialog.js";
|
||||
import server from "../services/server.js";
|
||||
|
||||
export default class LauncherContextMenu {
|
||||
/**
|
||||
* @param {NoteTreeWidget} treeWidget
|
||||
* @param {FancytreeNode} node
|
||||
*/
|
||||
constructor(treeWidget, node) {
|
||||
this.treeWidget = treeWidget;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
async show(e) {
|
||||
contextMenu.show({
|
||||
x: e.pageX,
|
||||
y: e.pageY,
|
||||
items: await this.getMenuItems(),
|
||||
selectMenuItemHandler: (item, e) => this.selectMenuItemHandler(item, e)
|
||||
})
|
||||
}
|
||||
|
||||
async getMenuItems() {
|
||||
const note = await froca.getNote(this.node.data.noteId);
|
||||
const parentNoteId = this.node.getParent().data.noteId;
|
||||
|
||||
const isVisibleRoot = note.noteId === 'lbVisibleLaunchers';
|
||||
const isAvailableRoot = note.noteId === 'lbAvailableLaunchers';
|
||||
const isVisibleItem = parentNoteId === 'lbVisibleLaunchers';
|
||||
const isAvailableItem = parentNoteId === 'lbAvailableLaunchers';
|
||||
const isItem = isVisibleItem || isAvailableItem;
|
||||
const canBeDeleted = !note.isLaunchBarConfig();
|
||||
const canBeReset = note.isLaunchBarConfig();
|
||||
|
||||
return [
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add a note launcher', command: 'addNoteLauncher', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add a script launcher', command: 'addScriptLauncher', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add a custom widget', command: 'addWidgetLauncher', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: 'Add spacer', command: 'addSpacerLauncher', uiIcon: "bx bx-plus" } : null,
|
||||
(isVisibleRoot || isAvailableRoot) ? { title: "----" } : null,
|
||||
{ title: 'Delete <kbd data-command="deleteNotes"></kbd>', command: "deleteNotes", uiIcon: "bx bx-trash", enabled: canBeDeleted },
|
||||
{ title: 'Reset', command: "resetLauncher", uiIcon: "bx bx-empty", enabled: canBeReset},
|
||||
{ title: "----" },
|
||||
isAvailableItem ? { title: 'Move to visible launchers', command: "moveLauncherToVisible", uiIcon: "bx bx-show", enabled: true } : null,
|
||||
isVisibleItem ? { title: 'Move to available launchers', command: "moveLauncherToAvailable", uiIcon: "bx bx-hide", enabled: true } : null,
|
||||
{ title: `Duplicate launcher <kbd data-command="duplicateSubtree">`, command: "duplicateSubtree", uiIcon: "bx bx-empty",
|
||||
enabled: isItem }
|
||||
].filter(row => row !== null);
|
||||
}
|
||||
|
||||
async selectMenuItemHandler({command}) {
|
||||
if (command === 'resetLauncher') {
|
||||
const confirmed = await dialogService.confirm(`Do you really want to reset "${this.node.title}"?
|
||||
All data / settings in this note (and its children) will be lost
|
||||
and the launcher will be returned to its original location.`);
|
||||
|
||||
if (confirmed) {
|
||||
await server.post(`special-notes/launchers/${this.node.data.noteId}/reset`);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.treeWidget.triggerCommand(command, {
|
||||
node: this.node,
|
||||
notePath: treeService.getNotePath(this.node),
|
||||
selectedOrActiveBranchIds: this.treeWidget.getSelectedOrActiveBranchIds(this.node),
|
||||
selectedOrActiveNoteIds: this.treeWidget.getSelectedOrActiveNoteIds(this.node)
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import contextMenu from "./context_menu.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
function openContextMenu(notePath, e) {
|
||||
contextMenu.show({
|
@ -1,12 +1,12 @@
|
||||
import treeService from './tree.js';
|
||||
import froca from "./froca.js";
|
||||
import clipboard from './clipboard.js';
|
||||
import noteCreateService from "./note_create.js";
|
||||
import treeService from '../services/tree.js';
|
||||
import froca from "../services/froca.js";
|
||||
import clipboard from '../services/clipboard.js';
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import contextMenu from "./context_menu.js";
|
||||
import appContext from "./app_context.js";
|
||||
import noteTypesService from "./note_types.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import noteTypesService from "../services/note_types.js";
|
||||
|
||||
class TreeContextMenu {
|
||||
export default class TreeContextMenu {
|
||||
/**
|
||||
* @param {NoteTreeWidget} treeWidget
|
||||
* @param {FancytreeNode} node
|
||||
@ -140,5 +140,3 @@ class TreeContextMenu {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default TreeContextMenu;
|
@ -1,8 +1,8 @@
|
||||
import appContext from "./services/app_context.js";
|
||||
import appContext from "./components/app_context.js";
|
||||
import MobileLayout from "./layouts/mobile_layout.js";
|
||||
import glob from "./services/glob.js";
|
||||
|
||||
glob.setupGlobs();
|
||||
|
||||
appContext.setLayout(new MobileLayout());
|
||||
appContext.start();
|
||||
appContext.start();
|
||||
|
@ -55,7 +55,7 @@ async function createNoteLink(noteId) {
|
||||
}
|
||||
|
||||
return $("<a>", {
|
||||
href: '#' + noteId,
|
||||
href: '#root/' + noteId,
|
||||
class: 'reference-link',
|
||||
'data-note-path': noteId
|
||||
})
|
||||
|
@ -4,14 +4,14 @@ import toastService from "./toast.js";
|
||||
import froca from "./froca.js";
|
||||
import hoistedNoteService from "./hoisted_note.js";
|
||||
import ws from "./ws.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
|
||||
branchIdsToMove = filterRootNote(branchIdsToMove);
|
||||
branchIdsToMove = filterSearchBranches(branchIdsToMove);
|
||||
|
||||
if (beforeBranchId === 'root') {
|
||||
toastService.showError('Cannot move notes before root note.');
|
||||
if (['root', 'lbRoot', 'lbAvailableLaunchers', 'lbVisibleLaunchers'].includes(beforeBranchId)) {
|
||||
toastService.showError('Cannot move notes here.');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -31,8 +31,16 @@ async function moveAfterBranch(branchIdsToMove, afterBranchId) {
|
||||
|
||||
const afterNote = await froca.getBranch(afterBranchId).getNote();
|
||||
|
||||
if (afterNote.noteId === 'root' || afterNote.noteId === hoistedNoteService.getHoistedNoteId()) {
|
||||
toastService.showError('Cannot move notes after root note.');
|
||||
const forbiddenNoteIds = [
|
||||
'root',
|
||||
hoistedNoteService.getHoistedNoteId(),
|
||||
'lbRoot',
|
||||
'lbAvailableLaunchers',
|
||||
'lbVisibleLaunchers'
|
||||
];
|
||||
|
||||
if (forbiddenNoteIds.includes(afterNote.noteId)) {
|
||||
toastService.showError('Cannot move notes here.');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -49,6 +57,11 @@ async function moveAfterBranch(branchIdsToMove, afterBranchId) {
|
||||
}
|
||||
|
||||
async function moveToParentNote(branchIdsToMove, newParentBranchId) {
|
||||
if (newParentBranchId === 'lbRoot') {
|
||||
toastService.showError('Cannot move notes here.');
|
||||
return;
|
||||
}
|
||||
|
||||
branchIdsToMove = filterRootNote(branchIdsToMove);
|
||||
|
||||
for (const branchIdToMove of branchIdsToMove) {
|
||||
@ -124,7 +137,10 @@ async function moveNodeUpInHierarchy(node) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resp = await server.put('branches/' + node.data.branchId + '/move-after/' + node.getParent().data.branchId);
|
||||
const targetBranchId = node.getParent().data.branchId;
|
||||
const branchIdToMove = node.data.branchId;
|
||||
|
||||
const resp = await server.put(`branches/${branchIdToMove}/move-after/${targetBranchId}`);
|
||||
|
||||
if (!resp.success) {
|
||||
toastService.showError(resp.message);
|
||||
|
@ -54,10 +54,10 @@ async function pasteInto(parentBranchId) {
|
||||
await branchService.cloneNoteToBranch(clipboardNote.noteId, parentBranchId);
|
||||
}
|
||||
|
||||
// copy will keep clipboardBranchIds and clipboardMode so it's possible to paste into multiple places
|
||||
// copy will keep clipboardBranchIds and clipboardMode, so it's possible to paste into multiple places
|
||||
}
|
||||
else {
|
||||
toastService.throwError("Unrecognized clipboard mode=" + mode);
|
||||
toastService.throwError("Unrecognized clipboard mode=" + clipboardMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import appContext from "../services/app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
async function info(message) {
|
||||
return new Promise(res =>
|
@ -1,5 +1,5 @@
|
||||
import ws from "./ws.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
const fileModificationStatus = {};
|
||||
|
||||
|
@ -2,7 +2,7 @@ import Branch from "../entities/branch.js";
|
||||
import NoteShort from "../entities/note_short.js";
|
||||
import Attribute from "../entities/attribute.js";
|
||||
import server from "./server.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import NoteComplement from "../entities/note_complement.js";
|
||||
|
||||
/**
|
||||
@ -226,6 +226,7 @@ class Froca {
|
||||
|
||||
/** @returns {Promise<NoteShort[]>} */
|
||||
async getNotes(noteIds, silentNotFoundError = false) {
|
||||
noteIds = Array.from(new Set(noteIds)); // make unique
|
||||
const missingNoteIds = noteIds.filter(noteId => !this.notes[noteId]);
|
||||
|
||||
await this.reloadNotes(missingNoteIds);
|
||||
|
@ -76,7 +76,7 @@ async function processEntityChanges(entityChanges) {
|
||||
noteAttributeCache.invalidate();
|
||||
}
|
||||
|
||||
const appContext = (await import("./app_context.js")).default;
|
||||
const appContext = (await import("../components/app_context.js")).default;
|
||||
await appContext.triggerEvent('entitiesReloaded', {loadResults});
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,11 @@ import dateNotesService from './date_notes.js';
|
||||
import searchService from './search.js';
|
||||
import CollapsibleWidget from '../widgets/collapsible_widget.js';
|
||||
import ws from "./ws.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import NoteContextAwareWidget from "../widgets/note_context_aware_widget.js";
|
||||
import NoteContextCachingWidget from "../widgets/note_context_caching_widget.js";
|
||||
import BasicWidget from "../widgets/basic_widget.js";
|
||||
import SpacedUpdate from "./spaced_update.js";
|
||||
import shortcutService from "./shortcuts.js";
|
||||
|
||||
/**
|
||||
* This is the main frontend API interface for scripts. It's published in the local "api" object.
|
||||
@ -22,8 +22,6 @@ import SpacedUpdate from "./spaced_update.js";
|
||||
* @hideconstructor
|
||||
*/
|
||||
function FrontendScriptApi(startNote, currentNote, originEntity = null, $container = null) {
|
||||
const $pluginButtons = $("#plugin-buttons");
|
||||
|
||||
/** @property {jQuery} container of all the rendered script content */
|
||||
this.$container = $container;
|
||||
|
||||
@ -40,24 +38,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
|
||||
/** @property {CollapsibleWidget} */
|
||||
this.CollapsibleWidget = CollapsibleWidget;
|
||||
|
||||
/**
|
||||
* @property {NoteContextAwareWidget}
|
||||
* @deprecated use NoteContextAwareWidget instead
|
||||
*/
|
||||
this.TabAwareWidget = NoteContextAwareWidget;
|
||||
|
||||
/** @property {NoteContextAwareWidget} */
|
||||
this.NoteContextAwareWidget = NoteContextAwareWidget;
|
||||
|
||||
/**
|
||||
* @property {NoteContextCachingWidget}
|
||||
* @deprecated use NoteContextCachingWidget instead
|
||||
*/
|
||||
this.TabCachingWidget = NoteContextCachingWidget;
|
||||
|
||||
/** @property {NoteContextAwareWidget} */
|
||||
this.NoteContextCachingWidget = NoteContextCachingWidget;
|
||||
|
||||
/** @property {BasicWidget} */
|
||||
this.BasicWidget = BasicWidget;
|
||||
|
||||
@ -131,49 +114,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds new button to the plugin area.
|
||||
*
|
||||
* @param {ToolbarButtonOptions} opts
|
||||
* @deprecated this API has no effect anymore. Use bookmarks or launchpad shortcuts instead.
|
||||
*/
|
||||
this.addButtonToToolbar = opts => {
|
||||
const buttonId = "toolbar-button-" + opts.title.replace(/\s/g, "-");
|
||||
|
||||
let button;
|
||||
if (utils.isMobile()) {
|
||||
$('#plugin-buttons-placeholder').remove();
|
||||
button = $('<a class="dropdown-item" href="#">')
|
||||
.on('click', () => {
|
||||
setTimeout(() => $pluginButtons.dropdown('hide'), 0);
|
||||
});
|
||||
|
||||
if (opts.icon) {
|
||||
button.append($("<span>").addClass("bx bx-" + opts.icon))
|
||||
.append(" ");
|
||||
}
|
||||
|
||||
button.append($("<span>").text(opts.title));
|
||||
} else {
|
||||
button = $('<span class="button-widget icon-action bx" data-toggle="tooltip" title="" data-placement="right"></span>')
|
||||
.addClass("bx bx-" + (opts.icon || "question-mark"));
|
||||
|
||||
button.attr("title", opts.title);
|
||||
button.tooltip({html: true});
|
||||
}
|
||||
|
||||
button = button.on('click', opts.action);
|
||||
|
||||
button.attr('id', buttonId);
|
||||
|
||||
if ($("#" + buttonId).replaceWith(button).length === 0) {
|
||||
$pluginButtons.append(button);
|
||||
}
|
||||
|
||||
if (opts.shortcut) {
|
||||
utils.bindGlobalShortcut(opts.shortcut, opts.action);
|
||||
|
||||
button.attr("title", "Shortcut " + opts.shortcut);
|
||||
}
|
||||
};
|
||||
this.addButtonToToolbar = () => console.warn("api.addButtonToToolbar() calls are deprecated and have no effect");
|
||||
|
||||
function prepareParams(params) {
|
||||
if (!params) {
|
||||
@ -566,8 +509,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
|
||||
* @method
|
||||
* @param {string} keyboardShortcut - e.g. "ctrl+shift+a"
|
||||
* @param {function} handler
|
||||
* @param {string} [namespace] - specify namespace of the handler for the cases where call for bind may be repeated.
|
||||
* If a handler with this ID exists, it's replaced by the new handler.
|
||||
*/
|
||||
this.bindGlobalShortcut = utils.bindGlobalShortcut;
|
||||
this.bindGlobalShortcut = shortcutService.bindGlobalShortcut;
|
||||
|
||||
/**
|
||||
* Trilium runs in backend and frontend process, when something is changed on the backend from script,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import utils from "./utils.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import server from "./server.js";
|
||||
import libraryLoader from "./library_loader.js";
|
||||
import ws from "./ws.js";
|
||||
|
@ -1,6 +1,7 @@
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import treeService from "./tree.js";
|
||||
import dialogService from "../widgets/dialog.js";
|
||||
import dialogService from "./dialog.js";
|
||||
import froca from "./froca.js";
|
||||
|
||||
function getHoistedNoteId() {
|
||||
const activeNoteContext = appContext.tabManager.getActiveContext();
|
||||
@ -26,6 +27,19 @@ function isHoistedNode(node) {
|
||||
|| node.data.noteId === getHoistedNoteId();
|
||||
}
|
||||
|
||||
async function isHoistedInHiddenSubtree() {
|
||||
const hoistedNoteId = getHoistedNoteId();
|
||||
|
||||
if (hoistedNoteId === 'root') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const hoistedNote = await froca.getNote(hoistedNoteId);
|
||||
const hoistedNotePath = treeService.getSomeNotePath(hoistedNote);
|
||||
|
||||
return treeService.isNotePathInHiddenSubtree(hoistedNotePath);
|
||||
}
|
||||
|
||||
async function checkNoteAccess(notePath, noteContext) {
|
||||
const resolvedNotePath = await treeService.resolveNotePath(notePath, noteContext.hoistedNoteId);
|
||||
|
||||
@ -53,5 +67,6 @@ export default {
|
||||
unhoist,
|
||||
isTopLevelNode,
|
||||
isHoistedNode,
|
||||
checkNoteAccess
|
||||
checkNoteAccess,
|
||||
isHoistedInHiddenSubtree
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import toastService from "./toast.js";
|
||||
import server from "./server.js";
|
||||
import ws from "./ws.js";
|
||||
import utils from "./utils.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
export async function uploadFiles(parentNoteId, files, options) {
|
||||
if (files.length === 0) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import server from "./server.js";
|
||||
import utils from "./utils.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import shortcutService from "./shortcuts.js";
|
||||
|
||||
const keyboardActionRepo = {};
|
||||
|
||||
@ -31,7 +31,7 @@ async function setupActionsForElement(scope, $el, component) {
|
||||
|
||||
for (const action of actions) {
|
||||
for (const shortcut of action.effectiveShortcuts) {
|
||||
utils.bindElShortcut($el, shortcut, () => component.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeNtxId}));
|
||||
shortcutService.bindElShortcut($el, shortcut, () => component.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeNtxId}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -39,37 +39,11 @@ async function setupActionsForElement(scope, $el, component) {
|
||||
getActionsForScope("window").then(actions => {
|
||||
for (const action of actions) {
|
||||
for (const shortcut of action.effectiveShortcuts) {
|
||||
utils.bindGlobalShortcut(shortcut, () => appContext.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeNtxId}));
|
||||
shortcutService.bindGlobalShortcut(shortcut, () => appContext.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeNtxId}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
server.get('keyboard-shortcuts-for-notes').then(shortcutForNotes => {
|
||||
for (const shortcut in shortcutForNotes) {
|
||||
utils.bindGlobalShortcut(shortcut, async () => {
|
||||
appContext.tabManager.getActiveContext().setNote(shortcutForNotes[shortcut]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function setElementActionHandler($el, actionName, handler) {
|
||||
keyboardActionsLoaded.then(() => {
|
||||
const action = keyboardActionRepo[actionName];
|
||||
|
||||
if (!action) {
|
||||
throw new Error(`Cannot find keyboard action '${actionName}'`);
|
||||
}
|
||||
|
||||
// not setting action.handler since this is not global
|
||||
|
||||
for (const shortcut of action.effectiveShortcuts) {
|
||||
if (shortcut) {
|
||||
utils.bindElShortcut($el, shortcut, handler);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function getAction(actionName, silent = false) {
|
||||
await keyboardActionsLoaded;
|
||||
|
||||
@ -116,10 +90,8 @@ function updateDisplayedShortcuts($container) {
|
||||
}
|
||||
|
||||
export default {
|
||||
setElementActionHandler,
|
||||
updateDisplayedShortcuts,
|
||||
setupActionsForElement,
|
||||
getActions,
|
||||
getActionsForScope,
|
||||
getAction
|
||||
getActionsForScope
|
||||
};
|
||||
|
@ -1,11 +1,11 @@
|
||||
import treeService from './tree.js';
|
||||
import linkContextMenuService from "./link_context_menu.js";
|
||||
import appContext from "./app_context.js";
|
||||
import linkContextMenuService from "../menus/link_context_menu.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import froca from "./froca.js";
|
||||
import utils from "./utils.js";
|
||||
|
||||
function getNotePathFromUrl(url) {
|
||||
const notePathMatch = /#(root[A-Za-z0-9/]*)$/.exec(url);
|
||||
const notePathMatch = /#(root[A-Za-z0-9_/]*)$/.exec(url);
|
||||
|
||||
return notePathMatch === null ? null : notePathMatch[1];
|
||||
}
|
||||
@ -90,27 +90,27 @@ function getNotePathFromLink($link) {
|
||||
return url ? getNotePathFromUrl(url) : null;
|
||||
}
|
||||
|
||||
function goToLink(e) {
|
||||
const $link = $(e.target).closest("a,.block-link");
|
||||
function goToLink(evt) {
|
||||
const $link = $(evt.target).closest("a,.block-link");
|
||||
const address = $link.attr('href');
|
||||
|
||||
if (address?.startsWith("data:")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
|
||||
const notePath = getNotePathFromLink($link);
|
||||
|
||||
const ctrlKey = (!utils.isMac() && e.ctrlKey) || (utils.isMac() && e.metaKey);
|
||||
const ctrlKey = utils.isCtrlKey(evt);
|
||||
|
||||
if (notePath) {
|
||||
if ((e.which === 1 && ctrlKey) || e.which === 2) {
|
||||
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(notePath);
|
||||
}
|
||||
else if (e.which === 1) {
|
||||
const ntxId = $(e.target).closest("[data-ntx-id]").attr("data-ntx-id");
|
||||
else if (evt.which === 1) {
|
||||
const ntxId = $(evt.target).closest("[data-ntx-id]").attr("data-ntx-id");
|
||||
|
||||
const noteContext = ntxId
|
||||
? appContext.tabManager.getNoteContextById(ntxId)
|
||||
@ -124,7 +124,7 @@ function goToLink(e) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((e.which === 1 && ctrlKey) || e.which === 2
|
||||
if ((evt.which === 1 && ctrlKey) || evt.which === 2
|
||||
|| $link.hasClass("ck-link-actions__preview") // within edit link dialog single click suffices
|
||||
|| $link.closest("[contenteditable]").length === 0 // outside of CKEditor single click suffices
|
||||
) {
|
||||
|
@ -2,15 +2,16 @@
|
||||
* Mac specific initialization
|
||||
*/
|
||||
import utils from "./utils.js";
|
||||
import shortcutService from "./shortcuts.js";
|
||||
|
||||
function init() {
|
||||
if (utils.isElectron() && utils.isMac()) {
|
||||
utils.bindGlobalShortcut('meta+c', () => exec("copy"));
|
||||
utils.bindGlobalShortcut('meta+v', () => exec('paste'));
|
||||
utils.bindGlobalShortcut('meta+x', () => exec('cut'));
|
||||
utils.bindGlobalShortcut('meta+a', () => exec('selectAll'));
|
||||
utils.bindGlobalShortcut('meta+z', () => exec('undo'));
|
||||
utils.bindGlobalShortcut('meta+y', () => exec('redo'));
|
||||
shortcutService.bindGlobalShortcut('meta+c', () => exec("copy"));
|
||||
shortcutService.bindGlobalShortcut('meta+v', () => exec('paste'));
|
||||
shortcutService.bindGlobalShortcut('meta+x', () => exec('cut'));
|
||||
shortcutService.bindGlobalShortcut('meta+a', () => exec('selectAll'));
|
||||
shortcutService.bindGlobalShortcut('meta+z', () => exec('undo'));
|
||||
shortcutService.bindGlobalShortcut('meta+y', () => exec('redo'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,4 +23,4 @@ function exec(cmd) {
|
||||
|
||||
export default {
|
||||
init
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import server from "./server.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import utils from './utils.js';
|
||||
import noteCreateService from './note_create.js';
|
||||
import treeService from './tree.js';
|
||||
|
@ -148,7 +148,7 @@ async function getRenderedContent(note, options = {}) {
|
||||
else if (type === 'book') {
|
||||
// nothing, book doesn't have its own content
|
||||
}
|
||||
else if (!options.tooltip && type === 'protected-session') {
|
||||
else if (!options.tooltip && type === 'protectedSession') {
|
||||
const $button = $(`<button class="btn btn-sm"><span class="bx bx-log-in"></span> Enter protected session</button>`)
|
||||
.on('click', protectedSessionService.enterProtectedSession);
|
||||
|
||||
@ -219,7 +219,7 @@ function getRenderingType(note) {
|
||||
protectedSessionHolder.touchProtectedSession();
|
||||
}
|
||||
else {
|
||||
type = 'protected-session';
|
||||
type = 'protectedSession';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import utils from "./utils.js";
|
||||
import protectedSessionHolder from "./protected_session_holder.js";
|
||||
import server from "./server.js";
|
||||
|
@ -92,7 +92,7 @@ const TPL = `
|
||||
border: 1px solid var(--main-border-color);
|
||||
}
|
||||
|
||||
.note-book-content.type-image, .note-book-content.type-file, .note-book-content.type-protected-session {
|
||||
.note-book-content.type-image, .note-book-content.type-file, .note-book-content.type-protectedSession {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
@ -6,13 +6,13 @@ async function getNoteTypeItems(command) {
|
||||
{ title: "Text", command: command, type: "text", uiIcon: "bx bx-note" },
|
||||
{ title: "Code", command: command, type: "code", uiIcon: "bx bx-code" },
|
||||
{ title: "Saved Search", command: command, type: "search", uiIcon: "bx bx-file-find" },
|
||||
{ title: "Relation Map", command: command, type: "relation-map", uiIcon: "bx bx-map-alt" },
|
||||
{ title: "Note Map", command: command, type: "note-map", uiIcon: "bx bx-map-alt" },
|
||||
{ title: "Relation Map", command: command, type: "relationMap", uiIcon: "bx bx-map-alt" },
|
||||
{ title: "Note Map", command: command, type: "noteMap", uiIcon: "bx bx-map-alt" },
|
||||
{ title: "Render Note", command: command, type: "render", uiIcon: "bx bx-extension" },
|
||||
{ title: "Book", command: command, type: "book", uiIcon: "bx bx-book" },
|
||||
{ title: "Mermaid Diagram", command: command, type: "mermaid", uiIcon: "bx bx-selection" },
|
||||
{ title: "Canvas", command: command, type: "canvas", uiIcon: "bx bx-pen" },
|
||||
{ title: "Web View", command: command, type: "web-view", uiIcon: "bx bx-globe-alt" },
|
||||
{ title: "Web View", command: command, type: "webView", uiIcon: "bx bx-globe-alt" },
|
||||
];
|
||||
|
||||
const templateNoteIds = await server.get("search-templates");
|
||||
|
@ -2,7 +2,7 @@ import server from './server.js';
|
||||
import protectedSessionHolder from './protected_session_holder.js';
|
||||
import toastService from "./toast.js";
|
||||
import ws from "./ws.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import froca from "./froca.js";
|
||||
import utils from "./utils.js";
|
||||
import options from "./options.js";
|
||||
|
@ -1,9 +1,10 @@
|
||||
import utils from './utils.js';
|
||||
import ValidationError from "./validation_error.js";
|
||||
|
||||
const REQUEST_LOGGING_ENABLED = false;
|
||||
|
||||
async function getHeaders(headers) {
|
||||
const appContext = (await import('./app_context.js')).default;
|
||||
const appContext = (await import('../components/app_context.js')).default;
|
||||
const activeNoteContext = appContext.tabManager ? appContext.tabManager.getActiveContext() : null;
|
||||
|
||||
// headers need to be lowercase because node.js automatically converts them to lower case
|
||||
@ -102,10 +103,15 @@ async function call(method, url, data, headers = {}) {
|
||||
return resp.body;
|
||||
}
|
||||
|
||||
async function reportError(method, url, status, error) {
|
||||
const message = "Error when calling " + method + " " + url + ": " + status + " - " + error;
|
||||
|
||||
async function reportError(method, url, status, response) {
|
||||
const toastService = (await import("./toast.js")).default;
|
||||
|
||||
if ([400, 404].includes(status) && response && typeof response === 'object') {
|
||||
toastService.showError(response.message);
|
||||
throw new ValidationError(response);
|
||||
}
|
||||
|
||||
const message = "Error when calling " + method + " " + url + ": " + status + " - " + response;
|
||||
toastService.showError(message);
|
||||
toastService.throwError(message);
|
||||
}
|
||||
|
57
src/public/app/services/shortcuts.js
Normal file
57
src/public/app/services/shortcuts.js
Normal file
@ -0,0 +1,57 @@
|
||||
import utils from "./utils.js";
|
||||
|
||||
function removeGlobalShortcut(namespace) {
|
||||
bindGlobalShortcut('', null, namespace);
|
||||
}
|
||||
|
||||
function bindGlobalShortcut(keyboardShortcut, handler, namespace = null) {
|
||||
bindElShortcut($(document), keyboardShortcut, handler, namespace);
|
||||
}
|
||||
|
||||
function bindElShortcut($el, keyboardShortcut, handler, namespace = null) {
|
||||
if (utils.isDesktop()) {
|
||||
keyboardShortcut = normalizeShortcut(keyboardShortcut);
|
||||
|
||||
let eventName = 'keydown';
|
||||
|
||||
if (namespace) {
|
||||
eventName += "." + namespace;
|
||||
|
||||
// if there's a namespace then we replace the existing event handler with the new one
|
||||
$el.off(eventName);
|
||||
}
|
||||
|
||||
// method can be called to remove the shortcut (e.g. when keyboardShortcut label is deleted)
|
||||
if (keyboardShortcut) {
|
||||
$el.bind(eventName, keyboardShortcut, e => {
|
||||
handler(e);
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize to the form expected by the jquery.hotkeys.js
|
||||
*/
|
||||
function normalizeShortcut(shortcut) {
|
||||
if (!shortcut) {
|
||||
return shortcut;
|
||||
}
|
||||
|
||||
return shortcut
|
||||
.toLowerCase()
|
||||
.replace("enter", "return")
|
||||
.replace("delete", "del")
|
||||
.replace("ctrl+alt", "alt+ctrl")
|
||||
.replace("meta+alt", "alt+meta"); // alt needs to be first;
|
||||
}
|
||||
|
||||
export default {
|
||||
bindGlobalShortcut,
|
||||
bindElShortcut,
|
||||
removeGlobalShortcut,
|
||||
normalizeShortcut
|
||||
}
|
@ -3,7 +3,7 @@ import utils from './utils.js';
|
||||
import server from './server.js';
|
||||
import froca from './froca.js';
|
||||
import hoistedNoteService from '../services/hoisted_note.js';
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
/**
|
||||
* @return {string|null}
|
||||
@ -304,6 +304,14 @@ function getHashValueFromAddress() {
|
||||
return str.split("-");
|
||||
}
|
||||
|
||||
function isNotePathInAddress() {
|
||||
const [notePath, ntxId] = getHashValueFromAddress();
|
||||
|
||||
return notePath.startsWith("root")
|
||||
// empty string is for empty/uninitialized tab
|
||||
|| (notePath === '' && !!ntxId);
|
||||
}
|
||||
|
||||
function parseNotePath(notePath) {
|
||||
let noteIds = notePath.split('/');
|
||||
|
||||
@ -314,6 +322,10 @@ function parseNotePath(notePath) {
|
||||
return noteIds;
|
||||
}
|
||||
|
||||
function isNotePathInHiddenSubtree(notePath) {
|
||||
return notePath?.includes("root/hidden");
|
||||
}
|
||||
|
||||
export default {
|
||||
resolveNotePath,
|
||||
resolveNotePathToSegments,
|
||||
@ -328,5 +340,7 @@ export default {
|
||||
getNotePathTitle,
|
||||
getNoteTitleWithPathAsSuffix,
|
||||
getHashValueFromAddress,
|
||||
parseNotePath
|
||||
isNotePathInAddress,
|
||||
parseNotePath,
|
||||
isNotePathInHiddenSubtree
|
||||
};
|
||||
|
@ -60,6 +60,11 @@ function isMac() {
|
||||
return navigator.platform.indexOf('Mac') > -1;
|
||||
}
|
||||
|
||||
function isCtrlKey(evt) {
|
||||
return (!isMac() && evt.ctrlKey)
|
||||
|| (isMac() && evt.metaKey);
|
||||
}
|
||||
|
||||
function assertArguments() {
|
||||
for (const i in arguments) {
|
||||
if (!arguments[i]) {
|
||||
@ -132,35 +137,6 @@ function randomString(len) {
|
||||
return text;
|
||||
}
|
||||
|
||||
function bindGlobalShortcut(keyboardShortcut, handler) {
|
||||
bindElShortcut($(document), keyboardShortcut, handler);
|
||||
}
|
||||
|
||||
function bindElShortcut($el, keyboardShortcut, handler) {
|
||||
if (isDesktop()) {
|
||||
keyboardShortcut = normalizeShortcut(keyboardShortcut);
|
||||
|
||||
$el.bind('keydown', keyboardShortcut, e => {
|
||||
handler(e);
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize to the form expected by the jquery.hotkeys.js
|
||||
*/
|
||||
function normalizeShortcut(shortcut) {
|
||||
return shortcut
|
||||
.toLowerCase()
|
||||
.replace("enter", "return")
|
||||
.replace("delete", "del")
|
||||
.replace("ctrl+alt", "alt+ctrl")
|
||||
.replace("meta+alt", "alt+meta"); // alt needs to be first;
|
||||
}
|
||||
|
||||
function isMobile() {
|
||||
return window.device === "mobile"
|
||||
// window.device is not available in setup
|
||||
@ -349,7 +325,13 @@ function openHelp(e) {
|
||||
}
|
||||
|
||||
function initHelpButtons($el) {
|
||||
$el.on("click", "*[data-help-page]", e => openHelp(e));
|
||||
// for some reason the .on(event, listener, handler) does not work here (e.g. Options -> Sync -> Help button)
|
||||
// so we do it manually
|
||||
$el.on("click", e => {
|
||||
if ($(e.target).attr("data-help-page")) {
|
||||
openHelp(e)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function filterAttributeName(name) {
|
||||
@ -385,14 +367,13 @@ export default {
|
||||
now,
|
||||
isElectron,
|
||||
isMac,
|
||||
isCtrlKey,
|
||||
assertArguments,
|
||||
escapeHtml,
|
||||
stopWatch,
|
||||
formatLabel,
|
||||
toObject,
|
||||
randomString,
|
||||
bindGlobalShortcut,
|
||||
bindElShortcut,
|
||||
isMobile,
|
||||
isDesktop,
|
||||
setCookie,
|
||||
@ -406,7 +387,6 @@ export default {
|
||||
focusSavedElement,
|
||||
isHtmlEmpty,
|
||||
clearBrowserCache,
|
||||
normalizeShortcut,
|
||||
copySelectionToClipboard,
|
||||
dynamicRequire,
|
||||
timeLimit,
|
||||
|
7
src/public/app/services/validation_error.js
Normal file
7
src/public/app/services/validation_error.js
Normal file
@ -0,0 +1,7 @@
|
||||
export default class ValidationError {
|
||||
constructor(resp) {
|
||||
for (const key in resp) {
|
||||
this[key] = resp[key];
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ import toastService from "./toast.js";
|
||||
import server from "./server.js";
|
||||
import options from "./options.js";
|
||||
import frocaUpdater from "./froca_updater.js";
|
||||
import appContext from "./app_context.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
|
||||
const messageHandlers = [];
|
||||
|
||||
|
@ -8,6 +8,7 @@ import promotedAttributeDefinitionParser from '../../services/promoted_attribute
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import SpacedUpdate from "../../services/spaced_update.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import shortcutService from "../../services/shortcuts.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="attr-detail">
|
||||
@ -213,7 +214,6 @@ const ATTR_HELP = {
|
||||
"inbox": "default inbox location for new notes - when you create a note using \"new note\" button in the sidebar, notes will be created as child notes in the note marked as with <code>#inbox</code> label.",
|
||||
"hoistedInbox": "default inbox location for new notes when hoisted to some ancestor of this note",
|
||||
"sqlConsoleHome": "default location of SQL console notes",
|
||||
"bookmarked": "note with this label will appear in bookmarks",
|
||||
"bookmarkFolder": "note with this label will appear in bookmarks as folder (allowing access to its children)",
|
||||
"shareHiddenFromTree": "this note is hidden from left navigation tree, but still accessible with its URL",
|
||||
"shareAlias": "define an alias using which the note will be available under https://your_trilium_host/share/[your_alias]",
|
||||
@ -238,7 +238,8 @@ const ATTR_HELP = {
|
||||
"template": "This note will appear in the selection of available template when creating new note",
|
||||
"toc": "<code>#toc</code> or <code>#toc=show</code> will force the Table of Contents to be shown, <code>#toc=hide</code> will force hiding it. If the label doesn't exist, the global setting is observed",
|
||||
"color": "defines color of the note in note tree, links etc. Use any valid CSS color value like 'red' or #a13d5f",
|
||||
"keyboardShortcut": "Defines a keyboard shortcut which will immediately jump to this note. Example: 'ctrl+alt+e'. Requires frontend reload for the change to take effect."
|
||||
"keyboardShortcut": "Defines a keyboard shortcut which will immediately jump to this note. Example: 'ctrl+alt+e'. Requires frontend reload for the change to take effect.",
|
||||
"keepCurrentHoisting": "Opening this link won't change hoisting even if the note is not displayable in the current hoisted subtree."
|
||||
},
|
||||
"relation": {
|
||||
"runOnNoteCreation": "executes when note is created on backend. Use this relation if you want to run the script for all notes created under a specific subtree. In that case, create it on the subtree root note and make it inheritable. A new note created within the subtree (any depth) will trigger the script.",
|
||||
@ -271,8 +272,8 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
|
||||
|
||||
this.$widget = $(TPL);
|
||||
|
||||
utils.bindElShortcut(this.$widget, 'ctrl+return', () => this.saveAndClose());
|
||||
utils.bindElShortcut(this.$widget, 'esc', () => this.cancelAndClose());
|
||||
shortcutService.bindElShortcut(this.$widget, 'ctrl+return', () => this.saveAndClose());
|
||||
shortcutService.bindElShortcut(this.$widget, 'esc', () => this.cancelAndClose());
|
||||
|
||||
|
||||
this.$title = this.$widget.find('.attr-detail-title');
|
||||
|
@ -1,7 +1,7 @@
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import noteAutocompleteService from "../../services/note_autocomplete.js";
|
||||
import server from "../../services/server.js";
|
||||
import contextMenuService from "../../services/context_menu.js";
|
||||
import contextMenuService from "../../menus/context_menu.js";
|
||||
import attributesParser from "../../services/attribute_parser.js";
|
||||
import libraryLoader from "../../services/library_loader.js";
|
||||
import froca from "../../services/froca.js";
|
||||
@ -333,7 +333,7 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget {
|
||||
|
||||
getPreprocessedData() {
|
||||
const str = this.textEditor.getData()
|
||||
.replace(/<a[^>]+href="(#[A-Za-z0-9/]*)"[^>]*>[^<]*<\/a>/g, "$1")
|
||||
.replace(/<a[^>]+href="(#[A-Za-z0-9_/]*)"[^>]*>[^<]*<\/a>/g, "$1")
|
||||
.replace(/ /g, " "); // otherwise .text() below outputs non-breaking space in unicode
|
||||
|
||||
return $("<div>").html(str).text();
|
||||
@ -357,7 +357,7 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget {
|
||||
// disable spellcheck for attribute editor
|
||||
this.textEditor.editing.view.change(writer => writer.setAttribute('spellcheck', 'false', this.textEditor.editing.view.document.getRoot()));
|
||||
|
||||
//await import(/* webpackIgnore: true */'../../libraries/ckeditor/inspector.js');
|
||||
//await import(/* webpackIgnore: true */'../../libraries/ckeditor/inspector');
|
||||
//CKEditorInspector.attach(this.textEditor);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Component from "./component.js";
|
||||
import Component from "../components/component.js";
|
||||
|
||||
class BasicWidget extends Component {
|
||||
constructor() {
|
||||
@ -53,12 +53,6 @@ class BasicWidget extends Component {
|
||||
return this;
|
||||
}
|
||||
|
||||
overflowing() {
|
||||
console.log("Using overflowing() is deprecated NOOP and it is recommended to remove its use.");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
collapsible() {
|
||||
this.css('min-height', '0');
|
||||
this.css('min-width', '0');
|
||||
@ -78,6 +72,7 @@ class BasicWidget extends Component {
|
||||
render() {
|
||||
this.doRender();
|
||||
|
||||
this.$widget.attr('data-component-id', this.componentId);
|
||||
this.$widget.addClass('component')
|
||||
.prop('component', this);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import FlexContainer from "./containers/flex_container.js";
|
||||
import searchService from "../services/search.js";
|
||||
import OpenNoteButtonWidget from "./buttons/open_note_button_widget.js";
|
||||
import BookmarkFolderWidget from "./buttons/bookmark_folder.js";
|
||||
import froca from "../services/froca.js";
|
||||
|
||||
export default class BookmarkButtons extends FlexContainer {
|
||||
constructor() {
|
||||
@ -11,19 +11,21 @@ export default class BookmarkButtons extends FlexContainer {
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
const bookmarkedNotes = await searchService.searchForNotes("#bookmarked or #bookmarkFolder");
|
||||
|
||||
this.$widget.empty();
|
||||
this.children = [];
|
||||
this.noteIds = [];
|
||||
|
||||
for (const note of bookmarkedNotes) {
|
||||
const bookmarkParentNote = await froca.getNote('lbBookmarks');
|
||||
|
||||
for (const note of await bookmarkParentNote.getChildNotes()) {
|
||||
this.noteIds.push(note.noteId);
|
||||
|
||||
const buttonWidget = note.hasLabel("bookmarkFolder")
|
||||
? new BookmarkFolderWidget(note)
|
||||
: new OpenNoteButtonWidget().targetNote(note.noteId);
|
||||
|
||||
buttonWidget.class("launcher-button");
|
||||
|
||||
this.child(buttonWidget);
|
||||
|
||||
this.$widget.append(buttonWidget.render());
|
||||
@ -37,11 +39,7 @@ export default class BookmarkButtons extends FlexContainer {
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
if (loadResults.getAttributes().find(attr => attr.type === 'label' && ['bookmarked', 'bookmarkFolder'].includes(attr.name))) {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
if (loadResults.getNoteIds().find(noteId => this.noteIds.includes(noteId))) {
|
||||
if (loadResults.getBranches().find(branch => branch.parentNoteId === 'lbBookmarks')) {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,14 @@
|
||||
import attributeService from "../services/attributes.js";
|
||||
import SwitchWidget from "./switch.js";
|
||||
import server from "../services/server.js";
|
||||
import toastService from "../services/toast.js";
|
||||
|
||||
export default class BookmarkSwitchWidget extends SwitchWidget {
|
||||
isEnabled() {
|
||||
return super.isEnabled()
|
||||
// it's not possible to bookmark root because that would clone it under bookmarks and thus create a cycle
|
||||
&& !['root', 'hidden'].includes(this.noteId);
|
||||
}
|
||||
|
||||
doRender() {
|
||||
super.doRender();
|
||||
|
||||
@ -12,32 +19,24 @@ export default class BookmarkSwitchWidget extends SwitchWidget {
|
||||
this.$switchOffButton.attr("title", "Remove bookmark");
|
||||
}
|
||||
|
||||
async switchOff() {
|
||||
for (const label of this.note.getLabels('bookmarked')) {
|
||||
await attributeService.removeAttributeById(this.noteId, label.attributeId);
|
||||
async toggle(state) {
|
||||
const resp = await server.put(`notes/${this.noteId}/toggle-in-parent/lbBookmarks/` + !!state);
|
||||
|
||||
if (!resp.success) {
|
||||
toastService.showError(resp.message);
|
||||
}
|
||||
}
|
||||
|
||||
switchOn() {
|
||||
return attributeService.setLabel(this.noteId, 'bookmarked');
|
||||
}
|
||||
|
||||
refreshWithNote(note) {
|
||||
const isBookmarked = note.hasLabel('bookmarked');
|
||||
const isBookmarked = !!note.getParentBranches().find(b => b.parentNoteId === 'lbBookmarks');
|
||||
|
||||
this.$switchOn.toggle(!isBookmarked);
|
||||
this.$switchOff.toggle(isBookmarked);
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
for (const attr of loadResults.getAttributes()) {
|
||||
if (attr.type === 'label'
|
||||
&& attr.name === 'bookmarked'
|
||||
&& attributeService.isAffecting(attr, this.note)) {
|
||||
|
||||
this.refresh();
|
||||
break;
|
||||
}
|
||||
if (loadResults.getBranches().find(b => b.noteId === this.noteId)) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
91
src/public/app/widgets/buttons/abstract_button.js
Normal file
91
src/public/app/widgets/buttons/abstract_button.js
Normal file
@ -0,0 +1,91 @@
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
|
||||
const TPL = `<button class="button-widget no-print" data-toggle="tooltip">
|
||||
<span class="bx"></span>
|
||||
</button>`;
|
||||
|
||||
export default class AbstractButtonWidget extends NoteContextAwareWidget {
|
||||
isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.settings = {
|
||||
titlePlacement: 'right',
|
||||
title: null,
|
||||
icon: null,
|
||||
onContextMenu: null
|
||||
};
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$iconSpan = this.$widget.find("span");
|
||||
|
||||
if (this.settings.onContextMenu) {
|
||||
this.$widget.on("contextmenu", e => {
|
||||
this.$widget.tooltip("hide");
|
||||
|
||||
this.settings.onContextMenu(e);
|
||||
});
|
||||
}
|
||||
|
||||
this.$widget.attr("data-placement", this.settings.titlePlacement);
|
||||
|
||||
this.$widget.tooltip({
|
||||
html: true,
|
||||
title: () => this.getTitle(),
|
||||
trigger: "hover"
|
||||
});
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
return typeof this.settings.title === "function"
|
||||
? this.settings.title()
|
||||
: this.settings.title;
|
||||
}
|
||||
|
||||
refreshIcon() {
|
||||
for (const className of this.$iconSpan[0].classList) {
|
||||
if (className.startsWith("bx-")) {
|
||||
this.$iconSpan.removeClass(className);
|
||||
}
|
||||
}
|
||||
|
||||
const icon = typeof this.settings.icon === "function"
|
||||
? this.settings.icon()
|
||||
: this.settings.icon;
|
||||
|
||||
this.$iconSpan.addClass(icon);
|
||||
}
|
||||
|
||||
initialRenderCompleteEvent() {
|
||||
this.refreshIcon();
|
||||
}
|
||||
|
||||
/** @param {string|function} icon */
|
||||
icon(icon) {
|
||||
this.settings.icon = icon;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @param {string|function} title */
|
||||
title(title) {
|
||||
this.settings.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @param {string} placement - "top", "bottom", "left", "right" */
|
||||
titlePlacement(placement) {
|
||||
this.settings.titlePlacement = placement;
|
||||
return this;
|
||||
}
|
||||
|
||||
onContextMenu(handler) {
|
||||
this.settings.onContextMenu = handler;
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@ const DROPDOWN_TPL = `
|
||||
|
||||
export default class BookmarkFolderWidget extends RightDropdownButtonWidget {
|
||||
constructor(note) {
|
||||
super(note.getIcon(), note.title, DROPDOWN_TPL);
|
||||
super(note.title, note.getIcon(), DROPDOWN_TPL);
|
||||
|
||||
this.note = note;
|
||||
}
|
||||
|
53
src/public/app/widgets/buttons/button_from_note.js
Normal file
53
src/public/app/widgets/buttons/button_from_note.js
Normal file
@ -0,0 +1,53 @@
|
||||
import froca from "../../services/froca.js";
|
||||
import attributeService from "../../services/attributes.js";
|
||||
import CommandButtonWidget from "./command_button.js";
|
||||
|
||||
export default class ButtonFromNoteWidget extends CommandButtonWidget {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.settings.buttonNoteIdProvider = null;
|
||||
}
|
||||
|
||||
buttonNoteIdProvider(provider) {
|
||||
this.settings.buttonNoteIdProvider = provider;
|
||||
return this;
|
||||
}
|
||||
|
||||
doRender() {
|
||||
super.doRender();
|
||||
|
||||
this.updateIcon();
|
||||
}
|
||||
|
||||
updateIcon() {
|
||||
const buttonNoteId = this.settings.buttonNoteIdProvider();
|
||||
|
||||
if (!buttonNoteId) {
|
||||
console.error(`buttonNoteId for '${this.componentId}' is not defined.`);
|
||||
return;
|
||||
}
|
||||
|
||||
froca.getNote(buttonNoteId).then(note => {
|
||||
this.settings.icon = note.getIcon();
|
||||
|
||||
this.refreshIcon();
|
||||
});
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
const buttonNote = froca.getNoteFromCache(this.buttonNoteIdProvider());
|
||||
|
||||
if (!buttonNote) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (loadResults.getAttributes(this.componentId).find(attr =>
|
||||
attr.type === 'label'
|
||||
&& attr.name === 'iconClass'
|
||||
&& attributeService.isAffecting(attr, buttonNote))) {
|
||||
|
||||
this.updateIcon();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||
import keyboardActionsService from "../../services/keyboard_actions.js";
|
||||
|
||||
const TPL = `<span class="button-widget icon-action bx"
|
||||
data-toggle="tooltip"
|
||||
title=""></span>`;
|
||||
|
||||
let actions;
|
||||
|
||||
keyboardActionsService.getActions().then(as => actions = as);
|
||||
|
||||
export default class ButtonWidget extends NoteContextAwareWidget {
|
||||
isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.settings = {
|
||||
titlePlacement: 'right'
|
||||
};
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
|
||||
if (this.settings.onClick) {
|
||||
this.$widget.on("click", e => {
|
||||
this.$widget.tooltip("hide");
|
||||
|
||||
this.settings.onClick(this, e);
|
||||
});
|
||||
} else {
|
||||
this.$widget.on("click", () => {
|
||||
this.$widget.tooltip("hide");
|
||||
|
||||
this.triggerCommand(this.settings.command);
|
||||
});
|
||||
}
|
||||
|
||||
this.$widget.attr("data-placement", this.settings.titlePlacement);
|
||||
|
||||
this.$widget.tooltip({
|
||||
html: true,
|
||||
title: () => {
|
||||
const title = typeof this.settings.title === "function"
|
||||
? this.settings.title()
|
||||
: this.settings.title;
|
||||
|
||||
const action = actions.find(act => act.actionName === this.settings.command);
|
||||
|
||||
if (action && action.effectiveShortcuts.length > 0) {
|
||||
return `${title} (${action.effectiveShortcuts.join(", ")})`;
|
||||
}
|
||||
else {
|
||||
return title;
|
||||
}
|
||||
},
|
||||
trigger: "hover"
|
||||
});
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
refreshIcon() {
|
||||
for (const className of this.$widget[0].classList) {
|
||||
if (className.startsWith("bx-")) {
|
||||
this.$widget.removeClass(className);
|
||||
}
|
||||
}
|
||||
|
||||
this.$widget
|
||||
.addClass(this.settings.icon);
|
||||
}
|
||||
|
||||
initialRenderCompleteEvent() {
|
||||
this.refreshIcon();
|
||||
}
|
||||
|
||||
icon(icon) {
|
||||
this.settings.icon = icon;
|
||||
return this;
|
||||
}
|
||||
|
||||
title(title) {
|
||||
this.settings.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
titlePlacement(placement) {
|
||||
this.settings.titlePlacement = placement;
|
||||
return this;
|
||||
}
|
||||
|
||||
command(command) {
|
||||
this.settings.command = command;
|
||||
return this;
|
||||
}
|
||||
|
||||
onClick(handler) {
|
||||
this.settings.onClick = handler;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ import libraryLoader from "../../services/library_loader.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import dateNoteService from "../../services/date_notes.js";
|
||||
import server from "../../services/server.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import RightDropdownButtonWidget from "./right_dropdown_button.js";
|
||||
import toastService from "../../services/toast.js";
|
||||
|
||||
@ -29,8 +29,8 @@ const DROPDOWN_TPL = `
|
||||
</div>`;
|
||||
|
||||
export default class CalendarWidget extends RightDropdownButtonWidget {
|
||||
constructor() {
|
||||
super("bx-calendar", "Calendar", DROPDOWN_TPL);
|
||||
constructor(title, icon) {
|
||||
super(title, icon, DROPDOWN_TPL);
|
||||
}
|
||||
|
||||
doRender() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import ButtonWidget from "./button_widget.js";
|
||||
import OnClickButtonWidget from "./onclick_button.js";
|
||||
|
||||
export default class ClosePaneButton extends ButtonWidget {
|
||||
export default class ClosePaneButton extends OnClickButtonWidget {
|
||||
isEnabled() {
|
||||
return super.isEnabled()
|
||||
// main note context should not be closeable
|
||||
|
54
src/public/app/widgets/buttons/command_button.js
Normal file
54
src/public/app/widgets/buttons/command_button.js
Normal file
@ -0,0 +1,54 @@
|
||||
import keyboardActionsService from "../../services/keyboard_actions.js";
|
||||
import AbstractButtonWidget from "./abstract_button.js";
|
||||
|
||||
let actions;
|
||||
|
||||
keyboardActionsService.getActions().then(as => actions = as);
|
||||
|
||||
export default class CommandButtonWidget extends AbstractButtonWidget {
|
||||
doRender() {
|
||||
super.doRender();
|
||||
|
||||
if (this.settings.command) {
|
||||
this.$widget.on("click", () => {
|
||||
this.$widget.tooltip("hide");
|
||||
|
||||
this.triggerCommand(this._command);
|
||||
});
|
||||
} else {
|
||||
console.warn(`Button widget '${this.componentId}' has no defined command`, this.settings);
|
||||
}
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
const title = super.getTitle();
|
||||
|
||||
const action = actions.find(act => act.actionName === this._command);
|
||||
|
||||
if (action && action.effectiveShortcuts.length > 0) {
|
||||
return `${title} (${action.effectiveShortcuts.join(", ")})`;
|
||||
} else {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
||||
onClick(handler) {
|
||||
this.settings.onClick = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function|string} command
|
||||
* @returns {CommandButtonWidget}
|
||||
*/
|
||||
command(command) {
|
||||
this.settings.command = command;
|
||||
return this;
|
||||
}
|
||||
|
||||
get _command() {
|
||||
return typeof this.settings.command === "function"
|
||||
? this.settings.command()
|
||||
: this.settings.command;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user