Commit ff2c87b4 authored by TasteBot's avatar TasteBot

update the build files for gh-pages [ci skip]

parent 3309651c
node_modules/director/*
node_modules/director/build/*
!node_modules/director/build
!node_modules/director/build/director.js
node_modules/react/*
!node_modules/react/dist
node_modules/react/dist/*
!node_modules/react/dist/react-with-addons.js
!node_modules/react/dist/JSXTransformer.js
node_modules/alt/*
!node_modules/alt/dist
node_modules/alt/dist/*
!node_modules/alt/dist/alt.js
node_modules/todomvc-app-css/*
!node_modules/todomvc-app-css/index.css
node_modules/todomvc-common/*
!node_modules/todomvc-common/base.css
!node_modules/todomvc-common/base.js
<!doctype html>
<html lang="en" data-framework="react">
<head>
<meta charset="utf-8">
<title>React + Alt • TodoMVC</title>
<link rel="stylesheet" href="node_modules/todomvc-common/base.css">
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
</head>
<body>
<section class="todoapp"></section>
<footer class="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://github.com/wishpishh">Hannes Johansson</a> based on React example by <a href="http://github.com/petehunt/">petehunt</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script src="node_modules/todomvc-common/base.js"></script>
<script src="node_modules/react/dist/react-with-addons.js"></script>
<script src="node_modules/react/dist/JSXTransformer.js"></script>
<script src="node_modules/director/build/director.js"></script>
<script src="node_modules/alt/dist/alt.js"></script>
<script src="js/utils.js"></script>
<script src="js/alt.js"></script>
<script src="js/actions/todoActions.js"></script>
<script src="js/stores/todoStore.js"></script>
<!-- jsx is an optional syntactic sugar that transforms methods in React's
`render` into an HTML-looking format. Since the two models above are
unrelated to React, we didn't need those transforms. -->
<script type="text/jsx" src="js/todoItem.jsx"></script>
<script type="text/jsx" src="js/footer.jsx"></script>
<script type="text/jsx" src="js/app.jsx"></script>
</body>
</html>
/*jshint quotmark:false */
/*jshint newcap:false */
var app = app || {};
(function () {
'use strict';
var Utils = app.Utils;
app.todoActions = app.alt.generateActions(
'toggleAll',
'toggle',
'destroy',
'save',
'clearCompleted',
'edit',
'show'
);
app.todoActions = Utils.extend(
app.todoActions,
app.alt.createActions({
addTodo: function (title) {
return {
id: Utils.uuid(),
title: title,
completed: false
};
}
})
);
})();
/*jshint quotmark:false */
/*jshint newcap:false */
/*global Alt */
var app = app || {};
(function () {
'use strict';
app.alt = new Alt();
})();
/*jshint quotmark:false */
/*jshint newcap:false */
/*global React, Router*/
var app = app || {};
(function () {
'use strict';
app.ALL_TODOS = 'all';
app.ACTIVE_TODOS = 'active';
app.COMPLETED_TODOS = 'completed';
var TodoFooter = app.TodoFooter;
var TodoItem = app.TodoItem;
var TodoActions = app.todoActions;
var TodoStore = app.todoStore;
var ENTER_KEY = 13;
var TodoApp = React.createClass({
getInitialState: function () {
return TodoStore.getState();
},
componentDidMount: function () {
TodoStore.listen(this.onStoreChange);
var router = Router({
'/': function () {
TodoActions.show(app.ALL_TODOS);
},
'/active': function () {
TodoActions.show(app.ACTIVE_TODOS);
},
'/completed': function () {
TodoActions.show(app.COMPLETED_TODOS);
}
});
router.init('/');
},
componentDidUnmount: function () {
TodoStore.unlisten(this.onStoreChange);
},
handleChange: function (event) {
this.setState({newTodo: event.target.value});
},
onStoreChange: function (state) {
this.setState(state);
},
handleNewTodoKeyDown: function (event) {
if (event.keyCode !== ENTER_KEY) {
return;
}
event.preventDefault();
var val = this.state.newTodo.trim();
if (val) {
this.setState({newTodo: ''});
TodoActions.addTodo(val);
}
},
toggleAll: function (event) {
var checked = event.target.checked;
TodoActions.toggleAll(checked);
},
toggle: function (todoToToggle) {
TodoActions.toggle(todoToToggle);
},
destroy: function (todo) {
TodoActions.destroy(todo);
},
edit: function (todo) {
TodoActions.edit(todo.id);
},
save: function (todoToSave, text) {
TodoActions.save({
todoToSave: todoToSave,
text: text
});
TodoActions.edit(null);
},
cancel: function () {
TodoActions.edit(null);
},
clearCompleted: function () {
TodoActions.clearCompleted();
},
render: function () {
var footer = null;
var main = null;
var todos = this.state.todos;
var shownTodos = todos.filter(function (todo) {
switch (this.state.nowShowing) {
case app.ACTIVE_TODOS:
return !todo.completed;
case app.COMPLETED_TODOS:
return todo.completed;
default:
return true;
}
}, this);
var todoItems = shownTodos.map(function (todo) {
return (
<TodoItem
key={todo.id}
todo={todo}
onToggle={this.toggle.bind(this, todo)}
onDestroy={this.destroy.bind(this, todo)}
onEdit={this.edit.bind(this, todo)}
editing={this.state.editing === todo.id}
onSave={this.save.bind(this, todo)}
onCancel={this.cancel}
/>
);
}, this);
var activeTodoCount = todos.reduce(function (accum, todo) {
return todo.completed ? accum : accum + 1;
}, 0);
var completedCount = todos.length - activeTodoCount;
if (activeTodoCount || completedCount) {
footer =
<TodoFooter
count={activeTodoCount}
completedCount={completedCount}
nowShowing={this.state.nowShowing}
onClearCompleted={this.clearCompleted}
/>;
}
if (todos.length) {
main = (
<section className="main">
<input
className="toggle-all"
type="checkbox"
onChange={this.toggleAll}
checked={activeTodoCount === 0}
/>
<ul className="todo-list">
{todoItems}
</ul>
</section>
);
}
return (
<div>
<header className="header">
<h1>todos</h1>
<input
ref="newField"
className="new-todo"
placeholder="What needs to be done?"
value={this.state.newTodo}
onKeyDown={this.handleNewTodoKeyDown}
onChange={this.handleChange}
autoFocus={true}
/>
</header>
{main}
{footer}
</div>
);
}
});
React.render(
<TodoApp/>,
document.getElementsByClassName('todoapp')[0]
);
})();
/*jshint quotmark:false */
/*jshint newcap:false */
/*global React */
var app = app || {};
(function () {
'use strict';
app.TodoFooter = React.createClass({
render: function () {
var activeTodoWord = app.Utils.pluralize(this.props.count, 'item');
var clearButton = null;
if (this.props.completedCount > 0) {
clearButton = (
<button
className="clear-completed"
onClick={this.props.onClearCompleted}>
Clear completed
</button>
);
}
// React idiom for shortcutting to `classSet` since it'll be used often
var cx = React.addons.classSet;
var nowShowing = this.props.nowShowing;
return (
<footer className="footer">
<span className="todo-count">
<strong>{this.props.count}</strong> {activeTodoWord} left
</span>
<ul className="filters">
<li>
<a
href="#/"
className={cx({selected: nowShowing === app.ALL_TODOS})}>
All
</a>
</li>
{' '}
<li>
<a
href="#/active"
className={cx({selected: nowShowing === app.ACTIVE_TODOS})}>
Active
</a>
</li>
{' '}
<li>
<a
href="#/completed"
className={cx({selected: nowShowing === app.COMPLETED_TODOS})}>
Completed
</a>
</li>
</ul>
{clearButton}
</footer>
);
}
});
})();
/*jshint quotmark:false */
/*jshint newcap:false */
var app = app || {};
(function () {
'use strict';
var Utils = app.Utils;
var LOCALSTORAGE_NAMESPACE = 'react-alt-todo';
var TodoStore = function () {
this.state = {
todos: Utils.store(LOCALSTORAGE_NAMESPACE + '.todos'),
nowShowing: Utils.store(LOCALSTORAGE_NAMESPACE + '.nowShowing') || app.ALL_TODOS,
editing: Utils.store(LOCALSTORAGE_NAMESPACE + '.editing') || null
};
this.bindListeners({
addTodo: app.todoActions.addTodo,
toggleAll: app.todoActions.toggleAll,
toggle: app.todoActions.toggle,
destroy: app.todoActions.destroy,
save: app.todoActions.save,
clearCompleted: app.todoActions.clearCompleted,
edit: app.todoActions.edit,
show: app.todoActions.show
});
};
TodoStore.prototype.addTodo = function (todo) {
this.setState({
todos: this.state.todos.concat(todo)
});
Utils.store(LOCALSTORAGE_NAMESPACE + '.todos', this.state.todos);
};
TodoStore.prototype.toggleAll = function (checked) {
var updatedTodos = this.state.todos.map(function (todo) {
return Utils.extend({}, todo, {completed: checked});
});
this.setState({
todos: updatedTodos
});
Utils.store(LOCALSTORAGE_NAMESPACE + '.todos', this.state.todos);
};
TodoStore.prototype.toggle = function (todoToToggle) {
var updatedTodos = this.state.todos.map(function (todo) {
return todo !== todoToToggle ?
todo :
Utils.extend({}, todo, {completed: !todo.completed});
});
this.setState({
todos: updatedTodos
});
Utils.store(LOCALSTORAGE_NAMESPACE + '.todos', this.state.todos);
};
TodoStore.prototype.destroy = function (todoToDestroy) {
var updatedTodos = this.state.todos.filter(function (todo) {
return todo !== todoToDestroy;
});
this.setState({
todos: updatedTodos
});
Utils.store(LOCALSTORAGE_NAMESPACE + '.todos', this.state.todos);
};
TodoStore.prototype.save = function (command) {
var updatedTodos = this.state.todos.map(function (todo) {
return todo !== command.todoToSave ?
todo :
Utils.extend({}, command.todoToSave, {title: command.text});
});
this.setState({
todos: updatedTodos
});
Utils.store(LOCALSTORAGE_NAMESPACE + '.todos', this.state.todos);
};
TodoStore.prototype.clearCompleted = function () {
var updatedTodos = this.state.todos.filter(function (todo) {
return !todo.completed;
});
this.setState({
todos: updatedTodos
});
Utils.store(LOCALSTORAGE_NAMESPACE + '.todos', this.state.todos);
};
TodoStore.prototype.edit = function (id) {
this.setState({
editing: id
});
Utils.store(LOCALSTORAGE_NAMESPACE + '.editing', this.editing);
};
TodoStore.prototype.show = function (nowShowing) {
this.setState({
nowShowing: nowShowing
});
Utils.store(LOCALSTORAGE_NAMESPACE + '.nowShowing', this.nowShowing);
};
TodoStore.displayName = 'TodoStore';
app.todoStore = app.alt.createStore(TodoStore);
})();
/*jshint quotmark: false */
/*jshint newcap: false */
/*global React */
var app = app || {};
(function () {
'use strict';
var ESCAPE_KEY = 27;
var ENTER_KEY = 13;
app.TodoItem = React.createClass({
handleSubmit: function (event) {
var val = this.state.editText.trim();
if (val) {
this.props.onSave(val);
this.setState({editText: val});
} else {
this.props.onDestroy();
}
},
handleEdit: function () {
this.props.onEdit();
this.setState({editText: this.props.todo.title});
},
handleKeyDown: function (event) {
if (event.which === ESCAPE_KEY) {
this.setState({editText: this.props.todo.title});
this.props.onCancel(event);
} else if (event.which === ENTER_KEY) {
this.handleSubmit(event);
}
},
handleChange: function (event) {
this.setState({editText: event.target.value});
},
getInitialState: function () {
return {editText: this.props.todo.title};
},
/**
* This is a completely optional performance enhancement that you can
* implement on any React component. If you were to delete this method
* the app would still work correctly (and still be very performant!), we
* just use it as an example of how little code it takes to get an order
* of magnitude performance improvement.
*/
shouldComponentUpdate: function (nextProps, nextState) {
return (
nextProps.todo !== this.props.todo ||
nextProps.editing !== this.props.editing ||
nextState.editText !== this.state.editText
);
},
/**
* Safely manipulate the DOM after updating the state when invoking
* `this.props.onEdit()` in the `handleEdit` method above.
* For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate
* and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate
*/
componentDidUpdate: function (prevProps) {
if (!prevProps.editing && this.props.editing) {
var node = React.findDOMNode(this.refs.editField);
node.focus();
node.setSelectionRange(node.value.length, node.value.length);
}
},
render: function () {
return (
<li className={React.addons.classSet({
completed: this.props.todo.completed,
editing: this.props.editing
})}>
<div className="view">
<input
className="toggle"
type="checkbox"
checked={this.props.todo.completed}
onChange={this.props.onToggle}
/>
<label onDoubleClick={this.handleEdit}>
{this.props.todo.title}
</label>
<button className="destroy" onClick={this.props.onDestroy} />
</div>
<input
ref="editField"
className="edit"
value={this.state.editText}
onBlur={this.handleSubmit}
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
/>
</li>
);
}
});
})();
var app = app || {};
(function () {
'use strict';
app.Utils = {
uuid: function () {
/*jshint bitwise:false */
var i, random;
var uuid = '';
for (i = 0; i < 32; i++) {
random = Math.random() * 16 | 0;
if (i === 8 || i === 12 || i === 16 || i === 20) {
uuid += '-';
}
uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random))
.toString(16);
}
return uuid;
},
pluralize: function (count, word) {
return count === 1 ? word : word + 's';
},
store: function (namespace, data) {
if (data) {
return localStorage.setItem(namespace, JSON.stringify(data));
}
var store = localStorage.getItem(namespace);
return (store && JSON.parse(store)) || [];
},
extend: function () {
var newObj = {};
for (var i = 0; i < arguments.length; i++) {
var obj = arguments[i];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
}
return newObj;
}
};
})();
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["Alt"] = factory();
else
root["Alt"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(1);
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
/* global window */
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
var _bind = Function.prototype.bind;
var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var _flux = __webpack_require__(2);
var _utilsStateFunctions = __webpack_require__(5);
var StateFunctions = _interopRequireWildcard(_utilsStateFunctions);
var _utilsFunctions = __webpack_require__(6);
var fn = _interopRequireWildcard(_utilsFunctions);
var _store = __webpack_require__(7);
var store = _interopRequireWildcard(_store);
var _utilsAltUtils = __webpack_require__(8);
var utils = _interopRequireWildcard(_utilsAltUtils);
var _actions = __webpack_require__(12);
var _actions2 = _interopRequireDefault(_actions);
var Alt = (function () {
function Alt() {
var config = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
_classCallCheck(this, Alt);
this.config = config;
this.serialize = config.serialize || JSON.stringify;
this.deserialize = config.deserialize || JSON.parse;
this.dispatcher = config.dispatcher || new _flux.Dispatcher();
this.batchingFunction = config.batchingFunction || function (callback) {
return callback();
};
this.actions = { global: {} };
this.stores = {};
this.storeTransforms = config.storeTransforms || [];
this.trapAsync = false;
this._actionsRegistry = {};
this._initSnapshot = {};
this._lastSnapshot = {};
}
_createClass(Alt, [{
key: 'dispatch',
value: function dispatch(action, data, details) {
var _this = this;
this.batchingFunction(function () {
var id = Math.random().toString(18).substr(2, 16);
if (action.id && action.dispatch) {
return utils.dispatch(id, action, data, _this);
}
return _this.dispatcher.dispatch({
id: id,
action: action,
data: data,
details: details
});
});
}
}, {
key: 'createUnsavedStore',
value: function createUnsavedStore(StoreModel) {
var key = StoreModel.displayName || '';
store.createStoreConfig(this.config, StoreModel);
var Store = store.transformStore(this.storeTransforms, StoreModel);
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return fn.isFunction(Store) ? store.createStoreFromClass.apply(store, [this, Store, key].concat(args)) : store.createStoreFromObject(this, Store, key);
}
}, {
key: 'createStore',
value: function createStore(StoreModel, iden) {
var key = iden || StoreModel.displayName || StoreModel.name || '';
store.createStoreConfig(this.config, StoreModel);
var Store = store.transformStore(this.storeTransforms, StoreModel);
/* istanbul ignore next */
if (false) delete this.stores[key];
if (this.stores[key] || !key) {
if (this.stores[key]) {
utils.warn('A store named ' + key + ' already exists, double check your store ' + 'names or pass in your own custom identifier for each store');
} else {
utils.warn('Store name was not specified');
}
key = utils.uid(this.stores, key);
}
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
args[_key2 - 2] = arguments[_key2];
}
var storeInstance = fn.isFunction(Store) ? store.createStoreFromClass.apply(store, [this, Store, key].concat(args)) : store.createStoreFromObject(this, Store, key);
this.stores[key] = storeInstance;
StateFunctions.saveInitialSnapshot(this, key);
return storeInstance;
}
}, {
key: 'generateActions',
value: function generateActions() {
var actions = { name: 'global' };
for (var _len3 = arguments.length, actionNames = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
actionNames[_key3] = arguments[_key3];
}
return this.createActions(actionNames.reduce(function (obj, action) {
obj[action] = utils.dispatchIdentity;
return obj;
}, actions));
}
}, {
key: 'createAction',
value: function createAction(name, implementation, obj) {
return (0, _actions2['default'])(this, 'global', name, implementation, obj);
}
}, {
key: 'createActions',
value: function createActions(ActionsClass) {
var _arguments2 = arguments,
_this2 = this;
var exportObj = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var actions = {};
var key = utils.uid(this._actionsRegistry, ActionsClass.displayName || ActionsClass.name || 'Unknown');
if (fn.isFunction(ActionsClass)) {
var _len4, argsForConstructor, _key4;
(function () {
fn.assign(actions, utils.getInternalMethods(ActionsClass, true));
var ActionsGenerator = (function (_ActionsClass) {
_inherits(ActionsGenerator, _ActionsClass);
function ActionsGenerator() {
_classCallCheck(this, ActionsGenerator);
for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
args[_key5] = arguments[_key5];
}
_get(Object.getPrototypeOf(ActionsGenerator.prototype), 'constructor', this).apply(this, args);
}
_createClass(ActionsGenerator, [{
key: 'generateActions',
value: function generateActions() {
for (var _len6 = arguments.length, actionNames = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
actionNames[_key6] = arguments[_key6];
}
actionNames.forEach(function (actionName) {
actions[actionName] = utils.dispatchIdentity;
});
}
}]);
return ActionsGenerator;
})(ActionsClass);
for (_len4 = _arguments2.length, argsForConstructor = Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {
argsForConstructor[_key4 - 2] = _arguments2[_key4];
}
fn.assign(actions, new (_bind.apply(ActionsGenerator, [null].concat(_toConsumableArray(argsForConstructor))))());
})();
} else {
fn.assign(actions, ActionsClass);
}
this.actions[key] = this.actions[key] || {};
fn.eachObject(function (actionName, action) {
if (!fn.isFunction(action)) {
return;
}
// create the action
exportObj[actionName] = (0, _actions2['default'])(_this2, key, actionName, action, exportObj);
// generate a constant
var constant = utils.formatAsConstant(actionName);
exportObj[constant] = exportObj[actionName].id;
}, [actions]);
return exportObj;
}
}, {
key: 'takeSnapshot',
value: function takeSnapshot() {
for (var _len7 = arguments.length, storeNames = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
storeNames[_key7] = arguments[_key7];
}
var state = StateFunctions.snapshot(this, storeNames);
fn.assign(this._lastSnapshot, state);
return this.serialize(state);
}
}, {
key: 'rollback',
value: function rollback() {
StateFunctions.setAppState(this, this.serialize(this._lastSnapshot), function (storeInst) {
storeInst.lifecycle('rollback');
storeInst.emitChange();
});
}
}, {
key: 'recycle',
value: function recycle() {
for (var _len8 = arguments.length, storeNames = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
storeNames[_key8] = arguments[_key8];
}
var initialSnapshot = storeNames.length ? StateFunctions.filterSnapshots(this, this._initSnapshot, storeNames) : this._initSnapshot;
StateFunctions.setAppState(this, this.serialize(initialSnapshot), function (storeInst) {
storeInst.lifecycle('init');
storeInst.emitChange();
});
}
}, {
key: 'flush',
value: function flush() {
var state = this.serialize(StateFunctions.snapshot(this));
this.recycle();
return state;
}
}, {
key: 'bootstrap',
value: function bootstrap(data) {
StateFunctions.setAppState(this, data, function (storeInst, state) {
storeInst.lifecycle('bootstrap', state);
storeInst.emitChange();
});
}
}, {
key: 'prepare',
value: function prepare(storeInst, payload) {
var data = {};
if (!storeInst.displayName) {
throw new ReferenceError('Store provided does not have a name');
}
data[storeInst.displayName] = payload;
return this.serialize(data);
}
// Instance type methods for injecting alt into your application as context
}, {
key: 'addActions',
value: function addActions(name, ActionsClass) {
for (var _len9 = arguments.length, args = Array(_len9 > 2 ? _len9 - 2 : 0), _key9 = 2; _key9 < _len9; _key9++) {
args[_key9 - 2] = arguments[_key9];
}
this.actions[name] = Array.isArray(ActionsClass) ? this.generateActions.apply(this, ActionsClass) : this.createActions.apply(this, [ActionsClass].concat(args));
}
}, {
key: 'addStore',
value: function addStore(name, StoreModel) {
for (var _len10 = arguments.length, args = Array(_len10 > 2 ? _len10 - 2 : 0), _key10 = 2; _key10 < _len10; _key10++) {
args[_key10 - 2] = arguments[_key10];
}
this.createStore.apply(this, [StoreModel, name].concat(args));
}
}, {
key: 'getActions',
value: function getActions(name) {
return this.actions[name];
}
}, {
key: 'getStore',
value: function getStore(name) {
return this.stores[name];
}
}], [{
key: 'debug',
value: function debug(name, alt) {
var key = 'alt.js.org';
if (typeof window !== 'undefined') {
window[key] = window[key] || [];
window[key].push({ name: name, alt: alt });
}
return alt;
}
}]);
return Alt;
})();
exports['default'] = Alt;
module.exports = exports['default'];
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
/**
* Copyright (c) 2014-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
module.exports.Dispatcher = __webpack_require__(3)
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
/*
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule Dispatcher
* @typechecks
*/
"use strict";
var invariant = __webpack_require__(4);
var _lastID = 1;
var _prefix = 'ID_';
/**
* Dispatcher is used to broadcast payloads to registered callbacks. This is
* different from generic pub-sub systems in two ways:
*
* 1) Callbacks are not subscribed to particular events. Every payload is
* dispatched to every registered callback.
* 2) Callbacks can be deferred in whole or part until other callbacks have
* been executed.
*
* For example, consider this hypothetical flight destination form, which
* selects a default city when a country is selected:
*
* var flightDispatcher = new Dispatcher();
*
* // Keeps track of which country is selected
* var CountryStore = {country: null};
*
* // Keeps track of which city is selected
* var CityStore = {city: null};
*
* // Keeps track of the base flight price of the selected city
* var FlightPriceStore = {price: null}
*
* When a user changes the selected city, we dispatch the payload:
*
* flightDispatcher.dispatch({
* actionType: 'city-update',
* selectedCity: 'paris'
* });
*
* This payload is digested by `CityStore`:
*
* flightDispatcher.register(function(payload) {
* if (payload.actionType === 'city-update') {
* CityStore.city = payload.selectedCity;
* }
* });
*
* When the user selects a country, we dispatch the payload:
*
* flightDispatcher.dispatch({
* actionType: 'country-update',
* selectedCountry: 'australia'
* });
*
* This payload is digested by both stores:
*
* CountryStore.dispatchToken = flightDispatcher.register(function(payload) {
* if (payload.actionType === 'country-update') {
* CountryStore.country = payload.selectedCountry;
* }
* });
*
* When the callback to update `CountryStore` is registered, we save a reference
* to the returned token. Using this token with `waitFor()`, we can guarantee
* that `CountryStore` is updated before the callback that updates `CityStore`
* needs to query its data.
*
* CityStore.dispatchToken = flightDispatcher.register(function(payload) {
* if (payload.actionType === 'country-update') {
* // `CountryStore.country` may not be updated.
* flightDispatcher.waitFor([CountryStore.dispatchToken]);
* // `CountryStore.country` is now guaranteed to be updated.
*
* // Select the default city for the new country
* CityStore.city = getDefaultCityForCountry(CountryStore.country);
* }
* });
*
* The usage of `waitFor()` can be chained, for example:
*
* FlightPriceStore.dispatchToken =
* flightDispatcher.register(function(payload) {
* switch (payload.actionType) {
* case 'country-update':
* flightDispatcher.waitFor([CityStore.dispatchToken]);
* FlightPriceStore.price =
* getFlightPriceStore(CountryStore.country, CityStore.city);
* break;
*
* case 'city-update':
* FlightPriceStore.price =
* FlightPriceStore(CountryStore.country, CityStore.city);
* break;
* }
* });
*
* The `country-update` payload will be guaranteed to invoke the stores'
* registered callbacks in order: `CountryStore`, `CityStore`, then
* `FlightPriceStore`.
*/
function Dispatcher() {
this.$Dispatcher_callbacks = {};
this.$Dispatcher_isPending = {};
this.$Dispatcher_isHandled = {};
this.$Dispatcher_isDispatching = false;
this.$Dispatcher_pendingPayload = null;
}
/**
* Registers a callback to be invoked with every dispatched payload. Returns
* a token that can be used with `waitFor()`.
*
* @param {function} callback
* @return {string}
*/
Dispatcher.prototype.register=function(callback) {
var id = _prefix + _lastID++;
this.$Dispatcher_callbacks[id] = callback;
return id;
};
/**
* Removes a callback based on its token.
*
* @param {string} id
*/
Dispatcher.prototype.unregister=function(id) {
invariant(
this.$Dispatcher_callbacks[id],
'Dispatcher.unregister(...): `%s` does not map to a registered callback.',
id
);
delete this.$Dispatcher_callbacks[id];
};
/**
* Waits for the callbacks specified to be invoked before continuing execution
* of the current callback. This method should only be used by a callback in
* response to a dispatched payload.
*
* @param {array<string>} ids
*/
Dispatcher.prototype.waitFor=function(ids) {
invariant(
this.$Dispatcher_isDispatching,
'Dispatcher.waitFor(...): Must be invoked while dispatching.'
);
for (var ii = 0; ii < ids.length; ii++) {
var id = ids[ii];
if (this.$Dispatcher_isPending[id]) {
invariant(
this.$Dispatcher_isHandled[id],
'Dispatcher.waitFor(...): Circular dependency detected while ' +
'waiting for `%s`.',
id
);
continue;
}
invariant(
this.$Dispatcher_callbacks[id],
'Dispatcher.waitFor(...): `%s` does not map to a registered callback.',
id
);
this.$Dispatcher_invokeCallback(id);
}
};
/**
* Dispatches a payload to all registered callbacks.
*
* @param {object} payload
*/
Dispatcher.prototype.dispatch=function(payload) {
invariant(
!this.$Dispatcher_isDispatching,
'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.'
);
this.$Dispatcher_startDispatching(payload);
try {
for (var id in this.$Dispatcher_callbacks) {
if (this.$Dispatcher_isPending[id]) {
continue;
}
this.$Dispatcher_invokeCallback(id);
}
} finally {
this.$Dispatcher_stopDispatching();
}
};
/**
* Is this Dispatcher currently dispatching.
*
* @return {boolean}
*/
Dispatcher.prototype.isDispatching=function() {
return this.$Dispatcher_isDispatching;
};
/**
* Call the callback stored with the given id. Also do some internal
* bookkeeping.
*
* @param {string} id
* @internal
*/
Dispatcher.prototype.$Dispatcher_invokeCallback=function(id) {
this.$Dispatcher_isPending[id] = true;
this.$Dispatcher_callbacks[id](this.$Dispatcher_pendingPayload);
this.$Dispatcher_isHandled[id] = true;
};
/**
* Set up bookkeeping needed when dispatching.
*
* @param {object} payload
* @internal
*/
Dispatcher.prototype.$Dispatcher_startDispatching=function(payload) {
for (var id in this.$Dispatcher_callbacks) {
this.$Dispatcher_isPending[id] = false;
this.$Dispatcher_isHandled[id] = false;
}
this.$Dispatcher_pendingPayload = payload;
this.$Dispatcher_isDispatching = true;
};
/**
* Clear bookkeeping used for dispatching.
*
* @internal
*/
Dispatcher.prototype.$Dispatcher_stopDispatching=function() {
this.$Dispatcher_pendingPayload = null;
this.$Dispatcher_isDispatching = false;
};
module.exports = Dispatcher;
/***/ },
/* 4 */
/***/ function(module, exports) {
/**
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule invariant
*/
"use strict";
/**
* Use invariant() to assert state which your program assumes to be true.
*
* Provide sprintf-style format (only %s is supported) and arguments
* to provide information about what broke and what you were
* expecting.
*
* The invariant message will be stripped in production, but the invariant
* will remain to ensure logic does not differ in production.
*/
var invariant = function(condition, format, a, b, c, d, e, f) {
if (false) {
if (format === undefined) {
throw new Error('invariant requires an error message argument');
}
}
if (!condition) {
var error;
if (format === undefined) {
error = new Error(
'Minified exception occurred; use the non-minified dev environment ' +
'for the full error message and additional helpful warnings.'
);
} else {
var args = [a, b, c, d, e, f];
var argIndex = 0;
error = new Error(
'Invariant Violation: ' +
format.replace(/%s/g, function() { return args[argIndex++]; })
);
}
error.framesToPop = 1; // we don't care about invariant's own frame
throw error;
}
};
module.exports = invariant;
/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports.setAppState = setAppState;
exports.snapshot = snapshot;
exports.saveInitialSnapshot = saveInitialSnapshot;
exports.filterSnapshots = filterSnapshots;
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
var _utilsFunctions = __webpack_require__(6);
var fn = _interopRequireWildcard(_utilsFunctions);
function setAppState(instance, data, onStore) {
var obj = instance.deserialize(data);
fn.eachObject(function (key, value) {
var store = instance.stores[key];
if (store) {
(function () {
var config = store.StoreModel.config;
var state = store.state;
if (config.onDeserialize) obj[key] = config.onDeserialize(value) || value;
if (fn.isPojo(state)) {
fn.eachObject(function (k) {
return delete state[k];
}, [state]);
fn.assign(state, obj[key]);
} else {
store.state = obj[key];
}
onStore(store, store.state);
})();
}
}, [obj]);
}
function snapshot(instance) {
var storeNames = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];
var stores = storeNames.length ? storeNames : Object.keys(instance.stores);
return stores.reduce(function (obj, storeHandle) {
var storeName = storeHandle.displayName || storeHandle;
var store = instance.stores[storeName];
var config = store.StoreModel.config;
store.lifecycle('snapshot');
var customSnapshot = config.onSerialize && config.onSerialize(store.state);
obj[storeName] = customSnapshot ? customSnapshot : store.getState();
return obj;
}, {});
}
function saveInitialSnapshot(instance, key) {
var state = instance.deserialize(instance.serialize(instance.stores[key].state));
instance._initSnapshot[key] = state;
instance._lastSnapshot[key] = state;
}
function filterSnapshots(instance, state, stores) {
return stores.reduce(function (obj, store) {
var storeName = store.displayName || store;
if (!state[storeName]) {
throw new ReferenceError(storeName + ' is not a valid store');
}
obj[storeName] = state[storeName];
return obj;
}, {});
}
/***/ },
/* 6 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports.isPojo = isPojo;
exports.isPromise = isPromise;
exports.eachObject = eachObject;
exports.assign = assign;
var isFunction = function isFunction(x) {
return typeof x === 'function';
};
exports.isFunction = isFunction;
function isPojo(target) {
var Ctor = target.constructor;
return !!target && typeof target === 'object' && Object.prototype.toString.call(target) === '[object Object]' && isFunction(Ctor) && (Ctor instanceof Ctor || target.type === 'AltStore');
}
function isPromise(obj) {
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
}
function eachObject(f, o) {
o.forEach(function (from) {
Object.keys(Object(from)).forEach(function (key) {
f(key, from[key]);
});
});
}
function assign(target) {
for (var _len = arguments.length, source = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
source[_key - 1] = arguments[_key];
}
eachObject(function (key, value) {
return target[key] = value;
}, source);
return target;
}
/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
var _bind = Function.prototype.bind;
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
exports.createStoreConfig = createStoreConfig;
exports.transformStore = transformStore;
exports.createStoreFromObject = createStoreFromObject;
exports.createStoreFromClass = createStoreFromClass;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var _utilsAltUtils = __webpack_require__(8);
var utils = _interopRequireWildcard(_utilsAltUtils);
var _utilsFunctions = __webpack_require__(6);
var fn = _interopRequireWildcard(_utilsFunctions);
var _AltStore = __webpack_require__(9);
var _AltStore2 = _interopRequireDefault(_AltStore);
var _StoreMixin = __webpack_require__(11);
var _StoreMixin2 = _interopRequireDefault(_StoreMixin);
function doSetState(store, storeInstance, state) {
if (!state) {
return;
}
var config = storeInstance.StoreModel.config;
var nextState = fn.isFunction(state) ? state(storeInstance.state) : state;
storeInstance.state = config.setState.call(store, storeInstance.state, nextState);
if (!store.alt.dispatcher.isDispatching()) {
store.emitChange();
}
}
function createPrototype(proto, alt, key, extras) {
return fn.assign(proto, _StoreMixin2['default'], {
displayName: key,
alt: alt,
dispatcher: alt.dispatcher,
preventDefault: function preventDefault() {
this.getInstance().preventDefault = true;
},
boundListeners: [],
lifecycleEvents: {},
actionListeners: {},
publicMethods: {},
handlesOwnErrors: false
}, extras);
}
function createStoreConfig(globalConfig, StoreModel) {
StoreModel.config = fn.assign({
getState: function getState(state) {
if (Array.isArray(state)) {
return state.slice();
} else if (fn.isPojo(state)) {
return fn.assign({}, state);
}
return state;
},
setState: function setState(currentState, nextState) {
if (fn.isPojo(nextState)) {
return fn.assign(currentState, nextState);
}
return nextState;
}
}, globalConfig, StoreModel.config);
}
function transformStore(transforms, StoreModel) {
return transforms.reduce(function (Store, transform) {
return transform(Store);
}, StoreModel);
}
function createStoreFromObject(alt, StoreModel, key) {
var storeInstance = undefined;
var StoreProto = createPrototype({}, alt, key, fn.assign({
getInstance: function getInstance() {
return storeInstance;
},
setState: function setState(nextState) {
doSetState(this, storeInstance, nextState);
}
}, StoreModel));
// bind the store listeners
/* istanbul ignore else */
if (StoreProto.bindListeners) {
_StoreMixin2['default'].bindListeners.call(StoreProto, StoreProto.bindListeners);
}
/* istanbul ignore else */
if (StoreProto.observe) {
_StoreMixin2['default'].bindListeners.call(StoreProto, StoreProto.observe(alt));
}
// bind the lifecycle events
/* istanbul ignore else */
if (StoreProto.lifecycle) {
fn.eachObject(function (eventName, event) {
_StoreMixin2['default'].on.call(StoreProto, eventName, event);
}, [StoreProto.lifecycle]);
}
// create the instance and fn.assign the public methods to the instance
storeInstance = fn.assign(new _AltStore2['default'](alt, StoreProto, StoreProto.state !== undefined ? StoreProto.state : {}, StoreModel), StoreProto.publicMethods, { displayName: key });
return storeInstance;
}
function createStoreFromClass(alt, StoreModel, key) {
var storeInstance = undefined;
var config = StoreModel.config;
// Creating a class here so we don't overload the provided store's
// prototype with the mixin behaviour and I'm extending from StoreModel
// so we can inherit any extensions from the provided store.
var Store = (function (_StoreModel) {
_inherits(Store, _StoreModel);
function Store() {
_classCallCheck(this, Store);
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
_get(Object.getPrototypeOf(Store.prototype), 'constructor', this).apply(this, args);
}
return Store;
})(StoreModel);
createPrototype(Store.prototype, alt, key, {
type: 'AltStore',
getInstance: function getInstance() {
return storeInstance;
},
setState: function setState(nextState) {
doSetState(this, storeInstance, nextState);
}
});
for (var _len = arguments.length, argsForClass = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
argsForClass[_key - 3] = arguments[_key];
}
var store = new (_bind.apply(Store, [null].concat(argsForClass)))();
if (config.bindListeners) store.bindListeners(config.bindListeners);
if (config.datasource) store.registerAsync(config.datasource);
storeInstance = fn.assign(new _AltStore2['default'](alt, store, store.state !== undefined ? store.state : store, StoreModel), utils.getInternalMethods(StoreModel), config.publicMethods, { displayName: key });
return storeInstance;
}
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports.getInternalMethods = getInternalMethods;
exports.warn = warn;
exports.uid = uid;
exports.formatAsConstant = formatAsConstant;
exports.dispatchIdentity = dispatchIdentity;
exports.dispatch = dispatch;
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
var _utilsFunctions = __webpack_require__(6);
var fn = _interopRequireWildcard(_utilsFunctions);
/*eslint-disable*/
var builtIns = Object.getOwnPropertyNames(NoopClass);
var builtInProto = Object.getOwnPropertyNames(NoopClass.prototype);
/*eslint-enable*/
function getInternalMethods(Obj, isProto) {
var excluded = isProto ? builtInProto : builtIns;
var obj = isProto ? Obj.prototype : Obj;
return Object.getOwnPropertyNames(obj).reduce(function (value, m) {
if (excluded.indexOf(m) !== -1) {
return value;
}
value[m] = obj[m];
return value;
}, {});
}
function warn(msg) {
/* istanbul ignore else */
/*eslint-disable*/
if (typeof console !== 'undefined') {
console.warn(new ReferenceError(msg));
}
/*eslint-enable*/
}
function uid(container, name) {
var count = 0;
var key = name;
while (Object.hasOwnProperty.call(container, key)) {
key = name + String(++count);
}
return key;
}
function formatAsConstant(name) {
return name.replace(/[a-z]([A-Z])/g, function (i) {
return i[0] + '_' + i[1].toLowerCase();
}).toUpperCase();
}
function dispatchIdentity(x) {
for (var _len = arguments.length, a = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
a[_key - 1] = arguments[_key];
}
this.dispatch(a.length ? [x].concat(a) : x);
}
function dispatch(id, actionObj, payload, alt) {
var data = actionObj.dispatch(payload);
if (data === undefined) return null;
var type = actionObj.id;
var namespace = type;
var name = type;
var details = { id: type, namespace: namespace, name: name };
var dispatchLater = function dispatchLater(x) {
return alt.dispatch(type, x, details);
};
if (fn.isFunction(data)) return data(dispatchLater, alt);
return alt.dispatcher.dispatch({
id: id,
action: type,
data: data,
details: details
});
}
/* istanbul ignore next */
function NoopClass() {}
/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var _utilsFunctions = __webpack_require__(6);
var fn = _interopRequireWildcard(_utilsFunctions);
var _transmitter = __webpack_require__(10);
var _transmitter2 = _interopRequireDefault(_transmitter);
var AltStore = (function () {
function AltStore(alt, model, state, StoreModel) {
var _this = this;
_classCallCheck(this, AltStore);
var lifecycleEvents = model.lifecycleEvents;
this.transmitter = (0, _transmitter2['default'])();
this.lifecycle = function (event, x) {
if (lifecycleEvents[event]) lifecycleEvents[event].push(x);
};
this.state = state;
this.alt = alt;
this.preventDefault = false;
this.displayName = model.displayName;
this.boundListeners = model.boundListeners;
this.StoreModel = StoreModel;
this.reduce = model.reduce || function (x) {
return x;
};
var output = model.output || function (x) {
return x;
};
this.emitChange = function () {
return _this.transmitter.push(output(_this.state));
};
var handleDispatch = function handleDispatch(f, payload) {
try {
return f();
} catch (e) {
if (model.handlesOwnErrors) {
_this.lifecycle('error', {
error: e,
payload: payload,
state: _this.state
});
return false;
}
throw e;
}
};
fn.assign(this, model.publicMethods);
// Register dispatcher
this.dispatchToken = alt.dispatcher.register(function (payload) {
_this.preventDefault = false;
_this.lifecycle('beforeEach', {
payload: payload,
state: _this.state
});
var actionHandlers = model.actionListeners[payload.action];
if (actionHandlers || model.otherwise) {
var result = undefined;
if (actionHandlers) {
result = handleDispatch(function () {
return actionHandlers.filter(Boolean).every(function (handler) {
return handler.call(model, payload.data, payload.action) !== false;
});
}, payload);
} else {
result = handleDispatch(function () {
return model.otherwise(payload.data, payload.action);
}, payload);
}
if (result !== false && !_this.preventDefault) _this.emitChange();
}
if (model.reduce) {
handleDispatch(function () {
_this.state = model.reduce(_this.state, payload);
}, payload);
if (!_this.preventDefault) _this.emitChange();
}
_this.lifecycle('afterEach', {
payload: payload,
state: _this.state
});
});
this.lifecycle('init');
}
_createClass(AltStore, [{
key: 'listen',
value: function listen(cb) {
var _this2 = this;
if (!fn.isFunction(cb)) throw new TypeError('listen expects a function');
this.transmitter.subscribe(cb);
return function () {
return _this2.unlisten(cb);
};
}
}, {
key: 'unlisten',
value: function unlisten(cb) {
this.lifecycle('unlisten');
this.transmitter.unsubscribe(cb);
}
}, {
key: 'getState',
value: function getState() {
return this.StoreModel.config.getState.call(this, this.state);
}
}]);
return AltStore;
})();
exports['default'] = AltStore;
module.exports = exports['default'];
/***/ },
/* 10 */
/***/ function(module, exports) {
"use strict";
function transmitter() {
var subscriptions = [];
var unsubscribe = function unsubscribe(onChange) {
var id = subscriptions.indexOf(onChange);
if (id >= 0) subscriptions.splice(id, 1);
};
var subscribe = function subscribe(onChange) {
subscriptions.push(onChange);
var dispose = function dispose() {
return unsubscribe(onChange);
};
return { dispose: dispose };
};
var push = function push(value) {
subscriptions.forEach(function (subscription) {
return subscription(value);
});
};
return { subscribe: subscribe, push: push, unsubscribe: unsubscribe };
}
module.exports = transmitter;
/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _transmitter = __webpack_require__(10);
var _transmitter2 = _interopRequireDefault(_transmitter);
var _utilsFunctions = __webpack_require__(6);
var fn = _interopRequireWildcard(_utilsFunctions);
var StoreMixin = {
waitFor: function waitFor() {
for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
sources[_key] = arguments[_key];
}
if (!sources.length) {
throw new ReferenceError('Dispatch tokens not provided');
}
var sourcesArray = sources;
if (sources.length === 1) {
sourcesArray = Array.isArray(sources[0]) ? sources[0] : sources;
}
var tokens = sourcesArray.map(function (source) {
return source.dispatchToken || source;
});
this.dispatcher.waitFor(tokens);
},
exportAsync: function exportAsync(asyncMethods) {
this.registerAsync(asyncMethods);
},
registerAsync: function registerAsync(asyncDef) {
var _this = this;
var loadCounter = 0;
var asyncMethods = fn.isFunction(asyncDef) ? asyncDef(this.alt) : asyncDef;
var toExport = Object.keys(asyncMethods).reduce(function (publicMethods, methodName) {
var desc = asyncMethods[methodName];
var spec = fn.isFunction(desc) ? desc(_this) : desc;
var validHandlers = ['success', 'error', 'loading'];
validHandlers.forEach(function (handler) {
if (spec[handler] && !spec[handler].id) {
throw new Error(handler + ' handler must be an action function');
}
});
publicMethods[methodName] = function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
var state = _this.getInstance().getState();
var value = spec.local && spec.local.apply(spec, [state].concat(args));
var shouldFetch = spec.shouldFetch ? spec.shouldFetch.apply(spec, [state].concat(args))
/*eslint-disable*/
: value == null;
/*eslint-enable*/
var intercept = spec.interceptResponse || function (x) {
return x;
};
var makeActionHandler = function makeActionHandler(action, isError) {
return function (x) {
var fire = function fire() {
loadCounter -= 1;
action(intercept(x, action, args));
if (isError) throw x;
};
return _this.alt.trapAsync ? function () {
return fire();
} : fire();
};
};
// if we don't have it in cache then fetch it
if (shouldFetch) {
loadCounter += 1;
/* istanbul ignore else */
if (spec.loading) spec.loading(intercept(null, spec.loading, args));
return spec.remote.apply(spec, [state].concat(args)).then(makeActionHandler(spec.success), makeActionHandler(spec.error, 1));
}
// otherwise emit the change now
_this.emitChange();
return value;
};
return publicMethods;
}, {});
this.exportPublicMethods(toExport);
this.exportPublicMethods({
isLoading: function isLoading() {
return loadCounter > 0;
}
});
},
exportPublicMethods: function exportPublicMethods(methods) {
var _this2 = this;
fn.eachObject(function (methodName, value) {
if (!fn.isFunction(value)) {
throw new TypeError('exportPublicMethods expects a function');
}
_this2.publicMethods[methodName] = value;
}, [methods]);
},
emitChange: function emitChange() {
this.getInstance().emitChange();
},
on: function on(lifecycleEvent, handler) {
if (lifecycleEvent === 'error') this.handlesOwnErrors = true;
var bus = this.lifecycleEvents[lifecycleEvent] || (0, _transmitter2['default'])();
this.lifecycleEvents[lifecycleEvent] = bus;
return bus.subscribe(handler.bind(this));
},
bindAction: function bindAction(symbol, handler) {
if (!symbol) {
throw new ReferenceError('Invalid action reference passed in');
}
if (!fn.isFunction(handler)) {
throw new TypeError('bindAction expects a function');
}
if (handler.length > 1) {
throw new TypeError('Action handler in store ' + this.displayName + ' for ' + ((symbol.id || symbol).toString() + ' was defined with ') + 'two parameters. Only a single parameter is passed through the ' + 'dispatcher, did you mean to pass in an Object instead?');
}
// You can pass in the constant or the function itself
var key = symbol.id ? symbol.id : symbol;
this.actionListeners[key] = this.actionListeners[key] || [];
this.actionListeners[key].push(handler.bind(this));
this.boundListeners.push(key);
},
bindActions: function bindActions(actions) {
var _this3 = this;
fn.eachObject(function (action, symbol) {
var matchFirstCharacter = /./;
var assumedEventHandler = action.replace(matchFirstCharacter, function (x) {
return 'on' + x[0].toUpperCase();
});
if (_this3[action] && _this3[assumedEventHandler]) {
// If you have both action and onAction
throw new ReferenceError('You have multiple action handlers bound to an action: ' + (action + ' and ' + assumedEventHandler));
}
var handler = _this3[action] || _this3[assumedEventHandler];
if (handler) {
_this3.bindAction(symbol, handler);
}
}, [actions]);
},
bindListeners: function bindListeners(obj) {
var _this4 = this;
fn.eachObject(function (methodName, symbol) {
var listener = _this4[methodName];
if (!listener) {
throw new ReferenceError(methodName + ' defined but does not exist in ' + _this4.displayName);
}
if (Array.isArray(symbol)) {
symbol.forEach(function (action) {
_this4.bindAction(action, listener);
});
} else {
_this4.bindAction(symbol, listener);
}
}, [obj]);
}
};
exports['default'] = StoreMixin;
module.exports = exports['default'];
/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
exports['default'] = makeAction;
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var _utilsFunctions = __webpack_require__(6);
var fn = _interopRequireWildcard(_utilsFunctions);
var _utilsAltUtils = __webpack_require__(8);
var utils = _interopRequireWildcard(_utilsAltUtils);
var AltAction = (function () {
function AltAction(alt, id, action, actions, actionDetails) {
_classCallCheck(this, AltAction);
this.id = id;
this._dispatch = action.bind(this);
this.actions = actions;
this.actionDetails = actionDetails;
this.alt = alt;
}
_createClass(AltAction, [{
key: 'dispatch',
value: function dispatch(data) {
this.dispatched = true;
this.alt.dispatch(this.id, data, this.actionDetails);
}
}]);
return AltAction;
})();
function makeAction(alt, namespace, name, implementation, obj) {
var id = utils.uid(alt._actionsRegistry, namespace + '.' + name);
alt._actionsRegistry[id] = 1;
var data = { id: id, namespace: namespace, name: name };
// Wrap the action so we can provide a dispatch method
var newAction = new AltAction(alt, id, implementation, obj, data);
var dispatch = function dispatch(payload) {
return alt.dispatch(id, payload, data);
};
// the action itself
var action = function action() {
newAction.dispatched = false;
var result = newAction._dispatch.apply(newAction, arguments);
// async functions that return promises should not be dispatched
if (!newAction.dispatched && result !== undefined && !fn.isPromise(result)) {
if (fn.isFunction(result)) {
result(dispatch, alt);
} else {
dispatch(result);
}
}
if (!newAction.dispatched && result === undefined) {
/* istanbul ignore else */
/*eslint-disable*/
if (typeof console !== 'undefined') {
console.warn('An action was called but nothing was dispatched');
}
/*eslint-enable*/
}
return result;
};
action.defer = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
setTimeout(function () {
newAction._dispatch.apply(null, args);
});
};
action.id = id;
action.data = data;
// ensure each reference is unique in the namespace
var container = alt.actions[namespace];
var namespaceId = utils.uid(container, name);
container[namespaceId] = action;
return action;
}
module.exports = exports['default'];
/***/ }
/******/ ])
});
;
\ No newline at end of file
//
// Generated on Tue Dec 16 2014 12:13:47 GMT+0100 (CET) by Charlie Robbins, Paolo Fragomeni & the Contributors (Using Codesurgeon).
// Version 1.2.6
//
(function (exports) {
/*
* browser.js: Browser specific functionality for director.
*
* (C) 2011, Charlie Robbins, Paolo Fragomeni, & the Contributors.
* MIT LICENSE
*
*/
var dloc = document.location;
function dlocHashEmpty() {
// Non-IE browsers return '' when the address bar shows '#'; Director's logic
// assumes both mean empty.
return dloc.hash === '' || dloc.hash === '#';
}
var listener = {
mode: 'modern',
hash: dloc.hash,
history: false,
check: function () {
var h = dloc.hash;
if (h != this.hash) {
this.hash = h;
this.onHashChanged();
}
},
fire: function () {
if (this.mode === 'modern') {
this.history === true ? window.onpopstate() : window.onhashchange();
}
else {
this.onHashChanged();
}
},
init: function (fn, history) {
var self = this;
this.history = history;
if (!Router.listeners) {
Router.listeners = [];
}
function onchange(onChangeEvent) {
for (var i = 0, l = Router.listeners.length; i < l; i++) {
Router.listeners[i](onChangeEvent);
}
}
//note IE8 is being counted as 'modern' because it has the hashchange event
if ('onhashchange' in window && (document.documentMode === undefined
|| document.documentMode > 7)) {
// At least for now HTML5 history is available for 'modern' browsers only
if (this.history === true) {
// There is an old bug in Chrome that causes onpopstate to fire even
// upon initial page load. Since the handler is run manually in init(),
// this would cause Chrome to run it twise. Currently the only
// workaround seems to be to set the handler after the initial page load
// http://code.google.com/p/chromium/issues/detail?id=63040
setTimeout(function() {
window.onpopstate = onchange;
}, 500);
}
else {
window.onhashchange = onchange;
}
this.mode = 'modern';
}
else {
//
// IE support, based on a concept by Erik Arvidson ...
//
var frame = document.createElement('iframe');
frame.id = 'state-frame';
frame.style.display = 'none';
document.body.appendChild(frame);
this.writeFrame('');
if ('onpropertychange' in document && 'attachEvent' in document) {
document.attachEvent('onpropertychange', function () {
if (event.propertyName === 'location') {
self.check();
}
});
}
window.setInterval(function () { self.check(); }, 50);
this.onHashChanged = onchange;
this.mode = 'legacy';
}
Router.listeners.push(fn);
return this.mode;
},
destroy: function (fn) {
if (!Router || !Router.listeners) {
return;
}
var listeners = Router.listeners;
for (var i = listeners.length - 1; i >= 0; i--) {
if (listeners[i] === fn) {
listeners.splice(i, 1);
}
}
},
setHash: function (s) {
// Mozilla always adds an entry to the history
if (this.mode === 'legacy') {
this.writeFrame(s);
}
if (this.history === true) {
window.history.pushState({}, document.title, s);
// Fire an onpopstate event manually since pushing does not obviously
// trigger the pop event.
this.fire();
} else {
dloc.hash = (s[0] === '/') ? s : '/' + s;
}
return this;
},
writeFrame: function (s) {
// IE support...
var f = document.getElementById('state-frame');
var d = f.contentDocument || f.contentWindow.document;
d.open();
d.write("<script>_hash = '" + s + "'; onload = parent.listener.syncHash;<script>");
d.close();
},
syncHash: function () {
// IE support...
var s = this._hash;
if (s != dloc.hash) {
dloc.hash = s;
}
return this;
},
onHashChanged: function () {}
};
var Router = exports.Router = function (routes) {
if (!(this instanceof Router)) return new Router(routes);
this.params = {};
this.routes = {};
this.methods = ['on', 'once', 'after', 'before'];
this.scope = [];
this._methods = {};
this._insert = this.insert;
this.insert = this.insertEx;
this.historySupport = (window.history != null ? window.history.pushState : null) != null
this.configure();
this.mount(routes || {});
};
Router.prototype.init = function (r) {
var self = this
, routeTo;
this.handler = function(onChangeEvent) {
var newURL = onChangeEvent && onChangeEvent.newURL || window.location.hash;
var url = self.history === true ? self.getPath() : newURL.replace(/.*#/, '');
self.dispatch('on', url.charAt(0) === '/' ? url : '/' + url);
};
listener.init(this.handler, this.history);
if (this.history === false) {
if (dlocHashEmpty() && r) {
dloc.hash = r;
} else if (!dlocHashEmpty()) {
self.dispatch('on', '/' + dloc.hash.replace(/^(#\/|#|\/)/, ''));
}
}
else {
if (this.convert_hash_in_init) {
// Use hash as route
routeTo = dlocHashEmpty() && r ? r : !dlocHashEmpty() ? dloc.hash.replace(/^#/, '') : null;
if (routeTo) {
window.history.replaceState({}, document.title, routeTo);
}
}
else {
// Use canonical url
routeTo = this.getPath();
}
// Router has been initialized, but due to the chrome bug it will not
// yet actually route HTML5 history state changes. Thus, decide if should route.
if (routeTo || this.run_in_init === true) {
this.handler();
}
}
return this;
};
Router.prototype.explode = function () {
var v = this.history === true ? this.getPath() : dloc.hash;
if (v.charAt(1) === '/') { v=v.slice(1) }
return v.slice(1, v.length).split("/");
};
Router.prototype.setRoute = function (i, v, val) {
var url = this.explode();
if (typeof i === 'number' && typeof v === 'string') {
url[i] = v;
}
else if (typeof val === 'string') {
url.splice(i, v, s);
}
else {
url = [i];
}
listener.setHash(url.join('/'));
return url;
};
//
// ### function insertEx(method, path, route, parent)
// #### @method {string} Method to insert the specific `route`.
// #### @path {Array} Parsed path to insert the `route` at.
// #### @route {Array|function} Route handlers to insert.
// #### @parent {Object} **Optional** Parent "routes" to insert into.
// insert a callback that will only occur once per the matched route.
//
Router.prototype.insertEx = function(method, path, route, parent) {
if (method === "once") {
method = "on";
route = function(route) {
var once = false;
return function() {
if (once) return;
once = true;
return route.apply(this, arguments);
};
}(route);
}
return this._insert(method, path, route, parent);
};
Router.prototype.getRoute = function (v) {
var ret = v;
if (typeof v === "number") {
ret = this.explode()[v];
}
else if (typeof v === "string"){
var h = this.explode();
ret = h.indexOf(v);
}
else {
ret = this.explode();
}
return ret;
};
Router.prototype.destroy = function () {
listener.destroy(this.handler);
return this;
};
Router.prototype.getPath = function () {
var path = window.location.pathname;
if (path.substr(0, 1) !== '/') {
path = '/' + path;
}
return path;
};
function _every(arr, iterator) {
for (var i = 0; i < arr.length; i += 1) {
if (iterator(arr[i], i, arr) === false) {
return;
}
}
}
function _flatten(arr) {
var flat = [];
for (var i = 0, n = arr.length; i < n; i++) {
flat = flat.concat(arr[i]);
}
return flat;
}
function _asyncEverySeries(arr, iterator, callback) {
if (!arr.length) {
return callback();
}
var completed = 0;
(function iterate() {
iterator(arr[completed], function(err) {
if (err || err === false) {
callback(err);
callback = function() {};
} else {
completed += 1;
if (completed === arr.length) {
callback();
} else {
iterate();
}
}
});
})();
}
function paramifyString(str, params, mod) {
mod = str;
for (var param in params) {
if (params.hasOwnProperty(param)) {
mod = params[param](str);
if (mod !== str) {
break;
}
}
}
return mod === str ? "([._a-zA-Z0-9-%()]+)" : mod;
}
function regifyString(str, params) {
var matches, last = 0, out = "";
while (matches = str.substr(last).match(/[^\w\d\- %@&]*\*[^\w\d\- %@&]*/)) {
last = matches.index + matches[0].length;
matches[0] = matches[0].replace(/^\*/, "([_.()!\\ %@&a-zA-Z0-9-]+)");
out += str.substr(0, matches.index) + matches[0];
}
str = out += str.substr(last);
var captures = str.match(/:([^\/]+)/ig), capture, length;
if (captures) {
length = captures.length;
for (var i = 0; i < length; i++) {
capture = captures[i];
if (capture.slice(0, 2) === "::") {
str = capture.slice(1);
} else {
str = str.replace(capture, paramifyString(capture, params));
}
}
}
return str;
}
function terminator(routes, delimiter, start, stop) {
var last = 0, left = 0, right = 0, start = (start || "(").toString(), stop = (stop || ")").toString(), i;
for (i = 0; i < routes.length; i++) {
var chunk = routes[i];
if (chunk.indexOf(start, last) > chunk.indexOf(stop, last) || ~chunk.indexOf(start, last) && !~chunk.indexOf(stop, last) || !~chunk.indexOf(start, last) && ~chunk.indexOf(stop, last)) {
left = chunk.indexOf(start, last);
right = chunk.indexOf(stop, last);
if (~left && !~right || !~left && ~right) {
var tmp = routes.slice(0, (i || 1) + 1).join(delimiter);
routes = [ tmp ].concat(routes.slice((i || 1) + 1));
}
last = (right > left ? right : left) + 1;
i = 0;
} else {
last = 0;
}
}
return routes;
}
var QUERY_SEPARATOR = /\?.*/;
Router.prototype.configure = function(options) {
options = options || {};
for (var i = 0; i < this.methods.length; i++) {
this._methods[this.methods[i]] = true;
}
this.recurse = options.recurse || this.recurse || false;
this.async = options.async || false;
this.delimiter = options.delimiter || "/";
this.strict = typeof options.strict === "undefined" ? true : options.strict;
this.notfound = options.notfound;
this.resource = options.resource;
this.history = options.html5history && this.historySupport || false;
this.run_in_init = this.history === true && options.run_handler_in_init !== false;
this.convert_hash_in_init = this.history === true && options.convert_hash_in_init !== false;
this.every = {
after: options.after || null,
before: options.before || null,
on: options.on || null
};
return this;
};
Router.prototype.param = function(token, matcher) {
if (token[0] !== ":") {
token = ":" + token;
}
var compiled = new RegExp(token, "g");
this.params[token] = function(str) {
return str.replace(compiled, matcher.source || matcher);
};
return this;
};
Router.prototype.on = Router.prototype.route = function(method, path, route) {
var self = this;
if (!route && typeof path == "function") {
route = path;
path = method;
method = "on";
}
if (Array.isArray(path)) {
return path.forEach(function(p) {
self.on(method, p, route);
});
}
if (path.source) {
path = path.source.replace(/\\\//ig, "/");
}
if (Array.isArray(method)) {
return method.forEach(function(m) {
self.on(m.toLowerCase(), path, route);
});
}
path = path.split(new RegExp(this.delimiter));
path = terminator(path, this.delimiter);
this.insert(method, this.scope.concat(path), route);
};
Router.prototype.path = function(path, routesFn) {
var self = this, length = this.scope.length;
if (path.source) {
path = path.source.replace(/\\\//ig, "/");
}
path = path.split(new RegExp(this.delimiter));
path = terminator(path, this.delimiter);
this.scope = this.scope.concat(path);
routesFn.call(this, this);
this.scope.splice(length, path.length);
};
Router.prototype.dispatch = function(method, path, callback) {
var self = this, fns = this.traverse(method, path.replace(QUERY_SEPARATOR, ""), this.routes, ""), invoked = this._invoked, after;
this._invoked = true;
if (!fns || fns.length === 0) {
this.last = [];
if (typeof this.notfound === "function") {
this.invoke([ this.notfound ], {
method: method,
path: path
}, callback);
}
return false;
}
if (this.recurse === "forward") {
fns = fns.reverse();
}
function updateAndInvoke() {
self.last = fns.after;
self.invoke(self.runlist(fns), self, callback);
}
after = this.every && this.every.after ? [ this.every.after ].concat(this.last) : [ this.last ];
if (after && after.length > 0 && invoked) {
if (this.async) {
this.invoke(after, this, updateAndInvoke);
} else {
this.invoke(after, this);
updateAndInvoke();
}
return true;
}
updateAndInvoke();
return true;
};
Router.prototype.invoke = function(fns, thisArg, callback) {
var self = this;
var apply;
if (this.async) {
apply = function(fn, next) {
if (Array.isArray(fn)) {
return _asyncEverySeries(fn, apply, next);
} else if (typeof fn == "function") {
fn.apply(thisArg, (fns.captures || []).concat(next));
}
};
_asyncEverySeries(fns, apply, function() {
if (callback) {
callback.apply(thisArg, arguments);
}
});
} else {
apply = function(fn) {
if (Array.isArray(fn)) {
return _every(fn, apply);
} else if (typeof fn === "function") {
return fn.apply(thisArg, fns.captures || []);
} else if (typeof fn === "string" && self.resource) {
self.resource[fn].apply(thisArg, fns.captures || []);
}
};
_every(fns, apply);
}
};
Router.prototype.traverse = function(method, path, routes, regexp, filter) {
var fns = [], current, exact, match, next, that;
function filterRoutes(routes) {
if (!filter) {
return routes;
}
function deepCopy(source) {
var result = [];
for (var i = 0; i < source.length; i++) {
result[i] = Array.isArray(source[i]) ? deepCopy(source[i]) : source[i];
}
return result;
}
function applyFilter(fns) {
for (var i = fns.length - 1; i >= 0; i--) {
if (Array.isArray(fns[i])) {
applyFilter(fns[i]);
if (fns[i].length === 0) {
fns.splice(i, 1);
}
} else {
if (!filter(fns[i])) {
fns.splice(i, 1);
}
}
}
}
var newRoutes = deepCopy(routes);
newRoutes.matched = routes.matched;
newRoutes.captures = routes.captures;
newRoutes.after = routes.after.filter(filter);
applyFilter(newRoutes);
return newRoutes;
}
if (path === this.delimiter && routes[method]) {
next = [ [ routes.before, routes[method] ].filter(Boolean) ];
next.after = [ routes.after ].filter(Boolean);
next.matched = true;
next.captures = [];
return filterRoutes(next);
}
for (var r in routes) {
if (routes.hasOwnProperty(r) && (!this._methods[r] || this._methods[r] && typeof routes[r] === "object" && !Array.isArray(routes[r]))) {
current = exact = regexp + this.delimiter + r;
if (!this.strict) {
exact += "[" + this.delimiter + "]?";
}
match = path.match(new RegExp("^" + exact));
if (!match) {
continue;
}
if (match[0] && match[0] == path && routes[r][method]) {
next = [ [ routes[r].before, routes[r][method] ].filter(Boolean) ];
next.after = [ routes[r].after ].filter(Boolean);
next.matched = true;
next.captures = match.slice(1);
if (this.recurse && routes === this.routes) {
next.push([ routes.before, routes.on ].filter(Boolean));
next.after = next.after.concat([ routes.after ].filter(Boolean));
}
return filterRoutes(next);
}
next = this.traverse(method, path, routes[r], current);
if (next.matched) {
if (next.length > 0) {
fns = fns.concat(next);
}
if (this.recurse) {
fns.push([ routes[r].before, routes[r].on ].filter(Boolean));
next.after = next.after.concat([ routes[r].after ].filter(Boolean));
if (routes === this.routes) {
fns.push([ routes["before"], routes["on"] ].filter(Boolean));
next.after = next.after.concat([ routes["after"] ].filter(Boolean));
}
}
fns.matched = true;
fns.captures = next.captures;
fns.after = next.after;
return filterRoutes(fns);
}
}
}
return false;
};
Router.prototype.insert = function(method, path, route, parent) {
var methodType, parentType, isArray, nested, part;
path = path.filter(function(p) {
return p && p.length > 0;
});
parent = parent || this.routes;
part = path.shift();
if (/\:|\*/.test(part) && !/\\d|\\w/.test(part)) {
part = regifyString(part, this.params);
}
if (path.length > 0) {
parent[part] = parent[part] || {};
return this.insert(method, path, route, parent[part]);
}
if (!part && !path.length && parent === this.routes) {
methodType = typeof parent[method];
switch (methodType) {
case "function":
parent[method] = [ parent[method], route ];
return;
case "object":
parent[method].push(route);
return;
case "undefined":
parent[method] = route;
return;
}
return;
}
parentType = typeof parent[part];
isArray = Array.isArray(parent[part]);
if (parent[part] && !isArray && parentType == "object") {
methodType = typeof parent[part][method];
switch (methodType) {
case "function":
parent[part][method] = [ parent[part][method], route ];
return;
case "object":
parent[part][method].push(route);
return;
case "undefined":
parent[part][method] = route;
return;
}
} else if (parentType == "undefined") {
nested = {};
nested[method] = route;
parent[part] = nested;
return;
}
throw new Error("Invalid route context: " + parentType);
};
Router.prototype.extend = function(methods) {
var self = this, len = methods.length, i;
function extend(method) {
self._methods[method] = true;
self[method] = function() {
var extra = arguments.length === 1 ? [ method, "" ] : [ method ];
self.on.apply(self, extra.concat(Array.prototype.slice.call(arguments)));
};
}
for (i = 0; i < len; i++) {
extend(methods[i]);
}
};
Router.prototype.runlist = function(fns) {
var runlist = this.every && this.every.before ? [ this.every.before ].concat(_flatten(fns)) : _flatten(fns);
if (this.every && this.every.on) {
runlist.push(this.every.on);
}
runlist.captures = fns.captures;
runlist.source = fns.source;
return runlist;
};
Router.prototype.mount = function(routes, path) {
if (!routes || typeof routes !== "object" || Array.isArray(routes)) {
return;
}
var self = this;
path = path || [];
if (!Array.isArray(path)) {
path = path.split(self.delimiter);
}
function insertOrMount(route, local) {
var rename = route, parts = route.split(self.delimiter), routeType = typeof routes[route], isRoute = parts[0] === "" || !self._methods[parts[0]], event = isRoute ? "on" : rename;
if (isRoute) {
rename = rename.slice((rename.match(new RegExp("^" + self.delimiter)) || [ "" ])[0].length);
parts.shift();
}
if (isRoute && routeType === "object" && !Array.isArray(routes[route])) {
local = local.concat(parts);
self.mount(routes[route], local);
return;
}
if (isRoute) {
local = local.concat(rename.split(self.delimiter));
local = terminator(local, self.delimiter);
}
self.insert(event, local, routes[route]);
}
for (var route in routes) {
if (routes.hasOwnProperty(route)) {
insertOrMount(route, path.slice(0));
}
}
};
}(typeof exports === "object" ? exports : window));
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
font-weight: inherit;
color: inherit;
-webkit-appearance: none;
appearance: none;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
font-smoothing: antialiased;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #f5f5f5;
color: #4d4d4d;
min-width: 230px;
max-width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
font-smoothing: antialiased;
font-weight: 300;
}
button,
input[type="checkbox"] {
outline: none;
}
.hidden {
display: none;
}
.todoapp {
background: #fff;
margin: 130px 0 40px 0;
position: relative;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.todoapp input::-webkit-input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::-moz-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp h1 {
position: absolute;
top: -155px;
width: 100%;
font-size: 100px;
font-weight: 100;
text-align: center;
color: rgba(175, 47, 47, 0.15);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
.new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
font-weight: 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);
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
font-smoothing: antialiased;
}
.new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.003);
box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
}
.main {
position: relative;
z-index: 2;
border-top: 1px solid #e6e6e6;
}
label[for='toggle-all'] {
display: none;
}
.toggle-all {
position: absolute;
top: -55px;
left: -12px;
width: 60px;
height: 34px;
text-align: center;
border: none; /* Mobile Safari */
}
.toggle-all:before {
content: '❯';
font-size: 22px;
color: #e6e6e6;
padding: 10px 27px 10px 27px;
}
.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 solid #ededed;
}
.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;
appearance: none;
}
.todo-list li .toggle:after {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
}
.todo-list li .toggle:checked:after {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
}
.todo-list li label {
white-space: pre;
word-break: break-word;
padding: 15px 60px 15px 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
transition: color 0.4s;
}
.todo-list li.completed label {
color: #d9d9d9;
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: 30px;
color: #cc9a9a;
margin-bottom: 11px;
transition: color 0.2s ease-out;
}
.todo-list li .destroy:hover {
color: #af5b5e;
}
.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: 10px 15px;
height: 20px;
text-align: center;
border-top: 1px solid #e6e6e6;
}
.footer:before {
content: '';
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 50px;
overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
0 8px 0 -3px #f6f6f6,
0 9px 1px -3px rgba(0, 0, 0, 0.2),
0 16px 0 -6px #f6f6f6,
0 17px 2px -6px rgba(0, 0, 0, 0.2);
}
.todo-count {
float: left;
text-align: left;
}
.todo-count strong {
font-weight: 300;
}
.filters {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
right: 0;
left: 0;
}
.filters li {
display: inline;
}
.filters li a {
color: inherit;
margin: 3px;
padding: 3px 7px;
text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
}
.filters li a.selected,
.filters li a:hover {
border-color: rgba(175, 47, 47, 0.1);
}
.filters li a.selected {
border-color: rgba(175, 47, 47, 0.2);
}
.clear-completed,
html .clear-completed:active {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
cursor: pointer;
position: relative;
}
.clear-completed:hover {
text-decoration: underline;
}
.info {
margin: 65px auto 0;
color: #bfbfbf;
font-size: 10px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-align: center;
}
.info p {
line-height: 1;
}
.info a {
color: inherit;
text-decoration: none;
font-weight: 400;
}
.info a:hover {
text-decoration: underline;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox
*/
@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 {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
}
@media (max-width: 430px) {
.footer {
height: 50px;
}
.filters {
bottom: 10px;
}
}
hr {
margin: 20px 0;
border: 0;
border-top: 1px dashed #c5c5c5;
border-bottom: 1px dashed #f7f7f7;
}
.learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
}
.learn a:hover {
text-decoration: underline;
color: #787e7e;
}
.learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
color: #000;
}
.learn h3 {
font-size: 24px;
}
.learn h4 {
font-size: 18px;
}
.learn h5 {
margin-bottom: 0;
font-size: 14px;
}
.learn ul {
padding: 0;
margin: 0 0 30px 25px;
}
.learn li {
line-height: 20px;
}
.learn p {
font-size: 15px;
font-weight: 300;
line-height: 1.3;
margin-top: 0;
margin-bottom: 0;
}
#issue-count {
display: none;
}
.quote {
border: none;
margin: 20px 0 60px 0;
}
.quote p {
font-style: italic;
}
.quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
}
.quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
}
.quote footer {
position: absolute;
bottom: -40px;
right: 0;
}
.quote footer img {
border-radius: 3px;
}
.quote footer a {
margin-left: 5px;
vertical-align: middle;
}
.speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
}
.speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
}
.learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
transition-property: left;
transition-duration: 500ms;
}
@media (min-width: 899px) {
.learn-bar {
width: auto;
padding-left: 300px;
}
.learn-bar > .learn {
left: 8px;
}
}
/* global _ */
(function () {
'use strict';
/* jshint ignore:start */
// Underscore's Template Module
// Courtesy of underscorejs.org
var _ = (function (_) {
_.defaults = function (object) {
if (!object) {
return object;
}
for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
var iterable = arguments[argsIndex];
if (iterable) {
for (var key in iterable) {
if (object[key] == null) {
object[key] = iterable[key];
}
}
}
}
return object;
}
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /(.)^/;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
var render;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
return match;
});
source += "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
try {
render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
return template;
};
return _;
})({});
if (location.hostname === 'todomvc.com') {
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-31081062-1', 'auto');
ga('send', 'pageview');
}
/* jshint ignore:end */
function redirect() {
if (location.hostname === 'tastejs.github.io') {
location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
}
}
function findRoot() {
var base = location.href.indexOf('examples/');
return location.href.substr(0, base);
}
function getFile(file, callback) {
if (!location.host) {
return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
}
var xhr = new XMLHttpRequest();
xhr.open('GET', findRoot() + file, true);
xhr.send();
xhr.onload = function () {
if (xhr.status === 200 && callback) {
callback(xhr.responseText);
}
};
}
function Learn(learnJSON, config) {
if (!(this instanceof Learn)) {
return new Learn(learnJSON, config);
}
var template, framework;
if (typeof learnJSON !== 'object') {
try {
learnJSON = JSON.parse(learnJSON);
} catch (e) {
return;
}
}
if (config) {
template = config.template;
framework = config.framework;
}
if (!template && learnJSON.templates) {
template = learnJSON.templates.todomvc;
}
if (!framework && document.querySelector('[data-framework]')) {
framework = document.querySelector('[data-framework]').dataset.framework;
}
this.template = template;
if (learnJSON.backend) {
this.frameworkJSON = learnJSON.backend;
this.frameworkJSON.issueLabel = framework;
this.append({
backend: true
});
} else if (learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework];
this.frameworkJSON.issueLabel = framework;
this.append();
}
this.fetchIssueCount();
}
Learn.prototype.append = function (opts) {
var aside = document.createElement('aside');
aside.innerHTML = _.template(this.template, this.frameworkJSON);
aside.className = 'learn';
if (opts && opts.backend) {
// Remove demo link
var sourceLinks = aside.querySelector('.source-links');
var heading = sourceLinks.firstElementChild;
var sourceLink = sourceLinks.lastElementChild;
// Correct link path
var href = sourceLink.getAttribute('href');
sourceLink.setAttribute('href', href.substr(href.lastIndexOf('http')));
sourceLinks.innerHTML = heading.outerHTML + sourceLink.outerHTML;
} else {
// Localize demo links
var demoLinks = aside.querySelectorAll('.demo-link');
Array.prototype.forEach.call(demoLinks, function (demoLink) {
if (demoLink.getAttribute('href').substr(0, 4) !== 'http') {
demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
}
});
}
document.body.className = (document.body.className + ' learn-bar').trim();
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
};
Learn.prototype.fetchIssueCount = function () {
var issueLink = document.getElementById('issue-count-link');
if (issueLink) {
var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos');
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
var parsedResponse = JSON.parse(e.target.responseText);
if (parsedResponse instanceof Array) {
var count = parsedResponse.length;
if (count !== 0) {
issueLink.innerHTML = 'This app has ' + count + ' open issues';
document.getElementById('issue-count').style.display = 'inline';
}
}
};
xhr.send();
}
};
redirect();
getFile('learn.json', Learn);
})();
{
"private": true,
"dependencies": {
"alt": "^0.17.3",
"director": "^1.2.0",
"react": "^0.13.3",
"todomvc-app-css": "^2.0.0",
"todomvc-common": "^1.0.1"
}
}
# React + Alt TodoMVC Example
> React is a JavaScript library for creating user interfaces. Its core principles are declarative code, efficiency, and flexibility. Simply specify what your component looks like and React will keep it up-to-date when the underlying data changes. Alt is one of many implementations of Facebook's Flux architecture. Some of the reasons for using Alt is given by the author [here](https://github.com/goatslacker/alt#why-you-should-be-using-alt).
> * _[React - facebook.github.io/react](http://facebook.github.io/react)_
> * _[Flux - facebook.github.io/flux](http://facebook.github.io/flux)_
> * _[Alt - alt.js.org](http://alt.js.org)_
## Learning React
The [React getting started documentation](http://facebook.github.io/react/docs/getting-started.html) is a great way to get started.
Here are some links you may find helpful:
* [Documentation](http://facebook.github.io/react/docs/getting-started.html)
* [API Reference](http://facebook.github.io/react/docs/reference.html)
* [Blog](http://facebook.github.io/react/blog/)
* [React on GitHub](https://github.com/facebook/react)
* [Support](http://facebook.github.io/react/support.html)
Articles and guides from the community:
* [Philosophy](http://www.quora.com/Pete-Hunt/Posts/React-Under-the-Hood)
* [How is Facebook's React JavaScript library](http://www.quora.com/React-JS-Library/How-is-Facebooks-React-JavaScript-library)
* [React: Under the hood](http://www.quora.com/Pete-Hunt/Posts/React-Under-the-Hood)
Get help from other React users:
* [React on StackOverflow](http://stackoverflow.com/questions/tagged/reactjs)
* [Flux on StackOverflow](http://stackoverflow.com/questions/tagged/reactjs-flux)
* [Mailing list on Google Groups](https://groups.google.com/forum/#!forum/reactjs)
_If you have other helpful links to share, or find any of the links above no longer work, please [let us know](https://github.com/tastejs/todomvc/issues)._
## Running
The app is built with [JSX](http://facebook.github.io/react/docs/jsx-in-depth.html) and compiled at runtime for a lighter and more fun code reading experience. As stated in the link, JSX is not mandatory.
To run the app, spin up an HTTP server (e.g. `python -m SimpleHTTPServer`) and visit http://localhost/.../myexample/.
## Credit
Most of the code in this example is copied from Pete Hunt's React example. It has been slightly modified to use the Alt Flux implementation, and most of the added code is in the actions and store.
...@@ -7,6 +7,6 @@ ...@@ -7,6 +7,6 @@
</p><ul class="js-app-list-inner applist js"><li class="routing"><a href="examples/spine" data-source="http://spinejs.com" data-content="Spine is a lightweight framework for building JavaScript web applications. Spine gives you an MVC structure and then gets out of your way, allowing you to concentrate on the fun stuff, building awesome web applications.">Spine</a></li><li class="routing"><a href="examples/vanilladart/build/web" data-source="http://dartlang.org" data-content="Dart firstly targets the development of modern and large scale browser-side web apps. It's an object oriented language with a C-style syntax. It has two run modes : it can be compiled to JS, and will later run in native VM in compliant browsers (just in a dedicated Chromium provided with Dart SDK for the moment).">Dart</a></li><li class="routing"><a href="examples/gwt" data-source="https://developers.google.com/web-toolkit/" data-content="Google Web Toolkit (GWT) is an MVP development toolkit for building and optimizing complex browser-based applications. GWT is used by many products at Google, including Google AdWords.">GWT</a></li><li class="routing"><a href="examples/closure" data-source="http://code.google.com/closure/library/" data-content="The Closure Library is a broad, well-tested, modular, and cross-browser JavaScript library. You can pull just what you need from a large set of reusable UI widgets and controls, and from lower-level utilities for DOM manipulation, server communication, animation, data structures, unit testing, rich-text editing, and more.">Closure</a></li><li class="routing"><a href="examples/elm" data-source="http://elm-lang.org" data-content="A functional reactive language for interactive applications">Elm</a></li><li><a href="examples/angular-dart/web" data-source="https://github.com/angular/angular.dart" data-content="Dart firstly targets the development of modern and large scale browser-side web apps. It's an object oriented language with a C-style syntax. AngularDart is a port of Angular to Dart.">AngularDart</a></li><li><a href="examples/typescript-backbone" data-source="http://typescriptlang.org" data-content="TypeScript is a language for application-scale JavaScript development. It offers classes, modules, interfaces and type-checking at compile time to help you build robust components.">TypeScript <br>+ Backbone.js</a></li><li><a href="examples/typescript-angular" data-source="http://typescriptlang.org" data-content="An AngularJS + TypeScript implementation of TodoMVC. The only significant difference between this and the vanilla Angular app is that dependency injection is done via annotated constructors, which allows minification of JavaScript.">TypeScript <br>+ AngularJS</a></li><li><a href="examples/typescript-react" data-source="http://typescriptlang.org" data-content="An TypeScript + React implementation of TodoMVC. TypeScript is a language for application-scale JavaScript development. It offers classes, modules, interfaces and type-checking at compile time to help you build robust components. This examples showcases how to work with TSX files, which allow us to enjoy native JSX support while working with TypeScript.">TypeScript <br>+ React</a></li><li><a href="examples/serenadejs" data-source="https://github.com/elabs/serenade.js" data-content="Serenade.js is yet another MVC client side JavaScript framework. Why do we indulge in recreating the wheel? We believe that Serenade.js more closely follows the ideas of classical MVC than competing frameworks.">Serenade.js</a></li><li class="routing"><a href="examples/reagent" data-source="https://reagent-project.github.io/" data-content="Reagent provides a minimalistic interface between ClojureScript and React.">Reagent</a></li><li class="routing"><a href="examples/scalajs-react" data-source="https://github.com/japgolly/scalajs-react" data-content="Facebook's React on Scala.js.">Scala.js + React</a></li><li class="routing"><a href="examples/js_of_ocaml" data-source="http://ocsigen.org/js_of_ocaml/" data-content="Js_of_ocaml is a compiler of OCaml bytecode to Javascript.">js_of_ocaml</a></li></ul></div><div class="js-app-list" data-app-list="labs"><p class="applist-intro"> </p><ul class="js-app-list-inner applist js"><li class="routing"><a href="examples/spine" data-source="http://spinejs.com" data-content="Spine is a lightweight framework for building JavaScript web applications. Spine gives you an MVC structure and then gets out of your way, allowing you to concentrate on the fun stuff, building awesome web applications.">Spine</a></li><li class="routing"><a href="examples/vanilladart/build/web" data-source="http://dartlang.org" data-content="Dart firstly targets the development of modern and large scale browser-side web apps. It's an object oriented language with a C-style syntax. It has two run modes : it can be compiled to JS, and will later run in native VM in compliant browsers (just in a dedicated Chromium provided with Dart SDK for the moment).">Dart</a></li><li class="routing"><a href="examples/gwt" data-source="https://developers.google.com/web-toolkit/" data-content="Google Web Toolkit (GWT) is an MVP development toolkit for building and optimizing complex browser-based applications. GWT is used by many products at Google, including Google AdWords.">GWT</a></li><li class="routing"><a href="examples/closure" data-source="http://code.google.com/closure/library/" data-content="The Closure Library is a broad, well-tested, modular, and cross-browser JavaScript library. You can pull just what you need from a large set of reusable UI widgets and controls, and from lower-level utilities for DOM manipulation, server communication, animation, data structures, unit testing, rich-text editing, and more.">Closure</a></li><li class="routing"><a href="examples/elm" data-source="http://elm-lang.org" data-content="A functional reactive language for interactive applications">Elm</a></li><li><a href="examples/angular-dart/web" data-source="https://github.com/angular/angular.dart" data-content="Dart firstly targets the development of modern and large scale browser-side web apps. It's an object oriented language with a C-style syntax. AngularDart is a port of Angular to Dart.">AngularDart</a></li><li><a href="examples/typescript-backbone" data-source="http://typescriptlang.org" data-content="TypeScript is a language for application-scale JavaScript development. It offers classes, modules, interfaces and type-checking at compile time to help you build robust components.">TypeScript <br>+ Backbone.js</a></li><li><a href="examples/typescript-angular" data-source="http://typescriptlang.org" data-content="An AngularJS + TypeScript implementation of TodoMVC. The only significant difference between this and the vanilla Angular app is that dependency injection is done via annotated constructors, which allows minification of JavaScript.">TypeScript <br>+ AngularJS</a></li><li><a href="examples/typescript-react" data-source="http://typescriptlang.org" data-content="An TypeScript + React implementation of TodoMVC. TypeScript is a language for application-scale JavaScript development. It offers classes, modules, interfaces and type-checking at compile time to help you build robust components. This examples showcases how to work with TSX files, which allow us to enjoy native JSX support while working with TypeScript.">TypeScript <br>+ React</a></li><li><a href="examples/serenadejs" data-source="https://github.com/elabs/serenade.js" data-content="Serenade.js is yet another MVC client side JavaScript framework. Why do we indulge in recreating the wheel? We believe that Serenade.js more closely follows the ideas of classical MVC than competing frameworks.">Serenade.js</a></li><li class="routing"><a href="examples/reagent" data-source="https://reagent-project.github.io/" data-content="Reagent provides a minimalistic interface between ClojureScript and React.">Reagent</a></li><li class="routing"><a href="examples/scalajs-react" data-source="https://github.com/japgolly/scalajs-react" data-content="Facebook's React on Scala.js.">Scala.js + React</a></li><li class="routing"><a href="examples/js_of_ocaml" data-source="http://ocsigen.org/js_of_ocaml/" data-content="Js_of_ocaml is a compiler of OCaml bytecode to Javascript.">js_of_ocaml</a></li></ul></div><div class="js-app-list" data-app-list="labs"><p class="applist-intro">
These are examples written in JavaScript that These are examples written in JavaScript that
we are still evaluating. we are still evaluating.
</p><ul class="js-app-list-inner applist js"><li class="routing"><a href="examples/thorax" data-source="http://thoraxjs.org" data-content="An opinionated, battle tested Backbone + Handlebars framework to build large scale web applications.">Thorax</a></li><li class="routing"><a href="examples/chaplin-brunch/public" data-source="http://chaplinjs.org" data-content="Chaplin is an architecture for JavaScript applications using the Backbone.js library. Chaplin addresses Backbone’s limitations by providing a lightweight and flexible structure that features well-proven design patterns and best practises.">Chaplin + Brunch</a></li><li class="routing"><a href="examples/backbone_require" data-source="http://requirejs.org" data-content="RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.">Backbone.js + RequireJS</a></li><li><a href="examples/knockoutjs_require" data-source="http://knockoutjs.com" data-content="This project is an adaptation of /examples/knockoutjs with require.js.">KnockoutJS + RequireJS</a></li><li class="routing"><a href="examples/angularjs_require" data-source="http://angularjs.org" data-content="What HTML would have been had it been designed for web apps. This is an example of using it with AMD modules.">AngularJS + RequireJS</a></li><li class="routing"><a href="examples/canjs_require" data-source="http://canjs.us" data-content="CanJS is a client-side, JavaScript framework that makes building rich web applications easy. The AMD version lets you use the framework in a fully modular fashion and will only what you actually need.">CanJS + RequireJS</a></li><li class="routing"><a href="examples/thorax_lumbar/public" data-source="http://walmartlabs.github.com/lumbar" data-content="An opinionated, battle tested Backbone + Handlebars framework to build large scale web applications. This implementation uses Lumbar, a route based module loader.">Thorax + Lumbar</a></li><li class="routing"><a href="examples/somajs_require" data-source="http://somajs.github.com/somajs" data-content="soma.js is a framework created to build scalable and maintainable javascript applications.">soma.js + RequireJS</a></li><li class="routing"><a href="examples/durandal" data-source="http://durandaljs.com/" data-content="Single Page Apps Done Right">Durandal</a></li><li class="routing"><a href="examples/lavaca_require" data-source="http://getlavaca.com" data-content="A curated collection of tools for building mobile web applications.">Lavaca + RequireJS</a></li><li><a href="examples/cujo/index.html" data-source="http://cujojs.com" data-content="cujoJS is an architectural framework for building highly modular, scalable, maintainable applications in Javascript. It provides architectural plumbing, such as modules (AMD and CommonJS), declarative application composition, declarative connections, and aspect oriented programming.">cujoJS</a></li><li class="routing"><a href="examples/sammyjs" data-source="http://sammyjs.org" data-content="Sammy.js is a tiny JavaScript framework developed to ease the pain and provide a basic structure for developing JavaScript applications.">Sammy.js</a></li><li><a href="examples/somajs" data-source="http://somajs.github.com/somajs" data-content="soma.js is a framework created to build scalable and maintainable javascript applications.">soma.js</a></li><li><a href="examples/duel/www" data-source="https://bitbucket.org/mckamey/duel/wiki/Home" data-content="DUEL is a dual-side templating engine using HTML for layout and 100% pure JavaScript as the binding language. The same views may be executed both directly in the browser (client-side template) and on the server (server-side template).">DUEL</a></li><li class="routing"><a href="examples/kendo" data-source="http://www.kendoui.com/" data-content="Kendo UI is a comprehensive HTML5, JavaScript framework for modern web and mobile app development">Kendo UI</a></li><li class="routing"><a href="examples/puremvc" data-source="http://puremvc.github.com" data-content="PureMVC is a lightweight framework for creating applications based upon the classic Model-View-Controller design meta-pattern.">PureMVC</a></li><li><a href="examples/olives" data-source="https://github.com/flams/olives" data-content="Olives is a JS MVC framework that helps you create realtime UIs. It includes a set of AMD/CommonJS modules that are easily extensive, a high level of abstraction to reduce boilerplate and is based on socket.io, to provide a powerful means to communicate with node.js.">Olives</a></li><li><a href="examples/dijon" data-source="https://github.com/creynders/dijon-framework" data-content="Dijon is an IOC and DI micro-framework for Javascript. Originally it was meant to be a port of Robotlegs, but deviated to something quite different. It remains however heavily inspired by Robotlegs, and more specifically Swiftsuspenders.">Dijon</a></li><li class="routing"><a href="examples/rappidjs" data-source="http://www.rappidjs.com" data-content="rAppid.js is a declarative JavaScript framework for rapid web application development. It supports dependency loading, Model-View binding, View-Model binding, dependency injection and i18n.">rAppid.js</a></li><li><a href="examples/extjs_deftjs" data-source="http://deftjs.org/" data-content="Essential extensions for enterprise web and mobile application development with Ext JS and Sencha Touch">DeftJS + ExtJS</a></li><li class="routing"><a href="examples/ariatemplates" data-source="http://ariatemplates.com/" data-content="Aria Templates has been designed for web apps that are used 8+ hours a day, and that need to display and process high amount of data with a minimum of bandwidth consumption.">Aria Templates</a></li><li class="routing"><a href="examples/enyo_backbone" data-source="http://enyojs.com/" data-content="Enyo is a simple but powerful encapsulation model, which helps you factor application functionality into self-contained building blocks that are easy to reuse and maintain.">Enyo +<br>Backbone.js</a></li><li class="routing"><a href="examples/angularjs-perf" data-source="http://angularjs.org" data-content="What HTML would have been had it been designed for web apps. A version with several performance optimizations.">AngularJS <br>(optimized)</a></li><li class="routing"><a href="examples/sapui5" data-source="http://scn.sap.com/community/developer-center/front-end" data-content="SAPUI5 is SAP's HTML5-based UI technology that allows you to build rich, interactive Web applications.">SAPUI5</a></li><li class="routing"><a href="examples/exoskeleton" data-source="http://exosjs.com/" data-content="A faster and leaner Backbone for your HTML5 apps.">Exoskeleton</a></li><li class="routing"><a href="examples/atmajs" data-source="http://atmajs.com/" data-content="HMVC and the component-based architecture for building client, server or hybrid applications">Atma.js</a></li><li><a href="examples/ractive" data-source="http://ractivejs.org" data-content="Ractive.js is a next-generation DOM manipulation library, optimised for developer sanity.">Ractive.js</a></li><li><a href="examples/componentjs" data-source="http://componentjs.com" data-content="ComponentJS is a stand-alone MPL-licensed Open Source library for JavaScript, providing a powerful run-time Component System for hierarchically structuring the User-Interface (UI) dialogs of complex HTML5-based Rich Clients (aka Single-Page-Apps) — under maximum applied Separation of Concerns (SoC) architecture principle, through optional Model, View and Controller component roles, with sophisticated hierarchical Event, Service, Hook, Model, Socket and Property mechanisms, and fully independent and agnostic of the particular UI widget toolkit.">ComponentJS</a></li><li><a href="examples/react-backbone" data-source="http://facebook.github.io/react/" data-content="This React example integrates Backbone for its model and router. It is a showcase of third-party library integration for developers wishing to use React together with a different JavaScript framework.">React + <br>Backbone.js</a></li><li><a href="examples/aurelia" data-source="http://aurelia.io/" data-content="Aurelia is a next generation JavaScript client framework that leverages simple conventions to empower your creativity">Aurelia</a></li><li class="routing"><a href="examples/foam" data-source="http://foam-framework.github.io/foam/" data-content="FOAM is a deeply MVC Javascript metaprogramming framework being developed by a team at Google.">FOAM</a></li><li class="routing"><a href="examples/webrx" data-source="http://webrxjs.org" data-content="WebRx is a Javascript MVVM-Framework that combines functional-reactive programming with declarative Data-Binding, Templating and Client-Side Routing. The framework is built on top of ReactiveX for Javascript (RxJs) which is a powerful set of libraries for processing and querying asynchronous data-streams that can originate from diverse sources such as Http-Requests, Input-Events, Timers and much more.">WebRx</a></li><li><a href="examples/angular2" data-source="http://angular.io" data-content="Angular is a development platform for building mobile and desktop web applications">Angular 2.0</a></li><li class="routing"><a href="examples/riotjs" data-source="http://riotjs.com/" data-content="Riot.js is a React-like user interface micro-library.">Riot</a></li><li class="routing"><a href="examples/jsblocks" data-source="http://jsblocks.com/" data-content="From simple user interfaces to complex single-page applications using faster, server-side rendered and easy to learn framework.">JSBlocks</a></li></ul></div></div><ul class="legend"><li><span class="label">R</span> = App also demonstrates routing</li></ul><hr><h2>Real-time</h2><ul class="applist"><li><a href="http://todomvcapp.meteor.com" data-source="http://meteor.com" data-content="Meteor is an ultra-simple environment for building modern websites. A Meteor application is a mix of JavaScript that runs inside a client web browser, JavaScript that runs on the Meteor server inside a Node.js container, and all the supporting HTML fragments, CSS rules, and static assets. Meteor automates the packaging and transmission of these different components. And, it is quite flexible about how you choose to structure those components in your file tree.">Meteor</a></li><li class="routing"><a href="http://todomvc-socketstream.herokuapp.com" data-source="http://www.socketstream.org" data-content="SocketStream is a fast, modular Node.js web framework dedicated to building realtime single-page apps">SocketStream</a></li><li class="routing"><a href="examples/firebase-angular" data-source="https://www.firebase.com" data-content="Firebase is a scalable realtime backend that lets you build apps without managing servers. Firebase persists and updates JSON data in realtime and is best used in combination with a JavaScript MV* framework such as AngularJS or Backbone.">Firebase + AngularJS</a></li></ul><hr><h2>Node.js</h2><ul class="applist"><li><a href="http://gcloud-todos.appspot.com" data-source="http://googlecloudplatform.github.io/gcloud-node/" data-content="An Express backend implementation for the AngularJS front end using Google Cloud Client Library for Node.js.">Express + gcloud-node</a></li></ul><hr><h2>Compare these to a non-framework implementation</h2><ul class="applist"><li class="routing"><a href="examples/vanillajs" data-source="https://developer.mozilla.org/en/JavaScript" data-content="You know JavaScript right? :P">Vanilla JS</a></li><li class="routing"><a href="examples/jquery" data-source="http://jquery.com" data-content="jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.">jQuery</a></li></ul></div></div><hr><div class="row"><div class="col-md-6 quotes"><blockquote class="quote speech-bubble"><p></p><footer><img width="40" height="40" alt=""><a></a></footer></blockquote></div><div class="col-md-6"><img class="screenshot" src="site-assets/screenshot.png" width="558" height="246" alt="Todo app screenshot"></div></div><hr><div class="row"><div class="col-md-4"><h2>New in 1.3</h2><ul class="whats-new"><li>We now have 64 applications. </p><ul class="js-app-list-inner applist js"><li class="routing"><a href="examples/thorax" data-source="http://thoraxjs.org" data-content="An opinionated, battle tested Backbone + Handlebars framework to build large scale web applications.">Thorax</a></li><li class="routing"><a href="examples/chaplin-brunch/public" data-source="http://chaplinjs.org" data-content="Chaplin is an architecture for JavaScript applications using the Backbone.js library. Chaplin addresses Backbone’s limitations by providing a lightweight and flexible structure that features well-proven design patterns and best practises.">Chaplin + Brunch</a></li><li class="routing"><a href="examples/backbone_require" data-source="http://requirejs.org" data-content="RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.">Backbone.js + RequireJS</a></li><li><a href="examples/knockoutjs_require" data-source="http://knockoutjs.com" data-content="This project is an adaptation of /examples/knockoutjs with require.js.">KnockoutJS + RequireJS</a></li><li class="routing"><a href="examples/angularjs_require" data-source="http://angularjs.org" data-content="What HTML would have been had it been designed for web apps. This is an example of using it with AMD modules.">AngularJS + RequireJS</a></li><li class="routing"><a href="examples/canjs_require" data-source="http://canjs.us" data-content="CanJS is a client-side, JavaScript framework that makes building rich web applications easy. The AMD version lets you use the framework in a fully modular fashion and will only what you actually need.">CanJS + RequireJS</a></li><li class="routing"><a href="examples/thorax_lumbar/public" data-source="http://walmartlabs.github.com/lumbar" data-content="An opinionated, battle tested Backbone + Handlebars framework to build large scale web applications. This implementation uses Lumbar, a route based module loader.">Thorax + Lumbar</a></li><li class="routing"><a href="examples/somajs_require" data-source="http://somajs.github.com/somajs" data-content="soma.js is a framework created to build scalable and maintainable javascript applications.">soma.js + RequireJS</a></li><li class="routing"><a href="examples/durandal" data-source="http://durandaljs.com/" data-content="Single Page Apps Done Right">Durandal</a></li><li class="routing"><a href="examples/lavaca_require" data-source="http://getlavaca.com" data-content="A curated collection of tools for building mobile web applications.">Lavaca + RequireJS</a></li><li><a href="examples/cujo/index.html" data-source="http://cujojs.com" data-content="cujoJS is an architectural framework for building highly modular, scalable, maintainable applications in Javascript. It provides architectural plumbing, such as modules (AMD and CommonJS), declarative application composition, declarative connections, and aspect oriented programming.">cujoJS</a></li><li class="routing"><a href="examples/sammyjs" data-source="http://sammyjs.org" data-content="Sammy.js is a tiny JavaScript framework developed to ease the pain and provide a basic structure for developing JavaScript applications.">Sammy.js</a></li><li><a href="examples/somajs" data-source="http://somajs.github.com/somajs" data-content="soma.js is a framework created to build scalable and maintainable javascript applications.">soma.js</a></li><li><a href="examples/duel/www" data-source="https://bitbucket.org/mckamey/duel/wiki/Home" data-content="DUEL is a dual-side templating engine using HTML for layout and 100% pure JavaScript as the binding language. The same views may be executed both directly in the browser (client-side template) and on the server (server-side template).">DUEL</a></li><li class="routing"><a href="examples/kendo" data-source="http://www.kendoui.com/" data-content="Kendo UI is a comprehensive HTML5, JavaScript framework for modern web and mobile app development">Kendo UI</a></li><li class="routing"><a href="examples/puremvc" data-source="http://puremvc.github.com" data-content="PureMVC is a lightweight framework for creating applications based upon the classic Model-View-Controller design meta-pattern.">PureMVC</a></li><li><a href="examples/olives" data-source="https://github.com/flams/olives" data-content="Olives is a JS MVC framework that helps you create realtime UIs. It includes a set of AMD/CommonJS modules that are easily extensive, a high level of abstraction to reduce boilerplate and is based on socket.io, to provide a powerful means to communicate with node.js.">Olives</a></li><li><a href="examples/dijon" data-source="https://github.com/creynders/dijon-framework" data-content="Dijon is an IOC and DI micro-framework for Javascript. Originally it was meant to be a port of Robotlegs, but deviated to something quite different. It remains however heavily inspired by Robotlegs, and more specifically Swiftsuspenders.">Dijon</a></li><li class="routing"><a href="examples/rappidjs" data-source="http://www.rappidjs.com" data-content="rAppid.js is a declarative JavaScript framework for rapid web application development. It supports dependency loading, Model-View binding, View-Model binding, dependency injection and i18n.">rAppid.js</a></li><li><a href="examples/extjs_deftjs" data-source="http://deftjs.org/" data-content="Essential extensions for enterprise web and mobile application development with Ext JS and Sencha Touch">DeftJS + ExtJS</a></li><li class="routing"><a href="examples/ariatemplates" data-source="http://ariatemplates.com/" data-content="Aria Templates has been designed for web apps that are used 8+ hours a day, and that need to display and process high amount of data with a minimum of bandwidth consumption.">Aria Templates</a></li><li class="routing"><a href="examples/enyo_backbone" data-source="http://enyojs.com/" data-content="Enyo is a simple but powerful encapsulation model, which helps you factor application functionality into self-contained building blocks that are easy to reuse and maintain.">Enyo +<br>Backbone.js</a></li><li class="routing"><a href="examples/angularjs-perf" data-source="http://angularjs.org" data-content="What HTML would have been had it been designed for web apps. A version with several performance optimizations.">AngularJS <br>(optimized)</a></li><li class="routing"><a href="examples/sapui5" data-source="http://scn.sap.com/community/developer-center/front-end" data-content="SAPUI5 is SAP's HTML5-based UI technology that allows you to build rich, interactive Web applications.">SAPUI5</a></li><li class="routing"><a href="examples/exoskeleton" data-source="http://exosjs.com/" data-content="A faster and leaner Backbone for your HTML5 apps.">Exoskeleton</a></li><li class="routing"><a href="examples/atmajs" data-source="http://atmajs.com/" data-content="HMVC and the component-based architecture for building client, server or hybrid applications">Atma.js</a></li><li><a href="examples/ractive" data-source="http://ractivejs.org" data-content="Ractive.js is a next-generation DOM manipulation library, optimised for developer sanity.">Ractive.js</a></li><li><a href="examples/componentjs" data-source="http://componentjs.com" data-content="ComponentJS is a stand-alone MPL-licensed Open Source library for JavaScript, providing a powerful run-time Component System for hierarchically structuring the User-Interface (UI) dialogs of complex HTML5-based Rich Clients (aka Single-Page-Apps) — under maximum applied Separation of Concerns (SoC) architecture principle, through optional Model, View and Controller component roles, with sophisticated hierarchical Event, Service, Hook, Model, Socket and Property mechanisms, and fully independent and agnostic of the particular UI widget toolkit.">ComponentJS</a></li><li class="routing"><a href="examples/react-alt" data-source="http://alt.js.org" data-content="This React example integrates Alt for an example of an application following the Flux architecture.">React + Alt</a></li><li><a href="examples/react-backbone" data-source="http://facebook.github.io/react/" data-content="This React example integrates Backbone for its model and router. It is a showcase of third-party library integration for developers wishing to use React together with a different JavaScript framework.">React + <br>Backbone.js</a></li><li><a href="examples/aurelia" data-source="http://aurelia.io/" data-content="Aurelia is a next generation JavaScript client framework that leverages simple conventions to empower your creativity">Aurelia</a></li><li class="routing"><a href="examples/foam" data-source="http://foam-framework.github.io/foam/" data-content="FOAM is a deeply MVC Javascript metaprogramming framework being developed by a team at Google.">FOAM</a></li><li class="routing"><a href="examples/webrx" data-source="http://webrxjs.org" data-content="WebRx is a Javascript MVVM-Framework that combines functional-reactive programming with declarative Data-Binding, Templating and Client-Side Routing. The framework is built on top of ReactiveX for Javascript (RxJs) which is a powerful set of libraries for processing and querying asynchronous data-streams that can originate from diverse sources such as Http-Requests, Input-Events, Timers and much more.">WebRx</a></li><li><a href="examples/angular2" data-source="http://angular.io" data-content="Angular is a development platform for building mobile and desktop web applications">Angular 2.0</a></li><li class="routing"><a href="examples/riotjs" data-source="http://riotjs.com/" data-content="Riot.js is a React-like user interface micro-library.">Riot</a></li><li class="routing"><a href="examples/jsblocks" data-source="http://jsblocks.com/" data-content="From simple user interfaces to complex single-page applications using faster, server-side rendered and easy to learn framework.">JSBlocks</a></li></ul></div></div><ul class="legend"><li><span class="label">R</span> = App also demonstrates routing</li></ul><hr><h2>Real-time</h2><ul class="applist"><li><a href="http://todomvcapp.meteor.com" data-source="http://meteor.com" data-content="Meteor is an ultra-simple environment for building modern websites. A Meteor application is a mix of JavaScript that runs inside a client web browser, JavaScript that runs on the Meteor server inside a Node.js container, and all the supporting HTML fragments, CSS rules, and static assets. Meteor automates the packaging and transmission of these different components. And, it is quite flexible about how you choose to structure those components in your file tree.">Meteor</a></li><li class="routing"><a href="http://todomvc-socketstream.herokuapp.com" data-source="http://www.socketstream.org" data-content="SocketStream is a fast, modular Node.js web framework dedicated to building realtime single-page apps">SocketStream</a></li><li class="routing"><a href="examples/firebase-angular" data-source="https://www.firebase.com" data-content="Firebase is a scalable realtime backend that lets you build apps without managing servers. Firebase persists and updates JSON data in realtime and is best used in combination with a JavaScript MV* framework such as AngularJS or Backbone.">Firebase + AngularJS</a></li></ul><hr><h2>Node.js</h2><ul class="applist"><li><a href="http://gcloud-todos.appspot.com" data-source="http://googlecloudplatform.github.io/gcloud-node/" data-content="An Express backend implementation for the AngularJS front end using Google Cloud Client Library for Node.js.">Express + gcloud-node</a></li></ul><hr><h2>Compare these to a non-framework implementation</h2><ul class="applist"><li class="routing"><a href="examples/vanillajs" data-source="https://developer.mozilla.org/en/JavaScript" data-content="You know JavaScript right? :P">Vanilla JS</a></li><li class="routing"><a href="examples/jquery" data-source="http://jquery.com" data-content="jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.">jQuery</a></li></ul></div></div><hr><div class="row"><div class="col-md-6 quotes"><blockquote class="quote speech-bubble"><p></p><footer><img width="40" height="40" alt=""><a></a></footer></blockquote></div><div class="col-md-6"><img class="screenshot" src="site-assets/screenshot.png" width="558" height="246" alt="Todo app screenshot"></div></div><hr><div class="row"><div class="col-md-4"><h2>New in 1.3</h2><ul class="whats-new"><li>We now have 64 applications.
<label class="link" for="news-expander">New since 1.3 ▼</label><input type="checkbox" id="news-expander"><ul class="collapsed" id="new-apps"><li><a href="examples/angular-dart/web">AngularDart</a></li><li><a href="examples/durandal">Durandel</a></li><li><a href="examples/atmajs">Atma.js</a></li><li><a href="examples/exoskeleton">Exoskeleton</a></li><li><a href="examples/componentjs">ComponentJS</a></li></ul></li><li>Updates have been made to apps including Vanilla, Angular, React, Backbone, Ember, jQuery &amp; many more.</li><li>The knockoutjs_classBindingProvider application has been removed.</li></ul></div><div class="col-md-4"><h2>Selecting a Framework</h2><p>Once you've downloaded the latest release and played around with the apps, you'll want to decide on a specific framework to try out.</p><p>Study the syntax required for defining models, views and (where applicable) controllers and classes in the frameworks you're interested in and try your hand at editing the code to see how it feels using it first-hand.</p><p>Please ensure that if you're happy with this, you do spend more time investigating the framework (including reading the official docs, the source and its complete feature list). There's often a lot more to a framework than what we present in our examples.</p></div><div class="col-md-4"><h2>Getting Involved</h2><p>Is there a bug we haven't fixed or an MV* framework you feel would benefit from being included in TodoMVC?</p><p>If so, feel free to fork the repo, read our <a href="https://github.com/tastejs/todomvc/wiki">contribution guidelines</a>, and submit a pull request &mdash; we'll be happy to review it for inclusion.</p><p>Make sure you use the <a href="https://github.com/tastejs/todomvc-app-template">template</a> as a starting point and read the <a href="https://github.com/tastejs/todomvc/blob/master/app-spec.md">app specification</a>.</p><p><a class="zocial small ltgray" href="https://github.com/tastejs/todomvc/wiki">Submit Pull Request &raquo;</a></p></div></div><hr><footer class="credit"><p>Brought to you by <label class="link" for="news-expander">New since 1.3 ▼</label><input type="checkbox" id="news-expander"><ul class="collapsed" id="new-apps"><li><a href="examples/angular-dart/web">AngularDart</a></li><li><a href="examples/durandal">Durandel</a></li><li><a href="examples/atmajs">Atma.js</a></li><li><a href="examples/exoskeleton">Exoskeleton</a></li><li><a href="examples/componentjs">ComponentJS</a></li></ul></li><li>Updates have been made to apps including Vanilla, Angular, React, Backbone, Ember, jQuery &amp; many more.</li><li>The knockoutjs_classBindingProvider application has been removed.</li></ul></div><div class="col-md-4"><h2>Selecting a Framework</h2><p>Once you've downloaded the latest release and played around with the apps, you'll want to decide on a specific framework to try out.</p><p>Study the syntax required for defining models, views and (where applicable) controllers and classes in the frameworks you're interested in and try your hand at editing the code to see how it feels using it first-hand.</p><p>Please ensure that if you're happy with this, you do spend more time investigating the framework (including reading the official docs, the source and its complete feature list). There's often a lot more to a framework than what we present in our examples.</p></div><div class="col-md-4"><h2>Getting Involved</h2><p>Is there a bug we haven't fixed or an MV* framework you feel would benefit from being included in TodoMVC?</p><p>If so, feel free to fork the repo, read our <a href="https://github.com/tastejs/todomvc/wiki">contribution guidelines</a>, and submit a pull request &mdash; we'll be happy to review it for inclusion.</p><p>Make sure you use the <a href="https://github.com/tastejs/todomvc-app-template">template</a> as a starting point and read the <a href="https://github.com/tastejs/todomvc/blob/master/app-spec.md">app specification</a>.</p><p><a class="zocial small ltgray" href="https://github.com/tastejs/todomvc/wiki">Submit Pull Request &raquo;</a></p></div></div><hr><footer class="credit"><p>Brought to you by
<a href="https://github.com/addyosmani"><img src="http://gravatar.com/avatar/96270e4c3e5e9806cf7245475c00b275?s=80" width="40" height="40" alt="Addy Osmani">Addy</a><a href="https://github.com/sindresorhus"><img src="http://gravatar.com/avatar/d36a92237c75c5337c17b60d90686bf9.png?s=80" width="40" height="40" alt="Sindre Sorhus">Sindre</a><a href="https://github.com/passy"><img src="http://gravatar.com/avatar/be451fcdbf0e5ff07f23ed16cb5c90a3.png?s=80" width="40" height="40" alt="Pascal Hartig">Pascal</a><a href="https://github.com/stephenplusplus"><img src="http://gravatar.com/avatar/098cfe2d360e77c3229f2cd5298354c4?s=80" width="40" height="40" alt="Stephen Sawchuk">Stephen</a><a href="https://github.com/colineberhardt"><img src="http://gravatar.com/avatar/73bba00b41ff1c9ecc3ee29487bace7d?s=80" width="40" height="40" alt="Colin Eberhardt">Colin</a><a href="https://github.com/arthurvr"><img src="https://avatars1.githubusercontent.com/u/6025224?v=3&s=80" width="40" height="40" alt="Arthur Verschaeve">Arthur</a><a href="https://github.com/samccone"><img src="https://avatars0.githubusercontent.com/u/883126?v=3&s=80" width="40" height="40" alt="Sam Saccone">Sam</a></p></footer></div><script src="site-assets/main.min.js"></script><script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.async=true;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs)}}(document,"script","twitter-wjs");</script><script>(function(){var po=document.createElement("script");po.type="text/javascript";po.async=true;po.src="https://apis.google.com/js/plusone.js";var s=document.getElementsByTagName("script")[0];s.parentNode.insertBefore(po,s)})();</script><script>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");</script></body></html> <a href="https://github.com/addyosmani"><img src="http://gravatar.com/avatar/96270e4c3e5e9806cf7245475c00b275?s=80" width="40" height="40" alt="Addy Osmani">Addy</a><a href="https://github.com/sindresorhus"><img src="http://gravatar.com/avatar/d36a92237c75c5337c17b60d90686bf9.png?s=80" width="40" height="40" alt="Sindre Sorhus">Sindre</a><a href="https://github.com/passy"><img src="http://gravatar.com/avatar/be451fcdbf0e5ff07f23ed16cb5c90a3.png?s=80" width="40" height="40" alt="Pascal Hartig">Pascal</a><a href="https://github.com/stephenplusplus"><img src="http://gravatar.com/avatar/098cfe2d360e77c3229f2cd5298354c4?s=80" width="40" height="40" alt="Stephen Sawchuk">Stephen</a><a href="https://github.com/colineberhardt"><img src="http://gravatar.com/avatar/73bba00b41ff1c9ecc3ee29487bace7d?s=80" width="40" height="40" alt="Colin Eberhardt">Colin</a><a href="https://github.com/arthurvr"><img src="https://avatars1.githubusercontent.com/u/6025224?v=3&s=80" width="40" height="40" alt="Arthur Verschaeve">Arthur</a><a href="https://github.com/samccone"><img src="https://avatars0.githubusercontent.com/u/883126?v=3&s=80" width="40" height="40" alt="Sam Saccone">Sam</a></p></footer></div><script src="site-assets/main.min.js"></script><script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.async=true;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs)}}(document,"script","twitter-wjs");</script><script>(function(){var po=document.createElement("script");po.type="text/javascript";po.async=true;po.src="https://apis.google.com/js/plusone.js";var s=document.getElementsByTagName("script")[0];s.parentNode.insertBefore(po,s)})();</script><script>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");</script></body></html>
...@@ -1670,14 +1670,17 @@ ...@@ -1670,14 +1670,17 @@
"name": "Example", "name": "Example",
"url": "examples/react" "url": "examples/react"
}, { }, {
"name": "React & Backbone.js", "name": "React + Backbone.js",
"url": "examples/react-backbone" "url": "examples/react-backbone"
}, { }, {
"name": "Scala.js & React", "name": "Scala.js + React",
"url": "examples/scalajs-react" "url": "examples/scalajs-react"
}, { }, {
"name": "TypeScript & React", "name": "TypeScript + React",
"url": "examples/typescript-react" "url": "examples/typescript-react"
}, {
"name": "React + Alt",
"url": "examples/react-alt"
}], }],
"link_groups": [{ "link_groups": [{
"heading": "Official Resources", "heading": "Official Resources",
......
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