Commit 90305011 authored by Sindre Sorhus's avatar Sindre Sorhus

PlastronJS: Fix code style and readme

parent 76d18d5a
# PlastronJS • [TodoMVC](http://todomvc.com)
# PlastronJS TodoMVC app
A todo app using [PlastronJS](https://github.com/rhysbrettbowen/PlastronJS) and [Closure Tools](https://developers.google.com/closure/)
A todo app using [PlastronJS](https://github.com/rhysbrettbowen/PlastronJS)
and [Closure Tools](https://developers.google.com/closure/)
## Run
Just open the index.html in your browser
## Run uncompiled
The app is built with [Plovr](http://plovr.com/). To run the unminified version you need to [download Plovr](http://plovr.com/download.html), create a directory called "build" and put the jar file in the build folder.
You will then need to [download PlastronJS](https://github.com/rhysbrettbowen/PlastronJS) to js/lib (you will need to create the folder).
Next open a command prompt in the base directory of the plastronjs todomvc example and type in.
Next open a command prompt in the base directory of the PlastronJS TodoMVC example and type in:
```
```shell
java -jar build/plovr.jar serve plovr.json
```
......@@ -27,6 +28,7 @@ http://localhost:9810/compile?id=todomvc&mode=raw
You can now view the uncompiled example and play around with it!
# Compilation
Once you have done the steps above you can compile any changes you make by running the below command:
......@@ -35,12 +37,14 @@ Once you have done the steps above you can compile any changes you make by runni
java -jar build/plovr.jar build plovr.json
```
and view the compiled version fo the page by changing the bottom script src back to js/compiled.
and view the compiled version for the page by changing the bottom script src back to js/compiled.
## Need help?
shoot me a quick message on [twitter](https://twitter.com/#!/RhysBB)
Message me on [twitter](https://twitter.com/#!/RhysBB)
## Credit
Created by [Rhys Brett-Bowen](http://rhysbrettbowen.com)
Created by [Rhys Brett-Bowen](http://rhysbrettbowen.com)
\ No newline at end of file
......@@ -6,16 +6,13 @@ goog.require('todomvc.listcontrol');
goog.require('todomvc.listmodel');
var todolist = new todomvc.listmodel();
//create the control for the collection.
var todolistControl = new todomvc.listcontrol(todolist);
todolistControl.decorate(goog.dom.getElement('todoapp'));
// Create the control for the collection.
var todolistControl = new todomvc.listcontrol( todolist );
todolistControl.decorate( goog.dom.getElement('todoapp') );
//setup router
// Setup router
var router = new mvc.Router();
......@@ -24,28 +21,27 @@ var router = new mvc.Router();
*
* @param {string} chosenFilter selected filter by name.
*/
var toggleFilters = function(chosenFilter) {
var filters = goog.dom.getElementsByTagNameAndClass('A', undefined,
goog.dom.getElement('filters'));
goog.array.forEach(filters, function(filter) {
goog.dom.classes.enable(filter, 'selected',
goog.dom.getTextContent(filter) === chosenFilter);
});
var toggleFilters = function( chosenFilter ) {
var filters = goog.dom.getElementsByTagNameAndClass( 'A', undefined,
goog.dom.getElement('filters') );
goog.array.forEach( filters, function( filter ) {
goog.dom.classes.enable( filter, 'selected',
goog.dom.getTextContent( filter ) === chosenFilter );
});
};
router.route('/', function() {
todolistControl.setFilter(todomvc.listcontrol.Filter.ALL);
toggleFilters('All');
router.route( '/', function() {
todolistControl.setFilter( todomvc.listcontrol.Filter.ALL );
toggleFilters('All');
});
router.route('/active', function() {
todolistControl.setFilter(todomvc.listcontrol.Filter.ACTIVE);
toggleFilters('Active');
router.route( '/active', function() {
todolistControl.setFilter( todomvc.listcontrol.Filter.ACTIVE );
toggleFilters('Active');
});
router.route('/completed', function() {
todolistControl.setFilter(todomvc.listcontrol.Filter.COMPLETED);
toggleFilters('Completed');
});
router.route( '/completed', function() {
todolistControl.setFilter( todomvc.listcontrol.Filter.COMPLETED );
toggleFilters('Completed');
});
\ No newline at end of file
......@@ -8,7 +8,6 @@ goog.require('todomvc.templates');
goog.require('todomvc.todocontrol');
/**
* the control for the todo list, handles the page as well
*
......@@ -16,20 +15,26 @@ goog.require('todomvc.todocontrol');
* @param {mvc.Collection} list model for todo items.
* @extends {mvc.Control}
*/
todomvc.listcontrol = function(list) {
goog.base(this, list);
todomvc.listcontrol = function( list ) {
goog.base( this, list );
this.filter_ = todomvc.listcontrol.Filter.ALL;
};
goog.inherits(todomvc.listcontrol, mvc.Control);
goog.inherits( todomvc.listcontrol, mvc.Control );
/**
* @enum {Function}
*/
todomvc.listcontrol.Filter = {
ALL: function() {return true},
ACTIVE: function(model) {return !model.get('completed')},
COMPLETED: function(model) {return model.get('completed')}
ALL: function() {
return true
},
ACTIVE: function( model ) {
return !model.get('completed')
},
COMPLETED: function( model ) {
return model.get('completed')
}
};
......@@ -39,76 +44,84 @@ todomvc.listcontrol.Filter = {
* @inheritDoc
*/
todomvc.listcontrol.prototype.enterDocument = function() {
goog.base(this, 'enterDocument');
goog.base( this, 'enterDocument' );
var list = /** @type {Object} */(this.getModel());
// create new model from text box
// Create new model from text box
var input = this.getEls('input')[0];
this.on(goog.events.EventType.KEYUP, function(e) {
// on return get trimmed text
if (e.keyCode !== goog.events.KeyCodes.ENTER) return;
this.on( goog.events.EventType.KEYUP, function( e ) {
// On return get trimmed text
if ( e.keyCode !== goog.events.KeyCodes.ENTER ) {
return;
}
var text = goog.string.trim(input.value);
if (text === '') return;
var text = goog.string.trim( input.value );
if ( !text) {
return;
}
//create new model
list.newModel({'title': text});
// Create new model
list.newModel({
'title': text
});
input.value = '';
}, 'todo-entry');
}, 'todo-entry' );
// clear completed
this.click(function(e) {
goog.array.forEach(list.get('completed'), function(model) {
// Clear completed
this.click(function( e ) {
goog.array.forEach( list.get('completed'), function( model ) {
model.dispose();
});
}, 'clear-completed');
}, 'clear-completed' );
// toggle completed
this.click(function(e) {
// Toggle completed
this.click(function( e ) {
var checked = e.target.checked;
goog.array.forEach(list.getModels(), function(model) {
model.set('completed', checked);
goog.array.forEach( list.getModels(), function( model ) {
model.set( 'completed', checked );
});
}, 'toggle-all');
}, 'toggle-all' );
// refresh the view on changes that effect the models order
// Refresh the view on changes that effect the models order
this.anyModelChange(function() {
this.refresh();
list.save();
}, this);
}, this );
// hide/show footer and main body
// Toggle footer and main body
this.modelChange(function() {
this.showMainFooter(!!list.getLength());
}, this);
this.showMainFooter(!!list.getLength());
this.showMainFooter( !!list.getLength() );
}, this );
this.showMainFooter( !!list.getLength() );
// update counts
this.bind('completed', function(completedModels) {
// Update counts
this.bind( 'completed', function( completedModels ) {
// update "left" count
// Update "left" count
soy.renderElement(goog.dom.getElement('todo-count'),
todomvc.templates.itemsLeft, {
left: list.getLength() - completedModels.length
});
todomvc.templates.itemsLeft, {
left: list.getLength() - completedModels.length
});
// update clear button
// Update clear button
var clearButton = goog.dom.getElement('clear-completed');
goog.dom.setTextContent(clearButton,
'Clear completed (' + completedModels.length + ')');
goog.style.showElement(clearButton, completedModels.length);
goog.dom.setTextContent( clearButton,
'Clear completed (' + completedModels.length + ')' );
goog.style.showElement( clearButton, completedModels.length );
// update checkbox
// Update checkbox
var checkBox = this.getEls('.toggle-all')[0];
checkBox.checked = completedModels.length === list.getLength();
});
// get the saved todos
// Get the saved todos
list.fetch();
};
......@@ -118,12 +131,12 @@ todomvc.listcontrol.prototype.enterDocument = function() {
*
* @param {boolean=} opt_hide whether to hide the footer.
*/
todomvc.listcontrol.prototype.showMainFooter = function(opt_hide) {
todomvc.listcontrol.prototype.showMainFooter = function( opt_hide ) {
var main = goog.dom.getElement('main');
var footer = goog.dom.getElementsByTagNameAndClass('footer')[0];
goog.style.showElement(main, opt_hide);
goog.style.showElement(footer, opt_hide);
goog.style.showElement( main, opt_hide );
goog.style.showElement( footer, opt_hide );
};
......@@ -132,7 +145,7 @@ todomvc.listcontrol.prototype.showMainFooter = function(opt_hide) {
*
* @param {Function} filter to decide models returned.
*/
todomvc.listcontrol.prototype.setFilter = function(filter) {
todomvc.listcontrol.prototype.setFilter = function( filter ) {
this.filter_ = filter;
this.refresh();
};
......@@ -143,17 +156,18 @@ todomvc.listcontrol.prototype.setFilter = function(filter) {
*/
todomvc.listcontrol.prototype.refresh = function() {
// dispose and remove all the children.
this.forEachChild(function(child) {child.dispose();});
this.removeChildren(true);
// create new controls for the models
goog.array.forEach(this.getModel().getModels(this.filter_),
function(model) {
var newModelControl = new todomvc.todocontrol(model);
this.addChild(newModelControl);
newModelControl.render(goog.dom.getElement('todo-list'));
}, this);
};
// Dispose and remove all the children.
this.forEachChild(function( child ) {
child.dispose();
});
this.removeChildren( true );
// Create new controls for the models
goog.array.forEach( this.getModel().getModels(this.filter_),
function( model ) {
var newModelControl = new todomvc.todocontrol( model );
this.addChild( newModelControl );
newModelControl.render( goog.dom.getElement('todo-list') );
}, this );
};
\ No newline at end of file
......@@ -13,11 +13,11 @@ goog.require('todomvc.templates');
* @param {mvc.Model} model for the control.
* @extends {mvc.Control}
*/
todomvc.todocontrol = function(model) {
goog.base(this, model);
todomvc.todocontrol = function( model ) {
goog.base( this, model );
};
goog.inherits(todomvc.todocontrol, mvc.Control);
goog.inherits( todomvc.todocontrol, mvc.Control );
......@@ -27,10 +27,11 @@ goog.inherits(todomvc.todocontrol, mvc.Control);
* @inheritDoc
*/
todomvc.todocontrol.prototype.createDom = function() {
var el = soy.renderAsFragment(todomvc.templates.todoItem, {
var el = soy.renderAsFragment( todomvc.templates.todoItem, {
model: this.getModel().toJson()
}, null);
this.setElementInternal(/** @type {Element} */(el));
}, null );
this.setElementInternal(/** @type {Element} */(el));
};
......@@ -43,32 +44,32 @@ todomvc.todocontrol.prototype.enterDocument = function() {
var model = this.getModel();
// toggle complete
this.click(function(e) {
model.set('completed', e.target.checked);
}, 'toggle');
// Toggle complete
this.click(function( e ) {
model.set( 'completed', e.target.checked );
}, 'toggle' );
// delete the model
this.click(function(e) {
// Delete the model
this.click(function( e ) {
model.dispose();
}, 'destroy');
}, 'destroy' );
// dblclick to edit
this.on(goog.events.EventType.DBLCLICK, function(e) {
this.makeEditable(true);
}, 'view');
// Dblclick to edit
this.on( goog.events.EventType.DBLCLICK, function( e ) {
this.makeEditable( true );
}, 'view' );
// save on edit
// Save on edit
var inputEl = this.getEls('.edit')[0];
this.on(goog.events.EventType.KEYUP, function(e) {
if (e.keyCode === goog.events.KeyCodes.ENTER) {
model.set('title', inputEl.value);
this.on( goog.events.EventType.KEYUP, function( e ) {
if ( e.keyCode === goog.events.KeyCodes.ENTER ) {
model.set( 'title', inputEl.value );
}
}, 'edit');
}, 'edit' );
this.on(goog.events.EventType.BLUR, function(e) {
model.set('title', inputEl.value);
}, 'edit');
this.on( goog.events.EventType.BLUR, function( e ) {
model.set( 'title', inputEl.value );
}, 'edit' );
};
......@@ -77,14 +78,13 @@ todomvc.todocontrol.prototype.enterDocument = function() {
*
* @param {boolean} editable whether to make editable.
*/
todomvc.todocontrol.prototype.makeEditable = function(editable) {
todomvc.todocontrol.prototype.makeEditable = function( editable ) {
var inputEl = this.getEls('.edit')[0];
goog.dom.classes.enable(this.getElement(), 'editing', editable);
if (editable) {
goog.dom.classes.enable( this.getElement(), 'editing', editable );
if ( editable ) {
inputEl.value = this.getModel().get('title');
inputEl.select();
}
};
};
\ No newline at end of file
......@@ -14,7 +14,7 @@ todomvc.listmodel = function() {
var todosSchema = {
'completed': {
get: function() {
return this.getModels(function(mod) {
return this.getModels(function( mod ) {
return mod.get('completed');
});
},
......@@ -22,22 +22,21 @@ todomvc.listmodel = function() {
}
};
goog.base(this, {
goog.base( this, {
'id': 'todos-plastronjs',
'sync': new todomvc.listsync(),
'schema': todosSchema,
'modelType': todomvc.todomodel
});
};
goog.inherits(todomvc.listmodel, mvc.Collection);
goog.inherits( todomvc.listmodel, mvc.Collection );
/**
* @return {Object} todos as json.
*/
todomvc.listmodel.prototype.toJson = function() {
return goog.array.map(this.getModels(), function(mod) {
return goog.array.map( this.getModels(), function( mod ) {
return mod.toJson();
});
};
};
\ No newline at end of file
......@@ -5,19 +5,21 @@ goog.require('mvc.Model');
goog.require('mvc.Model.ValidateError');
/**
* @constructor
* @param {Object=} opt_options to be put on the model.
* @extends {mvc.Model}
*/
todomvc.todomodel = function(opt_options) {
goog.base(this, opt_options);
todomvc.todomodel = function( opt_options ) {
goog.base( this, opt_options );
this.setter( 'title', function( title ) {
var updated = goog.string.trim( title );
this.setter('title', function(title) {
var updated = goog.string.trim(title);
if (!updated.length)
if ( !updated.length ) {
throw new mvc.Model.ValidateError('null string');
}
return updated;
});
......@@ -25,4 +27,4 @@ todomvc.todomodel = function(opt_options) {
this.dispose();
});
};
goog.inherits(todomvc.todomodel, mvc.Model);
goog.inherits( todomvc.todomodel, mvc.Model );
\ No newline at end of file
......@@ -3,28 +3,25 @@ goog.provide('todomvc.listsync');
goog.require('mvc.LocalSync');
/**
* @constructor
* @extends {mvc.LocalSync}
*/
todomvc.listsync = function() {
goog.base(this);
goog.base( this );
};
goog.inherits(todomvc.listsync, mvc.LocalSync);
goog.inherits( todomvc.listsync, mvc.LocalSync );
/**
* @inheritDoc
*/
todomvc.listsync.prototype.read = function(model, opt_callback) {
todomvc.listsync.prototype.read = function( model, opt_callback ) {
var id = /** @type {string} */(model.get('id'));
var todos = this.store_.get(id) || [];
goog.array.forEach(/** @type {Array} */(todos),
function(todo) {
model.newModel(todo, true);
function( todo ) {
model.newModel( todo, true );
});
model.change();
};
};
\ No newline at end of file
......@@ -10,7 +10,7 @@
<label>{$model['title']}</label>
<button class="destroy"></button>
</div>
<input class="edit" type="text" value="">
<input class="edit">
</li>
{/template}
......
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