Skip to content

Instantly share code, notes, and snippets.

@DarrenSem
Last active July 20, 2026 15:13
Show Gist options
  • Select an option

  • Save DarrenSem/444cc1c0539226a4902e7f265f23820f to your computer and use it in GitHub Desktop.

Select an option

Save DarrenSem/444cc1c0539226a4902e7f265f23820f to your computer and use it in GitHub Desktop.
console.save.js + DOWNLOAD contents as MarkDown.js -- download your JavaScript objects from your web browser's F12 Dev Tools console! (also Bookmarklet click defaults to saving prompt text data or body.innerText as `DL-[date].md`)
// DLasMD-console.save.js -- Download your JavaScript objects from your web browser's F12 Dev Tools console! (also Bookmarklet click defaults to saving prompt text data or body.innerText as `DL-[date].md`) [as of 15Jan2025 started using DLasMD-console.save.js]
// this GIST url: https://gist.github.com/DarrenSem/444cc1c0539226a4902e7f265f23820f
// DOWNLOAD contents as MarkDown.js, plus adds console.save() function
// javascript:void function(){"use strict";let a=document,b=a._,c="",d="\n\n",e="innerText",f="application/octet-stream",g=URL,h=Date.now,i=Object.assign,j=b=>a.createElement(b),k=(c,f="onselectstart")=>{if(c=a=>a,a[f]&&a[f]!=c)return a[f]=c,alert("Text selecting was disabled!"+d+"Try again, it is now enabled...");let g=a.getSelection(),h=g&&"Range"===g.type&&g.getRangeAt(0),i=h&&j("div");return i&&(i.appendChild(h.cloneContents()),i[e])||b},l=(a,b,d,e)=>{e=g.createObjectURL(a=new Blob([a],{type:d||a?.type||f})),b??="DL-"+h()+".md";i(j("a"),{href:e},!0===b?{target:"_blank"}:{download:b||c}).click(),g.revokeObjectURL(e)};(console.save=(g,i,j,m)=>{if(g??=k(),g==b){let f=(a,b)=>a.test(b??c),h=prompt("Enter data to download..."+d+"(Whitespace or =FILENAME.EXT defaults to document.body.innerText)")?.trim();if(h==b)return b;f(/^=./,h)&&(i=h.slice(1),h=0),g=g=h.length?h:a.body[e],i=!0===i?i:i?i+(f(/\./,i)?c:".md"):b}return m="object"==typeof g,m&&(g=JSON.stringify(g,0,4)),l(g,i||"DL-"+h()+(m?".json.txt":".md"),j||(m?"application/json":f))})()}();
// ^ Bookmarklet (1052 char, 20Jul2026 855am) -- drag-and-drop add this to your web browser's Favorites
// Expanded functionality after being inspired by the simple idea @ https://coderwall.com/p/prhwzg/add-console-save-to-chrome https://archive.is/cWiF6
"use strict";
// #region for "version" /history/ -- final step = REMOVE these 3 or 4 chars: ...now these are unlikely, I'm pretty sure... !1, ;!1 !1||
if (false) { // for "version" /history/ -- final step = REMOVE these 3 or 4 chars: ...now these are unlikely, I'm pretty sure... !1, ;!1 !1||
//// 20Jul2026 818am: removing one-usage references and extracted functions...
// 818am: no need for the LOGGER(stringify("console.save()")) in the final BM (oops) so... 1176 char javascript:void function(){"use strict";let a=document,b=a._,c="",d="\n\n",e="innerText",f="application/octet-stream",g=alert,h=console.log,i=Date.now,j=(a,b,c=2)=>JSON.stringify(a,b,c),k=b=>a.createElement(b),l=(c,f="onselectstart")=>{if(c=a=>a,a[f]&&a[f]!=c)return a[f]=c,g("Text selecting was disabled!"+d+"Try again, it is now enabled...");let h=a.getSelection(),i=h&&"Range"===h.type&&h.getRangeAt(0),j=i&&k("div");return j&&(j.appendChild(i.cloneContents()),j[e])||b},m=(a,b,d)=>{let e=URL,g=Object.assign,h=e.createObjectURL(a=new Blob([a],{type:d||a?.type||f}));b??="DL-"+i()+".md";(a=>(a?.click(),a))(g(k("a"),{href:h},!0===b?{target:"_blank"}:{download:b||c})),e.revokeObjectURL(h)};(console.save=(g,h,k,n,o)=>{if(n=(a,b)=>(a=typeof a,b?a==b:a),g??=l(),g==b){let f=a.body,i=prompt,j=(a,b)=>a.test(b??c),k=(a=>a?.trim())(i("Enter data to download..."+d+"(Whitespace or =FILENAME.EXT defaults to document.body.innerText)"));if(k==b)return b;j(/^=./,k)&&(h=((a,b,c)=>a.slice(b,c))(k,1),k=0),g=(a=>a?.length)(k)?k:f[e],h=!0===h?h:h?h+(j(/\./,h)?c:".md"):b}return o=n(g,"object"),o&&(g=j(g,0,4)),m(g,h||"DL-"+i()+(o?".json.txt":".md"),k||(o?"application/json":f))})()}();
// 821am: no need for extracted 'stringify' 1154 char javascript:void function(){"use strict";let a=document,b=a._,c="",d="\n\n",e="innerText",f="application/octet-stream",g=alert,h=console.log,i=Date.now,j=b=>a.createElement(b),k=(c,f="onselectstart")=>{if(c=a=>a,a[f]&&a[f]!=c)return a[f]=c,g("Text selecting was disabled!"+d+"Try again, it is now enabled...");let h=a.getSelection(),i=h&&"Range"===h.type&&h.getRangeAt(0),k=i&&j("div");return k&&(k.appendChild(i.cloneContents()),k[e])||b},l=(a,b,d)=>{let e=URL,g=Object.assign,h=e.createObjectURL(a=new Blob([a],{type:d||a?.type||f}));b??="DL-"+i()+".md";(a=>(a?.click(),a))(g(j("a"),{href:h},!0===b?{target:"_blank"}:{download:b||c})),e.revokeObjectURL(h)};(console.save=(g,h,j,m,n)=>{if(m=(a,b)=>(a=typeof a,b?a==b:a),g??=k(),g==b){let f=a.body,i=prompt,j=(a,b)=>a.test(b??c),k=(a=>a?.trim())(i("Enter data to download..."+d+"(Whitespace or =FILENAME.EXT defaults to document.body.innerText)"));if(k==b)return b;j(/^=./,k)&&(h=((a,b,c)=>a.slice(b,c))(k,1),k=0),g=(a=>a?.length)(k)?k:f[e],h=!0===h?h:h?h+(j(/\./,h)?c:".md"):b}return n=m(g,"object"),n&&(g=JSON.stringify(g,0,4)),l(g,h||"DL-"+i()+(n?".json.txt":".md"),j||(n?"application/json":f))})()}();
// 824am: no need for extracted 'ALERT_OBJECT' or 'LOGGER' 1136 char javascript:void function(){"use strict";let a=document,b=a._,c="",d="\n\n",e="innerText",f="application/octet-stream",g=Date.now,h=b=>a.createElement(b),i=(c,f="onselectstart")=>{if(c=a=>a,a[f]&&a[f]!=c)return a[f]=c,alert("Text selecting was disabled!"+d+"Try again, it is now enabled...");let g=a.getSelection(),i=g&&"Range"===g.type&&g.getRangeAt(0),j=i&&h("div");return j&&(j.appendChild(i.cloneContents()),j[e])||b},j=(a,b,d)=>{let e=URL,i=Object.assign,j=e.createObjectURL(a=new Blob([a],{type:d||a?.type||f}));b??="DL-"+g()+".md";(a=>(a?.click(),a))(i(h("a"),{href:j},!0===b?{target:"_blank"}:{download:b||c})),e.revokeObjectURL(j)};(console.save=(h,k,l,m,n)=>{if(m=(a,b)=>(a=typeof a,b?a==b:a),h??=i(),h==b){let f=a.body,g=prompt,i=(a,b)=>a.test(b??c),j=(a=>a?.trim())(g("Enter data to download..."+d+"(Whitespace or =FILENAME.EXT defaults to document.body.innerText)"));if(j==b)return b;i(/^=./,j)&&(k=((a,b,c)=>a.slice(b,c))(j,1),j=0),h=(a=>a?.length)(j)?j:f[e],k=!0===k?k:k?k+(i(/\./,k)?c:".md"):b}return n=m(h,"object"),n&&(h=JSON.stringify(h,0,4)),j(h,k||"DL-"+g()+(n?".json.txt":".md"),l||(n?"application/json":f))})()}();
//// 835am: no need for extracted 'click' or 'TYPE_OF' 1095 char (vs. 1069 for previous 'baseline') javascript:void function(){"use strict";let a=document,b=a._,c="",d="\n\n",e="innerText",f="application/octet-stream",g=URL,h=Date.now,i=Object.assign,j=b=>a.createElement(b),k=(c,f="onselectstart")=>{if(c=a=>a,a[f]&&a[f]!=c)return a[f]=c,alert("Text selecting was disabled!"+d+"Try again, it is now enabled...");let g=a.getSelection(),h=g&&"Range"===g.type&&g.getRangeAt(0),i=h&&j("div");return i&&(i.appendChild(h.cloneContents()),i[e])||b},l=(a,b,d)=>{let e=g.createObjectURL(a=new Blob([a],{type:d||a?.type||f}));b??="DL-"+h()+".md";i(j("a"),{href:e},!0===b?{target:"_blank"}:{download:b||c}).click(),g.revokeObjectURL(e)};(console.save=(g,i,j,m)=>{if(g??=k(),g==b){let f=a.body,h=prompt,j=(a,b)=>a.test(b??c),k=(a=>a?.trim())(h("Enter data to download..."+d+"(Whitespace or =FILENAME.EXT defaults to document.body.innerText)"));if(k==b)return b;j(/^=./,k)&&(i=((a,b,c)=>a.slice(b,c))(k,1),k=0),g=(a=>a?.length)(k)?k:f[e],i=!0===i?i:i?i+(j(/\./,i)?c:".md"):b}return m="object"==typeof g,m&&(g=JSON.stringify(g,0,4)),l(g,i||"DL-"+h()+(m?".json.txt":".md"),j||(m?"application/json":f))})()}();
// 851am: no need for extracted 'DOC_BODY' or 'PROMPT_OBJECT' or 'trimmed' or 'sliced' or 'len' 1054 char javascript:void function(){"use strict";let a=document,b=a._,c="",d="\n\n",e="innerText",f="application/octet-stream",g=URL,h=Date.now,i=Object.assign,j=b=>a.createElement(b),k=(c,f="onselectstart")=>{if(c=a=>a,a[f]&&a[f]!=c)return a[f]=c,alert("Text selecting was disabled!"+d+"Try again, it is now enabled...");let g=a.getSelection(),h=g&&"Range"===g.type&&g.getRangeAt(0),i=h&&j("div");return i&&(i.appendChild(h.cloneContents()),i[e])||b},l=(a,b,d)=>{let e=g.createObjectURL(a=new Blob([a],{type:d||a?.type||f}));b??="DL-"+h()+".md";i(j("a"),{href:e},!0===b?{target:"_blank"}:{download:b||c}).click(),g.revokeObjectURL(e)};(console.save=(g,i,j,m)=>{if(g??=k(),g==b){let f=(a,b)=>a.test(b??c),h=prompt("Enter data to download..."+d+"(Whitespace or =FILENAME.EXT defaults to document.body.innerText)")?.trim();if(h==b)return b;f(/^=./,h)&&(i=h.slice(1),h=0),g=g=h.length?h:a.body[e],i=!0===i?i:i?i+(f(/\./,i)?c:".md"):b}return m="object"==typeof g,m&&(g=JSON.stringify(g,0,4)),l(g,i||"DL-"+h()+(m?".json.txt":".md"),j||(m?"application/json":f))})()}();
// 855am: saveDataAsFilenameMime() signature '_href' instead of 'let href' 1052 char javascript:void function(){"use strict";let a=document,b=a._,c="",d="\n\n",e="innerText",f="application/octet-stream",g=URL,h=Date.now,i=Object.assign,j=b=>a.createElement(b),k=(c,f="onselectstart")=>{if(c=a=>a,a[f]&&a[f]!=c)return a[f]=c,alert("Text selecting was disabled!"+d+"Try again, it is now enabled...");let g=a.getSelection(),h=g&&"Range"===g.type&&g.getRangeAt(0),i=h&&j("div");return i&&(i.appendChild(h.cloneContents()),i[e])||b},l=(a,b,d,e)=>{e=g.createObjectURL(a=new Blob([a],{type:d||a?.type||f})),b??="DL-"+h()+".md";i(j("a"),{href:e},!0===b?{target:"_blank"}:{download:b||c}).click(),g.revokeObjectURL(e)};(console.save=(g,i,j,m)=>{if(g??=k(),g==b){let f=(a,b)=>a.test(b??c),h=prompt("Enter data to download..."+d+"(Whitespace or =FILENAME.EXT defaults to document.body.innerText)")?.trim();if(h==b)return b;f(/^=./,h)&&(i=h.slice(1),h=0),g=g=h.length?h:a.body[e],i=!0===i?i:i?i+(f(/\./,i)?c:".md"):b}return m="object"==typeof g,m&&(g=JSON.stringify(g,0,4)),l(g,i||"DL-"+h()+(m?".json.txt":".md"),j||(m?"application/json":f))})()}();
// 913am: GIST now updated 1052 char javascript:void function(){"use strict";let a=document,b=a._,c="",d="\n\n",e="innerText",f="application/octet-stream",g=URL,h=Date.now,i=Object.assign,j=b=>a.createElement(b),k=(c,f="onselectstart")=>{if(c=a=>a,a[f]&&a[f]!=c)return a[f]=c,alert("Text selecting was disabled!"+d+"Try again, it is now enabled...");let g=a.getSelection(),h=g&&"Range"===g.type&&g.getRangeAt(0),i=h&&j("div");return i&&(i.appendChild(h.cloneContents()),i[e])||b},l=(a,b,d,e)=>{e=g.createObjectURL(a=new Blob([a],{type:d||a?.type||f})),b??="DL-"+h()+".md";i(j("a"),{href:e},!0===b?{target:"_blank"}:{download:b||c}).click(),g.revokeObjectURL(e)};(console.save=(g,i,j,m)=>{if(g??=k(),g==b){let f=(a,b)=>a.test(b??c),h=prompt("Enter data to download..."+d+"(Whitespace or =FILENAME.EXT defaults to document.body.innerText)")?.trim();if(h==b)return b;f(/^=./,h)&&(i=h.slice(1),h=0),g=g=h.length?h:a.body[e],i=!0===i?i:i?i+(f(/\./,i)?c:".md"):b}return m="object"==typeof g,m&&(g=JSON.stringify(g,0,4)),l(g,i||"DL-"+h()+(m?".json.txt":".md"),j||(m?"application/json":f))})()}();
} else { ; }; // end if (false) { // for "version" /history/ -- final step = REMOVE these 3 or 4 chars: ...now these are unlikely, I'm pretty sure... !1, ;!1 !1||
// #endregion for "version" /history/ -- final step = REMOVE these 3 or 4 chars: ...now these are unlikely, I'm pretty sure... !1, ;!1 !1||
//// [reminder to self]
// 'new coding style' = focus on [MAINTAIN/SEARCH/TEST]ABILITY, then *as a FINAL step* do the smallest MINIFY
// SEE ALSO: "DLasMD-console.save.js" (no 'REWRITE') + "downloadData(dataOrBlob, filenameOrTrueForNewWindow, optionalMimeType).js"
//// TODO: the 'customization' extension for BOOKMARKLET_NAME = "DL_yt_L#_C#]" for multiple 'ytSubs' one-click-to-change-LINE_MAX-COMBO_MAX
let doc = document;
let UNDEF = doc._;
let BLANK_STRING = "";
// let LF = "\n";
// let LF_TWICE = LF + LF; // aka "\n\n"
let LF_TWICE = "\n\n";
let INNERTEXT_PROP = "innerText";
// let DOC_BODY = doc.body;
let OCTET_STREAM = "application/octet-stream"; // different than just "octet-stream"
let URL_OBJECT = URL;
// let PROMPT_OBJECT = prompt;
// let ALERT_OBJECT = alert;
// let CONSOLE_OBJECT = console;
// let LOGGER = CONSOLE_OBJECT.log;
// let LOGGER = console.log;
// let DATE_OBJECT = Date;
// let DATE_NOW = DATE_OBJECT.now;
let DATE_NOW = Date.now;
// let OBJECT_OBJECT = Object;
// let OBJECT_ASSIGN = OBJECT_OBJECT.assign;
let OBJECT_ASSIGN = Object.assign;
// let TYPE_OF = (v, name) => ( v = typeof v, name ? v == name : v );
// let fnIdentity = (v) => v;
// let trimmed = (v) => v?.trim();
// let tested = (regexPattern, v) => regexPattern.test(v ?? BLANK_STRING);
// let sliced = (v, indexStart, indexEnd) => v.slice(indexStart, indexEnd);
// let len = (v) => v?.length;
// let stringify = (v, replacer, space = 2) => JSON.stringify(v, replacer, space);
// let click = (el) => ( el?.click(), el );
let createElement = (tagName) => doc.createElement(tagName);
/** returns {string | UNDEFINED} innerText of document.getSelection() **/
let getSelectedText = (fnIdentity, SELECT_START_EVENT = "onselectstart") => {
// let getSelectedText = (ALERT_OBJECT, fnIdentity, SELECT_START_EVENT = "onselectstart") => {
// let getSelectedText = (doc, LF_TWICE, ALERT_OBJECT, fnIdentity, SELECT_START_EVENT = "onselectstart") => {
// doc = document;
// let LF = "\n";
// let LF_TWICE = LF + LF; // aka "\n\n"
// let LF_TWICE = "\n\n";
// ALERT_OBJECT = alert;
fnIdentity = (v) => v;
if (
doc[SELECT_START_EVENT] &&
doc[SELECT_START_EVENT] != fnIdentity
) {
doc[SELECT_START_EVENT] = fnIdentity;
// return ALERT_OBJECT(
return alert(
"Text selecting was disabled!"
+ LF_TWICE
+ "Try again, it is now enabled..."
);
};
// let UNDEF = getSelectedText._;
// let INNERTEXT_PROP = "innerText";
// let createElement = (tagName) => doc.createElement(tagName);
let selection = doc.getSelection();
let range = (
selection &&
selection.type === "Range" &&
selection.getRangeAt(0)
); // NOT the same as checking this flag: selection.isCollapsed
let el = range && createElement("div");
return el && (
el.appendChild( range.cloneContents() ),
el[INNERTEXT_PROP]
) || UNDEF;
}; // end let getSelectedText = (fnIdentity, SELECT_START_EVENT = "onselectstart") => {
let saveDataAsFilenameMime = (
dataOrBlob
, filenameOrTrueForNewWindow // default = "DL-" + DATE_NOW() + ".md" // `DL-${+new Date}.md` // missing filename extension automatically added based on Blob.type
, optionalMimeType
, _href
) => {
// let saveDataAsFilenameMime = (dataOrBlob, filenameOrTrueForNewWindow, optionalMimeType) => {
// let doc = document;
// let BLANK_STRING = "";
// let OCTET_STREAM = "application/octet-stream"; // different than just "octet-stream"
// let URL_OBJECT = URL;
// let DATE_OBJECT = Date;
// let DATE_NOW = DATE_OBJECT.now;
// let DATE_NOW = Date.now;
// let OBJECT_OBJECT = Object;
// let OBJECT_ASSIGN = OBJECT_OBJECT.assign;
// let OBJECT_ASSIGN = Object.assign;
// let click = (el) => ( el?.click(), el );
// let createElement = (tagName) => doc.createElement(tagName);
_href = URL_OBJECT.createObjectURL(
dataOrBlob = new Blob(
[dataOrBlob], { type: (
optionalMimeType
|| dataOrBlob?.type
|| OCTET_STREAM
) }
)
);
filenameOrTrueForNewWindow ??= "DL-" + DATE_NOW() + ".md" // `DL-${+new Date}.md` // missing filename extension automatically added based on Blob.type
if(!"TESTING") { return (
OBJECT_ASSIGN( {createElement: "a"},
// OBJECT_ASSIGN( createElement("a"),
{ href: _href },
filenameOrTrueForNewWindow === true
? { target: "_blank" }
: { download: (
filenameOrTrueForNewWindow
|| BLANK_STRING // <<< including if <false> or <null> was passed (but not <undefined>)
) }
)
); } else { ; }; // end if(!"TESTING") { return (
// click(
OBJECT_ASSIGN( createElement("a"),
{ href: _href },
filenameOrTrueForNewWindow === true
? { target: "_blank" }
: { download: (
filenameOrTrueForNewWindow
|| BLANK_STRING // <<< including if <false> or <null> was passed (but not <undefined>)
) }
).click();
// );
URL_OBJECT.revokeObjectURL(_href);
}; // end let saveDataAsFilenameMime = (dataOrBlob, filenameOrTrueForNewWindow, optionalMimeType) => {
/**/
( console.save = ( (
dataOrBlob
, filenameOrTrueForNewWindow // default = "DL-" + DATE_NOW() + (_isJson ? ".json.txt" : ".md") // default = `DL-${+new Date}` + (_isJson ? ".json.txt" : ".md")
, optionalMimeType
, _isJson
) => {
/**/
// let consoleSave = (dataOrBlob, filenameOrTrueForNewWindow, optionalMimeType, _isJson, TYPE_OF, UNDEF, OCTET_STREAM, DATE_NOW, stringify) => {
// let consoleSave = (dataOrBlob, filenameOrTrueForNewWindow, optionalMimeType, _isJson, TYPE_OF) => {
// let consoleSave = (dataOrBlob, filenameOrTrueForNewWindow, optionalMimeType, _isJson) => {
// OCTET_STREAM = "application/octet-stream"; // different than just "octet-stream"
// DATE_OBJECT = Date;
// DATE_NOW = DATE_OBJECT.now;
// DATE_NOW = Date.now;
// TYPE_OF = (v, name) => ( v = typeof v, name ? v == name : v );
// stringify = (v, replacer, space = 2) => JSON.stringify(v, replacer, space);
dataOrBlob ??= getSelectedText();
if (dataOrBlob == UNDEF) {
// let doc = document;
// let BLANK_STRING = "";
// let let LF = "\n";
// let LF_TWICE = LF + LF; // aka "\n\n"
// let LF_TWICE = "\n\n";
// let INNERTEXT_PROP = "innerText";
// let DOC_BODY = doc.body;
// let PROMPT_OBJECT = prompt;
// let trimmed = (v) => v?.trim();
let tested = (regexPattern, v) => regexPattern.test(v ?? BLANK_STRING);
// let sliced = (v, indexStart, indexEnd) => v.slice(indexStart, indexEnd);
// let len = (v) => v?.length;
// let promptData = trimmed(
let promptData = (
// PROMPT_OBJECT(
prompt(
"Enter data to download..."
+ LF_TWICE
+ "(Whitespace or =FILENAME.EXT"
+ " defaults to document.body.innerText)"
)
// );
)?.trim();
if (promptData == UNDEF) {
return UNDEF;
};
if ( tested( /^=./, promptData ) ) {
// filenameOrTrueForNewWindow = sliced(promptData, 1);
filenameOrTrueForNewWindow = promptData.slice(1);
promptData = 0;
};
dataOrBlob = (
// len(promptData)
dataOrBlob = promptData.length
? promptData
// : DOC_BODY[INNERTEXT_PROP]
: doc.body[INNERTEXT_PROP]
);
filenameOrTrueForNewWindow = (
true === filenameOrTrueForNewWindow
? filenameOrTrueForNewWindow
: filenameOrTrueForNewWindow
? ( filenameOrTrueForNewWindow + (
tested(/\./, filenameOrTrueForNewWindow)
? BLANK_STRING
: ".md"
) )
: UNDEF
);
}; // if (dataOrBlob == UNDEF) {
// _isJson = TYPE_OF(dataOrBlob, "object");
_isJson = typeof dataOrBlob == "object";
if (_isJson) {
// dataOrBlob = stringify(dataOrBlob, 0, 4);
dataOrBlob = JSON.stringify(dataOrBlob, 0, 4);
};
if(!!"TESTING") return (
saveDataAsFilenameMime(
dataOrBlob
, filenameOrTrueForNewWindow || (
"DL-" + DATE_NOW() + (
_isJson
? ".json.txt"
: ".md"
)
)
, optionalMimeType || (
_isJson
? "application/json"
: OCTET_STREAM
)
) // end if(!!"TESTING") return (
);
// }; // end let consoleSave = (dataOrBlob, filenameOrTrueForNewWindow, optionalMimeType, _isJson) => {
// ( console.save = consoleSave )();
/**/
} ) )(); // ( console.save = ( (
/**/
// LOGGER(
// ALERT_OBJECT(
// stringify(
// consoleSave()
// "console.save()"
// consoleSave(location, false)
// saveDataAsFilenameMime(location, false)
// )
// );
@DarrenSem

Copy link
Copy Markdown
Author
// BTW, you can learn from this (or any!) minified code by pasting it into https://beautifier.io/
// and then opening the prettier version in Visual Studio Code, using F2 to rename the shortened variable names...



javascript: void
function() {
    let a = Object,
        b = document,
        c = (c, d, e) => {
            let f = URL,
                g = f.createObjectURL(c = new Blob([c], {
                    type: e || c?.type || "application/octet-stream"
                }));
            a.assign(b.createElement("a"), {
                href: g
            }, !0 === d ? {
                target: "_blank"
            } : {
                download: d || ""
            }).click(), f.revokeObjectURL(g)
        },
        d = a => a,
        e = () => {
            if (b.onselectstart && b.onselectstart !== d) return b.onselectstart = d, alert("Text selecting was disabled!\n\nTry again, it is now enabled...");
            let a = b.getSelection(),
                c = a && "Range" === a.type && a.getRangeAt(0),
                e = c && b.createElement("div"),
                f = e ? (e.appendChild(c.cloneContents()), e.innerText) : "";
            return f
        },
        f = a.assign(console, {
            save: (a, d, f) => {
                a == null && (a = e(), "" === a.trim() && (a = b.body.innerText));
                let g = "object" == typeof a;
                g && (a = JSON.stringify(a, 0, 4));
                c(a, d || `DL-${+new Date}.${g?".json.txt":"md"}`, f || (g ? "application/json" : "octet-stream"))
            }
        });
    f.save()
}();



javascript: void
function() {

    let obj = Object,

        doc = document,

        downloadData = (dataOrBlob, filenameOrTrueForNewWindow, optionalMimeType) => {

            let U = URL,

                url = U.createObjectURL(dataOrBlob = new Blob([dataOrBlob], {
                    type: optionalMimeType || dataOrBlob?.type || "application/octet-stream"
                }));

            obj.assign(doc.createElement("a"), {
                href: url
            }, true === filenameOrTrueForNewWindow ? {
                target: "_blank"
            } : {
                download: filenameOrTrueForNewWindow || ""
            })
            .click(),
            
            U.revokeObjectURL(url)
        },

        fnIdentity = v => v,

        getSelectedText = () => {

            if (doc.onselectstart && doc.onselectstart !== fnIdentity) return doc.onselectstart = fnIdentity, alert("Text selecting was disabled!\n\nTry again, it is now enabled...");

            let selection = doc.getSelection(),

                range = selection && "Range" === selection.type && selection.getRangeAt(0),

                element = range && doc.createElement("div"),

                text = element ? (element.appendChild(range.cloneContents()), element.innerText) : "";

            return text

        },

        con = obj.assign(console, {

            save: (data, filename, mimeType) => {

                data == null && (data = getSelectedText(), "" === data.trim() && (data = doc.body.innerText));

                let isJson = "object" == typeof data;
                isJson && (data = JSON.stringify(data, 0, 4));

                downloadData(data, filename || `DL-${+new Date}.${isJson?".json.txt":"md"}`, mimeType || (isJson ? "application/json" : "octet-stream"))

            }
            
        });

    con.save()

}();

@DarrenSem

Copy link
Copy Markdown
Author

PS: try typing console.save(document.location, true) for a surprise!

@DarrenSem

Copy link
Copy Markdown
Author
// DLasMD-console.save

// DOWNLOAD contents as MarkDown.js, plus adds console.save() function

// FULL BOOKMARKLET...

// 15Jan2025 904pm START merging the 2 bookmarklets into 1, on "click" will call DLasMD(), END 1022pm [empty console.save() call no longer selectedText!]
// 741 char  (no need for NULL, just UNDEF) javascript:void function(){let a=document,b=Object,c=b._,d="application/octet-stream",e=console,f=()=>a.body.innerText,g=a=>a,h=(c,e=`DL-${+new Date}.md`,f)=>{let g=URL,h=g.createObjectURL(c=new Blob([c],{type:f||c?.type||d}));b.assign(a.createElement("a"),{href:h},!0===e?{target:"_blank"}:{download:e||""}).click(),g.revokeObjectURL(h)};(e.save||=(a,b,e)=>{if(a==c){let d=prompt("Enter data to download...\n\n(Whitespace or =FILENAME.EXT defaults to document.body.innerText)")?.trim();if(d==c)return c;/^=./.test(d)&&(b=d.slice(1),d=0);a=d.length?d:f(),b=!0===b?b:b?`${b}${b.includes(".")?"":".md"}`:c}let g="object"==typeof a;g&&(a=JSON.stringify(a,0,4));h(a,b||`DL-${+new Date}.${g?".json.txt":"md"}`,e||(g?"application/json":d))})()}();
// ^ final version. Because I didn't comment this clearly on 15Jan2025 130pm.



// [FULL BOOKMARKLET...]

let doc = document;

let obj = Object;

let UNDEF = obj._;

// let DEBUG_DEFAULT_SELECTED_TEXT_NOT_PROMPT = !!"DEBUG_DEFAULT_SELECTED_TEXT_NOT_PROMPT"; // console.save.js
let DEBUG_DEFAULT_SELECTED_TEXT_NOT_PROMPT = !"DEBUG_DEFAULT_SELECTED_TEXT_NOT_PROMPT"; // DLasMD.js

let OCTET_STREAM = "application/octet-stream"; // different than just "octet-stream"

let CON = console; // for final step: ( CON.save ||= consoleSave )();

let bodyText = _ => doc.body.innerText;

let fnIdentity = v => v;



let saveDataAsFilenameMime = (
  dataOrBlob,
  filenameOrTrueForNewWindow = `DL-${+new Date}.md`, // filename extension automatically added based on Blob.type
  optionalMimeType
) => {

  let U = URL;
  let href = U.createObjectURL(
    dataOrBlob = new Blob(
      [dataOrBlob],
      { type: optionalMimeType || dataOrBlob?.type || OCTET_STREAM }
    )
  );

  obj.assign( doc.createElement("a"),
    { href },
    filenameOrTrueForNewWindow === true
    ? { target: "_blank" }
    : { download: filenameOrTrueForNewWindow || "" } // including if <false> or <null> was passed (but not <undefined>)
  ).click();

  U.revokeObjectURL(href);

};



let selectedText = () => {
  if (doc.onselectstart && doc.onselectstart !== fnIdentity) {
    doc.onselectstart = fnIdentity;
    return alert("Text selecting was disabled!\n\nTry again, it is now enabled...");
  };

  let selection = doc.getSelection();
  let range = selection && selection.type === "Range" && selection.getRangeAt(0); // NOT the same as checking this flag: selection.isCollapsed
  let el = range && doc.createElement("div");
  let result = !el ? "" : (
    el.appendChild( range.cloneContents() ),
    el.innerText
  );

  return result;
};

let consoleSave = (dataOrBlob, filenameOrTrueForNewWindow, optionalMimeType) => {

  if (dataOrBlob == UNDEF) {

    // if (DEBUG_DEFAULT_SELECTED_TEXT_NOT_PROMPT) {
    //   dataOrBlob = selectedText();
    //   if (dataOrBlob.trim() === "") {
    //     dataOrBlob = bodyText();
    //   };
    // } else {

      let promptData = prompt(
        "Enter data to download...\n\n(Whitespace or =FILENAME.EXT defaults to document.body.innerText)"
      )?.trim();
  
      if (promptData == UNDEF) return UNDEF;
  
      if ( /^=./.test(promptData) ) {
        filenameOrTrueForNewWindow = promptData.slice(1);
        promptData = 0;
      };
  
      dataOrBlob = promptData.length ? promptData : bodyText();
  
      filenameOrTrueForNewWindow = (
        filenameOrTrueForNewWindow === true ? filenameOrTrueForNewWindow
        : filenameOrTrueForNewWindow ? `${filenameOrTrueForNewWindow}${filenameOrTrueForNewWindow.includes(".") ? "" : ".md"}`
        : UNDEF
      );

    // }; // if (DEBUG_DEFAULT_SELECTED_TEXT_NOT_PROMPT) {

  }; // if (dataOrBlob == UNDEF) {

  let isJson = typeof dataOrBlob === "object";
  if (isJson) {
    dataOrBlob = JSON.stringify(dataOrBlob, 0, 4);
  };

  saveDataAsFilenameMime(
    dataOrBlob,
    filenameOrTrueForNewWindow || `DL-${+new Date}.${isJson ? ".json.txt" : "md"}`,
    optionalMimeType || ( isJson ? "application/json" : OCTET_STREAM )
  );

};



( CON.save ||= consoleSave )();

// [/FULL BOOKMARKLET.]

@DarrenSem

Copy link
Copy Markdown
Author

3 LATEST UPLOADS to GDRV (1127pm + previous 2) -- 17Jul2026

DLasMD 3 most recent versions KEEP ON LAPTOP (1127pm and 2 previous, where I was finally ready to compare)

GDRV of DLasMD.js *new* JS code for STARTING OVER BRAND NEW APPROACH TO ALL MY CODE IS *TOP priority is MAINTAINABILITY, 2nd is TESTABILITY (Extract All The Things!),  3rd is ●SEARCHABILITY (harmonizes with FOO_OBJECT, BAR_PROP, etc; comment out local folder as soon as 2+ uses; again just for the TESTABLE pieces!)
  ●example: RETRY_POLLING_DELAY * RETRY_POLLING_DELAY
  ^ instead of 40 * 40, or 1600
NEW (longer delay was needed...)
...,N=40,k=2*N*N,... ■
  ^ instead of k=3200, esp. since I am already using 40 (and 500) lots!
  FUTURE: even better would be to delay 500 then "wait until toast is gone" OR EVEN BETTER RETRY 40 UNTIL TOAST APPEARS THEN RETRY 40 UNTIL THAT TOAST DISAPPEARS *THEN* RELOAD DLG

  ■ ytDK instead of 40*40, switch to 2x that(no need for 3x though)
So maybe tbh just be 3000 = 75*40

THEN READ COMMENTS I SENT MYSELF THAT SAID WHAT CELL TESTING "ZERO DELAY" WHICH WAS THAT!? PausePlay or some other thing???

Avoid doing the Magic Number of milliseconds for sleep... INSTEAD FIGURE OUT WHICH ELEMENT I EITHER CLICK OR VISIBLY WATCH (e.g. the TOAST) as my default way!

^^^ now REWRITTEN to follow MY NEW STANDARD CODING STYLE!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment