Skip to content

Instantly share code, notes, and snippets.

@DarrenSem
Last active March 5, 2024 22:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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
// 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 dtString = (
dateArg,
date,
h, n, ampm,
d, y,
m
) => (
date = new Date(dateArg || Date()),
[h, n, , ampm] = date.toLocaleTimeString().split(/\W/),
[, , d, y] = date.toString().split(" "),
m = date.toLocaleString().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 getRoleAndText = (section, i, isPlayground) => {
let elRole, elMessage, elTextArea;
if(isPlayground) {
elRole = qs(!i ? "div" : "div>div>span.chat-message-role-text", section)[0];
elMessage = !i ? section : elRole?.parentElement?.parentElement?.parentElement;
elTextArea = elMessage && qs("div>textarea.text-input", elMessage)[0];
} else {
elMessage = qs(":scope>div>div>div+div>div>div>div", section)[0];
elRole = elMessage && elMessage.parentElement.parentElement.parentElement;
};
const role = isPlayground ? elRole?.innerText : (elRole && elRole.classList.contains("agent-turn") ? "assistant" : "user" );
const text = isPlayground ? elTextArea?.value : elMessage?.innerText;
return [ (role ?? "").toUpperCase(), (text ?? "").trim() ];
};
const sanitizeOpenAI = (body, sections) => {
// https://chat.openai.com/ BEFORE the previous text-only logic in sanitizeOpenAIChat()
const main = qs("main", body)[0];
const isPlayground = !main;
sections = sections || [];
if(!sections.length) {
if(isPlayground)return;
// sections = [] so grab from mainDiv, since location = https://chat.openai.com/
const mainDiv = ( !isPlayground && qs("div header+div", main)[0] || {} ).parentElement;
sections = mainDiv ? qs(
`:scope>header,:scope>div[data-testid]`
, mainDiv
) : []
};
sections = [...sections];
// extra info when location = https://chat.openai.com/
const summary = ( !isPlayground && qs("h1", main.parentElement.parentElement)[0] || {} ).innerText || "";
const modelRaw = ( !isPlayground && sections.shift() || {} ).innerText || "";
const model = modelRaw.replace(/Default |[()-]/g, "");
const summarySection = model + `${model && summary ? " - " : ""}` + summary;
const LINES_BETWEEN_ROLES = 3;
const firstSection = sections[0];
const convo = isPlayground && firstSection && ("true" === firstSection.contentEditable)
// Playground "TEXT Completions" (legacy)
? [firstSection.innerText.replace(/\n\n\n\n/g, "\n").trim()]
: sections.map( (section, i) => {
// else WebUI (or Playground "CHAT Completions")
const [role, text] = getRoleAndText(section, i, isPlayground);
const message = text.length
? `## ${(
{USER: "ME", ASSISTANT: "BOT"}[role]
|| role
)}:\n\n${text}\n`
: "";
return message;
})
.filter(text => text.length);
if(convo.length && summarySection) {
convo.unshift(`# ${summarySection}\n`);
gloTitle =`${model} ${summary}`.trim();
};
const result = convo.join("\n".repeat(LINES_BETWEEN_ROLES));
return result;
};
const sanitizeOpenAIWebUI = (body, parts) => {
// https://chat.openai.com/
const resultLikePlayground = sanitizeOpenAI(body);
if(resultLikePlayground)return resultLikePlayground;
let result = parts;
if(
"Save & SubmitCancel" === [
...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 [Save & Submit] or [Cancel]");
};
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/.test(host) );
const chatSections = isChatGPTWebUI ? [1] : qs(
`div.chat-pg-instructions,div.chat-pg-message:not(.add-message),div.completions div[contenteditable]`
);
if(chatSections.length) {
result = (
isChatGPTWebUI
? sanitizeOpenAIWebUI(body, parts)
: sanitizeOpenAI(body, chatSections)
);
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 = (
(
"xyzDEBUG_FORCED_KEY_TO_SKIP_PROMPT" === "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 = String(prompted).trim();
const data = getBodyParts();
if(data != null) {
if("xyzDEBUG_CONSOLE_WARN_DATA" === "DEBUG_CONSOLE_WARN_DATA") {
console.warn(data);
};
if("xyzDEBUG_SKIP_WINDOW" !== "DEBUG_SKIP_WINDOW") {
textInNewWindow(gloTitle, data);
};
};
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment