1/********************************************************************* 2* #### Twitter Post Fetcher v17.0.2 #### 3* Coded by Jason Mayes 2015. A present to all the developers out there. 4* www.jasonmayes.com 5* Please keep this disclaimer with my code if you use it. Thanks. :-) 6* Got feedback or questions, ask here: 7* http://www.jasonmayes.com/projects/twitterApi/ 8* Github: https://github.com/jasonmayes/Twitter-Post-Fetcher 9* Updates will be posted to this site. 10*********************************************************************/ 11(function(root, factory) { 12 if (typeof define === 'function' && define.amd) { 13 // AMD. Register as an anonymous module. 14 define([], factory); 15 } else if (typeof exports === 'object') { 16 // Node. Does not work with strict CommonJS, but 17 // only CommonJS-like environments that support module.exports, 18 // like Node. 19 module.exports = factory(); 20 } else { 21 // Browser globals. 22 factory(); 23 } 24}(this, function() { 25 var domNode = ''; 26 var maxTweets = 20; 27 var parseLinks = true; 28 var queue = []; 29 var inProgress = false; 30 var printTime = true; 31 var printUser = true; 32 var formatterFunction = null; 33 var supportsClassName = true; 34 var showRts = true; 35 var customCallbackFunction = null; 36 var showInteractionLinks = true; 37 var showImages = false; 38 var useEmoji = false; 39 var targetBlank = true; 40 var lang = 'en'; 41 var permalinks = true; 42 var dataOnly = false; 43 var script = null; 44 var scriptAdded = false; 45 46 function handleTweets(tweets){ 47 if (customCallbackFunction === null) { 48 var x = tweets.length; 49 var n = 0; 50 var element = document.getElementById(domNode); 51 var html = '<ul>'; 52 while(n < x) { 53 html += '<li>' + tweets[n] + '</li>'; 54 n++; 55 } 56 html += '</ul>'; 57 element.innerHTML = html; 58 } else { 59 customCallbackFunction(tweets); 60 } 61 } 62 63 function strip(data) { 64 return data.replace(/<b[^>]*>(.*?)<\/b>/gi, function(a,s){return s;}) 65 .replace(/class="(?!(tco-hidden|tco-display|tco-ellipsis))+.*?"|data-query-source=".*?"|dir=".*?"|rel=".*?"/gi, 66 ''); 67 } 68 69 function targetLinksToNewWindow(el) { 70 var links = el.getElementsByTagName('a'); 71 for (var i = links.length - 1; i >= 0; i--) { 72 links[i].setAttribute('target', '_blank'); 73 } 74 } 75 76 function getElementsByClassName (node, classname) { 77 var a = []; 78 var regex = new RegExp('(^| )' + classname + '( |$)'); 79 var elems = node.getElementsByTagName('*'); 80 for (var i = 0, j = elems.length; i < j; i++) { 81 if(regex.test(elems[i].className)){ 82 a.push(elems[i]); 83 } 84 } 85 return a; 86 } 87 88 function extractImageUrl(image_data) { 89 if (image_data !== undefined && image_data.innerHTML.indexOf('data-srcset') >= 0) { 90 var data_src = image_data.innerHTML 91 .match(/data-srcset="([A-z0-9%_\.-]+)/i)[0]; 92 return decodeURIComponent(data_src).split('"')[1]; 93 } 94 } 95 96 var twitterFetcher = { 97 fetch: function(config) { 98 if (config.maxTweets === undefined) { 99 config.maxTweets = 20; 100 } 101 if (config.enableLinks === undefined) { 102 config.enableLinks = true; 103 } 104 if (config.showUser === undefined) { 105 config.showUser = true; 106 } 107 if (config.showTime === undefined) { 108 config.showTime = true; 109 } 110 if (config.dateFunction === undefined) { 111 config.dateFunction = 'default'; 112 } 113 if (config.showRetweet === undefined) { 114 config.showRetweet = true; 115 } 116 if (config.customCallback === undefined) { 117 config.customCallback = null; 118 } 119 if (config.showInteraction === undefined) { 120 config.showInteraction = true; 121 } 122 if (config.showImages === undefined) { 123 config.showImages = false; 124 } 125 if (config.useEmoji === undefined) { 126 config.useEmoji = false; 127 } 128 if (config.linksInNewWindow === undefined) { 129 config.linksInNewWindow = true; 130 } 131 if (config.showPermalinks === undefined) { 132 config.showPermalinks = true; 133 } 134 if (config.dataOnly === undefined) { 135 config.dataOnly = false; 136 } 137 138 if (inProgress) { 139 queue.push(config); 140 } else { 141 inProgress = true; 142 143 domNode = config.domId; 144 maxTweets = config.maxTweets; 145 parseLinks = config.enableLinks; 146 printUser = config.showUser; 147 printTime = config.showTime; 148 showRts = config.showRetweet; 149 formatterFunction = config.dateFunction; 150 customCallbackFunction = config.customCallback; 151 showInteractionLinks = config.showInteraction; 152 showImages = config.showImages; 153 useEmoji = config.useEmoji; 154 targetBlank = config.linksInNewWindow; 155 permalinks = config.showPermalinks; 156 dataOnly = config.dataOnly; 157 158 var head = document.getElementsByTagName('head')[0]; 159 if (script !== null) { 160 head.removeChild(script); 161 } 162 script = document.createElement('script'); 163 script.type = 'text/javascript'; 164 if (config.list !== undefined) { 165 script.src = 'https://syndication.twitter.com/timeline/list?' + 166 'callback=__twttrf.callback&dnt=false&list_slug=' + 167 config.list.listSlug + '&screen_name=' + config.list.screenName + 168 '&suppress_response_codes=true&lang=' + (config.lang || lang) + 169 '&rnd=' + Math.random(); 170 } else if (config.profile !== undefined) { 171 script.src = 'https://syndication.twitter.com/timeline/profile?' + 172 'callback=__twttrf.callback&dnt=false' + 173 '&screen_name=' + config.profile.screenName + 174 '&suppress_response_codes=true&lang=' + (config.lang || lang) + 175 '&rnd=' + Math.random(); 176 } else if (config.likes !== undefined) { 177 script.src = 'https://syndication.twitter.com/timeline/likes?' + 178 'callback=__twttrf.callback&dnt=false' + 179 '&screen_name=' + config.likes.screenName + 180 '&suppress_response_codes=true&lang=' + (config.lang || lang) + 181 '&rnd=' + Math.random(); 182 } else { 183 script.src = 'https://cdn.syndication.twimg.com/widgets/timelines/' + 184 config.id + '?&lang=' + (config.lang || lang) + 185 '&callback=__twttrf.callback&' + 186 'suppress_response_codes=true&rnd=' + Math.random(); 187 } 188 head.appendChild(script); 189 } 190 }, 191 callback: function(data) { 192 if (data === undefined || data.body === undefined) { 193 inProgress = false; 194 195 if (queue.length > 0) { 196 twitterFetcher.fetch(queue[0]); 197 queue.splice(0,1); 198 } 199 return; 200 } 201 202 // Remove emoji and summary card images. 203 if(!useEmoji){ 204 data.body = data.body.replace(/(<img[^c]*class="Emoji[^>]*>)|(<img[^c]*class="u-block[^>
204]*>)/g, ''); 205 } 206 207 // Remove display images. 208 if (!showImages) { 209 data.body = data.body.replace(/(<img[^c]*class="NaturalImage-image[^>]*>|(<img[^c]*class="CroppedImage-image[^>]*>))/g, ''); 210 } 211 // Remove avatar images. 212 if (!printUser) { 213 data.body = data.body.replace(/(<img[^c]*class="Avatar"[^>]*>)/g, ''); 214 } 215 216 var div = document.createElement('div'); 217 div.innerHTML = data.body; 218 if (typeof(div.getElementsByClassName) === 'undefined') { 219 supportsClassName = false; 220 } 221 222 function swapDataSrc(element) { 223 var avatarImg = element.getElementsByTagName('img')[0]; 224 avatarImg.src = avatarImg.getAttribute('data-src-2x'); 225 return element; 226 } 227 228 var tweets = []; 229 var authors = []; 230 var times = []; 231 var images = []; 232 var rts = []; 233 var tids = []; 234 var permalinksURL = []; 235 var x = 0; 236 237 if (supportsClassName) { 238 var tmp = div.getElementsByClassName('timeline-Tweet'); 239 while (x < tmp.length) { 240 if (tmp[x].getElementsByClassName('timeline-Tweet-retweetCredit').length > 0) { 241 rts.push(true); 242 } else { 243 rts.push(false); 244 } 245 if (!rts[x] || rts[x] && showRts) { 246 tweets.push(tmp[x].getElementsByClassName('timeline-Tweet-text')[0]); 247 tids.push(tmp[x].getAttribute('data-tweet-id')); 248 if (printUser) { 249 authors.push(swapDataSrc(tmp[x].getElementsByClassName('timeline-Tweet-author')[0])); 250 } 251 times.push(tmp[x].getElementsByClassName('dt-updated')[0]); 252 permalinksURL.push(tmp[x].getElementsByClassName('timeline-Tweet-timestamp')[0]); 253 if (tmp[x].getElementsByClassName('timeline-Tweet-media')[0] !== 254 undefined) { 255 images.push(tmp[x].getElementsByClassName('timeline-Tweet-media')[0]); 256 } else { 257 images.push(undefined); 258 } 259 } 260 x++; 261 } 262 } else { 263 var tmp = getElementsByClassName(div, 'timeline-Tweet'); 264 while (x < tmp.length) { 265 if (getElementsByClassName(tmp[x], 'timeline-Tweet-retweetCredit').length > 0) { 266 rts.push(true); 267 } else { 268 rts.push(false); 269 } 270 if (!rts[x] || rts[x] && showRts) { 271 tweets.push(getElementsByClassName(tmp[x], 'timeline-Tweet-text')[0]); 272 tids.push(tmp[x].getAttribute('data-tweet-id')); 273 if (printUser) { 274 authors.push(swapDataSrc(getElementsByClassName(tmp[x],'timeline-Tweet-author')[0])); 275 } 276 times.push(getElementsByClassName(tmp[x], 'dt-updated')[0]); 277 permalinksURL.push(getElementsByClassName(tmp[x], 'timeline-Tweet-timestamp')[0]); 278 if (getElementsByClassName(tmp[x], 'timeline-Tweet-media')[0] !== undefined) { 279 images.push(getElementsByClassName(tmp[x], 'timeline-Tweet-media')[0]); 280 } else { 281 images.push(undefined); 282 } 283 } 284 x++; 285 } 286 } 287 288 if (tweets.length > maxTweets) { 289 tweets.splice(maxTweets, (tweets.length - maxTweets)); 290 authors.splice(maxTweets, (authors.length - maxTweets)); 291 times.splice(maxTweets, (times.length - maxTweets)); 292 rts.splice(maxTweets, (rts.length - maxTweets)); 293 images.splice(maxTweets, (images.length - maxTweets)); 294 permalinksURL.splice(maxTweets, (permalinksURL.length - maxTweets)); 295 } 296 297 var arrayTweets = []; 298 var x = tweets.length; 299 var n = 0; 300 if (dataOnly) { 301 while (n < x) { 302 arrayTweets.push({ 303 tweet: tweets[n].innerHTML, 304 author: authors[n] ? authors[n].innerHTML : 'Unknown Author', 305 author_data: { 306 profile_url: authors[n] ? authors[n].querySelector('[data-scribe="element:user_link"]').href : null, 307 profile_image: authors[n] ? authors[n].querySelector('[data-scribe="element:avatar"]').getAttribute('data-src-1x') : null, 308 profile_image_2x: authors[n] ? authors[n].querySelector('[data-scribe="element:avatar"]').getAttribute('data-src-2x') : null, 309 screen_name: authors[n] ? authors[n].querySelector('[data-scribe="element:screen_name"]').title : null, 310 name: authors[n] ? authors[n].querySelector('[data-scribe="element:name"]').title : null 311 }, 312 time: times[n].textContent, 313 timestamp: times[n].getAttribute('datetime').replace('+0000', 'Z').replace(/([\+\-])(\d\d)(\d\d)/, '$1$2:$3'), 314 image: extractImageUrl(images[n]), 315 rt: rts[n], 316 tid: tids[n], 317 permalinkURL: (permalinksURL[n] === undefined) ? 318 '' : permalinksURL[n].href 319 }); 320 n++; 321 } 322 } else { 323 while (n < x) { 324 if (typeof(formatterFunction) !== 'string') { 325 var datetimeText = times[n].getAttribute('datetime'); 326 var newDate = new Date(times[n].getAttribute('datetime') 327 .replace(/-/g,'/').replace('T', ' ').split('+')[0]); 328 var dateString = formatterFunction(newDate, datetimeText); 329 times[n].setAttribute('aria-label', dateString); 330 331 if (tweets[n].textContent) { 332 // IE hack. 333 if (supportsClassName) { 334 times[n].textContent = dateString; 335 } else { 336 var h = document.createElement('p'); 337 var t = document.createTextNode(dateString); 338 h.appendChild(t); 339 h.setAttribute('aria-label', dateString); 340 times[n] = h; 341 } 342 } else { 343 times[n].textContent = dateString; 344 } 345 } 346 var op = ''; 347 if (parseLinks) { 348 if (targetBlank) { 349 targetLinksToNewWindow(tweets[n]); 350 if (printUser) { 351 targetLinksToNewWindow(authors[n]); 352 } 353 } 354 if (printUser) { 355 op += '<div class="user">' + strip(authors[n].innerHTML) + 356 '</div>'; 357 } 358 op += '<p class="tweet">' + strip(tweets[n].innerHTML) + '</p>'; 359 if (printTime) { 360 if (permalinks) { 361 op += '<p class="timePosted"><a href="' + permalinksURL[n] + 362 '">' + times[n].getAttribute('aria-label') + '</a></p>'; 363 } else { 364 op += '<p class="timePosted">' + 365 times[n].getAttribute('aria-label') + '</p>'; 366 } 367 } 368 } else { 369 if (tweets[n].textContent) { 370 if (printUser) { 371 op += '<p class="user">' + authors[n].textContent + '</p>'; 372 } 373 op += '<p class="tweet">' + tweets[n].textContent + '</p>'; 374 if (printTime) { 375 op += '<p class="timePosted">' + times[n].textContent + '</p>'; 376 } 377 378 } else { 379 if (printUser) { 380 op += '<p class="user">' + authors[n].textContent + '</p>'; 381 } 382 op += '<p class="tweet">' + tweets[n].textContent + '</p>'; 383 if (printTime) { 384 op += '<p class="timePosted">' + times[n].textContent + '</p>'; 385 } 386 } 387 } 388 if (showInteractionLinks) { 389 op += '<p class="interact"><a href="https://twitter.com/intent/' + 390 'tweet?in_reply_to=' + tids[n] + 391 '" class="twitter_reply_icon"' + 392 (targetBlank ? ' target="_blank">' : '>') + 393 'Reply</a><a href="https://twitter.com/intent/retweet?' + 394 'tweet_id=' + tids[n] + '" class="twitter_retweet_icon"' + 395 (targetBlank ? ' target="_blank">' : '>') + 'Retweet</a>' + 396 '<a href="https://twitter.com/intent/favorite?tweet_id=' + 397 tids[n] + '" class="twitter_fav_icon"' + 398 (targetBlank ? ' target="_blank">' : '>') + 'Favorite</a></p>'; 399 } 400 if (showImages && images[n] !== undefined && extractImageUrl(images[n]) !== undefined) { 401 op += '<div class="media">' + 402 '<img src="' + extractImageUrl(images[n]) + 403 '" alt="Image from tweet" />' + '</div>'; 404 } 405 if (showImages) { 406 arrayTweets.push(op); 407 } else if (!showImages && tweets[n].textContent.length) { 408 arrayTweets.push(op); 409 } 410 411 n++; 412 } 413 } 414 415 handleTweets(arrayTweets); 416 inProgress = false; 417 418 if (queue.length > 0) { 419 twitterFetcher.fetch(queue[0]); 420 queue.splice(0,1); 421 } 422 } 423 }; 424 425 // It must be a global variable because it will be called by JSONP. 426 window.__twttrf = twitterFetcher; 427 window.twitterFetcher = twitterFetcher; 428 return twitterFetcher; 429}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.