Skip to content

Instantly share code, notes, and snippets.

@DarrenSem
Last active June 24, 2024 16:18
Show Gist options
  • Save DarrenSem/7e1216bda80e6269ad53b43d90603158 to your computer and use it in GitHub Desktop.
Save DarrenSem/7e1216bda80e6269ad53b43d90603158 to your computer and use it in GitHub Desktop.
innerText.js bookmarklet for mobile (to show webpage text contents OR html) (including PARTIAL source of SELECTION)
// innerText.js bookmarklet for mobile (to show webpage text contents OR html) (including PARTIAL source of SELECTION)
// https://gist.github.com/DarrenSem/7e1216bda80e6269ad53b43d90603158
// BUGFIXED: 24Jun2024 regressive bug caused role to always be SYSTEM (it was only using the FIRST instance of div.interactive)
// 4322 char javascript:void function(){"use strict";const a=((a,b,c,e,f,g,d,h)=>(b=new Date(a||Date()),[c,e,,f]=b.toLocaleTimeString().replace(/(a|p)\.(m)\./i,"$1$2").split(/\W/),[,,g,d]=b.toString().split(" "),h=b.toLocaleString().replace(/(\d+)-(\d+)-(\d+)/,"$2/$1/$3").split("/")[0].padStart(2,0),`${c}${e}${(f||"").toLowerCase()} ${d}-${h}-${g}`))();let b=`${""} ${a}`;const c=top.document,d=location,e=(a,b)=>(b||c).querySelectorAll(a||null),f=(a,b)=>{let c=a?.innerText;return c==b?b:c.replace(/\n{3,}/g,"\n\n\n").replace(/\n\n/g,"\n")},g=a=>a.trim(),h=(a,b,c)=>{let d,h;c?(d=e("div.interactive>div",a?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement)[0],h=a):h=e(`:scope>div>div>div>div[data-message-author-role]`,a.parentElement)[0];const i=c?d?.innerText:h&&h.dataset.messageAuthorRole,j=f(h);return[(i??"").toUpperCase(),g(j??"")]},i=(a,c,d)=>{const i=e("main",a)[0],j=!i,k=j?e("div.engine-select"):[],l=1<k.length;c=c||[];let m;if(!c.length){if(j)return;m=(!j&&e(`div[role="presentation"]`,i)[0]||{}).parentElement,c=m?e(`div[class~="group/conversation-turn"]`,m):[]}c=[...c];const n=!j&&document.title||"",o=!j&&e(`:scope>div span>[type="button"]:last-child`,i.parentElement.parentElement),p=o.length&&(o[o.length-1]||{}).innerText||"",q=p?`ChatGPT ${p}`:(!j&&e(`:scope>div div>div[type="button"]`,i.parentElement.parentElement)[0]||{}).innerText||"",r=q.replace(/Default |[()-]/g,""),s=r+(r===n?"":`${r&&n?" - ":""}${n}`),t=c[0],u=(a,b)=>{let c=`## ${{user:"ME",assistant:"BOT"}[g((a??"").replace(/[^a-z]+/gi,"")).toLowerCase()]||a}:\n\n${b}\n`;return c};let v,w;const x=j&&t&&"true"===t.contentEditable?[g(t.innerText.replace(/\n\n\n\n/g,"\n"))]:c.map((a,b)=>{if(a.classList.contains("engine-select"))return v=a.innerText,w=!0,l?`# ${v}\n`:"";const[c,d]=h(a,b,j,w),e=d.length?u(c,d):"";return w=!1,e}).filter(a=>a.length);if(j&&d){const a=e("div+div button.role-button",d.parentElement.parentElement.parentElement.parentElement)[0],b=a?.innerText||"USER",c=f(d),g=u(b,c);x.push(g)}x.length&&s&&(x.unshift(`# ${s}\n`),b=g(`${r} ${n}`));const y=x.join("\n".repeat(3));return y},j=(a,b,c)=>{if("CancelSend"===[...a.querySelectorAll("div>textarea+div>button>div")].reduce((a,b)=>a+b.innerText,""))return alert("Retry after you are done editing your prompt.\n\nAKA click [Cancel] or [Send]");const d=i(a,!1,c);if(d)return d;let e=b;return e=e.replace(/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,""),e},k=(a,b)=>{let c=b;const f=d.hostname,h=/\bchat\.openai\.com|\bchatgpt\.com/.test(f),k=h?[1]:e(`div.engine-select,div+div div.interactive div[contenteditable]`),l=(h?e("textarea#prompt-textarea"):e(`div[role="presentation"] div[contenteditable]`))[0],m=l?l["value"in l?"value":"innerText"]:"";if(k.length||g(m).length){const d=g(m).length&&l;if(c=h?j(a,b,d):i(a,k,d),null==c)return null;if(c)return c+"\n"}return /\bblog(ger|spot)\.com\/blog\/post\/edit\b/.test(d)?[...e(`[aria-label="Title"],textarea[class]`)].reduce((a,b)=>a+"\n\n"+b.value,"")||b:b},l=(a,...b)=>{const c=open(URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),"_blank");c&&!c.closed&&(c.onload=()=>{a&&(c.document.title=a)})},m=(a=document)=>{const b=a.getSelection(),d=b&&"Range"===b.type&&b.getRangeAt(0),e=d&&c.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"";return[f,f.length]},n=()=>!0;if(c.onselectstart&&c.onselectstart!==n)c.onselectstart=n,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{let a="";const[e,f]=m(c),h=["innerText","textContent","outerText","innerHTML","outerHTML"],i=/^file:\/\/\/.*\.mht(ml|m|)$/i.test(d.href),j=!1||i?"innerText":f||(a=prompt("index (or body.propertyName):\n\n"+Object.entries(h))),n=()=>{let b,d=e??"";if(!f){try{b=c.body,d=b[h[0]]||"";const a=h[j]||j;if(a in b)d=b[a]??d;else if(a.length){const b=c.documentElement,e="outerText";d=b[e],d=a in b?b[a]??d:(0,eval)(a)??d}}catch(a){}const e=a.length&&"0"!=a&&a!=h[0];return e?d:k(b,d)}return d};if(null!==a){a=g(a+"");const c=n();null!=c&&(!1&&(console.clear(),console.warn(c)),!1||l(b,c))}}}();
// BUGFIXED: 19Jun2024 `role` no longer the ROLE but instead is now still the TEXT CONTENT (aka same as elMessage)
// 4230 char javascript:void function(){"use strict";const e=((e,t,i,r,n,a,d,l)=>(t=new Date(e||Date()),[i,r,,n]=t.toLocaleTimeString().replace(/(a|p)\.(m)\./i,"$1$2").split(/\W/),[,,a,d]=t.toString().split(" "),l=t.toLocaleString().replace(/(\d+)-(\d+)-(\d+)/,"$2/$1/$3").split("/")[0].padStart(2,0),`${i}${r}${(n||"").toLowerCase()} ${d}-${l}-${a}`))();let n=`${""} ${e}`;const t=top.document,d=location,r=(e,n)=>(n||t).querySelectorAll(e||null),a=(e,n)=>{let t=e?.innerText;return t==n?n:t.replace(/\n{3,}/g,"\n\n\n").replace(/\n\n/g,"\n")},l=e=>e.trim(),u=(e,n,t)=>{let d,i;t?(d=r("div.interactive>div")[0],i=e):i=r(`:scope>div>div>div>div[data-message-author-role]`,e.parentElement)[0];const u=t?d?.innerText:i&&i.dataset.messageAuthorRole,o=a(i);return[(u??"").toUpperCase(),l(o??"")]},o=(e,t,d)=>{const i=r("main",e)[0],o=!i,p=o?r("div.engine-select"):[],c=1<p.length;t=t||[];let s;if(!t.length){if(o)return;s=(!o&&r(`div[role="presentation"]`,i)[0]||{}).parentElement,t=s?r(`div[class~="group/conversation-turn"]`,s):[]}t=[...t];const f=!o&&document.title||"",g=!o&&r(`:scope>div span>[type="button"]:last-child`,i.parentElement.parentElement),m=g.length&&(g[g.length-1]||{}).innerText||"",h=m?`ChatGPT ${m}`:(!o&&r(`:scope>div div>div[type="button"]`,i.parentElement.parentElement)[0]||{}).innerText||"",x=h.replace(/Default |[()-]/g,""),T=x+(x===f?"":`${x&&f?" - ":""}${f}`),E=t[0],v=(e,n)=>{let t=`## ${{user:"ME",assistant:"BOT"}[l((e??"").replace(/[^a-z]+/gi,"")).toLowerCase()]||e}:\n\n${n}\n`;return t};let y,b;const S=o&&E&&"true"===E.contentEditable?[l(E.innerText.replace(/\n\n\n\n/g,"\n"))]:t.map((e,n)=>{if(e.classList.contains("engine-select"))return y=e.innerText,b=!0,c?`# ${y}\n`:"";const[t,d]=u(e,n,o,b),i=d.length?v(t,d):"";return b=!1,i}).filter(e=>e.length);if(o&&d){const e=r("div+div button.role-button",d.parentElement.parentElement.parentElement.parentElement)[0],n=e?.innerText||"USER",t=a(d),i=v(n,t);S.push(i)}S.length&&T&&(S.unshift(`# ${T}\n`),n=l(`${x} ${f}`));const L=S.join("\n".repeat(3));return L},p=(e,n,t)=>{if("CancelSend"===[...e.querySelectorAll("div>textarea+div>button>div")].reduce((e,n)=>e+n.innerText,""))return alert("Retry after you are done editing your prompt.\n\nAKA click [Cancel] or [Send]");const d=o(e,!1,t);if(d)return d;let i=n;return i=i.replace(/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,""),i},c=(e,n)=>{let t=n;const i=d.hostname,a=/\bchat\.openai\.com|\bchatgpt\.com/.test(i),u=a?[1]:r(`div.engine-select,div+div div.interactive div[contenteditable]`),c=(a?r("textarea#prompt-textarea"):r(`div[role="presentation"] div[contenteditable]`))[0],s=c?c["value"in c?"value":"innerText"]:"";if(u.length||l(s).length){const d=l(s).length&&c;if(t=a?p(e,n,d):o(e,u,d),null==t)return null;if(t)return t+"\n"}return /\bblog(ger|spot)\.com\/blog\/post\/edit\b/.test(d)?[...r(`[aria-label="Title"],textarea[class]`)].reduce((e,n)=>e+"\n\n"+n.value,"")||n:n},s=(e,...n)=>{const t=open(URL.createObjectURL(new Blob([n.join("\n")],{type:"text/plain;charset=utf-8"})),"_blank");t&&!t.closed&&(t.onload=()=>{e&&(t.document.title=e)})},f=(e=document)=>{const n=e.getSelection(),d=n&&"Range"===n.type&&n.getRangeAt(0),i=d&&t.createElement("div"),r=i?(i.appendChild(d.cloneContents()),i.innerHTML):"";return[r,r.length]},g=()=>!0;if(t.onselectstart&&t.onselectstart!==g)t.onselectstart=g,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{let e="";const[i,r]=f(t),a=["innerText","textContent","outerText","innerHTML","outerHTML"],u=/^file:\/\/\/.*\.mht(ml|m|)$/i.test(d.href),o=!1||u?"innerText":r||(e=prompt("index (or body.propertyName):\n\n"+Object.entries(a))),p=()=>{let n,d=i??"";if(!r){try{n=t.body,d=n[a[0]]||"";const e=a[o]||o;if(e in n)d=n[e]??d;else if(e.length){const n=t.documentElement,i="outerText";d=n[i],d=e in n?n[e]??d:(0,eval)(e)??d}}catch(n){}const i=e.length&&"0"!=e&&e!=a[0];return i?d:c(n,d)}return d};if(null!==e){e=l(e+"");const t=p();null!=t&&(!1&&(console.clear(),console.warn(t)),!1||s(n,t))}}}();
// BUGFIXED: 26May2024 role was sometimes "ASSISTANT[crlf]:" instead of "BOT:" due to "ASSISTANT[crlf]" inside role text; now keeps only Letters
// 4276 char javascript:void function(){"use strict";const a=((a,b,c,e,f,g,d,h)=>(b=new Date(a||Date()),[c,e,,f]=b.toLocaleTimeString().replace(/(a|p)\.(m)\./i,"$1$2").split(/\W/),[,,g,d]=b.toString().split(" "),h=b.toLocaleString().replace(/(\d+)-(\d+)-(\d+)/,"$2/$1/$3").split("/")[0].padStart(2,0),`${c}${e}${(f||"").toLowerCase()} ${d}-${h}-${g}`))();let b=`${""} ${a}`;const c=top.document,d=location,e=(a,b)=>(b||c).querySelectorAll(a||null),f=(a,b)=>{let c=a?.innerText;return c==b?b:c.replace(/\n{3,}/g,"\n\n\n").replace(/\n\n/g,"\n")},g=a=>a.trim(),h=(a,b,c)=>{let d,h;c?(d=e("div",a?.parentElement?.parentElement?.parentElement?.parentElement)[0],h=a):h=e(`:scope>div>div>div>div[data-message-author-role]`,a.parentElement)[0];const i=c?d?.innerText:h&&h.dataset.messageAuthorRole,j=f(h);return[(i??"").toUpperCase(),g(j??"")]},i=(a,c,d)=>{const i=e("main",a)[0],j=!i,k=j?e("div.engine-select"):[],l=1<k.length;c=c||[];let m;if(!c.length){if(j)return;m=(!j&&e(`div[role="presentation"]`,i)[0]||{}).parentElement,c=m?e(`div[class~="group/conversation-turn"]`,m):[]}c=[...c];const n=!j&&document.title||"",o=!j&&e(`:scope>div span>[type="button"]:last-child`,i.parentElement.parentElement),p=o.length&&(o[o.length-1]||{}).innerText||"",q=p?`ChatGPT ${p}`:(!j&&e(`:scope>div div>div[type="button"]`,i.parentElement.parentElement)[0]||{}).innerText||"",r=q.replace(/Default |[()-]/g,""),s=r+(r===n?"":`${r&&n?" - ":""}${n}`),t=c[0],u=(a,b)=>{let c=`## ${{user:"ME",assistant:"BOT"}[g((a??"").replace(/[^a-z]+/gi,"")).toLowerCase()]||a}:\n\n${b}\n`;return c};let v,w;const x=j&&t&&"true"===t.contentEditable?[g(t.innerText.replace(/\n\n\n\n/g,"\n"))]:c.map((a,b)=>{if(a.classList.contains("engine-select"))return v=a.innerText,w=!0,l?`# ${v}\n`:"";const[c,d]=h(a,b,j,w),e=d.length?u(c,d):"";return w=!1,e}).filter(a=>a.length);if(j&&d){const a=e("div+div button.role-button",d.parentElement.parentElement.parentElement.parentElement)[0],b=a?.innerText||"USER",c=f(d),g=u(b,c);x.push(g)}x.length&&s&&(x.unshift(`# ${s}\n`),b=g(`${r} ${n}`));const y=x.join("\n".repeat(3));return y},j=(a,b,c)=>{if("CancelSend"===[...a.querySelectorAll("div>textarea+div>button>div")].reduce((a,b)=>a+b.innerText,""))return alert("Retry after you are done editing your prompt.\n\nAKA click [Cancel] or [Send]");const d=i(a,!1,c);if(d)return d;let e=b;return e=e.replace(/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,""),e},k=(a,b)=>{let c=b;const f=d.hostname,h=/\bchat\.openai\.com|\bchatgpt\.com/.test(f),k=h?[1]:e(`div.engine-select,div+div div.interactive div[contenteditable]`),l=(h?e("textarea#prompt-textarea"):e(`div[role="presentation"] div[contenteditable]`))[0],m=l?l["value"in l?"value":"innerText"]:"";if(k.length||g(m).length){const d=g(m).length&&l;if(c=h?j(a,b,d):i(a,k,d),null==c)return null;if(c)return c+"\n"}return /\bblog(ger|spot)\.com\/blog\/post\/edit\b/.test(d)?[...e(`[aria-label="Title"],textarea[class]`)].reduce((a,b)=>a+"\n\n"+b.value,"")||b:b},l=(a,...b)=>{const c=open(URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),"_blank");c&&!c.closed&&(c.onload=()=>{a&&(c.document.title=a)})},m=(a=document)=>{const b=a.getSelection(),d=b&&"Range"===b.type&&b.getRangeAt(0),e=d&&c.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"";return[f,f.length]},n=()=>!0;if(c.onselectstart&&c.onselectstart!==n)c.onselectstart=n,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{let a="";const[e,f]=m(c),h=["innerText","textContent","outerText","innerHTML","outerHTML"],i=/^file:\/\/\/.*\.mht(ml|m|)$/i.test(d.href),j=!1||i?"innerText":f||(a=prompt("index (or body.propertyName):\n\n"+Object.entries(h))),n=()=>{let b,d=e??"";if(!f){try{b=c.body,d=b[h[0]]||"";const a=h[j]||j;if(a in b)d=b[a]??d;else if(a.length){const b=c.documentElement,e="outerText";d=b[e],d=a in b?b[a]??d:(0,eval)(a)??d}}catch(a){}const e=a.length&&"0"!=a&&a!=h[0];return e?d:k(b,d)}return d};if(null!==a){a=g(a+"");const c=n();null!=c&&(!1&&(console.clear(),console.warn(c)),!1||l(b,c))}}}();
// BUGFIXED: 23May2024 NEW 'Compare Models' feature breaks current scraping logic (thanks to 'GPT-4o' addition!) + (unrelated) handle if Date.toLocaleString() might end with 'a.m.' OR 'p.m.'
// 4273 char javascript:void function(){"use strict";const a=((a,b,c,e,f,g,d,h)=>(b=new Date(a||Date()),[c,e,,f]=b.toLocaleTimeString().replace(/(a|p)\.(m)\./i,"$1$2").split(/\W/),[,,g,d]=b.toString().split(" "),h=b.toLocaleString().replace(/(\d+)-(\d+)-(\d+)/,"$2/$1/$3").split("/")[0].padStart(2,0),`${c}${e}${(f||"").toLowerCase()} ${d}-${h}-${g}`))();let b=`${""} ${a}`;const c=top.document,d=location,e=(a,b)=>(b||c).querySelectorAll(a||null),f=(a,b)=>{let c=a?.innerText;return c==b?b:c.replace(/\n{3,}/g,"\n\n\n").replace(/\n\n/g,"\n")},g=(a,b,c)=>{let d,g;c?(d=e("div",a?.parentElement?.parentElement?.parentElement?.parentElement)[0],g=a):g=e(`:scope>div>div>div>div[data-message-author-role]`,a.parentElement)[0];const h=c?d?.innerText:g&&g.dataset.messageAuthorRole,i=f(g);return[(h??"").toUpperCase(),(i??"").trim()]},h=(a,c,d)=>{const h=e("main",a)[0],j=!h,k=j?e("div.engine-select"):[],l=1<k.length;c=c||[];let m;if(!c.length){if(j)return;m=(!j&&e(`div[role="presentation"]`,h)[0]||{}).parentElement,c=m?e(`div[class~="group/conversation-turn"]`,m):[]}c=[...c];const n=!j&&document.title||"",o=!j&&e(`:scope>div span>[type="button"]:last-child`,h.parentElement.parentElement),p=o.length&&(o[o.length-1]||{}).innerText||"",q=p?`ChatGPT ${p}`:(!j&&e(`:scope>div div>div[type="button"]`,h.parentElement.parentElement)[0]||{}).innerText||"",r=q.replace(/Default |[()-]/g,""),s=r+(r===n?"":`${r&&n?" - ":""}${n}`),t=c[0],u=(a,b)=>`## ${{user:"ME",assistant:"BOT"}[(a??"").trim().replace(/[\u200d]/g,"").toLowerCase()]||a}:\n\n${b}\n`;let v,w;const x=j&&t&&"true"===t.contentEditable?[t.innerText.replace(/\n\n\n\n/g,"\n").trim()]:c.map((a,b)=>{if(a.classList.contains("engine-select"))return v=a.innerText,w=!0,l?`# ${v}\n`:"";const[c,d]=g(a,b,j,w),e=d.length?u(c,d):"";return w=!1,e}).filter(a=>a.length);if(j&&d){const a=e("div+div button.role-button",d.parentElement.parentElement.parentElement.parentElement)[0],b=a?.innerText||"USER",c=u(b,f(d));x.push(c)}x.length&&s&&(x.unshift(`# ${s}\n`),b=`${r} ${n}`.trim());const y=x.join("\n".repeat(3));return y},i=(a,b,c)=>{if("CancelSend"===[...a.querySelectorAll("div>textarea+div>button>div")].reduce((a,b)=>a+b.innerText,""))return alert("Retry after you are done editing your prompt.\n\nAKA click [Cancel] or [Send]");const d=h(a,!1,c);if(d)return d;let e=b;return e=e.replace(/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,""),e},j=(a,b)=>{let c=b;const f=d.hostname,g=/\bchat\.openai\.com|\bchatgpt\.com/.test(f),j=g?[1]:e(`div.engine-select,div+div div.interactive div[contenteditable]`),k=(g?e("textarea#prompt-textarea"):e(`div[role="presentation"] div[contenteditable]`))[0],l=k?k["value"in k?"value":"innerText"]:"";if(j.length||l.trim().length){const d=l.trim().length&&k;if(c=g?i(a,b,d):h(a,j,d),null==c)return null;if(c)return c+"\n"}return /\bblog(ger|spot)\.com\/blog\/post\/edit\b/.test(d)?[...e(`[aria-label="Title"],textarea[class]`)].reduce((a,b)=>a+"\n\n"+b.value,"")||b:b},k=(a,...b)=>{const c=open(URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),"_blank");c&&!c.closed&&(c.onload=()=>{a&&(c.document.title=a)})},l=(a=document)=>{const b=a.getSelection(),d=b&&"Range"===b.type&&b.getRangeAt(0),e=d&&c.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"";return[f,f.length]},m=()=>!0;if(c.onselectstart&&c.onselectstart!==m)c.onselectstart=m,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{let a="";const[e,f]=l(c),g=["innerText","textContent","outerText","innerHTML","outerHTML"],h=/^file:\/\/\/.*\.mht(ml|m|)$/i.test(d.href),i=!1||h?"innerText":f||(a=prompt("index (or body.propertyName):\n\n"+Object.entries(g))),m=()=>{let b,d=e??"";if(!f){try{b=c.body,d=b[g[0]]||"";const a=g[i]||i;if(a in b)d=b[a]??d;else if(a.length){const b=c.documentElement,e="outerText";d=b[e],d=a in b?b[a]??d:(0,eval)(a)??d}}catch(a){}const e=a.length&&"0"!=a&&a!=g[0];return e?d:j(b,d)}return d};if(null!==a){a=(a+"").trim();const c=m();null!=c&&(!1&&(console.clear(),console.warn(c)),!1||k(b,c))}}}();
// FEAT: 05Mar2024 prompt skipped if isLocalFileMHT (but NOT for every "file:" === location.protocol) because MHT files apparently disables prompt() (even when from F12 -- since they won't run Bookmarklets)
// 3458 char javascript:void function(){"use strict";const a=((a,b,c,e,f,g,d,h)=>(b=new Date(a||Date()),[c,e,,f]=b.toLocaleTimeString().split(/\W/),[,,g,d]=b.toString().split(" "),h=b.toLocaleString().split("/")[0].padStart(2,0),`${c}${e}${(f||"").toLowerCase()} ${d}-${h}-${g}`))();let b=`${""} ${a}`;const c=top.document,d=location,e=(a,b)=>(b||c).querySelectorAll(a||null),f=(a,b,c)=>{let d,f,g;c?(d=e(b?"div>div>span.chat-message-role-text":"div",a)[0],f=b?d?.parentElement?.parentElement?.parentElement:a,g=f&&e("div>textarea.text-input",f)[0]):(f=e(":scope>div>div>div+div>div>div>div",a)[0],d=f&&f.parentElement.parentElement.parentElement);const h=c?d?.innerText:d&&d.classList.contains("agent-turn")?"assistant":"user",i=c?g?.value:f?.innerText;return[(h??"").toUpperCase(),(i??"").trim()]},g=(a,c)=>{const d=e("main",a)[0],g=!d;if(c=c||[],!c.length){if(g)return;const a=(!g&&e("div header+div",d)[0]||{}).parentElement;c=a?e(`:scope>header,:scope>div[data-testid]`,a):[]}c=[...c];const h=(!g&&e("h1",d.parentElement.parentElement)[0]||{}).innerText||"",i=(!g&&c.shift()||{}).innerText||"",j=i.replace(/Default |[()-]/g,""),k=j+`${j&&h?" - ":""}`+h,l=c[0],m=g&&l&&"true"===l.contentEditable?[l.innerText.replace(/\n\n\n\n/g,"\n").trim()]:c.map((a,b)=>{const[c,d]=f(a,b,g),e=d.length?`## ${{USER:"ME",ASSISTANT:"BOT"}[c]||c}:\n\n${d}\n`:"";return e}).filter(a=>a.length);m.length&&k&&(m.unshift(`# ${k}\n`),b=`${j} ${h}`.trim());const n=m.join("\n".repeat(3));return n},h=(a,b)=>{const c=g(a);if(c)return c;let d=b;return"Save & SubmitCancel"===[...a.querySelectorAll("div>textarea+div>button>div")].reduce((a,b)=>a+b.innerText,"")?alert("Retry after you are done editing your prompt.\n\nAKA click [Save & Submit] or [Cancel]"):(d=d.replace(/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,""),d)},i=(a,b)=>{let c=b;const f=d.hostname,i=/\bchat.openai\.com/.test(f),j=i?[1]:e(`div.chat-pg-instructions,div.chat-pg-message:not(.add-message),div.completions div[contenteditable]`);if(j.length&&(c=i?h(a,b):g(a,j),c))return c+"\n";return /\bblog(ger|spot)\.com\/blog\/post\/edit\b/.test(d)?[...e(`[aria-label="Title"],textarea[class]`)].reduce((a,b)=>a+"\n\n"+b.value,"")||b:b},j=(a,...b)=>{const c=open(URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),"_blank");c&&!c.closed&&(c.onload=()=>{a&&(c.document.title=a)})},k=(a=document)=>{const b=a.getSelection(),d=b&&"Range"===b.type&&b.getRangeAt(0),e=d&&c.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"";return[f,f.length]},l=()=>!0;if(c.onselectstart&&c.onselectstart!==l)c.onselectstart=l,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{let a="";const[e,f]=k(c),g=["innerText","textContent","outerText","innerHTML","outerHTML"],h=/^file:\/\/\/.*\.mht(ml|m|)$/i.test(d.href),l=h?"innerText":f||(a=prompt("index (or body.propertyName):\n\n"+Object.entries(g))),m=()=>{let b,d=e??"";if(!f){try{b=c.body,d=b[g[0]]||"";const a=g[l]||l;if(a in b)d=b[a]??d;else if(a.length){const b=c.documentElement,e="outerText";d=b[e],d=a in b?b[a]??d:(0,eval)(a)??d}}catch(a){}const e=a.length&&"0"!=a&&a!=g[0];return e?d:i(b,d)}return d};if(null!==a){a=(a+"").trim();const c=m();null!=c&&(!1,j(b,c))}}}();
// FEAT: 26Oct2023 "chat.openai.com/" now properly parses SECTIONS with almost identical logic as "platform.openai.com/playground"
// 3413 char javascript:void function(){"use strict";const a=((a,b,c,e,f,g,d,h)=>(b=new Date(a||Date()),[c,e,,f]=b.toLocaleTimeString().split(/\W/),[,,g,d]=b.toString().split(" "),h=b.toLocaleString().split("/")[0].padStart(2,0),`${c}${e}${(f||"").toLowerCase()} ${d}-${h}-${g}`))();let b=`${""} ${a}`;const c=top.document,d=(a,b)=>(b||c).querySelectorAll(a||null),e=(a,b,c)=>{let e,f,g;c?(e=d(b?"div>div>span.chat-message-role-text":"div",a)[0],f=b?e?.parentElement?.parentElement?.parentElement:a,g=f&&d("div>textarea.text-input",f)[0]):(f=d(":scope>div>div>div+div>div>div>div",a)[0],e=f&&f.parentElement.parentElement.parentElement);const h=c?e?.innerText:e&&e.classList.contains("agent-turn")?"assistant":"user",i=c?g?.value:f?.innerText;return[(h??"").toUpperCase(),(i??"").trim()]},f=(a,c)=>{const f=d("main",a)[0],g=!f;if(c=c||[],!c.length){if(g)return;const a=(!g&&d("div header+div",f)[0]||{}).parentElement;c=a?d(`:scope>header,:scope>div[data-testid]`,a):[]}c=[...c];const h=(!g&&d("h1",f.parentElement.parentElement)[0]||{}).innerText||"",i=(!g&&c.shift()||{}).innerText||"",j=i.replace(/Default |[()-]/g,""),k=j+`${j&&h?" - ":""}`+h,l=c[0],m=g&&l&&"true"===l.contentEditable?[l.innerText.replace(/\n\n\n\n/g,"\n").trim()]:c.map((a,b)=>{const[c,d]=e(a,b,g),f=d.length?`## ${{USER:"ME",ASSISTANT:"BOT"}[c]||c}:\n\n${d}\n`:"";return f}).filter(a=>a.length);m.length&&k&&(m.unshift(`# ${k}\n`),b=`${j} ${h}`.trim());const n=m.join("\n".repeat(3));return n},g=(a,b)=>{const c=f(a);if(c)return c;let d=b;return"Save & SubmitCancel"===[...a.querySelectorAll("div>textarea+div>button>div")].reduce((a,b)=>a+b.innerText,"")?alert("Retry after you are done editing your prompt.\n\nAKA click [Save & Submit] or [Cancel]"):(d=d.replace(/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,""),d)},h=(a,b)=>{let c=b;const e=location,h=e.hostname,i=/\bchat.openai\.com/.test(h),j=i?[1]:d(`div.chat-pg-instructions,div.chat-pg-message:not(.add-message),div.completions div[contenteditable]`);if(j.length&&(c=i?g(a,b):f(a,j),c))return c+"\n";return /\bblog(ger|spot)\.com\/blog\/post\/edit\b/.test(e)?[...d(`[aria-label="Title"],textarea[class]`)].reduce((a,b)=>a+"\n\n"+b.value,"")||b:b},i=(a,...b)=>{const c=open(URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),"_blank");c&&!c.closed&&(c.onload=()=>{a&&(c.document.title=a)})},j=(a=document)=>{const b=a.getSelection(),d=b&&"Range"===b.type&&b.getRangeAt(0),e=d&&c.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"";return[f,f.length]},k=()=>!0;if(c.onselectstart&&c.onselectstart!==k)c.onselectstart=k,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{let a="";const[d,e]=j(c),f=["innerText","textContent","outerText","innerHTML","outerHTML"],g=!1?"innerText":e||(a=prompt("index (or body.propertyName):\n\n"+Object.entries(f))),k=()=>{let b,i=d??"";if(!e){try{b=c.body,i=b[f[0]]||"";const a=f[g]||g;if(a in b)i=b[a]??i;else if(a.length){const b=c.documentElement,d="outerText";i=b[d],i=a in b?b[a]??i:(0,eval)(a)??i}}catch(a){}const d=a.length&&"0"!=a&&a!=f[0];return d?i:h(b,i)}return i};if(null!==a){a=(a+"").trim();const c=k();null!=c&&(!1,i(b,c))}}}();
// FEAT: 13Jul2023 Blogger.com blog post edit - mainly to get title and labels; actual contents are inside a shadow root textarea OR their "html string" = frustratingly inconsistent line breaks >_<
// 2457 char javascript:void function(){const a=top.document,b=(b,c)=>(c||a).querySelectorAll(b||null),c=(a,b)=>{let c=b;return"Save & SubmitCancel"===[...a.querySelectorAll("div>textarea+div>button>div")].reduce((a,b)=>a+b.innerText,"")?alert("Retry after you are done editing your prompt.\n\nAKA click [Save & Submit] or [Cancel]"):(c=c.replace(/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,""),c+"\n")},d=(a,c,d)=>{const e=d[0],f="true"===e.contentEditable?[e.innerText.replace(/\n\n\n\n/g,"\n").trim()]:[...d].map((a,c)=>{const d=b(c?"div>div>span.chat-message-role-text":"div",a)[0],e=(d?.innerText??"").toUpperCase(),f=c?d?.parentElement?.parentElement?.parentElement:a,g=f&&b("div>textarea.text-input",f)[0],h=(g?.value??"").trim(),i=h.length?`## ${{USER:"ME",ASSISTANT:"BOT"}[e]||e}:\n\n${h}\n`:"";return i}).filter(a=>a.length),g=f.join("\n".repeat(3));return g+"\n"},e=(a,e)=>{const f=location,g=f.hostname;if(/\bchat.openai\.com/.test(g))return c(a,e);const h=b(`div.chat-pg-instructions,div.chat-pg-message:not(.add-message),div.completions div[contenteditable]`);return h.length?d(a,e,h):/\bblog(ger|spot)\.com\/blog\/post\/edit\b/.test(f)?[...b(`[aria-label="Title"],textarea[class]`)].reduce((a,b)=>a+"\n\n"+b.value,"")||e:e},f=(...b)=>Object.assign(a.createElement("a"),{href:URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),target:"_blank"}).click(),g=(b=document)=>{const c=b.getSelection(),d=c&&"Range"===c.type&&c.getRangeAt(0),e=d&&a.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"";return[f,f.length]},h=()=>!0;if(a.onselectstart&&a.onselectstart!==h)a.onselectstart=h,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{let b="";const[c,d]=g(a),h=["innerText","textContent","outerText","innerHTML","outerHTML"],i=!1?"innerText":d||(b=prompt("index (or body.propertyName):\n\n"+Object.entries(h))),j=()=>{let f,g=c??"";if(!d){try{f=a.body,g=f[h[0]]||"";const b=h[i]||i;if(b in f)g=f[b]??g;else if(b.length){const c=a.documentElement,d="outerText";g=c[d],g=b in c?c[b]??g:(0,eval)(b)??g}}catch(a){}const c=b.length&&"0"!=b&&b!=h[0];return c?g:e(f,g)}return g};if(null!==b){b=(b+"").trim();const a=j();null!=a&&(!1,f(a))}}}();
// FEAT: 12Jul2023 "## " prefix for ChatGPT sections [ SYSTEM: ME: BOT: ] = more MarkDown-friendly
// 2320 char javascript:void function(){const a=top.document,b=(b,c)=>(c||a).querySelectorAll(b||null),c=(a,b)=>{let c=b;return"Save & SubmitCancel"===[...a.querySelectorAll("div>textarea+div>button>div")].reduce((a,b)=>a+b.innerText,"")?alert("Retry after you are done editing your prompt.\n\nAKA click [Save & Submit] or [Cancel]"):(c=c.replace(/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,""),c+"\n")},d=(a,c,d)=>{const e=d[0],f="true"===e.contentEditable?[e.innerText.replace(/\n\n\n\n/g,"\n").trim()]:[...d].map((a,c)=>{const d=b(c?"div>div>span.chat-message-role-text":"div",a)[0],e=(d?.innerText??"").toUpperCase(),f=c?d?.parentElement?.parentElement?.parentElement:a,g=f&&b("div>textarea.text-input",f)[0],h=(g?.value??"").trim(),i=h.length?`## ${{USER:"ME",ASSISTANT:"BOT"}[e]||e}:\n\n${h}\n`:"";return i}).filter(a=>a.length),g=f.join("\n".repeat(3));return g+"\n"},e=(a,e)=>{const f=location,g=f.hostname;if(/\bchat.openai\.com/.test(g))return c(a,e);const h=b(`div.chat-pg-instructions,div.chat-pg-message:not(.add-message),div.completions div[contenteditable]`);return h.length?d(a,e,h):e},f=(...b)=>Object.assign(a.createElement("a"),{href:URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),target:"_blank"}).click(),g=(b=document)=>{const c=b.getSelection(),d=c&&"Range"===c.type&&c.getRangeAt(0),e=d&&a.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"";return[f,f.length]},h=()=>!0;if(a.onselectstart&&a.onselectstart!==h)a.onselectstart=h,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{let b="";const[c,d]=g(a),h=["innerText","textContent","outerText","innerHTML","outerHTML"],i=!1?"innerText":d||(b=prompt("index (or body.propertyName):\n\n"+Object.entries(h))),j=()=>{let f,g=c??"";if(!d){try{f=a.body,g=f[h[0]]||"";const b=h[i]||i;if(b in f)g=f[b]??g;else if(b.length){const c=a.documentElement,d="outerText";g=c[d],g=b in c?c[b]??g:(0,eval)(b)??g}}catch(a){}const c=b.length&&"0"!=b&&b!=h[0];return c?g:e(f,g)}return g};if(null!==b){b=(b+"").trim();const a=j();null!=a&&(!1,f(a))}}}();
// FEAT: 07Jul2023 recognize OpenAI sections, including "chat.openai.com" and Playground CHAT (not just TEXT)
// 2317 char javascript:void function(){const a=top.document,b=(b,c)=>(c||a).querySelectorAll(b||null),c=(a,b)=>{let c=b;return"Save & SubmitCancel"===[...a.querySelectorAll("div>textarea+div>button>div")].reduce((a,b)=>a+b.innerText,"")?alert("Retry after you are done editing your prompt.\n\nAKA click [Save & Submit] or [Cancel]"):(c=c.replace(/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,""),c+"\n")},d=(a,c,d)=>{const e=d[0],f="true"===e.contentEditable?[e.innerText.replace(/\n\n\n\n/g,"\n").trim()]:[...d].map((a,c)=>{const d=b(c?"div>div>span.chat-message-role-text":"div",a)[0],e=(d?.innerText??"").toUpperCase(),f=c?d?.parentElement?.parentElement?.parentElement:a,g=f&&b("div>textarea.text-input",f)[0],h=(g?.value??"").trim(),i=h.length?`${{USER:"ME",ASSISTANT:"BOT"}[e]||e}:\n\n${h}\n`:"";return i}).filter(a=>a.length),g=f.join("\n".repeat(3));return g+"\n"},e=(a,e)=>{const f=location,g=f.hostname;if(/\bchat.openai\.com/.test(g))return c(a,e);const h=b(`div.chat-pg-instructions,div.chat-pg-message:not(.add-message),div.completions div[contenteditable]`);return h.length?d(a,e,h):e},f=(...b)=>Object.assign(a.createElement("a"),{href:URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),target:"_blank"}).click(),g=(b=document)=>{const c=b.getSelection(),d=c&&"Range"===c.type&&c.getRangeAt(0),e=d&&a.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"";return[f,f.length]},h=()=>!0;if(a.onselectstart&&a.onselectstart!==h)a.onselectstart=h,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{let b="";const[c,d]=g(a),h=["innerText","textContent","outerText","innerHTML","outerHTML"],i=!1?"innerText":d||(b=prompt("index (or body.propertyName):\n\n"+Object.entries(h))),j=()=>{let f,g=c??"";if(!d){try{f=a.body,g=f[h[0]]||"";const b=h[i]||i;if(b in f)g=f[b]??g;else if(b.length){const c=a.documentElement,d="outerText";g=c[d],g=b in c?c[b]??g:(0,eval)(b)??g}}catch(a){}const c=b.length&&"0"!=b&&b!=h[0];return c?g:e(f,g)}return g};if(null!==b){b=(b+"").trim();const a=j();null!=a&&(!1,f(a))}}}();
// BUGFIXED: ( _sel && _sel.type === "Range" && ) 721 char javascript:void function(){const a=top.document,b=(...b)=>Object.assign(a.createElement("a"),{href:URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),target:"_blank"}).click(),c=(b=document,c=b.getSelection(),d=c&&"Range"===c.type&&c.getRangeAt(0),e=d&&a.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"")=>[f,f.length],d=()=>!0;if(a.onselectstart&&a.onselectstart!==d)a.onselectstart=d,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{const[d,e]=c(a),f=["innerText","textContent","outerText","innerHTML","outerHTML"],g=e||(prompt("index (or body.propertyName):\n\n"+Object.entries(f))+"").trim();b(e?d:a.body[f[g]||g]||a.body[f[0]])}}();
// NEW: (now can view SELECTION as PARTIAL source) 703 char javascript:void function(){const a=top.document,b=(...b)=>Object.assign(a.createElement("a"),{href:URL.createObjectURL(new Blob([b.join("\n")],{type:"text/plain;charset=utf-8"})),target:"_blank"}).click(),c=(b=document,c=b.getSelection(),d=c&&c.getRangeAt(0),e=d&&a.createElement("div"),f=e?(e.appendChild(d.cloneContents()),e.innerHTML):"")=>[f,f.length],d=()=>!0;if(a.onselectstart&&a.onselectstart!==d)a.onselectstart=d,alert("Text selecting was disabled!\n\nTry again, it is now enabled...");else{const[d,e]=c(a),f=["innerText","textContent","outerText","innerHTML","outerHTML"],g=e||(prompt("index (or body.propertyName):\n\n"+Object.entries(f))+"").trim();b(e?d:a.body[f[g]||g]||a.body[f[0]])}}();
// OLD: (before allowing partial source selecting) 389 char javascript:void function(){let a=["innerText","textContent","outerText","innerHTML","outerHTML"],b=(prompt("index (or body.propertyName):\n\n"+Object.entries(a))+"").trim();void((...a)=>Object.assign(document.createElement("a"),{href:URL.createObjectURL(new Blob([a.join("\n")],{type:"text/plain;charset=utf-8"})),target:"_blank"}).click())(document.body[a[b]||b]||document.body[a[0]])}();
// example URL https://preactjs.com/repl?example=counter-htm
// What about FRAMES? https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
"use strict";
const DEBUG_FORCED_KEY_TO_SKIP_PROMPT = !"DEBUG_FORCED_KEY_TO_SKIP_PROMPT";
const DEBUG_CONSOLE_WARN_DATA = !"DEBUG_CONSOLE_WARN_DATA";
const DEBUG_SKIP_WINDOW = !"DEBUG_SKIP_WINDOW";
const dtString = (
dateArg,
date,
h, n, ampm,
d, y,
m
) => (
date = new Date(dateArg || Date()),
[h, n, , ampm] = date.toLocaleTimeString().replace(/(a|p)\.(m)\./i, "$1$2").split(/\W/),
[, , d, y] = date.toString().split(" "),
m = date.toLocaleString().replace(/(\d+)-(\d+)-(\d+)/, "$2/$1/$3").split("/")[0].padStart(2, 0),
`${h}${n}${(ampm || "").toLowerCase()} ${y}-${m}-${d}`
);
const now = dtString();
let gloTitle = `${""} ${now}`;
const doc = top.document;
const loc = location;
const qs = (sel, root) => (root || doc).querySelectorAll(sel || null);
const innerTextWithoutDoubleLineBreaks = (el, UNDEFINED) => {
let text = el?.innerText;
return (
text == UNDEFINED
? UNDEFINED
: text.replace(/\n{3,}/g, "\n\n\n").replace(/\n\n/g, "\n")
);
};
const trim = (string) => string.trim();
const getRoleAndText = (section, i, isPlayground, isSystem) => {
let elSystem, elRole, elMessage;
if(isPlayground) {
elRole = qs("div.interactive>div", section?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement)[0];
elMessage = section;
} else {
elMessage = qs(`:scope>div>div>div>div[data-message-author-role]`, section.parentElement)[0];
};
// "assistant" or "user" // this does NOT work: elMessage.dataset["message-author-role"]
const role = isPlayground ? elRole?.innerText : (elMessage && elMessage.dataset["messageAuthorRole"]);
const text = innerTextWithoutDoubleLineBreaks(elMessage);
return [ (role ?? "").toUpperCase(), trim( text ?? "" ) ];
};
const sanitizeOpenAI = (body, sections, inputSection) => {
const main = qs("main", body)[0];
const isPlayground = !main;
const engines = isPlayground ? qs("div.engine-select") : [];
const isComparingPlayground = engines.length > 1;
sections = sections || [];
let mainDiv;
if(!sections.length) {
if(isPlayground)return;
mainDiv = ( !isPlayground && qs(`div[role="presentation"]`, main)[0] || {} ).parentElement;
sections = mainDiv ? qs(
`div[class~="group/conversation-turn"]`
, mainDiv
) : []
};
sections = [...sections];
const summary = ( !isPlayground && document.title ) || "";
const modelsRaw = ( !isPlayground && qs(`:scope>div span>[type="button"]:last-child`, main.parentElement.parentElement) );
const modelRawLast = modelsRaw.length && ( modelsRaw[modelsRaw.length - 1] || {} ).innerText || "";
const modelRaw = modelRawLast ? `ChatGPT ${modelRawLast}` : ( !isPlayground && qs(`:scope>div div>div[type="button"]`, main.parentElement.parentElement)[0] || {} ).innerText || "";
const model = modelRaw.replace(/Default |[()-]/g, "");
const summarySection = model + (
model === summary
? ""
: `${model && summary ? " - " : ""}${summary}`
);
const LINES_BETWEEN_ROLES = 3;
const firstSection = sections[0];
const roleTextString = (role, text) => {
let string = `## ${(
{user: "ME", assistant: "BOT"}[
trim(
( role ?? "" )
.replace(/[^a-z]+/gi, "")
// ^ keep only LETTERS (not even just "words") in the ROLE (instead of maintaining a list of control chars to remove that caused the "ASSISTANT\n:" bug)
// ^ e.g. [\u200d] because .endsWith ZeroWidthJoiner "&zwj;" https://www.codetable.net/decimal/8205
)
.toLowerCase()
] || role
)}:\n\n${text}\n`;
return string;
};
let lastEngine, isSystem;
const convo = isPlayground && firstSection && ("true" === firstSection.contentEditable)
// Playground "TEXT Completions" (legacy)
? [ trim( firstSection.innerText.replace(/\n\n\n\n/g, "\n") ) ]
: sections.map( (section, i) => {
// else WebUI (or Playground "CHAT Completions")
if( section.classList.contains("engine-select") ) {
lastEngine = section.innerText;
isSystem = true;
return (
isComparingPlayground
? `# ${lastEngine}\n`
: ""
);
};
const [role, text] = getRoleAndText(section, i, isPlayground, isSystem);
const message = text.length ? roleTextString(role, text) : "";
isSystem = false;
return message;
})
.filter(text => text.length);
if( isPlayground && inputSection ) {
// main prompt editor textarea (aka CURRENT piece we haven't yet [ADD]ed to conversation, not previous pieces)
const elInputRoleButton = qs("div+div button.role-button", inputSection.parentElement.parentElement.parentElement.parentElement)[0];
const inputRole = elInputRoleButton?.innerText || "USER";
const inputText = innerTextWithoutDoubleLineBreaks(inputSection);
const inputMessage = roleTextString( inputRole, inputText );
convo.push(inputMessage);
};
// ONLY IF !isPlayground
if(convo.length && summarySection) {
convo.unshift(`# ${summarySection}\n`);
gloTitle = trim( `${model} ${summary}` );
};
const result = convo.join("\n".repeat(LINES_BETWEEN_ROLES));
return result;
};
const sanitizeOpenAIWebUI = (body, parts, inputSection) => {
if(
"CancelSend" === [
...body.querySelectorAll("div>textarea+div>button>div")
].reduce( (prev, el) => prev + el.innerText, "" )
) {
return alert("Retry after you are done editing your prompt.\n\nAKA click [Cancel] or [Send]");
};
const resultLikePlayground = sanitizeOpenAI(body, !"sections", inputSection);
if(resultLikePlayground)return resultLikePlayground;
let result = parts;
result = result.replace(
/(^Open sidebar\n)|(\n\nClose sidebar\nChat history\nNew chat)|((\nUpgrade to Plus(\nNEW)?)?\n(\S+@\S+$))|(\n(Free Research Preview. )?(ChatGPT (may produce inaccurate information about people, places, or facts|.+?). )?ChatGPT (\w+ \d+) Version\b)|((\nRegenerate response)?\nChatGPT$)/g,
"");
return result;
};
const sanitizeIfRecognized = (body, parts) => {
let result = parts;
const host = loc.hostname;
const isChatGPTWebUI = ( /\bchat\.openai\.com|\bchatgpt\.com/.test(host) ); // [16May2024: now 'https://chatgpt.com/'!]
// [1] because it is NOT passed to sanitizeOpenAIWebUI(body, parts_instead_of_chatSections, inputSectionText)
const chatSections = isChatGPTWebUI ? [1] : qs(
`div.engine-select,div+div div.interactive div[contenteditable]`
// ^ include engines elements too, so we can ensure we assign chats to proper Model
);
const inputSection = (
isChatGPTWebUI
? qs("textarea#prompt-textarea")
: qs(
`div[role="presentation"] div[contenteditable]`
)
)[0];
const inputSectionText = inputSection ? inputSection[ "value" in inputSection ? "value" : "innerText" ] : "";
if( chatSections.length || trim(inputSectionText).length ) {
const lastSection = trim(inputSectionText).length && inputSection;
result = (
isChatGPTWebUI
? sanitizeOpenAIWebUI(body, parts, lastSection)
: sanitizeOpenAI(body, chatSections, lastSection)
);
if(result == null) return null;
if(result) {
return result + "\n";
};
};
if(/\bblog(ger|spot)\.com\/blog\/post\/edit\b/.test(loc))return (
[...qs(`[aria-label="Title"],textarea[class]`)].reduce(
(prev, el) => prev + "\n\n" + el.value,
""
) || parts
);
return parts;
};
const textInNewWindow = (title, ...data) => {
const win = open(
URL.createObjectURL(
new Blob([data.join("\n")], { type: "text/plain;charset=utf-8" } )
// ^ or new Blob([ [contentsFinal].flat(1/0).join(delim) ]
)
, "_blank"
// ^ open as new tab for [blob:<location.origin>/abc-12-34-def]
);
if(win && !win.closed)win.onload = () => { if(title)win.document.title = title; };
};
const selectedHtml = (_doc = document) => {
const _sel = _doc.getSelection();
// ^ "You can call Window.getSelection(), which works identically to Document.getSelection()." https://developer.mozilla.org/en-US/docs/Web/API/Document/getSelection
const _range = _sel && _sel.type === "Range" && _sel.getRangeAt(0);
// ^ NOT the same as checking this flag: _sel.isCollapsed
const _el = _range && doc.createElement("div");
const _result = !_el ? "" : (
_el.appendChild( _range.cloneContents() ),
_el.innerHTML
);
return [_result, _result.length];
};
const TRUE = () => true;
if(doc.onselectstart && doc.onselectstart !== TRUE) {
doc.onselectstart = TRUE;
alert("Text selecting was disabled!\n\nTry again, it is now enabled...");
} else {
let prompted = "";
const [html, length] = selectedHtml(doc);
const props = [
"innerText",
"textContent",
"outerText",
"innerHTML",
"outerHTML",
];
const reLocalFileMHT = /^file:\/\/\/.*\.mht(ml|m|)$/i;
const isLocalFileMHT = reLocalFileMHT.test(loc.href);
const key = (
(
DEBUG_FORCED_KEY_TO_SKIP_PROMPT
|| isLocalFileMHT
) ? "innerText"
: (
length
|| ( prompted = prompt(
"index (or body.propertyName):\n\n"
+ Object.entries(props)
) )
)
);
const getBodyParts = () => {
let body;
let parts = html ?? "";
if(!length) {
try {
body = doc.body;
parts = body[props[0]] || "";
const propName = props[key] || key;
if(propName in body) {
parts = body[propName] ?? parts;
} else if(propName.length) {
const docElement = doc.documentElement;
const outer = "outerText";
parts = docElement[outer];
if(propName in docElement) {
parts = docElement[propName] ?? parts;
} else {
parts = (0, eval)(propName) ?? parts;
// ^ final step, since eval will throw on most webpages
};
};
} catch(e) {};
const stayRaw = prompted.length && prompted != "0" && prompted != props[0];
return (
stayRaw
? parts
: sanitizeIfRecognized(body, parts)
);
};
return parts;
};
if(prompted !== null) {
prompted = trim( String(prompted) );
const data = getBodyParts();
if(data != null) {
if(DEBUG_CONSOLE_WARN_DATA) {
console.clear();
console.warn(data);
};
if(!DEBUG_SKIP_WINDOW) {
// textInNewWindow(`${gloTitle || document.title || "txt"} ${dtString(Date.now())}`, data);
textInNewWindow(gloTitle, data);
};
};
};
};
@DarrenSem
Copy link
Author

// DL downloadAsMarkDown.js

// javascript:void function(){let a=document,b=prompt("Enter data to download...\n\n(Blank/Empty = document.body.innerText)");null!=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)})(b.trim().length?b:a.body.innerText)}();



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/Empty = document.body.innerText)"
);

if(promptData != null) {
  saveDataAsFilenameMime(
    promptData.trim().length
    ? promptData
    : doc.body.innerText
  )
};

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