aboutsummaryrefslogtreecommitdiff
path: root/scripts/theme-studio/app.js
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-20 03:34:57 -0400
committerCraig Jennings <c@cjennings.net>2026-06-20 03:34:57 -0400
commit0679c47c54dd935a0cc7d87c64081262b4367697 (patch)
treede84ffb19404a9a3767a77f2e56b1f3e6986ae12 /scripts/theme-studio/app.js
parentf0158f6b8460da2cfbfec596ae39b4b42953299f (diff)
downloaddotemacs-0679c47c54dd935a0cc7d87c64081262b4367697.tar.gz
dotemacs-0679c47c54dd935a0cc7d87c64081262b4367697.zip
feat(theme-studio): export through the save-file picker to overwrite in place
Re-exporting a theme used to land a "name (1).json" duplicate. The export built a blob and clicked a download link, which routes through the browser's downloads folder, and the browser uniquifies a re-save rather than replacing the file. I switched export to the File System Access API (showSaveFilePicker): it writes straight to the file you pick, so re-exporting the same WIP.json overwrites it. Where the API is absent the old blob download still runs, mirroring importTheme's picker-with-fallback shape. A new #savetest browser gate stubs the picker and checks the written content and the close.
Diffstat (limited to 'scripts/theme-studio/app.js')
-rw-r--r--scripts/theme-studio/app.js13
1 files changed, 12 insertions, 1 deletions
diff --git a/scripts/theme-studio/app.js b/scripts/theme-studio/app.js
index f6e4cd2cd..d6b42a324 100644
--- a/scripts/theme-studio/app.js
+++ b/scripts/theme-studio/app.js
@@ -436,7 +436,18 @@ function exportObj(){normalizePalette();const o={name:themeName(),palette:PALETT
function exportState(){const t=document.getElementById('export');t.value=JSON.stringify(exportObj(),null,1);t.style.display='block';t.focus();t.select();}
function toggleJSON(){const t=document.getElementById('export'),b=document.getElementById('jsonbtn');if(t.style.display==='block'){t.style.display='none';b.textContent='show';}else{exportState();b.textContent='hide';}}
function updateTitle(){const n=document.getElementById('themename').value.trim();document.getElementById('pagetitle').textContent=(n||'Untitled')+': theme';}
-function exportTheme(){const blob=new Blob([JSON.stringify(exportObj(),null,1)],{type:'application/json'});const a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download=fileSlug()+'.json';a.click();}
+// Export the theme JSON. Prefer the File System Access API (showSaveFilePicker)
+// so re-exporting overwrites the chosen file in place -- a blob download routes
+// through the browser's downloads folder, which uniquifies a re-save as
+// "name (1).json" rather than replacing it. Fall back to the blob download where
+// the API is absent (mirrors importTheme's showOpenFilePicker/fileinput fallback).
+async function exportTheme(){
+ const data=JSON.stringify(exportObj(),null,1);
+ if(!window.showSaveFilePicker){const blob=new Blob([data],{type:'application/json'});const a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download=fileSlug()+'.json';a.click();return;}
+ try{const h=await window.showSaveFilePicker({suggestedName:fileSlug()+'.json',types:[{description:'theme JSON',accept:{'application/json':['.json']}}]});
+ const w=await h.createWritable();await w.write(data);await w.close();
+ notify('saved "'+fileSlug()+'.json"',false);
+ }catch(e){if(e&&e.name!=='AbortError')notify('export failed: '+e.message,true);}}
function applyImported(text){const d=JSON.parse(text);lastGone={};if(d.name)document.getElementById('themename').value=d.name;if(d.palette)PALETTE=d.palette.map(normalizePaletteEntry);
if(!d.syntax)throw new Error('theme JSON is missing syntax; convert older files first');
SYNTAX={};CATS.forEach(c=>{const k=c[0];SYNTAX[k]=Object.assign(syntaxBlank(k),migrateLegacyFace(d.syntax[k]||{}));});syncAllSyntaxCache();