Last active
March 27, 2024 03:37
-
-
Save dfkaye/d3c7d0d59cb03616ad2eee8eec1141a5 to your computer and use it in GitHub Desktop.
Saving your console work in the browser, using one of two approaches.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 22 July 2022 | |
// Save() function for saving your console script experiments. | |
// See the long explanation on this gist at | |
// https://gist.github.com/dfkaye/d3c7d0d59cb03616ad2eee8eec1141a5#file-save-your-console-work-js | |
// Save() takes an array of script functions and fragments, | |
// and prints them as a single text block to the console, | |
// and attempts to download the text block to your browser's | |
// downloads folder. | |
function Save(scripts) { | |
// You can change the start and end fragments to your liking. | |
var script = `/* scripts */\n` | |
+ scripts.join(";\n\n") | |
+ `// comment out dangling debugger text -> `; | |
var blob = new Blob([script], { type: "text/plain"}); | |
var url = URL.createObjectURL(blob); | |
fetch(url) | |
.then(res => res.text()) | |
.then(text => { | |
// Clear out previous console statements. | |
// Note that this writes "console was cleared" at the top of the log. | |
// You'll need to remove or comment this line from the saved file if | |
// you try the right+click and "Save All Messages" approach. | |
console.clear(); | |
// Print out the script text. | |
console.log(text); | |
}) | |
.then(text => { | |
// Create and run command to download blob as text file. | |
var a = document.createElement("a"); | |
a.href = url; | |
a.target = "_new"; | |
a.download = "console-test_" + performance.now() + ".js.txt"; | |
a.click(); | |
}) | |
.catch(hmm => console.error("err", hmm)); | |
} | |
/* Example usage */ | |
// Our sample function. | |
function add (a, b) { | |
return a + b; | |
} | |
// Tests for our function. This function runs various tests, collects results, | |
// then batches up the sample function, the test function, a script command as | |
// a string, and the test results as a JSON string. | |
function test() { | |
var results = []; | |
var tests = [ | |
[1,2], | |
[3,"4"], | |
[5n, 6.2e-1], | |
[null, undefined] | |
]; | |
tests.forEach((pair, i, result) => { | |
try { | |
result = add.apply({}, pair); | |
} | |
catch (hmm) { | |
result = hmm; | |
} | |
finally { | |
results.push({ | |
pair: pair.toString(), | |
result: result.toString() | |
}); | |
} | |
}); | |
return results; | |
}; | |
// Our test run returns an array of functions and script strings. | |
var results = test(); | |
// Collect any functions and script fragment strings (even test results) | |
// that we wish to preserve in an array. | |
var scripts = [ | |
add, | |
test, | |
`test()`, | |
`/*\n ${JSON.stringify(results, null, 2)}\n*/`, | |
]; | |
// And finally, send scripts to be saved. | |
Save(scripts); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 21-22 July 2022 | |
// Save your console work in the browser, using one of two approaches. | |
// If you're like me you do a lot of testing in the JavaScript console | |
// in your web browser. When I want to save the whole thing once it's | |
// ready for preserving, I usually just make a new gist on GitHub, copy | |
// everything out, and save it there. | |
// If you'd rather save your console work to a local file, you can use one | |
// of two patterns outlined below. | |
// 1. Save by console statement link click. | |
// 2. Download blob automatically from an off-the-DOM anchor element. | |
// Both patterns involve creating a blob from a set of functions and strings | |
// of JavaScript, creating an object URL from the blob, then use the fetch() | |
// function to retrieve all the script text you want to preserve. | |
// That sounds roundabout but allows you to execute the functions before | |
// they are printed back out, and prints out only those functions you | |
// want to preserve. | |
//--------------------------------------------------------------------------- | |
// Pattern 1: Save by console statement link click. | |
//--------------------------------------------------------------------------- | |
// Because they are printed by console statements, you can right+click on | |
// the debugger link that appears in the console above each statement, then | |
// select "Save All Messages to File" to open the file browser, change the | |
// name you'd like to save to, select the directory for saving, and press OK. | |
// Caveat: This does not work when you use the console on a running site with | |
// a strict Content Security Policy that contains a script-src or script-src-elem | |
// directive that does *not* include `blob:` as one of the schemes or domains. | |
// This example runs on google.com, e.g., but not on github.com. | |
// Caveat 2: The example results in a "console was cleared" statement at the top | |
// of the generated console output. When saving the file, you'll need to comment | |
// it or remove it, and possibly some "debugger eval ..." indicators. | |
// The following example defines a function under development, called "add", | |
// a test function that executes different input pairs against it, then a | |
// series of statements for converting functions and fragments we want to | |
// preserve into a blob URL that we (eventually) fetch() and log to the console, | |
// after clearing the console first. | |
// Our sample function. | |
function add (a, b) { | |
return a + b; | |
} | |
// Tests for our function. This function runs various tests, collects results, | |
// then batches up the sample function, the test function, a script command as | |
// a string, and the test results as a JSON string. | |
function test() { | |
var results = []; | |
var tests = [ | |
[1,2], | |
[3,"4"], | |
[5n, 6.2e-1], | |
[null, undefined] | |
]; | |
tests.forEach((pair, i, result) => { | |
try { | |
result = add.apply({}, pair); | |
} | |
catch (hmm) { | |
result = hmm; | |
} | |
finally { | |
results.push({ | |
pair: pair.toString(), | |
result: result.toString() | |
}); | |
} | |
}); | |
return results; | |
}; | |
// Our test run returns an array of functions and script strings. | |
var results = test(); | |
// Collect any functions and script fragment strings (even test results) | |
// that we wish to preserve in an array. | |
var scripts = [ | |
`/* scripts */`, | |
add, | |
test, | |
`test()`, | |
`/*\n ${JSON.stringify(results, null, 2)}\n*/`, | |
`// comment out dangling debugger text -> ` | |
]; | |
// Join the array into a string. Joining itself treats the function bodies | |
// as strings. | |
var script = scripts.join(";\n\n"); | |
// We then create a text blob from that. | |
var blob = new Blob([script], { type: "text/plain"}); | |
// Create an object URL from the blob. | |
var url = URL.createObjectURL(blob); | |
// Use fetch() on that URL and print the concatenated script text in the console. | |
fetch(url) | |
.then(res => res.text()) | |
.then(text => { | |
// Clear out previous console statements. | |
// Note that this writes "console was cleared" at the top of the log. | |
// You'll need to remove or comment this line from the saved file if | |
// you try the right+click and "Save All Messages" approach. | |
console.clear(); | |
// Print out the script text. | |
console.log(text); | |
}) | |
.catch(hmm => console.error("err", hmm)); | |
// You should be able to save the fetched text as console output from | |
// the debugger link at upper right - link text is something like | |
// "debugger eval code 21:23" - by a right+click on the link, selecting | |
// "Save Messages to File", select your file name and directory, and done! | |
// When you run this full script in the browser console, you should see | |
// your script text, followed by test run results below. | |
// Here's what I get running all this in my console in Firefox, | |
// set off with back ticks so you can copy+paste this entire gist into | |
// the console and run it... | |
` | |
Console was cleared. debugger eval code:112:13 | |
/* scripts */; | |
function add (a, b) { | |
return a + b; | |
}; | |
function test() { | |
var results = []; | |
var tests = [ | |
[1,2], | |
[3,"4"], | |
[5n, 6.2e-1], | |
[null, undefined] | |
]; | |
tests.forEach((pair, i, result) => { | |
try { | |
result = add.apply({}, pair); | |
} | |
catch (hmm) { | |
result = hmm; | |
} | |
finally { | |
results.push({ | |
pair: pair.toString(), | |
result: result.toString() | |
}); | |
} | |
}); | |
return results; | |
}; | |
test(); | |
/* | |
[ | |
{ | |
"pair": "1,2", | |
"result": "3" | |
}, | |
{ | |
"pair": "3,4", | |
"result": "34" | |
}, | |
{ | |
"pair": "5,0.62", | |
"result": "TypeError: can't convert BigInt to number" | |
}, | |
{ | |
"pair": ",", | |
"result": "NaN" | |
} | |
] | |
*/; | |
// comment out dangling debugger text -> debugger eval code:115:13 | |
` | |
//--------------------------------------------------------------------------- | |
// Pattern 2: Download blob automatically from an off-the-DOM anchor element. | |
//--------------------------------------------------------------------------- | |
// I find Pattern 1 to be a hassle because of the lingering "Console was cleared" | |
// text and the dangling "debugger" link text, and mainly, that I have to do | |
// **any** clicking to initiate saving as a separate step from running the code. | |
// Turns out we can just download the script text from the blob URL automatically, | |
// per the example below. The strategy is to create an anchor element with a download | |
// name, href set to the blob URL, and target set to "_new". | |
fetch(url) | |
.then(res => res.text()) | |
.then(text => { | |
// Create and run command to download blob as text file. | |
var a = document.createElement("a"); | |
a.href = url; | |
a.target = "_new"; | |
a.download = "console-test_" + performance.now() + ".js.txt"; | |
a.click(); | |
}) | |
.catch(hmm => console.error("err", hmm)); | |
// The same URL access restrictions apply if you are working on a live web | |
// site with a strong Content Security Policy. However, because we are saving | |
// the file as plain text, malware detection software in your browser should | |
// permit the download automatically. | |
// As always, find a groove that works for you. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment