Commit 02166867 authored by Sindre Sorhus's avatar Sindre Sorhus

Remove duplicated old app

parent 1b892ae2
body {
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
padding: 60px 50px;
}
#mocha h1, h2 {
margin: 0;
}
#mocha h1 {
font-size: 1em;
font-weight: 200;
}
#mocha .suite .suite h1 {
font-size: .8em;
}
#mocha h2 {
font-size: 12px;
font-weight: normal;
cursor: pointer;
}
#mocha .suite {
margin-left: 15px;
}
#mocha .test {
margin-left: 15px;
}
#mocha .test:hover h2::after {
position: relative;
top: 0;
right: -10px;
content: '(view source)';
font-size: 12px;
font-family: arial;
color: #888;
}
#mocha .test.pending:hover h2::after {
content: '(pending)';
font-family: arial;
}
#mocha .test.pass::before {
content: '✓';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #00c41c;
}
#mocha .test.pending {
color: #0b97c4;
}
#mocha .test.pending::before {
content: '◦';
color: #0b97c4;
}
#mocha .test.fail {
color: #c00;
}
#mocha .test.fail pre {
color: black;
}
#mocha .test.fail::before {
content: '✖';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #c00;
}
#mocha .test pre.error {
color: #c00;
}
#mocha .test pre {
display: inline-block;
font: 12px/1.5 monaco, monospace;
margin: 5px;
padding: 15px;
border: 1px solid #eee;
border-bottom-color: #ddd;
-webkit-border-radius: 3px;
-webkit-box-shadow: 0 1px 3px #eee;
}
#error {
color: #c00;
font-size: 1.5 em;
font-weight: 100;
letter-spacing: 1px;
}
#stats {
position: fixed;
top: 15px;
right: 10px;
font-size: 12px;
margin: 0;
color: #888;
}
#stats .progress {
float: right;
padding-top: 0;
}
#stats em {
color: black;
}
#stats li {
display: inline-block;
margin: 0 5px;
list-style: none;
padding-top: 11px;
}
code .comment { color: #ddd }
code .init { color: #2F6FAD }
code .string { color: #5890AD }
code .keyword { color: #8A6343 }
code .number { color: #2F6FAD }
/* ==== Scroll down to find where to put your styles :) ==== */
/* HTML5 ✰ Boilerplate */
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
blockquote, q { quotes: none; }
blockquote:before, blockquote:after,
q:before, q:after { content: ''; content: none; }
ins { background-color: #ff9; color: #000; text-decoration: none; }
mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
del { text-decoration: line-through; }
abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
table { border-collapse: collapse; border-spacing: 0; }
hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
input, select { vertical-align: middle; }
body { font:13px/1.231 sans-serif; *font-size:small; }
select, input, textarea, button { font:99% sans-serif; }
pre, code, kbd, samp { font-family: monospace, sans-serif; }
html { overflow-y: scroll; }
a:hover, a:active { outline: none; }
ul, ol { margin-left: 2em; }
ol { list-style-type: decimal; }
nav ul, nav li { margin: 0; list-style:none; list-style-image: none; }
small { font-size: 85%; }
strong, th { font-weight: bold; }
td { vertical-align: top; }
sub, sup { font-size: 75%; line-height: 0; position: relative; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; padding: 15px; }
textarea { overflow: auto; }
.ie6 legend, .ie7 legend { margin-left: -7px; }
input[type="radio"] { vertical-align: text-bottom; }
input[type="checkbox"] { margin-right: 5px;
vertical-align: middle; }
.ie7 input[type="checkbox"] { vertical-align: baseline; }
.ie6 input { vertical-align: text-bottom; }
label, input[type="button"], input[type="submit"], input[type="image"], button { cursor: pointer; }
button, input, select, textarea { margin: 0; }
input:valid, textarea:valid { }
input:invalid, textarea:invalid { border-radius: 1px; -moz-box-shadow: 0px 0px 5px red; -webkit-box-shadow: 0px 0px 5px red; box-shadow: 0px 0px 5px red; }
.no-boxshadow input:invalid, .no-boxshadow textarea:invalid { background-color: #f0dddd; }
::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; }
::selection { background:#FF5E99; color:#fff; text-shadow: none; }
a:link { -webkit-tap-highlight-color: #FF5E99; }
button { width: auto; overflow: visible; }
.ie7 img { -ms-interpolation-mode: bicubic; }
body, select, input, textarea { color: #444; }
h1, h2, h3, h4, h5, h6 { font-weight: bold; }
a, a:active, a:visited { color: #607890; }
a:hover { color: #036; }
/*
// ========================================== \\
|| ||
|| Your styles ! ||
|| ||
\\ ========================================== //
*/
.ir { display: block; text-indent: -999em; overflow: hidden; background-repeat: no-repeat; text-align: left; direction: ltr; }
.hidden { display: none; visibility: hidden; }
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
.invisible { visibility: hidden; }
.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; }
.clearfix:after { clear: both; }
.clearfix { zoom: 1; }
@media all and (orientation:portrait) {
}
@media all and (orientation:landscape) {
}
@media screen and (max-device-width: 480px) {
/* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */
}
@media print {
* { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important;
-ms-filter: none !important; }
a, a:visited { color: #444 !important; text-decoration: underline; }
a[href]:after { content: " (" attr(href) ")"; }
abbr[title]:after { content: " (" attr(title) ")"; }
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
thead { display: table-header-group; }
tr, img { page-break-inside: avoid; }
@page { margin: 0.5cm; }
p, h2, h3 { orphans: 3; widows: 3; }
h2, h3{ page-break-after: avoid; }
}
\ No newline at end of file
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline; }
body {
line-height: 1; }
ol, ul {
list-style: none; }
table {
border-collapse: collapse;
border-spacing: 0; }
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle; }
q, blockquote {
quotes: none; }
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none; }
a img {
border: none; }
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block; }
/* CSS Reset */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline; }
body {
line-height: 1; }
ol, ul {
list-style: none; }
table {
border-collapse: collapse;
border-spacing: 0; }
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle; }
q, blockquote {
quotes: none; }
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none; }
a img {
border: none; }
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block; }
body {
line-height: 1;
font-family: "Lucida Grande", sans-serif;
font-size: 13px; }
ol, ul {
list-style: none; }
blockquote, q {
quotes: none; }
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none; }
table {
border-collapse: collapse;
border-spacing: 0; }
/* App CSS */
body, html {
}
.sc-view {
position: relative;
overflow: visible; }
/*new additions*/
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.4em;
background: #eeeeee;
color: #333333;
}
#todoapp {
width: 480px;
margin: 0 auto 40px;
background: white;
padding: 20px;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
-moz-border-radius-bottomleft: 5px;
-webkit-border-bottom-left-radius: 5px;
-o-border-bottom-left-radius: 5px;
-ms-border-bottom-left-radius: 5px;
-khtml-border-bottom-left-radius: 5px;
border-bottom-left-radius: 5px;
-moz-border-radius-bottomright: 5px;
-webkit-border-bottom-right-radius: 5px;
-o-border-bottom-right-radius: 5px;
-ms-border-bottom-right-radius: 5px;
-khtml-border-bottom-right-radius: 5px;
border-bottom-right-radius: 5px;
}
#todoapp h1 {
font-size: 36px;
font-weight: bold;
text-align: center;
padding: 20px 0 30px 0;
line-height: 1;
}
#create-todo {
position: relative;
}
#create-todo input {
width: 466px;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
padding: 6px;
border: 1px solid #999999;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
}
#create-todo input::-webkit-input-placeholder {
font-style: italic;
}
#create-todo span {
position: absolute;
z-index: 999;
width: 170px;
left: 50%;
margin-left: -85px;
}
#todo-list {
margin-top: 10px;
}
#todo-list li {
padding: 12px 20px 11px 0;
position: relative;
font-size: 24px;
line-height: 1.1em;
border-bottom: 1px solid #cccccc;
}
#todo-list li:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
#todo-list li.editing {
padding: 0;
border-bottom: 0;
}
#todo-list .editing .display,
#todo-list .edit {
display: none;
}
#todo-list .editing .edit {
display: block;
}
#todo-list .editing input {
width: 444px;
font-size: 24px;
font-family: inherit;
margin: 0;
line-height: 1.6em;
border: 0;
outline: none;
padding: 10px 7px 0px 27px;
border: 1px solid #999999;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
}
#todo-list .check {
position: relative;
top: 9px;
margin: 0 10px 0 7px;
float: left;
}
#todo-list .is-done label {
text-decoration: line-through;
color: #777777;
}
#todo-list .todo-destroy {
position: absolute;
right: 5px;
top: 14px;
display: none;
cursor: pointer;
width: 20px;
height: 20px;
background: url(destroy.png) no-repeat 0 0;
}
#todo-list li:hover .todo-destroy {
display: block;
}
#todo-list .todo-destroy:hover {
background-position: 0 -20px;
}
#todo-stats {
*zoom: 1;
margin-top: 10px;
color: #777777;
}
#todo-stats:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
#todo-stats .todo-count {
float: left;
}
#todo-stats .todo-count .number {
font-weight: bold;
color: #333333;
}
#todo-stats .todo-clear {
float: right;
}
#todo-stats .todo-clear a {
color: #777777;
font-size: 12px;
}
#todo-stats .todo-clear a:visited {
color: #777777;
}
#todo-stats .todo-clear a:hover {
color: 336699;
}
#instructions {
width: 520px;
margin: 10px auto;
color: #777777;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
}
#instructions a {
color: #336699;
}
#credits {
width: 520px;
margin: 30px auto;
color: #999;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
}
#credits a {
color: #888;
}
/* line 109 */
#todoapp #todo-stats {
*zoom: 1;
margin-top: 10px;
color: #555555;
-moz-border-radius-bottomleft: 5px;
-webkit-border-bottom-left-radius: 5px;
-o-border-bottom-left-radius: 5px;
-ms-border-bottom-left-radius: 5px;
-khtml-border-bottom-left-radius: 5px;
border-bottom-left-radius: 5px;
-moz-border-radius-bottomright: 5px;
-webkit-border-bottom-right-radius: 5px;
-o-border-bottom-right-radius: 5px;
-ms-border-bottom-right-radius: 5px;
-khtml-border-bottom-right-radius: 5px;
border-bottom-right-radius: 5px;
background: #f4fce8;
border-top: 1px solid #ededed;
padding: 0 20px;
line-height: 36px;
}
/* line 22, /opt/ree/lib/ruby/gems/1.8/gems/compass-0.10.5/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
#todoapp #todo-stats:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
/* line 118 */
#todoapp #todo-stats .todo-count {
float: left;
}
/* line 120 */
#todoapp #todo-stats .todo-count .number {
font-weight: bold;
color: #555555;
}
/* line 123 */
#todoapp #todo-stats .todo-clear {
float: right;
}
/* line 125 */
#todoapp #todo-stats button {
display: block;
line-height: 20px;
text-decoration: none;
-moz-border-radius: 12px;
-webkit-border-radius: 12px;
-o-border-radius: 12px;
-ms-border-radius: 12px;
-khtml-border-radius: 12px;
border-radius: 12px;
background: rgba(0, 0, 0, 0.1);
color: #555555;
font-size: 11px;
margin-top: 8px;
padding: 0 10px 1px;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
float:right;
border:0px;
}
/* line 136 */
#todoapp #todo-stats button:hover, #todoapp #todo-stats button:focus {
background: rgba(0, 0, 0, 0.15);
-moz-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
-webkit-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
-o-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
}
#todos { display:block}
@import "compass/css3";
@import "compass/reset";
/* CSS Reset */
@include global-reset;
body {
line-height: 1;
font-family: "Lucida Grande", sans-serif;
font-size: 13px;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* App CSS */
body, html {
color: #777;
background-color: #F2F4F5;
}
.sc-view {
position: relative;
overflow: visible;
}
$width: 600px;
$border: 1px solid #bbb;
body {
@include box-shadow(rgba(0,0,0,0.6) 0 0 1px);
@include border-radius(8px);
$padding: 10px;
$header-height: 20px;
position: absolute;
width: $width;
left: 50%;
margin-top: 38px;
border: $border;
margin-left: -300px;
background-color: #fff;
padding: ($header-height + $padding * 2) $padding $padding;
.mark-all-done label {
margin-left: 5px;
font-weight: bold;
}
#stats {
overflow: hidden;
width: 100%;
padding: 5px $padding;
margin: $padding ($padding * -1);
background-color: #eee;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
line-height: 25px;
.remaining {
float: left;
}
.sc-button {
@include background-image(linear-gradient(#F9F9F9 1%, #DDD, #F2F2F2, #F7F7F7));
border: 1px solid #828282;
color: #000;
float: right;
padding: 5px;
&:hover {
@include background-image(linear-gradient(#FFF 1%, #E2E2E2, #F7F7F7, #FCFCFC));
}
&.is-active {
@include background-image(linear-gradient(#EFEFEF 1%, #D3D3D3, #E8E8E8, #EDEDED));
}
}
}
input[type='text'] {
@include border-radius(5px);
@include single-box-shadow(rgba(0,0,0,0.6), 0, 0, 10px, -2px);
color: #999;
background-color: rgb(240,240,240);
width: $width - ($padding) - 2px;
font-size: 30px;
font-family: Helvetica, sans-serif;
padding: 5px;
border: $border;
font-weight: 500;
&::-webkit-input-placeholder {
color: #aaa;
}
}
h1 {
@include border-top-radius(8px);
@include background-image(linear-gradient(color-stops(white, rgb(244,244,244) 49%, rgb(237,237,237) 51%, #dedede)));
@include single-text-shadow(white, 0, 1px, 1px);
font-size: 15px;
position: absolute;
width: $width;
height: $header-height;
color: rgb(83,86,94);
top: 0;
left: 0;
padding: ($padding / 2) $padding;
border-bottom: $border;
}
.sc-checkbox {
input[type="checkbox"] {
margin-right: 7px;
}
}
ul {
margin: 10px 0 2px 0;
li {
padding: 5px;
&.is-done {
color: #B7B7B7;
text-decoration: line-through;
}
}
li:nth-child(odd) {
background-color: #F7F7F7;
}
}
}
<!doctype html>
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
<!--[if IE 7 ]> <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]> <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]> <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"> <!--<![endif]-->
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>ember.js + require.js</title>
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="/favicon.ico">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="css/style.css?v=2">
<link rel="stylesheet" href="css/todos.css">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script data-main="js/app.js" src="js/libs/require/require.js"></script>
</head>
<body>
<div id="todoapp">
<div class="title"><h1>Todos</h1></div>
<div class="content">
<div id="create-todo"></div>
<div id="stats-area"></div>
<div id="todos"></div>
</div>
</div>
<div id="credits">
Credits:
<p>Tom Dale, Addy Osmani, Стас Сушков</p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</div>
</body>
</html>
// Define libraries
require.config({
baseUrl: 'js/',
paths: {
jquery: 'libs/jquery-1.7.1.min',
ember: 'libs/ember-0.9.min',
text: 'libs/require/text'
}
});
// Load our app
define('app', [
'jquery',
'app/models/store',
'app/controllers/main',
'ember',
], function($, Store, Main) {
var App = Ember.Application.create({
VERSION: '0.1-omfg',
Views: Ember.Namespace.create(),
Models: Ember.Namespace.create(),
Controllers: Ember.Namespace.create(),
init: function() {
this._super();
this.Models.set('store', new Store('todos-emberjs'));
this.Controllers.set('main', Main.create());
var items = this.Models.get('store').findAll();
if (items.length > 0) {
this.Controllers.get('main').set('[]', items);
};
if (typeof(mocha) !== 'undefined') {
window.expect = chai.expect;
mocha.setup('bdd');
require([
'app/specs/models/store',
'app/specs/views/basic_acceptance',
'app/specs/controllers/main'
], function(){
mocha
.run()
.globals(['$', 'Ember', 'Todos'])
});
}
}
});
return window.Todos = App;
}
);
define('app/controllers/entries', ['ember'],
/**
* Entries controller
*
* @returns Class
*/
function() {
return Ember.ArrayProxy.extend({
storeBinding: 'Todos.Models.store',
content: [],
createNew: function(value) {
var todo = this.get('store').createFromTitle(value);
this.pushObject(todo);
var stats = document.getElementById('stats-area');
if (stats.style.display=='block')
stats.style.display = 'inline';
else
stats.style.display = 'block';
},
pushObject: function (item, ignoreStorage) {
if (!ignoreStorage)
this.get('store').create(item);
return this._super(item);
},
removeObject: function (item) {
this.get('store').remove(item);
return this._super(item);
},
clearCompleted: function() {
this.filterProperty('isDone', true).forEach(this.removeObject, this);
},
remaining: function() {
return this.filterProperty('isDone', false).get('length');
}.property('@each.isDone'),
completed: function() {
return this.filterProperty('isDone', true).get('length');
}.property('@each.isDone'),
allAreDone: function(key, value) {
if (value !== undefined) {
this.setEach('isDone', value);
return value;
} else {
return !!this.get('length') && this.everyProperty('isDone', true);
}
}.property('@each.isDone'),
});
}
);
define('app/controllers/main', [
'app/controllers/entries',
'text!app/views/clear_button.html',
'text!app/views/items.html'
],
/**
* Main controller
*
* Main controller inherits the `Entries` class
* which is an `ArrayProxy` linked with the `Store` model
*
* @param Class Entries, the Entries class
* @param String button_html, the html view for the clearCompletedButton
* @param String items_html, the html view for the `Todos` items
* @returns Class
*/
function(Entries, button_html, items_html) {
return Entries.extend({
// New todo input
inputView: Ember.TextField.create({
placeholder: 'What needs to be done?',
elementId: 'new-todo',
storageBinding: 'Todos.Controllers.main',
// Bind this to newly inserted line
insertNewline: function() {
var value = this.get('value');
if (value) {
this.get('storage').createNew(value);
this.set('value', '');
}
}
}),
// Stats label
statsView: Ember.View.create({
elementId: 'todo-stats',
contentBinding: 'Todos.Controllers.main',
remainingBinding: 'Todos.Controllers.main.remaining',
remainingString: function() {
var remaining = this.get('remaining');
return remaining + (remaining === 1 ? " item" : " items");
}.property('remaining'),
template: Ember.Handlebars.compile('{{remainingString}} left')
}),
// Clear completed tasks button
clearCompletedButton: Ember.Button.create({
template: Ember.Handlebars.compile(button_html),
target: 'Todos.Controllers.main',
action: 'clearCompleted',
completedBinding: 'Todos.Controllers.main.completed',
classNameBindings: 'buttonClass',
// Observer to update content if completed value changes
buttonString: function() {
var completed = this.get('completed');
return completed + " completed" + (completed === 1 ? " item" : " items");
}.property('completed'),
// Observer to update class if completed value changes
buttonClass: function () {
if (this.get('completed') < 1)
return 'hidden';
else
return '';
}.property('completed')
}),
// Checkbox to mark all todos done.
allDoneCheckbox: Ember.Checkbox.create({
classNames: ['mark-all-done'],
title: "Mark all as complete",
valueBinding: 'Todos.Controllers.main.allAreDone'
}),
// Compile and render the todos view
todosView: Ember.View.create({
template: Ember.Handlebars.compile(items_html)
}),
// Activates the views and other initializations
init: function() {
this._super();
this.get('inputView').appendTo('#create-todo');
this.get('allDoneCheckbox').appendTo('#stats-area');
this.get('todosView').appendTo('#todos');
this.get('statsView').appendTo('#todoapp .content');
this.get('clearCompletedButton').appendTo('#todo-stats');
}
});
}
);
define('app/models/store', [
'app/models/todo',
'ember'
],
/**
* Todo entries storage model
*
* @param Class Todo, the todo entry model
* @returns Class
*/
function(Todo){
// Our Store is represented by a single JS object in *localStorage*.
// Create it with a meaningful name, like the name you'd give a table.
return function(name) {
this.name = name;
var store = localStorage.getItem(this.name);
this.data = (store && JSON.parse(store)) || {};
// Save the current state of the **Store** to *localStorage*.
this.save = function() {
localStorage.setItem(this.name, JSON.stringify(this.data));
};
// Wrapper around `this.create`
// Creates a `Todo` model object out of the title
this.createFromTitle = function(title) {
var todo = Todo.create({title: title});
this.create(todo);
return todo;
};
// Store the model inside the `Store`
this.create = function (model) {
if (!model.get('id')) model.set('id', Date.now());
return this.update(model);
};
// Update a model by replacing its copy in `this.data`.
this.update = function(model) {
this.data[model.get('id')] = model.getProperties('id', 'title', 'isDone');
this.save();
return model;
};
// Retrieve a model from `this.data` by id.
this.find = function(model) {
return Todo.create(this.data[model.get('id')]);
};
// Return the array of all models currently in storage.
this.findAll = function() {
var result = [];
for (var key in this.data) {
var todo = Todo.create(this.data[key]);
result.push(todo);
}
return result;
};
// Delete a model from `this.data`, returning it.
this.remove = function(model) {
delete this.data[model.get('id')];
this.save();
return model;
};
};
}
);
define('app/models/todo', ['ember'],
/**
* Todo entry model
*
* @returns Class
*/
function(){
return Ember.Object.extend({
id: null,
title: null,
isDone: false,
// Observer that will react on item change and will update the storage
todoChanged: function() {
Todos.Models.get('store').update(this);
}.observes('title', 'isDone')
});
}
);
/**
* Some smoke tests
*/
describe('Todos.Controllers.main', function(){
var controller = Todos.Controllers.get('main');
var title = "Another title...";
it('should have a view for entering new entry', function(){
expect(controller.inputView).to.be.a('object');
expect(
$(controller.inputView.get('element')).attr('placeholder')
).to.equal(controller.inputView.get('placeholder'));
});
it('should create new entry on newline', function(){
controller.inputView.set('value', title);
controller.inputView.insertNewline();
expect(controller.get('lastObject').title).to.equal(title);
controller.removeObject(controller.get('lastObject'));
});
it('should reflect the same number of items as in store', function(){
controller.inputView.set('value', title);
controller.inputView.insertNewline();
var visibles = controller.todosView.get('childViews')[0].get('childViews').length;
expect(controller.get('content').length).to.equal(visibles);
controller.removeObject(controller.get('lastObject'));
});
it('should allow removing entries', function(done){
controller.inputView.set('value', title);
controller.inputView.insertNewline();
setTimeout(function(){
controller.allDoneCheckbox.set('value', true);
}, 100);
setTimeout(function(){
controller.clearCompletedButton.triggerAction();
}, 200);
setTimeout(function(){
expect(controller.get('content').length).to.equal(0);
}, 300);
done();
});
});
/**
* Some integration tests
*/
describe('Todos.Models.store', function(){
var title = 'Testing title...';
var store = Todos.Models.get('store');
it('should allow creating and removing items', function(){
var count = store.findAll().length;
var todo = Todos.Models.get('store').createFromTitle(title);
expect(store.findAll().length).to.equal(count + 1);
expect(todo).to.have.property('title', title);
expect(todo).to.have.property('isDone', false);
store.remove(todo);
expect(store.findAll().length).to.equal(count);
});
it('should allow finding and changing items', function(){
var todo = store.createFromTitle(title);
expect(store.find(todo).id).to.equal(todo.id);
expect(store.find(todo).title).to.equal(todo.title);
expect(store.find(todo).isDone).to.equal(false);
todo.set('isDone', true);
expect(store.find(todo).id).to.equal(todo.id);
expect(store.find(todo).isDone).to.equal(true);
Todos.Models.get('store').remove(todo);
});
});
/**
* Some acceptance testing for views
*/
describe('Todos Views', function(){
it('should validate clear button view', function(done){
require(['text!app/views/clear_button.html'], function(html){
expect(html).to.be.a('string');
expect(html).to.match(/buttonString/);
expect(Em.Handlebars.compile(html)).to.not.throw(Error);
done();
});
});
it('should validate items view', function(done){
require(['text!app/views/items.html'], function(html){
expect(html).to.be.a('string');
expect(html).to.match(/collection/);
expect(html).to.match(/Todos\.Controllers\.main/);
expect(html).to.match(/Checkbox/);
expect(Em.Handlebars.compile(html)).to.not.throw(Error);
done();
});
});
});
{{#collection id="todo-list" contentBinding="Todos.Controllers.main" tagName="ul" itemClassBinding="content.isDone"}}
{{view Ember.Checkbox titleBinding="content.title" valueBinding="content.isDone"}}
{{/collection}}
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
RequireJS text 0.27.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
Available via the MIT or new BSD license.
see: http://github.com/jrburke/requirejs for details
*/
(function(){var k=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],n=/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,o=/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,i=typeof location!=="undefined"&&location.href,p=i&&location.protocol&&location.protocol.replace(/\:/,""),q=i&&location.hostname,r=i&&(location.port||void 0),j=[];define(function(){var g,h,l;typeof window!=="undefined"&&window.navigator&&window.document?h=function(a,b){var c=g.createXhr();c.open("GET",a,!0);c.onreadystatechange=
function(){c.readyState===4&&b(c.responseText)};c.send(null)}:typeof process!=="undefined"&&process.versions&&process.versions.node?(l=require.nodeRequire("fs"),h=function(a,b){b(l.readFileSync(a,"utf8"))}):typeof Packages!=="undefined"&&(h=function(a,b){var c=new java.io.File(a),e=java.lang.System.getProperty("line.separator"),c=new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(c),"utf-8")),d,f,g="";try{d=new java.lang.StringBuffer;(f=c.readLine())&&f.length()&&
f.charAt(0)===65279&&(f=f.substring(1));for(d.append(f);(f=c.readLine())!==null;)d.append(e),d.append(f);g=String(d.toString())}finally{c.close()}b(g)});return g={version:"0.27.0",strip:function(a){if(a){var a=a.replace(n,""),b=a.match(o);b&&(a=b[1])}else a="";return a},jsEscape:function(a){return a.replace(/(['\\])/g,"\\$1").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r")},createXhr:function(){var a,b,c;if(typeof XMLHttpRequest!==
"undefined")return new XMLHttpRequest;else for(b=0;b<3;b++){c=k[b];try{a=new ActiveXObject(c)}catch(e){}if(a){k=[c];break}}if(!a)throw Error("createXhr(): XMLHttpRequest not available");return a},get:h,parseName:function(a){var b=!1,c=a.indexOf("."),e=a.substring(0,c),a=a.substring(c+1,a.length),c=a.indexOf("!");c!==-1&&(b=a.substring(c+1,a.length),b=b==="strip",a=a.substring(0,c));return{moduleName:e,ext:a,strip:b}},xdRegExp:/^((\w+)\:)?\/\/([^\/\\]+)/,useXhr:function(a,b,c,e){var d=g.xdRegExp.exec(a),
f;if(!d)return!0;a=d[2];d=d[3];d=d.split(":");f=d[1];d=d[0];return(!a||a===b)&&(!d||d===c)&&(!f&&!d||f===e)},finishLoad:function(a,b,c,e,d){c=b?g.strip(c):c;d.isBuild&&d.inlineText&&(j[a]=c);e(c)},load:function(a,b,c,e){var d=g.parseName(a),f=d.moduleName+"."+d.ext,m=b.toUrl(f),h=e&&e.text&&e.text.useXhr||g.useXhr;!i||h(m,p,q,r)?g.get(m,function(b){g.finishLoad(a,d.strip,b,c,e)}):b([f],function(a){g.finishLoad(d.moduleName+"."+d.ext,d.strip,a,c,e)})},write:function(a,b,c){if(b in j){var e=g.jsEscape(j[b]);
c.asModule(a+"!"+b,"define(function () { return '"+e+"';});\n")}},writeFile:function(a,b,c,e,d){var b=g.parseName(b),f=b.moduleName+"."+b.ext,h=c.toUrl(b.moduleName+"."+b.ext)+".js";g.load(f,c,function(){var b=function(a){return e(h,a)};b.asModule=function(a,b){return e.asModule(a,h,b)};g.write(a,f,b,d)},d)}}})})();
<!doctype html>
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
<!--[if IE 7 ]> <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]> <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]> <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"> <!--<![endif]-->
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>ember.js + require.js</title>
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="/favicon.ico">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="css/style.css?v=2">
<link rel="stylesheet" href="css/todos.css">
<link rel="stylesheet" href="css/mocha.css">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script src="js/libs/mocha.js"></script>
<script src="js/libs/chai.js"></script>
<script data-main="js/app.js" src="js/libs/require/require.js"></script>
</head>
<body>
<div id="todoapp">
<div class="title"><h1>Todos</h1></div>
<div class="content">
<div id="create-todo"></div>
<div id="stats-area"></div>
<div id="todos"></div>
</div>
</div>
<div id="mocha"></div>
<div id="credits">
Credits:
<br/>
Tom Dale, Addy Osmani, Стас Сушков
</div>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment