Comparing version 0.13.1 to 0.13.2
let setFilter = function(args, state) { | ||
let filter = | ||
args.pathname.indexOf('/#/active') !== -1 ? | ||
'active' : args.pathname.indexOf('/#/completed') !== -1 ? | ||
'completed' : 'all'; | ||
const filter = args.fragments[0] === '' ? 'all' : args.fragments[0]; | ||
state.set('filter', filter); | ||
@@ -7,0 +4,0 @@ }; |
@@ -8,3 +8,3 @@ let toggleAllChecked = function(args, state) { | ||
let todo = todos[key]; | ||
state.set(['todos', todo.ref, 'completed'], isCompleted); | ||
state.set(['todos', todo.$ref, 'completed'], isCompleted); | ||
}); | ||
@@ -11,0 +11,0 @@ |
import React from 'react'; | ||
import StateComponent from './StateComponent.js'; | ||
import {Decorator as Cerebral} from './CustomController.js'; | ||
import AddTodo from './components/AddTodo.js'; | ||
@@ -7,17 +7,15 @@ import TodosList from './components/TodosList.js'; | ||
class App extends StateComponent { | ||
getStatePaths() { | ||
return { | ||
visibleTodos: ['visibleTodos'], | ||
todos: ['todos'] | ||
}; | ||
} | ||
@Cerebral({ | ||
visibleTodos: ['visibleTodos'], | ||
todos: ['todos'] | ||
}) | ||
class App extends React.Component { | ||
record() { | ||
this.recorder.record(this.context.controller.get([]).export()); | ||
this.props.recorder.record(this.props.get().export()); | ||
} | ||
stop() { | ||
this.recorder.stop(); | ||
this.props.recorder.stop(); | ||
} | ||
play() { | ||
this.recorder.seek(0, true); | ||
this.props.recorder.seek(0, true); | ||
} | ||
@@ -29,8 +27,8 @@ render() { | ||
{ | ||
this.recorder.isRecording() ? | ||
<button className="btn btn-stop" onClick={this.stop.bind(this)}>Stop</button> : | ||
this.props.recorder.isRecording() ? | ||
<button className="btn btn-stop" onClick={() => this.stop()}>Stop</button> : | ||
null | ||
} | ||
{ | ||
this.recorder.isPlaying() ? | ||
this.props.recorder.isPlaying() ? | ||
<button className="btn btn-play" disabled>Play</button> : | ||
@@ -40,9 +38,9 @@ null | ||
{ | ||
!this.recorder.isRecording() && !this.recorder.isPlaying() && this.recorder.getRecording() ? | ||
<button className="btn btn-play" onClick={this.play.bind(this)}>Play</button> : | ||
!this.props.recorder.isRecording() && !this.props.recorder.isPlaying() && this.props.recorder.getRecording() ? | ||
<button className="btn btn-play" onClick={() => this.play()}>Play</button> : | ||
null | ||
} | ||
{ | ||
!this.recorder.isRecording() && !this.recorder.isPlaying() && !this.recorder.getRecording() ? | ||
<button className="btn btn-record" onClick={this.record.bind(this)}>Record</button> : | ||
!this.props.recorder.isRecording() && !this.props.recorder.isPlaying() && !this.props.recorder.getRecording() ? | ||
<button className="btn btn-record" onClick={() => this.record()}>Record</button> : | ||
null | ||
@@ -57,4 +55,4 @@ } | ||
{this.state.visibleTodos.length ? <TodosList/> : null} | ||
{Object.keys(this.state.todos).length ? <TodosFooter/> : null} | ||
{this.props.visibleTodos.length ? <TodosList/> : null} | ||
{Object.keys(this.props.todos).length ? <TodosFooter/> : null} | ||
</section> | ||
@@ -61,0 +59,0 @@ <footer id="info"> |
import React from 'react'; | ||
import StateComponent from './../StateComponent.js'; | ||
import {Decorator as Cerebral} from './../CustomController.js'; | ||
class AddTodo extends StateComponent { | ||
getStatePaths() { | ||
return { | ||
isSaving: ['isSaving'], | ||
newTodoTitle: ['newTodoTitle'] | ||
}; | ||
} | ||
addTodo(event) { | ||
@Cerebral({ | ||
isSaving: ['isSaving'], | ||
newTodoTitle: ['newTodoTitle'] | ||
}) | ||
class AddTodo extends React.Component { | ||
onFormSubmit(event) { | ||
event.preventDefault(); | ||
this.signals.newTodoSubmitted(); | ||
this.props.signals.newTodoSubmitted(); | ||
} | ||
setNewTodoTitle(event) { | ||
this.signals.newTodoTitleChanged({ | ||
onNewTodoTitleChange(event) { | ||
this.props.signals.newTodoTitleChanged({ | ||
title: event.target.value | ||
@@ -24,3 +22,3 @@ }); | ||
return ( | ||
<form id="todo-form" onSubmit={this.addTodo.bind(this)}> | ||
<form id="todo-form" onSubmit={(e) => this.onFormSubmit(e)}> | ||
<input | ||
@@ -30,5 +28,5 @@ id="new-todo" | ||
placeholder="What needs to be done?" | ||
disabled={this.state.isSaving} | ||
value={this.state.newTodoTitle} | ||
onChange={this.setNewTodoTitle.bind(this)} | ||
disabled={this.props.isSaving} | ||
value={this.props.newTodoTitle} | ||
onChange={(e) => this.onNewTodoTitleChange(e)} | ||
/> | ||
@@ -35,0 +33,0 @@ </form> |
import React from 'react'; | ||
import classNames from 'classnames'; | ||
import StateComponent from './../StateComponent.js'; | ||
import {Decorator as Cerebral} from './../CustomController.js'; | ||
class Todo extends StateComponent { | ||
@Cerebral() | ||
class Todo extends React.Component { | ||
edit() { | ||
@@ -13,3 +13,3 @@ | ||
this.signals.todoDoubleClicked({ | ||
this.props.signals.todoDoubleClicked({ | ||
ref: this.props.todo.$ref | ||
@@ -24,6 +24,6 @@ }); | ||
}, 0); | ||
} | ||
onNewTitleChanged(event) { | ||
this.signals.newTitleChanged({ | ||
onNewTitleChange(event) { | ||
this.props.signals.newTitleChanged({ | ||
ref: this.props.todo.$ref, | ||
@@ -33,8 +33,21 @@ title: event.target.value | ||
} | ||
onNewTitleSubmitted(event) { | ||
onNewTitleSubmit(event) { | ||
event.preventDefault(); | ||
this.refs.edit.getDOMNode().blur(); | ||
} | ||
onCompletedToggle() { | ||
this.props.signals.toggleCompletedChanged({ | ||
ref: this.props.todo.$ref | ||
}); | ||
} | ||
onRemoveClick() { | ||
this.props.signals.removeTodoClicked({ | ||
ref: this.props.todo.$ref | ||
}); | ||
} | ||
onNewTitleBlur() { | ||
this.props.signals.newTitleSubmitted({ | ||
ref: this.props.todo.$ref | ||
}); | ||
} | ||
render() { | ||
@@ -57,6 +70,6 @@ | ||
disabled={this.props.todo.$isSaving} | ||
onChange={this.signals.toggleCompletedChanged.bind(null, {ref: this.props.todo.$ref})} | ||
onChange={() => this.onCompletedToggle()} | ||
checked={this.props.todo.completed}/> | ||
} | ||
<label onDoubleClick={this.edit.bind(this)}> | ||
<label onDoubleClick={() => this.edit()}> | ||
{this.props.todo.title} {this.props.todo.$isSaving ? | ||
@@ -72,8 +85,6 @@ <small>(saving)</small> : | ||
className="destroy" | ||
onClick={this.signals.removeTodoClicked.bind(null, { | ||
ref: this.props.todo.$ref | ||
})}/> | ||
onClick={() => this.onRemoveClick()}/> | ||
} | ||
</div> | ||
<form onSubmit={this.onNewTitleSubmitted.bind(this)}> | ||
<form onSubmit={(e) => this.onNewTitleSubmit(e)}> | ||
<input | ||
@@ -83,6 +94,4 @@ ref="edit" | ||
value={this.props.todo.$newTitle || this.props.todo.title} | ||
onBlur={this.signals.newTitleSubmitted.bind(null, { | ||
ref: this.props.todo.$ref | ||
})} | ||
onChange={this.onNewTitleChanged.bind(this)} | ||
onBlur={() => this.onNewTitleBlur()} | ||
onChange={(e) => this.onNewTitleChange(e)} | ||
/> | ||
@@ -89,0 +98,0 @@ </form> |
import React from 'react/addons'; | ||
import StateComponent from './../StateComponent.js'; | ||
import {Decorator as Cerebral} from './../CustomController.js'; | ||
class TodosFooter extends StateComponent { | ||
getStatePaths() { | ||
return { | ||
remainingCount: ['remainingCount'], | ||
filter: ['filter'], | ||
completedCount: ['completedCount'] | ||
}; | ||
} | ||
@Cerebral({ | ||
remainingCount: ['remainingCount'], | ||
filter: ['filter'], | ||
completedCount: ['completedCount'] | ||
}) | ||
class TodosFooter extends React.Component { | ||
renderRemainingCount() { | ||
let count = this.state.remainingCount; | ||
let count = this.props.remainingCount; | ||
if (count === 0 || count > 1) { | ||
@@ -22,3 +20,3 @@ return count + ' items left'; | ||
renderRouteClass(filter) { | ||
return this.state.filter === filter ? 'selected' : ''; | ||
return this.props.filter === filter ? 'selected' : ''; | ||
} | ||
@@ -28,4 +26,4 @@ | ||
return ( | ||
<button id="clear-completed" onClick={this.signals.clearCompletedClicked}> | ||
Clear completed ({this.state.completedCount}) | ||
<button id="clear-completed" onClick={this.props.signals.clearCompletedClicked}> | ||
Clear completed ({this.props.completedCount}) | ||
</button> | ||
@@ -50,3 +48,3 @@ ); | ||
</ul> | ||
{this.state.completedCount ? this.renderCompletedButton() : null} | ||
{this.props.completedCount ? this.renderCompletedButton() : null} | ||
</footer> | ||
@@ -53,0 +51,0 @@ ); |
import React from 'react'; | ||
import Todo from './Todo.js'; | ||
import StateComponent from './../StateComponent.js'; | ||
import {Decorator as Cerebral} from './../CustomController.js'; | ||
class TodosList extends StateComponent { | ||
getStatePaths() { | ||
return { | ||
todos: ['visibleTodos'], | ||
isAllChecked: ['isAllChecked'], | ||
tod: ['todos'] | ||
}; | ||
} | ||
@Cerebral({ | ||
todos: ['visibleTodos'], | ||
isAllChecked: ['isAllChecked'], | ||
tod: ['todos'] | ||
}) | ||
class TodosList extends React.Component { | ||
renderTodo(todo, index) { | ||
@@ -23,8 +21,8 @@ return <Todo key={index} index={index} todo={todo}/> | ||
type="checkbox" | ||
checked={this.state.isAllChecked} | ||
onChange={this.signals.toggleAllChanged} | ||
checked={this.props.isAllChecked} | ||
onChange={() => this.props.signals.toggleAllChanged()} | ||
/> | ||
<label htmlFor="toggle-all">Mark all as complete</label> | ||
<ul id="todo-list"> | ||
{this.state.todos.map(this.renderTodo.bind(this))} | ||
{this.props.todos.map(this.renderTodo.bind(this))} | ||
</ul> | ||
@@ -31,0 +29,0 @@ </section> |
@@ -1,21 +0,20 @@ | ||
import Store from 'immutable-store'; | ||
import {Controller, Value} from 'cerebral'; | ||
import events from './events.js'; | ||
import Controller from './CustomController.js'; | ||
const initialState = Store({ | ||
const VisibleTodos = function() { | ||
return { | ||
value: [], | ||
deps: { | ||
todos: ['todos'] | ||
}, | ||
get: function(refs, deps) { | ||
return refs.map((ref) => deps.todos[ref]); | ||
} | ||
}; | ||
}; | ||
const state = { | ||
nextRef: 0, | ||
url: '/', | ||
todos: {}, | ||
visibleTodos: function() { | ||
return { | ||
value: [], | ||
deps: { | ||
todos: ['todos'] | ||
}, | ||
get: function(refs, deps) { | ||
return refs.map(function(ref) { | ||
return deps.todos[ref]; | ||
}); | ||
} | ||
}; | ||
}, | ||
visibleTodos: VisibleTodos, | ||
newTodoTitle: '', | ||
@@ -30,40 +29,4 @@ isSaving: false, | ||
filter: 'all' | ||
}); | ||
}; | ||
let state = initialState; | ||
export default Controller({ | ||
onReset: function () { | ||
state = initialState; | ||
events.emit('change', state); | ||
}, | ||
onSeek: function (seek, isPlaying, currentRecording) { | ||
state = state.import(currentRecording.initialState); | ||
events.emit('change', state); | ||
}, | ||
onUpdate: function () { | ||
events.emit('change', state); | ||
}, | ||
onGet: function (path) { | ||
return Value(path, state); | ||
}, | ||
onSet: function (path, value) { | ||
const key = path.pop(); | ||
state = Value(path, state).set(key, value); | ||
}, | ||
onUnset: function (path, key) { | ||
console.log(arguments); | ||
state = Value(path, state).unset(key); | ||
}, | ||
onPush: function (path, value) { | ||
state = Value(path, state).push(value); | ||
}, | ||
onSplice: function () { | ||
let args = [].slice.call(arguments); | ||
const value = Value(args.shift(), state); | ||
state = value.splice.apply(value, args); | ||
}, | ||
onMerge: function (path, value) { | ||
state = Value(path, state).merge(value); | ||
} | ||
}); | ||
export default Controller(state); |
@@ -8,3 +8,5 @@ import './../node_modules/todomvc-common/base.css'; | ||
import controller from './controller.js'; | ||
import Page from 'page'; | ||
import ReactiveRouter from 'reactive-router'; | ||
// ACTIONS | ||
import addTodo from './actions/addTodo.js'; | ||
@@ -25,2 +27,3 @@ import removeTodo from './actions/removeTodo.js'; | ||
import stopEditingTodo from './actions/stopEditingTodo.js'; | ||
import setUrl from './actions/setUrl.js'; | ||
@@ -34,3 +37,3 @@ // SIGNALS | ||
controller.signal('toggleAllChanged', toggleAllChecked, setVisibleTodos, setCounters); | ||
controller.signal('routeChanged', setFilter, setVisibleTodos); | ||
controller.signal('routeChanged', setUrl, setFilter, setVisibleTodos); | ||
controller.signal('clearCompletedClicked', clearCompleted, setVisibleTodos, setAllChecked, setCounters); | ||
@@ -42,24 +45,17 @@ controller.signal('todoDoubleClicked', editTodo); | ||
// RENDER | ||
const Wrapper = React.createClass({ | ||
childContextTypes: { | ||
controller: React.PropTypes.object | ||
}, | ||
getChildContext() { | ||
return { | ||
controller: controller | ||
} | ||
}, | ||
render() { | ||
return <App/>; | ||
} | ||
}); | ||
React.render(<Wrapper/>, document.querySelector('#app')); | ||
React.render(controller.injectInto(App), document.querySelector('#app')); | ||
// ROUTER | ||
Page.base(location.pathname.substr(0, location.pathname.length - 1)); | ||
const router = ReactiveRouter({ | ||
'/': controller.signals.routeChanged, | ||
'/active': controller.signals.routeChanged, | ||
'/completed': controller.signals.routeChanged | ||
}); | ||
Page('/', controller.signals.routeChanged); | ||
Page('/active', controller.signals.routeChanged); | ||
Page('/completed', controller.signals.routeChanged); | ||
controller.eventEmitter.on('change', function (state) { | ||
router.set(state.url); | ||
}); | ||
Page.start(); | ||
controller.eventEmitter.on('remember', function (state) { | ||
router.setSilent(state.url); | ||
}); |
{ | ||
"name": "cerebral", | ||
"version": "0.13.1", | ||
"version": "0.13.2", | ||
"description": "A state controller with its own debugger", | ||
@@ -22,3 +22,3 @@ "main": "src/index.js", | ||
"event-emitter": "^0.3.3", | ||
"immutable-store": "^0.5.1", | ||
"immutable-store": "^0.5.2", | ||
"jshint": "^2.6.0", | ||
@@ -28,4 +28,4 @@ "jshint-loader": "^0.8.2", | ||
"nodeunit-watcher": "0.0.3", | ||
"page": "^1.6.1", | ||
"react": "^0.13.3", | ||
"reactive-router": "^0.2.1", | ||
"style-loader": "^0.8.3", | ||
@@ -32,0 +32,0 @@ "todomvc-app-css": "^1.0.1", |
@@ -15,6 +15,7 @@ var utils = require('./utils.js'); | ||
var args = arguments.length === 1 ? [].slice.call(arguments) : [].slice.call(arguments).splice(1); | ||
var name = key.toLowerCase(); | ||
actions[actions.length - 1].mutations.push({ | ||
name: key.toLowerCase(), | ||
path: path.slice(), | ||
args: args | ||
name: name, | ||
path: name === 'unset' ? path.concat(args).slice() : path.slice(), | ||
args: name === 'unset' ? [] : args | ||
}); | ||
@@ -21,0 +22,0 @@ return options['on' + key] && options['on' + key].apply(null, [path].concat(args)); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2047936
25929