Commit 79ef2441 authored by Addy Osmani's avatar Addy Osmani

Merge pull request #529 from stephenplusplus/troopjs

troopjs updated to use bower.
parents 71448c46 2e471183
{
"name": "todomvc-troopjs",
"version": "0.0.0",
"dependencies": {
"todomvc-common": "~0.1.4",
"requirejs": "~2.1.5",
"jquery": "<=1.8.2"
}
}
This diff is collapsed.
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
color: inherit;
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea url('bg.png');
color: #4d4d4d;
width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#todoapp {
background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
}
#todoapp input::-webkit-input-placeholder {
font-style: italic;
}
#todoapp input:-moz-placeholder {
font-style: italic;
color: #a9a9a9;
}
#todoapp h1 {
position: absolute;
top: -120px;
width: 100%;
font-size: 70px;
font-weight: bold;
text-align: center;
color: #b3b3b3;
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.02);
z-index: 2;
box-shadow: none;
}
#main {
position: relative;
z-index: 2;
border-top: 1px dotted #adadad;
}
label[for='toggle-all'] {
display: none;
}
#toggle-all {
position: absolute;
top: -42px;
left: -4px;
width: 40px;
text-align: center;
border: none; /* Mobile Safari */
}
#toggle-all:before {
content: '»';
font-size: 28px;
color: #d9d9d9;
padding: 0 25px 7px;
}
#toggle-all:checked:before {
color: #737373;
}
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px dotted #ccc;
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list li.editing {
border-bottom: none;
padding: 0;
}
#todo-list li.editing .edit {
display: block;
width: 506px;
padding: 13px 17px 12px 17px;
margin: 0 0 0 43px;
}
#todo-list li.editing .view {
display: none;
}
#todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none; /* Mobile Safari */
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
#todo-list li .toggle:after {
content: '✔';
line-height: 43px; /* 40 + a couple of pixels visual adjustment */
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
}
#todo-list li .toggle:checked:after {
color: #85ada7;
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
}
#todo-list li label {
word-break: break-word;
padding: 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
-webkit-transition: color 0.4s;
-moz-transition: color 0.4s;
-ms-transition: color 0.4s;
-o-transition: color 0.4s;
transition: color 0.4s;
}
#todo-list li.completed label {
color: #a9a9a9;
text-decoration: line-through;
}
#todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 22px;
color: #a88a8a;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
#todo-list li .destroy:hover {
text-shadow: 0 0 1px #000,
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
-moz-transform: scale(1.3);
-ms-transform: scale(1.3);
-o-transform: scale(1.3);
transform: scale(1.3);
}
#todo-list li .destroy:after {
content: '✖';
}
#todo-list li:hover .destroy {
display: block;
}
#todo-list li .edit {
display: none;
}
#todo-list li.editing:last-child {
margin-bottom: -1px;
}
#footer {
color: #777;
padding: 0 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px;
z-index: 1;
text-align: center;
}
#footer:before {
content: '';
position: absolute;
right: 0;
bottom: 31px;
left: 0;
height: 50px;
z-index: -1;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
0 6px 0 -3px rgba(255, 255, 255, 0.8),
0 7px 1px -3px rgba(0, 0, 0, 0.3),
0 43px 0 -6px rgba(255, 255, 255, 0.8),
0 44px 2px -6px rgba(0, 0, 0, 0.2);
}
#todo-count {
float: left;
text-align: left;
}
#filters {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
right: 0;
left: 0;
}
#filters li {
display: inline;
}
#filters li a {
color: #83756f;
margin: 2px;
text-decoration: none;
}
#filters li a.selected {
font-weight: bold;
}
#clear-completed {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
font-size: 11px;
padding: 0 10px;
border-radius: 3px;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
}
#clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
}
#info {
margin: 65px auto 0;
color: #a6a6a6;
font-size: 12px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
text-align: center;
}
#info a {
color: inherit;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera
*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all,
#todo-list li .toggle {
background: none;
}
#todo-list li .toggle {
height: 40px;
}
#toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
}
.hidden{
display:none;
}
(function () {
'use strict';
if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
}
function getSourcePath() {
// If accessed via addyosmani.github.io/todomvc/, strip the project path.
if (location.hostname.indexOf('github.io') > 0) {
return location.pathname.replace(/todomvc\//, '');
}
return location.pathname;
}
function appendSourceLink() {
var sourceLink = document.createElement('a');
var paragraph = document.createElement('p');
var footer = document.getElementById('info');
var urlBase = 'https://github.com/addyosmani/todomvc/tree/gh-pages';
if (footer) {
sourceLink.href = urlBase + getSourcePath();
sourceLink.appendChild(document.createTextNode('Check out the source'));
paragraph.appendChild(sourceLink);
footer.appendChild(paragraph);
}
}
function redirect() {
if (location.hostname === 'addyosmani.github.io') {
location.href = location.href.replace('addyosmani.github.io/todomvc', 'todomvc.com');
}
}
appendSourceLink();
redirect();
})();
/* base.css overrides */
#footer, #main {
display: none;
}
.filter-active .completed,
.filter-completed .active {
display: none;
......
......@@ -4,11 +4,8 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Troop.js • TodoMVC</title>
<link rel="stylesheet" href="../../../assets/base.css">
<link rel="stylesheet" href="components/todomvc-common/base.css">
<link rel="stylesheet" href="css/app.css">
<!--[if IE]>
<script src="../../../assets/ie.js"></script>
<![endif]-->
</head>
<body>
<section id="todoapp">
......@@ -22,7 +19,9 @@
<ul id="todo-list" data-weave="widget/list"></ul>
</section>
<footer id="footer" data-weave="widget/display">
<span id="todo-count" data-weave="widget/count"><strong>0</strong> items left</span>
<span id="todo-count" data-weave="widget/count">
<strong>0</strong> items left
</span>
<ul id="filters" data-weave="widget/filters">
<li>
<a href="#/">All</a>
......@@ -42,7 +41,7 @@
<p>Created by <a href="http://github.com/mikaelkaron">Mikael Karon</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script src="../../../assets/base.js"></script>
<script type="text/javascript" data-main="js/app.js" src="../../../assets/require.min.js"></script>
<script src="components/todomvc-common/base.js"></script>
<script data-main="js/app.js" src="components/requirejs/require.js"></script>
</body>
</html>
/*newcap false*/
/*jshint newcap:false*/
require({
'paths': {
'jquery': '../../../../assets/jquery.min',
'troopjs-bundle': 'lib/troopjs-bundle.min'
paths: {
jquery: '../components/jquery/jquery',
'troopjs-bundle': 'lib/troopjs-bundle'
}
}, [ 'require', 'jquery', 'troopjs-bundle' ], function Deps(parentRequire, jQuery) {
}, [
'require',
'jquery',
'troopjs-bundle'
], function Deps(parentRequire, $) {
'use strict';
// Application and plug-ins
parentRequire([
......@@ -11,10 +18,11 @@ require({
'troopjs-jquery/weave',
'troopjs-jquery/destroy',
'troopjs-jquery/hashchange',
'troopjs-jquery/action' ], function App(Application) {
'troopjs-jquery/action'
], function App(Application) {
// Hook ready
jQuery(document).ready(function ready($) {
$(document).ready(function () {
Application($(this.body), 'app/todos').start();
});
});
......
/*global define*/
define({
'store': 'todos-troopjs'
store: 'todos-troopjs'
});
This diff is collapsed.
define( [ 'troopjs-core/widget/application', 'troopjs-core/route/router', 'jquery' ], function ApplicationModule(Application, Router, $) {
/*global define*/
/*jshint newcap:false*/
define([
'troopjs-core/widget/application',
'troopjs-core/route/router',
'jquery'
], function ApplicationModule(Application, Router, $) {
'use strict';
function forward(signal, deferred) {
var services = $.map(this.services, function map(service, index) {
function Forward(signal, deferred) {
var services = $.map(this.services, function map(service) {
return $.Deferred(function deferredSignal(deferSignal) {
service.signal(signal, deferSignal);
});
......@@ -13,11 +20,11 @@ define( [ 'troopjs-core/widget/application', 'troopjs-core/route/router', 'jquer
}
return Application.extend({
'sig/initialize': forward,
'sig/finalize': forward,
'sig/start': forward,
'sif/stop': forward,
'sig/initialize': Forward,
'sig/finalize': Forward,
'sig/start': Forward,
'sif/stop': Forward,
services: [ Router($(window)) ]
services: [Router($(window))]
});
});
define( [ 'troopjs-core/component/widget', 'jquery' ], function ClearModule(Widget, $) {
/*global define*/
define([
'troopjs-core/component/widget',
'jquery'
], function ClearModule(Widget, $) {
'use strict';
function filter(item, index) {
function filter(item) {
return item === null || !item.completed;
}
......@@ -8,10 +13,10 @@ define( [ 'troopjs-core/component/widget', 'jquery' ], function ClearModule(Widg
'hub:memory/todos/change': function onChange(topic, items) {
var count = $.grep(items, filter, true).length;
this.$element.text('Clear completed (' + count + ')')[count > 0 ? 'show' : 'hide']();
this.$element.text('Clear completed (' + count + ')').toggle(count > 0);
},
'dom/click': function onClear(topic, $event) {
'dom/click': function onClear() {
this.publish('todos/clear');
}
});
......
define( [ 'troopjs-core/component/widget', 'jquery' ], function CountModule(Widget, $) {
/*global define*/
define([
'troopjs-core/component/widget',
'jquery'
], function CountModule(Widget, $) {
'use strict';
function filter(item, index) {
function filter(item) {
return item === null || item.completed;
}
......
define( [ 'troopjs-core/component/widget' ], function CreateModule(Widget) {
/*global define*/
define([
'troopjs-core/component/widget'
], function CreateModule(Widget) {
'use strict';
var ENTER_KEY = 13;
return Widget.extend({
......
define( [ 'troopjs-core/component/widget', 'jquery' ], function DisplayModule(Widget, $) {
/*global define*/
define([
'troopjs-core/component/widget',
'jquery'
], function DisplayModule(Widget, $) {
'use strict';
function filter(item, index) {
function filter(item) {
return item === null;
}
return Widget.extend({
'hub:memory/todos/change': function onChange(topic, items) {
this.$element[$.grep(items, filter, true).length > 0 ? 'show' : 'hide']();
var count = $.grep(items, filter, true).length;
this.$element.toggle(count > 0);
}
});
});
define( ['jquery'], function EscapeModule($) {
var entityMap = {
escape: {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'/': '&#x2F;'
}
},
invert = function(obj) {
/*global define*/
/*jshint quotmark:false*/
define([
'jquery'
], function EscapeModule($) {
'use strict';
var invert = function (obj) {
var result = {};
for (var key in obj) {
var key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
result[obj[key]] = key;
}
}
return result;
},
nativeKeys = Object.keys,
keys = nativeKeys || function(obj) {
};
var fallbackKeys = function (obj) {
var keys = [];
var key;
if (obj !== Object(obj)) {
throw new TypeError('Invalid object');
}
var keys = [];
for (var key in obj) {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
keys[keys.length] = key;
}
}
return keys;
};
exports = {};
var keys = Object.keys || fallbackKeys;
var entityMap = {};
entityMap.escape = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'/': '&#x2F;'
};
entityMap.unescape = invert(entityMap.escape);
......@@ -40,12 +55,15 @@ define( ['jquery'], function EscapeModule($) {
unescape: new RegExp('(' + keys(entityMap.unescape).join('|') + ')', 'g')
};
$.each(['escape', 'unescape'], function(i, method) {
exports[method] = function(string) {
if (string == null) {
var exports = {};
$.each(['escape', 'unescape'], function (i, method) {
exports[method] = function (string) {
if (string === null) {
return '';
}
return ('' + string).replace(entityRegexes[method], function(match) {
return ('' + string).replace(entityRegexes[method], function (match) {
return entityMap[method][match];
});
};
......
define( [ 'troopjs-core/component/widget', 'jquery' ], function FiltersModule(Widget, $) {
/*global define*/
define([
'troopjs-core/component/widget',
'jquery'
], function FiltersModule(Widget, $) {
'use strict';
return Widget.extend({
'hub:memory/route': function onRoute(topic, uri) {
......
define( [ './escape', 'troopjs-core/component/widget', 'troopjs-core/store/local', 'jquery', 'template!./item.html' ], function ListModule(Escaper, Widget, store, $, template) {
/*global define*/
define([
'./escape',
'troopjs-core/component/widget',
'troopjs-core/store/local',
'jquery',
'troopjs-requirejs/template!./item.html'
], function ListModule(Escaper, Widget, store, $, template) {
'use strict';
var ENTER_KEY = 13;
var ESCAPE_KEY = 27;
var FILTER_ACTIVE = 'filter-active';
var FILTER_COMPLETED = 'filter-completed';
function filter(item, index) {
function filter(item) {
return item === null;
}
return Widget.extend(function ListWidget(element, name) {
return Widget.extend(function ListWidget() {
var self = this;
// Defer initialization
......@@ -26,9 +36,9 @@ define( [ './escape', 'troopjs-core/component/widget', 'troopjs-core/store/local
$.each(items, function itemIterator(i, item) {
// Append to self
self.append(template, {
'i': i,
'item': item,
'itemTitle': Escaper.escape(item.title)
i: i,
item: item,
itemTitle: Escaper.escape(item.title)
});
});
})
......@@ -51,15 +61,15 @@ define( [ './escape', 'troopjs-core/component/widget', 'troopjs-core/store/local
// Create new item, store in items
var item = items[i] = {
'completed': false,
'title': title
completed: false,
title: title
};
// Append new item to self
self.append(template, {
'i': i,
'item': item,
'itemTitle': Escaper.escape(item.title)
i: i,
item: item,
itemTitle: Escaper.escape(item.title)
});
// Set items and resolve set
......@@ -75,7 +85,7 @@ define( [ './escape', 'troopjs-core/component/widget', 'troopjs-core/store/local
this.$element.find(':checkbox').prop('checked', value).change();
},
'hub/todos/clear': function onClear(topic) {
'hub/todos/clear': function onClear() {
this.$element.find('.completed .destroy').click();
},
......@@ -96,7 +106,7 @@ define( [ './escape', 'troopjs-core/component/widget', 'troopjs-core/store/local
break;
default:
$element.removeClass([FILTER_ACTIVE, FILTER_COMPLETED].join(' '));
$element.removeClass(FILTER_ACTIVE + ' ' + FILTER_COMPLETED);
}
},
......@@ -191,8 +201,19 @@ define( [ './escape', 'troopjs-core/component/widget', 'troopjs-core/store/local
},
'dom/action/commit.keyup': function onCommitKeyUp(topic, $event) {
if ($event.originalEvent.keyCode === ENTER_KEY) {
$($event.target).focusout();
var $target = $($event.target);
var keyCode = $event.originalEvent.keyCode;
if (keyCode === ENTER_KEY) {
$target.focusout();
}
if (keyCode === ESCAPE_KEY) {
$target
.closest('li.editing')
.removeClass('editing');
$target.val(store.get(this.config.store));
}
},
......@@ -207,8 +228,7 @@ define( [ './escape', 'troopjs-core/component/widget', 'troopjs-core/store/local
.removeClass('editing')
.find('.destroy')
.click();
}
else {
} else {
// Defer set
$.Deferred(function deferredSet(deferSet) {
// Disable
......
define( [ 'troopjs-core/component/widget' ], function MarkModule(Widget) {
/*global define*/
define([
'jquery',
'troopjs-core/component/widget'
], function MarkModule($, Widget) {
'use strict';
return Widget.extend({
'hub:memory/todos/change': function onChange(topic, items) {
......@@ -18,21 +23,9 @@ define( [ 'troopjs-core/component/widget' ], function MarkModule(Widget) {
total++;
});
if (count === 0) {
$element
.prop('indeterminate', false)
.prop('checked', false);
}
else if (count === total) {
$element
.prop('indeterminate', false)
.prop('checked', true);
}
else {
$element
.prop('indeterminate', true)
.prop('checked', false);
}
.prop('indeterminate', count !== 0 && count !== total)
.prop('checked', count === total);
},
'dom/change': function onMark(topic, $event) {
......
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