Commit 007d96ee authored by Pascal Hartig's avatar Pascal Hartig

Merge branch 'pr-1457'

Close #1457
parents ce92430e e0c95d16
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.
......@@ -266,6 +266,9 @@
<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>
......
......@@ -1670,14 +1670,17 @@
"name": "Example",
"url": "examples/react"
}, {
"name": "React & Backbone.js",
"name": "React + Backbone.js",
"url": "examples/react-backbone"
}, {
"name": "Scala.js & React",
"name": "Scala.js + React",
"url": "examples/scalajs-react"
}, {
"name": "TypeScript & React",
"name": "TypeScript + React",
"url": "examples/typescript-react"
}, {
"name": "React + Alt",
"url": "examples/react-alt"
}],
"link_groups": [{
"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