diff options
Diffstat (limited to 'third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/vanilla-examples/vanillajs/js/controller.js')
-rw-r--r-- | third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/vanilla-examples/vanillajs/js/controller.js | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/vanilla-examples/vanillajs/js/controller.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/vanilla-examples/vanillajs/js/controller.js new file mode 100644 index 0000000000..0fbc62a89e --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/vanilla-examples/vanillajs/js/controller.js @@ -0,0 +1,270 @@ +(function (window) { + 'use strict'; + + /** + * Takes a model and view and acts as the controller between them + * + * @constructor + * @param {object} model The model instance + * @param {object} view The view instance + */ + function Controller(model, view) { + var self = this; + self.model = model; + self.view = view; + + self.view.bind('newTodo', function (title) { + self.addItem(title); + }); + + self.view.bind('itemEdit', function (item) { + self.editItem(item.id); + }); + + self.view.bind('itemEditDone', function (item) { + self.editItemSave(item.id, item.title); + }); + + self.view.bind('itemEditCancel', function (item) { + self.editItemCancel(item.id); + }); + + self.view.bind('itemRemove', function (item) { + self.removeItem(item.id); + }); + + self.view.bind('itemToggle', function (item) { + self.toggleComplete(item.id, item.completed); + }); + + self.view.bind('removeCompleted', function () { + self.removeCompletedItems(); + }); + + self.view.bind('toggleAll', function (status) { + self.toggleAll(status.completed); + }); + } + + /** + * Loads and initialises the view + * + * @param {string} '' | 'active' | 'completed' + */ + Controller.prototype.setView = function (locationHash) { + var route = locationHash.split('/')[1]; + var page = route || ''; + this._updateFilterState(page); + }; + + /** + * An event to fire on load. Will get all items and display them in the + * todo-list + */ + Controller.prototype.showAll = function () { + var self = this; + self.model.read(function (data) { + self.view.render('showEntries', data); + }); + }; + + /** + * Renders all active tasks + */ + Controller.prototype.showActive = function () { + var self = this; + self.model.read({ completed: false }, function (data) { + self.view.render('showEntries', data); + }); + }; + + /** + * Renders all completed tasks + */ + Controller.prototype.showCompleted = function () { + var self = this; + self.model.read({ completed: true }, function (data) { + self.view.render('showEntries', data); + }); + }; + + /** + * An event to fire whenever you want to add an item. Simply pass in the event + * object and it'll handle the DOM insertion and saving of the new item. + */ + Controller.prototype.addItem = function (title) { + var self = this; + + if (title.trim() === '') { + return; + } + + self.model.create(title, function () { + self.view.render('clearNewTodo'); + self._filter(true); + }); + }; + + /* + * Triggers the item editing mode. + */ + Controller.prototype.editItem = function (id) { + var self = this; + self.model.read(id, function (data) { + self.view.render('editItem', {id: id, title: data[0].title}); + }); + }; + + /* + * Finishes the item editing mode successfully. + */ + Controller.prototype.editItemSave = function (id, title) { + var self = this; + title = title.trim(); + + if (title.length !== 0) { + self.model.update(id, {title: title}, function () { + self.view.render('editItemDone', {id: id, title: title}); + }); + } else { + self.removeItem(id); + } + }; + + /* + * Cancels the item editing mode. + */ + Controller.prototype.editItemCancel = function (id) { + var self = this; + self.model.read(id, function (data) { + self.view.render('editItemDone', {id: id, title: data[0].title}); + }); + }; + + /** + * By giving it an ID it'll find the DOM element matching that ID, + * remove it from the DOM and also remove it from storage. + * + * @param {number} id The ID of the item to remove from the DOM and + * storage + */ + Controller.prototype.removeItem = function (id) { + var self = this; + self.model.remove(id, function () { + self.view.render('removeItem', id); + }); + + self._filter(); + }; + + /** + * Will remove all completed items from the DOM and storage. + */ + Controller.prototype.removeCompletedItems = function () { + var self = this; + self.model.read({ completed: true }, function (data) { + data.forEach(function (item) { + self.removeItem(item.id); + }); + }); + + self._filter(); + }; + + /** + * Give it an ID of a model and a checkbox and it will update the item + * in storage based on the checkbox's state. + * + * @param {number} id The ID of the element to complete or uncomplete + * @param {object} checkbox The checkbox to check the state of complete + * or not + * @param {boolean|undefined} silent Prevent re-filtering the todo items + */ + Controller.prototype.toggleComplete = function (id, completed, silent) { + var self = this; + self.model.update(id, { completed: completed }, function () { + self.view.render('elementComplete', { + id: id, + completed: completed + }); + }); + + if (!silent) { + self._filter(); + } + }; + + /** + * Will toggle ALL checkboxes' on/off state and completeness of models. + * Just pass in the event object. + */ + Controller.prototype.toggleAll = function (completed) { + var self = this; + self.model.read({ completed: !completed }, function (data) { + data.forEach(function (item) { + self.toggleComplete(item.id, completed, true); + }); + }); + + self._filter(); + }; + + /** + * Updates the pieces of the page which change depending on the remaining + * number of todos. + */ + Controller.prototype._updateCount = function () { + var self = this; + self.model.getCount(function (todos) { + self.view.render('updateElementCount', todos.active); + self.view.render('clearCompletedButton', { + completed: todos.completed, + visible: todos.completed > 0 + }); + + self.view.render('toggleAll', {checked: todos.completed === todos.total}); + self.view.render('contentBlockVisibility', {visible: todos.total > 0}); + }); + }; + + /** + * Re-filters the todo items, based on the active route. + * @param {boolean|undefined} force forces a re-painting of todo items. + */ + Controller.prototype._filter = function (force) { + var activeRoute = this._activeRoute.charAt(0).toUpperCase() + this._activeRoute.substr(1); + + // Update the elements on the page, which change with each completed todo + this._updateCount(); + + // If the last active route isn't "All", or we're switching routes, we + // re-create the todo item elements, calling: + // this.show[All|Active|Completed](); + if (force || this._lastActiveRoute !== 'All' || this._lastActiveRoute !== activeRoute) { + this['show' + activeRoute](); + } + + this._lastActiveRoute = activeRoute; + }; + + /** + * Simply updates the filter nav's selected states + */ + Controller.prototype._updateFilterState = function (currentPage) { + // Store a reference to the active route, allowing us to re-filter todo + // items as they are marked complete or incomplete. + this._activeRoute = currentPage; + + if (currentPage === '') { + this._activeRoute = 'All'; + } + + this._filter(); + + this.view.render('setFilter', currentPage); + }; + + // Export to window + window.app = window.app || {}; + window.app.Controller = Controller; +})(window); |