PageSourceSearch

https://thewavecoventry.com/wp-content/themes/the_wave/assets/js/custom/twitterFetcher.js

js thewavecoventry.com collected 2026-10-04 21:32:39 UTC 18,395 bytes, 671 lines download raw bytes

1/*********************************************************************
2 *  #### Twitter Post Fetcher v18.0.3 ####
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 = '<div class="row twitterFeedSlider">';
52			var html = "";
53			while (n < x) {
54				html += '<div>' + tweets[n] + "</div>";
55				n++;
56			}
57			// html += '</div>';
58
59			element.innerHTML = html;
60
61		// Slick for twitter
62			$(".twitterFeedSlider").slick({
63				dots: true,
64				arrows: false,
65				infinite: true,
66				speed: 300,
67				slidesToShow: 3,
68				slidesToScroll: 3,
69				adaptiveHeight: true,
70
71				responsive: [
72					{
73						breakpoint: 992,
74						settings: {
75							slidesToShow: 2,
76							slidesToScroll: 2
77						}
78					},
79					{
80						breakpoint: 768,
81						settings: {
82							slidesToShow: 1,
83							slidesToScroll: 1,
84							dots: false,
85							arrows: true,
86							prevArrow: $(".prevTweet"),
87							nextArrow: $(".nextTweet")
88						}
89					}
90				]
91			});
92
93			$(".twitterFeedSlider2").slick({
94				speed: 300,
95				slidesToShow: 1,
96				slidesToScroll: 1,
97				dots: false,
98				arrows: true,
99				prevArrow: $(".prevTweet"),
100				nextArrow: $(".nextTweet")
101			});
102      // End of slick for twitter 
103      
104		} else {
105			customCallbackFunction(tweets);
106		}
107	}
108
109	function strip(data) {
110		return data
111			.replace(/<b[^>]*>(.*?)<\/b>/gi, function(a, s) {
112				return s;
113			})
114			.replace(
115				/class="(?!(tco-hidden|tco-display|tco-ellipsis))+.*?"|data-query-source=".*?"|dir=".*?"|rel=".*?"/gi,
116				""
117			);
118	}
119
120	function targetLinksToNewWindow(el) {
121		var links = el.getElementsByTagName("a");
122		for (var i = links.length - 1; i >= 0; i--) {
123			links[i].setAttribute("target", "_blank");
124			links[i].setAttribute("rel", "noopener");
125		}
126	}
127
128	function getElementsByClassName(node, classname) {
129		var a = [];
130		var regex = new RegExp("(^| )" + classname + "( |$)");
131		var elems = node.getElementsByTagName("*");
132		for (var i = 0, j = elems.length; i < j; i++) {
133			if (regex.test(elems[i].className)) {
134				a.push(elems[i]);
135			}
136		}
137		return a;
138	}
139
140	function extractImagesUrl(image_data) {
141		if (
142			image_data !== undefined &&
143			image_data.innerHTML.indexOf("data-image") >= 0
144		) {
145			var data_src = image_data.innerHTML.match(
146				/data-image=\"([A-z0-9]+:\/\/[A-z0-9]+\.[A-z0-9]+\.[A-z0-9]+\/[A-z0-9]+\/[A-z0-9\-]+)\"/gi
147			);
148			for (var i = 0; i < data_src.length; i++) {
149				data_src[i] = data_src[i].match(
150					/data-image=\"([A-z0-9]+:\/\/[A-z0-9]+\.[A-z0-9]+\.[A-z0-9]+\/[A-z0-9]+\/[A-z0-9\-]+)\"/i
151				)[1];
152				data_src[i] = decodeURIComponent(data_src[i]) + ".jpg";
153			}
154			return data_src;
155		}
156	}
157
158	var twitterFetcher = {
159		fetch: function(config) {
160			if (config.maxTweets === undefined) {
161				config.maxTweets = 20;
162			}
163			if (config.enableLinks === undefined) {
164				config.enableLinks = true;
165			}
166			if (config.showUser === undefined) {
167				config.showUser = true;
168			}
169			if (config.showTime === undefined) {
170				config.showTime = true;
171			}
172			if (config.dateFunction === undefined) {
173				config.dateFunction = "default";
174			}
175			if (config.showRetweet === undefined) {
176				config.showRetweet = true;
177			}
178			if (config.customCallback === undefined) {
179				config.customCallback = null;
180			}
181			if (config.showInteraction === undefined) {
182				config.showInteraction = true;
183			}
184			if (config.showImages === undefined) {
185				config.showImages = false;
186			}
187			if (config.useEmoji === undefined) {
188				config.useEmoji = false;
189			}
190			if (config.linksInNewWindow === undefined) {
191				config.linksInNewWindow = true;
192			}
193			if (config.showPermalinks === undefined) {
194				config.showPermalinks = true;
195			}
196			if (config.dataOnly === undefined) {
197				config.dataOnly = false;
198			}
199
200			if (inProgress) {
201				queue.push(config);
202			} else {
203				inProgress = true;
204
205				domNode = config.domId;
206				maxTweets = config.maxTweets;
207				parseLinks = config.enableLinks;
208				printUser = config.showUser;
209				printTime = config.showTime;
210				showRts = config.showRetweet;
211				formatterFunction = config.dateFunction;
212				customCallbackFunction = config.customCallback;
213				showInteractionLinks = config.showInteraction;
214				showImages = config.showImages;
215				useEmoji = config.useEmoji;
216				targetBlank = config.linksInNewWindow;
217				permalinks = config.showPermalinks;
218				dataOnly = config.dataOnly;
219
220				var head = document.getElementsByTagName("head")[0];
221				if (script !== null) {
222					head.removeChild(script);
223				}
224				script = document.createElement("script");
225				script.type = "text/javascript";
226				if (config.list !== undefined) {
227					script.src =
228						"https://syndication.twitter.com/timeline/list?" +
229						"callback=__twttrf.callback&dnt=false&list_slug=" +
230						config.list.listSlug +
231						"&screen_name=" +
232						config.list.screenName +
233						"&suppress_response_codes=true&lang=" +
234						(config.lang || lang) +
235						"&rnd=" +
236						Math.random();
237				} else if (config.profile !== undefined) {
238					script.src =
239						"https://syndication.twitter.com/timeline/profile?" +
240						"callback=__twttrf.callback&dnt=false" +
241						"&screen_name=" +
242						config.profile.screenName +
243						"&suppress_response_codes=true&lang=" +
244						(config.lang || lang) +
245						"&rnd=" +
246						Math.random();
247				} else if (config.likes !== undefined) {
248					script.src =
249						"https://syndication.twitter.com/timeline/likes?" +
250						"callback=__twttrf.callback&dnt=false" +
251						"&screen_name=" +
252						config.likes.screenName +
253						"&suppress_response_codes=true&lang=" +
254						(config.lang || lang) +
255						"&rnd=" +
256						Math.random();
257				} else if (config.collection !== undefined) {
258					script.src =
259						"https://syndication.twitter.com/timeline/collection?" +
260						"callback=__twttrf.callback&dnt=false" +
261						"&collection_id=" +
262						config.collection.collectionId +
263						"&suppress_response_codes=true&lang=" +
264						(config.lang || lang) +
265						"&rnd=" +
266						Math.random();
267				} else {
268					script.src =
269						"https://cdn.syndication.twimg.com/widgets/timelines/" +
270						config.id +
271						"?&lang=" +
272						(config.lang || lang) +
273						"&callback=__twttrf.callback&" +
274						"suppress_response_codes=true&rnd=" +
275						Math.random();
276				}
277				head.appendChild(script);
278			}
279		},
280		callback: function(data) {
281			if (data === undefined || data.body === undefined) {
282				inProgress = false;
283
284				if (queue.length > 0) {
285					twitterFetcher.fetch(queue[0]);
286					queue.splice(0, 1);
287				}
288				return;
289			}
290
291			// Remove emoji and summary card images.
292			if (!useEmoji) {
293				data.body = data.body.replace(
294					/(<img[^c]*class="Emoji[^>]*>)|(<img[^c]*class="u-block[^>]*>)/g,
295					""
296				);
297			}
298
299			// Remove display images.
300			if (!showImages) {
301				data.body = data.body.replace(
302					/(<img[^c]*class="NaturalImage-image[^>]*>|(<img[^c]*class="CroppedImage-image[^>]*>))/g,
303					""
304				);
305			}
306			// Remove avatar images.
307			if (!printUser) {
308				data.body = data.body.replace(/(<img[^c]*class="Avatar"[^>]*>)/g, "");
309			}
310
311			var div = document.createElement("div");
312			div.innerHTML = data.body;
313			if (typeof div.getElementsByClassName === "undefined") {
314				supportsClassName = false;
315			}
316
317			function swapDataSrc(element) {
318				var avatarImg = element.getElementsByTagName("img")[0];
319				if (avatarImg) {
320					avatarImg.src = avatarImg.getAttribute("data-src-2x");
321				} else {
322					var screenName = element
323						.getElementsByTagName("a")[0]
324						.getAttribute("href")
325						.split("twitter.com/")[1];
326					var img = document.createElement("img");
327					img.setAttribute(
328						"src",
329						"https://twitter.com/" + screenName + "/profile_image?size=bigger"
330					);
331					element.prepend(img);
332				}
333				return element;
334			}
335
336			var tweets = [];
337			var authors = [];
338			var times = [];
339			var images = [];
340			var rts = [];
341			var tids = [];
342			var permalinksURL = [];
343			var x = 0;
344
345			if (supportsClassName) {
346				var tmp = div.getElementsByClassName("timeline-Tweet");
347				while (x < tmp.length) {
348					if (
349						tmp[x].getElementsByClassName("timeline-Tweet-retweetCredit")
350							.length > 0
351					) {
352						rts.push(true);
353					} else {
354						rts.push(false);
355					}
356					if (!rts[x] || (rts[x] && showRts)) {
357						tweets.push(
358							tmp[x].getElementsByClassName("timeline-Tweet-text")[0]
359						);
360						tids.push(tmp[x].getAttribute("data-tweet-id"));
361						if (printUser) {
362							authors.push(
363								swapDataSrc(
364									tmp[x].getElementsByClassName("timeline-Tweet-author")[0]
365								)
366							);
367						}
368						times.push(tmp[x].getElementsByClassName("dt-updated")[0]);
369						permalinksURL.push(
370							tmp[x].getElementsByClassName("timeline-Tweet-timestamp")[0]
371						);
372						if (
373							tmp[x].getElementsByClassName("timeline-Tweet-media")[0] !==
374							undefined
375						) {
376							images.push(
377								tmp[x].getElementsByClassName("timeline-Tweet-media")[0]
378							);
379						} else {
380							images.push(undefined);
381						}
382					}
383					x++;
384				}
385			} else {
386				var tmp = getElementsByClassName(div, "timeline-Tweet");
387				while (x < tmp.length) {
388					if (
389						getElementsByClassName(tmp[x], "timeline-Tweet-retweetCredit")
390							.length > 0
391					) {
392						rts.push(true);
393					} else {
394						rts.push(false);
395					}
396					if (!rts[x] || (rts[x] && showRts)) {
397						tweets.push(
398							getElementsByClassName(tmp[x], "timeline-Tweet-text")[0]
399						);
400						tids.push(tmp[x].getAttribute("data-tweet-id"));
401						if (printUser) {
402							authors.push(
403								swapDataSrc(
404									getElementsByClassName(tmp[x], "timeline-Tweet-author")[0]
405								)
406							);
407						}
408						times.push(getElementsByClassName(tmp[x], "dt-updated")[0]);
409						permalinksURL.push(
410							getElementsByClassName(tmp[x], "timeline-Tweet-timestamp")[0]
411						);
412						if (
413							getElementsByClassName(tmp[x], "timeline-Tweet-media")[0] !==
414							undefined
415						) {
416							images.push(
417								getElementsByClassName(tmp[x], "timeline-Tweet-media")[0]
418							);
419						} else {
420							images.push(undefined);
421						}
422					}
423					x++;
424				}
425			}
426
427			if (tweets.length > maxTweets) {
428				tweets.splice(maxTweets, tweets.length - maxTweets);
429				authors.splice(maxTweets, authors.length - maxTweets);
430				times.splice(maxTweets, times.length - maxTweets);
431				rts.splice(maxTweets, rts.length - maxTweets);
432				images.splice(maxTweets, images.length - maxTweets);
433				permalinksURL.splice(maxTweets, permalinksURL.length - maxTweets);
434			}
435
436			var arrayTweets = [];
437			var x = tweets.length;
438			var n = 0;
439			if (dataOnly) {
440				while (n < x) {
441					arrayTweets.push({
442						tweet: tweets[n].innerHTML,
443						author: authors[n] ? authors[n].innerHTML : "Unknown Author",
444						author_data: {
445							profile_url: authors[n]
446								? authors[n].querySelector('[data-scribe="element:user_link"]')
447										.href
448								: null,
449							profile_image: authors[n]
450								? "https://twitter.com/" +
451								  authors[n]
452										.querySelector('[data-scribe="element:screen_name"]')
453										.title.split("@")[1] +
454								  "/profile_image?size=bigger"
455								: null,
456							profile_image_2x: authors[n]
457								? "https://twitter.com/" +
458								  authors[n]
459										.querySelector('[data-scribe="element:screen_name"]')
460										.title.split("@")[1] +
461								  "/profile_image?size=original"
462								: null,
463							screen_name: authors[n]
464								? authors[n].querySelector(
465										'[data-scribe="element:screen_name"]'
466								  ).title
467								: null,
468							name: authors[n]
469								? authors[n].querySelector('[data-scribe="element:name"]').title
470								: null
471						},
472						time: times[n].textContent,
473						timestamp: times[n]
474							.getAttribute("datetime")
475							.replace("+0000", "Z")
476							.replace(/([\+\-])(\d\d)(\d\d)/, "$1$2:$3"),
477						image: extractImagesUrl(images[n])
478							? extractImagesUrl(images[n])[0]
479							: undefined,
480						images: extractImagesUrl(images[n]),
481						rt: rts[n],
482						tid: tids[n],
483						permalinkURL:
484							permalinksURL[n] === undefined ? "" : permalinksURL[n].href
485					});
486					n++;
487				}
488			} else {
489				while (n < x) {
490					if (typeof formatterFunction !== "string") {
491						var datetimeText = times[n].getAttribute("datetime");
492						var newDate = new Date(
493							times[n]
494								.getAttribute("datetime")
495								.replace(/-/g, "/")
496								.replace("T", " ")
497								.split("+")[0]
498						);
499						var dateString = formatterFunction(newDate, datetimeText);
500						times[n].setAttribute("aria-label", dateString);
501
502						if (tweets[n].textContent) {
503							// IE hack.
504							if (supportsClassName) {
505								times[n].textContent = dateString;
506							} else {
507								var h = document.createElement("p");
508								var t = document.createTextNode(dateString);
509								h.appendChild(t);
510								h.setAttribute("aria-label", dateString);
511								times[n] = h;
512							}
513						} else {
514							times[n].textContent = dateString;
515						}
516					}
517					var op = "";
518					if (parseLinks) {
519						if (targetBlank) {
520							targetLinksToNewWindow(tweets[n]);
521							if (printUser) {
522								targetLinksToNewWindow(authors[n]);
523							}
524						}
525						if (printUser) {
526							op +=
527								'<div class="user">' + strip(authors[n].innerHTML) + "</div>";
528						}
529						op += '<p class="tweet">' + strip(tweets[n].innerHTML) + "</p>";
530						if (printTime) {
531							if (permalinks) {
532								op +=
533									'<p class="timePosted"><a href="' +
534									permalinksURL[n] +
535									'">' +
536									times[n].getAttribute("aria-label") +
537									"</a></p>";
538							} else {
539								op +=
540									'<p class="timePosted">' +
541									times[n].getAttribute("aria-label") +
542									"</p>";
543							}
544						}
545					} else {
546						if (tweets[n].textContent) {
547							if (printUser) {
548								op += '<p class="user">' + authors[n].textContent + "</p>";
549							}
550							op += '<p class="tweet">' + tweets[n].textContent + "</p>";
551							if (printTime) {
552								op += '<p class="timePosted">' + times[n].textContent + "</p>";
553							}
554						} else {
555							if (printUser) {
556								op += '<p class="user">' + authors[n].textContent + "</p>";
557							}
558							op += '<p class="tweet">' + tweets[n].textContent + "</p>";
559							if (printTime) {
560								op += '<p class="timePosted">' + times[n].textContent + "</p>";
561							}
562						}
563					}
564					if (showInteractionLinks) {
565						op +=
566							'<p class="interact"><a href="https://twitter.com/intent/' +
567							"tweet?in_reply_to=" +
568							tids[n] +
569							'" class="twitter_reply_icon"' +
570							(targetBlank ? ' target="_blank" rel="noopener">' : ">") +
571							'Reply</a><a href="https://twitter.com/intent/retweet?' +
572							"tweet_id=" +
573							tids[n] +
574							'" class="twitter_retweet_icon"' +
575							(targetBlank ? ' target="_blank" rel="noopener">' : ">") +
576							"Retweet</a>" +
577							'<a href="https://twitter.com/intent/favorite?tweet_id=' +
578							tids[n] +
579							'" class="twitter_fav_icon"' +
580							(targetBlank ? ' target="_blank" rel="noopener">' : ">") +
581							"Favorite</a></p>";
582					}
583					if (
584						showImages &&
585						images[n] !== undefined &&
586						extractImagesUrl(images[n]) !== undefined
587					) {
588						var extractedImages = extractImagesUrl(images[n]);
589						for (var i = 0; i < extractedImages.length; i++) {
590							op +=
591								'<div class="media">' +
592								'<img src="' +
593								extractedImages[i] +
594								'" alt="Image from tweet" />' +
595								"</div>";
596						}
597					}
598					if (showImages) {
599						arrayTweets.push(op);
600					} else if (!showImages && tweets[n].textContent.length) {
601						arrayTweets.push(op);
602					}
603
604					n++;
605				}
606			}
607
608			handleTweets(arrayTweets);
609			inProgress = false;
610
611			if (queue.length > 0) {
612				twitterFetcher.fetch(queue[0]);
613				queue.splice(0, 1);
614			}
615		}
616	};
617
618	// It must be a global variable because it will be called by JSONP.
619	window.__twttrf = twitterFetcher;
620	window.twitterFetcher = twitterFetcher;
621	return twitterFetcher;
622});
623
624// Prepend polyfill for IE/Edge.
625(function(arr) {
626	arr.forEach(function(item) {
627		if (item.hasOwnProperty("prepend")) {
628			return;
629		}
630		Object.defineProperty(item, "prepend", {
631			configurable: true,
632			enumerable: true,
633			writable: true,
634			value: function prepend() {
635				var argArr = Array.prototype.slice.call(arguments),
636					docFrag = document.createDocumentFragment();
637
638				argArr.forEach(function(argItem) {
639					var isNode = argItem instanceof Node;
640					docFrag.appendChild(
641						isNode ? argItem : document.createTextNode(String(argItem))
642					);
643				});
644
645				this.insertBefore(docFrag, this.firstChild);
646			}
647		});
648	});
649})([Element.prototype, Document.prototype, DocumentFragment.prototype]);
650
651/* ================
652        CUSTOM   
653  ===================*/
654var configProfile = {
655	profile: { screenName: "thewavecovnews" },
656	domId: "twitterFeeds",
657	maxTweets: 12,
658	enableLinks: true,
659	showUser: false,
660	showTime: true,
661	showImages: false,
662	lang: "en"
663};
664twitterFetcher.fetch(configProfile);
665
666
667if (window.twitterFetcher) {  
668  console.log("loaded");
669} else {
670  // jQuery is not loaded
671}

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.