Commit f83a3caa authored by Stephen Sawchuk's avatar Stephen Sawchuk

DUEL bug fixed, code style.

parent b852875e
......@@ -2,7 +2,7 @@
<%-- could have embedded in 'tasks' for-loop, but this allows us to add single tasks --%>
<li class="<%= data.completed ? 'complete' : '' %>">
<li class="<%= data.completed ? 'completed' : '' %>">
<div class="view">
<input class="toggle" type="checkbox" checked="<%= data.completed %>"
......
/*global window */
/*jshint camelcase:false */
var todos = todos || {};
(function( todos, document ) {
(function (todos, document) {
'use strict';
/*-- private members -------------------------------*/
var ENTER_KEY = 13,
STATS_ID = 'footer',
TODOAPP_ID = 'todoapp',
TASKS_ID = 'main',
LIST_ID = 'todo-list',
EDITING_CSS = 'editing';
var ENTER_KEY = 13;
var STATS_ID = 'footer';
var TODOAPP_ID = 'todoapp';
var TASKS_ID = 'main';
var LIST_ID = 'todo-list';
var EDITING_CSS = 'editing';
function getById( id ) {
return document.getElementById( id );
function getById(id) {
return document.getElementById(id);
}
function refreshStats( stats ) {
function refreshStats(stats) {
// get the data
var data = stats || todos.model.stats();
// build the view
var view = todos.views.Stats( data ).toDOM();
var view = todos.views.Stats(data).toDOM();
// replace old stats
var old = getById( STATS_ID );
if ( old ) {
old.parentNode.replaceChild( view, old );
var old = getById(STATS_ID);
if (old) {
old.parentNode.replaceChild(view, old);
} else {
getById( TODOAPP_ID ).appendChild( view );
getById(TODOAPP_ID).appendChild(view);
}
}
......@@ -39,47 +43,47 @@ var todos = todos || {};
};
// build the view
var view = todos.views.Tasks( data ).toDOM();
var view = todos.views.Tasks(data).toDOM();
// replace old task list
var old = getById( TASKS_ID );
if ( old ) {
old.parentNode.replaceChild( view, old );
var old = getById(TASKS_ID);
if (old) {
old.parentNode.replaceChild(view, old);
} else {
getById( TODOAPP_ID ).appendChild( view );
getById(TODOAPP_ID).appendChild(view);
}
refreshStats( data.stats );
refreshStats(data.stats);
}
function add( input ) {
function add(input) {
var title = (input.value || '').trim();
input.value = '';
if ( !title ) {
if (!title) {
return;
}
var task = todos.model.add( title );
var task = todos.model.add(title);
var list = getById( LIST_ID );
if ( list ) {
var list = getById(LIST_ID);
if (list) {
// add new at the top
list.appendChild( todos.views.Task( task ).toDOM() );
list.appendChild(todos.views.Task(task).toDOM());
refreshStats();
} else {
refreshAll();
}
}
function edit( input, id ) {
function edit(input, id) {
var title = (input.value || '').trim();
input.value = title;
if ( title ) {
todos.model.edit( id, title );
if (title) {
todos.model.edit(id, title);
} else {
todos.model.remove( id );
todos.model.remove(id);
}
refreshAll();
}
......@@ -88,82 +92,92 @@ var todos = todos || {};
// event handlers
todos.actions = {
add_blur: function( e ) {
add( this );
addBlur: function () {
add(this);
},
add_keypress: function( e ) {
if ( e.keyCode === ENTER_KEY ) {
add( this );
add_keypress: function (e) {
if (e.keyCode === ENTER_KEY) {
add(this);
}
},
edit_blur: function( id ) {
edit_blur: function (id) {
// create a closure around the ID
return function( e ) {
edit( this, id );
return function () {
edit(this, id);
};
},
edit_keypress: function( id ) {
edit_keypress: function () {
// create a closure around the ID
return function(e) {
if ( e.keyCode === ENTER_KEY ) {
return function (e) {
if (e.keyCode === ENTER_KEY) {
// just blur so doesn't get triggered twice
this.blur();
}
};
},
remove_click: function( id ) {
remove_click: function (id) {
// create a closure around the ID
return function( e ) {
todos.model.remove( id );
return function () {
todos.model.remove(id);
refreshAll();
};
},
clear_click: function() {
clear_click: function () {
todos.model.expunge();
refreshAll();
},
content_dblclick: function( id ) {
content_dblclick: function () {
// create a closure around the ID
return function( e ) {
var li = this;
var toggleEditingMode = function (li) {
if (li.tagName !== 'LI') {
return toggleEditingMode(li.parentNode);
}
li.className = EDITING_CSS;
li.getElementsByTagName( 'input' )[1].focus();
var input = li.getElementsByTagName('input')[1];
input.focus();
input.value = input.value;
};
return function () {
toggleEditingMode(this);
};
},
completed_change: function( id ) {
completed_change: function (id) {
// create a closure around the ID
return function( e ) {
return function () {
var checkbox = this;
todos.model.toggle( id, checkbox.checked );
todos.model.toggle(id, checkbox.checked);
refreshAll();
};
},
toggle_change: function( e ) {
toggle_change: function () {
var checkbox = this;
todos.model.toggleAll( checkbox.checked );
todos.model.toggleAll(checkbox.checked);
refreshAll();
}
};
/*-- init task list -------------------------------*/
(function( body ) {
(function (body) {
// build out task list
var view = todos.views.TodoApp({
tasks: todos.model.tasks(),
stats: todos.model.stats()
}).toDOM();
tasks: todos.model.tasks(),
stats: todos.model.stats()
}).toDOM();
// insert at top
body.insertBefore( view, body.firstChild );
})( document.body );
body.insertBefore(view, body.firstChild);
})(document.body);
})( todos, document );
})(todos, window.document);
/*global window */
var todos = todos || {};
(function( todos, localStorage, KEY ) {
(function (todos, localStorage, KEY) {
'use strict';
/*-- private members -------------------------------*/
......@@ -8,22 +11,22 @@ var todos = todos || {};
// model uses localStorage as the underlying data store
// this creates a poor man's localStorage polyfill
localStorage = localStorage || (function() {
localStorage = localStorage || (function () {
var storage = {};
return {
getItem: function( key ) {
return storage[ key ];
getItem: function (key) {
return storage[key];
},
setItem: function( key, value ) {
storage[ key ] = value;
setItem: function (key, value) {
storage[key] = value;
}
};
})();
function create( title, completed ) {
function create(title, completed) {
return {
// fast, compact, non-repeating, unique ID: e.g., 'c2wwu0vz.pz4zpvi'
id: (new Date().getTime() + Math.random()).toString( 36 ),
id: (new Date().getTime() + Math.random()).toString(36),
title: title,
completed: !!completed
};
......@@ -31,16 +34,15 @@ var todos = todos || {};
function save() {
// if doesn't support JSON then will be directly stored in polyfill
var value = typeof JSON !== 'undefined' ? JSON.stringify( tasks ) : tasks;
localStorage.setItem( KEY, value );
var value = typeof JSON !== 'undefined' ? JSON.stringify(tasks) : tasks;
localStorage.setItem(KEY, value);
}
// initialize storage
var value = localStorage.getItem( KEY );
if ( value ) {
var value = localStorage.getItem(KEY);
if (value) {
// if doesn't support JSON then will be directly stored in polyfill
tasks = typeof JSON !== 'undefined' ? JSON.parse( value ) : value;
tasks = typeof JSON !== 'undefined' ? JSON.parse(value) : value;
} else {
tasks = [];
}
......@@ -48,90 +50,77 @@ var todos = todos || {};
/*-- export public interface -------------------------------*/
todos.model = {
tasks: function() {
tasks: function () {
return tasks;
},
stats: function() {
var stats = {
total: tasks.length,
active: tasks.length,
completed: 0
};
var i = tasks.length;
while ( i-- ) {
if ( tasks[i].completed ) {
stats.completed++;
}
}
stats.active -= stats.completed;
stats: function () {
var stats = {};
stats.total = tasks.length;
stats.completed = tasks.filter(function (task) {
return task.completed;
}).length;
stats.active = stats.total - stats.completed;
return stats;
},
add: function( title ) {
var task = create( title, false );
add: function (title) {
var task = create(title, false);
tasks.push( task );
tasks.push(task);
save();
return task;
},
edit: function( id, title ) {
var i = tasks.length;
while ( i-- ) {
if ( tasks[i].id === id ) {
tasks[i].title = title;
save();
return;
}
}
edit: function (id, title) {
tasks.filter(function (task) {
return task.id === id;
})[0].title = title;
save();
},
// toggle completion of task
toggle: function( id, completed ) {
var i = tasks.length;
while ( i-- ) {
if ( tasks[i].id === id ) {
tasks[i].completed = completed;
save();
return;
}
}
toggle: function (id, completed) {
tasks.filter(function (task) {
return task.id === id;
})[0].completed = completed;
save();
},
// toggle completion of all tasks
toggleAll: function( completed ) {
var i = tasks.length;
while ( i-- ) {
tasks[i].completed = completed;
}
toggleAll: function (completed) {
tasks.forEach(function (task) {
task.completed = completed;
});
save();
},
remove: function( id ) {
var i = tasks.length;
while ( i-- ) {
if ( tasks[i].id === id ) {
tasks.splice( i, 1 );
save();
return;
remove: function (id) {
tasks.forEach(function (task, index) {
if (task.id === id) {
tasks.splice(index, 1);
}
}
});
save();
},
expunge: function() {
var i = tasks.length;
while ( i-- ) {
if ( tasks[i].completed ) {
tasks.splice( i, 1 );
expunge: function () {
tasks.forEach(function (task, index) {
if (task.completed) {
tasks.splice(index, 1);
}
}
});
save();
}
};
})( todos, window.localStorage, 'todos-duel' );
})(todos, window.localStorage, 'todos-duel');
......@@ -12,7 +12,7 @@
<p>Ported to <a href="http://duelengine.org">DUEL</a> by <a href="http://mck.me">Stephen McKamey</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script src="./cdn/cb86ce6c04dc2c3e1a7111b0000b1252c883d20c.js"></script>
<script src="./cdn/4340176df828f72a94b201a48c223860b95908dc.js"></script>
</body>
</html>
\ No newline at end of file
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