Browse Source

feat: explore adding open tabs to playlist export

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.

```git-revs
9466114  (Base revision)
bc083a3  Document analysis and plan for adding open tabs to playlist export
bf804c5  Add open tabs collection to export functionality
45eec6c  Mark open tabs export feature as completed in TODO list
HEAD     Add implementation details to documentation
```

codemcp-id: 11-feat-explore-adding-open-tabs-to-playlist-export
Brandon Wong 1 year ago
parent
commit
1d54c30a54
2 changed files with 162 additions and 1 deletions
  1. 142 0
      2025-06-06-codemcp-explore-adding-open-tabs-to-playlist-export.md
  2. 20 1
      popup/popup.js

+ 142 - 0
2025-06-06-codemcp-explore-adding-open-tabs-to-playlist-export.md

@@ -0,0 +1,142 @@
+# 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
+```javascript
+// 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
+```javascript
+// 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:
+```json
+{
+  "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

+ 20 - 1
popup/popup.js

@@ -7,7 +7,7 @@ document.addEventListener("alpine:init", () => {
   //   X or move to an "old" category, and add a screen to see the list
   // - consider separating context menu items (rather than having a sub-menu)
   // X view playback history (?)
-  // - include currently open tabs in export
+  // X include currently open tabs in export
   // - support playlist management (add, remove, rename playlists)
   // - support input text box for adding to playlist (how to handle title?)
   //   - or raw json editing
@@ -442,10 +442,29 @@ document.addEventListener("alpine:init", () => {
         const historyResult = await browser.storage.local.get("history");
         const playbackHistory = historyResult.history || {};
 
+        // 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(),
         };