chromium/third_party/blink/perf_tests/speedometer20/resources/todomvc/labs/architecture-examples/react/js/todoItem.jsx

/**
 * @jsx React.DOM
 */
/*jshint quotmark: false */
/*jshint white: false */
/*jshint trailing: false */
/*jshint newcap: false */
/*global React, Utils */
(function (window) {
    'use strict';

    var ESCAPE_KEY = 27;
    var ENTER_KEY = 13;

    window.TodoItem = React.createClass({
        handleSubmit: function () {
            var val = this.state.editText.trim();
            if (val) {
                this.props.onSave(val);
                this.setState({editText: val});
            } else {
                this.props.onDestroy();
            }
            return false;
        },
        handleEdit: function () {
            // react optimizes renders by batching them. This means you can't call
            // parent's `onEdit` (which in this case triggeres a re-render), and
            // immediately manipulate the DOM as if the rendering's over. Put it as a
            // callback. Refer to app.js' `edit` method
            this.props.onEdit(function () {
                var node = this.refs.editField.getDOMNode();
                node.focus();
                node.setSelectionRange(node.value.length, node.value.length);
            }.bind(this));
        },

        handleKeyDown: function (event) {
            if (event.keyCode === ESCAPE_KEY) {
                this.setState({editText: this.props.todo.title});
                this.props.onCancel();
            } else if (event.keyCode === ENTER_KEY) {
                this.handleSubmit();
            } else {
                this.setState({editText: event.target.value});
            }
        },

        handleChange: function (event) {
            this.setState({editText: event.target.value});
        },

        getInitialState: function () {
            return {editText: this.props.todo.title};
        },

        componentWillReceiveProps: function (nextProps) {
            if (nextProps.todo.title !== this.props.todo.title) {
                this.setState(this.getInitialState());
            }
        },

        render: function () {
            return (
                <li class={Utils.stringifyObjKeys({
                    completed: this.props.todo.completed,
                    editing: this.props.editing
                })}>
                    <div class="view">
                        <input
                            class="toggle"
                            type="checkbox"
                            checked={this.props.todo.completed ? 'checked' : null}
                            onChange={this.props.onToggle}
                        />
                        <label onDoubleClick={this.handleEdit}>
                            {this.props.todo.title}
                        </label>
                        <button class='destroy' onClick={this.props.onDestroy} />
                    </div>
                    <input
                        ref="editField"
                        class="edit"
                        value={this.state.editText}
                        onBlur={this.handleSubmit}
                        onChange={this.handleChange}
                        onKeyDown={this.handleKeyDown}
                    />
                </li>
            );
        }
    });
})(window);