Commit 3c6c77d7 authored by Addy Osmani's avatar Addy Osmani

Merge pull request #56 from addyosmani/structure_reorganization

Reorganized the Folder structure to be more clear and concise.
parents 36093a3f 2ca2a83b
/* App Controllers */ /* App Controllers */
App.Controllers.TodoController = function (persistencejs) { App.Controllers.TodoController = function (persistencejs) {
var self = this; var self = this;
self.newTodo = ""; self.newTodo = "";
self.editTodoStartContent = ""; self.editTodoStartContent = "";
self.addTodo = function() { self.addTodo = function() {
if (self.newTodo.length === 0) return; if (self.newTodo.length === 0) return;
self.todos.push({ self.todos.push({
content: self.newTodo, content: self.newTodo,
done: false, done: false,
editing: false editing: false
}); });
persistencejs.add(self.newTodo); persistencejs.add(self.newTodo);
self.newTodo = ""; self.newTodo = "";
}; };
self.editTodo = function(todo) { self.editTodo = function(todo) {
angular.forEach(self.todos, function(value) { angular.forEach(self.todos, function(value) {
value.editing = false; value.editing = false;
}); });
todo.editing = true; todo.editing = true;
self.editTodoStartContent = todo.content; self.editTodoStartContent = todo.content;
}; };
self.changeStatus = function(todo){ self.changeStatus = function(todo){
persistencejs.changeStatus(todo); persistencejs.changeStatus(todo);
}; };
self.finishEditing = function(todo) { self.finishEditing = function(todo) {
todo.editing = false; todo.editing = false;
persistencejs.edit(self.editTodoStartContent, todo.content); persistencejs.edit(self.editTodoStartContent, todo.content);
}; };
self.removeTodo = function(todo) { self.removeTodo = function(todo) {
angular.Array.remove(self.todos, todo); angular.Array.remove(self.todos, todo);
persistencejs.remove(todo); persistencejs.remove(todo);
}; };
self.todos = []; self.todos = [];
var countTodos = function(done) { var countTodos = function(done) {
return function() { return function() {
return angular.Array.count(self.todos, function(x) { return angular.Array.count(self.todos, function(x) {
return x.done === (done === "done"); return x.done === (done === "done");
}); });
} }
}; };
self.remainingTodos = countTodos("undone"); self.remainingTodos = countTodos("undone");
self.finishedTodos = countTodos("done"); self.finishedTodos = countTodos("done");
self.clearCompletedItems = function() { self.clearCompletedItems = function() {
var oldTodos = self.todos; var oldTodos = self.todos;
self.todos = []; self.todos = [];
angular.forEach(oldTodos, function(todo) { angular.forEach(oldTodos, function(todo) {
if (!todo.done) self.todos.push(todo); if (!todo.done) self.todos.push(todo);
}); });
persistencejs.clearCompletedItems(); persistencejs.clearCompletedItems();
}; };
self.hasFinishedTodos = function() { self.hasFinishedTodos = function() {
return self.finishedTodos() > 0; return self.finishedTodos() > 0;
}; };
self.hasTodos = function() { self.hasTodos = function() {
return self.todos.length > 0; return self.todos.length > 0;
}; };
self.loadTodos = function(){ self.loadTodos = function(){
persistencejs.fetchAll(self); persistencejs.fetchAll(self);
} }
self.refresh = function(){ self.$apply(); } self.refresh = function(){ self.$apply(); }
self.loadTodos(); self.loadTodos();
/* /*
The following code deals with hiding the hint *while* you are typing, The following code deals with hiding the hint *while* you are typing,
showing it once you did *finish* typing (aka 500 ms since you hit the last key) showing it once you did *finish* typing (aka 500 ms since you hit the last key)
*in case* the result is a non empty string *in case* the result is a non empty string
*/ */
Rx.Observable.FromAngularScope(self, "newTodo") Rx.Observable.FromAngularScope(self, "newTodo")
.Do(function() { .Do(function() {
self.showHitEnterHint = false; self.showHitEnterHint = false;
}) })
.Throttle(500) .Throttle(500)
.Select(function(x) { .Select(function(x) {
return x.length > 0; return x.length > 0;
}) })
.ToOutputProperty(self, "showHitEnterHint"); .ToOutputProperty(self, "showHitEnterHint");
}; };
App.Controllers.TodoController.$inject = ['persistencejs']; App.Controllers.TodoController.$inject = ['persistencejs'];
\ No newline at end of file
angular.service('persistencejs', function() { angular.service('persistencejs', function() {
persistence.store.websql.config(persistence, 'todo-angular-persistence', 'todo database', 5*1024*1024); persistence.store.websql.config(persistence, 'todo-angular-persistence', 'todo database', 5*1024*1024);
var Todo = persistence.define('todo', { var Todo = persistence.define('todo', {
content: 'TEXT', content: 'TEXT',
done: 'BOOL' done: 'BOOL'
}); });
persistence.schemaSync(); persistence.schemaSync();
return { return {
add: function(item){ add: function(item){
var t = new Todo(); var t = new Todo();
t.content = item; t.content = item;
t.done = false; t.done = false;
persistence.add(t); persistence.add(t);
persistence.flush(); persistence.flush();
}, },
edit: function(startContent, endContent){ edit: function(startContent, endContent){
Todo.all().filter('content','=',startContent).one(function(item){ Todo.all().filter('content','=',startContent).one(function(item){
item.content = endContent; item.content = endContent;
persistence.flush(); persistence.flush();
}); });
}, },
changeStatus: function(item){ changeStatus: function(item){
Todo.all().filter('content','=',item.content).one(function(todo){ Todo.all().filter('content','=',item.content).one(function(todo){
todo.done = item.done; todo.done = item.done;
persistence.flush(); persistence.flush();
}); });
}, },
clearCompletedItems: function(){ clearCompletedItems: function(){
Todo.all().filter('done','=',true).destroyAll(); Todo.all().filter('done','=',true).destroyAll();
}, },
remove: function(item){ remove: function(item){
Todo.all().filter('content','=',item.content).destroyAll(); Todo.all().filter('content','=',item.content).destroyAll();
}, },
fetchAll: function(controller){ fetchAll: function(controller){
Todo.all().list(function(items){ Todo.all().list(function(items){
var itemCount = items.length; var itemCount = items.length;
var todos = []; var todos = [];
items.forEach(function(item){ items.forEach(function(item){
todos.push({ todos.push({
content: item.content, content: item.content,
done: item.done, done: item.done,
editing: false editing: false
}); });
if(--itemCount == 0){ if(--itemCount == 0){
controller.todos = todos; controller.todos = todos;
controller.refresh(); controller.refresh();
} }
}); });
}); });
}, },
}; };
}); });
/* /*
Content-Type: multipart/related; boundary="_" Content-Type: multipart/related; boundary="_"
--_ --_
Content-Location:img0 Content-Location:img0
Content-Transfer-Encoding:base64 Content-Transfer-Encoding:base64
R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrSLoc/AG8FeUUIN+sGebWAnbKSJodqqlsOxJtqYooU9vvk+vcJIcTkg+QAAA7 R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrSLoc/AG8FeUUIN+sGebWAnbKSJodqqlsOxJtqYooU9vvk+vcJIcTkg+QAAA7
--_ --_
Content-Location:img1 Content-Location:img1
Content-Transfer-Encoding:base64 Content-Transfer-Encoding:base64
R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrCLTcoM29yN6k9socs91e5X3EyJloipYrO4ohTMqA0Fn2XVNswJe+H+SXAAA7 R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrCLTcoM29yN6k9socs91e5X3EyJloipYrO4ohTMqA0Fn2XVNswJe+H+SXAAA7
--_ --_
Content-Location:img2 Content-Location:img2
Content-Transfer-Encoding:base64 Content-Transfer-Encoding:base64
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
--_-- --_--
*/ */
(function(){ (function(){
var jsUri = document.location.href.replace(/\/[^\/]+(#.*)?$/, '/') + var jsUri = document.location.href.replace(/\/[^\/]+(#.*)?$/, '/') +
document.getElementById('ng-ie-compat').src, document.getElementById('ng-ie-compat').src,
css = '#ng-callout .ng-arrow-left{*background-image:url("mhtml:' + jsUri + '!img0")}#ng-callout .ng-arrow-right{*background-image:url("mhtml:' + jsUri + '!img1")}.ng-input-indicator-wait {*background-image:url("mhtml:' + jsUri + '!img2")}', css = '#ng-callout .ng-arrow-left{*background-image:url("mhtml:' + jsUri + '!img0")}#ng-callout .ng-arrow-right{*background-image:url("mhtml:' + jsUri + '!img1")}.ng-input-indicator-wait {*background-image:url("mhtml:' + jsUri + '!img2")}',
s = document.createElement('style'); s = document.createElement('style');
s.setAttribute('type', 'text/css'); s.setAttribute('type', 'text/css');
if (s.styleSheet) { if (s.styleSheet) {
s.styleSheet.cssText = css; s.styleSheet.cssText = css;
} else { } else {
s.appendChild(document.createTextNode(css)); s.appendChild(document.createTextNode(css));
} }
document.getElementsByTagName('head')[0].appendChild(s); document.getElementsByTagName('head')[0].appendChild(s);
})(); })();
(function () { (function () {
var global = this, var global = this,
root = (typeof ProvideCustomRxRootObject == "undefined") ? global.Rx : ProvideCustomRxRootObject(); root = (typeof ProvideCustomRxRootObject == "undefined") ? global.Rx : ProvideCustomRxRootObject();
var observable = root.Observable; var observable = root.Observable;
var observableCreate = observable.Create; var observableCreate = observable.Create;
observable.FromAngularScope = function (angularScope, propertyName) { observable.FromAngularScope = function (angularScope, propertyName) {
return observableCreate(function (observer) { return observableCreate(function (observer) {
var unwatch = angularScope.$watch(function(){ var unwatch = angularScope.$watch(function(){
return angularScope[propertyName]; return angularScope[propertyName];
}, },
function(){ function(){
observer.OnNext(angularScope[propertyName]); observer.OnNext(angularScope[propertyName]);
}); });
return function () { return function () {
unwatch(); unwatch();
}; };
}) })
.Skip(1); //In AngularJS 0.10.x There is no way to avoid initial evaluation. So we take care about it! .Skip(1); //In AngularJS 0.10.x There is no way to avoid initial evaluation. So we take care about it!
}; };
observable.prototype.ToOutputProperty = function (scope, propertyName) { observable.prototype.ToOutputProperty = function (scope, propertyName) {
var disposable = this.Subscribe(function (data) { var disposable = this.Subscribe(function (data) {
scope[propertyName] = data; scope[propertyName] = data;
scope.$apply(); scope.$apply();
}); });
scope.$on('$destroy', function(event){ scope.$on('$destroy', function(event){
//we need to asure that we only dispose the observable when it's our scope that //we need to asure that we only dispose the observable when it's our scope that
//was destroyed. //was destroyed.
//TODO: Figure out if thats enough to asure the above (e.g what happens when //TODO: Figure out if thats enough to asure the above (e.g what happens when
//a child scope will be destroyed but ours won't be affected. Or the other way around, //a child scope will be destroyed but ours won't be affected. Or the other way around,
//if a higher scope will be destroyed (and therefore ours as well) does it mean that $destroy() //if a higher scope will be destroyed (and therefore ours as well) does it mean that $destroy()
//will be also called on our scope or will our scope get destroyed without actually //will be also called on our scope or will our scope get destroyed without actually
//calling $destroy() on it? //calling $destroy() on it?
if (event.targetScope === scope){ if (event.targetScope === scope){
disposable.Dispose(); disposable.Dispose();
} }
}); });
}; };
})(); })();
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment