summaryrefslogtreecommitdiffstats
path: root/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js')
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/app.js32
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/controllers/todoCtrl.js126
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoEscape.js24
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoFocus.js20
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/services/todoStorage.js96
5 files changed, 298 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/app.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/app.js
new file mode 100644
index 0000000000..5f30ea3a11
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/app.js
@@ -0,0 +1,32 @@
+/*global angular */
+
+/**
+ * The main TodoMVC app module
+ *
+ * @type {angular.Module}
+ */
+angular.module('todomvc', ['ngRoute', 'ngResource'])
+ .config(function ($routeProvider) {
+ 'use strict';
+
+ var routeConfig = {
+ controller: 'TodoCtrl',
+ templateUrl: 'todomvc-index.html',
+ resolve: {
+ store: function (todoStorage) {
+ // Get the correct module (API or localStorage).
+ return todoStorage.then(function (module) {
+ module.get(); // Fetch the todo records in the background.
+ return module;
+ });
+ }
+ }
+ };
+
+ $routeProvider
+ .when('/', routeConfig)
+ .when('/:status', routeConfig)
+ .otherwise({
+ redirectTo: '/'
+ });
+ });
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/controllers/todoCtrl.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/controllers/todoCtrl.js
new file mode 100644
index 0000000000..a39d5aec8c
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/controllers/todoCtrl.js
@@ -0,0 +1,126 @@
+/*global angular */
+
+/**
+ * The main controller for the app. The controller:
+ * - retrieves and persists the model via the todoStorage service
+ * - exposes the model to the template and provides event handlers
+ */
+angular.module('todomvc')
+ .controller('TodoCtrl', function TodoCtrl($scope, $routeParams, $filter, store) {
+ 'use strict';
+
+ var todos = $scope.todos = store.todos;
+
+ $scope.newTodo = '';
+ $scope.editedTodo = null;
+ $scope.status = '';
+
+ $scope.$watch('todos', function () {
+ $scope.remainingCount = $filter('filter')(todos, { completed: false }).length;
+ $scope.completedCount = todos.length - $scope.remainingCount;
+ $scope.allChecked = !$scope.remainingCount;
+ }, true);
+
+ // Monitor the current route for changes and adjust the filter accordingly.
+ $scope.$on('$routeChangeSuccess', function () {
+ var status = $scope.status = $routeParams.status || '';
+ $scope.statusFilter = (status === 'active') ?
+ { completed: false } : (status === 'completed') ?
+ { completed: true } : {};
+ });
+
+ $scope.addTodo = function () {
+ var newTodo = {
+ title: $scope.newTodo.trim(),
+ completed: false
+ };
+
+ if (!newTodo.title) {
+ return;
+ }
+
+ $scope.saving = true;
+ store.insert(newTodo)
+ .then(function success() {
+ $scope.newTodo = '';
+ })
+ .finally(function () {
+ $scope.saving = false;
+ });
+ };
+
+ $scope.editTodo = function (todo) {
+ $scope.editedTodo = todo;
+ // Clone the original todo to restore it on demand.
+ $scope.originalTodo = angular.extend({}, todo);
+ };
+
+ $scope.saveEdits = function (todo, event) {
+ // Blur events are automatically triggered after the form submit event.
+ // This does some unfortunate logic handling to prevent saving twice.
+ if (event === 'blur' && $scope.saveEvent === 'submit') {
+ $scope.saveEvent = null;
+ return;
+ }
+
+ $scope.saveEvent = event;
+
+ if ($scope.reverted) {
+ // Todo edits were reverted-- don't save.
+ $scope.reverted = null;
+ return;
+ }
+
+ todo.title = todo.title.trim();
+
+ if (todo.title === $scope.originalTodo.title) {
+ $scope.editedTodo = null;
+ return;
+ }
+
+ store[todo.title ? 'put' : 'delete'](todo)
+ .then(function success() {}, function error() {
+ todo.title = $scope.originalTodo.title;
+ })
+ .finally(function () {
+ $scope.editedTodo = null;
+ });
+ };
+
+ $scope.revertEdits = function (todo) {
+ todos[todos.indexOf(todo)] = $scope.originalTodo;
+ $scope.editedTodo = null;
+ $scope.originalTodo = null;
+ $scope.reverted = true;
+ };
+
+ $scope.removeTodo = function (todo) {
+ store.delete(todo);
+ };
+
+ $scope.saveTodo = function (todo) {
+ store.put(todo);
+ };
+
+ $scope.toggleCompleted = function (todo, completed) {
+ if (angular.isDefined(completed)) {
+ todo.completed = completed;
+ }
+ store.put(todo, todos.indexOf(todo))
+ .then(function success() {}, function error() {
+ todo.completed = !todo.completed;
+ });
+ };
+
+ $scope.clearCompletedTodos = function () {
+ store.clearCompleted();
+ };
+
+ $scope.markAll = function (completed) {
+ todos.forEach(function (todo) {
+ if (todo.completed !== completed) {
+ $scope.toggleCompleted(todo, completed);
+ }
+ });
+ };
+ });
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoEscape.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoEscape.js
new file mode 100644
index 0000000000..944b52c5f3
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoEscape.js
@@ -0,0 +1,24 @@
+/*global angular */
+
+/**
+ * Directive that executes an expression when the element it is applied to gets
+ * an `escape` keydown event.
+ */
+angular.module('todomvc')
+ .directive('todoEscape', function () {
+ 'use strict';
+
+ var ESCAPE_KEY = 27;
+
+ return function (scope, elem, attrs) {
+ elem.bind('keydown', function (event) {
+ if (event.keyCode === ESCAPE_KEY) {
+ scope.$apply(attrs.todoEscape);
+ }
+ });
+
+ scope.$on('$destroy', function () {
+ elem.unbind('keydown');
+ });
+ };
+ });
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoFocus.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoFocus.js
new file mode 100644
index 0000000000..e1e6c21c90
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/directives/todoFocus.js
@@ -0,0 +1,20 @@
+/*global angular */
+
+/**
+ * Directive that places focus on the element it is applied to when the
+ * expression it binds to evaluates to true
+ */
+angular.module('todomvc')
+ .directive('todoFocus', function todoFocus($timeout) {
+ 'use strict';
+
+ return function (scope, elem, attrs) {
+ scope.$watch(attrs.todoFocus, function (newVal) {
+ if (newVal) {
+ $timeout(function () {
+ elem[0].focus();
+ }, 0, false);
+ }
+ });
+ };
+ });
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/services/todoStorage.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/services/todoStorage.js
new file mode 100644
index 0000000000..b68e59628d
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angularjs/js/services/todoStorage.js
@@ -0,0 +1,96 @@
+/*global angular */
+
+/**
+ * Services that persists and retrieves todos from memory or a backend API
+ * if available.
+ *
+ * They both follow the same API, returning promises for all changes to the
+ * model.
+ */
+angular.module('todomvc')
+ .factory('todoStorage', function ($http, $injector) {
+ 'use strict';
+ return Promise.resolve().then(function() {
+ return $injector.get('localCache');
+ });
+ })
+
+ .factory('localCache', function ($q) {
+ 'use strict';
+
+ var STORAGE_ID = 'todos-angularjs';
+
+ var store = {
+ todos: [],
+ cache: [],
+
+ _getFromLocalCache: function () {
+ // return JSON.parse(this.cache[STORAGE_ID] || '[]');
+ return [];
+ },
+
+ _saveToLocalCache: function (todos) {
+ // this.cache[STORAGE_ID] = JSON.stringify(todos);
+ return;
+ },
+
+ clearCompleted: function () {
+ var deferred = $q.defer();
+
+ var incompleteTodos = store.todos.filter(function (todo) {
+ return !todo.completed;
+ });
+
+ angular.copy(incompleteTodos, store.todos);
+
+ store._saveToLocalCache(store.todos);
+ deferred.resolve(store.todos);
+
+ return deferred.promise;
+ },
+
+ delete: function (todo) {
+ var deferred = $q.defer();
+
+ store.todos.splice(store.todos.indexOf(todo), 1);
+
+ store._saveToLocalCache(store.todos);
+ deferred.resolve(store.todos);
+
+ return deferred.promise;
+ },
+
+ get: function () {
+ var deferred = $q.defer();
+
+ angular.copy(store._getFromLocalCache(), store.todos);
+ deferred.resolve(store.todos);
+
+ return deferred.promise;
+ },
+
+ insert: function (todo) {
+ var deferred = $q.defer();
+
+ store.todos.push(todo);
+
+ store._saveToLocalCache(store.todos);
+ deferred.resolve(store.todos);
+
+ return deferred.promise;
+ },
+
+ put: function (todo, index) {
+ var deferred = $q.defer();
+
+ store.todos[index] = todo;
+
+ store._saveToLocalCache(store.todos);
+ deferred.resolve(store.todos);
+
+ return deferred.promise;
+ }
+ };
+
+ return store;
+ });