Commit 517a75d0 authored by Peter Michaux's avatar Peter Michaux

rewrite Maria TodoMVC example to use the latest version of Maria and the new TodoMVC template

parent 3746529d
/*
Aristocrat version 1
Aristocrat version 2
Copyright (c) 2012, Peter Michaux
All rights reserved.
Licensed under the Simplified BSD License.
https://github.com/petermichaux/aristocrat/blob/master/LICENSE
*/
var aristocrat = aristocrat || {};
var aristocrat = {};
(function() {
......@@ -78,7 +78,7 @@ aristocrat.removeClass(document.body, 'king');
var re = getRegExp(className);
while (re.test(el.className)) { // in case multiple occurrences
el.className = el.className.replace(re, ' ');
}
}
};
/**
......
This diff is collapsed.
ul.completed li.incompleted,
ul.incompleted li.completed {
display: none;
}
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;
}
This diff is collapsed.
<!DOCTYPE html>
<html>
<head>
<title>To-do App</title>
<meta charset="utf-8">
<title>Maria • TodoMVC</title>
<link href="css/todos.css" rel="stylesheet" type="text/css">
<link href="css/base.css" rel="stylesheet">
<link href="css/app.css" rel="stylesheet">
</head>
<body>
......@@ -17,22 +19,15 @@
<script src="../lib/maria/maria.js"></script>
<script src="../lib/aristocrat/aristocrat.js"></script>
<script src="../lib/director/director.js"></script>
<script src="js/namespace.js"></script>
<script src="js/util.js"></script>
<script src="js/models/TodoModel.js"></script>
<script src="js/models/TodosModel.js"></script>
<script src="js/templates/TodosInputTemplate.js"></script>
<script src="js/views/TodosInputView.js"></script>
<script src="js/templates/TodosListTemplate.js"></script>
<script src="js/views/TodosListView.js"></script>
<script src="js/templates/TodosToolbarTemplate.js"></script>
<script src="js/views/TodosToolbarView.js"></script>
<script src="js/controllers/TodosToolbarController.js"></script>
<script src="js/templates/TodosStatsTemplate.js"></script>
<script src="js/views/TodosStatsView.js"></script>
<script src="js/templates/TodosAppTemplate.js"></script>
<script src="js/views/TodosAppView.js"></script>
<script src="js/controllers/TodosInputController.js"></script>
<script src="js/templates/TodosTemplate.js"></script>
<script src="js/views/TodosView.js"></script>
<script src="js/controllers/TodosController.js"></script>
<script src="js/templates/TodoTemplate.js"></script>
<script src="js/views/TodoView.js"></script>
<script src="js/controllers/TodoController.js"></script>
......
maria.addEventListener(window, 'load', function() {
maria.on(window, 'load', function() {
var loading = document.getElementById('loading');
loading.parentNode.removeChild(loading);
......@@ -7,7 +7,7 @@ maria.addEventListener(window, 'load', function() {
var store = localStorage.getItem('todos-maria');
model = store ? checkit.TodosModel.fromJSON(JSON.parse(store)) :
new checkit.TodosModel();
evento.addEventListener(model, 'change', function() {
maria.on(model, 'change', function() {
localStorage.setItem('todos-maria', JSON.stringify(model.toJSON()));
});
}
......@@ -15,6 +15,20 @@ maria.addEventListener(window, 'load', function() {
model = new checkit.TodosModel();
}
var routes = {
'/': function() {
model.setMode('all');
},
'/active': function() {
model.setMode('incompleted');
},
'/completed': function() {
model.setMode('completed');
}
};
var router = Router(routes);
router.init();
var view = new checkit.TodosAppView(model);
document.body.appendChild(view.build());
});
maria.Controller.subclass(checkit, 'TodoController', {
properties: {
onMouseoverRoot: function() {
this.getView().showHoverState();
},
onMouseoutRoot: function() {
this.getView().hideHoverState();
},
onClickCheck: function() {
this.getModel().toggleDone();
},
onClickDestroy: function() {
this.getModel().destroy();
},
onDblclickDisplay: function() {
this.getView().showEdit();
onClickToggle: function() {
this.getModel().toggleCompleted();
},
onKeyupInput: function() {
var view = this.getView();
if (/\S/.test(view.getInputValue())) {
view.showToolTip();
} else {
view.hideToolTip();
}
onDblclickLabel: function() {
this.getView().showEdit();
},
onKeypressInput: function(evt) {
if (evt.keyCode === 13) {
this.onBlurInput();
onKeyupEdit: function(evt) {
if (checkit.isEnterKeyCode(evt.keyCode)) {
this.onBlurEdit();
}
},
onBlurInput: function() {
onBlurEdit: function() {
var model = this.getModel();
var view = this.getView();
var value = view.getInputValue();
view.hideToolTip();
view.showDisplay();
if (!/^\s*$/.test(value)) {
this.getModel().setContent(value);
if (checkit.isBlank(value)) {
model.destroy();
}
else {
model.setTitle(value);
}
}
}
......
maria.Controller.subclass(checkit, 'TodosAppController', {
properties: {
onKeyupNewTodo: function(evt) {
if (checkit.isEnterKeyCode(evt.keyCode)) {
var view = this.getView();
var value = view.getInputValue();
if (!checkit.isBlank(value)) {
var todo = new checkit.TodoModel();
todo.setTitle(value);
this.getModel().add(todo);
view.clearInput();
}
}
},
onClickToggleAll: function() {
var model = this.getModel();
if (model.isAllCompleted()) {
model.markAllIncompleted();
}
else {
model.markAllCompleted();
}
},
onClickClearCompleted: function() {
this.getModel().deleteCompleted();
}
}
});
maria.Controller.subclass(checkit, 'TodosInputController', {
properties: {
onFocusInput: function() {
this.onKeyupInput();
},
onBlurInput: function() {
this.getView().hideToolTip();
},
onKeyupInput: function() {
var view = this.getView();
if (/\S/.test(view.getInputValue())) {
view.showToolTip();
} else {
view.hideToolTip();
}
},
onKeypressInput: function(evt) {
if (evt.keyCode != 13) {
return;
}
var view = this.getView();
var value = view.getInputValue();
if (/^\s*$/.test(value)) { // don't create an empty Todo
return;
}
var todo = new checkit.TodoModel();
todo.setContent(value);
this.getModel().add(todo);
view.clearInput();
}
}
});
maria.Controller.subclass(checkit, 'TodosToolbarController', {
properties: {
onClickAllCheckbox: function() {
var model = this.getModel();
if (model.isAllDone()) {
model.markAllUndone();
} else {
model.markAllDone();
}
},
onClickMarkAllDone: function() {
this.getModel().markAllDone();
},
onClickMarkAllUndone: function() {
this.getModel().markAllUndone();
},
onClickDeleteDone: function() {
this.getModel().deleteDone();
}
}
});
maria.Model.subclass(checkit, 'TodoModel', {
properties: {
_content: '',
_isDone: false,
getContent: function() {
return this._content;
_title: '',
_completed: false,
getTitle: function() {
return this._title;
},
setContent: function(content) {
content = ('' + content).replace(/^\s+|\s+$/g, '');
if (this._content !== content) {
this._content = content;
setTitle: function(title) {
title = checkit.trim('' + title);
if (this._title !== title) {
this._title = title;
this.dispatchEvent({type: 'change'});
}
},
isDone: function() {
return this._isDone;
isCompleted: function() {
return this._completed;
},
setDone: function(isDone) {
isDone = !!isDone;
if (this._isDone !== isDone) {
this._isDone = isDone;
setCompleted: function(completed) {
completed = !!completed;
if (this._completed !== completed) {
this._completed = completed;
this.dispatchEvent({type: 'change'});
}
},
toggleDone: function() {
this.setDone(!this.isDone());
toggleCompleted: function() {
this.setCompleted(!this.isCompleted());
},
toJSON: function() {
return {
content: this._content,
is_done: this._isDone
title: this._title,
completed: this._completed
};
}
}
......@@ -36,7 +36,7 @@ maria.Model.subclass(checkit, 'TodoModel', {
checkit.TodoModel.fromJSON = function(todoJSON) {
var model = new checkit.TodoModel();
model._content = todoJSON.content;
model._isDone = todoJSON.is_done;
model._title = todoJSON.title;
model._completed = todoJSON.completed;
return model;
};
maria.SetModel.subclass(checkit, 'TodosModel', {
properties: {
isEmpty: function() {
return this.length === 0;
_mode: 'all',
getPossibleModes: function() {
return ['all', 'incompleted', 'completed'];
},
getDone: function() {
getMode: function() {
return this._mode;
},
setMode: function(mode) {
if (this.getPossibleModes().some(function(m) {return m === mode;})) {
if (this._mode !== mode) {
this._mode = mode;
this.dispatchEvent({type: 'change'});
}
}
else {
throw new Error('checkit.TodosModel.prototype.setMode: unsupported mode "'+mode+'".');
}
},
getCompleted: function() {
return this.filter(function(todo) {
return todo.isDone();
return todo.isCompleted();
});
},
getUndone: function() {
getIncompleted: function() {
return this.filter(function(todo) {
return !todo.isDone();
return !todo.isCompleted();
});
},
isAllDone: function() {
return this.length > 0 &&
(this.getDone().length === this.length);
isAllCompleted: function() {
return (this.length > 0) &&
(this.getCompleted().length === this.length);
},
markAllDone: function() {
markAllCompleted: function() {
this.forEach(function(todo) {
todo.setDone(true);
todo.setCompleted(true);
});
},
markAllUndone: function() {
markAllIncompleted: function() {
this.forEach(function(todo) {
todo.setDone(false);
todo.setCompleted(false);
});
},
deleteDone: function() {
this['delete'].apply(this, this.getDone());
deleteCompleted: function() {
this['delete'].apply(this, this.getCompleted());
},
toJSON: function() {
return this.map(function(todo) {
......
......@@ -7,14 +7,11 @@
// included here.
//
checkit.TodoTemplate =
'<li class="todo">' +
'<div class="display">' +
'<input class="check" type="checkbox">' +
'<span class="todo-content"></span>' +
'<span class="todo-destroy">delete</span>' +
'</div>' +
'<div class="edit">' +
'<input class="todo-input" type="text">' +
'<span class="ui-tooltip-top" style="display:none;">Press enter to update this task.</span>' +
'<li>' +
'<div class="view">' +
'<input class="toggle" type="checkbox">' +
'<label></label>' +
'<button class="destroy"></span>' +
'</div>' +
'<input class="edit">' +
'</li>';
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit.TodosAppTemplate =
'<div class="todos-app">' +
'<h1>Todos</h1>' +
'<div class="content"></div>' +
'<p class="copyright">Another fine widget from AlphaBeta.</p>' +
'</div>';
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit.TodosInputTemplate =
'<div class="create-todo">' +
'<input class="new-todo" placeholder="What needs to be done?" type="text">' +
'<span class="ui-tooltip-top" style="display:none;">Press enter to add this task.</span>' +
'</div>';
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit.TodosListTemplate =
'<ul class="todos-list"></ul>';
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit.TodosStatsTemplate =
'<div class="todos-stats"><strong class="todos-count"></strong> todos in list</div>';
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit.TodosAppTemplate =
'<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 completed</label>' +
'<ul id="todo-list"></ul>' +
'</section>' +
'<footer id="footer">' +
'<span id="todo-count"></span>' +
'<ul id="filters">' +
'<li>' +
'<a class="all-filter" href="#/">All</a>' +
'</li>' +
'<li>' +
'<a class="incompleted-filter" href="#/active">Active</a>' +
'</li>' +
'<li>' +
'<a class="completed-filter" href="#/completed">Completed</a>' +
'</li>' +
'</ul>' +
'<button id="clear-completed"></button>' +
'</footer>' +
'</section>' +
'<footer id="info">' +
'<p>Double-click to edit a todo</p>' +
'<p>Inspired by the official <a href="https://github.com/maccman/spine.todos">Spine.Todos</a></p>' +
'<p>Created by <a href="http://github.com/petermichaux">Peter Michaux</a></p>' +
'</footer>';
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit.TodosToolbarTemplate =
'<ul class="todos-toolbar">' +
'<li><input type="checkbox" class="allCheckbox"></li> ' +
'<li class="markallDone">mark all as complete</li> ' +
'<li class="markallUndone">mark all as incomplete</li> ' +
'<li class="deleteComplete">delete complete</li>' +
'</ul>';
checkit.trim = function(str) {
return str.replace(/^\s+|\s+$/g, '');
};
checkit.isBlank = function(str) {
return /^\s*$/.test(str);
};
checkit.escapeHTML = function(str) {
return str.replace('&', '&amp;').replace('<', '&lt;');
};
checkit.isEnterKeyCode = function(keyCode) {
return keyCode === 13;
};
maria.ElementView.subclass(checkit, 'TodoView', {
uiActions: {
'mouseover .todo' : 'onMouseoverRoot' ,
'mouseout .todo' : 'onMouseoutRoot' ,
'click .check' : 'onClickCheck' ,
'click .todo-destroy': 'onClickDestroy' ,
'dblclick .todo-content': 'onDblclickDisplay',
'keyup .todo-input' : 'onKeyupInput' ,
'keypress .todo-input' : 'onKeypressInput' ,
'blur .todo-input' : 'onBlurInput'
'click .destroy': 'onClickDestroy' ,
'click .toggle' : 'onClickToggle' ,
'dblclick label' : 'onDblclickLabel',
'keyup .edit' : 'onKeyupEdit' ,
'blur .edit' : 'onBlurEdit'
},
properties: {
buildData: function() {
var model = this.getModel();
var content = model.getContent();
this.find('.todo-content').innerHTML =
content.replace('&', '&amp;').replace('<', '&lt;');
this.find('.check').checked = model.isDone();
aristocrat[model.isDone() ? 'addClass' : 'removeClass'](this.find('.todo'), 'done');
var item = this.find('li');
aristocrat.removeClass(item, '(in|)completed');
aristocrat.addClass(item, (model.isCompleted() ? 'completed' : 'incompleted'));
this.find('label').innerHTML = checkit.escapeHTML(model.getTitle());
this.find('.toggle').checked = model.isCompleted();
},
update: function() {
this.buildData();
},
showEdit: function() {
var input = this.find('.todo-input');
input.value = this.getModel().getContent();
aristocrat.addClass(this.find('.todo'), 'editing');
input.focus();
var input = this.find('.edit');
input.value = this.getModel().getTitle();
aristocrat.addClass(this.find('li'), 'editing');
input.select();
},
showDisplay: function() {
aristocrat.removeClass(this.find('.todo'), 'editing');
aristocrat.removeClass(this.find('li'), 'editing');
},
getInputValue: function() {
return this.find('.todo-input').value;
},
showHoverState: function() {
aristocrat.addClass(this.find('.todo'), 'todo-hover');
},
hideHoverState: function() {
aristocrat.removeClass(this.find('.todo'), 'todo-hover');
},
showToolTip: function() {
this.find('.ui-tooltip-top').style.display = 'block';
},
hideToolTip: function() {
this.find('.ui-tooltip-top').style.display = 'none';
return this.find('.edit').value;
}
}
});
// All the subviews of a TodosAppView will always have
// the same model as the TodosAppView has.
//
maria.ElementView.subclass(checkit, 'TodosAppView', {
properties: {
getContainerEl: function() {
return this.find('.content'); // child views will be appended to this element
},
initialize: function() {
this.appendChild(new checkit.TodosInputView());
this.appendChild(new checkit.TodosToolbarView());
this.appendChild(new checkit.TodosListView());
this.appendChild(new checkit.TodosStatsView());
},
insertBefore: function(newChild, oldChild) {
newChild.setModel(this.getModel());
maria.ElementView.prototype.insertBefore.call(this, newChild, oldChild);
},
setModel: function(model) {
if (model !== this.getModel()) {
maria.ElementView.prototype.setModel.call(this, model);
var childViews = this.childNodes;
for (var i = 0, ilen = childViews.length; i < ilen; i++) {
childViews[i].setModel(model);
}
}
}
}
});
maria.ElementView.subclass(checkit, 'TodosInputView', {
uiActions: {
'focus .new-todo': 'onFocusInput' ,
'blur .new-todo': 'onBlurInput' ,
'keyup .new-todo': 'onKeyupInput' ,
'keypress .new-todo': 'onKeypressInput'
},
properties: {
getInputValue: function() {
return this.find('.new-todo').value;
},
clearInput: function() {
this.find('.new-todo').value = '';
},
showToolTip: function() {
this.find('.ui-tooltip-top').style.display = 'block';
},
hideToolTip: function() {
this.find('.ui-tooltip-top').style.display = 'none';
}
}
});
maria.SetView.subclass(checkit, 'TodosListView', {
properties: {
createChildView: function(todoModel) {
return new checkit.TodoView(todoModel);
}
}
});
maria.ElementView.subclass(checkit, 'TodosStatsView', {
properties: {
buildData: function() {
this.find('.todos-count').innerHTML = this.getModel().length;
},
update: function() {
this.buildData();
}
}
});
maria.ElementView.subclass(checkit, 'TodosToolbarView', {
uiActions: {
'click .allCheckbox' : 'onClickAllCheckbox' ,
'click .markallDone' : 'onClickMarkAllDone' ,
'click .markallUndone' : 'onClickMarkAllUndone',
'click .deleteComplete': 'onClickDeleteDone'
},
properties: {
buildData: function() {
var model = this.getModel();
var checkbox = this.find('.allCheckbox');
checkbox.checked = model.isAllDone();
checkbox.disabled = model.isEmpty();
},
update: function() {
this.buildData();
}
}
});
maria.SetView.subclass(checkit, 'TodosAppView', {
uiActions: {
'keyup #new-todo' : 'onKeyupNewTodo' ,
'click #toggle-all' : 'onClickToggleAll' ,
'click #clear-completed': 'onClickClearCompleted'
},
properties: {
buildData: function() {
var model = this.getModel();
var checkbox = this.find('#toggle-all');
checkbox.checked = model.isAllCompleted();
checkbox.disabled = model.isEmpty();
var todoList = this.find('#todo-list');
model.getPossibleModes().forEach(function(mode) {
aristocrat.removeClass(todoList, mode);
});
aristocrat.addClass(todoList, model.getMode());
var incompletedLength = model.getIncompleted().length;
this.find('#todo-count').innerHTML =
'<b>' + incompletedLength + '</b> ' +
((incompletedLength === 1) ? 'item' : 'items') +
' left';
var selected = this.find('.selected');
if (selected) {
aristocrat.removeClass(selected, 'selected');
}
aristocrat.addClass(this.find('.' + model.getMode() + '-filter'), 'selected');
var completedLength = model.getCompleted().length;
var clearButton = this.find('#clear-completed');
clearButton.style.display = (completedLength > 0) ? '' : 'none';
clearButton.innerHTML = 'Clear completed (' + completedLength + ')';
},
update: function(evt) {
maria.SetView.prototype.update.call(this, evt);
this.buildData();
},
getContainerEl: function() {
// child views will be appended to this element
return this.find('#todo-list');
},
createChildView: function(todoModel) {
return new checkit.TodoView(todoModel);
},
getInputValue: function() {
return this.find('#new-todo').value;
},
clearInput: function() {
this.find('#new-todo').value = '';
}
}
});
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