diff --git a/ext/fiddle/EXPORTED_FUNCTIONS.fiddle b/ext/fiddle/EXPORTED_FUNCTIONS.fiddle index 6356910f3b..b96ce4e67c 100644 --- a/ext/fiddle/EXPORTED_FUNCTIONS.fiddle +++ b/ext/fiddle/EXPORTED_FUNCTIONS.fiddle @@ -4,3 +4,4 @@ _fiddle_experiment _fiddle_the_db _fiddle_db_arg _fiddle_db_filename +_fiddle_reset_db diff --git a/ext/fiddle/fiddle-worker.js b/ext/fiddle/fiddle-worker.js index 5c7f7e4fbf..302452f1c3 100644 --- a/ext/fiddle/fiddle-worker.js +++ b/ext/fiddle/fiddle-worker.js @@ -115,10 +115,10 @@ stderr("Restarting the app requires reloading the page."); wMsg('error', err); } - fiddleModule.setStatus('Exception thrown, see JavaScript console'); - fiddleModule.setStatus = function(text) { + fiddleModule.setStatus('Exception thrown, see JavaScript console:',text); + /*fiddleModule.setStatus = function(text) { console.error('[post-exception status]', text); - }; + };*/ }; const Sqlite3Shell = { @@ -135,13 +135,13 @@ exec: function f(sql){ if(!f._) f._ = fiddleModule.cwrap('fiddle_exec', null, ['string']); if(fiddleModule.isDead){ - wMsg('stderr', "shell module has exit()ed. Cannot run SQL."); + stderr("shell module has exit()ed. Cannot run SQL."); return; } wMsg('working','start'); try { if(f._running){ - wMsg('stderr','Cannot run multiple commands concurrently.'); + stderr('Cannot run multiple commands concurrently.'); }else{ f._running = true; f._(sql); @@ -151,11 +151,17 @@ wMsg('working','end'); } }, + resetDb: function f(){ + if(!f._) f._ = fiddleModule.cwrap('fiddle_reset_db', null); + stdout("Resetting database."); + f._(); + stdout("Reset",this.dbFilename()); + }, /* Interrupt can't work: this Worker is tied up working, so won't get the interrupt event which would be needed to perform the interrupt. */ interrupt: function f(){ if(!f._) f._ = fiddleModule.cwrap('fiddle_interrupt', null); - wMsg('stdout',"Requesting interrupt."); + stdout("Requesting interrupt."); f._(); } }; @@ -170,6 +176,7 @@ //console.debug("worker: onmessage.data",ev); switch(ev.type){ case 'shellExec': Sqlite3Shell.exec(ev.data); return; + case 'db-reset': Sqlite3Shell.resetDb(); return; case 'interrupt': Sqlite3Shell.interrupt(); return; /** Triggers the export of the current db. Fires an event in the form: @@ -184,7 +191,7 @@ */ case 'db-export': { const fn = Sqlite3Shell.dbFilename(); - wMsg('stdout',"Exporting",fn+"."); + stdout("Exporting",fn+"."); const fn2 = fn ? fn.split(/[/\\]/).pop() : null; try{ if(!fn2) throw new Error("DB appears to be closed."); @@ -213,7 +220,7 @@ }else if(buffer instanceof ArrayBuffer){ buffer = new Uint8Array(buffer); }else{ - wMsg('stderr',"'open' expects {buffer:Uint8Array} containing an uploaded db."); + stderr("'open' expects {buffer:Uint8Array} containing an uploaded db."); return; } const fn = ( @@ -232,7 +239,7 @@ if(oldName !== fn){ fiddleModule.FS.unlink(oldName); } - wMsg('stdout',"Replaced DB with",fn+"."); + stdout("Replaced DB with",fn+"."); return; } }; diff --git a/ext/fiddle/fiddle.html b/ext/fiddle/fiddle.html index d8625cbf64..0bdb22e6f5 100644 --- a/ext/fiddle/fiddle.html +++ b/ext/fiddle/fiddle.html @@ -60,9 +60,6 @@ label[for] { cursor: pointer; } - fieldset { - border-radius: 0.5em; - } .error { color: red; background-color: yellow; @@ -73,15 +70,55 @@ pointer-events: none !important; display: none !important; } - fieldset.options { - font-size: 70%; + /* Safari supports neither styling of nor event handling on a + fieldset legend, so we emulate a fieldset-like widget. */ + .fieldset { + border-radius: 0.5em; + border: 1px inset; + display: flex; + flex-direction: column; } - fieldset > legend { + .fieldset > .legend { + position: relative; + top: -1.5ex; padding: 0 0.5em; + font-size: 85%; + margin-left: 0.5em; + flex: 0 1 auto; + align-self: self-start; + cursor: pointer; } - fieldset.options > div { + .fieldset.options > div { display: flex; flex-wrap: wrap; + font-size: 70%; + margin: 0 0.5em 0.5em 0.5em; + } + .fieldset > .legend > span { + position: relative; + } + .fieldset > .legend::before { + /* Hide the parent element's top border where this + element intersects it. */ + content: ' '; + width: 100%; + height: 100%; + background-color: white + /* REALLY want to 'inherit' the color from the fieldset's + parent, but inherit leads to a transparent bg, which is + exactly what we're trying to avoid here. */; + opacity: 1; + position: absolute; + top: 0; + left: 0; + } + .fieldset > .legend::after { + content: " [hide]"; + position: relative; + } + .fieldset.collapsed > .legend::after { + content: " [show]"; + position: relative; } span.labeled-input { padding: 0.25em; @@ -117,6 +154,9 @@ display: flex; flex-direction: column-reverse; } + #view-split > .fieldset.options { + margin-top: 0.5em; + } @@ -141,8 +181,8 @@
-
- Options +
+ Options
+ + +
-
+