summaryrefslogtreecommitdiffstats
path: root/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js')
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js123
1 files changed, 123 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js
new file mode 100644
index 0000000000..bb3b4043ff
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/backbone/js/views/todo-view.js
@@ -0,0 +1,123 @@
+/*global Backbone, jQuery, _, ENTER_KEY, ESC_KEY */
+var app = app || {};
+
+(function ($) {
+ 'use strict';
+
+ // Todo Item View
+ // --------------
+
+ // The DOM element for a todo item...
+ app.TodoView = Backbone.View.extend({
+ //... is a list tag.
+ tagName: 'li',
+
+ // Cache the template function for a single item.
+ template: _.template($('#item-template').html()),
+
+ // The DOM events specific to an item.
+ events: {
+ 'click .toggle': 'toggleCompleted',
+ 'dblclick label': 'edit',
+ 'click .destroy': 'clear',
+ 'keypress .edit': 'updateOnEnter',
+ 'keydown .edit': 'revertOnEscape',
+ 'blur .edit': 'close'
+ },
+
+ // The TodoView listens for changes to its model, re-rendering. Since
+ // there's a one-to-one correspondence between a **Todo** and a
+ // **TodoView** in this app, we set a direct reference on the model for
+ // convenience.
+ initialize: function () {
+ this.listenTo(this.model, 'change', this.render);
+ this.listenTo(this.model, 'destroy', this.remove);
+ this.listenTo(this.model, 'visible', this.toggleVisible);
+ },
+
+ // Re-render the titles of the todo item.
+ render: function () {
+ // Backbone LocalStorage is adding `id` attribute instantly after
+ // creating a model. This causes our TodoView to render twice. Once
+ // after creating a model and once on `id` change. We want to
+ // filter out the second redundant render, which is caused by this
+ // `id` change. It's known Backbone LocalStorage bug, therefore
+ // we've to create a workaround.
+ // https://github.com/tastejs/todomvc/issues/469
+ if (this.model.changed.id !== undefined) {
+ return;
+ }
+
+ this.$el.html(this.template(this.model.toJSON()));
+ this.$el.toggleClass('completed', this.model.get('completed'));
+ this.toggleVisible();
+ this.$input = this.$('.edit');
+ return this;
+ },
+
+ toggleVisible: function () {
+ this.$el.toggleClass('hidden', this.isHidden());
+ },
+
+ isHidden: function () {
+ return this.model.get('completed') ?
+ app.TodoFilter === 'active' :
+ app.TodoFilter === 'completed';
+ },
+
+ // Toggle the `"completed"` state of the model.
+ toggleCompleted: function () {
+ this.model.toggle();
+ },
+
+ // Switch this view into `"editing"` mode, displaying the input field.
+ edit: function () {
+ this.$el.addClass('editing');
+ this.$input.focus();
+ },
+
+ // Close the `"editing"` mode, saving changes to the todo.
+ close: function () {
+ var value = this.$input.val();
+ var trimmedValue = value.trim();
+
+ // We don't want to handle blur events from an item that is no
+ // longer being edited. Relying on the CSS class here has the
+ // benefit of us not having to maintain state in the DOM and the
+ // JavaScript logic.
+ if (!this.$el.hasClass('editing')) {
+ return;
+ }
+
+ if (trimmedValue) {
+ this.model.save({ title: trimmedValue });
+ } else {
+ this.clear();
+ }
+
+ this.$el.removeClass('editing');
+ },
+
+ // If you hit `enter`, we're through editing the item.
+ updateOnEnter: function (e) {
+ if (e.which === ENTER_KEY) {
+ this.close();
+ }
+ },
+
+ // If you're pressing `escape` we revert your change by simply leaving
+ // the `editing` state.
+ revertOnEscape: function (e) {
+ if (e.which === ESC_KEY) {
+ this.$el.removeClass('editing');
+ // Also reset the hidden input back to the original value.
+ this.$input.val(this.model.get('title'));
+ }
+ },
+
+ // Remove the item, destroy the model from *localStorage* and delete its view.
+ clear: function () {
+ this.model.destroy();
+ }
+ });
+})(jQuery);