summaryrefslogtreecommitdiffstats
path: root/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src')
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/base.js49
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/index.js112
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/item.js58
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/model.js36
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/share.js58
5 files changed, 313 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/base.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/base.js
new file mode 100644
index 0000000000..89a2ca30c8
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/base.js
@@ -0,0 +1,49 @@
+import Inferno from 'inferno';
+import { states } from './share';
+
+/**
+ * Stateless Header component
+ */
+export function Head({onEnter}) {
+ return (
+ <header className="header">
+ <h1>todos</h1>
+ <input className="new-todo" autofocus onkeydown={ onEnter }
+ autocomplete="off" placeholder="What needs to be done?"
+ />
+ </header>
+ );
+}
+
+export const links = [
+ {hash: '#/', name: 'All'},
+ {hash: '#/active', name: 'Active'},
+ {hash: '#/completed', name: 'Completed'}
+];
+
+/**
+ * Stateless Footer component
+ */
+export function Foot({left, done, route, onClear}) {
+ return (
+ <footer className="footer">
+ <span className="todo-count">
+ <strong>{ left }</strong> { left > 1 ? 'items' : 'item' } left
+ </span>
+ <ul className="filters">
+ {
+ links.map(({hash, name}) => (
+ <li>
+ <a href={ hash } className={ name.toLowerCase() === route ? 'selected' : '' }>
+ { name }
+ </a>
+ </li>
+ ))
+ }
+ </ul>
+ { done > 0 ? (
+ <button className="clear-completed" onClick={ onClear }>Clear completed</button>
+ ) : null }
+ </footer>
+ );
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/index.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/index.js
new file mode 100644
index 0000000000..87414c0b38
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/index.js
@@ -0,0 +1,112 @@
+import Inferno from 'inferno';
+import Component from 'inferno-component';
+import { ENTER, filters, read } from './share';
+import { Head, Foot } from './base';
+import Model from './model';
+import Item from './item';
+
+const { render } = Inferno;
+const model = new Model();
+
+class App extends Component {
+ state = {
+ route: read(),
+ todos: model.get()
+ };
+
+ update = arr => this.setState({todos: arr});
+
+ componentWillMount = () => {
+ window.onhashchange = () => this.setState({route: read()});
+ };
+
+ add = e => {
+ if (e.which !== ENTER) return;
+
+ const val = e.target.value.trim();
+ if (!val) return;
+
+ e.target.value = '';
+ this.update(
+ model.add(val)
+ );
+ };
+
+ edit = (todo, val) => {
+ val = val.trim();
+ if (val.length) {
+ this.update(
+ model.put(todo, {title: val, editing: 0})
+ );
+ } else {
+ this.remove(todo);
+ }
+ };
+
+ focus = todo => this.update(
+ model.put(todo, {editing: 1})
+ );
+
+ blur = todo => this.update(
+ model.put(todo, {editing: 0})
+ );
+
+ remove = todo => this.update(
+ model.del(todo)
+ );
+
+ toggleOne = todo => this.update(
+ model.toggle(todo)
+ );
+
+ toggleAll = ev => this.update(
+ model.toggleAll(ev.target.checked)
+ );
+
+ clearCompleted = () => this.update(
+ model.clearCompleted()
+ );
+
+ render(_, {todos, route}) {
+ const num = todos.length;
+ const shown = todos.filter(filters[route]);
+ const numDone = todos.filter(filters.completed).length;
+ const numAct = num - numDone;
+
+ return (
+ <div>
+ <Head onEnter={ this.add } />
+
+ { num ? (
+ <section className="main">
+ <input className="toggle-all" type="checkbox"
+ onClick={ this.toggleAll } checked={ numAct === 0 }
+ />
+
+ <ul className="todo-list">
+ {
+ shown.map(t =>
+ <Item data={t}
+ onBlur={ () => this.blur(t) }
+ onFocus={ () => this.focus(t) }
+ doDelete={ () => this.remove(t) }
+ doSave={ val => this.edit(t, val) }
+ doToggle={ () => this.toggleOne(t) }
+ />
+ )
+ }
+ </ul>
+ </section>
+ ) : null }
+
+ { (numAct || numDone) ? (
+ <Foot onClear={ this.clearCompleted }
+ left={numAct} done={numDone} route={route}
+ />
+ ) : null }
+ </div>
+ )
+ }
+}
+
+render(<App />, document.getElementById('app'));
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/item.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/item.js
new file mode 100644
index 0000000000..57f8b1d0e8
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/item.js
@@ -0,0 +1,58 @@
+import Inferno from 'inferno';
+import Component from 'inferno-component';
+import { ESCAPE, ENTER, isEqual } from './share';
+
+export default class Item extends Component {
+ constructor({data, ...props}) {
+ super(props);
+ this.todo = data;
+ this.state = {text: data.title};
+ this.editor = null;
+ }
+
+ componentWillReceiveProps = ({data}) => this.setText(data.title);
+ shouldComponentUpdate = ({data}, {text}) => !(isEqual(data, this.todo) && text === this.state.text);
+ componentWillUpdate = ({data}) => (this.todo = data);
+ componentDidUpdate = () => this.editor.focus();
+
+ setText = text => this.setState({text});
+
+ render({doToggle, doDelete, doSave, onBlur, onFocus}, {text}) {
+ const {title, completed, editing} = this.todo;
+
+ const cls = [];
+ editing && cls.push('editing');
+ completed && cls.push('completed');
+
+ const handleKeydown = e => {
+ if (e.which === ESCAPE) return onBlur();
+ if (e.which === ENTER) return doSave(text);
+ };
+
+ // tmp fix
+ const handleBlur = () => doSave(text);
+ const handleInput = e => this.setText(e.target.value);
+
+ return (
+ <li className={ cls.join(' ') }>
+ <div className="view">
+ <input className="toggle" type="checkbox"
+ checked={ completed } onClick={ doToggle }
+ />
+
+ <label ondblclick={ onFocus }>{ title }</label>
+
+ <button className="destroy" onClick={ doDelete }></button>
+ </div>
+
+ <input className="edit"
+ ref={el => { this.editor = el }}
+ value={ editing && text }
+ onblur={ handleBlur }
+ oninput={ handleInput }
+ onkeydown={ handleKeydown }
+ />
+ </li>
+ );
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/model.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/model.js
new file mode 100644
index 0000000000..52eaf46635
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/model.js
@@ -0,0 +1,36 @@
+import { assign, isEqual } from './share';
+
+const STOR = {};
+const STOR_ID = 'todos-inferno';
+
+export default class Model {
+ get = () => (this.data = JSON.parse(STOR[STOR_ID] || '[]'))
+
+ set = arr => {
+ this.data = arr || this.data || [];
+ STOR[STOR_ID] = JSON.stringify(this.data);
+ return this.data;
+ }
+
+ add = str => this.set(
+ this.data.concat({title: str, completed: false})
+ )
+
+ put = (todo, obj) => this.set(
+ this.data.map(t => isEqual(t, todo) ? assign(todo, obj) : t)
+ )
+
+ del = todo => this.set(
+ this.data.filter(t => !isEqual(t, todo))
+ )
+
+ toggle = todo => this.put(todo, {completed: !todo.completed})
+
+ toggleAll = completed => this.set(
+ this.data.map(t => ({...t, completed}))
+ )
+
+ clearCompleted = () => this.set(
+ this.data.filter(t => !t.completed)
+ )
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/share.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/share.js
new file mode 100644
index 0000000000..9e7d962b8f
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/inferno/src/share.js
@@ -0,0 +1,58 @@
+/**
+ * Shared funcs/values
+ */
+
+export const ENTER = 13;
+export const ESCAPE = 27;
+
+export const filters = {
+ all: t => true,
+ active: t => !t.completed,
+ completed: t => t.completed
+}
+
+/**
+ * Read the `location.hash` value
+ * @return {String}
+ */
+export function read() {
+ return location.hash.replace('#/', '') || 'all';
+}
+
+/**
+ * Modified `Object.assign` shim
+ * - always writes to new object
+ * @return {Object}
+ */
+export function assign() {
+ let src;
+ let tar = {};
+ for (let s = 0; s < arguments.length; s++) {
+ src = Object(arguments[s]);
+ for (const k in src) {
+ tar[k] = src[k];
+ }
+ }
+ return tar;
+}
+
+/**
+ * Are two Objects equal values?
+ * @param {Object} a
+ * @param {Object} b
+ * @return {Boolean}
+ */
+export function isEqual(a, b) {
+ // Create arrays of property names
+ const aProps = Object.getOwnPropertyNames(a);
+ const bProps = Object.getOwnPropertyNames(b);
+
+ if (aProps.length !== bProps.length) return false;
+
+ for (let i = 0; i < aProps.length; i++) {
+ const k = aProps[i];
+ if (a[k] !== b[k]) return false;
+ }
+
+ return true;
+}