From 856de195c8433a63199a4bc067e9b7dcc485feff Mon Sep 17 00:00:00 2001 From: Mauro Balades Date: Tue, 6 Aug 2024 11:46:10 +0200 Subject: [PATCH] feat: Update splitViews module and split-views configuration --- .gitattributes | 2 +- @types/split-views.d.ts | 1 + README.md | 2 +- src/browser-splitViews.mjs | 122 ++++++++++++++++++++++++++++++------- 4 files changed, 102 insertions(+), 25 deletions(-) diff --git a/.gitattributes b/.gitattributes index 74f5f4a..40b88b3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -*.js linguist-language=TypeScript \ No newline at end of file +*.mjs linguist-language=TypeScript \ No newline at end of file diff --git a/@types/split-views.d.ts b/@types/split-views.d.ts index 2cb5ac5..839eba3 100644 --- a/@types/split-views.d.ts +++ b/@types/split-views.d.ts @@ -9,4 +9,5 @@ declare interface SplitViewConfig extends Config { declare interface SplitView { type: SplitType; tabs: MockedExports.BrowserTab[]; + id: number; }; diff --git a/README.md b/README.md index c8317ee..c797449 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Some components used by @zen-browser and @Floorp-Projects as an attempt to make ## Example usage ```js -import("chrome://../browser-splitView.mjs").then( +import("chrome://../browser-splitViews.mjs").then( ({ SplitViews }) => { window.gSplitView = new SplitViews({ splitIndicator: "zen-splitted", diff --git a/src/browser-splitViews.mjs b/src/browser-splitViews.mjs index d1a1bb0..28c119f 100644 --- a/src/browser-splitViews.mjs +++ b/src/browser-splitViews.mjs @@ -12,7 +12,7 @@ class SplitViewsBase { this.config = config; this.data = []; this.currentView = -1; - this.addEventListeners(); + this.globalIdCounter = 0; // Added to "navigator-toolbox" element this.parentSplitIndicator = this.config.splitIndicator + '-view'; this.log('SplitViewsBase initialized'); @@ -26,6 +26,100 @@ class SplitViewsBase { console.log(`SplitViews: ${message}`); } + get isActivated() { + return this.currentView !== -1; + } + + get activeView() { + if (!this.isActivated) { + throw new Error('No active view'); + } + return this.data[this.currentView]; + } + + /** + * @param {MockedExports.BrowserTab} tab + */ + getTabView(tab) { + return this.data.find(view => view.tabs.includes(tab)); + } + + /** + * @param {MockedExports.BrowserTab} tab + */ + isTabSplit(tab) { + return tab.hasAttribute(this.config.splitIndicator); + } + + /** + * @param {MockedExports.BrowserTab} tab + * @param {SplitType} type + * @param {MockedExports.BrowserTab[]} tabs + */ + changeSplitViewBase(tab, type, tabs) { + let view = this.getTabView(tab); + if (!view) { + return -1; + } + view.type = type; + view.tabs.push(...tabs.filter(t => !view.tabs.includes(t))); + return view.id; + } + + /** + * @param {MockedExports.BrowserTab[]} tabs + * @param {SplitType} type + */ + createSplitViewBase(tabs, type) { + let view = { + id: this.globalIdCounter++, + type, + tabs, + }; + this.data.push(view); + this.currentView = this.data.length - 1; + return view.id; + } + + /** + * @param {number} viewId + * @protected + */ + updateSplitView(viewId) { + let view = this.data.find(view => view.id === viewId); + if (!view) { + return; + } + // TODO: Update tab DOM here + } + + /** + * @param {MockedExports.BrowserTab[]} tabs + * @param {SplitType} type + * @protected + */ + createOrChangeSplitView(tabs, type) { + let activeTab = tabs.find(tab => this.isTabSplit(tab)); + let viewId = -1; + if (activeTab) { + viewId = this.changeSplitViewBase(activeTab, type, tabs); + } else { + viewId = this.createSplitViewBase(tabs, type); + } + this.updateSplitView(viewId); + } +} + +// Public API exposed by the module +export class SplitViews extends SplitViewsBase { + /** + * @param {SplitViewConfig} config + */ + constructor(config) { + super(config); + this.addEventListeners(); + } + addEventListeners() { window.addEventListener('TabClose', this); } @@ -47,27 +141,6 @@ class SplitViewsBase { onTabClose(event) { } - get isActivated() { - return this.currentView !== -1; - } - - get activeView() { - if (!this.isActivated) { - throw new Error('No active view'); - } - return this.data[this.currentView]; - } -} - -// Public API exposed by the module -export class SplitViews extends SplitViewsBase { - /** - * @param {SplitViewConfig} config - */ - constructor(config) { - super(config); - } - /** * @param {MockedExports.Browser} browser */ @@ -105,6 +178,9 @@ export class SplitViews extends SplitViewsBase { * @private */ createSplitView(tabs, type = this.config.defaultSplitView) { - this.log('createSplitView'); + if (tabs.length < 2) { + return; + } + this.createOrChangeSplitView(tabs, type); } };