Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/adalidbori/Tab-Closer-Ext/llms.txt

Use this file to discover all available pages before exploring further.

Architecture Overview

Tab Closer is built as a Chrome extension using three core components:
  1. Background Script (background.js) - Monitors tab creation and enforces limits
  2. Popup UI (popup.html + style.css) - User interface for configuration
  3. Settings Script (script.js) - Handles saving and loading user preferences
The extension uses Chrome’s event-driven architecture, responding to tab events in real-time without polling.

Core Mechanism

Tab Creation Monitoring

The extension listens for the chrome.tabs.onCreated event, which fires every time a new tab is opened:
chrome.tabs.onCreated.addListener(function (tab) {
    chrome.tabs.query({}, function (tabs) {
        // Tab management logic runs here
    });
});
This event-based approach ensures immediate response when tabs are created, without requiring background polling or timers.

Complete Tab Management Flow

Here’s the full implementation from background.js:
1

Tab Creation Event Triggered

When any new tab is created, the onCreated listener is invoked:
chrome.tabs.onCreated.addListener(function (tab) {
    // Query all current tabs
    chrome.tabs.query({}, function (tabs) {
        // Continue to validation...
    });
});
2

Check Feature Switch

Retrieve the fs (feature switch) value from storage to determine if the extension is enabled:
let fs = "";
chrome.storage.local.get('fs', function (result) {
    fs = result.fs;
    if (fs) {
        // Extension is enabled, proceed with tab limit check
    }
});
If fs is false or undefined, the extension does nothing and all tabs remain open.
3

Retrieve Tab Limit

Get the configured tabsallow value from storage:
let cantidadTabs = 0;
chrome.storage.local.get('tabsallow', function (result) {
    cantidadTabs = result.tabsallow;
    // Continue to validation...
});
4

Validate Minimum Limit

Ensure the tab limit meets the minimum requirement of 2:
if (cantidadTabs >= 2) {
    // Safe to proceed with tab closing logic
}
5

Check if Limit Exceeded

Compare the current tab count with the allowed limit:
if (tabs.length > cantidadTabs) {
    // Current tabs exceed limit, need to close some
}
6

Close Oldest Tabs

Remove the oldest tabs (earliest in the array) to bring the count within the limit:
for (let i = 0; i < tabs.length - cantidadTabs; i++) {
    try {
        chrome.tabs.remove(tabs[i].id, function () { });
    } catch (error) {
        console.log(error);
    }
}

Complete Background Script

Here’s the full background.js implementation with all logic combined:
chrome.tabs.onCreated.addListener(function (tab) {
    chrome.tabs.query({}, function (tabs) {
        //validar que el check este en verde
        let fs = "";
        chrome.storage.local.get('fs', function (result) {
            fs = result.fs;
            if (fs) {//el check esta en verde
                let cantidadTabs = 0;
                chrome.storage.local.get('tabsallow', function (result) {
                    cantidadTabs = result.tabsallow;
                    //validar que la cantidad de tabs posibles sea mayor o igual a dos
                    if (cantidadTabs >= 2) {
                        if (tabs.length > cantidadTabs) {
                            for (let i = 0; i < tabs.length - cantidadTabs; i++) {
                                try {
                                    chrome.tabs.remove(tabs[i].id, function () { });
                                } catch (error) {
                                    // código que se ejecuta si se produce un error
                                    console.log(error);
                                }
                            }
                        }
                    }
                });
            }
        });
    });
});

Tab Closing Algorithm

Which Tabs Get Closed?

The extension uses a FIFO (First In, First Out) approach:
Scenario: Tab limit is set to 5, user currently has 7 tabs open
Current Tabs (index order):
[0] Gmail (oldest)
[1] GitHub
[2] Documentation
[3] Stack Overflow
[4] YouTube
[5] Twitter
[6] Reddit (newest)

Calculation:
tabs.length - cantidadTabs = 7 - 5 = 2 tabs to close

Loop: for (let i = 0; i < 2; i++)

Action:
Close tabs[0] (Gmail)
Close tabs[1] (GitHub)

Result:
[0] Documentation
[1] Stack Overflow
[2] YouTube
[3] Twitter
[4] Reddit

Chrome Storage API Usage

The extension uses chrome.storage.local for persistent configuration:

Storage API Methods

// Save feature switch
chrome.storage.local.set({ fs: checkbox.checked }).then(() => {
  console.log('Feature switch saved');
});

// Save tab limit
chrome.storage.local.set({ tabsallow: tabsallow }).then(() => {
  console.log('Tab limit saved');
});
The set() method stores key-value pairs and returns a Promise that resolves when the operation completes.
// Read feature switch
chrome.storage.local.get('fs', function (result) {
    const featureEnabled = result.fs;
    console.log('Feature switch:', featureEnabled);
});

// Read tab limit
chrome.storage.local.get('tabsallow', function (result) {
    const limit = result.tabsallow;
    console.log('Tab limit:', limit);
});
The get() method retrieves values by key using a callback function.
Key characteristics of chrome.storage.local:
  • Data persists across browser sessions
  • Not cleared when the user clears cookies/cache
  • Maximum storage: 10 MB (more than sufficient for this extension)
  • Synchronous API with async callbacks
  • Available to all extension contexts (background, popup, content scripts)
Unlike localStorage, chrome.storage.local is specifically designed for extensions and provides better reliability.

Error Handling

The extension implements basic error handling for tab removal:
try {
    chrome.tabs.remove(tabs[i].id, function () { });
} catch (error) {
    // código que se ejecuta si se produce un error
    console.log(error);
}
Potential Error Scenarios:
  • Tab was already closed by the user before removal
  • Tab ID became invalid
  • Permission issues (unlikely with standard Chrome tabs)
  • Browser context was destroyed
The try-catch block prevents one failed tab closure from stopping the entire loop, ensuring maximum possible tabs are closed even if some operations fail. The script.js file manages the popup UI interaction:
const checkbox = document.getElementById('fs')
const button = document.getElementById('button')

// Load settings when popup opens
load();

// Attach save handler to button
button.addEventListener('click', function() {
    save();
});

Performance Considerations

The onCreated event listener is highly efficient because:
  • It only fires when a tab is actually created (not on every user action)
  • The tabs.query() call is fast, typically completing in less than 10ms
  • Storage reads are asynchronous and don’t block the UI
  • Tab removal operations are batched in a single loop
The extension has minimal memory footprint:
  • Background script: ~1-2 MB
  • No persistent timers or intervals
  • Storage: less than 1 KB (only two values stored)
  • Event listeners are passive until triggered
Storage is read on every tab creation event. This is acceptable because:
// Fast storage access (~1-5ms typically)
chrome.storage.local.get('fs', function (result) {
    // Callback executes quickly
});
The Chrome storage API is optimized for frequent reads and the small data size ensures minimal latency.

Chrome APIs Used

This extension uses three primary Chrome Extension APIs:

chrome.tabs

Methods Used:
  • onCreated.addListener() - Monitor tab creation
  • query() - Get all open tabs
  • remove() - Close specific tabs

chrome.storage

Methods Used:
  • local.set() - Save settings
  • local.get() - Retrieve settings
Keys:
  • fs (boolean)
  • tabsallow (number)

DOM APIs

Standard APIs:
  • getElementById() - Element access
  • addEventListener() - Event handling
  • document - DOM manipulation

Execution Timeline

Here’s what happens from installation to tab closing:
1

Extension Installation

  • Extension is loaded into Chrome
  • background.js starts running persistently
  • Event listeners are registered
  • No storage values exist yet (defaults apply)
2

First Configuration

  • User clicks extension icon
  • popup.html opens, script.js executes
  • load() function runs, reading storage (finds no values)
  • Defaults: checkbox checked, tab limit = 2
  • User adjusts settings and clicks Save
  • save() function writes fs and tabsallow to storage
3

Tab Creation Event

  • User opens a new tab (via Ctrl+T, clicking link, etc.)
  • chrome.tabs.onCreated event fires immediately
  • Background script executes full validation flow
4

Tab Limit Enforcement

  • Script queries all tabs
  • Reads fs and tabsallow from storage
  • Validates settings and current count
  • Closes oldest tabs if limit exceeded
  • All happens within milliseconds

Debugging and Development

  1. Navigate to chrome://extensions/
  2. Find “Tab Closer” extension
  3. Click “Inspect views: background page”
  4. Open the Console tab
Any console.log() statements from background.js appear here, including error messages from the catch block.
  1. Click the extension icon to open the popup
  2. Right-click anywhere in the popup
  3. Select “Inspect”
  4. View Console for script.js logs
  5. Use Elements tab to inspect HTML/CSS
Manual Testing:
// In background page console:
chrome.tabs.query({}, function(tabs) {
    console.log('Current tabs:', tabs.length);
    console.log('Tab details:', tabs);
});

// Check storage:
chrome.storage.local.get(['fs', 'tabsallow'], function(result) {
    console.log('Settings:', result);
});
Automated Testing: Open multiple tabs programmatically:
// Open 10 tabs quickly
for(let i = 0; i < 10; i++) {
    chrome.tabs.create({url: 'https://example.com'});
}

Limitations and Considerations

Known Limitations:
  1. Tab Order Assumption: The extension assumes tabs.query() returns tabs in creation order. While this is generally true, Chrome’s API doesn’t guarantee this ordering.
  2. No Pinned Tab Protection: Pinned tabs are not protected and may be closed if they’re among the oldest tabs.
  3. No Tab Priority: All tabs are treated equally; important tabs aren’t distinguished from trivial ones.
  4. Single Window Focus: The extension counts tabs across all windows, not per-window limits.
  5. No Undo Mechanism: Closed tabs cannot be automatically recovered by the extension.
Potential Enhancements:
  • Exclude pinned tabs from closing
  • Implement per-window tab limits
  • Add whitelist for important domains
  • Provide tab closing history
  • Use chrome.tabs.lastAccessed for smarter closing logic
  • Add keyboard shortcuts for quick enable/disable

Security and Permissions

The extension requires minimal permissions:
{
  "permissions": [
    "tabs",
    "storage"
  ]
}
tabs permission:
  • Required to listen to onCreated events
  • Needed to query tab information
  • Allows removal of tabs
storage permission:
  • Enables chrome.storage.local API
  • Required to persist user settings
The extension does NOT require:
  • Host permissions (doesn’t access page content)
  • Network access
  • Clipboard access
  • Downloads or file system access

Summary

Tab Closer implements a simple but effective tab management system:
  1. Event-Driven: Responds instantly to tab creation
  2. User-Controlled: Fully configurable enable/disable and limits
  3. Lightweight: Minimal resource usage and permissions
  4. Persistent: Settings survive browser restarts
  5. Safe: Enforces minimum limits and error handling
The extension demonstrates core Chrome Extension concepts including event listeners, storage APIs, and tab management while maintaining a simple, focused feature set.