diff --git a/src/browser/components/preferences/zen-settings.js b/src/browser/components/preferences/zen-settings.js
index 503adb97c..0b43d3fe4 100644
--- a/src/browser/components/preferences/zen-settings.js
+++ b/src/browser/components/preferences/zen-settings.js
@@ -16,6 +16,8 @@ var gZenMarketplaceManager = {
header.appendChild(this._initDisableAll());
+ this._initImportExport();
+
this.__hasInitializedEvents = true;
await this._buildThemesList();
@@ -56,6 +58,23 @@ var gZenMarketplaceManager = {
});
},
+ _initImportExport() {
+ const importButton = document.getElementById('zenThemeMarketplaceImport');
+ const exportButton = document.getElementById('zenThemeMarketplaceExport');
+
+ if (importButton) {
+ importButton.addEventListener('click', async () => {
+ await this._importThemes();
+ });
+ }
+
+ if (exportButton) {
+ exportButton.addEventListener('click', async () => {
+ await this._exportThemes();
+ });
+ }
+ },
+
_initDisableAll() {
const areThemesDisabled = Services.prefs.getBoolPref('zen.themes.disable-all', false);
const browser = ZenThemesCommon.currentBrowser;
@@ -153,6 +172,89 @@ var gZenMarketplaceManager = {
this.triggerThemeUpdate();
},
+ async _importThemes() {
+ const errorBox = document.getElementById('zenThemeMarketplaceImportFailure');
+ const successBox = document.getElementById('zenThemeMarketplaceImportSuccess');
+ successBox.hidden = true;
+ errorBox.hidden = true;
+ const input = document.createElement('input');
+ input.type = 'file';
+ input.accept = '.json';
+ input.style.display = 'none';
+ input.setAttribute('moz-accept', '.json');
+ input.setAttribute('accept', '.json');
+
+ let timeout;
+ const filePromise = new Promise((resolve) => {
+ input.addEventListener('change', (event) => {
+ if (timeout) clearTimeout(timeout);
+ const file = event.target.files[0];
+ resolve(file);
+ });
+ timeout = setTimeout(() => {
+ console.warn('[ZenThemeMarketplaceParent:settings]: Import timeout reached, aborting.');
+ resolve(null);
+ }, 60000);
+ });
+
+ input.click();
+
+ try {
+ const file = await filePromise;
+ if (!file) {
+ return;
+ }
+ const content = await file.text();
+
+ const themes = JSON.parse(content);
+ const existingThemes = await ZenThemesCommon.getThemes();
+ const uniqueThemes = { ...themes, ...existingThemes };
+
+ console.log(`[ZenThemeMarketplaceParent:settings]: Importing ${Object.keys(themes).length} themes`);
+ await IOUtils.writeJSON(ZenThemesCommon.themesDataFile, uniqueThemes);
+ this.triggerThemeUpdate();
+ successBox.hidden = false;
+ } catch (error) {
+ console.error('[ZenThemeMarketplaceParent:settings]: Error while importing themes:', error);
+ errorBox.hidden = false;
+ } finally {
+ if (input) input.remove();
+ }
+ },
+
+ async _exportThemes() {
+ const errorBox = document.getElementById('zenThemeMarketplaceExportFailure');
+ const successBox = document.getElementById('zenThemeMarketplaceExportSuccess');
+
+ successBox.hidden = true;
+ errorBox.hidden = true;
+
+ let a, url;
+ try {
+ const themes = await ZenThemesCommon.getThemes();
+ const themesJson = JSON.stringify(themes, null, 2);
+ const blob = new Blob([themesJson], { type: 'application/json' });
+ url = URL.createObjectURL(blob);
+ // Creating a link to download the JSON file
+ a = document.createElement('a');
+ a.href = url;
+ a.download = 'zen-themes-export.json';
+
+ document.body.appendChild(a);
+ a.click();
+ } catch (error) {
+ console.error('[ZenThemeMarketplaceParent:settings]: Error while exporting themes:', error);
+ errorBox.hidden = false;
+ } finally {
+ if (a) {
+ a.remove();
+ }
+ if (url) {
+ URL.revokeObjectURL(url);
+ }
+ }
+ },
+
async _buildThemesList() {
if (!this.themesList) {
return;
diff --git a/src/browser/components/preferences/zenMarketplace.inc.xhtml b/src/browser/components/preferences/zenMarketplace.inc.xhtml
index ba923554c..13ac61d74 100644
--- a/src/browser/components/preferences/zenMarketplace.inc.xhtml
+++ b/src/browser/components/preferences/zenMarketplace.inc.xhtml
@@ -16,12 +16,20 @@
+
+
+
+
+
+
+
+
diff --git a/src/browser/themes/shared/preferences/zen-preferences.css b/src/browser/themes/shared/preferences/zen-preferences.css
index 811992b61..6bd1b14f2 100644
--- a/src/browser/themes/shared/preferences/zen-preferences.css
+++ b/src/browser/themes/shared/preferences/zen-preferences.css
@@ -560,12 +560,23 @@ groupbox h2 {
.zenThemeMarketplaceItemUninstallButton {
margin-left: auto;
+ cursor: pointer;
+}
+
+#zenThemeMarketplaceImport {
+ margin-left: auto;
+ cursor: pointer;
+}
+
+#zenThemeMarketplaceExport {
+ cursor: pointer;
}
#zenThemeMarketplaceCheckForUpdates {
- margin-left: auto;
+ cursor: pointer;
}
+
.zenThemeMarketplaceItemPreferenceDialog {
display: flex;
flex-direction: column;