PageSourceSearch

https://todomvc.com/site-assets/main.js

js todomvc.com collected 2026-09-24 15:19:43 UTC 6,192 bytes, 217 lines download raw bytes

1/*global $ */
2(function () {
3	'use strict';
4
5	var date = new Date();
6	if (date.getDate() === 1 && date.getMonth() === 3) {
7		['', '-webkit-', '-moz-'].forEach(function (prefix) {
8			document.body.style[prefix + 'filter'] = 'blur(1px)';
9		});
10	}
11
12	$.fn.persistantPopover = function () {
13		var popoverTimeout;
14
15		function delay() {
16			popoverTimeout = setTimeout(function () {
17				$('.popover').hide();
18			}, 100);
19		}
20
21		return this.each(function () {
22			var $this = $(this);
23			$this.popover({
24				trigger: 'manual',
25				placement: 'auto',
26				animation: false,
27				html: true,
28				title: this.firstChild.textContent + '<a href="' + $this.data('source') + '">Website</a>'
29			});
30		})
31		.mouseenter(function () {
32			clearTimeout(popoverTimeout);
33			$('.popover').remove();
34			$(this).popover('show');
35		})
36		.mouseleave(function () {
37			delay();
38			$('.popover').mouseenter(function () {
39				clearTimeout(popoverTimeout);
40			}).mouseleave(function () {
41				delay();
42			});
43		});
44	};
45
46	var Quotes = {};
47	Quotes.build = function (quotes, template) {
48		var quoteContainer = document.createElement('q');
49		var quoteElemCount = 0;
50		var quoteCount = quotes.length;
51
52		var createQuoteElems = function () {
53			var quote = quotes[quoteElemCount];
54			var el = $(template).hide();
55
56			el.children('p').text(quote.quote);
57			el.find('a').text(quote.person.name).attr('href', quote.person.link);
58			el.find('img').attr('src', quote.person.gravatar);
59
60			quoteContainer.appendChild(el[0]);
61
62			if (quoteCount > ++quoteElemCount) {
63				createQuoteElems();
64			}
65
66			return quoteContainer.innerHTML;
67		};
68		return createQuoteElems();
69	};
70
71	Quotes.random = function (quotes) {
72		var quoteCount = quotes.length;
73		var randomQuotes = [];
74
75		var randomQuote = function () {
76			var randomQuoteIndex = Math.floor(Math.random() * quoteCount);
77
78			if ($.inArray(randomQuoteIndex, randomQuotes) > -1) {
79				return randomQuote();
80			}
81
82			if (randomQuotes.length === quoteCount - 1) {
83				randomQuotes = [];
84			}
85
86			randomQuotes.push(randomQuoteIndex);
87
88			return randomQuoteIndex;
89		};
90		return randomQuote;
91	};
92
93	Quotes.animate = function (container, animSpeed) {
94		var fader = function (fadeOut, fadeIn) {
95			var fadeOutCallback = function () {
96				fadeIn.fadeIn(500, fadeInCallback);
97			};
98
99			var fadeInCallback = function () {
100				window.setTimeout(swap, animSpeed);
101			};
102
103			fadeOut.fadeOut(500, fadeOutCallback);
104		};
105
106		var quotes = container.children();
107		var selectRandomQuoteIndex = Quotes.random(quotes);
108		var quoteElems = {};
109		var activeQuoteIndex = selectRandomQuoteIndex();
110		var prevQuoteElem = $(quotes[activeQuoteIndex]);
111
112		var swap = function () {
113			if (!quoteElems[activeQuoteIndex]) {
114				quoteElems[activeQuoteIndex] = $(quotes[activeQuoteIndex]);
115			}
116
117			var activeQuoteElem = quoteElems[activeQuoteIndex];
118
119			fader(prevQuoteElem, activeQuoteElem);
120
121			activeQuoteIndex = selectRandomQuoteIndex();
122			prevQuoteElem = activeQuoteElem;
123		};
124		return swap();
125	};
126
127	Quotes.init = function (quotes) {
128		var container = $(this);
129		var template = $(this).html();
130		var quotesHTML = Quotes.build(quotes, template);
131
132		container.html(quotesHTML);
133
134		Quotes.animate(container, 25000);
135	};
136
137	$.fn.quote = function (quotes) {
138		return this.each(function () {
139			Quotes.init.call(this, quotes);
140		});
141	};
142
143	// Apps popover
144	$('.applist a').persistantPopover();
145
146	// Quotes
147	$('.quotes').quote([{
148		quote: 'TodoMVC is a godsend for helping developers find what well-developed frameworks match their mental model of application architecture.',
149		person: {
150			name: 'Paul Irish',
151			gravatar: 'http://gravatar.com/avatar/ffe68d6f71b225f7661d33f2a8908281?s=40',
152			link: 'https://github.com/paulirish'
153		}
154	}, {
155		quote: 'Modern JavaScript developers realise an MVC framework is essential for managing the complexity of their apps. TodoMVC is a fabulous community contribution that helps developers compare frameworks on the basis of actual project code, not just claims and anecdotes.',
156		person: {
157			name: 'Michael Mahemoff',
158			gravatar: 'http://gravatar.com/avatar/cabf735ce7b8b4471ef46ea54f71832d?s=40',
159			link: 'https://github.com/mahemoff'
160		}
161	}, {
162		quote: 'TodoMVC is an immensely valuable attempt at a difficult problem - providing a structured way of comparing JS libraries and frameworks. TodoMVC is a lone data point in a sea of conjecture and opinion.',
163		person: {
164			name: 'Justin Meyer',
165			gravatar: 'http://gravatar.com/avatar/70ee60f32937b52758869488d5753259?s=40',
166			link: 'https://github.com/justinbmeyer'
167		}
168	}, {
169		quote: 'It can be hard to make the leap from hacking together code that works to writing code that`s organized, maintainable, reusable, and a joy to work on. The TodoMVC project does a great job of introducing developers to different approaches to code organization, and to the various libraries that can help them along the way. If you`re trying to get your bearings in the world of client-side application development, the TodoMVC project is a great place to get started.',
170		person: {
171			name: 'Rebecca Murphey',
172			gravatar: 'http://gravatar.com/avatar/0177cdce6af15e10db15b6bf5dc4e0b0?s=40',
173			link: 'https://github.com/rmurphey'
174		}
175	}]);
176
177	function AppTabs() {
178		var tabs = document.querySelector(AppTabs.selectors.tabs);
179		tabs.addEventListener('iron-select', this.onSelect.bind(this));
180		this.listHeight = 0;
181	}
182
183	AppTabs.selectors = {
184		tabs: '.js-app-tabs',
185		list: '.js-app-list',
186		innerList: '.js-app-list-inner'
187	};
188
189	AppTabs.prototype.onSelect = function (e) {
190		var selected = e.currentTarget.selectedItem.dataset.target;
191		[].slice.call(document.querySelectorAll(AppTabs.selectors.list)).forEac
191h(
192			function (el) {
193				var isSelected = el.dataset.appList === selected;
194				el.style.display = isSelected ? 'block' : 'none';
195				if (isSelected) {
196					this.switchTab(el);
197				}
198			}.bind(this)
199		);
200	};
201
202	AppTabs.prototype.switchTab = function (e) {
203		var list = e.querySelector(AppTabs.selectors.innerList);
204		var $clone = $(list)
205			.clone()
206			.css({ visibility: 'hidden' })
207			.height('auto')
208			.appendTo(list.parentElement);
209
210		window.requestAnimationFrame(function () {
211			$clone.remove();
212		}.bind(this));
213	};
214
215	new AppTabs();
216
217}());

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.