Skip to content

Commit efab5ec

Browse files
committed
add todomvc example + e2e tests
1 parent 1057d73 commit efab5ec

File tree

11 files changed

+2148
-2
lines changed

11 files changed

+2148
-2
lines changed

examples/todomvc/bower_components/director/director.js

Lines changed: 719 additions & 0 deletions
Large diffs are not rendered by default.

examples/todomvc/bower_components/todomvc-common/base.css

Lines changed: 556 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
(function () {
2+
'use strict';
3+
4+
// Underscore's Template Module
5+
// Courtesy of underscorejs.org
6+
var _ = (function (_) {
7+
_.defaults = function (object) {
8+
if (!object) {
9+
return object;
10+
}
11+
for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
12+
var iterable = arguments[argsIndex];
13+
if (iterable) {
14+
for (var key in iterable) {
15+
if (object[key] == null) {
16+
object[key] = iterable[key];
17+
}
18+
}
19+
}
20+
}
21+
return object;
22+
}
23+
24+
// By default, Underscore uses ERB-style template delimiters, change the
25+
// following template settings to use alternative delimiters.
26+
_.templateSettings = {
27+
evaluate : /<%([\s\S]+?)%>/g,
28+
interpolate : /<%=([\s\S]+?)%>/g,
29+
escape : /<%-([\s\S]+?)%>/g
30+
};
31+
32+
// When customizing `templateSettings`, if you don't want to define an
33+
// interpolation, evaluation or escaping regex, we need one that is
34+
// guaranteed not to match.
35+
var noMatch = /(.)^/;
36+
37+
// Certain characters need to be escaped so that they can be put into a
38+
// string literal.
39+
var escapes = {
40+
"'": "'",
41+
'\\': '\\',
42+
'\r': 'r',
43+
'\n': 'n',
44+
'\t': 't',
45+
'\u2028': 'u2028',
46+
'\u2029': 'u2029'
47+
};
48+
49+
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
50+
51+
// JavaScript micro-templating, similar to John Resig's implementation.
52+
// Underscore templating handles arbitrary delimiters, preserves whitespace,
53+
// and correctly escapes quotes within interpolated code.
54+
_.template = function(text, data, settings) {
55+
var render;
56+
settings = _.defaults({}, settings, _.templateSettings);
57+
58+
// Combine delimiters into one regular expression via alternation.
59+
var matcher = new RegExp([
60+
(settings.escape || noMatch).source,
61+
(settings.interpolate || noMatch).source,
62+
(settings.evaluate || noMatch).source
63+
].join('|') + '|$', 'g');
64+
65+
// Compile the template source, escaping string literals appropriately.
66+
var index = 0;
67+
var source = "__p+='";
68+
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
69+
source += text.slice(index, offset)
70+
.replace(escaper, function(match) { return '\\' + escapes[match]; });
71+
72+
if (escape) {
73+
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
74+
}
75+
if (interpolate) {
76+
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
77+
}
78+
if (evaluate) {
79+
source += "';\n" + evaluate + "\n__p+='";
80+
}
81+
index = offset + match.length;
82+
return match;
83+
});
84+
source += "';\n";
85+
86+
// If a variable is not specified, place data values in local scope.
87+
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
88+
89+
source = "var __t,__p='',__j=Array.prototype.join," +
90+
"print=function(){__p+=__j.call(arguments,'');};\n" +
91+
source + "return __p;\n";
92+
93+
try {
94+
render = new Function(settings.variable || 'obj', '_', source);
95+
} catch (e) {
96+
e.source = source;
97+
throw e;
98+
}
99+
100+
if (data) return render(data, _);
101+
var template = function(data) {
102+
return render.call(this, data, _);
103+
};
104+
105+
// Provide the compiled function source as a convenience for precompilation.
106+
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
107+
108+
return template;
109+
};
110+
111+
return _;
112+
})({});
113+
114+
if (location.hostname === 'todomvc.com') {
115+
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
116+
}
117+
118+
function redirect() {
119+
if (location.hostname === 'tastejs.github.io') {
120+
location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
121+
}
122+
}
123+
124+
function findRoot() {
125+
var base;
126+
127+
[/labs/, /\w*-examples/].forEach(function (href) {
128+
var match = location.href.match(href);
129+
130+
if (!base && match) {
131+
base = location.href.indexOf(match);
132+
}
133+
});
134+
135+
return location.href.substr(0, base);
136+
}
137+
138+
function getFile(file, callback) {
139+
if (!location.host) {
140+
return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
141+
}
142+
143+
var xhr = new XMLHttpRequest();
144+
145+
xhr.open('GET', findRoot() + file, true);
146+
xhr.send();
147+
148+
xhr.onload = function () {
149+
if (xhr.status === 200 && callback) {
150+
callback(xhr.responseText);
151+
}
152+
};
153+
}
154+
155+
function Learn(learnJSON, config) {
156+
if (!(this instanceof Learn)) {
157+
return new Learn(learnJSON, config);
158+
}
159+
160+
var template, framework;
161+
162+
if (typeof learnJSON !== 'object') {
163+
try {
164+
learnJSON = JSON.parse(learnJSON);
165+
} catch (e) {
166+
return;
167+
}
168+
}
169+
170+
if (config) {
171+
template = config.template;
172+
framework = config.framework;
173+
}
174+
175+
if (!template && learnJSON.templates) {
176+
template = learnJSON.templates.todomvc;
177+
}
178+
179+
if (!framework && document.querySelector('[data-framework]')) {
180+
framework = document.querySelector('[data-framework]').getAttribute('data-framework');
181+
}
182+
183+
184+
if (template && learnJSON[framework]) {
185+
this.frameworkJSON = learnJSON[framework];
186+
this.template = template;
187+
188+
this.append();
189+
}
190+
}
191+
192+
Learn.prototype.append = function () {
193+
var aside = document.createElement('aside');
194+
aside.innerHTML = _.template(this.template, this.frameworkJSON);
195+
aside.className = 'learn';
196+
197+
// Localize demo links
198+
var demoLinks = aside.querySelectorAll('.demo-link');
199+
Array.prototype.forEach.call(demoLinks, function (demoLink) {
200+
demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
201+
});
202+
203+
document.body.className = (document.body.className + ' learn-bar').trim();
204+
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
205+
};
206+
207+
redirect();
208+
getFile('learn.json', Learn);
209+
})();
Loading

examples/todomvc/index.html

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Todo</title>
5+
<meta charset="utf-8">
6+
<link rel="stylesheet" type="text/css" href="bower_components/todomvc-common/base.css">
7+
<style> [v-cloak] { display: none; } </style>
8+
</head>
9+
<body>
10+
<section id="todoapp">
11+
<header id="header">
12+
<h1>todos</h1>
13+
<input
14+
id="new-todo"
15+
autofocus
16+
autocomplete="off"
17+
placeholder="What needs to be done?"
18+
v-model="newTodo"
19+
v-on="keyup:addTodo | key enter"
20+
>
21+
</header>
22+
<section id="main" v-show="todos.length" v-cloak>
23+
<input
24+
id="toggle-all"
25+
type="checkbox"
26+
v-model="allDone"
27+
>
28+
<ul id="todo-list">
29+
<li
30+
class="todo"
31+
v-repeat="todos | filterTodos"
32+
v-class="
33+
completed : completed,
34+
editing : this == editedTodo
35+
"
36+
>
37+
<div class="view">
38+
<input
39+
class="toggle"
40+
type="checkbox"
41+
v-model="completed"
42+
>
43+
<label v-text="title" v-on="dblclick: editTodo(this)"></label>
44+
<button class="destroy" v-on="click: removeTodo(this)"></button>
45+
</div>
46+
<input
47+
class="edit"
48+
type="text"
49+
v-model="title"
50+
v-todo-focus="this == editedTodo"
51+
v-on="
52+
blur : doneEdit(this),
53+
keyup : doneEdit(this) | key enter,
54+
keyup : cancelEdit(this) | key esc
55+
"
56+
>
57+
</li>
58+
</ul>
59+
</section>
60+
<footer id="footer" v-show="todos.length" v-cloak>
61+
<span id="todo-count">
62+
<strong v-text="remaining"></strong> {{remaining | pluralize item}} left
63+
</span>
64+
<ul id="filters">
65+
<li><a href="#/all" v-class="selected: activeFilter == 'all'">All</a></li>
66+
<li><a href="#/active" v-class="selected: activeFilter == 'active'">Active</a></li>
67+
<li><a href="#/completed" v-class="selected: activeFilter == 'completed'">Completed</a></li>
68+
</ul>
69+
<button id="clear-completed" v-on="click:removeCompleted" v-show="todos.length > remaining">
70+
Clear completed ({{todos.length - remaining}})
71+
</button>
72+
</footer>
73+
</section>
74+
<footer id="info">
75+
<p>Double-click to edit a todo</p>
76+
<p>Powered by <a href="http://vuejs.org">Vue.js</a></p>
77+
<p>Created by <a href="http://evanyou.me">Evan You</a></p>
78+
</footer>
79+
80+
<!-- testing/benchmark only -->
81+
<script>
82+
if (navigator.userAgent.indexOf('PhantomJS') > -1) {
83+
localStorage.clear()
84+
}
85+
var now = window.performance && window.performance.now
86+
? function () { return window.performance.now() }
87+
: Date.now
88+
var metrics = { beforeLoad: now() }
89+
</script>
90+
<!-- end testing/bench -->
91+
92+
<script src="../../dist/vue.js"></script>
93+
<script>metrics.afterLoad = now()</script>
94+
<script src="bower_components/director/director.js"></script>
95+
<script src="js/store.js"></script>
96+
<script>metrics.beforeRender = now()</script>
97+
<script src="js/app.js"></script>
98+
<script src="js/routes.js"></script>
99+
<script>metrics.afterRender = now()</script>
100+
<script src="js/perf.js"></script>
101+
102+
</body>
103+
</html>

0 commit comments

Comments
 (0)