mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	refactored TabContext => NoteContext
This commit is contained in:
		| @@ -1,3 +1,4 @@ | ||||
| - drop branches.utcDateCreated - not used for anything | ||||
| - drop options.utcDateCreated - not used for anything | ||||
| - isDeleted = 0 by default | ||||
| - rename openTabs to openNoteContexts | ||||
|   | ||||
							
								
								
									
										146
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										146
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "trilium", | ||||
|   "version": "0.47.3", | ||||
|   "version": "0.47.2", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
| @@ -711,9 +711,9 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/eslint": { | ||||
|       "version": "7.2.10", | ||||
|       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", | ||||
|       "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", | ||||
|       "version": "7.2.11", | ||||
|       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.11.tgz", | ||||
|       "integrity": "sha512-WYhv//5K8kQtsSc9F1Kn2vHzhYor6KpwPbARH7hwYe3C3ETD0EVx/3P5qQybUoaBEuUa9f/02JjBiXFWalYUmw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@types/estree": "*", | ||||
| @@ -2957,9 +2957,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "electron": { | ||||
|       "version": "13.0.0-beta.27", | ||||
|       "resolved": "https://registry.npmjs.org/electron/-/electron-13.0.0-beta.27.tgz", | ||||
|       "integrity": "sha512-Co5143QQBiUHLY8qKPbe4axGnFxFLIPbdBuKh0pMvhmsGsVbTK3mEihmhl/lBKQe36cu+gnODpvtZZ0uGsqlxA==", | ||||
|       "version": "13.0.0-beta.28", | ||||
|       "resolved": "https://registry.npmjs.org/electron/-/electron-13.0.0-beta.28.tgz", | ||||
|       "integrity": "sha512-fWNlnyRU4XtMpzsHTm20nnwMHSI580+LBOWj/75HDC012oU019O83QtzLuNsFSw0yoHFOQ8jg/dc4r6z/Xo/sA==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@electron/get": "^1.0.1", | ||||
| @@ -2968,9 +2968,9 @@ | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "@types/node": { | ||||
|           "version": "14.14.45", | ||||
|           "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.45.tgz", | ||||
|           "integrity": "sha512-DssMqTV9UnnoxDWu959sDLZzfvqCF0qDNRjaWeYSui9xkFe61kKo4l1TWNTQONpuXEm+gLMRvdlzvNHBamzmEw==", | ||||
|           "version": "14.17.0", | ||||
|           "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.0.tgz", | ||||
|           "integrity": "sha512-w8VZUN/f7SSbvVReb9SWp6cJFevxb4/nkG65yLAya//98WgocKm5PLDAtSs5CtJJJM+kHmJjO/6mmYW4MHShZA==", | ||||
|           "dev": true | ||||
|         } | ||||
|       } | ||||
| @@ -3822,9 +3822,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "electron-to-chromium": { | ||||
|       "version": "1.3.727", | ||||
|       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", | ||||
|       "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", | ||||
|       "version": "1.3.735", | ||||
|       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.735.tgz", | ||||
|       "integrity": "sha512-cp7MWzC3NseUJV2FJFgaiesdrS+A8ZUjX5fLAxdRlcaPDkaPGFplX930S5vf84yqDp4LjuLdKouWuVOTwUfqHQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "electron-window-state": { | ||||
| @@ -4108,20 +4108,25 @@ | ||||
|       "integrity": "sha512-o1JrraDGpMFaPtkuvtZ4cIBC/xuJn90KBGlxRrm3FxcfER1bPaBnBsTnypF65p+CMTXul2KrZodb3Vv3MScB4A==" | ||||
|     }, | ||||
|     "express-session": { | ||||
|       "version": "1.17.1", | ||||
|       "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz", | ||||
|       "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==", | ||||
|       "version": "1.17.2", | ||||
|       "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", | ||||
|       "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", | ||||
|       "requires": { | ||||
|         "cookie": "0.4.0", | ||||
|         "cookie": "0.4.1", | ||||
|         "cookie-signature": "1.0.6", | ||||
|         "debug": "2.6.9", | ||||
|         "depd": "~2.0.0", | ||||
|         "on-headers": "~1.0.2", | ||||
|         "parseurl": "~1.3.3", | ||||
|         "safe-buffer": "5.2.0", | ||||
|         "safe-buffer": "5.2.1", | ||||
|         "uid-safe": "~2.1.5" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "cookie": { | ||||
|           "version": "0.4.1", | ||||
|           "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", | ||||
|           "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" | ||||
|         }, | ||||
|         "debug": { | ||||
|           "version": "2.6.9", | ||||
|           "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", | ||||
| @@ -4136,9 +4141,9 @@ | ||||
|           "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" | ||||
|         }, | ||||
|         "safe-buffer": { | ||||
|           "version": "5.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", | ||||
|           "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" | ||||
|           "version": "5.2.1", | ||||
|           "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", | ||||
|           "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
| @@ -5894,9 +5899,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "nanoid": { | ||||
|       "version": "3.1.22", | ||||
|       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz", | ||||
|       "integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==" | ||||
|       "version": "3.1.23", | ||||
|       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", | ||||
|       "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==" | ||||
|     }, | ||||
|     "napi-build-utils": { | ||||
|       "version": "1.0.2", | ||||
| @@ -6052,9 +6057,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node-releases": { | ||||
|       "version": "1.1.71", | ||||
|       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", | ||||
|       "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", | ||||
|       "version": "1.1.72", | ||||
|       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", | ||||
|       "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "noop-logger": { | ||||
| @@ -6240,9 +6245,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "open": { | ||||
|       "version": "8.0.8", | ||||
|       "resolved": "https://registry.npmjs.org/open/-/open-8.0.8.tgz", | ||||
|       "integrity": "sha512-3XmKIU8+H/TVr8wB8C4vj0z748+yBydSvtpzZVS6vQ1dKNHB6AiPbhaoG+89zb80717GPk9y/7OvK0R6FXkNmQ==", | ||||
|       "version": "8.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/open/-/open-8.1.0.tgz", | ||||
|       "integrity": "sha512-jB5hAtsDOhCy/FNQJwQJOrGlxLUat482Yr14rbA5l2Zb1eOeoS+ccQPO036C1+z9VDBTmOZqzh1tBbI4myzIYw==", | ||||
|       "requires": { | ||||
|         "define-lazy-prop": "^2.0.0", | ||||
|         "is-docker": "^2.1.1", | ||||
| @@ -6572,13 +6577,13 @@ | ||||
|       } | ||||
|     }, | ||||
|     "postcss": { | ||||
|       "version": "8.2.8", | ||||
|       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.8.tgz", | ||||
|       "integrity": "sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw==", | ||||
|       "version": "8.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", | ||||
|       "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", | ||||
|       "requires": { | ||||
|         "colorette": "^1.2.2", | ||||
|         "nanoid": "^3.1.20", | ||||
|         "source-map": "^0.6.1" | ||||
|         "nanoid": "^3.1.23", | ||||
|         "source-map-js": "^0.6.2" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "colorette": { | ||||
| @@ -7110,9 +7115,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "sanitize-html": { | ||||
|       "version": "2.3.3", | ||||
|       "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.3.3.tgz", | ||||
|       "integrity": "sha512-DCFXPt7Di0c6JUnlT90eIgrjs6TsJl/8HYU3KLdmrVclFN4O0heTcVbJiMa23OKVr6aR051XYtsgd8EWwEBwUA==", | ||||
|       "version": "2.4.0", | ||||
|       "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.4.0.tgz", | ||||
|       "integrity": "sha512-Y1OgkUiTPMqwZNRLPERSEi39iOebn2XJLbeiGOBhaJD/yLqtLGu6GE5w7evx177LeGgSE+4p4e107LMiydOf6A==", | ||||
|       "requires": { | ||||
|         "deepmerge": "^4.2.2", | ||||
|         "escape-string-regexp": "^4.0.0", | ||||
| @@ -7124,36 +7129,36 @@ | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "dom-serializer": { | ||||
|           "version": "1.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz", | ||||
|           "integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==", | ||||
|           "version": "1.3.2", | ||||
|           "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", | ||||
|           "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", | ||||
|           "requires": { | ||||
|             "domelementtype": "^2.0.1", | ||||
|             "domhandler": "^4.0.0", | ||||
|             "domhandler": "^4.2.0", | ||||
|             "entities": "^2.0.0" | ||||
|           } | ||||
|         }, | ||||
|         "domelementtype": { | ||||
|           "version": "2.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", | ||||
|           "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==" | ||||
|           "version": "2.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", | ||||
|           "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" | ||||
|         }, | ||||
|         "domhandler": { | ||||
|           "version": "4.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", | ||||
|           "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", | ||||
|           "version": "4.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", | ||||
|           "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", | ||||
|           "requires": { | ||||
|             "domelementtype": "^2.1.0" | ||||
|             "domelementtype": "^2.2.0" | ||||
|           } | ||||
|         }, | ||||
|         "domutils": { | ||||
|           "version": "2.5.0", | ||||
|           "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.5.0.tgz", | ||||
|           "integrity": "sha512-Ho16rzNMOFk2fPwChGh3D2D9OEHAfG19HgmRR2l+WLSsIstNsAYBzePH412bL0y5T44ejABIVfTHQ8nqi/tBCg==", | ||||
|           "version": "2.6.0", | ||||
|           "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.6.0.tgz", | ||||
|           "integrity": "sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==", | ||||
|           "requires": { | ||||
|             "dom-serializer": "^1.0.1", | ||||
|             "domelementtype": "^2.0.1", | ||||
|             "domhandler": "^4.0.0" | ||||
|             "domelementtype": "^2.2.0", | ||||
|             "domhandler": "^4.2.0" | ||||
|           } | ||||
|         }, | ||||
|         "entities": { | ||||
| @@ -7167,13 +7172,13 @@ | ||||
|           "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" | ||||
|         }, | ||||
|         "htmlparser2": { | ||||
|           "version": "6.0.1", | ||||
|           "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.0.1.tgz", | ||||
|           "integrity": "sha512-GDKPd+vk4jvSuvCbyuzx/unmXkk090Azec7LovXP8as1Hn8q9p3hbjmDGbUqqhknw0ajwit6LiiWqfiTUPMK7w==", | ||||
|           "version": "6.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", | ||||
|           "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", | ||||
|           "requires": { | ||||
|             "domelementtype": "^2.0.1", | ||||
|             "domhandler": "^4.0.0", | ||||
|             "domutils": "^2.4.4", | ||||
|             "domutils": "^2.5.2", | ||||
|             "entities": "^2.0.0" | ||||
|           } | ||||
|         } | ||||
| @@ -7512,6 +7517,11 @@ | ||||
|       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", | ||||
|       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" | ||||
|     }, | ||||
|     "source-map-js": { | ||||
|       "version": "0.6.2", | ||||
|       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", | ||||
|       "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==" | ||||
|     }, | ||||
|     "source-map-support": { | ||||
|       "version": "0.5.19", | ||||
|       "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", | ||||
| @@ -7832,9 +7842,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "terser-webpack-plugin": { | ||||
|       "version": "5.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", | ||||
|       "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", | ||||
|       "version": "5.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.2.tgz", | ||||
|       "integrity": "sha512-6QhDaAiVHIQr5Ab3XUWZyDmrIPCHMiqJVljMF91YKyqwKkL5QHnYMkrMBy96v9Z7ev1hGhSEw1HQZc2p/s5Z8Q==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "jest-worker": "^26.6.2", | ||||
| @@ -7842,7 +7852,7 @@ | ||||
|         "schema-utils": "^3.0.0", | ||||
|         "serialize-javascript": "^5.0.1", | ||||
|         "source-map": "^0.6.1", | ||||
|         "terser": "^5.5.1" | ||||
|         "terser": "^5.7.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "p-limit": { | ||||
| @@ -8240,9 +8250,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "watchpack": { | ||||
|       "version": "2.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", | ||||
|       "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", | ||||
|       "version": "2.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", | ||||
|       "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "glob-to-regexp": "^0.4.1", | ||||
| @@ -8264,9 +8274,9 @@ | ||||
|       "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" | ||||
|     }, | ||||
|     "webpack": { | ||||
|       "version": "5.37.0", | ||||
|       "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.37.0.tgz", | ||||
|       "integrity": "sha512-yvdhgcI6QkQkDe1hINBAJ1UNevqNGTVaCkD2SSJcB8rcrNNl922RI8i2DXUAuNfANoxwsiXXEA4ZPZI9q2oGLA==", | ||||
|       "version": "5.37.1", | ||||
|       "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.37.1.tgz", | ||||
|       "integrity": "sha512-btZjGy/hSjCAAVHw+cKG+L0M+rstlyxbO2C+BOTaQ5/XAnxkDrP5sVbqWhXgo4pL3X2dcOib6rqCP20Zr9PLow==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@types/eslint-scope": "^3.7.0", | ||||
|   | ||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @@ -42,7 +42,7 @@ | ||||
|     "electron-window-state": "5.0.3", | ||||
|     "express": "4.17.1", | ||||
|     "express-partial-content": "^1.0.2", | ||||
|     "express-session": "1.17.1", | ||||
|     "express-session": "1.17.2", | ||||
|     "fs-extra": "10.0.0", | ||||
|     "helmet": "4.6.0", | ||||
|     "html": "1.0.0", | ||||
| @@ -59,13 +59,13 @@ | ||||
|     "mime-types": "2.1.30", | ||||
|     "multer": "1.4.2", | ||||
|     "node-abi": "2.26.0", | ||||
|     "open": "8.0.8", | ||||
|     "open": "8.1.0", | ||||
|     "portscanner": "2.2.0", | ||||
|     "rand-token": "1.0.1", | ||||
|     "request": "^2.88.2", | ||||
|     "rimraf": "3.0.2", | ||||
|     "sanitize-filename": "1.6.3", | ||||
|     "sanitize-html": "2.3.3", | ||||
|     "sanitize-html": "2.4.0", | ||||
|     "sax": "1.2.4", | ||||
|     "semver": "7.3.5", | ||||
|     "serve-favicon": "2.5.0", | ||||
| @@ -80,7 +80,7 @@ | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "cross-env": "7.0.3", | ||||
|     "electron": "13.0.0-beta.26", | ||||
|     "electron": "13.0.0-beta.28", | ||||
|     "electron-builder": "22.11.3", | ||||
|     "electron-packager": "15.2.0", | ||||
|     "electron-rebuild": "2.3.5", | ||||
| @@ -89,7 +89,7 @@ | ||||
|     "jsdoc": "3.6.7", | ||||
|     "lorem-ipsum": "2.0.3", | ||||
|     "rcedit": "3.0.0", | ||||
|     "webpack": "5.37.0", | ||||
|     "webpack": "5.37.1", | ||||
|     "webpack-cli": "4.7.0" | ||||
|   }, | ||||
|   "optionalDependencies": { | ||||
|   | ||||
| @@ -20,7 +20,7 @@ export async function showDialog() { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             appContext.tabManager.getActiveTabContext().setNote(suggestion.notePath); | ||||
|             appContext.tabManager.getActiveNoteContext().setNote(suggestion.notePath); | ||||
|         }); | ||||
|  | ||||
|     // if you open the Jump To dialog soon after using it previously it can often mean that you | ||||
|   | ||||
| @@ -12,9 +12,9 @@ const $okButton = $("#note-info-ok-button"); | ||||
| export async function showDialog() { | ||||
|     utils.openDialog($dialog); | ||||
|  | ||||
|     const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|     const {note} = activeTabContext; | ||||
|     const noteComplement = await activeTabContext.getNoteComplement(); | ||||
|     const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|     const {note} = activeNoteContext; | ||||
|     const noteComplement = await activeNoteContext.getNoteComplement(); | ||||
|  | ||||
|     $noteId.text(note.noteId); | ||||
|     $dateCreated.text(noteComplement.dateCreated); | ||||
|   | ||||
| @@ -7,7 +7,7 @@ const $noteSource = $("#note-source"); | ||||
| export async function showDialog() { | ||||
|     utils.openDialog($dialog); | ||||
|  | ||||
|     const noteCompletement = await appContext.tabManager.getActiveTabContext().getNoteComplement(); | ||||
|     const noteCompletement = await appContext.tabManager.getActiveNoteContext().getNoteComplement(); | ||||
|  | ||||
|     $noteSource.text(formatHtml(noteCompletement.content)); | ||||
| } | ||||
|   | ||||
| @@ -56,7 +56,7 @@ export async function showDialog(ancestorNoteId) { | ||||
|  | ||||
|                                 await froca.reloadNotes([change.noteId]); | ||||
|  | ||||
|                                 appContext.tabManager.getActiveTabContext().setNote(change.noteId); | ||||
|                                 appContext.tabManager.getActiveNoteContext().setNote(change.noteId); | ||||
|                             } | ||||
|                         }); | ||||
|  | ||||
|   | ||||
| @@ -145,23 +145,23 @@ $(window).on('beforeunload', () => { | ||||
| }); | ||||
|  | ||||
| function isNotePathInAddress() { | ||||
|     const [notePath, tabId] = treeService.getHashValueFromAddress(); | ||||
|     const [notePath, ntxId] = treeService.getHashValueFromAddress(); | ||||
|  | ||||
|     return notePath.startsWith("root") | ||||
|         // empty string is for empty/uninitialized tab | ||||
|         || (notePath === '' && !!tabId); | ||||
|         || (notePath === '' && !!ntxId); | ||||
| } | ||||
|  | ||||
| $(window).on('hashchange', function() { | ||||
|     if (isNotePathInAddress()) { | ||||
|         const [notePath, tabId] = treeService.getHashValueFromAddress(); | ||||
|         const [notePath, ntxId] = treeService.getHashValueFromAddress(); | ||||
|  | ||||
|         if (!notePath) { | ||||
|             console.log(`Invalid hash value "${document.location.hash}", ignoring.`); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         appContext.tabManager.switchToTab(tabId, notePath); | ||||
|         appContext.tabManager.switchToTab(ntxId, notePath); | ||||
|     } | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -74,8 +74,8 @@ export default class Entrypoints extends Component { | ||||
|  | ||||
|         await ws.waitForMaxKnownEntityChangeId(); | ||||
|  | ||||
|         const hoistedNoteId = appContext.tabManager.getActiveTabContext() | ||||
|             ? appContext.tabManager.getActiveTabContext().hoistedNoteId | ||||
|         const hoistedNoteId = appContext.tabManager.getActiveNoteContext() | ||||
|             ? appContext.tabManager.getActiveNoteContext().hoistedNoteId | ||||
|             : 'root'; | ||||
|  | ||||
|         await appContext.tabManager.openTabWithNote(note.noteId, true, null, hoistedNoteId); | ||||
| @@ -84,29 +84,29 @@ export default class Entrypoints extends Component { | ||||
|     } | ||||
|  | ||||
|     async toggleNoteHoistingCommand() { | ||||
|         const tabContext = appContext.tabManager.getActiveTabContext(); | ||||
|         const noteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|         if (tabContext.note.noteId === tabContext.hoistedNoteId) { | ||||
|             await tabContext.unhoist(); | ||||
|         if (noteContext.note.noteId === noteContext.hoistedNoteId) { | ||||
|             await noteContext.unhoist(); | ||||
|         } | ||||
|         else if (tabContext.note.type !== 'search') { | ||||
|             await tabContext.setHoistedNoteId(tabContext.note.noteId); | ||||
|         else if (noteContext.note.type !== 'search') { | ||||
|             await noteContext.setHoistedNoteId(noteContext.note.noteId); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async hoistNoteCommand({noteId}) { | ||||
|         const tabContext = appContext.tabManager.getActiveTabContext(); | ||||
|         const noteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|         if (tabContext.hoistedNoteId !== noteId) { | ||||
|             await tabContext.setHoistedNoteId(noteId); | ||||
|         if (noteContext.hoistedNoteId !== noteId) { | ||||
|             await noteContext.setHoistedNoteId(noteId); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async unhoistCommand() { | ||||
|         const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|         const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|         if (activeTabContext) { | ||||
|             activeTabContext.unhoist(); | ||||
|         if (activeNoteContext) { | ||||
|             activeNoteContext.unhoist(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -194,8 +194,8 @@ export default class Entrypoints extends Component { | ||||
|     } | ||||
|  | ||||
|     async runActiveNoteCommand() { | ||||
|         const tabContext = appContext.tabManager.getActiveTabContext(); | ||||
|         const note = tabContext.note; | ||||
|         const noteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|         const note = noteContext.note; | ||||
|  | ||||
|         // ctrl+enter is also used elsewhere so make sure we're running only when appropriate | ||||
|         if (!note || note.type !== 'code') { | ||||
| @@ -210,7 +210,7 @@ export default class Entrypoints extends Component { | ||||
|         } else if (note.mime === 'text/x-sqlite;schema=trilium') { | ||||
|             const result = await server.post("sql/execute/" + note.noteId); | ||||
|  | ||||
|             this.triggerEvent('sqlQueryResults', {tabId: tabContext.tabId, results: result.results}); | ||||
|             this.triggerEvent('sqlQueryResults', {ntxId: noteContext.ntxId, results: result.results}); | ||||
|         } | ||||
|  | ||||
|         toastService.showMessage("Note executed"); | ||||
|   | ||||
| @@ -56,7 +56,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | ||||
|      * @returns {Promise<void>} | ||||
|      */ | ||||
|     this.activateNote = async notePath => { | ||||
|         await appContext.tabManager.getActiveTabContext().setNote(notePath); | ||||
|         await appContext.tabManager.getActiveNoteContext().setNote(notePath); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
| @@ -68,7 +68,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | ||||
|     this.activateNewNote = async notePath => { | ||||
|         await ws.waitForMaxKnownEntityChangeId(); | ||||
|  | ||||
|         await appContext.tabManager.getActiveTabContext().setNote(notePath); | ||||
|         await appContext.tabManager.getActiveNoteContext().setNote(notePath); | ||||
|         appContext.triggerEvent('focusAndSelectTitle'); | ||||
|     }; | ||||
|  | ||||
| @@ -406,10 +406,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | ||||
|      * @return {Promise} | ||||
|      */ | ||||
|     this.setHoistedNoteId = (noteId) => { | ||||
|         const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|         const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|         if (activeTabContext) { | ||||
|             activeTabContext.setHoistedNoteId(noteId); | ||||
|         if (activeNoteContext) { | ||||
|             activeNoteContext.setHoistedNoteId(noteId); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|   | ||||
| @@ -2,16 +2,16 @@ import appContext from "./app_context.js"; | ||||
| import treeService from "./tree.js"; | ||||
|  | ||||
| function getHoistedNoteId() { | ||||
|     const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|     const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|     return activeTabContext ? activeTabContext.hoistedNoteId : 'root'; | ||||
|     return activeNoteContext ? activeNoteContext.hoistedNoteId : 'root'; | ||||
| } | ||||
|  | ||||
| async function unhoist() { | ||||
|     const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|     const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|     if (activeTabContext) { | ||||
|         await activeTabContext.unhoist(); | ||||
|     if (activeNoteContext) { | ||||
|         await activeNoteContext.unhoist(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -25,15 +25,15 @@ function isHoistedNode(node) { | ||||
|         || node.data.noteId === getHoistedNoteId(); | ||||
| } | ||||
|  | ||||
| async function checkNoteAccess(notePath, tabContext) { | ||||
|     const resolvedNotePath = await treeService.resolveNotePath(notePath, tabContext.hoistedNoteId); | ||||
| async function checkNoteAccess(notePath, noteContext) { | ||||
|     const resolvedNotePath = await treeService.resolveNotePath(notePath, noteContext.hoistedNoteId); | ||||
|  | ||||
|     if (!resolvedNotePath) { | ||||
|         console.log("Cannot activate " + notePath); | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     const hoistedNoteId = tabContext.hoistedNoteId; | ||||
|     const hoistedNoteId = noteContext.hoistedNoteId; | ||||
|  | ||||
|     if (!resolvedNotePath.includes(hoistedNoteId)) { | ||||
|         const confirmDialog = await import('../dialogs/confirm.js'); | ||||
|   | ||||
| @@ -64,7 +64,7 @@ ws.subscribeToMessages(async message => { | ||||
|         toastService.showPersistent(toast); | ||||
|  | ||||
|         if (message.result.importedNoteId) { | ||||
|             await appContext.tabManager.getActiveTabContext().setNote(message.result.importedNoteId); | ||||
|             await appContext.tabManager.getActiveNoteContext().setNote(message.result.importedNoteId); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
|   | ||||
| @@ -27,7 +27,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, {tabId: appContext.tabManager.activeTabId})); | ||||
| 			utils.bindElShortcut($el, shortcut, () => component.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeTabId})); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -35,7 +35,7 @@ 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, {tabId: appContext.tabManager.activeTabId})); | ||||
| 			utils.bindGlobalShortcut(shortcut, () => appContext.triggerCommand(action.actionName, {ntxId: appContext.tabManager.activeTabId})); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| @@ -43,7 +43,7 @@ getActionsForScope("window").then(actions => { | ||||
| server.get('keyboard-shortcuts-for-notes').then(shortcutForNotes => { | ||||
| 	for (const shortcut in shortcutForNotes) { | ||||
| 		utils.bindGlobalShortcut(shortcut, async () => { | ||||
| 			appContext.tabManager.getActiveTabContext().setNote(shortcutForNotes[shortcut]); | ||||
| 			appContext.tabManager.getActiveNoteContext().setNote(shortcutForNotes[shortcut]); | ||||
| 		}); | ||||
| 	} | ||||
| }); | ||||
|   | ||||
| @@ -81,15 +81,15 @@ function goToLink(e) { | ||||
|             appContext.tabManager.openTabWithNoteWithHoisting(notePath); | ||||
|         } | ||||
|         else if (e.which === 1) { | ||||
|             const tabId = $(e.target).closest("[data-tab-id]").attr("data-tab-id"); | ||||
|             const ntxId = $(e.target).closest("[data-tab-id]").attr("data-tab-id"); | ||||
|  | ||||
|             const tabContext = tabId | ||||
|                 ? appContext.tabManager.getTabContextById(tabId) | ||||
|                 : appContext.tabManager.getActiveTabContext(); | ||||
|             const noteContext = ntxId | ||||
|                 ? appContext.tabManager.getNoteContextById(ntxId) | ||||
|                 : appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|             tabContext.setNote(notePath).then(() => { | ||||
|                 if (tabContext !== appContext.tabManager.getActiveTabContext()) { | ||||
|                     appContext.tabManager.activateTab(tabContext.tabId); | ||||
|             noteContext.setNote(notePath).then(() => { | ||||
|                 if (noteContext !== appContext.tabManager.getActiveNoteContext()) { | ||||
|                     appContext.tabManager.activateTab(noteContext.ntxId); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|   | ||||
| @@ -27,14 +27,14 @@ export default class MainTreeExecutors extends Component { | ||||
|     } | ||||
|  | ||||
|     async createNoteIntoCommand() { | ||||
|         const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|         const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|         if (!activeTabContext) { | ||||
|         if (!activeNoteContext) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         await noteCreateService.createNote(activeTabContext.notePath, { | ||||
|             isProtected: activeTabContext.note.isProtected, | ||||
|         await noteCreateService.createNote(activeNoteContext.notePath, { | ||||
|             isProtected: activeNoteContext.note.isProtected, | ||||
|             saveSelection: false | ||||
|         }); | ||||
|     } | ||||
|   | ||||
| @@ -48,14 +48,14 @@ async function createNote(parentNotePath, options = {}) { | ||||
|     await ws.waitForMaxKnownEntityChangeId(); | ||||
|  | ||||
|     if (options.activate) { | ||||
|         const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|         await activeTabContext.setNote(`${parentNotePath}/${note.noteId}`); | ||||
|         const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|         await activeNoteContext.setNote(`${parentNotePath}/${note.noteId}`); | ||||
|  | ||||
|         if (options.focus === 'title') { | ||||
|             appContext.triggerEvent('focusAndSelectTitle'); | ||||
|         } | ||||
|         else if (options.focus === 'content') { | ||||
|             appContext.triggerEvent('focusOnDetail', {tabId: activeTabContext.tabId}); | ||||
|             appContext.triggerEvent('focusOnDetail', {ntxId: activeNoteContext.ntxId}); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -90,8 +90,8 @@ async function duplicateSubtree(noteId, parentNotePath) { | ||||
|  | ||||
|     await ws.waitForMaxKnownEntityChangeId(); | ||||
|  | ||||
|     const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|     activeTabContext.setNote(`${parentNotePath}/${note.noteId}`); | ||||
|     const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|     activeNoteContext.setNote(`${parentNotePath}/${note.noteId}`); | ||||
|  | ||||
|     const origNote = await froca.getNote(noteId); | ||||
|     toastService.showMessage(`Note "${origNote.title}" has been duplicated`); | ||||
|   | ||||
| @@ -64,17 +64,17 @@ export default class RootCommandExecutor extends Component { | ||||
|     async showSQLConsoleCommand() { | ||||
|         const sqlConsoleNote = await dateNoteService.createSqlConsole(); | ||||
|  | ||||
|         const tabContext = await appContext.tabManager.openTabWithNote(sqlConsoleNote.noteId, true); | ||||
|         const noteContext = await appContext.tabManager.openTabWithNote(sqlConsoleNote.noteId, true); | ||||
|  | ||||
|         appContext.triggerEvent('focusOnDetail', {tabId: tabContext.tabId}); | ||||
|         appContext.triggerEvent('focusOnDetail', {ntxId: noteContext.ntxId}); | ||||
|     } | ||||
|  | ||||
|     async searchNotesCommand({searchString, ancestorNoteId}) { | ||||
|         const searchNote = await dateNoteService.createSearchNote({searchString, ancestorNoteId}); | ||||
|  | ||||
|         const tabContext = await appContext.tabManager.openTabWithNote(searchNote.noteId, true); | ||||
|         const noteContext = await appContext.tabManager.openTabWithNote(searchNote.noteId, true); | ||||
|  | ||||
|         appContext.triggerCommand('focusOnSearchDefinition', {tabId: tabContext.tabId}); | ||||
|         appContext.triggerCommand('focusOnSearchDefinition', {ntxId: noteContext.ntxId}); | ||||
|     } | ||||
|  | ||||
|     async searchInSubtreeCommand({notePath}) { | ||||
|   | ||||
| @@ -4,14 +4,14 @@ const REQUEST_LOGGING_ENABLED = false; | ||||
|  | ||||
| async function getHeaders(headers) { | ||||
|     const appContext = (await import('./app_context.js')).default; | ||||
|     const activeTabContext = appContext.tabManager ? appContext.tabManager.getActiveTabContext() : null; | ||||
|     const activeNoteContext = appContext.tabManager ? appContext.tabManager.getActiveNoteContext() : null; | ||||
|  | ||||
|     // headers need to be lowercase because node.js automatically converts them to lower case | ||||
|     // also avoiding using underscores instead of dashes since nginx filters them out by default | ||||
|     const allHeaders = { | ||||
|         'trilium-source-id': glob.sourceId, | ||||
|         'trilium-local-now-datetime': utils.localNowDateTime(), | ||||
|         'trilium-hoisted-note-id': activeTabContext ? activeTabContext.hoistedNoteId : null, | ||||
|         'trilium-hoisted-note-id': activeNoteContext ? activeNoteContext.hoistedNoteId : null, | ||||
|         'x-csrf-token': glob.csrfToken | ||||
|     }; | ||||
|  | ||||
|   | ||||
| @@ -7,21 +7,21 @@ import Component from "../widgets/component.js"; | ||||
| import froca from "./froca.js"; | ||||
| import hoistedNoteService from "./hoisted_note.js"; | ||||
|  | ||||
| class TabContext extends Component { | ||||
| class NoteContext extends Component { | ||||
|     /** | ||||
|      * @param {string|null} tabId | ||||
|      * @param {string|null} ntxId | ||||
|      */ | ||||
|     constructor(tabId = null, hoistedNoteId = 'root', parentTabId = null) { | ||||
|     constructor(ntxId = null, hoistedNoteId = 'root', mainNtxId = null) { | ||||
|         super(); | ||||
|  | ||||
|         this.tabId = tabId || utils.randomString(4); | ||||
|         this.ntxId = ntxId || utils.randomString(4); | ||||
|         this.hoistedNoteId = hoistedNoteId; | ||||
|         this.parentTabId = parentTabId; | ||||
|         this.mainNtxId = mainNtxId; | ||||
|     } | ||||
|  | ||||
|     setEmpty() { | ||||
|         this.triggerEvent('tabNoteSwitched', { | ||||
|             tabContext: this, | ||||
|             noteContext: this, | ||||
|             notePath: this.notePath | ||||
|         }); | ||||
|     } | ||||
| @@ -33,7 +33,7 @@ class TabContext extends Component { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         await this.triggerEvent('beforeNoteSwitch', {tabContext: this}); | ||||
|         await this.triggerEvent('beforeNoteSwitch', {noteContext: this}); | ||||
|  | ||||
|         utils.closeActiveDialog(); | ||||
|  | ||||
| @@ -49,7 +49,7 @@ class TabContext extends Component { | ||||
|  | ||||
|         if (triggerSwitchEvent) { | ||||
|             await this.triggerEvent('tabNoteSwitched', { | ||||
|                 tabContext: this, | ||||
|                 noteContext: this, | ||||
|                 notePath: this.notePath | ||||
|             }); | ||||
|         } | ||||
| @@ -60,13 +60,13 @@ class TabContext extends Component { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     getAllSubTabContexts() { | ||||
|         return appContext.tabManager.tabContexts.filter(tc => tc.tabId === this.tabId || tc.parentTabId === this.tabId); | ||||
|     getAllSubNoteContexts() { | ||||
|         return appContext.tabManager.noteContexts.filter(nc => nc.ntxId === this.ntxId || nc.mainNtxId === this.ntxId); | ||||
|     } | ||||
|  | ||||
|     getMainTabContext() { | ||||
|         if (this.parentTabId) { | ||||
|             return appContext.tabManager.getTabContextById(this.parentTabId); | ||||
|     getMainNoteContext() { | ||||
|         if (this.mainNtxId) { | ||||
|             return appContext.tabManager.getNoteContextById(this.mainNtxId); | ||||
|         } | ||||
|         else { | ||||
|             return this; | ||||
| @@ -138,7 +138,7 @@ class TabContext extends Component { | ||||
|     } | ||||
|  | ||||
|     isActive() { | ||||
|         return appContext.tabManager.activeTabId === this.tabId; | ||||
|         return appContext.tabManager.activeTabId === this.ntxId; | ||||
|     } | ||||
|  | ||||
|     getTabState() { | ||||
| @@ -147,8 +147,8 @@ class TabContext extends Component { | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             tabId: this.tabId, | ||||
|             parentTabId: this.parentTabId, | ||||
|             ntxId: this.ntxId, | ||||
|             mainNtxId: this.mainNtxId, | ||||
|             notePath: this.notePath, | ||||
|             hoistedNoteId: this.hoistedNoteId, | ||||
|             active: this.isActive() | ||||
| @@ -168,7 +168,7 @@ class TabContext extends Component { | ||||
|  | ||||
|         await this.triggerEvent('hoistedNoteChanged', { | ||||
|             noteId: noteIdToHoist, | ||||
|             tabId: this.tabId | ||||
|             ntxId: this.ntxId | ||||
|         }); | ||||
|     } | ||||
|  | ||||
| @@ -181,7 +181,7 @@ class TabContext extends Component { | ||||
|                 this.notePath = null; | ||||
|  | ||||
|                 this.triggerEvent('tabNoteSwitched', { | ||||
|                     tabContext: this, | ||||
|                     noteContext: this, | ||||
|                     notePath: this.notePath | ||||
|                 }); | ||||
|             } | ||||
| @@ -189,4 +189,4 @@ class TabContext extends Component { | ||||
|     } | ||||
| } | ||||
|  | ||||
| export default TabContext; | ||||
| export default NoteContext; | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import options from "./options.js"; | ||||
| import froca from "./froca.js"; | ||||
| import treeService from "./tree.js"; | ||||
| import utils from "./utils.js"; | ||||
| import TabContext from "./tab_context.js"; | ||||
| import NoteContext from "./tab_context.js"; | ||||
| import appContext from "./app_context.js"; | ||||
|  | ||||
| export default class TabManager extends Component { | ||||
| @@ -19,8 +19,8 @@ export default class TabManager extends Component { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const openTabs = this.tabContexts | ||||
|                 .map(tc => tc.getTabState()) | ||||
|             const openTabs = this.noteContexts | ||||
|                 .map(nc => nc.getTabState()) | ||||
|                 .filter(t => !!t); | ||||
|  | ||||
|             await server.put('options', { | ||||
| @@ -31,14 +31,14 @@ export default class TabManager extends Component { | ||||
|         appContext.addBeforeUnloadListener(this); | ||||
|     } | ||||
|  | ||||
|     /** @type {TabContext[]} */ | ||||
|     get tabContexts() { | ||||
|     /** @type {NoteContext[]} */ | ||||
|     get noteContexts() { | ||||
|         return this.children; | ||||
|     } | ||||
|  | ||||
|     /** @type {TabContext[]} */ | ||||
|     get mainTabContexts() { | ||||
|         return this.tabContexts.filter(tc => !tc.parentTabId) | ||||
|     /** @type {NoteContext[]} */ | ||||
|     get mainNoteContexts() { | ||||
|         return this.noteContexts.filter(nc => !nc.mainNtxId) | ||||
|     } | ||||
|  | ||||
|     async loadTabs() { | ||||
| @@ -104,13 +104,13 @@ export default class TabManager extends Component { | ||||
|  | ||||
|         await this.tabsUpdate.allowUpdateWithoutChange(async () => { | ||||
|             for (const tab of filteredTabs) { | ||||
|                 await this.openTabWithNote(tab.notePath, tab.active, tab.tabId, tab.hoistedNoteId, tab.parentTabId); | ||||
|                 await this.openTabWithNote(tab.notePath, tab.active, tab.ntxId, tab.hoistedNoteId, tab.mainNtxId); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     tabNoteSwitchedEvent({tabContext}) { | ||||
|         if (tabContext.isActive()) { | ||||
|     tabNoteSwitchedEvent({noteContext}) { | ||||
|         if (noteContext.isActive()) { | ||||
|             this.setCurrentNotePathToHash(); | ||||
|         } | ||||
|  | ||||
| @@ -118,11 +118,11 @@ export default class TabManager extends Component { | ||||
|     } | ||||
|  | ||||
|     setCurrentNotePathToHash() { | ||||
|         const activeTabContext = this.getActiveTabContext(); | ||||
|         const activeNoteContext = this.getActiveNoteContext(); | ||||
|  | ||||
|         if (window.history.length === 0 // first history entry | ||||
|             || (activeTabContext && activeTabContext.notePath !== treeService.getHashValueFromAddress()[0])) { | ||||
|             const url = '#' + (activeTabContext.notePath || "") + "-" + activeTabContext.tabId; | ||||
|             || (activeNoteContext && activeNoteContext.notePath !== treeService.getHashValueFromAddress()[0])) { | ||||
|             const url = '#' + (activeNoteContext.notePath || "") + "-" + activeNoteContext.ntxId; | ||||
|  | ||||
|             // using pushState instead of directly modifying document.location because it does not trigger hashchange | ||||
|             window.history.pushState(null, "", url); | ||||
| @@ -130,46 +130,46 @@ export default class TabManager extends Component { | ||||
|  | ||||
|         document.title = "Trilium Notes"; | ||||
|  | ||||
|         if (activeTabContext.note) { | ||||
|         if (activeNoteContext.note) { | ||||
|             // it helps navigating in history if note title is included in the title | ||||
|             document.title += " - " + activeTabContext.note.title; | ||||
|             document.title += " - " + activeNoteContext.note.title; | ||||
|         } | ||||
|  | ||||
|         this.triggerEvent('activeNoteChanged'); // trigger this even in on popstate event | ||||
|     } | ||||
|  | ||||
|     /** @return {TabContext[]} */ | ||||
|     getTabContexts() { | ||||
|         return this.tabContexts; | ||||
|     /** @return {NoteContext[]} */ | ||||
|     getNoteContexts() { | ||||
|         return this.noteContexts; | ||||
|     } | ||||
|  | ||||
|     /** @returns {TabContext} */ | ||||
|     getTabContextById(tabId) { | ||||
|         const tabContext = this.tabContexts.find(tc => tc.tabId === tabId); | ||||
|     /** @returns {NoteContext} */ | ||||
|     getNoteContextById(ntxId) { | ||||
|         const noteContext = this.noteContexts.find(nc => nc.ntxId === ntxId); | ||||
|  | ||||
|         if (!tabContext) { | ||||
|             throw new Error(`Cannot find tabContext id='${tabId}'`); | ||||
|         if (!noteContext) { | ||||
|             throw new Error(`Cannot find noteContext id='${ntxId}'`); | ||||
|         } | ||||
|  | ||||
|         return tabContext; | ||||
|         return noteContext; | ||||
|     } | ||||
|  | ||||
|     /** @returns {TabContext} */ | ||||
|     getActiveTabContext() { | ||||
|     /** @returns {NoteContext} */ | ||||
|     getActiveNoteContext() { | ||||
|         return this.activeTabId | ||||
|             ? this.getTabContextById(this.activeTabId) | ||||
|             ? this.getNoteContextById(this.activeTabId) | ||||
|             : null; | ||||
|     } | ||||
|  | ||||
|     /** @returns {string|null} */ | ||||
|     getActiveTabNotePath() { | ||||
|         const activeContext = this.getActiveTabContext(); | ||||
|         const activeContext = this.getActiveNoteContext(); | ||||
|         return activeContext ? activeContext.notePath : null; | ||||
|     } | ||||
|  | ||||
|     /** @return {NoteShort} */ | ||||
|     getActiveTabNote() { | ||||
|         const activeContext = this.getActiveTabContext(); | ||||
|         const activeContext = this.getActiveNoteContext(); | ||||
|         return activeContext ? activeContext.note : null; | ||||
|     } | ||||
|  | ||||
| @@ -187,79 +187,79 @@ export default class TabManager extends Component { | ||||
|         return activeNote ? activeNote.type : null; | ||||
|     } | ||||
|  | ||||
|     async switchToTab(tabId, notePath) { | ||||
|         const tabContext = this.tabContexts.find(tc => tc.tabId === tabId) | ||||
|     async switchToTab(ntxId, notePath) { | ||||
|         const noteContext = this.noteContexts.find(nc => nc.ntxId === ntxId) | ||||
|             || await this.openEmptyTab(); | ||||
|  | ||||
|         this.activateTab(tabContext.tabId); | ||||
|         await tabContext.setNote(notePath); | ||||
|         this.activateTab(noteContext.ntxId); | ||||
|         await noteContext.setNote(notePath); | ||||
|     } | ||||
|  | ||||
|     async openAndActivateEmptyTab() { | ||||
|         const tabContext = await this.openEmptyTab(); | ||||
|         const noteContext = await this.openEmptyTab(); | ||||
|  | ||||
|         await this.activateTab(tabContext.tabId); | ||||
|         await this.activateTab(noteContext.ntxId); | ||||
|  | ||||
|         await tabContext.setEmpty(); | ||||
|         await noteContext.setEmpty(); | ||||
|     } | ||||
|  | ||||
|     async openEmptyTab(tabId, hoistedNoteId = 'root', parentTabId = null) { | ||||
|         const tabContext = new TabContext(tabId, hoistedNoteId, parentTabId); | ||||
|     async openEmptyTab(ntxId, hoistedNoteId = 'root', mainNtxId = null) { | ||||
|         const noteContext = new NoteContext(ntxId, hoistedNoteId, mainNtxId); | ||||
|  | ||||
|         const existingTabContext = this.children.find(tc => tc.tabId === tabContext.tabId); | ||||
|         const existingNoteContext = this.children.find(nc => nc.ntxId === noteContext.ntxId); | ||||
|  | ||||
|         if (existingTabContext) { | ||||
|             return existingTabContext; | ||||
|         if (existingNoteContext) { | ||||
|             return existingNoteContext; | ||||
|         } | ||||
|  | ||||
|         this.child(tabContext); | ||||
|         this.child(noteContext); | ||||
|  | ||||
|         await this.triggerEvent('newTabOpened', {tabContext}); | ||||
|         await this.triggerEvent('newTabOpened', {noteContext}); | ||||
|  | ||||
|         return tabContext; | ||||
|         return noteContext; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * If the requested notePath is within current note hoisting scope then keep the note hoisting also for the new tab. | ||||
|      */ | ||||
|     async openTabWithNoteWithHoisting(notePath) { | ||||
|         const tabContext = this.getActiveTabContext(); | ||||
|         const noteContext = this.getActiveNoteContext(); | ||||
|         let hoistedNoteId = 'root'; | ||||
|  | ||||
|         if (tabContext) { | ||||
|             const resolvedNotePath = await treeService.resolveNotePath(notePath, tabContext.hoistedNoteId); | ||||
|         if (noteContext) { | ||||
|             const resolvedNotePath = await treeService.resolveNotePath(notePath, noteContext.hoistedNoteId); | ||||
|  | ||||
|             if (resolvedNotePath.includes(tabContext.hoistedNoteId)) { | ||||
|                 hoistedNoteId = tabContext.hoistedNoteId; | ||||
|             if (resolvedNotePath.includes(noteContext.hoistedNoteId)) { | ||||
|                 hoistedNoteId = noteContext.hoistedNoteId; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return this.openTabWithNote(notePath, false, null, hoistedNoteId); | ||||
|     } | ||||
|  | ||||
|     async openTabWithNote(notePath, activate, tabId, hoistedNoteId = 'root', parentTabId = null) { | ||||
|         const tabContext = await this.openEmptyTab(tabId, hoistedNoteId, parentTabId); | ||||
|     async openTabWithNote(notePath, activate, ntxId, hoistedNoteId = 'root', mainNtxId = null) { | ||||
|         const noteContext = await this.openEmptyTab(ntxId, hoistedNoteId, mainNtxId); | ||||
|  | ||||
|         if (notePath) { | ||||
|             await tabContext.setNote(notePath, !activate); // if activate is false then send normal noteSwitched event | ||||
|             await noteContext.setNote(notePath, !activate); // if activate is false then send normal noteSwitched event | ||||
|         } | ||||
|  | ||||
|         if (activate) { | ||||
|             this.activateTab(tabContext.tabId, false); | ||||
|             this.activateTab(noteContext.ntxId, false); | ||||
|  | ||||
|             await this.triggerEvent('tabNoteSwitchedAndActivated', { | ||||
|                 tabContext, | ||||
|                 notePath: tabContext.notePath // resolved note path | ||||
|                 noteContext, | ||||
|                 notePath: noteContext.notePath // resolved note path | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return tabContext; | ||||
|         return noteContext; | ||||
|     } | ||||
|  | ||||
|     async activateOrOpenNote(noteId) { | ||||
|         for (const tabContext of this.getTabContexts()) { | ||||
|             if (tabContext.note && tabContext.note.noteId === noteId) { | ||||
|                 this.activateTab(tabContext.tabId); | ||||
|         for (const noteContext of this.getNoteContexts()) { | ||||
|             if (noteContext.note && noteContext.note.noteId === noteId) { | ||||
|                 this.activateTab(noteContext.ntxId); | ||||
|  | ||||
|                 return; | ||||
|             } | ||||
| @@ -270,16 +270,16 @@ export default class TabManager extends Component { | ||||
|         await this.openTabWithNote(noteId, true); | ||||
|     } | ||||
|  | ||||
|     activateTab(tabId, triggerEvent = true) { | ||||
|         if (tabId === this.activeTabId) { | ||||
|     activateTab(ntxId, triggerEvent = true) { | ||||
|         if (ntxId === this.activeTabId) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this.activeTabId = tabId; | ||||
|         this.activeTabId = ntxId; | ||||
|  | ||||
|         if (triggerEvent) { | ||||
|             this.triggerEvent('activeTabChanged', { | ||||
|                 tabContext: this.getTabContextById(tabId) | ||||
|                 noteContext: this.getNoteContextById(ntxId) | ||||
|             }); | ||||
|         } | ||||
|  | ||||
| @@ -288,23 +288,23 @@ export default class TabManager extends Component { | ||||
|         this.setCurrentNotePathToHash(); | ||||
|     } | ||||
|  | ||||
|     async removeTab(tabId) { | ||||
|         const mainTabContextToRemove = this.getTabContextById(tabId).getMainTabContext(); | ||||
|     async removeTab(ntxId) { | ||||
|         const mainNoteContextToRemove = this.getNoteContextById(ntxId).getMainNoteContext(); | ||||
|  | ||||
|         // close dangling autocompletes after closing the tab | ||||
|         $(".aa-input").autocomplete("close"); | ||||
|  | ||||
|         const tabIdsToRemove = mainTabContextToRemove.getAllSubTabContexts().map(tc => tc.tabId); | ||||
|         const ntxIdsToRemove = mainNoteContextToRemove.getAllSubNoteContexts().map(nc => nc.ntxId); | ||||
|  | ||||
|         await this.triggerEvent('beforeTabRemove', { tabIds: tabIdsToRemove }); | ||||
|         await this.triggerEvent('beforeTabRemove', { ntxIds: ntxIdsToRemove }); | ||||
|  | ||||
|         if (this.mainTabContexts.length <= 1) { | ||||
|         if (this.mainNoteContexts.length <= 1) { | ||||
|             await this.openAndActivateEmptyTab(); | ||||
|         } | ||||
|         else if (tabIdsToRemove.includes(this.activeTabId)) { | ||||
|             const idx = this.mainTabContexts.findIndex(tc => tc.tabId === mainTabContextToRemove.tabId); | ||||
|         else if (ntxIdsToRemove.includes(this.activeTabId)) { | ||||
|             const idx = this.mainNoteContexts.findIndex(nc => nc.ntxId === mainNoteContextToRemove.ntxId); | ||||
|  | ||||
|             if (idx === this.mainTabContexts.length - 1) { | ||||
|             if (idx === this.mainNoteContexts.length - 1) { | ||||
|                 this.activatePreviousTabCommand(); | ||||
|             } | ||||
|             else { | ||||
| @@ -312,35 +312,35 @@ export default class TabManager extends Component { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this.children = this.children.filter(tc => !tabIdsToRemove.includes(tc.tabId)); | ||||
|         this.children = this.children.filter(nc => !ntxIdsToRemove.includes(nc.ntxId)); | ||||
|  | ||||
|         this.triggerEvent('tabRemoved', {tabIds: tabIdsToRemove}); | ||||
|         this.triggerEvent('tabRemoved', {ntxIds: ntxIdsToRemove}); | ||||
|  | ||||
|         this.tabsUpdate.scheduleUpdate(); | ||||
|     } | ||||
|  | ||||
|     tabReorderEvent({tabIdsInOrder}) { | ||||
|     tabReorderEvent({ntxIdsInOrder}) { | ||||
|         const order = {}; | ||||
|  | ||||
|         for (const i in tabIdsInOrder) { | ||||
|             order[tabIdsInOrder[i]] = i; | ||||
|         for (const i in ntxIdsInOrder) { | ||||
|             order[ntxIdsInOrder[i]] = i; | ||||
|         } | ||||
|  | ||||
|         this.children.sort((a, b) => order[a.tabId] < order[b.tabId] ? -1 : 1); | ||||
|         this.children.sort((a, b) => order[a.ntxId] < order[b.ntxId] ? -1 : 1); | ||||
|  | ||||
|         this.tabsUpdate.scheduleUpdate(); | ||||
|     } | ||||
|  | ||||
|     activateNextTabCommand() { | ||||
|         const oldIdx = this.mainTabContexts.findIndex(tc => tc.tabId === this.activeTabId); | ||||
|         const newActiveTabId = this.mainTabContexts[oldIdx === this.tabContexts.length - 1 ? 0 : oldIdx + 1].tabId; | ||||
|         const oldIdx = this.mainNoteContexts.findIndex(nc => nc.ntxId === this.activeTabId); | ||||
|         const newActiveTabId = this.mainNoteContexts[oldIdx === this.noteContexts.length - 1 ? 0 : oldIdx + 1].ntxId; | ||||
|  | ||||
|         this.activateTab(newActiveTabId); | ||||
|     } | ||||
|  | ||||
|     activatePreviousTabCommand() { | ||||
|         const oldIdx = this.mainTabContexts.findIndex(tc => tc.tabId === this.activeTabId); | ||||
|         const newActiveTabId = this.mainTabContexts[oldIdx === 0 ? this.tabContexts.length - 1 : oldIdx - 1].tabId; | ||||
|         const oldIdx = this.mainNoteContexts.findIndex(nc => nc.ntxId === this.activeTabId); | ||||
|         const newActiveTabId = this.mainNoteContexts[oldIdx === 0 ? this.noteContexts.length - 1 : oldIdx - 1].ntxId; | ||||
|  | ||||
|         this.activateTab(newActiveTabId); | ||||
|     } | ||||
| @@ -360,23 +360,23 @@ export default class TabManager extends Component { | ||||
|     } | ||||
|  | ||||
|     async removeAllTabsCommand() { | ||||
|         for (const tabIdToRemove of this.tabContexts.map(tc => tc.tabId)) { | ||||
|             await this.removeTab(tabIdToRemove); | ||||
|         for (const ntxIdToRemove of this.noteContexts.map(nc => nc.ntxId)) { | ||||
|             await this.removeTab(ntxIdToRemove); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async removeAllTabsExceptForThisCommand({tabId}) { | ||||
|         for (const tabIdToRemove of this.tabContexts.map(tc => tc.tabId)) { | ||||
|             if (tabIdToRemove !== tabId) { | ||||
|                 await this.removeTab(tabIdToRemove); | ||||
|     async removeAllTabsExceptForThisCommand({ntxId}) { | ||||
|         for (const ntxIdToRemove of this.noteContexts.map(nc => nc.ntxId)) { | ||||
|             if (ntxIdToRemove !== ntxId) { | ||||
|                 await this.removeTab(ntxIdToRemove); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     moveTabToNewWindowCommand({tabId}) { | ||||
|         const {notePath, hoistedNoteId} = this.getTabContextById(tabId); | ||||
|     moveTabToNewWindowCommand({ntxId}) { | ||||
|         const {notePath, hoistedNoteId} = this.getNoteContextById(ntxId); | ||||
|  | ||||
|         this.removeTab(tabId); | ||||
|         this.removeTab(ntxId); | ||||
|  | ||||
|         this.triggerCommand('openInWindow', {notePath, hoistedNoteId}); | ||||
|     } | ||||
|   | ||||
| @@ -24,7 +24,7 @@ async function resolveNotePath(notePath, hoistedNoteId = 'root') { | ||||
| async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logErrors = true) { | ||||
|     utils.assertArguments(notePath); | ||||
|  | ||||
|     // we might get notePath with the tabId suffix, remove it if present | ||||
|     // we might get notePath with the ntxId suffix, remove it if present | ||||
|     notePath = notePath.split("-")[0].trim(); | ||||
|  | ||||
|     if (notePath.length === 0) { | ||||
| @@ -154,7 +154,7 @@ function getNoteIdFromNotePath(notePath) { | ||||
|  | ||||
|     const lastSegment = path[path.length - 1]; | ||||
|  | ||||
|     // path could have also tabId suffix | ||||
|     // path could have also ntxId suffix | ||||
|     return lastSegment.split("-")[0]; | ||||
| } | ||||
|  | ||||
| @@ -180,7 +180,7 @@ function getNoteIdAndParentIdFromNotePath(notePath) { | ||||
|  | ||||
|         const lastSegment = path[path.length - 1]; | ||||
|  | ||||
|         // path could have also tabId suffix | ||||
|         // path could have also ntxId suffix | ||||
|         noteId = lastSegment.split("-")[0]; | ||||
|  | ||||
|         if (path.length > 1) { | ||||
|   | ||||
| @@ -39,7 +39,7 @@ class TreeContextMenu { | ||||
|         const note = await froca.getNote(this.node.data.noteId); | ||||
|         const branch = froca.getBranch(this.node.data.branchId); | ||||
|         const isNotRoot = note.noteId !== 'root'; | ||||
|         const isHoisted = note.noteId === appContext.tabManager.getActiveTabContext().hoistedNoteId; | ||||
|         const isHoisted = note.noteId === appContext.tabManager.getActiveNoteContext().hoistedNoteId; | ||||
|         const parentNote = isNotRoot ? await froca.getNote(branch.parentNoteId) : null; | ||||
|  | ||||
|         // some actions don't support multi-note so they are disabled when notes are selected | ||||
|   | ||||
| @@ -226,15 +226,15 @@ export default class AttributeEditorWidget extends TabAwareWidget { | ||||
|     } | ||||
|  | ||||
|     // triggered from keyboard shortcut | ||||
|     addNewLabelEvent({tabId}) { | ||||
|         if (this.isTab(tabId)) { | ||||
|     addNewLabelEvent({ntxId}) { | ||||
|         if (this.isTab(ntxId)) { | ||||
|             this.handleAddNewAttributeCommand('addNewLabel'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // triggered from keyboard shortcut | ||||
|     addNewRelationEvent({tabId}) { | ||||
|         if (this.isTab(tabId)) { | ||||
|     addNewRelationEvent({ntxId}) { | ||||
|         if (this.isTab(ntxId)) { | ||||
|             this.handleAddNewAttributeCommand('addNewRelation'); | ||||
|         } | ||||
|     } | ||||
| @@ -482,8 +482,8 @@ export default class AttributeEditorWidget extends TabAwareWidget { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async focusOnAttributesEvent({tabId}) { | ||||
|         if (this.tabContext.tabId === tabId) { | ||||
|     async focusOnAttributesEvent({ntxId}) { | ||||
|         if (this.noteContext.ntxId === ntxId) { | ||||
|             if (this.$editor.is(":visible")) { | ||||
|                 this.$editor.trigger('focus'); | ||||
|  | ||||
| @@ -492,7 +492,7 @@ export default class AttributeEditorWidget extends TabAwareWidget { | ||||
|                 }); | ||||
|             } | ||||
|             else { | ||||
|                 this.triggerEvent('focusOnDetail', {tabId: this.tabContext.tabId}); | ||||
|                 this.triggerEvent('focusOnDetail', {ntxId: this.noteContext.ntxId}); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -56,7 +56,7 @@ export default class CalendarWidget extends CollapsibleWidget { | ||||
|             const note = await dateNoteService.getDateNote(date); | ||||
|  | ||||
|             if (note) { | ||||
|                 appContext.tabManager.getActiveTabContext().setNote(note.noteId); | ||||
|                 appContext.tabManager.getActiveNoteContext().setNote(note.noteId); | ||||
|             } | ||||
|             else { | ||||
|                 alert("Cannot find day note"); | ||||
|   | ||||
| @@ -100,7 +100,7 @@ export default class NoteInfoWidget extends CollapsibleWidget { | ||||
|     } | ||||
|  | ||||
|     async refreshWithNote(note) { | ||||
|         const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|         this.$noteId.text(note.noteId); | ||||
|         this.$dateCreated | ||||
|   | ||||
| @@ -14,20 +14,20 @@ export default class PaneContainer extends FlexContainer { | ||||
|         this.css('flex-grow', '1'); | ||||
|     } | ||||
|  | ||||
|     async newTabOpenedEvent({tabContext}) { | ||||
|     async newTabOpenedEvent({noteContext}) { | ||||
|         const widget = this.widgetFactory(); | ||||
|  | ||||
|         const $renderedWidget = widget.render(); | ||||
|  | ||||
|         $renderedWidget.attr("data-tab-id", tabContext.tabId); | ||||
|         $renderedWidget.attr("data-tab-id", noteContext.ntxId); | ||||
|  | ||||
|         $renderedWidget.on('click', () => appContext.tabManager.activateTab(tabContext.tabId)); | ||||
|         $renderedWidget.on('click', () => appContext.tabManager.activateTab(noteContext.ntxId)); | ||||
|  | ||||
|         this.$widget.append($renderedWidget); | ||||
|  | ||||
|         this.widgets[tabContext.tabId] = widget; | ||||
|         this.widgets[noteContext.ntxId] = widget; | ||||
|  | ||||
|         await widget.handleEvent('setTabContext', { tabContext }); | ||||
|         await widget.handleEvent('setNoteContext', { noteContext }); | ||||
|  | ||||
|         this.child(widget); | ||||
|  | ||||
| @@ -35,11 +35,11 @@ export default class PaneContainer extends FlexContainer { | ||||
|     } | ||||
|  | ||||
|     async openNewPaneCommand() { | ||||
|         const tabContext = await appContext.tabManager.openEmptyTab(null, 'root', appContext.tabManager.getActiveTabContext().tabId); | ||||
|         const noteContext = await appContext.tabManager.openEmptyTab(null, 'root', appContext.tabManager.getActiveNoteContext().ntxId); | ||||
|  | ||||
|         await appContext.tabManager.activateTab(tabContext.tabId); | ||||
|         await appContext.tabManager.activateTab(noteContext.ntxId); | ||||
|  | ||||
|         await tabContext.setEmpty(); | ||||
|         await noteContext.setEmpty(); | ||||
|     } | ||||
|  | ||||
|     async refresh() { | ||||
| @@ -49,16 +49,16 @@ export default class PaneContainer extends FlexContainer { | ||||
|     toggleInt(show) {} // not needed | ||||
|  | ||||
|     toggleExt(show) { | ||||
|         const activeTabId = appContext.tabManager.getActiveTabContext().getMainTabContext().tabId; | ||||
|         const activeTabId = appContext.tabManager.getActiveNoteContext().getMainNoteContext().ntxId; | ||||
|  | ||||
|         for (const tabId in this.widgets) { | ||||
|             const tabContext = appContext.tabManager.getTabContextById(tabId); | ||||
|         for (const ntxId in this.widgets) { | ||||
|             const noteContext = appContext.tabManager.getNoteContextById(ntxId); | ||||
|  | ||||
|             const widget = this.widgets[tabId]; | ||||
|             widget.toggleExt(show && activeTabId && [tabContext.tabId, tabContext.parentTabId].includes(activeTabId)); | ||||
|             const widget = this.widgets[ntxId]; | ||||
|             widget.toggleExt(show && activeTabId && [noteContext.ntxId, noteContext.mainNtxId].includes(activeTabId)); | ||||
|  | ||||
|             if (!widget.hasBeenAlreadyShown) { | ||||
|                 widget.handleEvent('activeTabChanged', {tabContext}); | ||||
|                 widget.handleEvent('activeTabChanged', {noteContext}); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -71,7 +71,7 @@ export default class PaneContainer extends FlexContainer { | ||||
|     handleEventInChildren(name, data) { | ||||
|         if (['tabNoteSwitched', 'tabNoteSwitchedAndActivated'].includes(name)) { | ||||
|             // this event is propagated only to the widgets of a particular tab | ||||
|             const widget = this.widgets[data.tabContext.tabId]; | ||||
|             const widget = this.widgets[data.noteContext.ntxId]; | ||||
|  | ||||
|             if (!widget) { | ||||
|                 return Promise.resolve(); | ||||
| @@ -79,23 +79,23 @@ export default class PaneContainer extends FlexContainer { | ||||
|  | ||||
|             const promises = []; | ||||
|  | ||||
|             if (appContext.tabManager.getActiveTabContext().getMainTabContext() === data.tabContext.getMainTabContext()) { | ||||
|             if (appContext.tabManager.getActiveNoteContext().getMainNoteContext() === data.noteContext.getMainNoteContext()) { | ||||
|                 promises.push(widget.handleEvent('activeTabChanged', data)); | ||||
|             } | ||||
|  | ||||
|             for (const subTabContext of data.tabContext.getMainTabContext().getAllSubTabContexts()) { | ||||
|                 const subWidget = this.widgets[subTabContext.tabId]; | ||||
|             for (const subNoteContext of data.noteContext.getMainNoteContext().getAllSubNoteContexts()) { | ||||
|                 const subWidget = this.widgets[subNoteContext.ntxId]; | ||||
|  | ||||
|                 if (!subWidget) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 if (subTabContext !== data.tabContext && !subWidget.hasBeenAlreadyShown) { | ||||
|                     promises.push(widget.handleEvent('activeTabChanged', {tabContext: subTabContext})); | ||||
|                 if (subNoteContext !== data.noteContext && !subWidget.hasBeenAlreadyShown) { | ||||
|                     promises.push(widget.handleEvent('activeTabChanged', {noteContext: subNoteContext})); | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 if (subTabContext === data.tabContext && (subWidget.hasBeenAlreadyShown || name === 'tabNoteSwitchedAndActivated')) { | ||||
|                 if (subNoteContext === data.noteContext && (subWidget.hasBeenAlreadyShown || name === 'tabNoteSwitchedAndActivated')) { | ||||
|                     subWidget.hasBeenAlreadyShown = true; | ||||
|  | ||||
|                     promises.push(widget.handleEvent('tabNoteSwitched', data)); | ||||
| @@ -112,15 +112,15 @@ export default class PaneContainer extends FlexContainer { | ||||
|         if (name === 'activeTabChanged') { | ||||
|             const promises = []; | ||||
|  | ||||
|             for (const subTabContext of data.tabContext.getMainTabContext().getAllSubTabContexts()) { | ||||
|                 console.log("subTabContext", subTabContext); | ||||
|             for (const subNoteContext of data.noteContext.getMainNoteContext().getAllSubNoteContexts()) { | ||||
|                 console.log("subNoteContext", subNoteContext); | ||||
|  | ||||
|                 const widget = this.widgets[subTabContext.tabId]; | ||||
|                 const widget = this.widgets[subNoteContext.ntxId]; | ||||
|  | ||||
|                 if (!widget.hasBeenAlreadyShown) { | ||||
|                     widget.hasBeenAlreadyShown = true; | ||||
|  | ||||
|                     promises.push(widget.handleEvent(name, {tabContext: subTabContext})); | ||||
|                     promises.push(widget.handleEvent(name, {noteContext: subNoteContext})); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -7,9 +7,9 @@ export default class ScrollingContainer extends Container { | ||||
|         this.css('height: 100%; overflow: auto;'); | ||||
|     } | ||||
|  | ||||
|     async tabNoteSwitchedEvent({tabContext, notePath}) { | ||||
|         // if notePath does not match then the tabContext has been switched to another note in the mean time | ||||
|         if (tabContext.notePath === notePath) { | ||||
|     async tabNoteSwitchedEvent({noteContext, notePath}) { | ||||
|         // if notePath does not match then the noteContext has been switched to another note in the mean time | ||||
|         if (noteContext.notePath === notePath) { | ||||
|             this.$widget.scrollTop(0); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -60,7 +60,7 @@ export default class HistoryNavigationWidget extends BasicWidget { | ||||
|         for (const idx in this.webContents.history) { | ||||
|             const url = this.webContents.history[idx]; | ||||
|             const [_, notePathWithTab] = url.split('#'); | ||||
|             const [notePath, tabId] = notePathWithTab.split('-'); | ||||
|             const [notePath, ntxId] = notePathWithTab.split('-'); | ||||
|  | ||||
|             const title = await treeService.getNotePathTitle(notePath); | ||||
|  | ||||
|   | ||||
| @@ -114,7 +114,7 @@ export default class NoteActionsWidget extends TabAwareWidget { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             import('../dialogs/export.js').then(d => d.showDialog(this.tabContext.notePath, 'single')); | ||||
|             import('../dialogs/export.js').then(d => d.showDialog(this.noteContext.notePath, 'single')); | ||||
|         }); | ||||
|  | ||||
|         this.$importNoteButton = this.$widget.find('.import-files-button'); | ||||
|   | ||||
| @@ -55,7 +55,7 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|         this.typeWidgets = {}; | ||||
|  | ||||
|         this.spacedUpdate = new SpacedUpdate(async () => { | ||||
|             const {note} = this.tabContext; | ||||
|             const {note} = this.noteContext; | ||||
|             const {noteId} = note; | ||||
|  | ||||
|             const dto = note.dto; | ||||
| @@ -119,12 +119,12 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|  | ||||
|             this.$widget.append($renderedWidget); | ||||
|  | ||||
|             await typeWidget.handleEvent('setTabContext', {tabContext: this.tabContext}); | ||||
|             await typeWidget.handleEvent('setNoteContext', {noteContext: this.noteContext}); | ||||
|  | ||||
|             // this is happening in update() so note has been already set and we need to reflect this | ||||
|             await typeWidget.handleEvent('tabNoteSwitched', { | ||||
|                 tabContext: this.tabContext, | ||||
|                 notePath: this.tabContext.notePath | ||||
|                 noteContext: this.noteContext, | ||||
|                 notePath: this.noteContext.notePath | ||||
|             }); | ||||
|  | ||||
|             this.child(typeWidget); | ||||
| @@ -150,8 +150,8 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|  | ||||
|         let type = note.type; | ||||
|  | ||||
|         if (type === 'text' && !this.tabContext.textPreviewDisabled) { | ||||
|             const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         if (type === 'text' && !this.noteContext.textPreviewDisabled) { | ||||
|             const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|             if (note.hasLabel('readOnly') || | ||||
|                 (noteComplement.content | ||||
| @@ -161,8 +161,8 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (type === 'code' && !this.tabContext.codePreviewDisabled) { | ||||
|             const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         if (type === 'code' && !this.noteContext.codePreviewDisabled) { | ||||
|             const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|             if (note.hasLabel('readOnly') || | ||||
|                 (noteComplement.content | ||||
| @@ -187,8 +187,8 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|         return type; | ||||
|     } | ||||
|  | ||||
|     async focusOnDetailEvent({tabId}) { | ||||
|         if (this.tabContext.tabId === tabId) { | ||||
|     async focusOnDetailEvent({ntxId}) { | ||||
|         if (this.noteContext.ntxId === ntxId) { | ||||
|             await this.refresh(); | ||||
|  | ||||
|             const widget = this.getTypeWidget(); | ||||
| @@ -196,20 +196,20 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async beforeNoteSwitchEvent({tabContext}) { | ||||
|         if (this.isTab(tabContext.tabId)) { | ||||
|     async beforeNoteSwitchEvent({noteContext}) { | ||||
|         if (this.isTab(noteContext.ntxId)) { | ||||
|             await this.spacedUpdate.updateNowIfNecessary(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async beforeTabRemoveEvent({tabIds}) { | ||||
|         if (this.isTab(tabIds)) { | ||||
|     async beforeTabRemoveEvent({ntxIds}) { | ||||
|         if (this.isTab(ntxIds)) { | ||||
|             await this.spacedUpdate.updateNowIfNecessary(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async printActiveNoteEvent() { | ||||
|         if (!this.tabContext.isActive()) { | ||||
|         if (!this.noteContext.isActive()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
| @@ -241,8 +241,8 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     hoistedNoteChangedEvent({tabId}) { | ||||
|         if (this.isTab(tabId)) { | ||||
|     hoistedNoteChangedEvent({ntxId}) { | ||||
|         if (this.isTab(ntxId)) { | ||||
|             this.refresh(); | ||||
|         } | ||||
|     } | ||||
| @@ -278,14 +278,14 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|         return this.spacedUpdate.isAllSavedAndTriggerUpdate(); | ||||
|     } | ||||
|  | ||||
|     textPreviewDisabledEvent({tabContext}) { | ||||
|         if (this.isTab(tabContext.tabId)) { | ||||
|     textPreviewDisabledEvent({noteContext}) { | ||||
|         if (this.isTab(noteContext.ntxId)) { | ||||
|             this.refresh(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     codePreviewDisabledEvent({tabContext}) { | ||||
|         if (this.isTab(tabContext.tabId)) { | ||||
|     codePreviewDisabledEvent({noteContext}) { | ||||
|         if (this.isTab(noteContext.ntxId)) { | ||||
|             this.refresh(); | ||||
|         } | ||||
|     } | ||||
| @@ -310,7 +310,7 @@ export default class NoteDetailWidget extends TabAwareWidget { | ||||
|     } | ||||
|  | ||||
|     renderActiveNoteEvent() { | ||||
|         if (this.tabContext.isActive()) { | ||||
|         if (this.noteContext.isActive()) { | ||||
|             this.refresh(); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -77,8 +77,8 @@ export default class NoteListWidget extends TabAwareWidget { | ||||
|      * If it's evaluated before note detail then it's clearly intersected (visible) although after note detail load | ||||
|      * it is not intersected (visible) anymore. | ||||
|      */ | ||||
|     noteDetailRefreshedEvent({tabId}) { | ||||
|         if (!this.isTab(tabId)) { | ||||
|     noteDetailRefreshedEvent({ntxId}) { | ||||
|         if (!this.isTab(ntxId)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -50,7 +50,7 @@ export default class NoteTitleWidget extends TabAwareWidget { | ||||
|         this.$noteTitle.on('input', () => this.spacedUpdate.scheduleUpdate()); | ||||
|  | ||||
|         utils.bindElShortcut(this.$noteTitle, 'return', () => { | ||||
|             this.triggerCommand('focusOnAttributes', {tabId: this.tabContext.tabId}); | ||||
|             this.triggerCommand('focusOnAttributes', {ntxId: this.noteContext.ntxId}); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
| @@ -66,26 +66,26 @@ export default class NoteTitleWidget extends TabAwareWidget { | ||||
|         this.$noteTitle.toggleClass("protected", !!note.isProtected); | ||||
|     } | ||||
|  | ||||
|     async beforeNoteSwitchEvent({tabContext}) { | ||||
|         if (this.isTab(tabContext.tabId)) { | ||||
|     async beforeNoteSwitchEvent({noteContext}) { | ||||
|         if (this.isTab(noteContext.ntxId)) { | ||||
|             await this.spacedUpdate.updateNowIfNecessary(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async beforeTabRemoveEvent({tabIds}) { | ||||
|         if (this.isTab(tabIds)) { | ||||
|     async beforeTabRemoveEvent({ntxIds}) { | ||||
|         if (this.isTab(ntxIds)) { | ||||
|             await this.spacedUpdate.updateNowIfNecessary(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     focusOnTitleEvent() { | ||||
|         if (this.tabContext && this.tabContext.isActive()) { | ||||
|         if (this.noteContext && this.noteContext.isActive()) { | ||||
|             this.$noteTitle.trigger('focus'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     focusAndSelectTitleEvent() { | ||||
|         if (this.tabContext && this.tabContext.isActive()) { | ||||
|         if (this.noteContext && this.noteContext.isActive()) { | ||||
|             this.$noteTitle | ||||
|                 .trigger('focus') | ||||
|                 .trigger('select'); | ||||
|   | ||||
| @@ -395,8 +395,8 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|  | ||||
|                 const notePath = treeService.getNotePath(data.node); | ||||
|  | ||||
|                 const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|                 await activeTabContext.setNote(notePath); | ||||
|                 const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|                 await activeNoteContext.setNote(notePath); | ||||
|  | ||||
|                 if (utils.isMobile()) { | ||||
|                     this.triggerCommand('setActiveScreen', {screen: 'detail'}); | ||||
| @@ -525,13 +525,13 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|                 } | ||||
|  | ||||
|                 const note = await froca.getNote(node.data.noteId); | ||||
|                 const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|                 const activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|                 const $span = $(node.span); | ||||
|  | ||||
|                 $span.find('.tree-item-button').remove(); | ||||
|  | ||||
|                 const isHoistedNote = activeTabContext && activeTabContext.hoistedNoteId === note.noteId && note.noteId !== 'root'; | ||||
|                 const isHoistedNote = activeNoteContext && activeNoteContext.hoistedNoteId === note.noteId && note.noteId !== 'root'; | ||||
|  | ||||
|                 if (isHoistedNote) { | ||||
|                     const $unhoistButton = $('<span class="tree-item-button unhoist-button bx bx-door-open" title="Unhoist"></span>'); | ||||
| @@ -810,7 +810,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|     } | ||||
|  | ||||
|     async scrollToActiveNoteEvent() { | ||||
|         const activeContext = appContext.tabManager.getActiveTabContext(); | ||||
|         const activeContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|         if (activeContext && activeContext.notePath) { | ||||
|             this.tree.$container.focus(); | ||||
| @@ -920,7 +920,7 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|     } | ||||
|  | ||||
|     isEnabled() { | ||||
|         return !!this.tabContext; | ||||
|         return !!this.noteContext; | ||||
|     } | ||||
|  | ||||
|     async refresh() { | ||||
| @@ -939,12 +939,12 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|             oldActiveNode.setFocus(false); | ||||
|         } | ||||
|  | ||||
|         if (this.tabContext && this.tabContext.notePath && !this.tabContext.note.isDeleted) { | ||||
|             const newActiveNode = await this.getNodeFromPath(this.tabContext.notePath); | ||||
|         if (this.noteContext && this.noteContext.notePath && !this.noteContext.note.isDeleted) { | ||||
|             const newActiveNode = await this.getNodeFromPath(this.noteContext.notePath); | ||||
|  | ||||
|             if (newActiveNode) { | ||||
|                 if (!newActiveNode.isVisible()) { | ||||
|                     await this.expandToNote(this.tabContext.notePath); | ||||
|                     await this.expandToNote(this.noteContext.notePath); | ||||
|                 } | ||||
|  | ||||
|                 newActiveNode.setActive(true, {noEvents: true, noFocus: !oldActiveNodeFocused}); | ||||
| @@ -993,8 +993,8 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|              */ | ||||
|  | ||||
|             const noteIdsToKeepExpanded = new Set( | ||||
|                 appContext.tabManager.getTabContexts() | ||||
|                     .map(tc => tc.notePathArray) | ||||
|                 appContext.tabManager.getNoteContexts() | ||||
|                     .map(nc => nc.notePathArray) | ||||
|                     .flat() | ||||
|             ); | ||||
|  | ||||
| @@ -1159,10 +1159,10 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|                 if (node) { | ||||
|                     // FIXME: this is conceptually wrong | ||||
|                     //        here note tree is responsible for updating global state of the application | ||||
|                     //        this should be done by tabcontext / tabmanager and note tree should only listen to | ||||
|                     //        this should be done by NoteContext / TabManager and note tree should only listen to | ||||
|                     //        changes in active note and just set the "active" state | ||||
|                     // We don't await since that can bring up infinite cycles when e.g. custom widget does some backend requests which wait for max sync ID processed | ||||
|                     appContext.tabManager.getActiveTabContext().setNote(nextNotePath).then(() => { | ||||
|                     appContext.tabManager.getActiveNoteContext().setNote(nextNotePath).then(() => { | ||||
|                         const newActiveNode = this.getActiveNode(); | ||||
|  | ||||
|                         // return focus if the previously active node was also focused | ||||
| @@ -1232,25 +1232,25 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async hoistedNoteChangedEvent({tabId}) { | ||||
|         if (this.isTab(tabId)) { | ||||
|     async hoistedNoteChangedEvent({ntxId}) { | ||||
|         if (this.isTab(ntxId)) { | ||||
|             this.filterHoistedBranch(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async filterHoistedBranch() { | ||||
|         if (this.tabContext) { | ||||
|         if (this.noteContext) { | ||||
|             // make sure the hoisted node is loaded (can be unloaded e.g. after tree collapse in another tab) | ||||
|             const hoistedNotePath = await treeService.resolveNotePath(this.tabContext.hoistedNoteId); | ||||
|             const hoistedNotePath = await treeService.resolveNotePath(this.noteContext.hoistedNoteId); | ||||
|             await this.getNodeFromPath(hoistedNotePath); | ||||
|  | ||||
|             if (this.tabContext.hoistedNoteId === 'root') { | ||||
|             if (this.noteContext.hoistedNoteId === 'root') { | ||||
|                 this.tree.clearFilter(); | ||||
|             } | ||||
|             else { | ||||
|                 // hack when hoisted note is cloned then it could be filtered multiple times while we want only 1 | ||||
|                 this.tree.filterBranches(node => | ||||
|                     node.data.noteId === this.tabContext.hoistedNoteId // optimization to not having always resolve the node path | ||||
|                     node.data.noteId === this.noteContext.hoistedNoteId // optimization to not having always resolve the node path | ||||
|                     && treeService.getNotePath(node) === hoistedNotePath); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -136,7 +136,7 @@ export default class NoteTypeWidget extends TabAwareWidget { | ||||
|     } | ||||
|  | ||||
|     async confirmChangeIfContent() { | ||||
|         const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|         if (!noteComplement.content || !noteComplement.content.trim().length) { | ||||
|             return true; | ||||
|   | ||||
| @@ -98,13 +98,13 @@ export default class QuickSearchWidget extends BasicWidget { | ||||
|  | ||||
|                 if (!e.target || e.target.nodeName !== 'A') { | ||||
|                     // click on the link is handled by link handling but we want the whole item clickable | ||||
|                     appContext.tabManager.getActiveTabContext().setNote(note.noteId); | ||||
|                     appContext.tabManager.getActiveNoteContext().setNote(note.noteId); | ||||
|                 } | ||||
|             }); | ||||
|             utils.bindElShortcut($link, 'return', () => { | ||||
|                 this.$dropdownToggle.dropdown("hide"); | ||||
|  | ||||
|                 appContext.tabManager.getActiveTabContext().setNote(note.noteId); | ||||
|                 appContext.tabManager.getActiveNoteContext().setNote(note.noteId); | ||||
|             }); | ||||
|  | ||||
|             this.$dropdownMenu.append($link); | ||||
| @@ -131,7 +131,7 @@ export default class QuickSearchWidget extends BasicWidget { | ||||
|     async showInFullSearch() { | ||||
|         const searchNote = await dateNotesService.createSearchNote({searchString: this.$searchString.val()}); | ||||
|  | ||||
|         await appContext.tabManager.getActiveTabContext().setNote(searchNote.noteId); | ||||
|         await appContext.tabManager.getActiveNoteContext().setNote(searchNote.noteId); | ||||
|     } | ||||
|  | ||||
|     quickSearchEvent() { | ||||
|   | ||||
| @@ -56,8 +56,8 @@ export default class SearchResultWidget extends TabAwareWidget { | ||||
|         await noteListRenderer.renderList(); | ||||
|     } | ||||
|  | ||||
|     searchRefreshedEvent({tabId}) { | ||||
|         if (!this.isTab(tabId)) { | ||||
|     searchRefreshedEvent({ntxId}) { | ||||
|         if (!this.isTab(ntxId)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -25,8 +25,8 @@ export default class SqlResultWidget extends TabAwareWidget { | ||||
|         this.$sqlConsoleResultContainer = this.$widget.find('.sql-console-result-container'); | ||||
|     } | ||||
|  | ||||
|     async sqlQueryResultsEvent({tabId, results}) { | ||||
|         if (!this.isTab(tabId)) { | ||||
|     async sqlQueryResultsEvent({ntxId, results}) { | ||||
|         if (!this.isTab(ntxId)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -2,17 +2,17 @@ import BasicWidget from "./basic_widget.js"; | ||||
| import appContext from "../services/app_context.js"; | ||||
|  | ||||
| export default class TabAwareWidget extends BasicWidget { | ||||
|     isTab(tabId) { | ||||
|         if (Array.isArray(tabId)) { | ||||
|             return this.tabContext && tabId.includes(this.tabContext.tabId); | ||||
|     isTab(ntxId) { | ||||
|         if (Array.isArray(ntxId)) { | ||||
|             return this.noteContext && ntxId.includes(this.noteContext.ntxId); | ||||
|         } | ||||
|         else { | ||||
|             return this.tabContext && this.tabContext.tabId === tabId; | ||||
|             return this.noteContext && this.noteContext.ntxId === ntxId; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     isTabOrParent(tabId) { | ||||
|         return this.tabContext && (this.tabContext.tabId === tabId || this.tabContext.parentTabId === tabId); | ||||
|     isTabOrParent(ntxId) { | ||||
|         return this.noteContext && (this.noteContext.ntxId === ntxId || this.noteContext.mainNtxId === ntxId); | ||||
|     } | ||||
|  | ||||
|     isNote(noteId) { | ||||
| @@ -20,7 +20,7 @@ export default class TabAwareWidget extends BasicWidget { | ||||
|     } | ||||
|  | ||||
|     get note() { | ||||
|         return this.tabContext && this.tabContext.note; | ||||
|         return this.noteContext && this.noteContext.note; | ||||
|     } | ||||
|  | ||||
|     get noteId() { | ||||
| @@ -28,11 +28,11 @@ export default class TabAwareWidget extends BasicWidget { | ||||
|     } | ||||
|  | ||||
|     get notePath() { | ||||
|         return this.tabContext && this.tabContext.notePath; | ||||
|         return this.noteContext && this.noteContext.notePath; | ||||
|     } | ||||
|  | ||||
|     get hoistedNoteId() { | ||||
|         return this.tabContext && this.tabContext.hoistedNoteId; | ||||
|         return this.noteContext && this.noteContext.hoistedNoteId; | ||||
|     } | ||||
|  | ||||
|     isEnabled() { | ||||
| @@ -59,9 +59,9 @@ export default class TabAwareWidget extends BasicWidget { | ||||
|  | ||||
|     async refreshWithNote(note) {} | ||||
|  | ||||
|     async tabNoteSwitchedEvent({tabContext, notePath}) { | ||||
|         // if notePath does not match then the tabContext has been switched to another note in the mean time | ||||
|         if (tabContext.notePath === notePath) { | ||||
|     async tabNoteSwitchedEvent({noteContext, notePath}) { | ||||
|         // if notePath does not match then the noteContext has been switched to another note in the mean time | ||||
|         if (noteContext.notePath === notePath) { | ||||
|             await this.noteSwitched(); | ||||
|         } | ||||
|     } | ||||
| @@ -70,8 +70,8 @@ export default class TabAwareWidget extends BasicWidget { | ||||
|         await this.refresh(); | ||||
|     } | ||||
|  | ||||
|     async activeTabChangedEvent({tabContext}) { | ||||
|         this.tabContext = tabContext; | ||||
|     async activeTabChangedEvent({noteContext}) { | ||||
|         this.noteContext = noteContext; | ||||
|  | ||||
|         await this.activeTabChanged(); | ||||
|     } | ||||
| @@ -81,18 +81,18 @@ export default class TabAwareWidget extends BasicWidget { | ||||
|     } | ||||
|  | ||||
|     // when note is both switched and activated, this should not produce double refresh | ||||
|     async tabNoteSwitchedAndActivatedEvent({tabContext, notePath}) { | ||||
|         this.tabContext = tabContext; | ||||
|     async tabNoteSwitchedAndActivatedEvent({noteContext, notePath}) { | ||||
|         this.noteContext = noteContext; | ||||
|  | ||||
|         // if notePath does not match then the tabContext has been switched to another note in the mean time | ||||
|         // if notePath does not match then the noteContext has been switched to another note in the mean time | ||||
|         if (this.notePath === notePath) { | ||||
|             await this.refresh(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     setTabContextEvent({tabContext}) { | ||||
|         /** @var {TabContext} */ | ||||
|         this.tabContext = tabContext; | ||||
|     setNoteContextEvent({noteContext}) { | ||||
|         /** @var {NoteContext} */ | ||||
|         this.noteContext = noteContext; | ||||
|     } | ||||
|  | ||||
|     async noteTypeMimeChangedEvent({noteId}) { | ||||
| @@ -106,8 +106,8 @@ export default class TabAwareWidget extends BasicWidget { | ||||
|     } | ||||
|  | ||||
|     async lazyLoadedEvent() { | ||||
|         if (!this.tabContext) { // has not been loaded yet | ||||
|             this.tabContext = appContext.tabManager.getActiveTabContext(); | ||||
|         if (!this.noteContext) { // has not been loaded yet | ||||
|             this.noteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|         } | ||||
|  | ||||
|         await this.refresh(); | ||||
|   | ||||
| @@ -13,34 +13,34 @@ export default class TabCachingWidget extends TabAwareWidget { | ||||
|         return this.$widget = $(`<div class="marker" style="display: none;">`); | ||||
|     } | ||||
|  | ||||
|     async newTabOpenedEvent({tabContext}) { | ||||
|         const {tabId} = tabContext; | ||||
|     async newTabOpenedEvent({noteContext}) { | ||||
|         const {ntxId} = noteContext; | ||||
|  | ||||
|         if (this.widgets[tabId]) { | ||||
|         if (this.widgets[ntxId]) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this.widgets[tabId] = this.widgetFactory(); | ||||
|         this.widgets[ntxId] = this.widgetFactory(); | ||||
|  | ||||
|         const $renderedWidget = this.widgets[tabId].render(); | ||||
|         this.widgets[tabId].toggleExt(false); // new tab is always not active, can be activated after creation | ||||
|         const $renderedWidget = this.widgets[ntxId].render(); | ||||
|         this.widgets[ntxId].toggleExt(false); // new tab is always not active, can be activated after creation | ||||
|  | ||||
|         this.$widget.after($renderedWidget); | ||||
|  | ||||
|         keyboardActionsService.updateDisplayedShortcuts($renderedWidget); | ||||
|  | ||||
|         await this.widgets[tabId].handleEvent('setTabContext', {tabContext}); | ||||
|         await this.widgets[ntxId].handleEvent('setNoteContext', {noteContext}); | ||||
|  | ||||
|         this.child(this.widgets[tabId]); // add as child only once it is ready (rendered with tabContext) | ||||
|         this.child(this.widgets[ntxId]); // add as child only once it is ready (rendered with noteContext) | ||||
|     } | ||||
|  | ||||
|     tabRemovedEvent({tabIds}) { | ||||
|         for (const tabId of tabIds) { | ||||
|             const widget = this.widgets[tabId]; | ||||
|     tabRemovedEvent({ntxIds}) { | ||||
|         for (const ntxId of ntxIds) { | ||||
|             const widget = this.widgets[ntxId]; | ||||
|  | ||||
|             if (widget) { | ||||
|                 widget.remove(); | ||||
|                 delete this.widgets[tabId]; | ||||
|                 delete this.widgets[ntxId]; | ||||
|  | ||||
|                 this.children = this.children.filter(ch => ch !== widget); | ||||
|             } | ||||
| @@ -54,8 +54,8 @@ export default class TabCachingWidget extends TabAwareWidget { | ||||
|     toggleInt(show) {} // not needed | ||||
|  | ||||
|     toggleExt(show) { | ||||
|         for (const tabId in this.widgets) { | ||||
|             this.widgets[tabId].toggleExt(show && this.isTab(tabId)); | ||||
|         for (const ntxId in this.widgets) { | ||||
|             this.widgets[ntxId].toggleExt(show && this.isTab(ntxId)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -67,10 +67,10 @@ export default class TabCachingWidget extends TabAwareWidget { | ||||
|     handleEventInChildren(name, data) { | ||||
|         if (['tabNoteSwitched', 'tabNoteSwitchedAndActivated'].includes(name)) { | ||||
|             // this event is propagated only to the widgets of a particular tab | ||||
|             let widget = this.widgets[data.tabContext.tabId]; | ||||
|             let widget = this.widgets[data.noteContext.ntxId]; | ||||
|  | ||||
|             if (!widget) { | ||||
|                 widget = this.widgets[data.tabContext.parentTabId]; | ||||
|                 widget = this.widgets[data.noteContext.mainNtxId]; | ||||
|             } | ||||
|  | ||||
|             if (widget && (widget.hasBeenAlreadyShown || name === 'tabNoteSwitchedAndActivated')) { | ||||
| @@ -84,10 +84,10 @@ export default class TabCachingWidget extends TabAwareWidget { | ||||
|         } | ||||
|  | ||||
|         if (name === 'activeTabChanged') { | ||||
|             let widget = this.widgets[data.tabContext.tabId]; | ||||
|             let widget = this.widgets[data.noteContext.ntxId]; | ||||
|  | ||||
|             if (!widget) { | ||||
|                 widget = this.widgets[data.tabContext.parentTabId]; | ||||
|                 widget = this.widgets[data.noteContext.mainNtxId]; | ||||
|             } | ||||
|  | ||||
|             if (widget.hasBeenAlreadyShown) { | ||||
|   | ||||
| @@ -266,7 +266,7 @@ export default class TabRowWidget extends BasicWidget { | ||||
|         this.$widget.on('contextmenu', '.note-tab', e => { | ||||
|             e.preventDefault(); | ||||
|  | ||||
|             const tabId = $(e.target).closest(".note-tab").attr('data-tab-id'); | ||||
|             const ntxId = $(e.target).closest(".note-tab").attr('data-tab-id'); | ||||
|  | ||||
|             contextMenu.show({ | ||||
|                 x: e.pageX, | ||||
| @@ -277,7 +277,7 @@ export default class TabRowWidget extends BasicWidget { | ||||
|                     {title: "Close all tabs except for this", command: "removeAllTabsExceptForThis", uiIcon: "x"}, | ||||
|                 ], | ||||
|                 selectMenuItemHandler: ({command}) => { | ||||
|                     this.triggerCommand(command, {tabId}); | ||||
|                     this.triggerCommand(command, {ntxId}); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
| @@ -388,8 +388,8 @@ export default class TabRowWidget extends BasicWidget { | ||||
|         this.$style.html(styleHTML); | ||||
|     } | ||||
|  | ||||
|     addTab(tabId) { | ||||
|         const $tab = $(TAB_TPL).attr('data-tab-id', tabId); | ||||
|     addTab(ntxId) { | ||||
|         const $tab = $(TAB_TPL).attr('data-tab-id', ntxId); | ||||
|  | ||||
|         keyboardActionService.updateDisplayedShortcuts($tab); | ||||
|  | ||||
| @@ -407,9 +407,9 @@ export default class TabRowWidget extends BasicWidget { | ||||
|     } | ||||
|  | ||||
|     closeActiveTabCommand({$el}) { | ||||
|         const tabId = $el.closest(".note-tab").attr('data-tab-id'); | ||||
|         const ntxId = $el.closest(".note-tab").attr('data-tab-id'); | ||||
|  | ||||
|         appContext.tabManager.removeTab(tabId); | ||||
|         appContext.tabManager.removeTab(ntxId); | ||||
|     } | ||||
|  | ||||
|     setTabCloseEvent($tab) { | ||||
| @@ -427,31 +427,31 @@ export default class TabRowWidget extends BasicWidget { | ||||
|     } | ||||
|  | ||||
|     activeTabChangedEvent() { | ||||
|         let activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||
|         let activeNoteContext = appContext.tabManager.getActiveNoteContext(); | ||||
|  | ||||
|         if (!activeTabContext) { | ||||
|         if (!activeNoteContext) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (activeTabContext.parentTabId) { | ||||
|             activeTabContext = appContext.tabManager.getTabContextById(activeTabContext.parentTabId); | ||||
|         if (activeNoteContext.mainNtxId) { | ||||
|             activeNoteContext = appContext.tabManager.getNoteContextById(activeNoteContext.mainNtxId); | ||||
|         } | ||||
|  | ||||
|         const tabEl = this.getTabById(activeTabContext.tabId)[0]; | ||||
|         const tabEl = this.getTabById(activeNoteContext.ntxId)[0]; | ||||
|         const activeTabEl = this.activeTabEl; | ||||
|         if (activeTabEl === tabEl) return; | ||||
|         if (activeTabEl) activeTabEl.removeAttribute('active'); | ||||
|         if (tabEl) tabEl.setAttribute('active', ''); | ||||
|     } | ||||
|  | ||||
|     newTabOpenedEvent({tabContext}) { | ||||
|         if (!tabContext.parentTabId) { | ||||
|             this.addTab(tabContext.tabId); | ||||
|     newTabOpenedEvent({noteContext}) { | ||||
|         if (!noteContext.mainNtxId) { | ||||
|             this.addTab(noteContext.ntxId); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     removeTab(tabId) { | ||||
|         const tabEl = this.getTabById(tabId)[0]; | ||||
|     removeTab(ntxId) { | ||||
|         const tabEl = this.getTabById(ntxId)[0]; | ||||
|  | ||||
|         if (tabEl) { | ||||
|             tabEl.parentNode.removeChild(tabEl); | ||||
| @@ -470,17 +470,17 @@ export default class TabRowWidget extends BasicWidget { | ||||
|         $tab.find('.note-tab-title').text(title); | ||||
|     } | ||||
|  | ||||
|     getTabById(tabId) { | ||||
|         return this.$widget.find(`[data-tab-id='${tabId}']`); | ||||
|     getTabById(ntxId) { | ||||
|         return this.$widget.find(`[data-tab-id='${ntxId}']`); | ||||
|     } | ||||
|  | ||||
|     getTabId($tab) { | ||||
|         return $tab.attr('data-tab-id'); | ||||
|     } | ||||
|  | ||||
|     tabRemovedEvent({tabIds}) { | ||||
|         for (const tabId of tabIds) { | ||||
|             this.removeTab(tabId); | ||||
|     tabRemovedEvent({ntxIds}) { | ||||
|         for (const ntxId of ntxIds) { | ||||
|             this.removeTab(ntxId); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -567,7 +567,7 @@ export default class TabRowWidget extends BasicWidget { | ||||
|                 } | ||||
|  | ||||
|                 if (Math.abs(moveVector.y) > 100) { | ||||
|                     this.triggerCommand('moveTabToNewWindow', {tabId: this.getTabId($(tabEl))}); | ||||
|                     this.triggerCommand('moveTabToNewWindow', {ntxId: this.getTabId($(tabEl))}); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
| @@ -581,7 +581,7 @@ export default class TabRowWidget extends BasicWidget { | ||||
|  | ||||
|             tabEl.parentNode.insertBefore(tabEl, beforeEl); | ||||
|         } | ||||
|         this.triggerEvent('tabReorder', {tabIdsInOrder: this.getTabIdsInOrder()}); | ||||
|         this.triggerEvent('tabReorder', {ntxIdsInOrder: this.getTabIdsInOrder()}); | ||||
|         this.layoutTabs(); | ||||
|     } | ||||
|  | ||||
| @@ -611,20 +611,20 @@ export default class TabRowWidget extends BasicWidget { | ||||
|         return closestIndex; | ||||
|     }; | ||||
|  | ||||
|     tabNoteSwitchedAndActivatedEvent({tabContext}) { | ||||
|     tabNoteSwitchedAndActivatedEvent({noteContext}) { | ||||
|         this.activeTabChangedEvent(); | ||||
|  | ||||
|         this.updateTabById(tabContext.parentTabId || tabContext.tabId); | ||||
|         this.updateTabById(noteContext.mainNtxId || noteContext.ntxId); | ||||
|     } | ||||
|  | ||||
|     tabNoteSwitchedEvent({tabContext}) { | ||||
|         this.updateTabById(tabContext.parentTabId || tabContext.tabId); | ||||
|     tabNoteSwitchedEvent({noteContext}) { | ||||
|         this.updateTabById(noteContext.mainNtxId || noteContext.ntxId); | ||||
|     } | ||||
|  | ||||
|     updateTabById(tabId) { | ||||
|         const $tab = this.getTabById(tabId); | ||||
|     updateTabById(ntxId) { | ||||
|         const $tab = this.getTabById(ntxId); | ||||
|  | ||||
|         const {note} = appContext.tabManager.getTabContextById(tabId); | ||||
|         const {note} = appContext.tabManager.getNoteContextById(ntxId); | ||||
|  | ||||
|         this.updateTab($tab, note); | ||||
|     } | ||||
| @@ -640,10 +640,10 @@ export default class TabRowWidget extends BasicWidget { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const tabContext = appContext.tabManager.getTabContextById(this.getTabId($tab)); | ||||
|         const noteContext = appContext.tabManager.getNoteContextById(this.getTabId($tab)); | ||||
|  | ||||
|         if (tabContext) { | ||||
|             const hoistedNote = froca.getNoteFromCache(tabContext.hoistedNoteId); | ||||
|         if (noteContext) { | ||||
|             const hoistedNote = froca.getNoteFromCache(noteContext.hoistedNoteId); | ||||
|  | ||||
|             if (hoistedNote) { | ||||
|                 $tab.find('.note-tab-icon') | ||||
| @@ -671,38 +671,38 @@ export default class TabRowWidget extends BasicWidget { | ||||
|     } | ||||
|  | ||||
|     async entitiesReloadedEvent({loadResults}) { | ||||
|         for (const tabContext of appContext.tabManager.tabContexts) { | ||||
|             if (!tabContext.noteId) { | ||||
|         for (const noteContext of appContext.tabManager.noteContexts) { | ||||
|             if (!noteContext.noteId) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (loadResults.isNoteReloaded(tabContext.noteId) || | ||||
|             if (loadResults.isNoteReloaded(noteContext.noteId) || | ||||
|                 loadResults.getAttributes().find(attr => | ||||
|                     ['workspace', 'workspaceIconClass', 'workspaceTabBackgroundColor'].includes(attr.name) | ||||
|                     && attr.isAffecting(tabContext.note)) | ||||
|                     && attr.isAffecting(noteContext.note)) | ||||
|             ) { | ||||
|                 const $tab = this.getTabById(tabContext.tabId); | ||||
|                 const $tab = this.getTabById(noteContext.ntxId); | ||||
|  | ||||
|                 this.updateTab($tab, tabContext.note); | ||||
|                 this.updateTab($tab, noteContext.note); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     frocaReloadedEvent() { | ||||
|         for (const tabContext of appContext.tabManager.tabContexts) { | ||||
|             const $tab = this.getTabById(tabContext.tabId); | ||||
|         for (const noteContext of appContext.tabManager.noteContexts) { | ||||
|             const $tab = this.getTabById(noteContext.ntxId); | ||||
|  | ||||
|             this.updateTab($tab, tabContext.note); | ||||
|             this.updateTab($tab, noteContext.note); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     hoistedNoteChangedEvent({tabId}) { | ||||
|         const $tab = this.getTabById(tabId); | ||||
|     hoistedNoteChangedEvent({ntxId}) { | ||||
|         const $tab = this.getTabById(ntxId); | ||||
|  | ||||
|         if ($tab) { | ||||
|             const tabContext = appContext.tabManager.getTabContextById(tabId); | ||||
|             const noteContext = appContext.tabManager.getNoteContextById(ntxId); | ||||
|  | ||||
|             this.updateTab($tab, tabContext.note); | ||||
|             this.updateTab($tab, noteContext.note); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -126,7 +126,7 @@ export default class FilePropertiesWidget extends TabAwareWidget { | ||||
|         this.$fileName.text(attributeMap.originalFileName || "?"); | ||||
|         this.$fileType.text(note.mime); | ||||
|  | ||||
|         const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|         this.$fileSize.text(noteComplement.contentLength + " bytes"); | ||||
|  | ||||
|   | ||||
| @@ -67,7 +67,7 @@ export default class ImagePropertiesWidget extends TabAwareWidget { | ||||
|         this.$imageDownloadButton = this.$widget.find(".image-download"); | ||||
|         this.$imageDownloadButton.on('click', () => openService.downloadFileNote(this.noteId)); | ||||
|  | ||||
|         this.$copyToClipboardButton.on('click', () => this.triggerEvent(`copyImageToClipboard`, {tabId: this.tabContext.tabId})); | ||||
|         this.$copyToClipboardButton.on('click', () => this.triggerEvent(`copyImageToClipboard`, {ntxId: this.noteContext.ntxId})); | ||||
|  | ||||
|         this.$uploadNewRevisionButton.on("click", () => { | ||||
|             this.$uploadNewRevisionInput.trigger("click"); | ||||
| @@ -109,7 +109,7 @@ export default class ImagePropertiesWidget extends TabAwareWidget { | ||||
|  | ||||
|         this.$widget.show(); | ||||
|  | ||||
|         const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|         this.$fileName.text(attributeMap.originalFileName || "?"); | ||||
|         this.$fileSize.text(noteComplement.contentLength + " bytes"); | ||||
|   | ||||
| @@ -271,7 +271,7 @@ export default class SearchDefinitionWidget extends TabAwareWidget { | ||||
|             toastService.showError(e.message); | ||||
|         } | ||||
|  | ||||
|         this.triggerEvent('searchRefreshed', {tabId: this.tabContext.tabId}); | ||||
|         this.triggerEvent('searchRefreshed', {ntxId: this.noteContext.ntxId}); | ||||
|     } | ||||
|  | ||||
|     async refreshSearchDefinitionCommand() { | ||||
|   | ||||
| @@ -23,7 +23,7 @@ export default class AbstractTextTypeWidget extends TypeWidget { | ||||
|         const noteId = this.getNoteIdFromImage(imgSrc); | ||||
|  | ||||
|         if (noteId) { | ||||
|             appContext.tabManager.getActiveTabContext().setNote(noteId); | ||||
|             appContext.tabManager.getActiveNoteContext().setNote(noteId); | ||||
|         } else { | ||||
|             window.open(imgSrc, '_blank'); | ||||
|         } | ||||
|   | ||||
| @@ -72,7 +72,7 @@ export default class EditableCodeTypeWidget extends TypeWidget { | ||||
|             || note.mime === 'text/x-sqlite;schema=trilium' | ||||
|         ); | ||||
|  | ||||
|         const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|         await this.spacedUpdate.allowUpdateWithoutChange(() => { | ||||
|             // CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check) | ||||
|   | ||||
| @@ -61,7 +61,7 @@ export default class EmptyTypeWidget extends TypeWidget { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 appContext.tabManager.getActiveTabContext().setNote(suggestion.notePath); | ||||
|                 appContext.tabManager.getActiveNoteContext().setNote(suggestion.notePath); | ||||
|             }); | ||||
|  | ||||
|         noteAutocompleteService.showRecentNotes(this.$autoComplete); | ||||
|   | ||||
| @@ -53,7 +53,7 @@ export default class FileTypeWidget extends TypeWidget { | ||||
|     async doRefresh(note) { | ||||
|         this.$widget.show(); | ||||
|  | ||||
|         const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|         this.$previewContent.empty().hide(); | ||||
|         this.$pdfPreview.attr('src', '').empty().hide(); | ||||
|   | ||||
| @@ -62,8 +62,8 @@ class ImageTypeWidget extends TypeWidget { | ||||
|         this.$imageView.prop("src", `api/images/${note.noteId}/${note.title}?${imageHash}`); | ||||
|     } | ||||
|  | ||||
|     copyImageToClipboardEvent({tabId}) { | ||||
|         if (!this.isTab(tabId)) { | ||||
|     copyImageToClipboardEvent({ntxId}) { | ||||
|         if (!this.isTab(ntxId)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -36,14 +36,14 @@ export default class ReadOnlyCodeTypeWidget extends TypeWidget { | ||||
|         this.$content = this.$widget.find('.note-detail-read-only-code-content'); | ||||
|  | ||||
|         this.$widget.find('.edit-code-note-button').on('click', () => { | ||||
|             this.tabContext.codePreviewDisabled = true; | ||||
|             this.noteContext.codePreviewDisabled = true; | ||||
|  | ||||
|             this.triggerEvent('codePreviewDisabled', {tabContext: this.tabContext}); | ||||
|             this.triggerEvent('codePreviewDisabled', {noteContext: this.noteContext}); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     async doRefresh(note) { | ||||
|         const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|         this.$content.text(noteComplement.content); | ||||
|     } | ||||
|   | ||||
| @@ -63,9 +63,9 @@ export default class ReadOnlyTextTypeWidget extends AbstractTextTypeWidget { | ||||
|         this.$content = this.$widget.find('.note-detail-readonly-text-content'); | ||||
|  | ||||
|         this.$widget.find('.edit-text-note-button').on('click', () => { | ||||
|             this.tabContext.textPreviewDisabled = true; | ||||
|             this.noteContext.textPreviewDisabled = true; | ||||
|  | ||||
|             this.triggerEvent('textPreviewDisabled', {tabContext: this.tabContext}); | ||||
|             this.triggerEvent('textPreviewDisabled', {noteContext: this.noteContext}); | ||||
|         }); | ||||
|  | ||||
|         this.setupImageOpening(true); | ||||
|   | ||||
| @@ -246,7 +246,7 @@ export default class RelationMapTypeWidget extends TypeWidget { | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         const noteComplement = await this.tabContext.getNoteComplement(); | ||||
|         const noteComplement = await this.noteContext.getNoteComplement(); | ||||
|  | ||||
|         if (noteComplement.content) { | ||||
|             try { | ||||
|   | ||||
| @@ -38,7 +38,7 @@ export default class RenderTypeWidget extends TypeWidget { | ||||
|     } | ||||
|  | ||||
|     renderActiveNoteEvent() { | ||||
|         if (this.tabContext.isActive()) { | ||||
|         if (this.noteContext.isActive()) { | ||||
|             this.refresh(); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -23,7 +23,7 @@ export default class TypeWidget extends TabAwareWidget { | ||||
|  | ||||
|             await this.doRefresh(this.note); | ||||
|  | ||||
|             this.triggerEvent('noteDetailRefreshed', {tabId: this.tabContext.tabId}); | ||||
|             this.triggerEvent('noteDetailRefreshed', {ntxId: this.noteContext.ntxId}); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -35,14 +35,14 @@ export default class TypeWidget extends TabAwareWidget { | ||||
|  | ||||
|     focus() {} | ||||
|  | ||||
|     textPreviewDisabledEvent({tabContext}) { | ||||
|         if (this.isTab(tabContext.tabId)) { | ||||
|     textPreviewDisabledEvent({noteContext}) { | ||||
|         if (this.isTab(noteContext.ntxId)) { | ||||
|             this.refresh(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     codePreviewDisabledEvent({tabContext}) { | ||||
|         if (this.isTab(tabContext.tabId)) { | ||||
|     codePreviewDisabledEvent({noteContext}) { | ||||
|         if (this.isTab(noteContext.ntxId)) { | ||||
|             this.refresh(); | ||||
|         } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user