forked from tastejs/todomvc
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8a84177
commit f00d362
Showing
16 changed files
with
752 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Ignore file for Nodemon: https://github.com/remy/nodemon | ||
# Install with 'npm install -g nodemon' then start your app with 'nodemon app.js' | ||
# From then on, all changes you make to /server will cause your app to automatically restart | ||
|
||
/client/* | ||
./README.md |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# SocketStream TodoMVC app | ||
|
||
> A fast, modular Node.js web framework dedicated to building realtime single-page apps | ||
|
||
## Getting Started | ||
|
||
Running this app requires [Node.js](http://nodejs.org) | ||
|
||
- `cd` into this folder and run `npm install` to fetch all the required dependencies | ||
- `node app.js` to start the app | ||
- Open `localhost:3000` in two side-by-side browser windows, add a todo and see the magic |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
var http = require('http'), | ||
ss = require('socketstream'); | ||
|
||
// Define a single-page client | ||
ss.client.define('main', { | ||
view: 'app.html', | ||
css: ['base.css'], | ||
code: [ 'libs', 'app' ], | ||
tmpl: '*' | ||
}); | ||
|
||
// Serve this client on the root URL | ||
ss.http.route( '/', function( req, res ) { | ||
res.serveClient('main'); | ||
}); | ||
|
||
// Use server-side compiled Hogan (Mustache) templates. Others engines available | ||
ss.client.templateEngine.use( require('ss-hogan') ); | ||
|
||
// Minimize and pack assets if you type: SS_ENV=production node app.js | ||
if ( ss.env === 'production' ) { | ||
ss.client.packAssets(); | ||
} | ||
|
||
// Start web server | ||
var server = http.Server( ss.http.middleware ); | ||
server.listen(3000); | ||
|
||
// Start SocketStream | ||
ss.start( server ); |
159 changes: 159 additions & 0 deletions
159
labs/architecture-examples/socketstream/client/code/app/app.js
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
/*global $, ss */ | ||
'use strict'; | ||
|
||
var Utils = { | ||
// https://gist.github.com/1308368 | ||
uuid: function(a,b){for(b=a='';a++<36;b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'-');return b}, | ||
pluralize: function( count, word ) { | ||
return count === 1 ? word : word + 's'; | ||
} | ||
}; | ||
|
||
var App = { | ||
init: function() { | ||
var self = this; | ||
this.ENTER_KEY = 13; | ||
ss.rpc('todos.getAll', function( todos ) { | ||
self.todos = todos; | ||
self.cacheElements(); | ||
self.bindEvents(); | ||
self.render(); | ||
}); | ||
}, | ||
cacheElements: function() { | ||
this.$todoApp = $('#todoapp'); | ||
this.$newTodo = $('#new-todo'); | ||
this.$toggleAll = $('#toggle-all'); | ||
this.$main = $('#main'); | ||
this.$todoList = $('#todo-list'); | ||
this.$footer = this.$todoApp.find('#footer'); | ||
this.$count = $('#todo-count'); | ||
this.$clearBtn = $('#clear-completed'); | ||
}, | ||
bindEvents: function() { | ||
var list = this.$todoList; | ||
this.$newTodo.on( 'keyup', this.create ); | ||
this.$toggleAll.on( 'change', this.toggleAll ); | ||
this.$footer.on( 'click', '#clear-completed', this.destroyCompleted ); | ||
list.on( 'change', '.toggle', this.toggle ); | ||
list.on( 'dblclick', '.view', this.edit ); | ||
list.on( 'keypress', '.edit', this.blurOnEnter ); | ||
list.on( 'blur', '.edit', this.update ); | ||
list.on( 'click', '.destroy', this.destroy ); | ||
ss.event.on( 'updateTodos', this.updateTodos ); | ||
}, | ||
updateTodos: function( todos ) { | ||
App.todos = todos; | ||
App.render( true ); | ||
}, | ||
render: function( preventRpc ) { | ||
var html = this.todos.map(function( el ) { | ||
return ss.tmpl.todo.render( el ); | ||
}).join(''); | ||
|
||
this.$todoList.html( html ); | ||
this.$main.toggle( !!this.todos.length ); | ||
this.$toggleAll.prop( 'checked', !this.activeTodoCount() ); | ||
this.renderFooter(); | ||
|
||
if ( !preventRpc ) { | ||
ss.rpc( 'todos.update', this.todos ); | ||
} | ||
}, | ||
renderFooter: function() { | ||
var todoCount = this.todos.length, | ||
activeTodoCount = this.activeTodoCount(), | ||
footer = { | ||
activeTodoCount: activeTodoCount, | ||
activeTodoWord: Utils.pluralize( activeTodoCount, 'item' ), | ||
completedTodos: todoCount - activeTodoCount | ||
}; | ||
|
||
this.$footer.toggle( !!todoCount ); | ||
this.$footer.html( ss.tmpl.footer.render( footer ) ); | ||
}, | ||
toggleAll: function() { | ||
var isChecked = $( this ).prop('checked'); | ||
$.each( App.todos, function( i, val ) { | ||
val.completed = isChecked; | ||
}); | ||
App.render(); | ||
}, | ||
activeTodoCount: function() { | ||
var count = 0; | ||
$.each( this.todos, function( i, val ) { | ||
if ( !val.completed ) { | ||
count++; | ||
} | ||
}); | ||
return count; | ||
}, | ||
destroyCompleted: function() { | ||
var todos = App.todos, | ||
l = todos.length; | ||
while ( l-- ) { | ||
if ( todos[l].completed ) { | ||
todos.splice( l, 1 ); | ||
} | ||
} | ||
App.render(); | ||
}, | ||
// Accepts an element from inside the ".item" div and | ||
// returns the corresponding todo in the todos array | ||
getTodo: function( elem, callback ) { | ||
var id = $( elem ).closest('li').data('id'); | ||
$.each( this.todos, function( i, val ) { | ||
if ( val.id === id ) { | ||
callback.apply( App, arguments ); | ||
return false; | ||
} | ||
}); | ||
}, | ||
create: function(e) { | ||
var $input = $(this), | ||
val = $.trim( $input.val() ); | ||
if ( e.which !== App.ENTER_KEY || !val ) { | ||
return; | ||
} | ||
App.todos.push({ | ||
id: Utils.uuid(), | ||
title: val, | ||
completed: false | ||
}); | ||
$input.val(''); | ||
App.render(); | ||
}, | ||
toggle: function() { | ||
App.getTodo( this, function( i, val ) { | ||
val.completed = !val.completed; | ||
}); | ||
App.render(); | ||
}, | ||
edit: function() { | ||
$(this).closest('li').addClass('editing').find('.edit').focus(); | ||
}, | ||
blurOnEnter: function( e ) { | ||
if ( e.keyCode === App.ENTER_KEY ) { | ||
e.target.blur(); | ||
} | ||
}, | ||
update: function() { | ||
var val = $.trim( $(this).removeClass('editing').val() ); | ||
App.getTodo( this, function( i ) { | ||
if ( val ) { | ||
this.todos[ i ].title = val; | ||
} else { | ||
this.todos.splice( i, 1 ); | ||
} | ||
this.render(); | ||
}); | ||
}, | ||
destroy: function() { | ||
App.getTodo( this, function( i ) { | ||
this.todos.splice( i, 1 ); | ||
this.render(); | ||
}); | ||
} | ||
}; | ||
|
||
App.init(); |
24 changes: 24 additions & 0 deletions
24
labs/architecture-examples/socketstream/client/code/app/entry.js
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// This file automatically gets called first by SocketStream and must always exist | ||
|
||
// Make 'ss' available to all modules and the browser console | ||
window.ss = require('socketstream'); | ||
|
||
ss.server.on('disconnect', function() { | ||
console.log('Connection down :-('); | ||
}); | ||
|
||
ss.server.on('reconnect', function() { | ||
console.log('Connection back up :-)'); | ||
}); | ||
|
||
ss.server.on('ready', function() { | ||
|
||
// Wait for the DOM to finish loading | ||
$(function() { | ||
|
||
// Load app | ||
require('/app'); | ||
|
||
}); | ||
|
||
}); |
7 changes: 7 additions & 0 deletions
7
labs/architecture-examples/socketstream/client/code/libs/base.js
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
(function( window ) { | ||
'use strict'; | ||
|
||
if ( location.hostname === 'todomvc.com' ) { | ||
var _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')); | ||
} | ||
})( window ); |
Oops, something went wrong.