diff --git a/src/ZenViewSplitter.mjs b/src/ZenViewSplitter.mjs index eb91dbe..3dafe84 100644 --- a/src/ZenViewSplitter.mjs +++ b/src/ZenViewSplitter.mjs @@ -1,57 +1,101 @@ -var gZenViewSplitter = { +var gZenViewSplitter = new class { + constructor() { + this._data = []; + this.currentView = -1; + this._tabBrowserPanel = null; + this.__modifierElement = null; + this.__hasSetMenuListener = false; + + window.addEventListener("TabClose", this.handleTabClose.bind(this)); + this.initializeContextMenu(); + this.insertPageActionButton(); + } + /** - * [ - * { - * tabs: [ - * tab1, - * tab2, - * tab3, - * ], - * gridType: "vsep" | "hsep" | "grid", - * } - * ] + * @param {Event} event - The event that triggered the tab close. + * @description Handles the tab close event.7 */ - _data: [], - currentView: -1, + handleTabClose(event) { + const tab = event.target; + const groupIndex = this._data.findIndex(group => group.tabs.includes(tab)); + if (groupIndex < 0) { + return; + } + this.removeTabFromGroup(tab, groupIndex, event.forUnsplit); + } - init() { - window.addEventListener("TabClose", this); - this.initializeUI(); - console.log("ZenViewSplitter initialized"); - }, + /** + * Removes a tab from a group. + * + * @param {Tab} tab - The tab to remove. + * @param {number} groupIndex - The index of the group. + * @param {boolean} forUnsplit - Indicates if the tab is being removed for unsplitting. + */ + removeTabFromGroup(tab, groupIndex, forUnsplit) { + const group = this._data[groupIndex]; + const tabIndex = group.tabs.indexOf(tab); + group.tabs.splice(tabIndex, 1); - initializeUI() { - this.insertIntoContextMenu(); - this.initializeUpdateContextMenuItems(); - this.initializeTabContextMenu(); - this.initializeZenSplitBox(); - }, + this.resetTabState(tab, forUnsplit); - initializeZenSplitBox() { - const fragment = window.MozXULElement.parseXULToFragment(` - `); - document.getElementById("star-button-box").after(fragment); - }, + if (group.tabs.length < 2) { + this.removeGroup(groupIndex); + } else { + this.updateSplitView(group.tabs[group.tabs.length - 1]); + } + } - initializeTabContextMenu() { - const fragment = window.MozXULElement.parseXULToFragment(` - - - `); - document.getElementById("tabContextMenu").appendChild(fragment); - }, + /** + * Resets the state of a tab. + * + * @param {Tab} tab - The tab to reset. + * @param {boolean} forUnsplit - Indicates if the tab is being reset for unsplitting. + */ + resetTabState(tab, forUnsplit) { + tab.splitView = false; + tab.linkedBrowser.zenModeActive = false; + const container = tab.linkedBrowser.closest(".browserSidebarContainer"); + container.removeAttribute("zen-split"); + container.removeAttribute("style"); - initializeUpdateContextMenuItems() { + if (!forUnsplit) { + tab.linkedBrowser.docShellIsActive = false; + } else { + container.style.gridArea = "1 / 1"; + } + } + + /** + * Removes a group. + * + * @param {number} groupIndex - The index of the group to remove. + */ + removeGroup(groupIndex) { + if (this.currentView === groupIndex) { + this.resetSplitView(); + } + this._data.splice(groupIndex, 1); + } + + /** + * Resets the split view. + */ + resetSplitView() { + for (const tab of this._data[this.currentView].tabs) { + this.resetTabState(tab, true); + } + + this.currentView = -1; + this.tabBrowserPanel.removeAttribute("zen-split-view"); + this.tabBrowserPanel.style.gridTemplateAreas = ""; + this.tabBrowserPanel.style.gridGap = "0px"; + } + + /** + * context menu item display update + */ + insetUpdateContextMenuItems() { const contentAreaContextMenu = document.getElementById("tabContextMenu"); contentAreaContextMenu.addEventListener("popupshowing", () => { const tabCountInfo = JSON.stringify({ @@ -63,283 +107,477 @@ var gZenViewSplitter = { document.getElementById("context_zenSplitTabs").disabled = !this.contextCanSplitTabs(); }); - }, + } - handleEvent(event) { - switch (event.type) { - case "TabClose": - this.onTabClose(event); - } - }, + /** + * Inserts the split link into the context menu. + */ + insertSplitLinkIntoContextMenu() { + const element = window.MozXULElement.parseXULToFragment(` +