Skip to content

Instantly share code, notes, and snippets.

@DarrenSem
Last active March 8, 2025 18:14
Show Gist options
  • Save DarrenSem/444cc1c0539226a4902e7f265f23820f to your computer and use it in GitHub Desktop.
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 - DOWNLOAD contents as MarkDown.js
// old as of 15Jan2025; start using DLasMD-console.save.js
// 27Dec2024 1053am NEW promptData rules (Blank or Empty or =FILENAME.EXT defaults to document.body.innerText)
// 477 char javascript:void function(){let a=document,b=(b,c=`DL-${+new Date}.md`,d="octet-stream")=>{let e=URL.createObjectURL(new Blob([b],{type:d}));Object.assign(a.createElement("a"),{href:e,download:c}).click(),URL.revokeObjectURL(e)},c=prompt("Enter data to download...\n\n(Blank or Empty or =FILENAME.EXT defaults to document.body.innerText)")?.trim();if(null!=c){let d=c.startsWith("=")&&c.slice(1);b(c.length&&!d?c:a.body.innerText,d?`${d}${d.includes(".")?"":".md"}`:void 0)}}();
let doc=document;
let saveDataAsFilenameMime = (
data,
filename=`DL-${+new Date}.md`,
mimeType = "octet-stream"
) => {
let href = URL.createObjectURL(
new Blob(
[data],
{ type: mimeType }
)
);
Object.assign(
doc.createElement("a"),
{ href, download: filename }
).click();
URL.revokeObjectURL(href);
};
let promptData = prompt(
"Enter data to download...\n\n(Blank or Empty or =FILENAME.EXT defaults to document.body.innerText)"
)?.trim();
if(promptData != null) {
let filename = promptData.startsWith("=") && promptData.slice(1);
saveDataAsFilenameMime(
promptData.length && !filename
? promptData
: doc.body.innerText
, filename ? `${filename}${filename.includes(".") ? "" : ".md"}` : undefined
)
};
// 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`)
// 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))})()}();
// ^ Bookmarklet (741 char) -- drag-and-drop add this to your web browser's Favorites
// (15Jan2025; stop using old "DLasMD - DOWNLOAD contents as MarkDown.js")
// inspired by the simple idea @ https://coderwall.com/p/prhwzg/add-console-save-to-chrome https://archive.is/cWiF6
// this GIST url: https://gist.github.com/DarrenSem/444cc1c0539226a4902e7f265f23820f
@DarrenSem
Copy link
Author

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

@DarrenSem
Copy link
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.]

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