Sharing:
- 👀 popup/popup.html
- 👀 popup/popup.js
- files
@files this is the html and js code of a firefox browser extension popup window, implemented with alpine.js (using the CSP-friendly mode). add a button at the bottom of the window that will export the playlists and the playback history and download it as a json file.
I need to add a button to the popup HTML and implement JavaScript functionality to export playlists and playback history as a JSON file. Let's break down the task:
this.playlists object)Let's start by modifying the HTML file to add the export button:
For the HTML (popup.html), I'll add a button at the bottom, after the playlists container but still within the app div:
<div id="app" x-data="playlistManager">
<!-- existing header and playlists content -->
<div class="playlists-container">
<!-- existing playlist template -->
</div>
<!-- New export button -->
<div class="actions-container">
<button class="export-btn" x-bind="exportButton">Export Playlists</button>
</div>
</div>
Now for the JavaScript (popup.js), I need to add:
exportButton binding similar to the existing button bindingsexportPlaylists function that does the actual export workHere's what I'll add to the Alpine data object:
exportButton: {
["@click"]() {
this.exportPlaylists();
},
},
async exportPlaylists() {
try {
// Get current playlists from our data
const playlists = this.playlists;
// Get playback history if it exists (or use empty object)
const result = await browser.storage.local.get("playbackHistory");
const playbackHistory = result.playbackHistory || {};
// Combine into a single export object
const exportData = {
playlists: playlists,
playbackHistory: playbackHistory,
exportDate: new Date().toISOString()
};
// Convert to JSON string
const jsonString = JSON.stringify(exportData, null, 2);
// Create a download link
const blob = new Blob([jsonString], { type: 'application/json' });
const url = URL.createObjectURL(blob);
// Create a temporary link element and trigger download
const a = document.createElement('a');
a.href = url;
a.download = `playlists-export-${new Date().toISOString().split('T')[0]}.json`;
document.body.appendChild(a);
a.click();
// Clean up
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 100);
} catch (error) {
console.error("Error exporting playlists:", error);
}
}
Now I'll put this all together to create the changes needed.
For popup.html, I'll add the export button at the bottom, after line 59 (the closing of the playlists-container) but before line 60 (the closing of the app div).
For popup.js, I'll add the new methods to the Alpine data object before the final closing braces.
Let me create the XML response for the tools:
Looking at your files, I'll add an export button at the bottom of the popup window to export playlists and playback history as a JSON file.
First, let's add the button to the HTML and then implement the JavaScript functionality:
<tools>
<tool name="files">
<action type="edit">
<path>/home/brwong/projects/experiments/playlist/popup/popup.html</path>
<search><![CDATA[ </div>
</div>
</body>]]></search>
<replace><![CDATA[ </div>
<!-- Export button -->
<div class="export-container">
<button class="export-btn" x-bind="exportButton">Export Playlists</button>
</div>
</div>
</body>]]></replace>
</action>
</tool>
</tools>
Now let's add the JavaScript functionality to handle the export:
<tools>
<tool name="files">
<action type="edit">
<path>/home/brwong/projects/experiments/playlist/popup/popup.js</path>
<search><![CDATA[ removeVideoButton: {
["@click"]() {
this.removeVideo(
this.$el.dataset.playlistName,
this.$el.dataset.playlistIndex,
);
},
},]]></search>
<replace><![CDATA[ removeVideoButton: {
["@click"]() {
this.removeVideo(
this.$el.dataset.playlistName,
this.$el.dataset.playlistIndex,
);
},
},
exportButton: {
["@click"]() {
this.exportPlaylists();
},
},
async exportPlaylists() {
try {
// Get current playlists
const playlists = this.playlists;
// Get playback history if it exists
const result = await browser.storage.local.get("playbackHistory");
const playbackHistory = result.playbackHistory || {};
// Create export data object
const exportData = {
playlists: playlists,
playbackHistory: playbackHistory,
exportDate: new Date().toISOString()
};
// Convert to JSON
const jsonString = JSON.stringify(exportData, null, 2);
// Create download
const blob = new Blob([jsonString], { type: 'application/json' });
const url = URL.createObjectURL(blob);
// Trigger download
const a = document.createElement('a');
a.href = url;
a.download = `playlists-export-${new Date().toISOString().split('T')[0]}.json`;
document.body.appendChild(a);
a.click();
// Clean up
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 100);
} catch (error) {
console.error("Error exporting playlists:", error);
}
},]]></replace>
</action>
</tool>
</tools>
Now we should also add some basic styling for the export button. Would you like me to create or modify a CSS file for this as well?
Sharing:
- 👀 popup/popup.html
- 👀 popup/popup.js
- files