Created
April 7, 2017 22:33
-
-
Save camilokawerin/5dd6434a37d8c54d54a90e7c6cc17602 to your computer and use it in GitHub Desktop.
JS Bin TodoMVC Guide 3.0 Start // source https://jsbin.com/bosogem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="description" content="TodoMVC Guide 3.0 Start"> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
<style id="jsbin-css"> | |
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.saving { | |
font-style: italic; | |
} | |
#todoapp #todo-list li.destroying label { | |
font-style: italic; | |
color: #a88a8a; | |
} | |
#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: '\2713'; | |
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: 'x'; | |
} | |
#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; | |
} | |
hr { | |
margin: 20px 0; | |
border: 0; | |
border-top: 1px dashed #C5C5C5; | |
border-bottom: 1px dashed #F7F7F7; | |
} | |
.learn a { | |
font-weight: normal; | |
text-decoration: none; | |
color: #b83f45; | |
} | |
.learn a:hover { | |
text-decoration: underline; | |
color: #787e7e; | |
} | |
.learn h3, | |
.learn h4, | |
.learn h5 { | |
margin: 10px 0; | |
font-weight: 500; | |
line-height: 1.2; | |
color: #000; | |
} | |
.learn h3 { | |
font-size: 24px; | |
} | |
.learn h4 { | |
font-size: 18px; | |
} | |
.learn h5 { | |
margin-bottom: 0; | |
font-size: 14px; | |
} | |
.learn ul { | |
padding: 0; | |
margin: 0 0 30px 25px; | |
} | |
.learn li { | |
line-height: 20px; | |
} | |
.learn p { | |
font-size: 15px; | |
font-weight: 300; | |
line-height: 1.3; | |
margin-top: 0; | |
margin-bottom: 0; | |
} | |
.quote { | |
border: none; | |
margin: 20px 0 60px 0; | |
} | |
.quote p { | |
font-style: italic; | |
} | |
.quote p:before { | |
content: '“'; | |
font-size: 50px; | |
opacity: .15; | |
position: absolute; | |
top: -20px; | |
left: 3px; | |
} | |
.quote p:after { | |
content: '”'; | |
font-size: 50px; | |
opacity: .15; | |
position: absolute; | |
bottom: -42px; | |
right: 3px; | |
} | |
.quote footer { | |
position: absolute; | |
bottom: -40px; | |
right: 0; | |
} | |
.quote footer img { | |
border-radius: 3px; | |
} | |
.quote footer a { | |
margin-left: 5px; | |
vertical-align: middle; | |
} | |
.speech-bubble { | |
position: relative; | |
padding: 10px; | |
background: rgba(0, 0, 0, .04); | |
border-radius: 5px; | |
} | |
.speech-bubble:after { | |
content: ''; | |
position: absolute; | |
top: 100%; | |
right: 30px; | |
border: 13px solid transparent; | |
border-top-color: rgba(0, 0, 0, .04); | |
} | |
/**body*/.learn-bar > .learn { | |
position: absolute; | |
width: 272px; | |
top: 8px; | |
left: -300px; | |
padding: 10px; | |
border-radius: 5px; | |
background-color: rgba(255, 255, 255, .6); | |
transition-property: left; | |
transition-duration: 500ms; | |
} | |
@media (min-width: 899px) { | |
/**body*/.learn-bar { | |
width: auto; | |
margin: 0 0 0 300px; | |
} | |
/**body*/.learn-bar > .learn { | |
left: 8px; | |
} | |
/**body*/.learn-bar #todoapp { | |
width: 550px; | |
margin: 130px auto 40px auto; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<script type='text/stache' id='todo-create-template'> | |
<input id="new-todo" | |
placeholder="What needs to be done?" | |
{($value)}="todo.name" | |
($enter)="createTodo()"/> | |
</script> | |
<script type='text/stache' id='todo-list-template'> | |
<ul id="todo-list"> | |
{{#each todos}} | |
<li class="todo {{#if complete}}completed{{/if}} | |
{{#if isDestroying}}destroying{{/if}} | |
{{#if isEditing(this)}}editing{{/if}}"> | |
<div class="view"> | |
<input class="toggle" type="checkbox" | |
{($checked)}="complete" ($change)="save()"> | |
<label ($dblclick)="edit(this)">{{name}}</label> | |
<button class="destroy" ($click)="destroy()"></button> | |
</div> | |
<input class="edit" type="text" | |
{($value)}="name" | |
($enter)="updateName()" | |
{$focused}="isEditing(this)" | |
($blur)="cancelEdit()"/> | |
</li> | |
{{/each}} | |
</ul> | |
</script> | |
<script type="text/stache" id="todomvc-template"> | |
<section id="todoapp"> | |
<header id="header"> | |
<h1>todos</h1> | |
<todo-create/> | |
</header> | |
<section id="main" class=""> | |
<input id="toggle-all" type="checkbox" | |
{($checked)}="allChecked" | |
{$disabled}="todosList.saving.length"/> | |
<label for="toggle-all">Mark all as complete</label> | |
<todo-list {todos}="todosPromise.value"/> | |
</section> | |
<footer id="footer" class=""> | |
<span id="todo-count"> | |
<strong>{{todosPromise.value.active.length}}</strong> items left | |
</span> | |
<ul id="filters"> | |
<li> | |
<a href="{{routeUrl filter=undefined}}" | |
{{#routeCurrent filter=undefined}}class='selected'{{/routeCurrent}}>All</a> | |
</li> | |
<li> | |
<a href="{{routeUrl filter='active'}}" | |
{{#routeCurrent filter='active'}}class='selected'{{/routeCurrent}}>Active</a> | |
</li> | |
<li> | |
<a href="{{routeUrl filter='complete'}}" | |
{{#routeCurrent filter='complete'}}class='selected'{{/routeCurrent}}>Completed</a> | |
</li> | |
</ul> | |
<button id="clear-completed" | |
($click)="todosList.destroyComplete()"> | |
Clear completed ({{todosPromise.value.complete.length}}) | |
</button> | |
</footer> | |
</section> | |
</script> | |
<script src="https://code.jquery.com/jquery-2.2.4.js"></script> | |
<script src="https://unpkg.com/can/dist/global/can.all.js"></script> | |
<script id="jsbin-javascript"> | |
var todoAlgebra = new can.set.Algebra( | |
can.set.props.boolean("complete"), | |
can.set.props.id("id"), | |
can.set.props.sort("sort") | |
); | |
var todoStore = can.fixture.store([ | |
{ name: "mow lawn", complete: false, id: 5 }, | |
{ name: "dishes", complete: true, id: 6 }, | |
{ name: "learn canjs", complete: false, id: 7 } | |
], todoAlgebra); | |
can.fixture("/api/todos", todoStore); | |
can.fixture.delay = 1000; | |
var Todo = can.DefineMap.extend({ | |
id: "number", | |
name: "string", | |
complete: {type: "boolean", value: false} | |
}); | |
Todo.List = can.DefineList.extend({ | |
"#": Todo, | |
get active(){ | |
return this.filter({complete: false}); | |
}, | |
get complete(){ | |
return this.filter({complete: true}); | |
}, | |
get allComplete(){ | |
return this.length === this.complete.length; | |
}, | |
get saving(){ | |
return this.filter(function(todo){ | |
return todo.isSaving(); | |
}); | |
}, | |
updateCompleteTo: function(value){ | |
this.forEach(function(todo){ | |
todo.complete = value; | |
todo.save(); | |
}); | |
}, | |
destroyComplete: function(){ | |
this.complete.forEach(function(todo){ | |
todo.destroy(); | |
}); | |
} | |
}); | |
can.connect.superMap({ | |
url: "/api/todos", | |
Map: Todo, | |
List: Todo.List, | |
name: "todo", | |
algebra: todoAlgebra | |
}); | |
var TodoCreateVM = can.DefineMap.extend({ | |
todo: {Value: Todo}, | |
createTodo: function(){ | |
this.todo.save().then(function(){ | |
this.todo = new Todo(); | |
}.bind(this)); | |
} | |
}); | |
can.Component.extend({ | |
tag: "todo-create", | |
view: can.stache.from("todo-create-template"), | |
ViewModel: TodoCreateVM | |
}); | |
var TodoListVM = can.DefineMap.extend({ | |
todos: Todo.List, | |
editing: Todo, | |
backupName: "string", | |
isEditing: function(todo){ | |
return todo === this.editing; | |
}, | |
edit: function(todo){ | |
this.backupName = todo.name; | |
this.editing = todo; | |
}, | |
cancelEdit: function(){ | |
if(this.editing) { | |
this.editing.name = this.backupName; | |
} | |
this.editing = null; | |
}, | |
updateName: function() { | |
this.editing.save(); | |
this.editing = null; | |
} | |
}); | |
can.Component.extend({ | |
tag: "todo-list", | |
view: can.stache.from("todo-list-template"), | |
ViewModel: TodoListVM | |
}); | |
var AppVM = can.DefineMap.extend({ | |
filter: "string", | |
get todosPromise(){ | |
if(!this.filter) { | |
return Todo.getList({}); | |
} else { | |
return Todo.getList({complete: this.filter === "complete"}); | |
} | |
}, | |
todosList: { | |
get: function(lastSetValue, resolve){ | |
this.todosPromise.then(resolve); | |
} | |
}, | |
get allChecked(){ | |
return this.todosList && this.todosList.allComplete; | |
}, | |
set allChecked(newVal){ | |
this.todosList && this.todosList.updateCompleteTo(newVal); | |
} | |
}); | |
var appVM = new AppVM(); | |
can.route.data = appVM; | |
can.route("{filter}"); | |
can.route.ready(); | |
var template = can.stache.from("todomvc-template"); | |
var frag = template(appVM); | |
document.body.appendChild(frag); | |
</script> | |
<script id="jsbin-source-css" type="text/css">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.saving { | |
font-style: italic; | |
} | |
#todoapp #todo-list li.destroying label { | |
font-style: italic; | |
color: #a88a8a; | |
} | |
#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: '\2713'; | |
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: 'x'; | |
} | |
#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; | |
} | |
hr { | |
margin: 20px 0; | |
border: 0; | |
border-top: 1px dashed #C5C5C5; | |
border-bottom: 1px dashed #F7F7F7; | |
} | |
.learn a { | |
font-weight: normal; | |
text-decoration: none; | |
color: #b83f45; | |
} | |
.learn a:hover { | |
text-decoration: underline; | |
color: #787e7e; | |
} | |
.learn h3, | |
.learn h4, | |
.learn h5 { | |
margin: 10px 0; | |
font-weight: 500; | |
line-height: 1.2; | |
color: #000; | |
} | |
.learn h3 { | |
font-size: 24px; | |
} | |
.learn h4 { | |
font-size: 18px; | |
} | |
.learn h5 { | |
margin-bottom: 0; | |
font-size: 14px; | |
} | |
.learn ul { | |
padding: 0; | |
margin: 0 0 30px 25px; | |
} | |
.learn li { | |
line-height: 20px; | |
} | |
.learn p { | |
font-size: 15px; | |
font-weight: 300; | |
line-height: 1.3; | |
margin-top: 0; | |
margin-bottom: 0; | |
} | |
.quote { | |
border: none; | |
margin: 20px 0 60px 0; | |
} | |
.quote p { | |
font-style: italic; | |
} | |
.quote p:before { | |
content: '“'; | |
font-size: 50px; | |
opacity: .15; | |
position: absolute; | |
top: -20px; | |
left: 3px; | |
} | |
.quote p:after { | |
content: '”'; | |
font-size: 50px; | |
opacity: .15; | |
position: absolute; | |
bottom: -42px; | |
right: 3px; | |
} | |
.quote footer { | |
position: absolute; | |
bottom: -40px; | |
right: 0; | |
} | |
.quote footer img { | |
border-radius: 3px; | |
} | |
.quote footer a { | |
margin-left: 5px; | |
vertical-align: middle; | |
} | |
.speech-bubble { | |
position: relative; | |
padding: 10px; | |
background: rgba(0, 0, 0, .04); | |
border-radius: 5px; | |
} | |
.speech-bubble:after { | |
content: ''; | |
position: absolute; | |
top: 100%; | |
right: 30px; | |
border: 13px solid transparent; | |
border-top-color: rgba(0, 0, 0, .04); | |
} | |
/**body*/.learn-bar > .learn { | |
position: absolute; | |
width: 272px; | |
top: 8px; | |
left: -300px; | |
padding: 10px; | |
border-radius: 5px; | |
background-color: rgba(255, 255, 255, .6); | |
transition-property: left; | |
transition-duration: 500ms; | |
} | |
@media (min-width: 899px) { | |
/**body*/.learn-bar { | |
width: auto; | |
margin: 0 0 0 300px; | |
} | |
/**body*/.learn-bar > .learn { | |
left: 8px; | |
} | |
/**body*/.learn-bar #todoapp { | |
width: 550px; | |
margin: 130px auto 40px auto; | |
} | |
} | |
</script> | |
<script id="jsbin-source-javascript" type="text/javascript">var todoAlgebra = new can.set.Algebra( | |
can.set.props.boolean("complete"), | |
can.set.props.id("id"), | |
can.set.props.sort("sort") | |
); | |
var todoStore = can.fixture.store([ | |
{ name: "mow lawn", complete: false, id: 5 }, | |
{ name: "dishes", complete: true, id: 6 }, | |
{ name: "learn canjs", complete: false, id: 7 } | |
], todoAlgebra); | |
can.fixture("/api/todos", todoStore); | |
can.fixture.delay = 1000; | |
var Todo = can.DefineMap.extend({ | |
id: "number", | |
name: "string", | |
complete: {type: "boolean", value: false} | |
}); | |
Todo.List = can.DefineList.extend({ | |
"#": Todo, | |
get active(){ | |
return this.filter({complete: false}); | |
}, | |
get complete(){ | |
return this.filter({complete: true}); | |
}, | |
get allComplete(){ | |
return this.length === this.complete.length; | |
}, | |
get saving(){ | |
return this.filter(function(todo){ | |
return todo.isSaving(); | |
}); | |
}, | |
updateCompleteTo: function(value){ | |
this.forEach(function(todo){ | |
todo.complete = value; | |
todo.save(); | |
}); | |
}, | |
destroyComplete: function(){ | |
this.complete.forEach(function(todo){ | |
todo.destroy(); | |
}); | |
} | |
}); | |
can.connect.superMap({ | |
url: "/api/todos", | |
Map: Todo, | |
List: Todo.List, | |
name: "todo", | |
algebra: todoAlgebra | |
}); | |
var TodoCreateVM = can.DefineMap.extend({ | |
todo: {Value: Todo}, | |
createTodo: function(){ | |
this.todo.save().then(function(){ | |
this.todo = new Todo(); | |
}.bind(this)); | |
} | |
}); | |
can.Component.extend({ | |
tag: "todo-create", | |
view: can.stache.from("todo-create-template"), | |
ViewModel: TodoCreateVM | |
}); | |
var TodoListVM = can.DefineMap.extend({ | |
todos: Todo.List, | |
editing: Todo, | |
backupName: "string", | |
isEditing: function(todo){ | |
return todo === this.editing; | |
}, | |
edit: function(todo){ | |
this.backupName = todo.name; | |
this.editing = todo; | |
}, | |
cancelEdit: function(){ | |
if(this.editing) { | |
this.editing.name = this.backupName; | |
} | |
this.editing = null; | |
}, | |
updateName: function() { | |
this.editing.save(); | |
this.editing = null; | |
} | |
}); | |
can.Component.extend({ | |
tag: "todo-list", | |
view: can.stache.from("todo-list-template"), | |
ViewModel: TodoListVM | |
}); | |
var AppVM = can.DefineMap.extend({ | |
filter: "string", | |
get todosPromise(){ | |
if(!this.filter) { | |
return Todo.getList({}); | |
} else { | |
return Todo.getList({complete: this.filter === "complete"}); | |
} | |
}, | |
todosList: { | |
get: function(lastSetValue, resolve){ | |
this.todosPromise.then(resolve); | |
} | |
}, | |
get allChecked(){ | |
return this.todosList && this.todosList.allComplete; | |
}, | |
set allChecked(newVal){ | |
this.todosList && this.todosList.updateCompleteTo(newVal); | |
} | |
}); | |
var appVM = new AppVM(); | |
can.route.data = appVM; | |
can.route("{filter}"); | |
can.route.ready(); | |
var template = can.stache.from("todomvc-template"); | |
var frag = template(appVM); | |
document.body.appendChild(frag);</script></body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.saving { | |
font-style: italic; | |
} | |
#todoapp #todo-list li.destroying label { | |
font-style: italic; | |
color: #a88a8a; | |
} | |
#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: '\2713'; | |
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: 'x'; | |
} | |
#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; | |
} | |
hr { | |
margin: 20px 0; | |
border: 0; | |
border-top: 1px dashed #C5C5C5; | |
border-bottom: 1px dashed #F7F7F7; | |
} | |
.learn a { | |
font-weight: normal; | |
text-decoration: none; | |
color: #b83f45; | |
} | |
.learn a:hover { | |
text-decoration: underline; | |
color: #787e7e; | |
} | |
.learn h3, | |
.learn h4, | |
.learn h5 { | |
margin: 10px 0; | |
font-weight: 500; | |
line-height: 1.2; | |
color: #000; | |
} | |
.learn h3 { | |
font-size: 24px; | |
} | |
.learn h4 { | |
font-size: 18px; | |
} | |
.learn h5 { | |
margin-bottom: 0; | |
font-size: 14px; | |
} | |
.learn ul { | |
padding: 0; | |
margin: 0 0 30px 25px; | |
} | |
.learn li { | |
line-height: 20px; | |
} | |
.learn p { | |
font-size: 15px; | |
font-weight: 300; | |
line-height: 1.3; | |
margin-top: 0; | |
margin-bottom: 0; | |
} | |
.quote { | |
border: none; | |
margin: 20px 0 60px 0; | |
} | |
.quote p { | |
font-style: italic; | |
} | |
.quote p:before { | |
content: '“'; | |
font-size: 50px; | |
opacity: .15; | |
position: absolute; | |
top: -20px; | |
left: 3px; | |
} | |
.quote p:after { | |
content: '”'; | |
font-size: 50px; | |
opacity: .15; | |
position: absolute; | |
bottom: -42px; | |
right: 3px; | |
} | |
.quote footer { | |
position: absolute; | |
bottom: -40px; | |
right: 0; | |
} | |
.quote footer img { | |
border-radius: 3px; | |
} | |
.quote footer a { | |
margin-left: 5px; | |
vertical-align: middle; | |
} | |
.speech-bubble { | |
position: relative; | |
padding: 10px; | |
background: rgba(0, 0, 0, .04); | |
border-radius: 5px; | |
} | |
.speech-bubble:after { | |
content: ''; | |
position: absolute; | |
top: 100%; | |
right: 30px; | |
border: 13px solid transparent; | |
border-top-color: rgba(0, 0, 0, .04); | |
} | |
/**body*/.learn-bar > .learn { | |
position: absolute; | |
width: 272px; | |
top: 8px; | |
left: -300px; | |
padding: 10px; | |
border-radius: 5px; | |
background-color: rgba(255, 255, 255, .6); | |
transition-property: left; | |
transition-duration: 500ms; | |
} | |
@media (min-width: 899px) { | |
/**body*/.learn-bar { | |
width: auto; | |
margin: 0 0 0 300px; | |
} | |
/**body*/.learn-bar > .learn { | |
left: 8px; | |
} | |
/**body*/.learn-bar #todoapp { | |
width: 550px; | |
margin: 130px auto 40px auto; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var todoAlgebra = new can.set.Algebra( | |
can.set.props.boolean("complete"), | |
can.set.props.id("id"), | |
can.set.props.sort("sort") | |
); | |
var todoStore = can.fixture.store([ | |
{ name: "mow lawn", complete: false, id: 5 }, | |
{ name: "dishes", complete: true, id: 6 }, | |
{ name: "learn canjs", complete: false, id: 7 } | |
], todoAlgebra); | |
can.fixture("/api/todos", todoStore); | |
can.fixture.delay = 1000; | |
var Todo = can.DefineMap.extend({ | |
id: "number", | |
name: "string", | |
complete: {type: "boolean", value: false} | |
}); | |
Todo.List = can.DefineList.extend({ | |
"#": Todo, | |
get active(){ | |
return this.filter({complete: false}); | |
}, | |
get complete(){ | |
return this.filter({complete: true}); | |
}, | |
get allComplete(){ | |
return this.length === this.complete.length; | |
}, | |
get saving(){ | |
return this.filter(function(todo){ | |
return todo.isSaving(); | |
}); | |
}, | |
updateCompleteTo: function(value){ | |
this.forEach(function(todo){ | |
todo.complete = value; | |
todo.save(); | |
}); | |
}, | |
destroyComplete: function(){ | |
this.complete.forEach(function(todo){ | |
todo.destroy(); | |
}); | |
} | |
}); | |
can.connect.superMap({ | |
url: "/api/todos", | |
Map: Todo, | |
List: Todo.List, | |
name: "todo", | |
algebra: todoAlgebra | |
}); | |
var TodoCreateVM = can.DefineMap.extend({ | |
todo: {Value: Todo}, | |
createTodo: function(){ | |
this.todo.save().then(function(){ | |
this.todo = new Todo(); | |
}.bind(this)); | |
} | |
}); | |
can.Component.extend({ | |
tag: "todo-create", | |
view: can.stache.from("todo-create-template"), | |
ViewModel: TodoCreateVM | |
}); | |
var TodoListVM = can.DefineMap.extend({ | |
todos: Todo.List, | |
editing: Todo, | |
backupName: "string", | |
isEditing: function(todo){ | |
return todo === this.editing; | |
}, | |
edit: function(todo){ | |
this.backupName = todo.name; | |
this.editing = todo; | |
}, | |
cancelEdit: function(){ | |
if(this.editing) { | |
this.editing.name = this.backupName; | |
} | |
this.editing = null; | |
}, | |
updateName: function() { | |
this.editing.save(); | |
this.editing = null; | |
} | |
}); | |
can.Component.extend({ | |
tag: "todo-list", | |
view: can.stache.from("todo-list-template"), | |
ViewModel: TodoListVM | |
}); | |
var AppVM = can.DefineMap.extend({ | |
filter: "string", | |
get todosPromise(){ | |
if(!this.filter) { | |
return Todo.getList({}); | |
} else { | |
return Todo.getList({complete: this.filter === "complete"}); | |
} | |
}, | |
todosList: { | |
get: function(lastSetValue, resolve){ | |
this.todosPromise.then(resolve); | |
} | |
}, | |
get allChecked(){ | |
return this.todosList && this.todosList.allComplete; | |
}, | |
set allChecked(newVal){ | |
this.todosList && this.todosList.updateCompleteTo(newVal); | |
} | |
}); | |
var appVM = new AppVM(); | |
can.route.data = appVM; | |
can.route("{filter}"); | |
can.route.ready(); | |
var template = can.stache.from("todomvc-template"); | |
var frag = template(appVM); | |
document.body.appendChild(frag); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment