SHOW:
|
|
- or go back to the newest paste.
| 1 | - | javascript:(function(){const MAX_IMAGES_PER_POST=10;function replaceDomain(e){return e.replace(/^(https?:\/\/)([^\/]+)/,"$1bsky.app")}function cleanText(e){return e?e.replace(/<a href="([^"]+)"[^>]*>([^<]+)<\/a>/g,(match,url,text)=>(url.startsWith('/')?`[U][URL=https://bsky.app${url}]${text}[/URL][/U]`:`[U][URL=${url}]${text}[/URL][/U]`)).replace(/<br\s*\/?>/g,"\n").replace(/<[^>]+>/g,"").trim():""}function extractMedia(e){const images=Array.from(e.querySelectorAll('img[src*="cdn.bsky.app"]')).map(e=>e.src).filter(e=>!e.includes("/avatar_thumbnail/")),videoSources=new Set([...Array.from(e.querySelectorAll("video source[src]")).map(e=>e.src),...Array.from(e.querySelectorAll("video[src]")).map(e=>e.src)]);return{images,videos:Array.from(videoSources)}}function showToast(e){const t=document.createElement("div");t.style.cssText="position:fixed;bottom:20px;left:20px;padding:10px 20px;background:#333;color:#fff;border-radius:4px;z-index:10000;font-family:Arial,sans-serif;font-size:14px;opacity=1;transition:opacity%201s;box-shadow:0%202px%205px%20rgba(0,0,0,0.3)";t.innerText=e;document.body.appendChild(t);setTimeout(()=>{t.style.opacity="0";setTimeout(()=>document.body.removeChild(t),1e3)},2e3)}function createPostCountPrompt(e){const t=document.createElement("div");t.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;display:flex;justify-content:center;align-items:center";const r=document.createElement("div");r.style.cssText="background:white;padding:20px;border-radius:8px;box-shadow:0%200%2010px%20rgba(0,0,0,0.3);text-align:center";const n=document.createElement("input");n.type="text";n.value="12";n.style.cssText="font-size:30px;width:100px;text-align:center;margin-bottom:20px";const o=document.createElement("div");o.style.cssText="display:grid;grid-template-columns:repeat(3,1fr);gap:10px";"1234567890".split("").forEach(e=>{const t=document.createElement("button");t.textContent=e;t.style.cssText="font-size:20px;padding:10px;cursor:pointer";t.onclick=()=>n.value+=e;o.appendChild(t)});const p=document.createElement("div");p.style.cssText="display:flex;gap:10px;margin-bottom:20px";[1,2,10,25,35,50].forEach(num=>{const b=document.createElement("button");b.textContent=num;b.style.cssText="font-size:16px;padding:8px;cursor:pointer";b.onclick=()=>n.value=num;p.appendChild(b)});const s=document.createElement("button");s.textContent="Clear";s.style.cssText="font-size:18px;margin-top:10px;padding:10px%2020px;cursor:pointer";s.onclick=()=>n.value="";const a=document.createElement("button");a.textContent="Set%20Number%20of%20Posts";a.style.cssText="font-size:18px;margin-top:20px;padding:10px%2020px;cursor:pointer";a.onclick=()=>{const o=parseInt(n.value,10);isNaN(o)||o<=0?showToast("Please%20enter%20a%20valid%20number."):(document.body.removeChild(t),e(o))};r.append(n,p,o,s,a);t.appendChild(r);document.body.appendChild(t)}async function getEmbedUrl(threadData){let url=null;const post=threadData?.thread?.post;if(post?.embed?.$type==="app.bsky.embed.video#view"&&post.embed.playlist){url=post.embed.playlist;console.log("Found%20playlist%20(main):",url)}else if(post?.record?.embed?.$type==="app.bsky.embed.video"&&post.author.did&&post.record.embed.video.ref?.$link){url=constructVideoUrl(post.author.did,post.record.embed.video);console.log("Constructed%20URL%20(main):",url)}return url}function constructVideoUrl(did,videoEmbed){if(videoEmbed.mimeType==="video/webm")return`https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${encodeURIComponent(did)}&cid=${encodeURIComponent(videoEmbed.ref.$link)}`;return`https://video.bsky.app/watch/${encodeURIComponent(did)}/${encodeURIComponent(videoEmbed.ref.$link)}/playlist.m3u8`}async function extractPost(e,isActivePost=false){if(!(e instanceof Element))return console.error("Invalid%20post%20element:",e),{text:"",author:"",url:"",threadData:null};const t=e.querySelector(".css-146c3p1.r-dnmrzs.r-1udh08x.r-1udbk01.r-3s2u2q.r-1iln25a"),r=t?.textContent?.trim()||"Unknown",n=e.querySelector('div[data-word-wrap="1"]')||e.querySelector('[data-testid="postText"]');let o=n?cleanText(n.innerHTML||n.textContent):"",s=e.getAttribute("data-testid")?.match(/postThreadItem-by-(.+)/)?.[1],a=null;if(s){let postId=e.querySelector('[data-testid="postTimestamp"]%20a[href*="/post/"]')?.href.split('/').pop().split('?')[0]||e.querySelector('a[href*="/post/"]')?.href.split('/').pop().split('?')[0]||e.closest('[data-testid^="postThreadItem-by-"]')?.querySelector('a[href*="/post/"]')?.href.split('/').pop().split('?')[0];a=postId?`https://bsky.app/profile/${s}/post/${postId}`:"";if(!postId&&isActivePost){const apiUri=`at://${s}/app.bsky.feed.post/${postId||window.location.href.split('/').pop().split('?')[0]}`,t=`https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${encodeURIComponent(apiUri)}&depth=1`;try{const e=await fetch(t);const i=e.ok?await e.json():null;if(i)postId=i.thread.post.uri.split('/').pop(),a=`https://bsky.app/profile/${s}/post/${postId}`;}catch(e){console.warn("API%20fetch%20for%20post%20ID%20failed:",e);}}}let i=null;if(a&&e.querySelector('video')){const e=`at://${s}/app.bsky.feed.post/${a.split('/').pop()}`,t=`https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${encodeURIComponent(e)}&depth=1`;try{const e=await fetch(t);i=e.ok?await e.json():null;if(i)console.log("API%20data%20for",a,":",i);}catch(e){console.warn("API%20fetch%20failed,%20skipping%20thread%20data:",e);}}const l=extractMedia(e);l.images.slice(0,MAX_IMAGES_PER_POST).forEach(e=>o+=`\n[img]${e}[/img]`);if(i){const videoUrl=await getEmbedUrl(i);if(videoUrl)o+=`\n[U][URL]${videoUrl}[/URL][/U]`;}const normalizeUrl=(url)=>(url.startsWith('/')?`https://bsky.app${url}`:url).replace(/\/+$/,"").toLowerCase();const c=new Set(Array.from(e.querySelectorAll("a[href]")).map(e=>normalizeUrl(e.href)).filter(e=>e.startsWith("http")&&!e.includes("/post/")&&!e.includes("/profile/")&&!o.includes(e)));c.forEach(e=>o+=`\n[U][URL]${e}[/URL][/U]`);const d=e.querySelector('[role="link"][aria-label*="Post%20by"]');let quotedUrl=null;if(d&&isActivePost){const t=d.querySelector('div[data-word-wrap="1"]')?.innerHTML||"";if(t){const quotedHandle=d.querySelector('a[href*="/profile/"]')?.href?.split('/profile/')[1]?.split('/')[0]||"Unknown",quotedPostId=d.querySelector('a[href*="/post/"]')?.href.split('/').pop().split('?')[0];const quotedText=cleanText(t);if(quotedText){o+=`\n\n[QUOTED%20POST]\n%F0%9F%87%BA%20${quotedHandle}\n${quotedText}`;let quotedVideoUrl=null;if(quotedPostId){const quotedUri=`at://${quotedHandle}/app.bsky.feed.post/${quotedPostId}`,quotedApi=`https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${encodeURIComponent(quotedUri)}&depth=0`;try{const res=await fetch(quotedApi);const quotedData=res.ok?await res.json():null;if(quotedData?.thread?.post?.record?.embed?.$type==="app.bsky.embed.video"&"edData?.thread?.post?.author?.did&"edData?.thread?.post?.record?.embed?.video?.ref?.$link){quotedVideoUrl=constructVideoUrl(quotedData.thread.post.author.did,quotedData.thread.post.record.embed.video);console.log("Quoted%20video%20URL%20(API):",quotedVideoUrl);}}catch(e){console.warn("Quoted%20post%20API%20fetch%20failed:",e);}}if(!quotedVideoUrl&&d.querySelector('video[poster]')){const poster=d.querySelector('video[poster]').getAttribute('poster');if(poster.includes('video.bsky.app/watch/')){const parts=poster.split('/');quotedVideoUrl=`https://video.bsky.app/watch/${parts[4]}/${parts[5]}/playlist.m3u8`;console.log("Quoted%20video%20URL%20(poster%20fallback):",quotedVideoUrl);}}if(!quotedVideoUrl&&d.querySelector('video[src^="blob:"]')){quotedVideoUrl=d.querySelector('video[src^="blob:"]').src;console.log("Quoted%20video%20URL%20(blob%20fallback):",quotedVideoUrl);}if(quotedVideoUrl)o+=`\n[U][URL]${quotedVideoUrl}[/URL][/U]`;}quotedUrl=quotedPostId?`https://bsky.app/profile/${quotedHandle}/post/${quotedPostId}`:"";const r=extractMedia(d);r.images.slice(0,MAX_IMAGES_PER_POST).forEach(e=>o+=`\n[img]${e}[/img]`);}}if(i?.thread?.post?.record?.embed?.record&&isActivePost){const qText=cleanText(i.thread.post.record.embed.record.value?.text||"");if(qText){o+=`\n\n[QUOTED%20POST]\n%F0%9F%87%BA%20${i.thread.post.record.embed.record.uri.split('/')[2]}\n${qText}`;if(i.thread.post.record.embed.record.value?.embed?.$type==="app.bsky.embed.video"){const quotedVideoUrl=constructVideoUrl(i.thread.post.record.embed.record.uri.split('/')[2],i.thread.post.record.embed.record.value.embed.video);o+=`\n[U][URL]${quotedVideoUrl}[/URL][/U]`;console.log("Quoted%20video%20URL%20from%20embed:",quotedVideoUrl);}}quotedUrl=`https://bsky.app/profile/${i.thread.post.record.embed.record.uri.split('/')[2]}/post/${i.thread.post.record.embed.record.uri.split('/')[4]}`;}return{text:o,author:s?`%F0%9F%87%BA%20${s}`:"",url:a,threadData:i,quotedUrl}}async function extractPosts(e){const allPosts=Array.from(document.querySelectorAll('[data-testid^="postThreadItem-by-"],%20[data-testid="postThreadItem"]'));if(!allPosts.length)return void showToast("No%20posts%20found%20on%20this%20page.");let activePost=allPosts.find(p=>p.querySelector('a[href*="/post/'+window.location.href.split('/').pop().split('?')[0]+'"]'))||allPosts[0];const activeIndex=allPosts.indexOf(activePost);const{text:activeText,author:activeAuthor,url:activeUrl,threadData:activeThreadData,quotedUrl:activeQuotedUrl}=await extractPost(activePost,true);const r=activePost.querySelector(".css-146c3p1.r-dnmrzs.r-1udh08x.r-1udbk01.r-3s2u2q.r-1iln25a"),n=r?.textContent?.trim()||document.querySelector('[data-testid="profileHandle"]')?.textContent?.trim()||"";if(!n)return void showToast("Could%20not%20determine%20main%20username.");let t=[activePost],parentUrl=null,parentText=null,parentAuthor=null,quotedPostUrl=activeQuotedUrl;let parentFromDom=activeIndex>0?allPosts[activeIndex-1]:null;if(!activeThreadData?.thread?.post?.reply?.parent&&parentFromDom){const{text,author,url}=await extractPost(parentFromDom,false);if(author===activeAuthor||parentFromDom.querySelector(".css-146c3p1.r-dnmrzs.r-1udh08x.r-1udbk01.r-3s2u2q.r-1iln25a")?.textContent?.trim()===n){parentUrl=url;parentText=text;parentAuthor=author;}}if(activeThreadData?.thread?.post?.reply?.parent){const parentUri=activeThreadData.thread.post.reply.parent.uri;const parentAuthorUri=parentUri.split('/')[2];const parentId=parentUri.split('/')[4];parentUrl=`https://bsky.app/profile/${parentAuthorUri}/post/${parentId}`;parentText=cleanText(activeThreadData.thread.post.reply.parent.value?.text||"");parentAuthor=`%F0%9F%87%BA%20${parentAuthorUri}`;const parentQuotedPost=activeThreadData.thread.post.reply.parent.embed?.record;if(parentQuotedPost){const qText=cleanText(parentQuotedPost.value?.text||"");if(qText)parentText+=`\n\n[QUOTED%20POST]\n%F0%9F%87%BA%20${parentQuotedPost.uri.split('/')[2]}\n${qText}`;quotedPostUrl=`https://bsky.app/profile/${parentQuotedPost.uri.split('/')[2]}/post/${parentQuotedPost.uri.split('/')[4]}`;}t=[{text:parentText,author:parentAuthor,url:parentUrl},...t];}t=[...t,...allPosts.slice(activeIndex+1,activeIndex+e)];if(t.length>e)t=t.slice(0,e);let mainPostUrls=new Set([activeUrl]);if(parentAuthor===activeAuthor&&parentUrl)mainPostUrls.add(parentUrl);let s=parentText?[{author:parentAuthor,text:parentText},{author:activeAuthor,text:activeText}]:[{author:activeAuthor,text:activeText}],a=0,i=parentText?2:1,l=[];for(const[r,c]of t.entries()){if(r===0)continue;const{text:d,author:p,url:u,threadData}=await extractPost(c,false);if(!d&&!u&&!extractMedia(c).images.length)continue;if(u&&p===`%F0%9F%87%BA%20${n}`&&u!==activeUrl&&u!==parentUrl)mainPostUrls.add(u);s.push({author:p,text:d});a+=(d.match(/$$img$$/g)||[]).length;i++;if(a>=20||r===t.length-1||r===e-1){const hasThreads=parentUrl&&parentUrl!==activeUrl||[...mainPostUrls].some(u=>u!==activeUrl)||quotedPostUrl&"edPostUrl!==activeUrl;l.push(`${activeUrl||replaceDomain(window.location.href.split("?")[0])}${hasThreads?`\n[SPOILER="Threads%20Continued"]${parentUrl&&parentUrl!==activeUrl?`\n${parentUrl}`:""}${[...mainPostUrls].filter(u=>u!==activeUrl).length>0?`\n${[...mainPostUrls].filter(u=>u!==activeUrl).join("\n")}`:""}${quotedPostUrl&"edPostUrl!==activeUrl?`\n${quotedPostUrl}`:""}\n[/SPOILER]`:""}\n[SPOILER="full%20text%20&%20large%20images"]\n\n${s.map((e,t)=>`${t+1}/${s.length}\n${e.author}\n${e.text}`).join("\n\n")}\n\n[COLOR=rgb(184,49,47)][B][SIZE=5]To%20post%20tweets%20in%20this%20format,%20more%20info%20here:%20[URL]https://www.thecoli.com/threads/tips-and-tricks-for-posting-the-coli-megathread.984734/post-52211196[/URL][/SIZE][/B][/COLOR]\n[/SPOILER]`);s=parentText?[{author:parentAuthor,text:parentText},{author:activeAuthor,text:activeText}]:[{author:activeAuthor,text:activeText}];a=0;}}if(s.length&&!l.length){const hasThreads=parentUrl&&parentUrl!==activeUrl||[...mainPostUrls].some(u=>u!==activeUrl)||quotedPostUrl&"edPostUrl!==activeUrl;l.push(`${activeUrl||replaceDomain(window.location.href.split("?")[0])}${hasThreads?`\n[SPOILER="Threads%20Continued"]${parentUrl&&parentUrl!==activeUrl?`\n${parentUrl}`:""}${[...mainPostUrls].filter(u=>u!==activeUrl).length>0?`\n${[...mainPostUrls].filter(u=>u!==activeUrl).join("\n")}`:""}${quotedPostUrl&"edPostUrl!==activeUrl?`\n${quotedPostUrl}`:""}\n[/SPOILER]`:""}\n[SPOILER="full%20text%20&%20large%20images"]\n\n${s.map((e,t)=>`${t+1}/${s.length}\n${e.author}\n${e.text}`).join("\n\n")}\n\n[COLOR=rgb(184,49,47)][B][SIZE=5]To%20post%20tweets%20in%20this%20format,%20more%20info%20here:%20[URL]https://www.thecoli.com/threads/tips-and-tricks-for-posting-the-coli-megathread.984734/post-52211196[/URL][/SIZE][/B][/COLOR]\n[/SPOILER]`);}const c=l.join("\n\n[threads%20continued]\n\n"),d=document.createElement("textarea");d.value=c;document.body.appendChild(d);d.select();document.execCommand("copy");document.body.removeChild(d);showToast(`Copied:%20${i}%20posts`)}createPostCountPrompt(extractPosts)})();
|
| 1 | + | javascript:(function() {
|
| 2 | - | |
| 2 | + | var textareas = document.querySelectorAll('textarea.input');
|
| 3 | textareas.forEach(function(textarea) {
| |
| 4 | var text = textarea.value; | |
| 5 | ||
| 6 | ||
| 7 | var pattern1 = /$$\s*URL=(.*?)\s*\$\$(.*?)\s*\/\s*URL\s*$$/gi; | |
| 8 | var pattern2 = /$$\s*URL\s*\$\$(.*?)\s*\/\s*URL\s*$$/gi; | |
| 9 | replacedText = text.replace(pattern1, '[U][URL=$1]$2[/URL][/U]'); | |
| 10 | replacedText = replacedText.replace(pattern2, '[U][URL]$1[/URL][/U]'); | |
| 11 | replacedText = replacedText.replace(/$$U$$\$\$U\$\$URL=(.*?)\/URL\$\$\/U\$\$\/U$$/g, '[U][URL=$1[/URL][/U]'); | |
| 12 | ||
| 13 | ||
| 14 | var existingUrlPattern = /\[URL=(.*?)\](.*?)\[\/URL\]/gi; | |
| 15 | replacedText = replacedText.replace(existingUrlPattern, '[U][URL=$1]$2[/URL][/U]'); | |
| 16 | ||
| 17 | var existingUrlSimplePattern = /\[URL\](.*?)\[\/URL\]/gi; | |
| 18 | replacedText = replacedText.replace(existingUrlSimplePattern, '[U][URL]$1[/URL][/U]'); | |
| 19 | ||
| 20 | var pattern3 = /(\n)([A-Z"]|\d|$$B$$|$$I$$|$$IMG$$)/g; | |
| 21 | var pattern6 = /($$HEADING=2$$|$$LIST$$|$$\*$$|$$\/LIST$$|$$IMG$$)/g; | |
| 22 | replacedText = replacedText.replace(pattern6, '\n$1'); | |
| 23 | replacedText = replacedText.replace(/$$\/HEADING$$\n/g, '[/HEADING]\n'); | |
| 24 | replacedText = replacedText.replace(/$$\/IMG$$\n/g, '[/IMG]\n'); | |
| 25 | replacedText = replacedText.replace(/\[\/LIST\]/g, '[/LIST]\n'); | |
| 26 | ||
| 27 | var pattern4 = /$$IMG alt="([^"]*)"/g; | |
| 28 | var pattern9 = /\$\$\/IMG$$([A-Za-z0-9])/g; | |
| 29 | replacedText = replacedText.replace(pattern4, '\n[IMG alt="$1"] '); | |
| 30 | replacedText = replacedText.replace(pattern9, '[/IMG] $1'); | |
| 31 | ||
| 32 | var pattern5 = /\n/g; | |
| 33 | var pattern10 = /^\n+|\n{2,}|\n+$/g;
| |
| 34 | replacedText = replacedText.replace(pattern5, '\n'); | |
| 35 | replacedText = replacedText.replace(pattern10, '\n'); | |
| 36 | ||
| 37 | var pattern7 = /$$\/?FONT(=.*?)?$$/g; | |
| 38 | var pattern8 = /$$\/?COLOR(=.*?)?$$/g; | |
| 39 | replacedText = replacedText.replace(pattern7, ''); | |
| 40 | replacedText = replacedText.replace(pattern8, ''); | |
| 41 | ||
| 42 | replacedText = replacedText.replace(/\$\$B\$\$(.*?)\$\$\/B\$\$/g, '[B]$1[/B]'); | |
| 43 | replacedText = replacedText.replace(/\$\$I\$\$(.*?)\$\$\/I\$\$/g, '[I]$1[/I]'); | |
| 44 | ||
| 45 | var mathPattern = /\$\$(.*?)\$\$/g; | |
| 46 | replacedText = replacedText.replace(mathPattern, '\$$$1\$$'); | |
| 47 | ||
| 48 | var paragraphPattern = /([^\n])\n([A-Z0-9])/g; | |
| 49 | replacedText = replacedText.replace(paragraphPattern, '$1\n\n$2'); | |
| 50 | ||
| 51 | var quotePattern = /$$QUOTE$$(?:.*?\n)*?(.*?)$$\/QUOTE$$/gs; | |
| 52 | replacedText = replacedText.replace(quotePattern, '[QUOTE][SIZE=4]$1[/SIZE][/QUOTE]'); | |
| 53 | ||
| 54 | const emptyListItemsPattern = /\[LIST\](\n\[\*\]\s*)+\[\/LIST\]/gi; | |
| 55 | replacedText = replacedText.replace(emptyListItemsPattern, ''); | |
| 56 | const emptyListBlockPattern = /\[LIST\]\s*\[\/LIST\]/gi; | |
| 57 | replacedText = replacedText.replace(emptyListBlockPattern, ''); | |
| 58 | ||
| 59 | replacedText = replacedText.replace(/\[B\]\[\/B\]/g, ''); | |
| 60 | replacedText = replacedText.replace(/\[I\]\[\/I\]/g, ''); | |
| 61 | ||
| 62 | textarea.value = replacedText; | |
| 63 | }); | |
| 64 | })(); |