Last active
June 24, 2024 16:18
-
-
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)
This file contains 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
// 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 "‍" 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); | |
}; | |
}; | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
// DL downloadAsMarkDown.js