Extension to return old Twitter layout from 2015.
at master 4.5 kB view raw
1let r = document.createElement('a'); 2let hrefUrl = new URL(location.href); 3let searchParams = new URLSearchParams(hrefUrl.search); 4searchParams.delete('newtwitter') 5hrefUrl.search = searchParams.toString(); 6r.href = hrefUrl.toString(); 7setInterval(() => { 8 let hrefUrl = new URL(location.href); 9 let searchParams = new URLSearchParams(hrefUrl.search); 10 searchParams.delete('newtwitter') 11 hrefUrl.search = searchParams.toString(); 12 r.href = hrefUrl.toString(); 13 14 let realPath = location.pathname.split('?')[0].split('#')[0]; 15 if (realPath.endsWith("/")) { 16 realPath = realPath.slice(0, -1); 17 } 18 if( 19 /^\/[A-z-0-9-_]{1,15}\/status\/\d{5,32}\/analytics$/.test(realPath) || 20 (realPath.startsWith('/i/') && realPath !== "/i/bookmarks" && !realPath.startsWith('/i/lists/')) || 21 realPath === '/explore' || 22 realPath === '/login' || 23 realPath === '/register' || 24 realPath === '/logout' || 25 realPath === '/messages' || 26 realPath.endsWith('/tos') || 27 realPath.endsWith('/privacy') || 28 realPath.startsWith('/account/') || 29 realPath.endsWith('/lists') || 30 realPath.endsWith('/topics') || 31 realPath.startsWith('/settings/') 32 ) { 33 r.hidden = true; 34 } else { 35 r.hidden = false; 36 } 37 38 if(!location.search.includes('newtwitter=true')) { 39 let url = new URL(location.href); 40 url.searchParams.set('newtwitter', 'true'); 41 history.replaceState(null, null, url.href); 42 } 43}, 500); 44r.textContent = 'Open this page in OldTwitter'; 45r.style.cssText = 'position: fixed; top: 0; right: 10px; padding: 0.5em; background: #fff; color: #000; font-family: Arial, sans-serif;border-radius:3px;'; 46document.body.appendChild(r); 47 48setTimeout(() => { 49 let realPath = location.pathname.split('?')[0].split('#')[0]; 50 if (realPath.endsWith("/")) { 51 realPath = realPath.slice(0, -1); 52 } 53 if(realPath === '/i/flow/login') { 54 let i = setInterval(() => { 55 let head = document.getElementById('modal-header'); 56 if(head) { 57 clearInterval(i); 58 let span = document.createElement('span'); 59 span.innerHTML = `OldTwitter relies on internal APIs that only work when you're logged in.<br>Please log in on this page to see old Twitter layout.`; 60 span.style.cssText = `display: block;margin: 0.5em 0px;color: #fbfeff;font-family: TwitterChirp;background: rgb(0 161 255 / 10%);padding: 8px;border-radius: 5px;`; 61 head.after(span); 62 } 63 }, 500); 64 } 65}, 1000); 66 67(() => { 68 let keysHeld = {}; 69 function processHotkeys() { 70 if (keysHeld['Alt'] && keysHeld['Control'] && keysHeld['KeyO']) { 71 let url = new URL(location.href); 72 url.searchParams.delete('newtwitter'); 73 location.replace(url.href); 74 } 75 } 76 window.addEventListener('keydown', (ev) => { 77 let key = ev.code; 78 if(key === 'AltLeft' || key === 'AltRight') key = 'Alt'; 79 if(key === 'ControlLeft' || key === 'ControlRight') key = 'Control'; 80 if(key === 'ShiftLeft' || key === 'ShiftRight') key = 'Shift'; 81 keysHeld[key] = true; 82 83 processHotkeys(); 84 }); 85 86 window.addEventListener('keyup', (ev) => { 87 let key = ev.code; 88 if(key === 'AltLeft' || key === 'AltRight') key = 'Alt'; 89 if(key === 'ControlLeft' || key === 'ControlRight') key = 'Control'; 90 if(key === 'ShiftLeft' || key === 'ShiftRight') key = 'Shift'; 91 keysHeld[key] = true; 92 processHotkeys(); 93 keysHeld[key] = false; 94 }); 95})(); 96 97function modifyLink(a) { 98 if(a.href && !a.href.includes('newtwitter=true')) { 99 let url = new URL(a.href); 100 url.searchParams.set('newtwitter', 'true'); 101 a.href = url.href; 102 } 103} 104 105const linkObserver = new MutationObserver((mutations) => { 106 mutations.forEach((mutation) => { 107 if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { 108 mutation.addedNodes.forEach((node) => { 109 if (node.nodeType === Node.ELEMENT_NODE) { 110 if(node.tagName === 'A') { 111 modifyLink(node); 112 } 113 node.querySelectorAll('a').forEach(modifyLink); 114 } 115 }); 116 } 117 }); 118}); 119 120// Start observing the page for changes 121linkObserver.observe(document.documentElement, { childList: true, subtree: true });