summaryrefslogtreecommitdiffstats
path: root/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src')
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/footer.js33
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/index.js134
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/item.js85
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/model.js54
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/util.js23
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/index.html17
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/index.js6
7 files changed, 352 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/footer.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/footer.js
new file mode 100644
index 0000000000..814bcb8976
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/footer.js
@@ -0,0 +1,33 @@
+import cx from 'classnames';
+import { h, Component } from 'preact';
+import { pluralize } from './util';
+
+export default class TodoFooter extends Component {
+ render({ nowShowing, count, completedCount, onClearCompleted }) {
+ return (
+ <footer class="footer">
+ <span class="todo-count">
+ <strong>{count}</strong> {pluralize(count, 'item')} left
+ </span>
+ <ul class="filters">
+ <li>
+ <a href="#/" class={cx({ selected: nowShowing == 'all' })}>All</a>
+ </li>
+ {' '}
+ <li>
+ <a href="#/active" class={cx({ selected: nowShowing == 'active' })}>Active</a>
+ </li>
+ {' '}
+ <li>
+ <a href="#/completed" class={cx({ selected: nowShowing == 'completed' })}>Completed</a>
+ </li>
+ </ul>
+ { completedCount > 0 && (
+ <button class="clear-completed" onClick={onClearCompleted}>
+ Clear completed
+ </button>
+ ) }
+ </footer>
+ );
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/index.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/index.js
new file mode 100644
index 0000000000..64390be17d
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/index.js
@@ -0,0 +1,134 @@
+import { h, Component } from 'preact';
+import linkState from 'linkstate';
+
+import TodoModel from './model';
+import TodoFooter from './footer';
+import TodoItem from './item';
+
+const ENTER_KEY = 13;
+
+const FILTERS = {
+ all: todo => true,
+ active: todo => !todo.completed,
+ completed: todo => todo.completed
+};
+
+export default class App extends Component {
+ constructor() {
+ super();
+ this.model = new TodoModel('preact-todos', () => this.setState({}) );
+ addEventListener('hashchange', this.handleRoute.bind(this));
+ this.handleRoute();
+ }
+
+ handleRoute() {
+ let nowShowing = String(location.hash || '').split('/').pop();
+ if (!FILTERS[nowShowing]) {
+ nowShowing = 'all';
+ }
+ this.setState({ nowShowing });
+ }
+
+ handleNewTodoKeyDown = (e) => {
+ if (e.keyCode !== ENTER_KEY) return;
+ e.preventDefault();
+
+ // let val = '';
+ // if (this.state.newTodo === undefined) {
+ // val = e.target.value.trim();
+ // }
+
+ let val = e.target.value.trim();
+
+ if (val) {
+ this.model.addTodo(val);
+ this.setState({ newTodo: '' });
+ }
+ };
+
+ toggleAll = event => {
+ let checked = event.target.checked;
+ this.model.toggleAll(checked);
+ };
+
+ toggle = todo => {
+ this.model.toggle(todo);
+ };
+
+ destroy = todo => {
+ this.model.destroy(todo);
+ };
+
+ edit = todo => {
+ this.setState({ editing: todo.id });
+ };
+
+ save = (todoToSave, text) => {
+ this.model.save(todoToSave, text);
+ this.setState({ editing: null });
+ };
+
+ cancel = () => {
+ this.setState({ editing: null });
+ };
+
+ clearCompleted = () => {
+ this.model.clearCompleted();
+ };
+
+ render({ }, { nowShowing = ALL_TODOS, newTodo, editing }) {
+ let { todos } = this.model,
+ shownTodos = todos.filter( FILTERS[nowShowing] ),
+ activeTodoCount = todos.reduce( (a, todo) => a + (todo.completed ? 0 : 1), 0),
+ completedCount = todos.length - activeTodoCount;
+
+ return (
+ <div>
+ <header class="header">
+ <h1>todos</h1>
+ <input
+ class="new-todo"
+ placeholder="What needs to be done?"
+ value={newTodo}
+ onKeyDown={this.handleNewTodoKeyDown}
+ onInput={linkState(this, 'newTodo')}
+ autoFocus={true}
+ />
+ </header>
+
+ { todos.length ? (
+ <section class="main">
+ <input
+ class="toggle-all"
+ type="checkbox"
+ onChange={this.toggleAll}
+ checked={activeTodoCount === 0}
+ />
+ <ul class="todo-list">
+ { shownTodos.map( todo => (
+ <TodoItem
+ todo={todo}
+ onToggle={this.toggle}
+ onDestroy={this.destroy}
+ onEdit={this.edit}
+ editing={editing === todo.id}
+ onSave={this.save}
+ onCancel={this.cancel}
+ />
+ )) }
+ </ul>
+ </section>
+ ) : null }
+
+ { (activeTodoCount || completedCount) ? (
+ <TodoFooter
+ count={activeTodoCount}
+ completedCount={completedCount}
+ nowShowing={nowShowing}
+ onClearCompleted={this.clearCompleted}
+ />
+ ) : null }
+ </div>
+ );
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/item.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/item.js
new file mode 100644
index 0000000000..eed31ba8e1
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/item.js
@@ -0,0 +1,85 @@
+import cx from 'classnames';
+import { h, Component } from 'preact';
+
+const ESCAPE_KEY = 27;
+const ENTER_KEY = 13;
+
+export default class TodoItem extends Component {
+ handleSubmit = () => {
+ let { onSave, onDestroy, todo } = this.props,
+ val = this.state.editText.trim();
+ if (val) {
+ onSave(todo, val);
+ this.setState({ editText: val });
+ }
+ else {
+ onDestroy(todo);
+ }
+ };
+
+ handleEdit = () => {
+ let { onEdit, todo } = this.props;
+ onEdit(todo);
+ this.setState({ editText: todo.title });
+ };
+
+ toggle = e => {
+ let { onToggle, todo } = this.props;
+ onToggle(todo);
+ e.preventDefault();
+ };
+
+ handleKeyDown = e => {
+ if (e.which===ESCAPE_KEY) {
+ let { todo } = this.props;
+ this.setState({ editText: todo.title });
+ this.props.onCancel(todo);
+ }
+ else if (e.which===ENTER_KEY) {
+ this.handleSubmit();
+ }
+ };
+
+ handleDestroy = () => {
+ this.props.onDestroy(this.props.todo);
+ };
+
+ // shouldComponentUpdate({ todo, editing, editText }) {
+ // return (
+ // todo !== this.props.todo ||
+ // editing !== this.props.editing ||
+ // editText !== this.state.editText
+ // );
+ // }
+
+ componentDidUpdate() {
+ let node = this.base && this.base.querySelector('.edit');
+ if (node) node.focus();
+ }
+
+ render({ todo:{ title, completed }, onToggle, onDestroy, editing }, { editText }) {
+ return (
+ <li class={cx({ completed, editing })}>
+ <div class="view">
+ <input
+ class="toggle"
+ type="checkbox"
+ checked={completed}
+ onChange={this.toggle}
+ />
+ <label onDblClick={this.handleEdit}>{title}</label>
+ <button class="destroy" onClick={this.handleDestroy} />
+ </div>
+ { editing && (
+ <input
+ class="edit"
+ value={editText}
+ onBlur={this.handleSubmit}
+ onInput={this.linkState('editText')}
+ onKeyDown={this.handleKeyDown}
+ />
+ ) }
+ </li>
+ );
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/model.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/model.js
new file mode 100644
index 0000000000..2c8aae1d51
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/model.js
@@ -0,0 +1,54 @@
+import { uuid, store } from './util';
+
+export default class TodoModel {
+ constructor(key, sub) {
+ this.key = key;
+ this.todos = store(key) || [];
+ this.onChanges = [sub];
+ }
+
+ inform() {
+ store(this.key, this.todos);
+ this.onChanges.forEach( cb => cb() );
+ }
+
+ addTodo(title) {
+ this.todos = this.todos.concat({
+ id: uuid(),
+ title,
+ completed: false
+ });
+ this.inform();
+ }
+
+ toggleAll(completed) {
+ this.todos = this.todos.map(
+ todo => ({ ...todo, completed })
+ );
+ this.inform();
+ }
+
+ toggle(todoToToggle) {
+ this.todos = this.todos.map( todo => (
+ todo !== todoToToggle ? todo : ({ ...todo, completed: !todo.completed })
+ ) );
+ this.inform();
+ }
+
+ destroy(todo) {
+ this.todos = this.todos.filter( t => t !== todo );
+ this.inform();
+ }
+
+ save(todoToSave, title) {
+ this.todos = this.todos.map( todo => (
+ todo !== todoToSave ? todo : ({ ...todo, title })
+ ));
+ this.inform();
+ }
+
+ clearCompleted() {
+ this.todos = this.todos.filter( todo => !todo.completed );
+ this.inform();
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/util.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/util.js
new file mode 100644
index 0000000000..241ec1ad8b
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/app/util.js
@@ -0,0 +1,23 @@
+export function uuid() {
+ let uuid = '';
+ for (let i = 0; i < 32; i++) {
+ let 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;
+}
+
+export function pluralize(count, word) {
+ return count === 1 ? word : word + 's';
+}
+
+export function store(namespace, data) {
+ // if (data) return localStorage[namespace] = JSON.stringify(data);
+
+ // let store = localStorage[namespace];
+ // return store && JSON.parse(store) || [];
+ return [];
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/index.html b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/index.html
new file mode 100644
index 0000000000..f5eea51d92
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/index.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html lang="en" data-framework="preact">
+ <head>
+ <meta charset="utf-8">
+ <title>Preact TodoMVC example</title>
+ <link rel="stylesheet" href="todomvc-common/base.css">
+ <link rel="stylesheet" href="todomvc.css">
+ </head>
+ <body>
+ <section class="todoapp"></section>
+ <footer class="info">
+ <p>Double-click to edit a todo</p>
+ <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
+ </footer>
+ <script src="app.js"></script>
+ </body>
+</html>
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/index.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/index.js
new file mode 100644
index 0000000000..56bc51fdf1
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/preact/src/index.js
@@ -0,0 +1,6 @@
+import { h, render } from 'preact';
+import App from './app';
+// import 'todomvc-common';
+// import 'todomvc-common/base.css';
+// import 'todomvc-app-css/index.css';
+render(<App />, document.querySelector('.todoapp'));