Permalink
Browse files

Merge labs branch into master/labs

  • Loading branch information...
2 parents e574886 + b2978df commit 86c4c86f087b1770a1b239ea2d914c447e3d452c @sindresorhus sindresorhus committed Apr 21, 2012
Showing 362 changed files with 79,949 additions and 0 deletions.
View
@@ -0,0 +1,5 @@
+# TodoMVC Labs
+
+TodoMVC Labs showcases sample Todo applications for frameworks that have just been released or are still awaiting consideration for inclusion in TodoMVC.
+
+While our team are working on improving these applications for a future release of TodoMVC (e.g ensuring they meet our functional requirements), developers wishing to try out brand new frameworks or see what's coming next for this project can preview this today.
@@ -0,0 +1,59 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Agility.js • TodoMVC</title>
+ <link rel="stylesheet" href="../../assets/base.css">
+</head>
+<body>
+ <section id="todoapp">
+ <header id="header">
+ <h1>todos</h1>
+ <input id="new-todo" type="text" data-bind="newtitle" placeholder="What needs to be done?" autofocus>
+ </header>
+
+ <section id="main" data-bind="class = mainStyle">
+ <input id="toggle-all" type="checkbox">
+ <label for="toggle-all">Mark all as complete</label>
+ <ul id="todo-list">
+ <li>
+ <div class="view">
+ <input class="toggle" type="checkbox" data-bind="complete">
+ <label data-bind="title"></label>
+ <button class="destroy"></button>
+ </div>
+ <input class="edit" type="text" data-bind="title">
+ </li>
+ </ul>
+ </section>
+
+ <footer id="footer" data-bind="class = mainStyle">
+ <span id="todo-count"><strong data-bind='todoCount'></strong> item<span data-bind='pluralizer'></span> left</span>
+
+ <ul id="filters">
+ <li>
+ <a class="selected" href="#/">All</a>
+ </li>
+ <li>
+ <a href="#/active">Active</a>
+ </li>
+ <li>
+ <a href="#/completed">Completed</a>
+ </li>
+ </ul>
+ <button id="clear-completed" data-bind="class = clearBtnStyle">Clear completed (<span data-bind="completeCount"></span>)</button>
+ </footer>
+ </section>
+ <footer id="info">
+ <p>Double-click to edit a todo</p>
+ <p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
+ <p>Created by <a href="http://github.com/tshm/todomvc/">Tosh Shimayama</a></p>
+ <p>Part of <a href="http://github.com/addyosmani/todomvc/">TodoMVC</a></p>
+ </footer>
+
+ <script src="../../assets/jquery.min.js"></script>
+ <script src="js/lib/agility.min.js"></script>
+ <script src="js/localstorage.js"></script>
+ <script src="js/app.js"></script>
+</body>
+</html>
@@ -0,0 +1,169 @@
+(function( $, $$ ) {
+ 'use strict';
+ var ENTER_KEY = 13;
+
+ // Hack of taking out html elements from DOM so that agility's view can use it.
+ // We need 'outerhtml' also, as agilityjs will append DOM, so removing it.
+ var drawHtml = function( selector ) {
+ return $(selector).remove().wrap( '<div>' ).parent().html();
+ };
+
+ // Simple Two layer composition:
+ // individual 'todoitem' and 'app'lication which holds multiple todoitems.
+ $(function() {
+ // todo item
+ var todoitem = $$({
+ model: {
+ title: 'no name',
+ complete: false
+ },
+ view: {
+ format: drawHtml( '#todo-list li' ),
+ style: '.hidden { display: none }'
+ },
+ controller: {
+ 'change:complete': function() {
+ this.view.$().toggleClass( 'complete', this.model.get( 'complete' ));
+ app.updateStatus();
+ },
+ 'dblclick .view': function() {
+ this.view.$().addClass( 'editing' );
+ this.view.$('.edit').select();
+ },
+ 'click .destroy': function() {
+ this.destroy();
+ },
+ 'create': function() {
+ this.view.$().toggleClass( 'complete', this.model.get( 'complete' ));
+ },
+ 'change': function() {
+ this.save();
+ },
+ 'destroy': function() {
+ this.erase();
+ },
+ 'change:title': function() {
+ this.view.$().removeClass( 'editing' );
+ var title = this.model.get( 'title' ).trim();
+ if ( title ) {
+ this.model.set({
+ title: title
+ });
+ } else {
+ this.destroy();
+ }
+ }
+ }
+ }).persist( $$.adapter.localStorage, {
+ collection: 'todos-agilityjs'
+ });
+
+ // The main application which holds todo items.
+ var app = $$({
+ model: {
+ todoCount: '0',
+ pluralizer: '',
+ completeCount: '0',
+ newtitle: '',
+ mainStyle: '',
+ clearBtnStyle: ''
+ },
+ view: {
+ format: drawHtml( '#todoapp' ),
+ style: '.hidden { display: none }'
+ },
+ controller: {
+ 'remove': function() {
+ this.updateStatus();
+ },
+ 'append': function() {
+ this.updateStatus();
+ },
+ 'keyup #new-todo': function( event ) {
+ var title;
+ if ( event.which === ENTER_KEY && (title = $('#new-todo').val().trim()) ) {
+ var item = $$(todoitem, {
+ title: title
+ }).save();
+ this.append( item, '#todo-list' );
+ event.target.value = ''; // clear input field
+ }
+ },
+ 'click #toggle-all': function() {
+ var ischecked = this.view.$('#toggle-all').prop('checked');
+ this.each(function( id, item ) {
+ item.model.set({
+ complete: ischecked
+ });
+ });
+ },
+ 'click #clear-completed': function() {
+ this.each(function( id, item ) {
+ if ( item.model.get( 'complete' ) ) {
+ item.destroy();
+ }
+ });
+ }
+ },
+ // utility functions
+ updateStatus: function() {
+ // update counts
+ var count = this.size(),
+ completeCount = 0;
+ this.each(function( id, item ) {
+ if ( item.model.get( 'complete' ) ) {
+ completeCount++;
+ }
+ });
+ this.model.set({
+ todoCount: count - completeCount + '',
+ pluralizer: (count > 1 ? 's' : ''),
+ completeCount: completeCount + '',
+ mainStyle: (count === 0 ? 'hidden' : ''),
+ clearBtnStyle: (completeCount === 0 ? 'hidden' : '')
+ });
+ // update toggle-all checked status
+ $('#toggle-all').prop( 'checked', completeCount === count );
+ },
+ // filter handler
+ filters: {
+ '#/': function( item ) {
+ return true;
+ },
+ '#/active': function( item ) {
+ return !item.model.get( 'complete' );
+ },
+ '#/completed': function( item ) {
+ return item.model.get( 'complete' );
+ }
+ },
+ applyFilter: function( hash ) {
+ var isVisible = this.filters[hash];
+ this.each(function( id, item ) {
+ item.view.$().toggleClass( 'hidden', !isVisible( item ));
+ });
+ }
+ }).persist();
+ $$.document.prepend( app );
+
+ // load from localStorage
+ app.gather( todoitem, 'append', '#todo-list' ).updateStatus();
+
+ // manual routing (not supported by agilityjs)
+ $(window).on( 'hashchange', function() {
+ var hash = location.hash;
+ app.applyFilter( hash );
+ $('#filters a').each(function() {
+ if ( hash === $(this).attr( 'href' ) ) {
+ $(this).addClass( 'selected' );
+ } else {
+ $(this).removeClass( 'selected' );
+ }
+ });
+ });
+ if ( location.hash ) {
+ $(window).trigger( 'hashchange' );
+ }
+ });
+
+})( window.jQuery, window.agility );
Oops, something went wrong.

0 comments on commit 86c4c86

Please sign in to comment.