| 
									
										
										
										
											2020-01-11 21:19:56 +01:00
										 |  |  | import GlobalButtonsWidget from "../widgets/global_buttons.js"; | 
					
						
							|  |  |  | import SearchBoxWidget from "../widgets/search_box.js"; | 
					
						
							|  |  |  | import SearchResultsWidget from "../widgets/search_results.js"; | 
					
						
							|  |  |  | import NoteTreeWidget from "../widgets/note_tree.js"; | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  | import treeService from "./tree.js"; | 
					
						
							|  |  |  | import noteDetailService from "./note_detail.js"; | 
					
						
							|  |  |  | import TabContext from "./tab_context.js"; | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  | import server from "./server.js"; | 
					
						
							|  |  |  | import keyboardActionService from "./keyboard_actions.js"; | 
					
						
							| 
									
										
										
										
											2020-01-14 21:52:18 +01:00
										 |  |  | import TabRowWidget from "../widgets/tab_row.js"; | 
					
						
							| 
									
										
										
										
											2020-01-12 23:03:55 +01:00
										 |  |  | import NoteTitleWidget from "../widgets/note_title.js"; | 
					
						
							| 
									
										
										
										
											2020-01-13 20:25:56 +01:00
										 |  |  | import PromotedAttributesWidget from "../widgets/promoted_attributes.js"; | 
					
						
							| 
									
										
										
										
											2020-01-13 21:48:44 +01:00
										 |  |  | import NoteDetailWidget from "../widgets/note_detail.js"; | 
					
						
							| 
									
										
										
										
											2020-01-14 20:27:40 +01:00
										 |  |  | import TabCachingWidget from "../widgets/tab_caching_widget.js"; | 
					
						
							| 
									
										
										
										
											2020-01-14 21:23:32 +01:00
										 |  |  | import NoteInfoWidget from "../widgets/note_info.js"; | 
					
						
							|  |  |  | import NoteRevisionsWidget from "../widgets/note_revisions.js"; | 
					
						
							|  |  |  | import LinkMapWidget from "../widgets/link_map.js"; | 
					
						
							|  |  |  | import SimilarNotesWidget from "../widgets/similar_notes.js"; | 
					
						
							|  |  |  | import WhatLinksHereWidget from "../widgets/what_links_here.js"; | 
					
						
							|  |  |  | import AttributesWidget from "../widgets/attributes.js"; | 
					
						
							| 
									
										
										
										
											2020-01-15 19:40:17 +01:00
										 |  |  | import TitleBarButtonsWidget from "../widgets/title_bar_buttons.js"; | 
					
						
							|  |  |  | import GlobalMenuWidget from "../widgets/global_menu.js"; | 
					
						
							| 
									
										
										
										
											2020-01-15 21:36:01 +01:00
										 |  |  | import RowFlexContainer from "../widgets/row_flex_container.js"; | 
					
						
							| 
									
										
										
										
											2020-01-15 20:10:54 +01:00
										 |  |  | import StandardTopWidget from "../widgets/standard_top_widget.js"; | 
					
						
							| 
									
										
										
										
											2020-01-15 21:36:01 +01:00
										 |  |  | import treeCache from "./tree_cache.js"; | 
					
						
							|  |  |  | import treeUtils from "./tree_utils.js"; | 
					
						
							| 
									
										
										
										
											2020-01-11 21:19:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 09:57:28 +01:00
										 |  |  | class AppContext { | 
					
						
							| 
									
										
										
										
											2020-01-11 21:19:56 +01:00
										 |  |  |     constructor() { | 
					
						
							|  |  |  |         this.widgets = []; | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  |         /** @type {TabContext[]} */ | 
					
						
							|  |  |  |         this.tabContexts = []; | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  |         this.tabsChangedTaskId = null; | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         /** @type {TabRowWidget} */ | 
					
						
							|  |  |  |         this.tabRow = null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     showWidgets() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.tabRow = new TabRowWidget(this); | 
					
						
							| 
									
										
										
										
											2020-01-12 20:15:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-15 20:10:54 +01:00
										 |  |  |         const topPaneWidgets = [ | 
					
						
							| 
									
										
										
										
											2020-01-15 21:36:01 +01:00
										 |  |  |             new RowFlexContainer(this, [ | 
					
						
							| 
									
										
										
										
											2020-01-15 20:10:54 +01:00
										 |  |  |                 new GlobalMenuWidget(this), | 
					
						
							|  |  |  |                 this.tabRow, | 
					
						
							|  |  |  |                 new TitleBarButtonsWidget(this) | 
					
						
							|  |  |  |             ]), | 
					
						
							|  |  |  |             new StandardTopWidget(this) | 
					
						
							| 
									
										
										
										
											2020-01-15 19:40:17 +01:00
										 |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-15 20:10:54 +01:00
										 |  |  |         const $topPane = $("#top-pane"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const widget of topPaneWidgets) { | 
					
						
							|  |  |  |             widget.renderTo($topPane); | 
					
						
							| 
									
										
										
										
											2020-01-15 19:40:17 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const $leftPane = $("#left-pane"); | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.noteTreeWidget = new NoteTreeWidget(this); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-13 21:48:44 +01:00
										 |  |  |         const leftPaneWidgets = [ | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |             new GlobalButtonsWidget(this), | 
					
						
							|  |  |  |             new SearchBoxWidget(this), | 
					
						
							|  |  |  |             new SearchResultsWidget(this), | 
					
						
							|  |  |  |             this.noteTreeWidget | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-13 21:48:44 +01:00
										 |  |  |         for (const widget of leftPaneWidgets) { | 
					
						
							| 
									
										
										
										
											2020-01-14 20:27:40 +01:00
										 |  |  |             widget.renderTo($leftPane); | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-01-12 23:03:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-13 21:48:44 +01:00
										 |  |  |         const $centerPane = $("#center-pane"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const centerPaneWidgets = [ | 
					
						
							| 
									
										
										
										
											2020-01-14 20:27:40 +01:00
										 |  |  |             new TabCachingWidget(this, () => new NoteTitleWidget(this)), | 
					
						
							|  |  |  |             new TabCachingWidget(this, () => new PromotedAttributesWidget(this)), | 
					
						
							|  |  |  |             new TabCachingWidget(this, () => new NoteDetailWidget(this)) | 
					
						
							| 
									
										
										
										
											2020-01-13 21:48:44 +01:00
										 |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const widget of centerPaneWidgets) { | 
					
						
							| 
									
										
										
										
											2020-01-14 20:27:40 +01:00
										 |  |  |             widget.renderTo($centerPane); | 
					
						
							| 
									
										
										
										
											2020-01-13 21:48:44 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-14 21:23:32 +01:00
										 |  |  |         const $rightPane = $("#right-pane"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const rightPaneWidgets = [ | 
					
						
							|  |  |  |             new NoteInfoWidget(this), | 
					
						
							|  |  |  |             new TabCachingWidget(this, () => new AttributesWidget(this)), | 
					
						
							|  |  |  |             new TabCachingWidget(this, () => new LinkMapWidget(this)), | 
					
						
							|  |  |  |             new TabCachingWidget(this, () => new NoteRevisionsWidget(this)), | 
					
						
							|  |  |  |             new TabCachingWidget(this, () => new SimilarNotesWidget(this)), | 
					
						
							|  |  |  |             new TabCachingWidget(this, () => new WhatLinksHereWidget(this)), | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const widget of rightPaneWidgets) { | 
					
						
							|  |  |  |             widget.renderTo($rightPane); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-13 21:48:44 +01:00
										 |  |  |         this.widgets = [ | 
					
						
							|  |  |  |             this.tabRow, | 
					
						
							|  |  |  |             ...leftPaneWidgets, | 
					
						
							| 
									
										
										
										
											2020-01-14 21:23:32 +01:00
										 |  |  |             ...centerPaneWidgets, | 
					
						
							|  |  |  |             ...rightPaneWidgets | 
					
						
							| 
									
										
										
										
											2020-01-13 21:48:44 +01:00
										 |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2020-01-11 21:19:56 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     trigger(name, data) { | 
					
						
							| 
									
										
										
										
											2020-01-12 23:03:55 +01:00
										 |  |  |         this.eventReceived(name, data); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-15 21:36:01 +01:00
										 |  |  |         for (const tabContext of this.tabContexts) { | 
					
						
							|  |  |  |             tabContext.eventReceived(name, data); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-11 21:19:56 +01:00
										 |  |  |         for (const widget of this.widgets) { | 
					
						
							|  |  |  |             widget.eventReceived(name, data); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 23:03:55 +01:00
										 |  |  |     eventReceived(name, data) { | 
					
						
							|  |  |  |         const fun = this[name + 'Listener']; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (typeof fun === 'function') { | 
					
						
							|  |  |  |             fun.call(this, data); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-15 21:36:01 +01:00
										 |  |  |     activateNote(notePath) { | 
					
						
							|  |  |  |         const activeTabContext = this.getActiveTabContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         activeTabContext.setNote(notePath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this._setTitleBar(); | 
					
						
							|  |  |  |         this._setCurrentNotePathToHash(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _setCurrentNotePathToHash() { | 
					
						
							|  |  |  |         const activeTabContext = this.getActiveTabContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (activeTabContext && activeTabContext.notePath) { | 
					
						
							|  |  |  |             document.location.hash = (activeTabContext.notePath || "") + "-" + activeTabContext.tabId; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async _setTitleBar() { | 
					
						
							|  |  |  |         document.title = "Trilium Notes"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const activeTabContext = this.getActiveTabContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (activeTabContext && activeTabContext.notePath) { | 
					
						
							|  |  |  |             const note = await treeCache.getNote(treeUtils.getNoteIdFromNotePath(activeTabContext.notePath)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // it helps navigating in history if note title is included in the title
 | 
					
						
							|  |  |  |             document.title += " - " + note.title; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  |     /** @return {TabContext[]} */ | 
					
						
							|  |  |  |     getTabContexts() { | 
					
						
							|  |  |  |         return this.tabContexts; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @returns {TabContext} */ | 
					
						
							|  |  |  |     getActiveTabContext() { | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         const activeTabEl = this.tabRow.activeTabEl; | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!activeTabEl) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const tabId = activeTabEl.getAttribute('data-tab-id'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return this.tabContexts.find(tc => tc.tabId === tabId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @returns {string|null} */ | 
					
						
							|  |  |  |     getActiveTabNotePath() { | 
					
						
							|  |  |  |         const activeContext = this.getActiveTabContext(); | 
					
						
							|  |  |  |         return activeContext ? activeContext.notePath : null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @return {NoteFull} */ | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!tabContext) { | 
					
						
							|  |  |  |             await noteDetailService.loadNoteDetail(notePath, { | 
					
						
							|  |  |  |                 newTab: true, | 
					
						
							|  |  |  |                 activate: true | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             await tabContext.activate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (notePath && tabContext.notePath !== notePath) { | 
					
						
							|  |  |  |                 await treeService.activateNote(notePath); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async showTab(tabId) { | 
					
						
							|  |  |  |         for (const ctx of this.tabContexts) { | 
					
						
							|  |  |  |             if (ctx.tabId === tabId) { | 
					
						
							|  |  |  |                 await ctx.show(); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 ctx.hide(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const oldActiveNode = this.getMainNoteTree().getActiveNode(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (oldActiveNode) { | 
					
						
							|  |  |  |             oldActiveNode.setActive(false); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const newActiveTabContext = this.getActiveTabContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (newActiveTabContext && newActiveTabContext.notePath) { | 
					
						
							|  |  |  |             const newActiveNode = await this.getMainNoteTree().getNodeFromPath(newActiveTabContext.notePath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (newActiveNode) { | 
					
						
							|  |  |  |                 if (!newActiveNode.isVisible()) { | 
					
						
							|  |  |  |                     await this.getMainNoteTree().expandToNote(newActiveTabContext.notePath); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 newActiveNode.setActive(true, {noEvents: true}); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 11:15:23 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @return {NoteTreeWidget} | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     getMainNoteTree() { | 
					
						
							|  |  |  |         return this.noteTreeWidget; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     getTab(newTab, state) { | 
					
						
							|  |  |  |         if (!this.getActiveTabContext() || newTab) { | 
					
						
							|  |  |  |             // if it's a new tab explicitly by user then it's in background
 | 
					
						
							| 
									
										
										
										
											2020-01-15 21:36:01 +01:00
										 |  |  |             const ctx = new TabContext(this, this.tabRow, state); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  |             this.tabContexts.push(ctx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return ctx; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             return this.getActiveTabContext(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async reloadAllTabs() { | 
					
						
							|  |  |  |         for (const tabContext of this.tabContexts) { | 
					
						
							|  |  |  |             await this.reloadTab(tabContext); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async refreshTabs(sourceTabId, noteId) { | 
					
						
							|  |  |  |         for (const tc of this.tabContexts) { | 
					
						
							|  |  |  |             if (tc.noteId === noteId && tc.tabId !== sourceTabId) { | 
					
						
							|  |  |  |                 await this.reloadTab(tc); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async reloadTab(tc) { | 
					
						
							|  |  |  |         if (tc.note) { | 
					
						
							|  |  |  |             noteDetailService.reloadNote(tc); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async openEmptyTab() { | 
					
						
							| 
									
										
										
										
											2020-01-15 21:36:01 +01:00
										 |  |  |         const ctx = new TabContext(this, this.tabRow); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  |         this.tabContexts.push(ctx); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         await this.tabRow.activateTab(ctx.$tab[0]); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     async filterTabs(noteId) { | 
					
						
							|  |  |  |         for (const tc of this.tabContexts) { | 
					
						
							|  |  |  |             if (tc.notePath && !tc.notePath.split("/").includes(noteId)) { | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |                 await this.tabRow.removeTab(tc.$tab[0]); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (this.tabContexts.length === 0) { | 
					
						
							|  |  |  |             this.openEmptyTab() | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         await this.saveOpenTabs(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async saveOpenTabs() { | 
					
						
							|  |  |  |         const openTabs = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         for (const tabEl of this.tabRow.tabEls) { | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  |             const tabId = tabEl.getAttribute('data-tab-id'); | 
					
						
							|  |  |  |             const tabContext = appContext.getTabContexts().find(tc => tc.tabId === tabId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (tabContext) { | 
					
						
							|  |  |  |                 const tabState = tabContext.getTabState(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (tabState) { | 
					
						
							|  |  |  |                     openTabs.push(tabState); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         await server.put('options', { | 
					
						
							|  |  |  |             openTabs: JSON.stringify(openTabs) | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     clearOpenTabsTask() { | 
					
						
							|  |  |  |         if (this.tabsChangedTaskId) { | 
					
						
							|  |  |  |             clearTimeout(this.tabsChangedTaskId); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     openTabsChanged() { | 
					
						
							|  |  |  |         // we don't want to send too many requests with tab changes so we always schedule task to do this in 1 seconds,
 | 
					
						
							|  |  |  |         // but if there's any change in between, we cancel the old one and schedule new one
 | 
					
						
							|  |  |  |         // so effectively we kind of wait until user stopped e.g. quickly switching tabs
 | 
					
						
							|  |  |  |         this.clearOpenTabsTask(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.tabsChangedTaskId = setTimeout(() => this.saveOpenTabs(), 1000); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-12 09:57:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 20:15:05 +01:00
										 |  |  |     async activateTab(tabContext) { | 
					
						
							|  |  |  |         return this.tabRow.activateTab(tabContext.$tab[0]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |     newTabListener() { | 
					
						
							|  |  |  |         this.openEmptyTab(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-12 09:57:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |     async activeTabChangedListener({tabEl}) { | 
					
						
							|  |  |  |         const tabId = tabEl.getAttribute('data-tab-id'); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         await this.showTab(tabId); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |     async tabRemoveListener({tabEl}) { | 
					
						
							|  |  |  |         const tabId = tabEl.getAttribute('data-tab-id'); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         this.tabContexts.filter(nc => nc.tabId === tabId) | 
					
						
							|  |  |  |             .forEach(tc => tc.remove()); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         this.tabContexts = this.tabContexts.filter(nc => nc.tabId !== tabId); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         if (this.tabContexts.length === 0) { | 
					
						
							|  |  |  |             this.openEmptyTab(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         this.openTabsChanged(); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:30:30 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |     tabReorderListener() { | 
					
						
							|  |  |  |         this.openTabsChanged(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const appContext = new AppContext(); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | keyboardActionService.setGlobalActionHandler('OpenNewTab', () => { | 
					
						
							|  |  |  |     appContext.openEmptyTab(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | keyboardActionService.setGlobalActionHandler('CloseActiveTab', () => { | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |     if (this.tabRow.activeTabEl) { | 
					
						
							|  |  |  |         this.tabRow.removeTab(this.tabRow.activeTabEl); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | keyboardActionService.setGlobalActionHandler('ActivateNextTab', () => { | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |     const nextTab = this.tabRow.nextTabEl; | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (nextTab) { | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         this.tabRow.activateTab(nextTab); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | keyboardActionService.setGlobalActionHandler('ActivatePreviousTab', () => { | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |     const prevTab = this.tabRow.previousTabEl; | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (prevTab) { | 
					
						
							| 
									
										
										
										
											2020-01-12 19:05:09 +01:00
										 |  |  |         this.tabRow.activateTab(prevTab); | 
					
						
							| 
									
										
										
										
											2020-01-12 12:48:17 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 09:57:28 +01:00
										 |  |  | export default appContext; |