Compare commits

...

49 Commits

Author SHA1 Message Date
zadam
13e9f9f9e7 release 0.33.7 2019-07-11 20:55:56 +02:00
zadam
a76dcb44ae improvements in the exported file extensions 2019-07-11 20:54:57 +02:00
zadam
b9373806cf fix doubling of extension 2019-07-11 20:40:40 +02:00
zadam
9de2927304 image import/export related fixes 2019-07-10 23:01:30 +02:00
zadam
c3e1126489 backported image fixes 2019-07-10 20:38:27 +02:00
zadam
3413c9ed64 backport notePath handling fixes from master 2019-07-10 20:35:01 +02:00
zadam
ddf381f92d fixed duplicated notes after creating into a folder which wasn't yet loaded 2019-07-06 13:14:33 +02:00
zadam
2b44f3bc76 fixed websocket reconnection 2019-07-06 12:03:51 +02:00
zadam
bf3360572a nest code editor instance to avoid visibility issues 2019-07-03 20:37:59 +02:00
zadam
e5036318af fix enter on title to the code editor 2019-07-03 20:29:55 +02:00
zadam
6d2394a9da release 0.33.6 2019-07-02 22:26:05 +02:00
zadam
196264b8c2 use bootstrap modal to confirm note deletion which fixes #582 2019-07-02 21:54:37 +02:00
zadam
afe24866f0 some debug logging for duplicated nodes 2019-07-02 20:35:06 +02:00
zadam
d18a20cc06 fix focus issue from title to the text content with tab/enter 2019-07-02 20:28:57 +02:00
zadam
9c91b0459e release 0.33.5 2019-06-30 21:47:04 +02:00
zadam
af21dd4463 fix mobile text editor display 2019-06-30 20:14:57 +02:00
zadam
1ea0d283de fix text instance sometimes remaining displayed when switching to e.g. image 2019-06-30 19:41:26 +02:00
zadam
6e3d8472e1 avoid duplicate key error 2019-06-28 21:50:15 +02:00
zadam
2a9f36a027 fix activating parent note after delete 2019-06-27 22:58:04 +02:00
zadam
cf3726289c attempt to fix the duplicate issue 2019-06-27 21:24:25 +02:00
zadam
c8e4a5c9e7 release 0.33.4 2019-06-26 21:20:30 +02:00
zadam
a3951f1cce make sure autocomplete is closed when navigating to note 2019-06-26 21:08:54 +02:00
zadam
7c77ae758b fix frontend reload again 2019-06-26 20:49:17 +02:00
zadam
20d3d61cec release 0.33.3 2019-06-24 20:47:50 +02:00
zadam
1b831f94a9 fix orphan note autocomplete, closes #569 2019-06-24 20:45:35 +02:00
zadam
3f241553aa fix pngquant for linux-x64 2019-06-24 20:27:28 +02:00
zadam
8624c83108 use 127.0.0.1 instead of localhost, #577 2019-06-24 20:26:28 +02:00
zadam
d49cae9cea fix update of window title during note renaming 2019-06-24 20:12:04 +02:00
zadam
504b2e2c4a Merge pull request #574 from maurerit/master
Build failed without python for arm
2019-06-21 09:10:17 +02:00
Matt Maurer
2c5292222f Build failed without python for arm 2019-06-20 23:45:31 +00:00
zadam
989da8877b added link map 2019-06-20 10:20:44 +02:00
zadam
70591eadd5 release 0.33.2-beta 2019-06-20 09:39:11 +02:00
zadam
fead3cd7ad fix note export/import/branch prefix to use right-clicked note as opposed to current active 2019-06-20 09:37:18 +02:00
zadam
a7cf3cdf05 fix unloading protected session after the timeout, fixes #571 2019-06-19 22:23:55 +02:00
zadam
5372f71faa hide menu bar 2019-06-19 20:45:19 +02:00
zadam
3b76939f17 distinction between unfocused active and hovered node - unfocused active has dashed border 2019-06-17 22:30:26 +02:00
zadam
c827d38f39 when single note is selected and it's the same that was right clicked for context menu, then we treat it as no-selection action 2019-06-17 22:25:22 +02:00
zadam
1e7586fae4 context menu items are now disabled when there are selected notes and the item does not support actions on multiple items 2019-06-17 20:34:00 +02:00
zadam
ee89111bfb fix clipboard operation for single nodes 2019-06-16 18:07:22 +02:00
zadam
288b3077b2 context menu items are now disabled when there are selected notes and the item does not support actions on multiple items 2019-06-16 12:06:06 +02:00
zadam
5c1922ac9f release 0.33.1-beta 2019-06-16 11:13:37 +02:00
zadam
93f1d46104 fix tree activation/focus after deleting node 2019-06-16 11:12:07 +02:00
zadam
c5daaf541a active note has also border to make it more prominent 2019-06-16 10:53:30 +02:00
zadam
12b17b1e9e fix ctrl+. to switch focus to note tree 2019-06-16 10:41:22 +02:00
zadam
ad46ba7d0f fix fancytree navigation bug before official release, use unminified build in the meantime 2019-06-16 09:44:23 +02:00
zadam
44f592c6cb fix reload 2019-06-16 09:15:37 +02:00
zadam
943b35fb7d fix delete with keyboard and context menu regarding the selection 2019-06-13 22:55:06 +02:00
zadam
f1967fd466 fix unhoisting note 2019-06-13 22:45:55 +02:00
zadam
ce2404b18a add link to link map to README 2019-06-12 22:10:05 +02:00
41 changed files with 379 additions and 287 deletions

View File

@@ -18,6 +18,7 @@ RUN set -x \
make \ make \
nasm \ nasm \
libpng-dev \ libpng-dev \
python \
&& npm install --production \ && npm install --production \
&& apk del .build-dependencies && apk del .build-dependencies

View File

@@ -15,7 +15,7 @@ Trilium Notes is a hierarchical note taking application with focus on building l
* Note [attributes](https://github.com/zadam/trilium/wiki/Attributes) can be used for note organization, querying and advanced [scripting](https://github.com/zadam/trilium/wiki/Scripts) * Note [attributes](https://github.com/zadam/trilium/wiki/Attributes) can be used for note organization, querying and advanced [scripting](https://github.com/zadam/trilium/wiki/Scripts)
* [Synchronization](https://github.com/zadam/trilium/wiki/Synchronization) with self-hosted sync server * [Synchronization](https://github.com/zadam/trilium/wiki/Synchronization) with self-hosted sync server
* Strong [note encryption](https://github.com/zadam/trilium/wiki/Protected-notes) with per-note granularity * Strong [note encryption](https://github.com/zadam/trilium/wiki/Protected-notes) with per-note granularity
* [Relation maps](https://github.com/zadam/trilium/wiki/Relation-map) for visualizing notes and their relations * [Relation maps](https://github.com/zadam/trilium/wiki/Relation-map) and [link maps](https://github.com/zadam/trilium/wiki/Link-map) for visualizing notes and their relations
* [Scripting](https://github.com/zadam/trilium/wiki/Scripts) - see [Advanced showcases](https://github.com/zadam/trilium/wiki/Advanced-showcases) * [Scripting](https://github.com/zadam/trilium/wiki/Scripts) - see [Advanced showcases](https://github.com/zadam/trilium/wiki/Advanced-showcases)
* Scales well in both usability and performance upwards of 100 000 notes * Scales well in both usability and performance upwards of 100 000 notes
* Touch optimized [mobile frontend](https://github.com/zadam/trilium/wiki/Mobile-frontend) for smartphones and tablets * Touch optimized [mobile frontend](https://github.com/zadam/trilium/wiki/Mobile-frontend) for smartphones and tablets
@@ -24,7 +24,7 @@ Trilium Notes is a hierarchical note taking application with focus on building l
## Builds ## Builds
Trilium is provided as either desktop application (Linux, Windows, Mac) or web application hosted on your server (Linux). Trilium is provided as either desktop application (Linux and Windows) or web application hosted on your server (Linux). Mac OS desktop build is available, but it is [unsupported](https://github.com/zadam/trilium/wiki/FAQ#mac-os-support).
* If you want to use Trilium on the desktop, download binary release for your platform from [latest release](https://github.com/zadam/trilium/releases/latest), unzip the package and run ```trilium``` executable. * If you want to use Trilium on the desktop, download binary release for your platform from [latest release](https://github.com/zadam/trilium/releases/latest), unzip the package and run ```trilium``` executable.
* If you want to install Trilium on server, follow [this page](https://github.com/zadam/trilium/wiki/Server-installation). * If you want to install Trilium on server, follow [this page](https://github.com/zadam/trilium/wiki/Server-installation).

View File

@@ -7,6 +7,9 @@ rm -r node_modules/sqlite3/lib/binding/*
cp -r bin/deps/linux-x64/sqlite/* node_modules/sqlite3/lib/binding/ cp -r bin/deps/linux-x64/sqlite/* node_modules/sqlite3/lib/binding/
# rebuild binaries for image operations (pngquant ...)
npm rebuild
./node_modules/.bin/electron-packager . --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite ./node_modules/.bin/electron-packager . --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite
mv "./dist/Trilium Notes-linux-x64" $BUILD_DIR mv "./dist/Trilium Notes-linux-x64" $BUILD_DIR

View File

@@ -58,8 +58,8 @@ async function createMainWindow() {
mainWindowState.manage(win); mainWindowState.manage(win);
win.setMenu(null); win.setMenuBarVisibility(false);
win.loadURL('http://localhost:' + await port); win.loadURL('http://127.0.0.1:' + await port);
win.on('closed', onClosed); win.on('closed', onClosed);
win.webContents.on('new-window', (e, url) => { win.webContents.on('new-window', (e, url) => {
@@ -74,7 +74,7 @@ async function createMainWindow() {
const parsedUrl = url.parse(targetUrl); const parsedUrl = url.parse(targetUrl);
// we still need to allow internal redirects from setup and migration pages // we still need to allow internal redirects from setup and migration pages
if (parsedUrl.hostname !== 'localhost' || (parsedUrl.path && parsedUrl.path !== '/')) { if (!['localhost', '127.0.0.1'].includes(parsedUrl.hostname) || (parsedUrl.path && parsedUrl.path !== '/')) {
ev.preventDefault(); ev.preventDefault();
} }
}); });

File diff suppressed because one or more lines are too long

View File

@@ -3235,7 +3235,8 @@ var uniqueId = $.fn.extend( {
node.makeVisible({ scrollIntoView: false }); node.makeVisible({ scrollIntoView: false });
} catch (e) {} // #272 } catch (e) {} // #272
if (activate === false) { if (activate === false) {
return node.setFocus(); node.setFocus();
return _getResolvedPromise();
} }
return node.setActive(); return node.setActive();
} }

235
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{ {
"name": "trilium", "name": "trilium",
"version": "0.32.4", "version": "0.33.6",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@@ -589,32 +589,32 @@
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="
}, },
"app-builder-bin": { "app-builder-bin": {
"version": "2.6.6", "version": "2.6.16",
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-2.6.6.tgz", "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-2.6.16.tgz",
"integrity": "sha512-G0Ee6xkbxV+fvM/7xXWIgSDjWAD4E/d/aNbxerq/TVsCyBIau/0VPmrEqBMyZv0NbTwLDW5aF/yHG+0ZEY77kA==", "integrity": "sha512-TSq2/AwXbFI+jK4SPRRASZEpZ32HsrugxuCzHshnZ3Wj5LDVIAMU3EGXfaciXWx7TV047G69RlA4/Y8OiHBn3w==",
"dev": true "dev": true
}, },
"app-builder-lib": { "app-builder-lib": {
"version": "20.43.0", "version": "20.44.2",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-20.43.0.tgz", "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-20.44.2.tgz",
"integrity": "sha512-8OhRPGbTFsgBn07mcG1x0FApqsLLQkNMrdl2sBPo/haI/E1QqhN4DU5x7nKbbFwnsG2XvqvBBZwnMV3FXgDi9Q==", "integrity": "sha512-84AEt+k/edrwHwFtaXx8SGAC9ZdMJabx5xf2VGM8L8sFYbBPJppl4G6TieHqpPhDURbPXqL710HKEA/lyiEIRQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"7zip-bin": "~4.1.0", "7zip-bin": "~4.1.0",
"app-builder-bin": "2.6.6", "app-builder-bin": "2.6.16",
"async-exit-hook": "^2.0.1", "async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
"builder-util": "10.0.2", "builder-util": "10.1.0",
"builder-util-runtime": "8.2.4", "builder-util-runtime": "8.2.5",
"chromium-pickle-js": "^0.2.0", "chromium-pickle-js": "^0.2.0",
"debug": "^4.1.1", "debug": "^4.1.1",
"ejs": "^2.6.1", "ejs": "^2.6.2",
"electron-osx-sign": "0.4.11", "electron-osx-sign": "0.4.11",
"electron-publish": "20.43.0", "electron-publish": "20.44.2",
"fs-extra-p": "^8.0.2", "fs-extra-p": "^8.0.2",
"hosted-git-info": "^2.7.1", "hosted-git-info": "^2.7.1",
"is-ci": "^2.0.0", "is-ci": "^2.0.0",
"isbinaryfile": "^4.0.0", "isbinaryfile": "^4.0.1",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
"lazy-val": "^1.0.4", "lazy-val": "^1.0.4",
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
@@ -623,7 +623,7 @@
"read-config-file": "3.2.2", "read-config-file": "3.2.2",
"sanitize-filename": "^1.6.1", "sanitize-filename": "^1.6.1",
"semver": "^6.1.1", "semver": "^6.1.1",
"temp-file": "^3.3.2" "temp-file": "^3.3.3"
}, },
"dependencies": { "dependencies": {
"ci-info": { "ci-info": {
@@ -678,9 +678,9 @@
} }
}, },
"resolve": { "resolve": {
"version": "1.11.1", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz",
"integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==",
"dev": true, "dev": true,
"requires": { "requires": {
"path-parse": "^1.0.6" "path-parse": "^1.0.6"
@@ -713,7 +713,7 @@
"dependencies": { "dependencies": {
"file-type": { "file-type": {
"version": "3.9.0", "version": "3.9.0",
"resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
} }
} }
@@ -1022,7 +1022,7 @@
}, },
"uuid": { "uuid": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
"integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho="
} }
} }
@@ -1056,7 +1056,7 @@
"dependencies": { "dependencies": {
"semver": { "semver": {
"version": "4.3.6", "version": "4.3.6",
"resolved": "http://registry.npmjs.org/semver/-/semver-4.3.6.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
"integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto="
} }
} }
@@ -1076,7 +1076,7 @@
}, },
"bl": { "bl": {
"version": "1.2.2", "version": "1.2.2",
"resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"requires": { "requires": {
"readable-stream": "^2.3.5", "readable-stream": "^2.3.5",
@@ -1375,27 +1375,27 @@
"dependencies": { "dependencies": {
"file-type": { "file-type": {
"version": "3.9.0", "version": "3.9.0",
"resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
}, },
"uuid": { "uuid": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
"integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho="
} }
} }
}, },
"builder-util": { "builder-util": {
"version": "10.0.2", "version": "10.1.0",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-10.0.2.tgz", "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-10.1.0.tgz",
"integrity": "sha512-Dt11O/MTdCsaCjAdnkVVcDSSkQEkvPWAs18sNQBc6l6wt5RvzcI4nfgpLxwbUi/DkCpHCltUgIj94TLQXQv1bw==", "integrity": "sha512-M+XnPGbVKSssgxgejtcrCPr7BcJfTyZZYf9yJ8r3o3kDJfBcF0ShaxyuOk956PnAUuanRGtfhZb4cD6dx+x1jA==",
"dev": true, "dev": true,
"requires": { "requires": {
"7zip-bin": "~4.1.0", "7zip-bin": "~4.1.0",
"@types/debug": "^4.1.4", "@types/debug": "^4.1.4",
"app-builder-bin": "2.6.6", "app-builder-bin": "2.6.16",
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
"builder-util-runtime": "^8.2.4", "builder-util-runtime": "^8.2.5",
"chalk": "^2.4.2", "chalk": "^2.4.2",
"debug": "^4.1.1", "debug": "^4.1.1",
"fs-extra-p": "^8.0.2", "fs-extra-p": "^8.0.2",
@@ -1403,7 +1403,7 @@
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
"source-map-support": "^0.5.12", "source-map-support": "^0.5.12",
"stat-mode": "^0.3.0", "stat-mode": "^0.3.0",
"temp-file": "^3.3.2" "temp-file": "^3.3.3"
}, },
"dependencies": { "dependencies": {
"ansi-styles": { "ansi-styles": {
@@ -1475,9 +1475,9 @@
} }
}, },
"builder-util-runtime": { "builder-util-runtime": {
"version": "8.2.4", "version": "8.2.5",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.2.4.tgz", "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.2.5.tgz",
"integrity": "sha512-iwRnmFnGs63+p6uJem2N/d9Q0SKj5c0TP8PTesKnWsWvo1saKKM/0yiT137w+3uz+r/Cmf8VH/8nt75uW8jeUw==", "integrity": "sha512-YILT+YUlxrE3yNB6mDC1tF+Q24mr1LSYdjP5U861jbBeDZfvy1/VPDzW3boMVrDtzYnDnvkYrzLJnoh6TXA75w==",
"dev": true, "dev": true,
"requires": { "requires": {
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
@@ -1625,7 +1625,7 @@
}, },
"chalk": { "chalk": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": { "requires": {
"ansi-styles": "^2.2.1", "ansi-styles": "^2.2.1",
@@ -1895,7 +1895,7 @@
}, },
"commander": { "commander": {
"version": "2.8.1", "version": "2.8.1",
"resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
"requires": { "requires": {
"graceful-readlink": ">= 1.0.0" "graceful-readlink": ">= 1.0.0"
@@ -2621,14 +2621,14 @@
} }
}, },
"dmg-builder": { "dmg-builder": {
"version": "6.6.4", "version": "6.7.0",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-6.6.4.tgz", "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-6.7.0.tgz",
"integrity": "sha512-neJXwnFaJ4wisP++Yyi9H0kEUsvxyY7TBBEK2fu8V8i1VoMQKljY/6Dgf2HktLVHzXSWP71TQwKKWSIWI/3aeQ==", "integrity": "sha512-YluV5KM2sbqKZ0SeL+K7Q0E37EAeV64UmdUtnV4CZqe7TYaVa5j2K5zpfoMZyg+sekxAN8utfmrvaLf9V6SNeA==",
"dev": true, "dev": true,
"requires": { "requires": {
"app-builder-lib": "~20.43.0", "app-builder-lib": "~20.44.2",
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
"builder-util": "~10.0.2", "builder-util": "~10.1.0",
"fs-extra-p": "^8.0.2", "fs-extra-p": "^8.0.2",
"iconv-lite": "^0.4.24", "iconv-lite": "^0.4.24",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
@@ -2815,14 +2815,14 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
}, },
"ejs": { "ejs": {
"version": "2.6.1", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.2.tgz",
"integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==" "integrity": "sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q=="
}, },
"electron": { "electron": {
"version": "6.0.0-beta.7", "version": "6.0.0-beta.13",
"resolved": "https://registry.npmjs.org/electron/-/electron-6.0.0-beta.7.tgz", "resolved": "https://registry.npmjs.org/electron/-/electron-6.0.0-beta.13.tgz",
"integrity": "sha512-GYG/uAG8VcZnbhd7zYo5lfkqsQElwdjBxoI+eg9xmKiU13QqtVhoyofZPb1OadVqfkyOTjGm4GlW75KlTNgdyw==", "integrity": "sha512-q1pX18l4N6PH0iCoHXPmgqDNEX2slvMYZcxWXHlUFQodtvXq7bnsFfr6uvifMT5oSdfsCZtXXPK3/iK6PdODNQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/node": "^10.12.18", "@types/node": "^10.12.18",
@@ -2831,17 +2831,17 @@
} }
}, },
"electron-builder": { "electron-builder": {
"version": "20.43.0", "version": "20.44.2",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-20.43.0.tgz", "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-20.44.2.tgz",
"integrity": "sha512-8trMnW3K2BWtPGQJqCWZ5QMwZajMucmzlTCHrzhufQWuQbaPhanmho6tWFm2ftyuYku3T4TB4kD7UCX/YQDGyg==", "integrity": "sha512-4n7s8gfmMuNr3IbVLXo/XzcdaWcOFxu+VeC0FUjl90lU8H8pvuQ/LZS+yD7k0zVw98p4+GvMg0nIwjdF+BbwTA==",
"dev": true, "dev": true,
"requires": { "requires": {
"app-builder-lib": "20.43.0", "app-builder-lib": "20.44.2",
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
"builder-util": "10.0.2", "builder-util": "10.1.0",
"builder-util-runtime": "8.2.4", "builder-util-runtime": "8.2.5",
"chalk": "^2.4.2", "chalk": "^2.4.2",
"dmg-builder": "6.6.4", "dmg-builder": "6.7.0",
"fs-extra-p": "^8.0.2", "fs-extra-p": "^8.0.2",
"is-ci": "^2.0.0", "is-ci": "^2.0.0",
"lazy-val": "^1.0.4", "lazy-val": "^1.0.4",
@@ -3055,15 +3055,15 @@
"dev": true "dev": true
}, },
"package-json": { "package-json": {
"version": "6.3.0", "version": "6.4.0",
"resolved": "https://registry.npmjs.org/package-json/-/package-json-6.3.0.tgz", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.4.0.tgz",
"integrity": "sha512-XO7WS3EEXd48vmW633Y97Mh9xuENFiOevI9G+ExfTG/k6xuY9cBd3fxkAoDMSEsNZXasaVJIJ1rD/n7GMf18bA==", "integrity": "sha512-bd1T8OBG7hcvMd9c/udgv6u5v9wISP3Oyl9Cm7Weop8EFwrtcQDnS2sb6zhwqus2WslSr5wSTIPiTTpxxmPm7Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"got": "^9.6.0", "got": "^9.6.0",
"registry-auth-token": "^3.4.0", "registry-auth-token": "^3.4.0",
"registry-url": "^5.0.0", "registry-url": "^5.0.0",
"semver": "^5.6.0" "semver": "^6.1.1"
} }
}, },
"prepend-http": { "prepend-http": {
@@ -3091,12 +3091,6 @@
"rc": "^1.2.8" "rc": "^1.2.8"
} }
}, },
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true
},
"string-width": { "string-width": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
@@ -3583,18 +3577,18 @@
} }
}, },
"electron-publish": { "electron-publish": {
"version": "20.43.0", "version": "20.44.2",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-20.43.0.tgz", "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-20.44.2.tgz",
"integrity": "sha512-+oaTdbMmh1xceKPZWORYyGkNmxIhu7rkE1qEEn0NeG3KHEAePHg9FZGemR4aV3tQmtOwti2Vj+x8snAUxsnHHQ==", "integrity": "sha512-GRzmMFdVG63zKip2wY+fa5Vmw6bHz1OaGemz3Ebfzm60CfaPOw8o3iWa49JuxYYPobi2BbZrbr76a0flECmAzg==",
"dev": true, "dev": true,
"requires": { "requires": {
"bluebird-lst": "^1.0.9", "bluebird-lst": "^1.0.9",
"builder-util": "~10.0.2", "builder-util": "~10.1.0",
"builder-util-runtime": "^8.2.4", "builder-util-runtime": "^8.2.5",
"chalk": "^2.4.2", "chalk": "^2.4.2",
"fs-extra-p": "^8.0.2", "fs-extra-p": "^8.0.2",
"lazy-val": "^1.0.4", "lazy-val": "^1.0.4",
"mime": "^2.4.3" "mime": "^2.4.4"
}, },
"dependencies": { "dependencies": {
"ansi-styles": { "ansi-styles": {
@@ -5013,9 +5007,9 @@
} }
}, },
"file-type": { "file-type": {
"version": "11.1.0", "version": "12.0.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz", "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.0.0.tgz",
"integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==" "integrity": "sha512-VV3aQAyoV/fHl0I9uU3/DGjItgh5nylAoJPHOXkZXHW4nFFrxJnHR2xdVqsqyw/9fqYy80m+tS+Rf77w0FTKqg=="
}, },
"filename-regex": { "filename-regex": {
"version": "2.0.1", "version": "2.0.1",
@@ -5832,7 +5826,7 @@
}, },
"got": { "got": {
"version": "5.7.1", "version": "5.7.1",
"resolved": "http://registry.npmjs.org/got/-/got-5.7.1.tgz", "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz",
"integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=",
"requires": { "requires": {
"create-error-class": "^3.0.1", "create-error-class": "^3.0.1",
@@ -6619,7 +6613,7 @@
}, },
"into-stream": { "into-stream": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "http://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
"integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
"requires": { "requires": {
"from2": "^2.1.1", "from2": "^2.1.1",
@@ -8053,7 +8047,7 @@
}, },
"get-stream": { "get-stream": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
}, },
"got": { "got": {
@@ -8089,7 +8083,7 @@
}, },
"p-cancelable": { "p-cancelable": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "http://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
"integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ=="
}, },
"p-event": { "p-event": {
@@ -8236,7 +8230,7 @@
"dependencies": { "dependencies": {
"file-type": { "file-type": {
"version": "3.9.0", "version": "3.9.0",
"resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
} }
} }
@@ -8261,7 +8255,7 @@
"dependencies": { "dependencies": {
"get-stream": { "get-stream": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
}, },
"pify": { "pify": {
@@ -8318,7 +8312,7 @@
}, },
"get-stream": { "get-stream": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
"integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
"requires": { "requires": {
"object-assign": "^4.0.1", "object-assign": "^4.0.1",
@@ -8348,7 +8342,7 @@
"dependencies": { "dependencies": {
"get-stream": { "get-stream": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
} }
} }
@@ -8378,7 +8372,7 @@
}, },
"pify": { "pify": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
}, },
"prepend-http": { "prepend-http": {
@@ -8484,7 +8478,7 @@
}, },
"readable-stream": { "readable-stream": {
"version": "1.1.14", "version": "1.1.14",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": { "requires": {
"core-util-is": "~1.0.0", "core-util-is": "~1.0.0",
@@ -8554,9 +8548,9 @@
} }
}, },
"ms": { "ms": {
"version": "2.1.1", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
} }
} }
}, },
@@ -8576,9 +8570,9 @@
"integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
}, },
"node-abi": { "node-abi": {
"version": "2.8.0", "version": "2.9.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.8.0.tgz", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.9.0.tgz",
"integrity": "sha512-1/aa2clS0pue0HjckL62CsbhWWU35HARvBDXcJtYKbYR7LnIutmpxmXbuDMV9kEviD2lP/wACOgWmmwljghHyQ==", "integrity": "sha512-jmEOvv0eanWjhX8dX1pmjb7oJl1U1oR4FOh0b2GnvALwSYoOdU7sj+kLDSAyjo4pfC9aj/IxkloxdLJQhSSQBA==",
"requires": { "requires": {
"semver": "^5.4.1" "semver": "^5.4.1"
}, },
@@ -8910,7 +8904,7 @@
}, },
"onetime": { "onetime": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k="
}, },
"open": { "open": {
@@ -9097,7 +9091,7 @@
}, },
"p-is-promise": { "p-is-promise": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
"integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=" "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4="
}, },
"p-limit": { "p-limit": {
@@ -9600,7 +9594,7 @@
}, },
"get-stream": { "get-stream": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
} }
} }
@@ -9884,7 +9878,7 @@
"dependencies": { "dependencies": {
"file-type": { "file-type": {
"version": "3.9.0", "version": "3.9.0",
"resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
} }
} }
@@ -9909,7 +9903,7 @@
"dependencies": { "dependencies": {
"get-stream": { "get-stream": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
}, },
"pify": { "pify": {
@@ -9947,7 +9941,7 @@
}, },
"get-stream": { "get-stream": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
} }
} }
@@ -9999,7 +9993,7 @@
}, },
"get-stream": { "get-stream": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
"integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
"requires": { "requires": {
"object-assign": "^4.0.1", "object-assign": "^4.0.1",
@@ -10029,7 +10023,7 @@
"dependencies": { "dependencies": {
"get-stream": { "get-stream": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
} }
} }
@@ -10286,7 +10280,7 @@
}, },
"query-string": { "query-string": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "http://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
"integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
"requires": { "requires": {
"decode-uri-component": "^0.2.0", "decode-uri-component": "^0.2.0",
@@ -11469,9 +11463,9 @@
} }
}, },
"sqlite3": { "sqlite3": {
"version": "4.0.8", "version": "4.0.9",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.0.8.tgz", "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.0.9.tgz",
"integrity": "sha512-kgwHu4j10KhpCHtx//dejd/tVQot7jc3sw+Sn0vMuKOw0X00Ckyg9VceKgzPyGmmz+zEoYue9tOLriWTvYy0ww==", "integrity": "sha512-IkvzjmsWQl9BuBiM4xKpl5X8WCR4w0AeJHRdobCdXZ8dT/lNc1XS6WqvY35N6+YzIIgzSBeY5prdFObID9F9tA==",
"requires": { "requires": {
"nan": "^2.12.1", "nan": "^2.12.1",
"node-pre-gyp": "^0.11.0", "node-pre-gyp": "^0.11.0",
@@ -11627,7 +11621,7 @@
}, },
"strip-dirs": { "strip-dirs": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "http://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz", "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz",
"integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=", "integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=",
"requires": { "requires": {
"chalk": "^1.0.0", "chalk": "^1.0.0",
@@ -11917,37 +11911,14 @@
"integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=" "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0="
}, },
"temp-file": { "temp-file": {
"version": "3.3.2", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.3.2.tgz", "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.3.3.tgz",
"integrity": "sha512-FGKccAW0Mux9hC/2bdUIe4bJRv4OyVo4RpVcuplFird1V/YoplIFbnPZjfzbJSf/qNvRZIRB9/4n/RkI0GziuQ==", "integrity": "sha512-ErWJ0vfZwkozaH7dn/5QtYdrGwy6fWID0GG3PEzNb9Vmt6urL4mQ3lKz7NWVi1/kmZsWQzgjTL7/P4mwGx5jqg==",
"dev": true, "dev": true,
"requires": { "requires": {
"async-exit-hook": "^2.0.1", "async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.6", "bluebird-lst": "^1.0.9",
"fs-extra-p": "^7.0.0" "fs-extra-p": "^8.0.2"
},
"dependencies": {
"fs-extra": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"fs-extra-p": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-7.0.1.tgz",
"integrity": "sha512-yhd2OV0HnHt2oitlp+X9hl2ReX4X/7kQeL7/72qzPHTZj5eUPGzAKOvEglU02Fa1OeG2rSy/aKB4WGVaLiF8tw==",
"dev": true,
"requires": {
"bluebird-lst": "^1.0.7",
"fs-extra": "^7.0.1"
}
}
} }
}, },
"tempfile": { "tempfile": {
@@ -12007,7 +11978,7 @@
}, },
"readable-stream": { "readable-stream": {
"version": "1.0.34", "version": "1.0.34",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"requires": { "requires": {
"core-util-is": "~1.0.0", "core-util-is": "~1.0.0",
@@ -12877,9 +12848,9 @@
} }
}, },
"ws": { "ws": {
"version": "7.0.0", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.0.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-7.0.1.tgz",
"integrity": "sha512-cknCal4k0EAOrh1SHHPPWWh4qm93g1IuGGGwBjWkXmCG7LsDtL8w9w+YVfaF+KSVwiHQKDIMsSLBVftKf9d1pg==", "integrity": "sha512-ILHfMbuqLJvnSgYXLgy4kMntroJpe8hT41dOVWM8bxRuw6TK4mgMp9VJUNsZTEc5Bh+Mbs0DJT4M0N+wBG9l9A==",
"requires": { "requires": {
"async-limiter": "^1.0.0" "async-limiter": "^1.0.0"
} }

View File

@@ -2,7 +2,7 @@
"name": "trilium", "name": "trilium",
"productName": "Trilium Notes", "productName": "Trilium Notes",
"description": "Trilium Notes", "description": "Trilium Notes",
"version": "0.33.0-beta", "version": "0.33.7",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"main": "electron.js", "main": "electron.js",
"bin": { "bin": {
@@ -30,14 +30,14 @@
"csurf": "1.10.0", "csurf": "1.10.0",
"dayjs": "1.8.14", "dayjs": "1.8.14",
"debug": "4.1.1", "debug": "4.1.1",
"ejs": "2.6.1", "ejs": "2.6.2",
"electron-debug": "3.0.0", "electron-debug": "3.0.0",
"electron-dl": "1.14.0", "electron-dl": "1.14.0",
"electron-find": "1.0.6", "electron-find": "1.0.6",
"electron-window-state": "5.0.3", "electron-window-state": "5.0.3",
"express": "4.17.1", "express": "4.17.1",
"express-session": "1.16.2", "express-session": "1.16.2",
"file-type": "11.1.0", "file-type": "12.0.0",
"fs-extra": "8.0.1", "fs-extra": "8.0.1",
"get-port": "5.0.0", "get-port": "5.0.0",
"helmet": "3.18.0", "helmet": "3.18.0",
@@ -53,7 +53,7 @@
"mime-types": "2.1.24", "mime-types": "2.1.24",
"moment": "2.24.0", "moment": "2.24.0",
"multer": "1.4.1", "multer": "1.4.1",
"node-abi": "2.8.0", "node-abi": "2.9.0",
"open": "6.3.0", "open": "6.3.0",
"pngjs": "3.4.0", "pngjs": "3.4.0",
"rand-token": "0.4.0", "rand-token": "0.4.0",
@@ -66,17 +66,17 @@
"session-file-store": "1.3.0", "session-file-store": "1.3.0",
"simple-node-logger": "18.12.22", "simple-node-logger": "18.12.22",
"sqlite": "3.0.3", "sqlite": "3.0.3",
"sqlite3": "4.0.8", "sqlite3": "4.0.9",
"tar-stream": "2.1.0", "tar-stream": "2.1.0",
"turndown": "5.0.3", "turndown": "5.0.3",
"unescape": "1.0.1", "unescape": "1.0.1",
"ws": "7.0.0", "ws": "7.0.1",
"xml2js": "0.4.19" "xml2js": "0.4.19"
}, },
"devDependencies": { "devDependencies": {
"devtron": "1.4.0", "devtron": "1.4.0",
"electron": "6.0.0-beta.7", "electron": "6.0.0-beta.13",
"electron-builder": "20.43.0", "electron-builder": "20.44.2",
"electron-compile": "6.4.4", "electron-compile": "6.4.4",
"electron-installer-debian": "2.0.0", "electron-installer-debian": "2.0.0",
"electron-packager": "13.1.1", "electron-packager": "13.1.1",

View File

@@ -90,10 +90,10 @@ app.use((req, res, next) => {
app.use((err, req, res, next) => { app.use((err, req, res, next) => {
if (err && err.message && err.message.includes("Invalid package")) { if (err && err.message && err.message.includes("Invalid package")) {
// electron 6 outputs a lot of such errors which do not seem important // electron 6 outputs a lot of such errors which do not seem important
return;
} }
else {
log.info(err); log.info(err);
}
res.status(err.status || 500); res.status(err.status || 500);
res.send({ res.send({

View File

@@ -142,10 +142,10 @@ $noteTabContainer.on("click", ".export-note-button", function () {
return; return;
} }
exportDialog.showDialog('single'); exportDialog.showDialog(treeService.getActiveNode(), 'single');
}); });
$noteTabContainer.on("click", ".import-files-button", importDialog.showDialog); $noteTabContainer.on("click", ".import-files-button", () => importDialog.showDialog(treeService.getActiveNode()));
$('[data-toggle="tooltip"]').tooltip({ $('[data-toggle="tooltip"]').tooltip({
html: true html: true

View File

@@ -12,21 +12,19 @@ const $noteTitle = $('#branch-prefix-note-title');
let branchId; let branchId;
async function showDialog() { async function showDialog(node) {
utils.closeActiveDialog(); utils.closeActiveDialog();
glob.activeDialog = $dialog; glob.activeDialog = $dialog;
$dialog.modal(); $dialog.modal();
const currentNode = treeService.getActiveNode(); branchId = node.data.branchId;
branchId = currentNode.data.branchId;
const branch = await treeCache.getBranch(branchId); const branch = await treeCache.getBranch(branchId);
$treePrefixInput.val(branch.prefix); $treePrefixInput.val(branch.prefix);
const noteTitle = await treeUtils.getNoteTitle(currentNode.data.noteId); const noteTitle = await treeUtils.getNoteTitle(node.data.noteId);
$noteTitle.text(" - " + noteTitle); $noteTitle.text(" - " + noteTitle);
} }

View File

@@ -7,8 +7,11 @@ const $custom = $("#confirm-dialog-custom");
const DELETE_NOTE_BUTTON_ID = "confirm-dialog-delete-note"; const DELETE_NOTE_BUTTON_ID = "confirm-dialog-delete-note";
let resolve; let resolve;
let $originallyFocused; // element focused before the dialog was opened so we can return to it afterwards
function confirm(message) { function confirm(message) {
$originallyFocused = $(':focus');
$custom.hide(); $custom.hide();
glob.activeDialog = $dialog; glob.activeDialog = $dialog;
@@ -55,6 +58,11 @@ $dialog.on("hidden.bs.modal", () => {
if (resolve) { if (resolve) {
resolve(false); resolve(false);
} }
if ($originallyFocused) {
$originallyFocused.focus();
$originallyFocused = null;
}
}); });
function doResolve(ret) { function doResolve(ret) {

View File

@@ -1,4 +1,3 @@
import treeService from '../services/tree.js';
import treeUtils from "../services/tree_utils.js"; import treeUtils from "../services/tree_utils.js";
import utils from "../services/utils.js"; import utils from "../services/utils.js";
import messagingService from "../services/messaging.js"; import messagingService from "../services/messaging.js";
@@ -6,7 +5,7 @@ import infoService from "../services/info.js";
const $dialog = $("#export-dialog"); const $dialog = $("#export-dialog");
const $form = $("#export-form"); const $form = $("#export-form");
const $noteTitle = $dialog.find(".note-title"); const $noteTitle = $dialog.find(".export-note-title");
const $subtreeFormats = $("#export-subtree-formats"); const $subtreeFormats = $("#export-subtree-formats");
const $singleFormats = $("#export-single-formats"); const $singleFormats = $("#export-single-formats");
const $subtreeType = $("#export-type-subtree"); const $subtreeType = $("#export-type-subtree");
@@ -17,8 +16,9 @@ const $exportButton = $("#export-button");
const $opmlVersions = $("#opml-versions"); const $opmlVersions = $("#opml-versions");
let exportId = ''; let exportId = '';
let branchId = null;
async function showDialog(defaultType) { async function showDialog(node, defaultType) {
utils.closeActiveDialog(); utils.closeActiveDialog();
// each opening of the dialog resets the exportId so we don't associate it with previous exports anymore // each opening of the dialog resets the exportId so we don't associate it with previous exports anymore
@@ -46,8 +46,9 @@ async function showDialog(defaultType) {
$dialog.modal(); $dialog.modal();
const currentNode = treeService.getActiveNode(); branchId = node.data.branchId;
const noteTitle = await treeUtils.getNoteTitle(currentNode.data.noteId);
const noteTitle = await treeUtils.getNoteTitle(node.data.noteId);
$noteTitle.html(noteTitle); $noteTitle.html(noteTitle);
} }
@@ -70,9 +71,7 @@ $form.submit(() => {
const exportVersion = exportFormat === 'opml' ? $dialog.find("input[name='opml-version']:checked").val() : "1.0"; const exportVersion = exportFormat === 'opml' ? $dialog.find("input[name='opml-version']:checked").val() : "1.0";
const currentNode = treeService.getActiveNode(); exportBranch(branchId, exportType, exportFormat, exportVersion);
exportBranch(currentNode.data.branchId, exportType, exportFormat, exportVersion);
return false; return false;
}); });

View File

@@ -19,8 +19,9 @@ const $codeImportedAsCodeCheckbox = $("#code-imported-as-code-checkbox");
const $explodeArchivesCheckbox = $("#explode-archives-checkbox"); const $explodeArchivesCheckbox = $("#explode-archives-checkbox");
let importId; let importId;
let importIntoNoteId = null;
async function showDialog() { async function showDialog(node) {
utils.closeActiveDialog(); utils.closeActiveDialog();
// each opening of the dialog resets the importId so we don't associate it with previous imports anymore // each opening of the dialog resets the importId so we don't associate it with previous imports anymore
@@ -37,19 +38,18 @@ async function showDialog() {
glob.activeDialog = $dialog; glob.activeDialog = $dialog;
const currentNode = treeService.getActiveNode(); importIntoNoteId = node.data.noteId;
$noteTitle.text(await treeUtils.getNoteTitle(currentNode.data.noteId));
$noteTitle.text(await treeUtils.getNoteTitle(importIntoNoteId));
$dialog.modal(); $dialog.modal();
} }
$form.submit(() => { $form.submit(() => {
const currentNode = treeService.getActiveNode();
// disabling so that import is not triggered again. // disabling so that import is not triggered again.
$importButton.attr("disabled", "disabled"); $importButton.attr("disabled", "disabled");
importIntoNote(currentNode.data.noteId); importIntoNote(importIntoNoteId);
return false; return false;
}); });

View File

@@ -5,8 +5,11 @@ const $infoContent = $("#info-dialog-content");
const $okButton = $("#info-dialog-ok-button"); const $okButton = $("#info-dialog-ok-button");
let resolve; let resolve;
let $originallyFocused; // element focused before the dialog was opened so we can return to it afterwards
function info(message) { function info(message) {
$originallyFocused = $(':focus');
utils.closeActiveDialog(); utils.closeActiveDialog();
glob.activeDialog = $dialog; glob.activeDialog = $dialog;
@@ -24,6 +27,11 @@ $dialog.on("hidden.bs.modal", () => {
if (resolve) { if (resolve) {
resolve(); resolve();
} }
if ($originallyFocused) {
$originallyFocused.focus();
$originallyFocused = null;
}
}); });
$okButton.click(() => $dialog.modal("hide")); $okButton.click(() => $dialog.modal("hide"));

View File

@@ -3,8 +3,10 @@ import utils from './utils.js';
import server from './server.js'; import server from './server.js';
import infoService from "./info.js"; import infoService from "./info.js";
import treeCache from "./tree_cache.js"; import treeCache from "./tree_cache.js";
import treeUtils from "./tree_utils.js";
import hoistedNoteService from "./hoisted_note.js"; import hoistedNoteService from "./hoisted_note.js";
import noteDetailService from "./note_detail.js"; import noteDetailService from "./note_detail.js";
import confirmDialog from "../dialogs/confirm.js";
async function moveBeforeNode(nodesToMove, beforeNode) { async function moveBeforeNode(nodesToMove, beforeNode) {
nodesToMove = await filterRootNote(nodesToMove); nodesToMove = await filterRootNote(nodesToMove);
@@ -81,7 +83,7 @@ async function moveToNode(nodesToMove, toNode) {
async function deleteNodes(nodes) { async function deleteNodes(nodes) {
nodes = await filterRootNote(nodes); nodes = await filterRootNote(nodes);
if (nodes.length === 0 || !confirm('Are you sure you want to delete select note(s) and all the sub-notes?')) { if (nodes.length === 0 || !await confirmDialog.confirm('Are you sure you want to delete select note(s) and all the sub-notes?')) {
return false; return false;
} }
@@ -101,13 +103,14 @@ async function deleteNodes(nodes) {
next = nodes[0].getPrevSibling(); next = nodes[0].getPrevSibling();
} }
if (!next && !hoistedNoteService.isTopLevelNode(nodes[0])) { if (!next && !await hoistedNoteService.isTopLevelNode(nodes[0])) {
next = nodes[0].getParent(); next = nodes[0].getParent();
} }
let activeNotePath = null;
if (next) { if (next) {
// activate next element after this one is deleted so we don't lose focus activeNotePath = await treeUtils.getNotePath(next);
next.setActive();
} }
await treeService.loadTreeCache(); await treeService.loadTreeCache();
@@ -119,7 +122,15 @@ async function deleteNodes(nodes) {
} }
for (const parentNoteId of parentNoteIds) { for (const parentNoteId of parentNoteIds) {
treeService.reloadNote(parentNoteId); await treeService.reloadNote(parentNoteId);
}
// activate after all the reloading
if (activeNotePath) {
treeService.focusTree();
const node = await treeService.activateNote(activeNotePath);
node.setFocus(true);
} }
infoService.showMessage("Note(s) has been deleted."); infoService.showMessage("Note(s) has been deleted.");

View File

@@ -67,12 +67,9 @@ function connectWebSocket() {
// use wss for secure messaging // use wss for secure messaging
const ws = new WebSocket(protocol + "://" + location.host); const ws = new WebSocket(protocol + "://" + location.host);
ws.onopen = event => console.debug(utils.now(), "Connected to server with WebSocket"); ws.onopen = () => console.debug(utils.now(), "Connected to server with WebSocket");
ws.onmessage = handleMessage; ws.onmessage = handleMessage;
ws.onclose = function(){ // we're not handling ws.onclose here because reconnection is done in sendPing()
// Try to reconnect in 5 seconds
setTimeout(() => connectWebSocket(), 5000);
};
return ws; return ws;
} }
@@ -88,10 +85,17 @@ setTimeout(() => {
console.log("Lost connection to server"); console.log("Lost connection to server");
} }
ws.send(JSON.stringify({ if (ws.readyState === ws.OPEN) {
type: 'ping', ws.send(JSON.stringify({
lastSyncId: lastSyncId type: 'ping',
})); lastSyncId: lastSyncId
}));
}
else if (ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) {
console.log("WS closed or closing, trying to reconnect");
ws = connectWebSocket();
}
}, 1000); }, 1000);
}, 0); }, 0);

View File

@@ -401,11 +401,14 @@ tabRow.addListener('activeTabChange', async ({ detail }) => {
tabRow.addListener('tabRemove', async ({ detail }) => { tabRow.addListener('tabRemove', async ({ detail }) => {
const tabId = detail.tabEl.getAttribute('data-tab-id'); const tabId = detail.tabEl.getAttribute('data-tab-id');
const tabContentToDelete = tabContexts.find(nc => nc.tabId === tabId); const tabContextToDelete = tabContexts.find(nc => nc.tabId === tabId);
if (tabContentToDelete) { if (tabContextToDelete) {
await tabContentToDelete.saveNoteIfChanged(); // sometimes there are orphan autocompletes after closing the tab
tabContentToDelete.$tabContent.remove(); tabContextToDelete.closeAutocomplete();
await tabContextToDelete.saveNoteIfChanged();
tabContextToDelete.$tabContent.remove();
} }
tabContexts = tabContexts.filter(nc => nc.tabId !== tabId); tabContexts = tabContexts.filter(nc => nc.tabId !== tabId);

View File

@@ -14,6 +14,7 @@ class NoteDetailCode {
this.ctx = ctx; this.ctx = ctx;
this.codeEditor = null; this.codeEditor = null;
this.$component = ctx.$tabContent.find('.note-detail-code'); this.$component = ctx.$tabContent.find('.note-detail-code');
this.$editorEl = this.$component.find('.note-detail-code-editor');
this.$executeScriptButton = ctx.$tabContent.find(".execute-script-button"); this.$executeScriptButton = ctx.$tabContent.find(".execute-script-button");
utils.bindElShortcut(ctx.$tabContent, "ctrl+return", () => this.executeCurrentNote()); utils.bindElShortcut(ctx.$tabContent, "ctrl+return", () => this.executeCurrentNote());
@@ -34,7 +35,7 @@ class NoteDetailCode {
CodeMirror.modeURL = 'libraries/codemirror/mode/%N/%N.js'; CodeMirror.modeURL = 'libraries/codemirror/mode/%N/%N.js';
this.codeEditor = CodeMirror(this.$component[0], { this.codeEditor = CodeMirror(this.$editorEl[0], {
value: "", value: "",
viewportMargin: Infinity, viewportMargin: Infinity,
indentUnit: 4, indentUnit: 4,

View File

@@ -1,5 +1,4 @@
import utils from "./utils.js"; import utils from "./utils.js";
import noteDetailService from "./note_detail.js";
import infoService from "./info.js"; import infoService from "./info.js";
import server from "./server.js"; import server from "./server.js";

View File

@@ -8,6 +8,7 @@ class NoteDetailText {
constructor(ctx) { constructor(ctx) {
this.ctx = ctx; this.ctx = ctx;
this.$component = ctx.$tabContent.find('.note-detail-text'); this.$component = ctx.$tabContent.find('.note-detail-text');
this.$editorEl = this.$component.find('.note-detail-text-editor');
this.textEditor = null; this.textEditor = null;
this.$component.on("dblclick", "img", e => { this.$component.on("dblclick", "img", e => {
@@ -39,7 +40,7 @@ class NoteDetailText {
// textEditor might have been initialized during previous await so checking again // textEditor might have been initialized during previous await so checking again
// looks like double initialization can freeze CKEditor pretty badly // looks like double initialization can freeze CKEditor pretty badly
if (!this.textEditor) { if (!this.textEditor) {
this.textEditor = await BalloonEditor.create(this.$component[0], { this.textEditor = await BalloonEditor.create(this.$editorEl[0], {
placeholder: "Type the content of your note here ..." placeholder: "Type the content of your note here ..."
}); });
@@ -73,7 +74,7 @@ class NoteDetailText {
} }
focus() { focus() {
this.$component.focus(); this.$editorEl.focus();
} }
getEditor() { getEditor() {

View File

@@ -43,6 +43,7 @@ async function setupProtectedSession(password) {
} }
protectedSessionHolder.setProtectedSessionId(response.protectedSessionId); protectedSessionHolder.setProtectedSessionId(response.protectedSessionId);
protectedSessionHolder.touchProtectedSession();
await treeService.reload(); await treeService.reload();

View File

@@ -37,6 +37,8 @@ function isProtectedSessionAvailable() {
function touchProtectedSession() { function touchProtectedSession() {
if (isProtectedSessionAvailable()) { if (isProtectedSessionAvailable()) {
lastProtectedSessionOperationDate = new Date();
setProtectedSessionId(utils.getCookie(PROTECTED_SESSION_ID_KEY)); setProtectedSessionId(utils.getCookie(PROTECTED_SESSION_ID_KEY));
} }
} }

View File

@@ -67,17 +67,27 @@ class TabContext {
this.components = {}; this.components = {};
this.$noteTitle.on('input', () => { this.$noteTitle.on('input', () => {
if (!this.note) {
return;
}
this.noteChanged(); this.noteChanged();
const title = this.$noteTitle.val(); this.note.title = this.$noteTitle.val();
this.tabRow.updateTab(this.$tab[0], {title}); this.tabRow.updateTab(this.$tab[0], {title: this.note.title});
treeService.setNoteTitle(this.noteId, title); treeService.setNoteTitle(this.noteId, this.note.title);
this.setTitleBar();
}); });
if (utils.isDesktop()) { if (utils.isDesktop()) {
// keyboard plugin is not loaded in mobile // keyboard plugin is not loaded in mobile
this.$noteTitle.bind('keydown', 'return', () => this.getComponent().focus()); this.$noteTitle.bind('keydown', 'return', () => {
this.getComponent().focus();
return false; // to not propagate the enter into the editor (causes issues with codemirror)
});
} }
this.$protectButton = this.$tabContent.find(".protect-button"); this.$protectButton = this.$tabContent.find(".protect-button");
@@ -86,7 +96,7 @@ class TabContext {
this.$unprotectButton = this.$tabContent.find(".unprotect-button"); this.$unprotectButton = this.$tabContent.find(".unprotect-button");
this.$unprotectButton.click(protectedSessionService.unprotectNoteAndSendToServer); this.$unprotectButton.click(protectedSessionService.unprotectNoteAndSendToServer);
console.log(`Created note tab ${this.tabId}`); console.debug(`Created note tab ${this.tabId}`);
} }
setNote(note, notePath) { setNote(note, notePath) {
@@ -103,6 +113,8 @@ class TabContext {
this.setTitleBar(); this.setTitleBar();
this.closeAutocomplete(); // esp. on windows autocomplete is not getting closed automatically
setTimeout(async () => { setTimeout(async () => {
// we include the note into recent list only if the user stayed on the note at least 5 seconds // we include the note into recent list only if the user stayed on the note at least 5 seconds
if (notePath && notePath === this.notePath) { if (notePath && notePath === this.notePath) {
@@ -119,7 +131,7 @@ class TabContext {
this.showPaths(); this.showPaths();
console.log(`Switched tab ${this.tabId} to ${this.noteId}`); console.debug(`Switched tab ${this.tabId} to ${this.noteId}`);
} }
show() { show() {
@@ -328,6 +340,12 @@ class TabContext {
} }
} }
} }
closeAutocomplete() {
if (utils.isDesktop()) {
this.$tabContent.find('.aa-input').autocomplete('close');
}
}
} }
export default TabContext; export default TabContext;

View File

@@ -196,6 +196,8 @@ async function resolveNotePath(notePath) {
async function getRunPath(notePath) { async function getRunPath(notePath) {
utils.assertArguments(notePath); utils.assertArguments(notePath);
notePath = notePath.split("-")[0];
const path = notePath.split("/").reverse(); const path = notePath.split("/").reverse();
if (!path.includes("root")) { if (!path.includes("root")) {
@@ -303,6 +305,15 @@ function getSelectedNodes(stopOnParents = false) {
return getTree().getSelectedNodes(stopOnParents); return getTree().getSelectedNodes(stopOnParents);
} }
function getSelectedOrActiveNodes(node) {
let notes = getSelectedNodes(true);
if (notes.length === 0) {
notes.push(node);
}
return notes;
}
function clearSelectedNodes() { function clearSelectedNodes() {
for (const selectedNode of getSelectedNodes()) { for (const selectedNode of getSelectedNodes()) {
selectedNode.setSelected(false); selectedNode.setSelected(false);
@@ -453,12 +464,6 @@ function initFancyTree(tree) {
$tree.on('contextmenu', '.fancytree-node', function(e) { $tree.on('contextmenu', '.fancytree-node', function(e) {
const node = $.ui.fancytree.getNode(e); const node = $.ui.fancytree.getNode(e);
// right click resets selection to just this node
// this is important when e.g. you right click on a note while having different note active
// and then click on delete - obviously you want to delete only that one right-clicked
node.setSelected(true);
clearSelectedNodes();
contextMenuWidget.initContextMenu(e, new TreeContextMenu(node)); contextMenuWidget.initContextMenu(e, new TreeContextMenu(node));
return false; // blocks default browser right click menu return false; // blocks default browser right click menu
@@ -522,17 +527,20 @@ async function collapseTree(node = null) {
node.visit(node => node.setExpanded(false)); node.visit(node => node.setExpanded(false));
} }
function focusTree() {
$tree.find('.fancytree-container').focus();
}
async function scrollToActiveNote() { async function scrollToActiveNote() {
const activeContext = noteDetailService.getActiveTabContext(); const activeContext = noteDetailService.getActiveTabContext();
if (activeContext && activeContext.notePath) { if (activeContext && activeContext.notePath) {
focusTree();
const node = await expandToNote(activeContext.notePath); const node = await expandToNote(activeContext.notePath);
node.makeVisible({scrollIntoView: true}); node.makeVisible({scrollIntoView: true});
node.setFocus(true);
node.setFocus();
await activateNote(activeContext.notePath);
} }
} }
@@ -624,7 +632,8 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) {
extraClasses: await treeBuilder.getExtraClasses(noteEntity), extraClasses: await treeBuilder.getExtraClasses(noteEntity),
icon: await treeBuilder.getIcon(noteEntity), icon: await treeBuilder.getIcon(noteEntity),
folder: extraOptions.type === 'search', folder: extraOptions.type === 'search',
lazy: true lazy: true,
key: utils.randomString(12) // this should prevent some "duplicate key" errors
}; };
if (target === 'after') { if (target === 'after') {
@@ -632,10 +641,14 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) {
} }
else if (target === 'into') { else if (target === 'into') {
if (!node.getChildren() && node.isFolder()) { if (!node.getChildren() && node.isFolder()) {
// folder is not loaded - load will bring up the note since it was already put into cache
await node.load(true);
await node.setExpanded(); await node.setExpanded();
} }
else {
node.addChildren(newNode); node.addChildren(newNode);
}
await node.getLastChild().setActive(true); await node.getLastChild().setActive(true);
@@ -731,10 +744,12 @@ utils.bindShortcut('ctrl+o', async () => {
async function createNoteInto() { async function createNoteInto() {
const node = getActiveNode(); const node = getActiveNode();
await createNote(node, node.data.noteId, 'into', { if (node) {
isProtected: node.data.isProtected, await createNote(node, node.data.noteId, 'into', {
saveSelection: true isProtected: node.data.isProtected,
}); saveSelection: true
});
}
} }
async function checkFolderStatus(node) { async function checkFolderStatus(node) {
@@ -808,6 +823,7 @@ export default {
createNote, createNote,
createNoteInto, createNoteInto,
getSelectedNodes, getSelectedNodes,
getSelectedOrActiveNodes,
clearSelectedNodes, clearSelectedNodes,
sortAlphabetically, sortAlphabetically,
showTree, showTree,
@@ -821,5 +837,6 @@ export default {
expandToNote, expandToNote,
getNodeFromPath, getNodeFromPath,
resolveNotePath, resolveNotePath,
getSomeNotePath getSomeNotePath,
focusTree
}; };

View File

@@ -83,7 +83,8 @@ async function prepareNode(branch) {
icon: await getIcon(note), icon: await getIcon(note),
refKey: note.noteId, refKey: note.noteId,
expanded: branch.isExpanded || hoistedNoteId === note.noteId, expanded: branch.isExpanded || hoistedNoteId === note.noteId,
lazy: true lazy: true,
key: utils.randomString(12) // this should prevent some "duplicate key" errors
}; };
if (note.hasChildren() || note.type === 'search') { if (note.hasChildren() || note.type === 'search') {

View File

@@ -34,45 +34,52 @@ class TreeContextMenu {
const isNotRoot = note.noteId !== 'root'; const isNotRoot = note.noteId !== 'root';
const isHoisted = note.noteId === await hoistedNoteService.getHoistedNoteId(); const isHoisted = note.noteId === await hoistedNoteService.getHoistedNoteId();
// some actions don't support multi-note so they are disabled when notes are selected
// the only exception is when the only selected note is the one that was right-clicked, then
// it's clear what the user meant to do.
const selNodes = treeService.getSelectedNodes();
const noSelectedNotes = selNodes.length === 0
|| (selNodes.length === 1 && selNodes[0] === this.node);
const insertNoteAfterEnabled = isNotRoot && !isHoisted && parentNote.type !== 'search'; const insertNoteAfterEnabled = isNotRoot && !isHoisted && parentNote.type !== 'search';
const insertChildNoteEnabled = note.type !== 'search'; const insertChildNoteEnabled = note.type !== 'search';
return [ return [
{ title: "Open in new tab", cmd: "openInTab", uiIcon: "empty" }, { title: "Open in new tab", cmd: "openInTab", uiIcon: "empty", enabled: noSelectedNotes },
{ title: "Insert note after <kbd>Ctrl+O</kbd>", cmd: "insertNoteAfter", uiIcon: "plus", { title: "Insert note after <kbd>Ctrl+O</kbd>", cmd: "insertNoteAfter", uiIcon: "plus",
items: insertNoteAfterEnabled ? this.getNoteTypeItems("insertNoteAfter") : null, items: insertNoteAfterEnabled ? this.getNoteTypeItems("insertNoteAfter") : null,
enabled: insertNoteAfterEnabled }, enabled: insertNoteAfterEnabled && noSelectedNotes },
{ title: "Insert child note <kbd>Ctrl+P</kbd>", cmd: "insertChildNote", uiIcon: "plus", { title: "Insert child note <kbd>Ctrl+P</kbd>", cmd: "insertChildNote", uiIcon: "plus",
items: insertChildNoteEnabled ? this.getNoteTypeItems("insertChildNote") : null, items: insertChildNoteEnabled ? this.getNoteTypeItems("insertChildNote") : null,
enabled: insertChildNoteEnabled }, enabled: insertChildNoteEnabled && noSelectedNotes },
{ title: "Delete <kbd>Delete</kbd>", cmd: "delete", uiIcon: "trash", { title: "Delete <kbd>Delete</kbd>", cmd: "delete", uiIcon: "trash",
enabled: isNotRoot && !isHoisted && parentNote.type !== 'search' }, enabled: isNotRoot && !isHoisted && parentNote.type !== 'search' },
{ title: "----" }, { title: "----" },
isHoisted ? null : { title: "Hoist note <kbd>Ctrl-H</kbd>", cmd: "hoist", uiIcon: "empty" }, isHoisted ? null : { title: "Hoist note <kbd>Ctrl-H</kbd>", cmd: "hoist", uiIcon: "empty", enabled: noSelectedNotes },
!isHoisted || !isNotRoot ? null : { title: "Unhoist note <kbd>Ctrl-H</kbd>", cmd: "unhoist", uiIcon: "arrow-up" }, !isHoisted || !isNotRoot ? null : { title: "Unhoist note <kbd>Ctrl-H</kbd>", cmd: "unhoist", uiIcon: "arrow-up" },
{ title: "Edit branch prefix <kbd>F2</kbd>", cmd: "editBranchPrefix", uiIcon: "empty", { title: "Edit branch prefix <kbd>F2</kbd>", cmd: "editBranchPrefix", uiIcon: "empty",
enabled: isNotRoot && parentNote.type !== 'search'}, enabled: isNotRoot && parentNote.type !== 'search' && noSelectedNotes},
{ title: "----" }, { title: "----" },
{ title: "Protect subtree", cmd: "protectSubtree", uiIcon: "shield-check" }, { title: "Protect subtree", cmd: "protectSubtree", uiIcon: "shield-check", enabled: noSelectedNotes },
{ title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield-close" }, { title: "Unprotect subtree", cmd: "unprotectSubtree", uiIcon: "shield-close", enabled: noSelectedNotes },
{ title: "----" }, { title: "----" },
{ title: "Copy / clone <kbd>Ctrl+C</kbd>", cmd: "copy", uiIcon: "files", { title: "Copy / clone <kbd>Ctrl+C</kbd>", cmd: "copy", uiIcon: "files",
enabled: isNotRoot }, enabled: isNotRoot },
{ title: "Cut <kbd>Ctrl+X</kbd>", cmd: "cut", uiIcon: "scissors", { title: "Cut <kbd>Ctrl+X</kbd>", cmd: "cut", uiIcon: "scissors",
enabled: isNotRoot }, enabled: isNotRoot },
{ title: "Paste into <kbd>Ctrl+V</kbd>", cmd: "pasteInto", uiIcon: "clipboard", { title: "Paste into <kbd>Ctrl+V</kbd>", cmd: "pasteInto", uiIcon: "clipboard",
enabled: !clipboard.isEmpty() && note.type !== 'search' }, enabled: !clipboard.isEmpty() && note.type !== 'search' && noSelectedNotes },
{ title: "Paste after", cmd: "pasteAfter", uiIcon: "clipboard", { title: "Paste after", cmd: "pasteAfter", uiIcon: "clipboard",
enabled: !clipboard.isEmpty() && isNotRoot && parentNote.type !== 'search' }, enabled: !clipboard.isEmpty() && isNotRoot && parentNote.type !== 'search' && noSelectedNotes },
{ title: "----" }, { title: "----" },
{ title: "Export", cmd: "export", uiIcon: "empty", { title: "Export", cmd: "export", uiIcon: "empty",
enabled: note.type !== 'search' }, enabled: note.type !== 'search' && noSelectedNotes },
{ title: "Import into note", cmd: "importIntoNote", uiIcon: "empty", { title: "Import into note", cmd: "importIntoNote", uiIcon: "empty",
enabled: note.type !== 'search' }, enabled: note.type !== 'search' && noSelectedNotes },
{ title: "----" }, { title: "----" },
{ title: "Collapse subtree <kbd>Alt+-</kbd>", cmd: "collapseSubtree", uiIcon: "align-justify" }, { title: "Collapse subtree <kbd>Alt+-</kbd>", cmd: "collapseSubtree", uiIcon: "align-justify", enabled: noSelectedNotes },
{ title: "Force note sync", cmd: "forceNoteSync", uiIcon: "refresh" }, { title: "Force note sync", cmd: "forceNoteSync", uiIcon: "refresh", enabled: noSelectedNotes },
{ title: "Sort alphabetically <kbd>Alt+S</kbd>", cmd: "sortAlphabetically", uiIcon: "empty" } { title: "Sort alphabetically <kbd>Alt+S</kbd>", cmd: "sortAlphabetically", uiIcon: "empty", enabled: noSelectedNotes }
].filter(row => row !== null); ].filter(row => row !== null);
} }
@@ -110,10 +117,10 @@ class TreeContextMenu {
protectedSessionService.protectSubtree(this.node.data.noteId, false); protectedSessionService.protectSubtree(this.node.data.noteId, false);
} }
else if (cmd === "copy") { else if (cmd === "copy") {
clipboard.copy(treeService.getSelectedNodes()); clipboard.copy(treeService.getSelectedOrActiveNodes(this.node));
} }
else if (cmd === "cut") { else if (cmd === "cut") {
clipboard.cut(treeService.getSelectedNodes()); clipboard.cut(treeService.getSelectedOrActiveNodes(this.node));
} }
else if (cmd === "pasteAfter") { else if (cmd === "pasteAfter") {
clipboard.pasteAfter(this.node); clipboard.pasteAfter(this.node);
@@ -122,13 +129,13 @@ class TreeContextMenu {
clipboard.pasteInto(this.node); clipboard.pasteInto(this.node);
} }
else if (cmd === "delete") { else if (cmd === "delete") {
treeChangesService.deleteNodes(treeService.getSelectedNodes(true)); treeChangesService.deleteNodes(treeService.getSelectedOrActiveNodes(this.node));
} }
else if (cmd === "export") { else if (cmd === "export") {
exportDialog.showDialog("subtree"); exportDialog.showDialog(this.node,"subtree");
} }
else if (cmd === "importIntoNote") { else if (cmd === "importIntoNote") {
importDialog.showDialog(); importDialog.showDialog(this.node);
} }
else if (cmd === "collapseSubtree") { else if (cmd === "collapseSubtree") {
treeService.collapseTree(this.node); treeService.collapseTree(this.node);

View File

@@ -7,7 +7,7 @@ import clipboard from "./clipboard.js";
const keyBindings = { const keyBindings = {
"del": node => { "del": node => {
treeChangesService.deleteNodes(treeService.getSelectedNodes(true)); treeChangesService.deleteNodes(treeService.getSelectedOrActiveNodes(node));
}, },
"ctrl+up": node => { "ctrl+up": node => {
const beforeNode = node.getPrevSibling(); const beforeNode = node.getPrevSibling();
@@ -104,13 +104,13 @@ const keyBindings = {
return false; return false;
}, },
"ctrl+c": () => { "ctrl+c": node => {
clipboard.copy(treeService.getSelectedNodes()); clipboard.copy(treeService.getSelectedOrActiveNodes(node));
return false; return false;
}, },
"ctrl+x": () => { "ctrl+x": node => {
clipboard.cut(treeService.getSelectedNodes()); clipboard.cut(treeService.getSelectedOrActiveNodes(node));
return false; return false;
}, },

View File

@@ -19,7 +19,10 @@ function getNoteIdFromNotePath(notePath) {
const path = notePath.split("/"); const path = notePath.split("/");
return path[path.length - 1]; const lastSegment = path[path.length - 1];
// path could have also tabId suffix
return lastSegment.split("-")[0];
} }
async function getNotePath(node) { async function getNotePath(node) {
@@ -38,7 +41,9 @@ async function getNotePath(node) {
node = node.getParent(); node = node.getParent();
} }
path.push(node.data.noteId); // root or hoisted noteId if (node) { // null node can happen directly after unhoisting when tree is still hoisted but option has been changed already
path.push(node.data.noteId); // root or hoisted noteId
}
return path.reverse().join("/"); return path.reverse().join("/");
} }

View File

@@ -135,13 +135,16 @@ ul.fancytree-container {
.note-detail-text h6 { font-size: 1.1em; } .note-detail-text h6 { font-size: 1.1em; }
.note-detail-text { .note-detail-text {
overflow: auto;
font-family: var(--detail-text-font-family);
}
.note-detail-text-editor {
padding-top: 10px;
border: 0 !important; border: 0 !important;
box-shadow: none !important; box-shadow: none !important;
/* This is because with empty content height of editor is 0 and it's impossible to click into it */ /* This is because with empty content height of editor is 0 and it's impossible to click into it */
min-height: 200px; min-height: 200px;
padding-top: 10px;
overflow: auto;
font-family: var(--detail-text-font-family);
} }
.note-detail-text p:first-child, .note-detail-text::before { .note-detail-text p:first-child, .note-detail-text::before {
@@ -190,27 +193,32 @@ span.fancytree-node.fancytree-active-clone:not(.fancytree-active) .fancytree-tit
span.fancytree-active .fancytree-title { span.fancytree-active .fancytree-title {
font-weight: bold; font-weight: bold;
border-color: var(--main-background-color) !important; /* invisible border */ border-color: var(--main-border-color) !important;
border-radius: 5px;
}
span.fancytree-active:not(.fancytree-focused) .fancytree-title {
border-style: dashed !important;
} }
span.fancytree-focused .fancytree-title, span.fancytree-focused.fancytree-selected .fancytree-title { span.fancytree-focused .fancytree-title, span.fancytree-focused.fancytree-selected .fancytree-title {
color: var(--active-item-text-color) !important; color: var(--active-item-text-color) !important;
background-color: var(--active-item-background-color) !important; background-color: var(--active-item-background-color) !important;
border-color: var(--main-background-color) !important; /* invisible border */ border-color: var(--main-background-color) !important; /* invisible border */
border-radius: 3px; border-radius: 5px;
} }
span.fancytree-selected .fancytree-title { span.fancytree-selected .fancytree-title {
color: var(--hover-item-text-color) !important; color: var(--hover-item-text-color) !important;
background-color: var(--hover-item-background-color) !important; background-color: var(--hover-item-background-color) !important;
border-color: var(--main-background-color) !important; /* invisible border */ border-color: var(--main-background-color) !important; /* invisible border */
border-radius: 3px; border-radius: 5px;
font-style: italic; font-style: italic;
} }
span.fancytree-node:hover span.fancytree-title { span.fancytree-node:hover span.fancytree-title {
border-color: var(--main-border-color) !important; border-color: var(--main-border-color) !important;
border-radius: 3px; border-radius: 5px;
} }
.ui-autocomplete { .ui-autocomplete {
@@ -349,10 +357,13 @@ div.ui-tooltip {
} }
.note-detail-code { .note-detail-code {
min-height: 200px;
overflow: auto; overflow: auto;
} }
.note-detail-code-editor {
min-height: 200px;
}
.note-detail-render { .note-detail-render {
min-height: 200px; min-height: 200px;
} }

View File

@@ -1,9 +1,9 @@
"use strict"; "use strict";
const imageType = require('image-type');
const imageService = require('../../services/image'); const imageService = require('../../services/image');
const utils = require('../../services/utils'); const utils = require('../../services/utils');
const dateNoteService = require('../../services/date_notes'); const dateNoteService = require('../../services/date_notes');
const sql = require('../../services/sql');
const noteService = require('../../services/notes'); const noteService = require('../../services/notes');
const passwordEncryptionService = require('../../services/password_encryption'); const passwordEncryptionService = require('../../services/password_encryption');
const optionService = require('../../services/options'); const optionService = require('../../services/options');
@@ -36,9 +36,11 @@ async function uploadImage(req) {
return [400, "Unknown image type: " + file.mimetype]; return [400, "Unknown image type: " + file.mimetype];
} }
const originalName = "Sender image." + imageType(file.buffer).ext;
const parentNote = await dateNoteService.getDateNote(req.headers['x-local-date']); const parentNote = await dateNoteService.getDateNote(req.headers['x-local-date']);
const {noteId} = await imageService.saveImage(file.buffer, "Sender image", parentNote.noteId, true); const {noteId} = await imageService.saveImage(file.buffer, originalName, parentNote.noteId, true);
return { return {
noteId: noteId noteId: noteId

View File

@@ -1 +1 @@
module.exports = { buildDate:"2019-06-12T21:45:05+02:00", buildRevision: "c646019536dbc48f5f3ea1a35e4df844a4a2c8c3" }; module.exports = { buildDate:"2019-07-11T20:55:56+02:00", buildRevision: "a76dcb44ae1c1cef58b9a66041b183893745a944" };

View File

@@ -32,11 +32,11 @@ async function exportToTar(exportContext, branch, format, res) {
do { do {
index = existingFileNames[lcFileName]++; index = existingFileNames[lcFileName]++;
newName = lcFileName + "_" + index; newName = index + "_" + lcFileName;
} }
while (newName in existingFileNames); while (newName in existingFileNames);
return fileName + "_" + index; return index + "_" + fileName;
} }
else { else {
existingFileNames[lcFileName] = 1; existingFileNames[lcFileName] = 1;
@@ -46,24 +46,32 @@ async function exportToTar(exportContext, branch, format, res) {
} }
function getDataFileName(note, baseFileName, existingFileNames) { function getDataFileName(note, baseFileName, existingFileNames) {
let extension; const existingExtension = path.extname(baseFileName).toLowerCase();
let newExtension;
// following two are handled specifically since we always want to have these extensions no matter the automatic detection
// and/or existing detected extensions in the note name
if (note.type === 'text' && format === 'markdown') { if (note.type === 'text' && format === 'markdown') {
extension = 'md'; newExtension = 'md';
}
else if (note.type === 'text' && format === 'html') {
newExtension = 'html';
} }
else if (note.mime === 'application/x-javascript' || note.mime === 'text/javascript') { else if (note.mime === 'application/x-javascript' || note.mime === 'text/javascript') {
extension = 'js'; newExtension = 'js';
}
else if (existingExtension.length > 0) { // if the page already has an extension, then we'll just keep it
newExtension = null;
} }
else { else {
extension = mimeTypes.extension(note.mime) || "dat"; newExtension = mimeTypes.extension(note.mime) || "dat";
} }
let fileName = baseFileName; let fileName = baseFileName;
const existingExtension = path.extname(fileName).toLowerCase();
// if the note is already named with extension (e.g. "jquery.js"), then it's silly to append exact same extension again // if the note is already named with extension (e.g. "jquery.js"), then it's silly to append exact same extension again
if (existingExtension !== extension) { if (newExtension && existingExtension !== "." + newExtension.toLowerCase()) {
fileName += "." + extension; fileName += "." + newExtension;
} }
return getUniqueFilename(existingFileNames, fileName); return getUniqueFilename(existingFileNames, fileName);

View File

@@ -13,14 +13,20 @@ const imageType = require('image-type');
const sanitizeFilename = require('sanitize-filename'); const sanitizeFilename = require('sanitize-filename');
async function saveImage(buffer, originalName, parentNoteId, shrinkImageSwitch) { async function saveImage(buffer, originalName, parentNoteId, shrinkImageSwitch) {
const origImageFormat = imageType(buffer);
if (origImageFormat.ext === "webp") {
// JIMP does not support webp at the moment: https://github.com/oliver-moran/jimp/issues/144
shrinkImageSwitch = false;
}
const finalImageBuffer = shrinkImageSwitch ? await shrinkImage(buffer, originalName) : buffer; const finalImageBuffer = shrinkImageSwitch ? await shrinkImage(buffer, originalName) : buffer;
const imageFormat = imageType(finalImageBuffer); const imageFormat = imageType(finalImageBuffer);
const parentNote = await repository.getNote(parentNoteId); const parentNote = await repository.getNote(parentNoteId);
const fileNameWithoutExtension = originalName.replace(/\.[^/.]+$/, ""); const fileName = sanitizeFilename(originalName);
const fileName = sanitizeFilename(fileNameWithoutExtension + "." + imageFormat.ext);
const {note} = await noteService.createNote(parentNoteId, fileName, finalImageBuffer, { const {note} = await noteService.createNote(parentNoteId, fileName, finalImageBuffer, {
target: 'into', target: 'into',
@@ -48,7 +54,7 @@ async function shrinkImage(buffer, originalName) {
try { try {
finalImageBuffer = await optimize(resizedImage); finalImageBuffer = await optimize(resizedImage);
} catch (e) { } catch (e) {
log.error("Failed to optimize image '" + originalName + "\nStack: " + e.stack); log.error("Failed to optimize image '" + originalName + "'\nStack: " + e.stack);
finalImageBuffer = resizedImage; finalImageBuffer = resizedImage;
} }
@@ -93,7 +99,7 @@ async function optimize(buffer) {
quality: 50 quality: 50
}), }),
imageminPngQuant({ imageminPngQuant({
quality: "0-70" quality: [0, 0.7]
}), }),
imageminGifLossy({ imageminGifLossy({
lossy: 80, lossy: 80,

View File

@@ -74,11 +74,7 @@ function getMime(fileName) {
const ext = path.extname(fileName).toLowerCase(); const ext = path.extname(fileName).toLowerCase();
console.log("EXT", ext);
if (ext in EXTENSION_TO_MIME) { if (ext in EXTENSION_TO_MIME) {
console.log(EXTENSION_TO_MIME[ext]);
return EXTENSION_TO_MIME[ext]; return EXTENSION_TO_MIME[ext];
} }
@@ -110,7 +106,7 @@ async function importSingleFile(importContext, file, parentNote) {
} }
async function importImage(file, parentNote, importContext) { async function importImage(file, parentNote, importContext) {
const {note} = await imageService.saveImage(file.buffer, getFileNameWithoutExtension(file.originalname), parentNote.noteId, importContext.shrinkImages); const {note} = await imageService.saveImage(file.buffer, file.originalname, parentNote.noteId, importContext.shrinkImages);
importContext.increaseProgressCount(); importContext.increaseProgressCount();

View File

@@ -200,7 +200,7 @@
<!-- Include Fancytree skin and library --> <!-- Include Fancytree skin and library -->
<link href="libraries/fancytree/skin-win8/ui.fancytree.css" rel="stylesheet"> <link href="libraries/fancytree/skin-win8/ui.fancytree.css" rel="stylesheet">
<script src="libraries/fancytree/jquery.fancytree-all-deps.min.js"></script> <script src="libraries/fancytree/jquery.fancytree-all-deps.js"></script>
<script src="libraries/jquery.hotkeys.js"></script> <script src="libraries/jquery.hotkeys.js"></script>
<script src="libraries/jquery.fancytree.hotkeys.js"></script> <script src="libraries/jquery.fancytree.hotkeys.js"></script>

View File

@@ -2,7 +2,7 @@
<div class="modal-dialog modal-lg" role="document"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title">Export note</h5> <h5 class="modal-title">Export note "<span class="export-note-title"></span>"</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>

View File

@@ -36,9 +36,13 @@
</div> </div>
</div> </div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0;"> <div style="display: inline-block;">
<span aria-hidden="true">&times;</span> <button type="button" class="close" data-dismiss="modal" aria-label="Close" style="margin-left: 0;">
</button> <span aria-hidden="true">&times;</span>
</button>
<button class="help-button" type="button" data-help-page="Link-map" title="Help on Link map">?</button>
</div>
</div> </div>
<div class="modal-body" style="outline: none; overflow: hidden;"> <div class="modal-body" style="outline: none; overflow: hidden;">
<div id="link-map-container"></div> <div id="link-map-container"></div>

View File

@@ -72,7 +72,7 @@
document.cookie = name + "=" + (value || "") + expires + "; path=/"; document.cookie = name + "=" + (value || "") + expires + "; path=/";
} }
</script> </script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
</body> </body>
</html> </html>

View File

@@ -49,7 +49,9 @@
</div> </div>
<div class="note-detail-component-wrapper"> <div class="note-detail-component-wrapper">
<div class="note-detail-text note-detail-component" tabindex="10000"></div> <div class="note-detail-text note-detail-component" tabindex="10000">
<div class="note-detail-text-editor"></div>
</div>
<div class="note-detail-code note-detail-component"></div> <div class="note-detail-code note-detail-component"></div>

View File

@@ -11,9 +11,13 @@
<table class="note-detail-promoted-attributes"></table> <table class="note-detail-promoted-attributes"></table>
<div class="note-detail-component-wrapper"> <div class="note-detail-component-wrapper">
<div class="note-detail-text note-detail-component" tabindex="10000"></div> <div class="note-detail-text note-detail-component">
<div class="note-detail-text-editor" tabindex="10000"></div>
</div>
<div class="note-detail-code note-detail-component"></div> <div class="note-detail-code note-detail-component">
<div class="note-detail-code-editor"></div>
</div>
<% include details/empty.ejs %> <% include details/empty.ejs %>