Commit a543e298 authored by Sindre Sorhus's avatar Sindre Sorhus

Flight - code style

parent 994d727a
/*global define */
'use strict';
define(
[
'./data/todos',
'./data/stats',
......@@ -25,11 +25,11 @@ define(
StatsData.attachTo(document);
TodosData.attachTo(document);
NewItemUI.attachTo('#new-todo');
MainSelectorUI.attachTo("#main");
MainSelectorUI.attachTo('#main');
StatsUI.attachTo('#footer');
ToggleAllUI.attachTo('#toggle-all');
TodoListUI.attachTo('#todo-list');
}
};
return {
initialize: initialize
......
/*global define */
'use strict';
define(
[
'flight/component',
'../store'
],
function (defineComponent, dataStore) {
return defineComponent(stats);
function stats() {
......@@ -16,7 +15,7 @@ define(
var todos = dataStore.all();
var all = todos.length;
var remaining = todos.reduce(function (memo, each) {
return memo += (each.completed) ? 0 : 1;
return memo += each.completed ? 0 : 1;
}, 0);
this.trigger('dataStatsCounted', {
......@@ -25,7 +24,7 @@ define(
completed: all - remaining,
filter: localStorage.getItem('filter') || ''
});
}
};
this.after('initialize', function () {
this.on(document, 'dataTodosLoaded', this.recount);
......
/*global define */
'use strict';
define(
[
'flight/component',
'../store'
],
function (defineComponent, dataStore) {
return defineComponent(todos);
function todos() {
var filter;
this.add = function (e, data) {
var todo = dataStore.save({
title: data.title,
completed: false
});
this.trigger('dataTodoAdded', { todo: todo, filter: filter });
}
this.remove = function (e, data) {
var todo = dataStore.destroy(data.id);
this.trigger('dataTodoRemoved', todo);
}
this.load = function (e, data) {
var todos;
filter = localStorage.getItem('filter');
todos = this.find();
this.trigger('dataTodosLoaded', { todos: todos });
}
this.update = function (e, data) {
dataStore.save(data);
}
this.toggleCompleted = function (e, data) {
var eventType;
var todo = dataStore.get(data.id);
todo.completed = !todo.completed;
dataStore.save(todo);
eventType = (filter) ? 'dataTodoRemoved' : 'dataTodoToggled';
this.trigger(eventType, todo);
}
this.toggleAllCompleted = function (e, data) {
dataStore.updateAll({ completed: data.completed });
this.trigger('dataTodoToggledAll', { todos: this.find(filter) });
}
this.filter = function (e, data) {
var todos;
localStorage.setItem('filter', data.filter);
filter = data.filter;
todos = this.find();
this.trigger('dataTodosFiltered', { todos: todos });
}
this.find = function () {
var todos;
if (filter) {
todos = dataStore.find(function (each) {
return (typeof each[filter] !== 'undefined') ? each.completed : !each.completed;
});
}
else {
todos = dataStore.all();
}
return todos;
}
this.clearCompleted = function () {
var todos;
dataStore.destroyAll({ completed: true });
todos = dataStore.all();
this.trigger('dataClearedCompleted', { todos: todos });
}
this.after('initialize', function () {
this.on(document, 'uiAddRequested', this.add);
this.on(document, 'uiUpdateRequested', this.update);
this.on(document, 'uiRemoveRequested', this.remove);
this.on(document, 'uiLoadRequested', this.load);
this.on(document, 'uiToggleRequested', this.toggleCompleted);
this.on(document, 'uiToggleAllRequested', this.toggleAllCompleted);
this.on(document, 'uiClearRequested', this.clearCompleted);
this.on(document, 'uiFilterRequested', this.filter);
});
}
}
[
'flight/component',
'../store'
],
function (defineComponent, dataStore) {
return defineComponent(todos);
function todos() {
var filter;
this.add = function (e, data) {
var todo = dataStore.save({
title: data.title,
completed: false
});
this.trigger('dataTodoAdded', { todo: todo, filter: filter });
};
this.remove = function (e, data) {
var todo = dataStore.destroy(data.id);
this.trigger('dataTodoRemoved', todo);
};
this.load = function (e, data) {
var todos;
filter = localStorage.getItem('filter');
todos = this.find();
this.trigger('dataTodosLoaded', { todos: todos });
};
this.update = function (e, data) {
dataStore.save(data);
};
this.toggleCompleted = function (e, data) {
var eventType;
var todo = dataStore.get(data.id);
todo.completed = !todo.completed;
dataStore.save(todo);
eventType = filter ? 'dataTodoRemoved' : 'dataTodoToggled';
this.trigger(eventType, todo);
};
this.toggleAllCompleted = function (e, data) {
dataStore.updateAll({ completed: data.completed });
this.trigger('dataTodoToggledAll', { todos: this.find(filter) });
};
this.filter = function (e, data) {
var todos;
localStorage.setItem('filter', data.filter);
filter = data.filter;
todos = this.find();
this.trigger('dataTodosFiltered', { todos: todos });
};
this.find = function () {
var todos;
if (filter) {
todos = dataStore.find(function (each) {
return (typeof each[filter] !== 'undefined') ? each.completed : !each.completed;
});
}
else {
todos = dataStore.all();
}
return todos;
};
this.clearCompleted = function () {
var todos;
dataStore.destroyAll({ completed: true });
todos = dataStore.all();
this.trigger('dataClearedCompleted', { todos: todos });
};
this.after('initialize', function () {
this.on(document, 'uiAddRequested', this.add);
this.on(document, 'uiUpdateRequested', this.update);
this.on(document, 'uiRemoveRequested', this.remove);
this.on(document, 'uiLoadRequested', this.load);
this.on(document, 'uiToggleRequested', this.toggleCompleted);
this.on(document, 'uiToggleAllRequested', this.toggleAllCompleted);
this.on(document, 'uiClearRequested', this.clearCompleted);
this.on(document, 'uiFilterRequested', this.filter);
});
}
}
);
/*global define */
'use strict';
define(
[
'flight/component'
],
function (defineComponent) {
return defineComponent(mainSelector);
function mainSelector() {
this.toggle = function (e, data) {
var toggle = data.all > 0;
this.$node.toggle(toggle);
}
};
this.after('initialize', function () {
this.$node.hide();
......
/*global define */
'use strict';
define(
[
'flight/component'
],
function (defineComponent) {
return defineComponent(newItem);
function newItem() {
var ENTER_KEY = 13;
this.createOnEnter = function (e) {
......@@ -25,7 +23,7 @@ define(
});
this.$node.val('');
}
};
this.after('initialize', function () {
this.on('keydown', this.createOnEnter);
......
/*global define */
'use strict';
define(
[
'flight/component',
'./with_filters',
......@@ -10,7 +10,6 @@ define(
],
function (defineComponent, withFilters, statsTmpl, utils) {
return defineComponent(stats, withFilters);
function stats() {
......@@ -26,11 +25,11 @@ define(
this.$node.html(template(data));
this.$node.toggle(toggle);
this.markSelected(data.filter);
}
};
this.clearCompleted = function (e, data) {
this.trigger('uiClearRequested');
}
};
this.after('initialize', function () {
this.$node.hide();
......
/*global define $ */
'use strict';
define(
[
'flight/component',
'text!app/templates/todo.html',
......@@ -9,11 +9,9 @@ define(
],
function (defineComponent, todoTmpl, utils) {
return defineComponent(todoList);
function todoList() {
var ENTER_KEY = 13;
var template = utils.tmpl(todoTmpl);
......@@ -29,29 +27,28 @@ define(
data.todos.forEach(function (each) {
this.render(e, { todo: each });
}, this);
}
};
this.render = function (e, data) {
if (e.type == 'dataTodoAdded'
&& data.filter == 'completed') {
if (e.type === 'dataTodoAdded' && data.filter === 'completed') {
return;
}
this.$node.append(template(data.todo));
}
};
this.edit = function (e, data) {
var $todoEl = $(data.el).parents('li');
$todoEl.addClass('editing');
this.select('editSelector').focus();
}
};
this.requestUpdate = function (e, data) {
var $inputEl = $(e.currentTarget);
var $todoEl = $inputEl.parents('li');
var $todoEl = $inputEl.parents('li');
var value = $inputEl.val().trim();
var id = $todoEl.attr('id');
var id = $todoEl.attr('id');
if (!$todoEl.hasClass('editing')) {
return;
......@@ -65,30 +62,30 @@ define(
} else {
this.trigger('uiRemoveRequested', { id: id });
}
},
};
this.requestUpdateOnEnter = function (e, data) {
if (e.which === ENTER_KEY) {
this.requestUpdate(e, data);
}
},
};
this.requestRemove = function (e, data) {
var id = $(data.el).attr('id').split('_')[1];
this.trigger('uiRemoveRequested', { id: id });
}
};
this.remove = function (e, data) {
var $todoEl = this.$node.find('#' + data.id);
$todoEl.remove();
}
};
this.toggle = function (e, data) {
var $todoEl = $(data.el).parents('li');
$todoEl.toggleClass('completed');
this.trigger('uiToggleRequested', { id: $todoEl.attr('id') });
}
};
this.after('initialize', function () {
this.on(document, 'dataTodoAdded', this.render);
......
/*global define */
'use strict';
define(
[
'flight/component'
],
function (defineComponent) {
return defineComponent(toggleAll);
function toggleAll() {
......@@ -15,11 +14,11 @@ define(
this.trigger('uiToggleAllRequested', {
completed: this.$node.is(':checked')
});
}
};
this.toggleCheckbox = function (e, data) {
this.$node[0].checked = !data.remaining;
}
};
this.after('initialize', function () {
this.on('click', this.toggleAllComplete);
......
/*global define $ */
'use strict';
define(
function() {
return withFilters;
function withFilters() {
function () {
return function withFilters() {
this.defaultAttrs({
filterSelector: '#filters a'
});
......@@ -17,15 +14,15 @@ define(
this.select('filterSelector').removeClass('selected');
$(data.el).addClass('selected');
this.trigger('uiFilterRequested', { filter: filter });
}
};
this.markSelected = function (filter) {
this.$node.find('[href="#/' + filter + '"]').addClass('selected');
}
};
this.after('initialize', function() {
this.after('initialize', function () {
this.on('click', { filterSelector: this.chooseFilter });
});
}
};
}
);
/*global define */
'use strict';
// tmpl function scooped from underscore.
......@@ -13,6 +14,7 @@ define(function () {
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
/*jshint quotmark:false */
"'": '&#x27;',
'/': '&#x2F;'
}
......@@ -28,28 +30,32 @@ define(function () {
};
// Functions for escaping and unescaping strings to/from HTML interpolation.
['escape', 'unescape'].forEach(function(method) {
_[method] = function(string) {
if (string == null) return '';
return ('' + string).replace(entityRegexes[method], function(match) {
['escape', 'unescape'].forEach(function (method) {
_[method] = function (string) {
if (string === null || string === undefined) {
return '';
}
return ('' + string).replace(entityRegexes[method], function (match) {
return entityMap[method][match];
});
};
});
var settings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
evaluate: /<%([\s\S]+?)%>/g,
interpolate: /<%=([\s\S]+?)%>/g,
escape: /<%-([\s\S]+?)%>/g
};
var noMatch = /(.)^/;
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
/*jshint quotmark:false */
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
......@@ -59,22 +65,24 @@ define(function () {
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
var template = function(text, data) {
var template = function (text, data) {
var render;
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
text.replace(matcher, function (match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
.replace(escaper, function (match) {
return '\\' + escapes[match];
});
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
......@@ -91,7 +99,9 @@ define(function () {
source += "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
if (!settings.variable) {
source = 'with(obj||{}){\n' + source + '}\n';
}
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
......@@ -99,13 +109,16 @@ define(function () {
try {
render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
} catch (err) {
err.source = source;
throw err;
}
if (data) {
return render(data, _);
}
if (data) return render(data, _);
var template = function(data) {
var template = function (data) {
return render.call(this, data, _);
};
......
......@@ -6,24 +6,25 @@
<title>Flight • Todo</title>
<link rel="stylesheet" href="../../assets/base.css">
</head>
<body>
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus>
</header>
<section id="main">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
<body>
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus>
</header>
<section id="main">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
</section>
<footer id="footer"></footer>
</section>
<footer id="footer"></footer>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://github.com/mkuklis">Michal Kuklis</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script data-main="app/js/main" src="components/requirejs/requirejs.js"></script>
</body>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://github.com/mkuklis">Michal Kuklis</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script src="../../assets/base.js"></script>
<script data-main="app/js/main" src="components/requirejs/requirejs.js"></script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Template • TodoMVC</title>
<link rel="stylesheet" href="../assets/base.css">
<!-- CSS overrides - remove if you don't need it -->
<link rel="stylesheet" href="css/app.css">
<!--[if IE]>
<script src="../assets/ie.js"></script>
<![endif]-->
</head>
<body>
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus>
</header>
<!-- This section should be hidden by default and shown when there are todos -->
<section id="main">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list">
<!-- These are here just to show the structure of the list items -->
<!-- List items should get the class `editing` when editing and `completed` when marked as completed -->
<li class="completed">
<div class="view">
<input class="toggle" type="checkbox" checked>
<label>Create a TodoMVC template</label>
<button class="destroy"></button>
</div>
<input class="edit" value="Create a TodoMVC template">
</li>
<li>
<div class="view">
<input class="toggle" type="checkbox">
<label>Rule the web</label>
<button class="destroy"></button>
</div>
<input class="edit" value="Rule the web">
</li>
</ul>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Template • TodoMVC</title>
<link rel="stylesheet" href="../assets/base.css">
<!-- CSS overrides - remove if you don't need it -->
<link rel="stylesheet" href="css/app.css">
<!--[if IE]>
<script src="../assets/ie.js"></script>
<![endif]-->
</head>
<body>
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus>
</header>
<!-- This section should be hidden by default and shown when there are todos -->
<section id="main">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list">
<!-- These are here just to show the structure of the list items -->
<!-- List items should get the class `editing` when editing and `completed` when marked as completed -->
<li class="completed">
<div class="view">
<input class="toggle" type="checkbox" checked>
<label>Create a TodoMVC template</label>
<button class="destroy"></button>
</div>
<input class="edit" value="Create a TodoMVC template">
</li>
<li>
<div class="view">
<input class="toggle" type="checkbox">
<label>Rule the web</label>
<button class="destroy"></button>
</div>
<input class="edit" value="Rule the web">
</li>
</ul>
</section>
<!-- This footer should hidden by default and shown when there are todos -->
<footer id="footer">
<!-- This should be `0 items left` by default -->
<span id="todo-count"><strong>1</strong> item left</span>
<!-- Remove this if you don't implement routing -->
<ul id="filters">
<li>
<a class="selected" href="#/">All</a>
</li>
<li>
<a href="#/active">Active</a>
</li>
<li>
<a href="#/completed">Completed</a>
</li>
</ul>
<button id="clear-completed">Clear completed (1)</button>
</footer>
</section>
<!-- This footer should hidden by default and shown when there are todos -->
<footer id="footer">
<!-- This should be `0 items left` by default -->
<span id="todo-count"><strong>1</strong> item left</span>
<!-- Remove this if you don't implement routing -->
<ul id="filters">
<li>
<a class="selected" href="#/">All</a>
</li>
<li>
<a href="#/active">Active</a>
</li>
<li>
<a href="#/completed">Completed</a>
</li>
</ul>
<button id="clear-completed">Clear completed (1)</button>
<footer id="info">
<p>Double-click to edit a todo</p>
<!-- Remove the below line ↓ -->
<p>Template by <a href="http://github.com/sindresorhus">Sindre Sorhus</a></p>
<!-- Change this out with your name and url ↓ -->
<p>Created by <a href="http://todomvc.com">you</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<!-- Remove the below line ↓ -->
<p>Template by <a href="http://github.com/sindresorhus">Sindre Sorhus</a></p>
<!-- Change this out with your name and url ↓ -->
<p>Created by <a href="http://todomvc.com">you</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<!-- Scripts here. Don't remove this ↓ -->
<script src="../assets/base.js"></script>
<script src="js/app.js"></script>
</body>
<!-- Scripts here. Don't remove this ↓ -->
<script src="../assets/base.js"></script>
<script src="js/app.js"></script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment