Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
51248e7
initial
iamEvanYT May 24, 2025
3b7000d
tab
iamEvanYT May 26, 2025
478066d
feat: add destroyed state management to Tab class
iamEvanYT May 29, 2025
f7f2731
feat: tab manager
iamEvanYT Jun 1, 2025
9e6b9cb
feat: initial tabs orchestrator
iamEvanYT Jun 1, 2025
0289c78
feat: initial tab group implementation
iamEvanYT Jun 3, 2025
45b4d59
feat: add navigation history change event and enhance webview data ha…
iamEvanYT Jun 7, 2025
a797a45
feat: add TabGroupWindowController to TabGroup and update exports in …
iamEvanYT Jun 8, 2025
7e6357c
refactor: remove TabSpaceController from Tab and controllers
iamEvanYT Jun 8, 2025
fdd9175
feat: add asleep state management to TabDataController and update eve…
iamEvanYT Jun 8, 2025
df8c680
feat: enhance TabDataController with webview data handling and state …
iamEvanYT Jun 8, 2025
0d899bd
refactor: streamline property updates in TabDataController using a ge…
iamEvanYT Jun 8, 2025
6d7b7e4
refactor: remove spaceId from TabCreationOptions and related tab crea…
iamEvanYT Jun 8, 2025
81dfcb0
feat: add initial animation state management to TabBoundsController
iamEvanYT Jun 8, 2025
f26afcc
docs: add docs for tab-group
iamEvanYT Jul 5, 2025
f6114d0
docs: add docs for tab
iamEvanYT Jul 5, 2025
0e37eb3
feat: Tab Group Manager
iamEvanYT Jul 8, 2025
d0af10d
feat: Active Tab Group Manager
iamEvanYT Jul 9, 2025
a149746
chore: delete old tab system
iamEvanYT Jul 10, 2025
7fd5ba3
chore: move & reorganise files
iamEvanYT Jul 10, 2025
eaa1c24
feat: tab container
iamEvanYT Jul 11, 2025
a1304f2
feat: tab containers
iamEvanYT Jul 14, 2025
82d4816
idk
iamEvanYT Aug 26, 2025
88ff34f
idk2
iamEvanYT Aug 26, 2025
a39b65e
d
iamEvanYT Sep 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions docs/api/tabs/general.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Tabs General Documentation

## Success Creteria

- Have different active tab groups in different spaces
- Tabs in sidebar achievable
- Different tab groups in different places visible at once
- Have different containers in a Space ("Favourite", "Pinned", "Normal")

## Managers

- Tab Manager
- Tab Group Manager
- Active Tab Group Manager
- Tabs Container Manager

## Objects

- Tab
- Tab Group
- Tab Container

## TODO APIs

- TabGroup.transferTab() -> boolean (transfer tab to another tab group, true if success & false if failed)
- TabGroup.createTab() -> Tab (added to TabGroup automatically)
- TabContainer.newNormalTabGroup() -> NormalTabGroup (added to TabContainer automatically)

## How to:

### Create a new tab

1. Create a new tab group via TabContainer.newNormalTabGroup()
2. Create a new tab via TabGroup.createTab()

### Change a Tab Group's Tab Container

- **TODO!**

### Create a Tab Folder

1. Run TabContainer.createTabFolder()
253 changes: 253 additions & 0 deletions docs/api/tabs/tab-group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
# Tab Group API Documentation

## Overview

The Tab Group system provides a way to organize and manage collections of tabs within the Flow browser. Tab groups can contain multiple tabs and provide functionality for managing focus, window assignment, and tab lifecycle within the group.

## Core Components

### TabGroup Class

The main `TabGroup` class is the central component that orchestrates tab management through specialized controllers.

#### Constructor

```typescript
constructor(variant: TabGroupVariant, details: TabGroupCreationDetails)
```

Creates a new tab group with the specified variant and creation details.

#### Properties

- `id: string` - Unique identifier for the tab group
- `destroyed: boolean` - Whether the tab group has been destroyed
- `type: TabGroupTypes` - The type of tab group ("normal", "split", or "glance")
- `maxTabs: number` - Maximum number of tabs allowed in the group (-1 for unlimited)
- `creationDetails: TabGroupCreationDetails` - Details used to create the tab group
- `window: TabGroupWindowController` - Controller for managing the window
- `tabs: TabGroupTabsController` - Controller for managing tabs
- `focusedTab: TabGroupFocusedTabController` - Controller for managing focused tab

#### Methods

- `destroy()` - Destroys the tab group and cleans up all resources
- `throwIfDestroyed()` - Throws an error if the tab group has been destroyed

#### Events

The `TabGroup` class extends `TypedEventEmitter` and emits the following events:

- `"window-changed"` - Emitted when the tab group's window changes
- `"tab-added"` - Emitted when a tab is added to the group
- `"tab-removed"` - Emitted when a tab is removed from the group
- `"destroyed"` - Emitted when the tab group is destroyed

## Controllers

### TabGroupTabsController

Manages the collection of tabs within a tab group.

#### Methods

- `addTab(tab: Tab): boolean` - Adds a tab to the group

- Returns `false` if the tab is already in the group or would exceed maxTabs
- Sets up event listeners for tab lifecycle management
- Emits "tab-added" event

- `removeTab(tab: Tab): boolean` - Removes a tab from the group

- Returns `false` if the tab is not in the group
- Cleans up event listeners to prevent memory leaks
- Emits "tab-removed" event

- `get(): Tab[]` - Returns all tabs currently in the group

- Filters out destroyed tabs automatically

- `cleanupListeners()` - Cleans up all event listeners for all tabs

#### Behavior

- Automatically destroys the tab group when the last tab is removed
- Respects the `maxTabs` limit when adding tabs
- Maintains event listeners for tab destruction and focus events
- Provides O(1) tab lookup using internal Set data structure

### TabGroupFocusedTabController

Manages which tab is currently focused within the tab group.

#### Methods

- `set(tab: Tab): boolean` - Sets the focused tab

- Returns `false` if the tab is already focused
- Automatically removes the previous focused tab

- `remove(): boolean` - Removes the currently focused tab
- Returns `false` if no tab was focused

#### Behavior

- Automatically sets focus to the first tab when a tab is added to an empty group
- Automatically reassigns focus when the focused tab is removed
- Listens for "tab-added" and "tab-removed" events to manage focus

### TabGroupWindowController

Manages the window that contains the tab group.

#### Methods

- `get(): TabbedBrowserWindow` - Returns the current window
- `set(window: TabbedBrowserWindow): boolean` - Sets the window

- Returns `false` if the window is already set
- Emits "window-changed" event
- Updates all tabs in the group to use the new window

- `updateTabsWindow()` - Updates all tabs in the group to use the current window

## Types and Interfaces

### TabGroupTypes

```typescript
type TabGroupTypes = "normal" | "split" | "glance";
```

Defines the available tab group types:

- `"normal"` - Standard tab group with configurable tab limit
- `"split"` - Tab group designed for split-screen functionality
- `"glance"` - Tab group for quick preview/glance functionality

### TabGroupVariant

```typescript
interface TabGroupVariant {
type: TabGroupTypes;
maxTabs: number;
}
```

Specifies the variant configuration for a tab group:

- `type` - The type of tab group
- `maxTabs` - Maximum number of tabs allowed (-1 for unlimited)

### TabGroupCreationDetails

```typescript
interface TabGroupCreationDetails {
browser: Browser;
window: TabbedBrowserWindow;
spaceId: string;
}
```

Contains the details needed to create a tab group:

- `browser` - The browser instance that owns the tab group
- `window` - The initial window for the tab group
- `spaceId` - The space ID where the tab group belongs

## Specialized Tab Group Types

### NormalTabGroup

A specialized tab group that can only contain one tab.

```typescript
class NormalTabGroup extends TabGroup {
constructor(details: TabGroupCreationDetails) {
super({ type: "normal", maxTabs: 1 }, details);
}
}
```

## Usage Examples

### Creating a Tab Group

```typescript
import { TabGroup } from "@/browser/tabs/tab-group";

const tabGroup = new TabGroup(
{ type: "normal", maxTabs: 5 },
{
browser: browserInstance,
window: windowInstance,
spaceId: "space-123"
}
);
```

### Adding Tabs to a Group

```typescript
const success = tabGroup.tabs.addTab(tab);
if (success) {
console.log("Tab added successfully");
} else {
console.log("Failed to add tab (already exists or exceeds limit)");
}
```

### Listening for Events

```typescript
tabGroup.connect("tab-added", (tab) => {
console.log("Tab added:", tab.id);
});

tabGroup.connect("tab-removed", (tab) => {
console.log("Tab removed:", tab.id);
});

tabGroup.connect("window-changed", () => {
console.log("Window changed for tab group");
});
```

### Managing Focus

```typescript
// Set focused tab
tabGroup.focusedTab.set(tab);

// Remove focused tab
tabGroup.focusedTab.remove();
```

### Changing Window

```typescript
tabGroup.window.set(newWindow);
```

### Destroying a Tab Group

```typescript
tabGroup.destroy();
```

## Error Handling

The tab group system includes several error handling mechanisms:

- `throwIfDestroyed()` - Prevents operations on destroyed tab groups
- Event listener cleanup to prevent memory leaks
- Automatic filtering of destroyed tabs in `get()` method
- Graceful handling of tab limits in `addTab()`

## Implementation Notes

- Tab groups use a Set-based data structure for O(1) tab lookup performance
- Event listeners are automatically cleaned up when tabs are removed
- The system is designed to be memory-efficient and prevent leaks
- Tab groups automatically destroy themselves when they become empty
- Focus management is handled automatically based on tab addition/removal events
Loading
Loading