2025-06-06-codemcp-explore-adding-open-tabs-to-playlist-export.md 4.5 KB

2025-06-06 - CodeMCP: Explore Adding Open Tabs to Playlist Export

User Request

the popup menu has a button to "export" the playlists. it currently puts the playlists and the playbackHistory into a json object along with the exportDate, and triggers the browser to download it. how feasible would it be to add openTabs to the export, containing a url and page title for each? don't make any code changes yet, just propose a plan for now.

Analysis

Current Export Implementation

The export functionality is in popup.js lines 435-474 in the exportPlaylists() method:

  • Gets playlists from browser.storage.local
  • Gets playback history from browser.storage.local
  • Creates export data object with playlists, playbackHistory, and exportDate
  • Downloads as JSON file

Feasibility Assessment for Adding Open Tabs

HIGHLY FEASIBLE - The implementation would be straightforward:

Permissions ✅

  • Extension already has "tabs" permission in manifest.json
  • Firefox WebExtensions API browser.tabs.query() available to get all open tabs

Technical Implementation ✅

  • Add browser.tabs.query({}) call to get all open tabs
  • Extract URL and title from each tab
  • Add openTabs array to export data object
  • Minimal code changes (~10 lines)

Proposed Plan

1. Modify exportPlaylists() method

// Add after getting history data:
const tabsResult = await browser.tabs.query({});
const openTabs = tabsResult
  .filter(tab => tab.url && !tab.url.startsWith('moz-extension://') && !tab.url.startsWith('about:'))
  .map(tab => ({
    url: tab.url,
    title: tab.title
  }));

// Add to export data:
const exportData = {
  playlists,
  playbackHistory,
  openTabs,
  exportDate: new Date().toISOString(),
};

2. Error Handling

  • Wrap tabs query in try-catch
  • Gracefully handle permission or API issues
  • Provide fallback if tabs can't be accessed

3. Optional Filtering

  • Filter out extension internal pages
  • Filter out browser internal pages (about:, chrome://, etc.)
  • Consider deduplicating identical URLs

Benefits

  • Minimal complexity: Only ~10 lines of additional code
  • No breaking changes: Existing exports continue to work
  • Useful data: Open tabs represent current interests/research
  • Consistent format: Follows existing data structure pattern

Considerations

  • Privacy: Users should know open tabs are being exported
  • Performance: Large number of tabs (~100+) would create larger files
  • Optional feature: Could add checkbox to include/exclude open tabs

Recommendation

Proceed with implementation - This is a low-risk, high-value addition that fits naturally with the existing export functionality.


Implementation

Changes Made

1. Modified exportPlaylists() method in popup.js

  • Added browser.tabs.query({}) call to retrieve all open tabs
  • Added filtering to exclude browser internal pages:
    • moz-extension:// URLs (Firefox extension pages)
    • about: URLs (Firefox internal pages)
    • chrome:// URLs (Chrome internal pages)
  • Added error handling with try-catch around tabs query
  • Added openTabs array to export data structure

2. Updated TODO list

  • Marked "include currently open tabs in export" as completed (X)

Final Implementation

// Get open tabs
let openTabs = [];
try {
  const tabsResult = await browser.tabs.query({});
  openTabs = tabsResult
    .filter(tab => tab.url &&
      !tab.url.startsWith('moz-extension://') &&
      !tab.url.startsWith('about:') &&
      !tab.url.startsWith('chrome://'))
    .map(tab => ({
      url: tab.url,
      title: tab.title || 'Untitled'
    }));
} catch (error) {
  console.warn("Could not retrieve open tabs:", error);
  openTabs = [];
}

// Create export data object
const exportData = {
  playlists,
  playbackHistory,
  openTabs,
  exportDate: new Date().toISOString(),
};

Export Data Structure

The exported JSON now includes:

{
  "playlists": { /* existing playlist data */ },
  "playbackHistory": { /* existing history data */ },
  "openTabs": [
    {
      "url": "https://example.com",
      "title": "Example Page Title"
    }
  ],
  "exportDate": "2025-06-06T..."
}

Features

  • Graceful degradation: If tabs can't be accessed, exports still work with empty openTabs array
  • Privacy-conscious filtering: Excludes internal browser/extension pages
  • Fallback titles: Uses 'Untitled' if tab has no title
  • Non-breaking: Existing import functionality will ignore the new openTabs field