Commit c9d80c13 authored by Stephen Sawchuk's avatar Stephen Sawchuk

cujo updated to use bower.

parent c08c83b8
/*global define */
define(function () { define(function () {
"use strict"; 'use strict';
var updateRemainingCount, textProp; var textProp;
updateRemainingCount = normalizeTextProp; /**
* Self-optimizing function to set the text of a node
*/
var updateRemainingCount = function () {
// sniff for proper textContent property
textProp = 'textContent' in document.documentElement ? 'textContent' : 'innerText';
// resume normally
updateRemainingCount = setTextProp;
updateRemainingCount(arguments);
};
var setTextProp = function (nodes, value) {
for (var i = 0; i < nodes.length; i++) {
nodes[i][textProp] = '' + value;
}
};
return { return {
/** /**
...@@ -12,27 +29,27 @@ define(function () { ...@@ -12,27 +29,27 @@ define(function () {
* @param todo {Object} data used to create new todo * @param todo {Object} data used to create new todo
* @param todo.text {String} text of the todo * @param todo.text {String} text of the todo
*/ */
createTodo: function(todo) {}, createTodo: function () {},
/** /**
* Remove an existing todo * Remove an existing todo
* @injected * @injected
* @param todo {Object} existing todo, or object with same identifier, to remove * @param todo {Object} existing todo, or object with same identifier, to remove
*/ */
removeTodo: function(todo) {}, removeTodo: function () {},
/** /**
* Update an existing todo * Update an existing todo
* @injected * @injected
* @param todo {Object} updated todo * @param todo {Object} updated todo
*/ */
updateTodo: function(todo) {}, updateTodo: function () {},
/** /**
* Start inline editing a todo * Start inline editing a todo
* @param node {Node} Dom node of the todo * @param node {Node} Dom node of the todo
*/ */
beginEditTodo: function(node) { beginEditTodo: function (node) {
this.querySelector('.edit', node).focus(); this.querySelector('.edit', node).focus();
}, },
...@@ -40,7 +57,7 @@ define(function () { ...@@ -40,7 +57,7 @@ define(function () {
* Finish editing a todo * Finish editing a todo
* @param todo {Object} todo to finish editing and save changes * @param todo {Object} todo to finish editing and save changes
*/ */
endEditTodo: function(todo) { endEditTodo: function (todo) {
// As per application spec, todos edited to have empty // As per application spec, todos edited to have empty
// text should be removed. // text should be removed.
if (/\S/.test(todo.text)) { if (/\S/.test(todo.text)) {
...@@ -53,24 +70,24 @@ define(function () { ...@@ -53,24 +70,24 @@ define(function () {
/** /**
* Remove all completed todos * Remove all completed todos
*/ */
removeCompleted: function() { removeCompleted: function () {
var todos = this.todos; var todos = this.todos;
todos.forEach(function(todo) { todos.forEach(function (todo) {
if(todo.complete) todos.remove(todo); if (todo.complete) {
todos.remove(todo);
}
}); });
}, },
/** /**
* Check/uncheck all todos * Check/uncheck all todos
*/ */
toggleAll: function() { toggleAll: function () {
var todos, complete; var todos = this.todos;
var complete = this.masterCheckbox.checked;
todos = this.todos;
complete = this.masterCheckbox.checked;
todos.forEach(function(todo) { todos.forEach(function (todo) {
todo.complete = complete; todo.complete = complete;
todos.update(todo); todos.update(todo);
}); });
...@@ -81,14 +98,16 @@ define(function () { ...@@ -81,14 +98,16 @@ define(function () {
* the check/uncheck all checkbox if all todos have become * the check/uncheck all checkbox if all todos have become
* checked or unchecked. * checked or unchecked.
*/ */
updateCount: function() { updateCount: function () {
var total, checked; var total = 0;
var checked = 0;
total = checked = 0;
this.todos.forEach(function(todo) { this.todos.forEach(function (todo) {
total++; total++;
if(todo.complete) checked++;
if (todo.complete) {
checked++;
}
}); });
this.masterCheckbox.checked = total > 0 && checked === total; this.masterCheckbox.checked = total > 0 && checked === total;
...@@ -99,32 +118,14 @@ define(function () { ...@@ -99,32 +118,14 @@ define(function () {
this.updateRemainingCount(total - checked); this.updateRemainingCount(total - checked);
}, },
updateTotalCount: function(total) {}, updateTotalCount: function () {},
updateCompletedCount: function(completed) { updateCompletedCount: function (completed) {
this.countNode.innerHTML = completed; this.countNode.innerHTML = completed;
}, },
updateRemainingCount: function (remaining) { updateRemainingCount: function (remaining) {
updateRemainingCount(this.remainingNodes, remaining); updateRemainingCount(this.remainingNodes, remaining);
} }
}; };
/**
* Self-optimizing function to set the text of a node
*/
function normalizeTextProp () {
// sniff for proper textContent property
textProp = 'textContent' in document.documentElement ? 'textContent' : 'innerText';
// resume normally
(updateRemainingCount = setTextProp).apply(this, arguments);
}
function setTextProp (nodes, value) {
for (var i = 0; i < nodes.length; i++) {
nodes[i][textProp] = '' + value;
}
}
}); });
/*global define */
define({ define({
// TODO: Deal with singular vs. plural
itemsLeft: { itemsLeft: {
zero: '<strong></strong> items left', zero: '<strong></strong> items left',
one: '<strong></strong> item left', one: '<strong></strong> item left',
......
...@@ -19,20 +19,23 @@ ...@@ -19,20 +19,23 @@
#clear-completed { #clear-completed {
opacity: 1; opacity: 1;
} }
.completed-zero #clear-completed { .completed-zero #clear-completed {
opacity: 0; opacity: 0;
} }
#footer { .todos-one #main,
display: none; .todos-many #main,
}
.todos-one #footer, .todos-one #footer,
.todos-many #footer { .todos-many #footer {
display: block; display: block;
} }
/* TODO: Reinstate once we add routing */ #main,
#filters { #footer,
.todos-zero #main,
.todos-zero #footer {
display: none; display: none;
} }
/* TODO: Reinstate once we add routing */
<footer id="footer"> <footer id="footer">
<!-- This should be `0 items left` by default -->
<span id="todo-count"> <span id="todo-count">
<span class="remaining-count-zero">${itemsLeft.zero}</span> <span class="remaining-count-zero">${itemsLeft.zero}</span>
<span class="remaining-count-one">${itemsLeft.one}</span> <span class="remaining-count-one">${itemsLeft.one}</span>
<span class="remaining-count-many">${itemsLeft.many}</span> <span class="remaining-count-many">${itemsLeft.many}</span>
</span> </span>
<!-- Remove this if you don't implement routing -->
<ul id="filters">
<li>
<a class="selected" href="#/">${filter.all}</a>
</li>
<li>
<a href="#/active">${filter.active}</a>
</li>
<li>
<a href="#/completed">${filter.completed}</a>
</li>
</ul>
<button id="clear-completed">${clearCompleted} (<span class="count">1</span>)</button> <button id="clear-completed">${clearCompleted} (<span class="count">1</span>)</button>
</footer> </footer>
define(function() { /*global define */
define(function () {
'use strict';
return function(todo) { return function (todo) {
todo.text = todo.text && todo.text.trim() || ''; todo.text = todo.text && todo.text.trim() || '';
todo.complete = !!todo.complete; todo.complete = !!todo.complete;
return todo; return todo;
} };
}); });
define(function() { /*global define */
/*jshint bitwise:false */
/** define(function () {
* Since we're using a datastore (localStorage) that doesn't generate ids and such 'use strict';
* for us, this transform generates a GUID id and a dateCreated. It can be
* injected into a pipeline for creating new todos.
*/
return function generateMetadata(item) {
item.id = guidLike();
item.dateCreated = new Date().getTime();
return item;
};
// GUID-like generation, not actually a GUID, tho, from: // GUID-like generation, not actually a GUID, tho, from:
// http://stackoverflow.com/questions/7940616/what-makes-this-pseudo-guid-generator-better-than-math-random // http://stackoverflow.com/questions/7940616/what-makes-this-pseudo-guid-generator-better-than-math-random
function s4() { function s4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1); return (((1 + Math.random()) * 0x10000)|0).toString(16).substring(1);
} }
function guidLike() { function guidLike() {
return (s4()+s4()+"-"+s4()+"-"+s4()+"-"+s4()+"-"+s4()+s4()+s4()); return (s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4());
} }
/**
* Since we're using a datastore (localStorage) that doesn't generate ids and
* such for us, this transform generates a GUID id and a dateCreated. It can
* be injected into a pipeline for creating new todos.
*/
return function generateMetadata(item) {
item.id = guidLike();
item.dateCreated = new Date().getTime();
return item;
};
}); });
/*global define */
define({ define({
title: 'todos', title: 'todos',
todo: { todo: {
......
define(function() { /*global define */
define(function () {
'use strict';
/** /**
* Validate a todo * Validate a todo
*/ */
return function validateTodo(todo) { return function validateTodo(todo) {
var valid, result;
// Must be a valid object, and have a text property that is non-empty // Must be a valid object, and have a text property that is non-empty
valid = todo && 'text' in todo && todo.text.trim(); var valid = todo && 'text' in todo && todo.text.trim();
result = { valid: !!valid }; var result = { valid: !!valid };
if(!valid) result.errors = [{ property: 'text', message: 'missing' }];
return result; if (!valid) {
result.errors = [{ property: 'text', message: 'missing' }];
} }
return result;
};
}); });
/*global define */
define({ define({
edit: 'Double-click to edit a todo', edit: 'Double-click to edit a todo',
templateBy: 'Template by', templateBy: 'Template by',
......
define(function() { /*global define */
define(function () {
'use strict';
/** /**
* Custom data linking handler for setting the "completed" class. * Custom data linking handler for setting the "completed" class.
...@@ -6,9 +8,8 @@ define(function() { ...@@ -6,9 +8,8 @@ define(function() {
* handlers for data/dom linking to do anything that isn't provided * handlers for data/dom linking to do anything that isn't provided
* by default. * by default.
*/ */
return function(node, data, info) { return function (node, data, info) {
// Simple-minded implementation just to show custom data linking handler // Simple-minded implementation just to show custom data linking handler
node.className = data[info.prop] ? 'completed' : ''; node.className = data[info.prop] ? 'completed' : '';
}; };
}); });
/*global define */
define({ define({
markAll: 'Mark all as complete' markAll: 'Mark all as complete'
}); });
#toggle-all { #toggle-all {
display: none; display: none;
} }
.todos-one #toggle-all, .todos-many #toggle-all {
.todos-one #toggle-all,
.todos-many #toggle-all {
display: block; display: block;
} }
/*global define */
define({ define({
// Cujo uses OOCSS principles and thus separates theme (skin) // Cujo uses OOCSS principles and thus separates theme (skin)
// from structure CSS. // from structure CSS.
theme: { module: 'css!theme/base.css' }, theme: { module: 'css!theme/base.css' },
...@@ -174,7 +174,7 @@ define({ ...@@ -174,7 +174,7 @@ define({
}, },
plugins: [ plugins: [
// { module: 'wire/debug', trace: true }, // { module: 'wire/debug', trace: true },
{ module: 'wire/dom' }, { module: 'wire/dom' },
{ module: 'wire/dom/render' }, { module: 'wire/dom/render' },
{ module: 'wire/on' }, { module: 'wire/on' },
......
(function( curl ) { /*global curl */
(function (curl) {
'use strict';
var config = { var config = {
baseUrl: 'app', baseUrl: 'app',
...@@ -17,5 +19,4 @@ ...@@ -17,5 +19,4 @@
}; };
curl(config, ['poly/string', 'poly/array']).next(['wire!main']); curl(config, ['poly/string', 'poly/array']).next(['wire!main']);
})(curl);
})( curl );
{
"name": "todomvc-cujo",
"version": "0.0.0",
"dependencies": {
"todomvc-common": "~0.1.4",
"curl": "~0.7.3",
"cola": "latest",
"poly": "~0.5.1",
"when": "~2.0.1",
"wire": "~0.9.4",
"meld": "~1.3.0"
}
}
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
color: inherit;
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea url('bg.png');
color: #4d4d4d;
width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#todoapp {
background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
}
#todoapp input::-webkit-input-placeholder {
font-style: italic;
}
#todoapp input:-moz-placeholder {
font-style: italic;
color: #a9a9a9;
}
#todoapp h1 {
position: absolute;
top: -120px;
width: 100%;
font-size: 70px;
font-weight: bold;
text-align: center;
color: #b3b3b3;
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.02);
z-index: 2;
box-shadow: none;
}
#main {
position: relative;
z-index: 2;
border-top: 1px dotted #adadad;
}
label[for='toggle-all'] {
display: none;
}
#toggle-all {
position: absolute;
top: -42px;
left: -4px;
width: 40px;
text-align: center;
border: none; /* Mobile Safari */
}
#toggle-all:before {
content: '»';
font-size: 28px;
color: #d9d9d9;
padding: 0 25px 7px;
}
#toggle-all:checked:before {
color: #737373;
}
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px dotted #ccc;
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list li.editing {
border-bottom: none;
padding: 0;
}
#todo-list li.editing .edit {
display: block;
width: 506px;
padding: 13px 17px 12px 17px;
margin: 0 0 0 43px;
}
#todo-list li.editing .view {
display: none;
}
#todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none; /* Mobile Safari */
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
#todo-list li .toggle:after {
content: '✔';
line-height: 43px; /* 40 + a couple of pixels visual adjustment */
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
}
#todo-list li .toggle:checked:after {
color: #85ada7;
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
}
#todo-list li label {
word-break: break-word;
padding: 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
-webkit-transition: color 0.4s;
-moz-transition: color 0.4s;
-ms-transition: color 0.4s;
-o-transition: color 0.4s;
transition: color 0.4s;
}
#todo-list li.completed label {
color: #a9a9a9;
text-decoration: line-through;
}
#todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 22px;
color: #a88a8a;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
#todo-list li .destroy:hover {
text-shadow: 0 0 1px #000,
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
-moz-transform: scale(1.3);
-ms-transform: scale(1.3);
-o-transform: scale(1.3);
transform: scale(1.3);
}
#todo-list li .destroy:after {
content: '✖';
}
#todo-list li:hover .destroy {
display: block;
}
#todo-list li .edit {
display: none;
}
#todo-list li.editing:last-child {
margin-bottom: -1px;
}
#footer {
color: #777;
padding: 0 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px;
z-index: 1;
text-align: center;
}
#footer:before {
content: '';
position: absolute;
right: 0;
bottom: 31px;
left: 0;
height: 50px;
z-index: -1;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
0 6px 0 -3px rgba(255, 255, 255, 0.8),
0 7px 1px -3px rgba(0, 0, 0, 0.3),
0 43px 0 -6px rgba(255, 255, 255, 0.8),
0 44px 2px -6px rgba(0, 0, 0, 0.2);
}
#todo-count {
float: left;
text-align: left;
}
#filters {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
right: 0;
left: 0;
}
#filters li {
display: inline;
}
#filters li a {
color: #83756f;
margin: 2px;
text-decoration: none;
}
#filters li a.selected {
font-weight: bold;
}
#clear-completed {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
font-size: 11px;
padding: 0 10px;
border-radius: 3px;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
}
#clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
}
#info {
margin: 65px auto 0;
color: #a6a6a6;
font-size: 12px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
text-align: center;
}
#info a {
color: inherit;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all,
#todo-list li .toggle {
background: none;
}
#todo-list li .toggle {
height: 40px;
}
#toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
}
.hidden{
display:none;
}
(function () {
'use strict';
if (location.hostname === 'todomvc.com') {
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'));
}
function getSourcePath() {
// If accessed via addyosmani.github.io/todomvc/, strip the project path.
if (location.hostname.indexOf('github.io') > 0) {
return location.pathname.replace(/todomvc\//, '');
}
return location.pathname;
}
function appendSourceLink() {
var sourceLink = document.createElement('a');
var paragraph = document.createElement('p');
var footer = document.getElementById('info');
var urlBase = 'https://github.com/addyosmani/todomvc/tree/gh-pages';
if (footer) {
sourceLink.href = urlBase + getSourcePath();
sourceLink.appendChild(document.createTextNode('Check out the source'));
paragraph.appendChild(sourceLink);
footer.appendChild(paragraph);
}
}
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink();
redirect();
})();
...@@ -4,15 +4,12 @@ ...@@ -4,15 +4,12 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>cujo • TodoMVC</title> <title>cujo • TodoMVC</title>
<link rel="stylesheet" href="../../../assets/base.css"> <link rel="stylesheet" href="bower_components/todomvc-common/base.css">
<!--[if IE]>
<script src="../../../assets/ie.js"></script>
<![endif]-->
<script src="lib/curl/src/curl.js"></script>
<script src="app/run.js"></script>
</head> </head>
<body> <body>
<section id="todoapp"></section> <section id="todoapp"></section>
<script src="../../../assets/base.js"></script> <script src="bower_components/todomvc-common/base.js"></script>
<script src="lib/curl/src/curl.js"></script>
<script src="app/run.js"></script>
</body> </body>
</html> </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