Embed Tweets in an iframe - https://tf.rita.moe
at main 4.4 kB view raw
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>twitframe</title> 7 <meta name="description" content="Embed Tweets in an iframe" /> 8 <style> 9 body { 10 font-family: helvetica neue, arial, sans-serif; 11 padding-top: 1px; 12 } 13 14 #brand { 15 background-color: #fbfbfb; 16 color: #bbb; 17 font-size: 8pt; 18 left: 0px; 19 opacity: 0.2; 20 padding-left: 0.5rem; 21 padding-right: 0.5rem; 22 position: absolute; 23 top: 0px; 24 } 25 26 #brand a { 27 color: #aaa; 28 text-decoration: none; 29 } 30 31 blockquote.twitter-tweet { 32 margin: 1rem auto; 33 } 34 35 #author_name { 36 font-weight: bold; 37 } 38 </style> 39</head> 40<body> 41 <span id="brand"> 42 <a href="https://tf.rita.moe/?ref=t" target="_blank">twitframe</a> 43 </span> 44 <blockquote class="twitter-tweet" id="t"> 45 <span id="author_name"></span> 46 <span id="author_username"></span> 47 <p> 48 <span id="tweet"></span> 49 </p> 50 <a id="date" target="_blank"></a> 51 </blockquote> 52 <script> 53 const params = {} 54 const searchParams = new URLSearchParams(window.location.search) 55 for (const [key, value] of searchParams.entries()) { 56 params[key] = value.replace(/\+/g, ' ') 57 } 58 59 const url = params['url']?.replace('x.com', 'twitter.com') || '' 60 const datetime = (params['datetime'] || 0) 61 const tweet = (params['tweet'] ? params['tweet'] : 'Loading tweet...') 62 const authorName = (params['author_name'] ? params['author_name'] : '') 63 const align = params['align'] 64 const linkColor = params['link_color'] 65 const theme = params['theme'] 66 const conversation = params['conversation'] 67 const cards = params['cards'] 68 const lang = params['lang'] 69 70 let authorUsername = (params['author_username'] ? params['author_username'] : '') 71 let formattedDate = 'Unknown date' 72 73 const m = url.match(/^(?:https?:)?\/\/(?:www\.)?twitter\.com\/([^/]+)\//) 74 if (m && !authorUsername) { 75 authorUsername = m[1] 76 } 77 78 if (authorUsername && authorUsername.substr(0, 1) !== '@') { 79 authorUsername = '@' + authorUsername 80 } 81 82 if (datetime) { 83 const d = new Date(datetime * 1000) 84 formattedDate = d.toDateString() 85 } 86 87 const t = document.getElementById('t') 88 if (align) { 89 t.align = align 90 } 91 if (linkColor) { 92 t.setAttribute('data-link-color', linkColor) 93 } 94 if (theme) { 95 t.setAttribute('data-theme', theme) 96 } 97 if (conversation) { 98 t.setAttribute('data-conversation', conversation) 99 } 100 if (cards) { 101 t.setAttribute('data-cards', cards) 102 } 103 if (lang) { 104 t.setAttribute('data-lang', lang) 105 } 106 107 if (authorName) { 108 document.getElementById('author_name').innerText = authorName 109 } 110 if (authorUsername) { 111 document.getElementById('author_username').innerText = authorUsername 112 } 113 114 document.getElementById('tweet').innerText = tweet 115 116 document.getElementById('date').href = url 117 document.getElementById('date').innerText = formattedDate 118 119 if (!params['force_fail']) { 120 const s = document.createElement('script') 121 s.src = 'https://platform.twitter.com/widgets.js' 122 document.body.appendChild(s) 123 } 124 125 let caller 126 const saveCaller = (e) => { 127 if (e.data.element) { 128 caller = e 129 sendResponse() 130 } 131 } 132 133 if (window.addEventListener) { 134 window.addEventListener('message', saveCaller, false) 135 } else { 136 window.attachEvent('onmessage', saveCaller) 137 } 138 139 let lastHeight = 0 140 const loadedTime = window.performance ? window.performance.now() : 0 141 const checkHeight = () => { 142 if (document.body.scrollHeight !== lastHeight && caller) { 143 lastHeight = document.body.scrollHeight 144 sendResponse() 145 } 146 147 /* give up after a while to save cpu */ 148 if (window.performance && (window.performance.now() - loadedTime > (10 * 1000))) { 149 return 150 } 151 152 window.requestAnimationFrame(checkHeight) 153 } 154 window.requestAnimationFrame(checkHeight) 155 156 const sendResponse = () => { 157 if (caller.data.query === 'height') { 158 caller.source.postMessage( 159 { 160 element: caller.data.element, 161 height: document.body.scrollHeight + 20, 162 }, 163 caller.origin, 164 ) 165 } 166 } 167 </script> 168</body> 169</html>