| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | import Component from "../widgets/component.js"; | 
					
						
							|  |  |  | import SpacedUpdate from "./spaced_update.js"; | 
					
						
							|  |  |  | import server from "./server.js"; | 
					
						
							|  |  |  | import options from "./options.js"; | 
					
						
							|  |  |  | import treeCache from "./tree_cache.js"; | 
					
						
							|  |  |  | import treeService from "./tree.js"; | 
					
						
							|  |  |  | import utils from "./utils.js"; | 
					
						
							|  |  |  | import TabContext from "./tab_context.js"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default class TabManager extends Component { | 
					
						
							| 
									
										
										
										
											2020-02-27 10:03:14 +01:00
										 |  |  |     constructor() { | 
					
						
							|  |  |  |         super(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.activeTabId = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.tabsUpdate = new SpacedUpdate(async () => { | 
					
						
							|  |  |  |             const openTabs = this.tabContexts | 
					
						
							|  |  |  |                 .map(tc => tc.getTabState()) | 
					
						
							|  |  |  |                 .filter(t => !!t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             await server.put('options', { | 
					
						
							|  |  |  |                 openTabs: JSON.stringify(openTabs) | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |     /** @type {TabContext[]} */ | 
					
						
							|  |  |  |     get tabContexts() { | 
					
						
							|  |  |  |         return this.children; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     async loadTabs() { | 
					
						
							|  |  |  |         const openTabs = options.getJson('openTabs') || []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         await treeCache.initializedPromise; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // if there's notePath in the URL, make sure it's open and active
 | 
					
						
							|  |  |  |         // (useful, among others, for opening clipped notes from clipper)
 | 
					
						
							|  |  |  |         if (window.location.hash) { | 
					
						
							|  |  |  |             const notePath = window.location.hash.substr(1); | 
					
						
							|  |  |  |             const noteId = treeService.getNoteIdFromNotePath(notePath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (noteId && await treeCache.noteExists(noteId)) { | 
					
						
							|  |  |  |                 for (const tab of openTabs) { | 
					
						
							|  |  |  |                     tab.active = false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 const foundTab = openTabs.find(tab => noteId === treeService.getNoteIdFromNotePath(tab.notePath)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (foundTab) { | 
					
						
							|  |  |  |                     foundTab.active = true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     openTabs.push({ | 
					
						
							|  |  |  |                         notePath: notePath, | 
					
						
							|  |  |  |                         active: true | 
					
						
							|  |  |  |                     }); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let filteredTabs = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const openTab of openTabs) { | 
					
						
							|  |  |  |             const noteId = treeService.getNoteIdFromNotePath(openTab.notePath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (await treeCache.noteExists(noteId)) { | 
					
						
							|  |  |  |                 // note doesn't exist so don't try to open tab for it
 | 
					
						
							|  |  |  |                 filteredTabs.push(openTab); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (utils.isMobile()) { | 
					
						
							|  |  |  |             // mobile frontend doesn't have tabs so show only the active tab
 | 
					
						
							|  |  |  |             filteredTabs = filteredTabs.filter(tab => tab.active); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (filteredTabs.length === 0) { | 
					
						
							|  |  |  |             filteredTabs.push({ | 
					
						
							|  |  |  |                 notePath: 'root', | 
					
						
							|  |  |  |                 active: true | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!filteredTabs.find(tab => tab.active)) { | 
					
						
							|  |  |  |             filteredTabs[0].active = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-08 21:23:42 +01:00
										 |  |  |         await this.tabsUpdate.allowUpdateWithoutChange(async () => { | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |             for (const tab of filteredTabs) { | 
					
						
							| 
									
										
										
										
											2020-02-27 12:26:42 +01:00
										 |  |  |                 await this.openTabWithNote(tab.notePath, tab.active, tab.tabId); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 13:40:46 +01:00
										 |  |  |     tabNoteSwitchedEvent({tabContext}) { | 
					
						
							|  |  |  |         if (tabContext.isActive()) { | 
					
						
							| 
									
										
										
										
											2020-02-08 21:23:42 +01:00
										 |  |  |             this.setCurrentNotePathToHash(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-02-08 21:23:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.tabsUpdate.scheduleUpdate(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-08 21:23:42 +01:00
										 |  |  |     setCurrentNotePathToHash() { | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         const activeTabContext = this.getActiveTabContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |         if (activeTabContext | 
					
						
							|  |  |  |             && activeTabContext.notePath !== treeService.getHashValueFromAddress()) { | 
					
						
							|  |  |  |             const url = '#' + (activeTabContext.notePath || "") + "-" + activeTabContext.tabId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // using pushState instead of directly modifying document.location because it does not trigger hashchange
 | 
					
						
							|  |  |  |             window.history.pushState(null, "", url); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             document.title = "Trilium Notes"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (activeTabContext.note) { | 
					
						
							|  |  |  |                 // it helps navigating in history if note title is included in the title
 | 
					
						
							|  |  |  |                 document.title += " - " + activeTabContext.note.title; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @return {TabContext[]} */ | 
					
						
							|  |  |  |     getTabContexts() { | 
					
						
							|  |  |  |         return this.tabContexts; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @returns {TabContext} */ | 
					
						
							|  |  |  |     getTabContextById(tabId) { | 
					
						
							|  |  |  |         return this.tabContexts.find(tc => tc.tabId === tabId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @returns {TabContext} */ | 
					
						
							|  |  |  |     getActiveTabContext() { | 
					
						
							|  |  |  |         return this.getTabContextById(this.activeTabId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @returns {string|null} */ | 
					
						
							|  |  |  |     getActiveTabNotePath() { | 
					
						
							|  |  |  |         const activeContext = this.getActiveTabContext(); | 
					
						
							|  |  |  |         return activeContext ? activeContext.notePath : null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @return {NoteShort} */ | 
					
						
							|  |  |  |     getActiveTabNote() { | 
					
						
							|  |  |  |         const activeContext = this.getActiveTabContext(); | 
					
						
							|  |  |  |         return activeContext ? activeContext.note : null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @return {string|null} */ | 
					
						
							|  |  |  |     getActiveTabNoteId() { | 
					
						
							|  |  |  |         const activeNote = this.getActiveTabNote(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return activeNote ? activeNote.noteId : null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @return {string|null} */ | 
					
						
							|  |  |  |     getActiveTabNoteType() { | 
					
						
							|  |  |  |         const activeNote = this.getActiveTabNote(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return activeNote ? activeNote.type : null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async switchToTab(tabId, notePath) { | 
					
						
							|  |  |  |         const tabContext = this.tabContexts.find(tc => tc.tabId === tabId) | 
					
						
							| 
									
										
										
										
											2020-02-29 16:26:46 +01:00
										 |  |  |             || await this.openEmptyTab(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.activateTab(tabContext.tabId); | 
					
						
							|  |  |  |         await tabContext.setNote(notePath); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async openAndActivateEmptyTab() { | 
					
						
							| 
									
										
										
										
											2020-02-29 16:26:46 +01:00
										 |  |  |         const tabContext = await this.openEmptyTab(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         await this.activateTab(tabContext.tabId); | 
					
						
							| 
									
										
										
										
											2020-02-28 11:46:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         await tabContext.setEmpty(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-29 16:26:46 +01:00
										 |  |  |     async openEmptyTab(tabId) { | 
					
						
							| 
									
										
										
										
											2020-02-27 10:03:14 +01:00
										 |  |  |         const tabContext = new TabContext(tabId); | 
					
						
							|  |  |  |         this.child(tabContext); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-06 22:17:07 +01:00
										 |  |  |         await this.triggerEvent('newTabOpened', {tabContext}); | 
					
						
							| 
									
										
										
										
											2020-02-27 10:03:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         return tabContext; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-27 12:26:42 +01:00
										 |  |  |     async openTabWithNote(notePath, activate, tabId = null) { | 
					
						
							| 
									
										
										
										
											2020-02-29 16:26:46 +01:00
										 |  |  |         const tabContext = await this.openEmptyTab(tabId); | 
					
						
							| 
									
										
										
										
											2020-02-27 12:26:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         await tabContext.setNote(notePath, !activate); // if activate is false then send normal noteSwitched event
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (activate) { | 
					
						
							|  |  |  |             this.activateTab(tabContext.tabId, false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 00:31:12 +01:00
										 |  |  |             this.triggerEvent('tabNoteSwitchedAndActivated', { | 
					
						
							| 
									
										
										
										
											2020-03-07 13:40:46 +01:00
										 |  |  |                 tabContext, | 
					
						
							| 
									
										
										
										
											2020-02-28 00:31:12 +01:00
										 |  |  |                 notePath | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2020-02-27 12:26:42 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     async activateOrOpenNote(noteId) { | 
					
						
							|  |  |  |         for (const tabContext of this.getTabContexts()) { | 
					
						
							|  |  |  |             if (tabContext.note && tabContext.note.noteId === noteId) { | 
					
						
							|  |  |  |                 await tabContext.activate(); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // if no tab with this note has been found we'll create new tab
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-29 16:26:46 +01:00
										 |  |  |         await this.openTabWithNote(noteId); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-27 12:26:42 +01:00
										 |  |  |     activateTab(tabId, triggerEvent = true) { | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         if (tabId === this.activeTabId) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.activeTabId = tabId; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-27 12:26:42 +01:00
										 |  |  |         if (triggerEvent) { | 
					
						
							| 
									
										
										
										
											2020-03-07 13:40:46 +01:00
										 |  |  |             this.triggerEvent('activeTabChanged', { | 
					
						
							|  |  |  |                 tabContext: this.getTabContextById(tabId) | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2020-02-27 12:26:42 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-02-08 21:23:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.tabsUpdate.scheduleUpdate(); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         this.setCurrentNotePathToHash(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async removeTab(tabId) { | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |         const tabContextToRemove = this.getTabContextById(tabId); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!tabContextToRemove) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:21:17 +01:00
										 |  |  |         await this.triggerEvent('beforeTabRemove', {tabId}, true); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |         if (this.tabContexts.length <= 1) { | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |             this.openAndActivateEmptyTab(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-02-25 12:32:21 +01:00
										 |  |  |         else if (tabContextToRemove.isActive()) { | 
					
						
							|  |  |  |             this.activateNextTabCommand(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |         this.children = this.children.filter(tc => tc.tabId !== tabId); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:21:17 +01:00
										 |  |  |         this.triggerEvent('tabRemoved', {tabId}); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-08 21:23:42 +01:00
										 |  |  |         this.tabsUpdate.scheduleUpdate(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:23:49 +01:00
										 |  |  |     tabReorderEvent({tabIdsInOrder}) { | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         const order = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const i in tabIdsInOrder) { | 
					
						
							|  |  |  |             order[tabIdsInOrder[i]] = i; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |         this.children.sort((a, b) => order[a.tabId] < order[b.tabId] ? -1 : 1); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-08 21:23:42 +01:00
										 |  |  |         this.tabsUpdate.scheduleUpdate(); | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:54:11 +01:00
										 |  |  |     activateNextTabCommand() { | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId); | 
					
						
							|  |  |  |         const newActiveTabId = this.tabContexts[oldIdx === this.tabContexts.length - 1 ? 0 : oldIdx + 1].tabId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.activateTab(newActiveTabId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:54:11 +01:00
										 |  |  |     activatePreviousTabCommand() { | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         const oldIdx = this.tabContexts.findIndex(tc => tc.tabId === this.activeTabId); | 
					
						
							|  |  |  |         const newActiveTabId = this.tabContexts[oldIdx === 0 ? this.tabContexts.length - 1 : oldIdx - 1].tabId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.activateTab(newActiveTabId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:54:11 +01:00
										 |  |  |     closeActiveTabCommand() { | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         this.removeTab(this.activeTabId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:23:49 +01:00
										 |  |  |     beforeUnloadEvent() { | 
					
						
							| 
									
										
										
										
											2020-02-08 20:53:07 +01:00
										 |  |  |         this.tabsUpdate.updateNowIfNecessary(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:54:11 +01:00
										 |  |  |     openNewTabCommand() { | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |         this.openAndActivateEmptyTab(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:54:11 +01:00
										 |  |  |     async removeAllTabsCommand() { | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |         for (const tabIdToRemove of this.tabContexts.map(tc => tc.tabId)) { | 
					
						
							|  |  |  |             await this.removeTab(tabIdToRemove); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:54:11 +01:00
										 |  |  |     async removeAllTabsExceptForThisCommand({tabId}) { | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |         for (const tabIdToRemove of this.tabContexts.map(tc => tc.tabId)) { | 
					
						
							|  |  |  |             if (tabIdToRemove !== tabId) { | 
					
						
							|  |  |  |                 await this.removeTab(tabIdToRemove); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 19:23:49 +01:00
										 |  |  |     async hoistedNoteChangedEvent({hoistedNoteId}) { | 
					
						
							| 
									
										
										
										
											2020-02-09 21:13:05 +01:00
										 |  |  |         if (hoistedNoteId === 'root') { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const tc of this.tabContexts.splice()) { | 
					
						
							|  |  |  |             if (tc.notePath && !tc.notePath.split("/").includes(hoistedNoteId)) { | 
					
						
							|  |  |  |                 await this.removeTab(tc.tabId); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-02-07 21:08:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } |