diff --git a/LICENSE b/LICENSE
index 187d4d6..d598d52 100644
--- a/LICENSE
+++ b/LICENSE
@@ -5,8 +5,8 @@ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
-*Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
diff --git a/public/css/boot.css b/public/css/boot.css
deleted file mode 100644
index 2794bfa..0000000
--- a/public/css/boot.css
+++ /dev/null
@@ -1,4 +0,0 @@
-body {
- padding-top: 60px;
-}
-
diff --git a/public/css/main.css b/public/css/main.css
index edbf2a1..3bcf2e1 100644
--- a/public/css/main.css
+++ b/public/css/main.css
@@ -1,3 +1,14 @@
+/*
+ Copyright 2013 Joshua Marsh. All rights reserved. Use of this
+ source code is governed by a BSD-style license that can be found in
+ the LICENSE file.
+*/
+
+body {
+ /* We add the padding for the fixed header. */
+ padding-top: 60px;
+}
+
.all-scroll-cursor {
cursor: all-scroll;
}
@@ -6,34 +17,36 @@
cursor: pointer;
}
+/* This is the style of a completed list item. */
.done-true {
text-decoration: line-through;
color: grey;
}
+/* To enable sorting, we use a list instead of a table, so we
+implement the table striping for lists. */
.list-striped > li {
- line-height: 20px;
- padding: 8px;
- border-top: 1px solid #dddddd;
+ line-height: 20px;
+ padding: 8px;
+ border-top: 1px solid #dddddd;
}
.list-striped li:nth-child(odd) {
background-color: #f9f9f9;
}
-.pad-bottom {
+/* This is used to make a reasonable amount of space between the forms
+and buttons and the list items. */
+.pad-bottom {
padding-bottom: 15px;
}
+/* The text box is slightly off, so we move it up a bit. */
.editing-item {
margin-top: -5px;
- display: none;
-}
-
-.viewing-item {
- display: inline;
}
+/* The drag icon is slightly off, so we move it up a bit. */
.drag-icon {
margin-top: -5px;
}
\ No newline at end of file
diff --git a/public/header.html b/public/header.html
deleted file mode 100644
index e69de29..0000000
diff --git a/public/index.html b/public/index.html
index ea4b8a7..be4fe9d 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,9 +1,14 @@
+
-
-
-
diff --git a/public/js/lists.js b/public/js/lists.js
index 79af990..005d573 100644
--- a/public/js/lists.js
+++ b/public/js/lists.js
@@ -1,9 +1,19 @@
+/*
+ Copyright 2013 Joshua Marsh. All rights reserved. Use of this
+ source code is governed by a BSD-style license that can be found in
+ the LICENSE file.
+*/
+
// ListsCtrl is the controller for viewing all lists.
function ListsCtrl($scope, $location, List) {
+ // The entire list box is clickable and this function handles that
+ // by changing the location path.
$scope.view = function(key) {
$location.path('/view/' + key + '/');
};
+ // This handles clicking the copy button. It pops up the modal and
+ // prepares it's name.
$scope.copymodal = function(key, name, event) {
$scope.copyKey = key;
$scope.copyName = "Copy of " + name;
@@ -14,7 +24,7 @@ function ListsCtrl($scope, $location, List) {
event.stopPropagation();
};
-
+ // This function actually makes the copy of the list.
$scope.copy = function() {
$('#copyModal').modal('hide');
@@ -27,6 +37,8 @@ function ListsCtrl($scope, $location, List) {
};
+ // This function opens up the modal to verify that
+ // they want to delete the list.
$scope.delete = function(key, event) {
$scope.deleteKey = key;
@@ -36,6 +48,7 @@ function ListsCtrl($scope, $location, List) {
event.stopPropagation();
};
+ // This function performs the actual delete.
$scope.sure = function() {
$('#deleteModal').modal('hide');
List.delete($scope.deleteKey, function() {
@@ -45,16 +58,20 @@ function ListsCtrl($scope, $location, List) {
});
};
+ // This function opens up the new modal box.
$scope.new = function() {
$('#newModal').modal();
-
};
+ // If any of the modals click cancel, this is
+ // called to close it.
$scope.back = function() {
$('#newModal').modal('hide');
$('#copyModal').modal('hide');
};
+ // This creates the new list and redirects you to
+ // that list.
$scope.save = function() {
$('#newModal').modal('hide');
List.create({"Name": $scope.name}, function (l) {
@@ -62,6 +79,7 @@ function ListsCtrl($scope, $location, List) {
});
};
+ // To start off, we should get all the lists.
List.getall(function (lists) {
$scope.lists = lists;
});
diff --git a/public/js/rest.js b/public/js/rest.js
index 24974c3..2ff6e88 100644
--- a/public/js/rest.js
+++ b/public/js/rest.js
@@ -1,11 +1,27 @@
+/*
+ Copyright 2013 Joshua Marsh. All rights reserved. Use of this
+ source code is governed by a BSD-style license that can be found in
+ the LICENSE file.
+*/
+
// This is a module for interacting with the rest framework.
angular.module('rest', ['ngResource'])
+ /* This is an interface to the RESTful User service. */
.factory('User', function($resource) {
var User = $resource("/rest/user/", {}, {});
return User;
})
+ /* This is an interface to the RESTful List service. We have
+ * to use a service here because go and angular don't play nicely
+ * together with trailing slashes.
+ */
.service('List', function($http) {
+ // Note: All of these functions accept callback
+ // functions in which the resulting data from the
+ // server is returned.
+
+ // Create a new list.
this.create = function(data, call) {
return $http.post("/rest/list/", data)
.then(function (response) {
@@ -13,6 +29,7 @@ angular.module('rest', ['ngResource'])
});
};
+ // Save an existing list.
this.save = function(data, call) {
return $http.put("/rest/list/" + data.Key + "/", data)
.then(function (response) {
@@ -20,9 +37,11 @@ angular.module('rest', ['ngResource'])
});
};
+ // Check to see if a list has been modified.
this.checkupdate = function(data, call) {
return $http.get("/rest/list/" + data.Key + "/")
.then(function (response) {
+ // We are just going to compare LastModified dates.
var sdate = Date.parseRFC3339(response.data.LastModified);
var mdate = Date.parseRFC3339(data.LastModified);
@@ -31,6 +50,7 @@ angular.module('rest', ['ngResource'])
};
+ // Delete the list wit the given key.
this.delete = function(key, call) {
return $http.delete("/rest/list/" + key + "/")
.then(function(response) {
@@ -38,6 +58,7 @@ angular.module('rest', ['ngResource'])
});
};
+ // Get all lists.
this.getall = function(call) {
return $http.get("/rest/list/")
.then(function(response) {
@@ -46,6 +67,7 @@ angular.module('rest', ['ngResource'])
};
+ // Get a specific list.
this.get = function(key, call) {
return $http.get("/rest/list/" + key + "/")
.then(function(response) {
diff --git a/public/js/routing.js b/public/js/routing.js
index 0a0f383..90cde52 100644
--- a/public/js/routing.js
+++ b/public/js/routing.js
@@ -1,3 +1,9 @@
+/*
+ Copyright 2013 Joshua Marsh. All rights reserved. Use of this
+ source code is governed by a BSD-style license that can be found in
+ the LICENSE file.
+*/
+
// This is the routing mechanism.
angular.module('list', ['rest'])
.config(function ($routeProvider) {
@@ -14,6 +20,8 @@ angular.module('list', ['rest'])
}
)
+ // This is used to auto-focus the items then they are switched
+ // from a span to a text box.
.directive('ngHasfocus', function() {
return function(scope, element, attrs) {
scope.$watch(attrs.ngHasfocus, function (nVal, oVal) {
diff --git a/public/js/user.js b/public/js/user.js
index a6e6446..d5f1cf8 100644
--- a/public/js/user.js
+++ b/public/js/user.js
@@ -1,3 +1,9 @@
+/*
+ Copyright 2013 Joshua Marsh. All rights reserved. Use of this
+ source code is governed by a BSD-style license that can be found in
+ the LICENSE file.
+*/
+
// UserCtrl is the controller for part of the site that lists all of
// the lists.
function UserCtrl($scope, User) {
diff --git a/public/js/view.js b/public/js/view.js
index 1687995..4c1445c 100644
--- a/public/js/view.js
+++ b/public/js/view.js
@@ -1,3 +1,9 @@
+/*
+ Copyright 2013 Joshua Marsh. All rights reserved. Use of this
+ source code is governed by a BSD-style license that can be found in
+ the LICENSE file.
+*/
+
// ViewCtrl is the controller for viewing and updating lists.
function ViewCtrl($scope, $location, $routeParams, $timeout, List) {
@@ -21,11 +27,14 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) {
};
$scope.timer = $timeout($scope.checkupdate, 30000);
+ // This is called when the update button is pressed.
$scope.update = function() {
if ($scope.dirty) {
- // Ask them if they want to merge their changes.
+ // Ask them if they want to merge their changes
+ // if there are changes.
$('#updateModal').modal();
} else {
+ // Otherwise, we can just update.
List.get($routeParams.id, function(l) {
$scope.list = l;
});
@@ -33,12 +42,16 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) {
}
};
+ // This is called when they want to merge their changes with
+ // the latest list.
$scope.updatemerge = function() {
$scope.save();
$scope.updatable = false;
$('#updateModal').modal('hide');
};
+ // This is called when they want to just get the updated list
+ // and lose their changes.
$scope.updateoverwrite = function() {
List.get($routeParams.id, function(l) {
$scope.list = l;
@@ -47,15 +60,20 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) {
$('#updateModal').modal('hide');
};
+ // When the order of the list items change, this is called to
+ // update the internal array that is storing the list items.
$scope.sort = function(event, ui) {
var ids = $("#sortablelist").sortable("toArray");
var items = new Array();
+
+ // Make a new list from the array.
ids.forEach(function(e, i, a) {
var eid = e.replace("list-item-", "");
var id = parseInt(eid);
items.push($scope.list.Items[id]);
});
-
+
+ // Set the list ot be the newly made list.
$scope.list.Items = items;
$scope.dirty = true;
};
@@ -66,6 +84,7 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) {
$scope.list.Items = new Array();
}
+ // We unshift to add it to the top.
$scope.list.Items.unshift({
"Name": $scope.newitem,
"Completed": false,
@@ -115,11 +134,17 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) {
return !item.Delete;
};
+ // Stop propogating a click. This is mainly used by the list
+ // item input text boxes so they don't change the completed
+ // state of the item when they are clicked.
$scope.noclick = function(event) {
// Don't let it fall through to the view.
event.stopPropagation();
};
+ // This changes the state of the item being edited. There
+ // are two special values: -1 is for no item, and -2 is the
+ // title of the list.
$scope.edit = function(id, event) {
$scope.editing = id;
$scope.dirty = true;
@@ -143,6 +168,9 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) {
});
});
+ // Start out with cursor in the add text box.
$('#newitem').focus();
+
+ // We start out not editing any list.
$scope.editing = -1;
}
\ No newline at end of file
diff --git a/public/lists.html b/public/lists.html
index 707e160..29b0ec5 100644
--- a/public/lists.html
+++ b/public/lists.html
@@ -1,22 +1,28 @@
+