]> git.za3k.com Git - flowy.git/commitdiff
View doesn't know about collection, model is always associated with being part of...
authorZachary Vance <vanceza@gmail.com>
Wed, 27 May 2015 00:39:58 +0000 (17:39 -0700)
committerZachary Vance <vanceza@gmail.com>
Wed, 27 May 2015 00:39:58 +0000 (17:39 -0700)
dist/flowy.js
dist/flowy.unwrapped.js
src/models/todo.js
src/views/app.js
src/views/todo.js

index 230d67b7babf8ee22a3261c627f245be4c4e8392..c41bc863cecc7533cae55df4b7cfbe293a3593e2 100644 (file)
@@ -460,21 +460,21 @@ var TodoView = Backbone.View.extend({
     } else {
         this.stopEditingText();
         this.model.toggleComplete();
-        var next = this.model.nextNode(this.model.collection, { childrenAllowed: false}) || this.model.getParent(this.model.collection, { rootAllowed: false});
+        var next = this.model.nextNode({ childrenAllowed: false}) || this.model.getParent({ rootAllowed: false});
         if (!next) return false;
         next.getView().startEditingText();
     }
     return false;
   },
   focusNext: function() {
-    var nextNode = this.model.nextNode(this.model.collection, { childrenAllowed: true });
+    var nextNode = this.model.nextNode({ childrenAllowed: true });
     if (!nextNode) return false;
     this.stopEditingText();
     nextNode.getView().startEditingText();
     return false;
   },
   focusPrevious: function() {
-    var previousNode = this.model.previousNode(this.model.collection, { childrenAllowed: true });
+    var previousNode = this.model.previousNode({ childrenAllowed: true });
     if (!previousNode) return false;
     this.stopEditingText();
     previousNode.getView().startEditingText();
@@ -484,17 +484,17 @@ var TodoView = Backbone.View.extend({
     if (this.model.hasChildren()) {
         return;
     }
-    var previousNode = this.model.previousNode(this.model.collection);
+    var previousNode = this.model.previousNode();
     if (!previousNode) {
         return;
     }
     if (this.model.get("text") === "") {
-        this.model.remove(this.model.collection);
+        this.model.remove();
         previousNode.getView().startEditingText({"atEnd":true});
         return false;
     } else if (this.isFocusAtBeginning()) {
         var text = this.model.get("text");
-        this.model.remove(this.model.collection);
+        this.model.remove();
         previousNode.setText(previousNode.get("text") + '<span class="focus"></span>' + text);
         previousNode.getView().startEditingText({"atMarker": ".focus"});
         return false;
@@ -504,17 +504,17 @@ var TodoView = Backbone.View.extend({
     if (this.model.hasChildren()) {
         return;
     }
-    var nextNode = this.model.nextNode(this.model.collection);
+    var nextNode = this.model.nextNode();
     if (!nextNode) {
         return;
     }
     if (this.model.get("text") === "") {
-        this.model.remove(this.model.collection);
+        this.model.remove();
         nextNode.getView().startEditingText();
         return false;
     } else if (this.isFocusAtEnd()) {
         var text = nextNode.get("text");
-        nextNode.remove(this.model.collection);
+        nextNode.remove();
         this.stopEditingText();
         this.model.setText(this.model.get("text") + '<span class="focus"></span>' + text);
         this.startEditingText({"atMarker": ".focus"});
@@ -524,17 +524,17 @@ var TodoView = Backbone.View.extend({
   "delete": function() {
     // Delete node and its entire subtree
     this.focusPrevious();
-    this.model.removeAll(this.model.collection);
+    this.model.removeAll();
     return false;
   },
   indent: function() {
     // TODO: maintain focus
-    this.model.indent(this.model.collection);
+    this.model.indent();
     return false;
   },
   outdent: function() {
     // TODO: maintain focus
-    this.model.outdent(this.model.collection);
+    this.model.outdent();
   },
   expand: function() {
     console.log("Expand not implemented"); // TODO
@@ -549,14 +549,13 @@ var TodoView = Backbone.View.extend({
   },
   moveDown: function() {
     // TODO: maintain focus
-    this.model.moveDown(this.model.collection);
+    this.model.moveDown();
   },
   moveUp: function() {
     // TODO: maintain focus
-    this.model.moveUp(this.model.collection);
+    this.model.moveUp();
   },
   textChange: function(e) {
-    var collection = this.model.collection;
     var lines = $(e.target).html().split(/<br\\?>/);
     if (lines.length === 0) {
         console.log("unexpected number of lines in textChange");
@@ -581,16 +580,16 @@ var TodoView = Backbone.View.extend({
         this.outdent();
      } else if ((lines.length === 2 && lines[1] === "") || (lines.length === 3 && lines[1] === "" && lines[2] === "")) { // Line break at end
         this.model.setText(this.decodeText(lines[0]));
-        var emptyAfter = this.model.addTodoAfter({text: this.decodeText(lines[1])}, collection); // Child or not depending on whether this has children
+        var emptyAfter = this.model.addTodoAfter({text: this.decodeText(lines[1])}); // Child or not depending on whether this has children
         this.stopEditingText();
         emptyAfter.getView().startEditingText();
      } else if (lines.length === 2 && lines[0] === "") { // Line break at beginning
-        var emptyBefore = this.model.addTodoBefore({text: this.decodeText(lines[0])}, collection);
+        var emptyBefore = this.model.addTodoBefore({text: this.decodeText(lines[0])});
         this.model.setText(this.decodeText(lines[1]));
         this.stopEditingText();
         emptyBefore.getView().startEditingText();
     } else if (lines.length === 2) { // Line break in middle
-        var newNode = this.model.addTodoAfter({text: this.decodeText(lines[1])}, collection);
+        var newNode = this.model.addTodoAfter({text: this.decodeText(lines[1])});
         this.model.setText(this.decodeText(lines[0]));
         this.stopEditingText(); // For re-render
         newNode.getView().startEditingText(); // Keep focus on current node (second half)
@@ -658,59 +657,59 @@ var TodoModel = Backbone.Model.extend({
     getChildrenCount: function() {
         return this.get("bullets").length;
     },
-    getChildren: function(collection) {
+    getChildren: function() {
         return _.map(this.get("bullets"), function(id) {
-            return collection.get(id);
+            return this.collection.get(id);
         }, this);
     },
-    getChild: function(collection, index) {
-        return collection.get(this.get("bullets")[index]);
+    getChild: function(index) {
+        return this.collection.get(this.get("bullets")[index]);
     },
-    getParent: function(collection, options) {
+    getParent: function(options) {
         options = _.defaults({}, options, { rootAllowed: true });
-        var parent = collection.get(this.get("parent"));
-        if (parent && parent.id == collection.rootId && !options.rootAllowed) return undefined;
+        var parent = this.collection.get(this.get("parent"));
+        if (parent && parent.isRoot() && !options.rootAllowed) return undefined;
         return parent;
     },
-    getPreviousSibling: function(collection) {
-        var parent = this.getParent(collection);
+    getPreviousSibling: function() {
+        var parent = this.getParent();
         if (!parent) return undefined;
         var index = parent.findChild(this.id);
         if (index < 0 || index === 0) return undefined;
-        return parent.getChild(collection, index - 1);
+        return parent.getChild(index - 1);
     },
-    getNextSibling: function(collection) {
-        var parent = this.getParent(collection);
+    getNextSibling: function() {
+        var parent = this.getParent();
         if (!parent) return undefined;
         var index = parent.findChild(this.id);
         var numChildren = parent.getChildrenCount();
         if (index < 0 || index === numChildren - 1) return undefined;
-        return parent.getChild(collection, index + 1);
+        return parent.getChild(index + 1);
     },
-    nextNode: function(collection, options) {
+    nextNode: function(options) {
         options = _.defaults({}, options, {childrenAllowed: true});
         if (options.childrenAllowed) {
             if (this.hasChildren()) {
-                return this.getChild(collection, 0);
+                return this.getChild(0);
             }
         }
-        for (var node = this; node && node.id !== collection.rootId; node = node.getParent(collection)) {
-            var next = node.getNextSibling(collection);
+        for (var node = this; node && !node.isRoot(); node = node.getParent()) {
+            var next = node.getNextSibling();
             if (next) return next;
         }
         return undefined;
     },
-    previousNode: function(collection, options) {
+    previousNode: function(options) {
         options = _.defaults({}, options, {childrenAllowed: true});
-        var previous = this.getPreviousSibling(collection);
+        var previous = this.getPreviousSibling();
         if (previous && options.childrenAllowed) {
             while (previous.hasChildren()) {
-                previous = previous.getChild(collection, previous.getChildrenCount() - 1);
+                previous = previous.getChild(previous.getChildrenCount() - 1);
             }
         }
-        if (!previous) previous = this.getParent(collection);
+        if (!previous) previous = this.getParent();
         if (!previous) return undefined;
-        if (previous.id === collection.rootId) {
+        if (previous.isRoot()) {
             return undefined;
         } else {
             return previous;
@@ -719,11 +718,11 @@ var TodoModel = Backbone.Model.extend({
     getView: function() { //TODO: remove
         return this.collection.app.getView(this);
     },
-    isTopLevel: function(collection) {
-        return this.get("parent") === collection.rootId;
+    isTopLevel: function() {
+        return this.get("parent") === this.collection.rootId;
     },
-    isParentLoaded: function(collection, collectionView) {
-        return this.isTopLevel(collection) ? true : (this.getParent(collection) && collectionView.getView(this.getParent(collection)));
+    isParentLoaded: function(collectionView) {
+        return this.isTopLevel() ? true : (this.getParent() && collectionView.getView(this.getParent()));
     },
     findChild: function(childId) {
         return this.get("bullets").indexOf(childId);
@@ -735,14 +734,14 @@ var TodoModel = Backbone.Model.extend({
         this.set("bullets", bullets);
         return this;
     },
-    moveTo: function(newLocation, collection) {
-        if (collection.rootId == this.id) {
+    moveTo: function(newLocation) {
+        if (this.isRoot()) {
             console.log("Cannot move root");
             return this;
         }
         var existingLocation = {
-            parent: this.getParent(collection),
-            index: this.getParent(collection).findChild(this.id),
+            parent: this.getParent(),
+            index: this.getParent().findChild(this.id),
         };
         newLocation = _.defaults({}, newLocation, existingLocation);
         var newChildren;
@@ -767,28 +766,31 @@ var TodoModel = Backbone.Model.extend({
             newLocation.parent.save();
             this.save();
         }
-        collection.trigger("move", this, existingLocation);
+        this.collection.trigger("move", this, existingLocation);
         return this;
     },
-    moveUp: function(collection) {
+    moveUp: function() {
         // Before previous sibling, then as last child of previous node of parent, then before parent, then nothing
     },
-    moveDown: function(collection) {
+    moveDown: function() {
         // After next sibling, then as first child of next node after parent, then up one level, then nothing
     },
-    indent: function(collection) {
+    indent: function() {
         // Last child of previous sibling, then nothing
-        var previous = this.getPreviousSibling(collection);
+        var previous = this.getPreviousSibling();
         if (!previous) return undefined;
         return this.moveTo({
             parent: previous,
             index: previous.getChildrenCount(),
-        }, collection);
+        });
     },
-    outdent: function(collection) {
+    outdent: function() {
         // After parent, then nothing
     },
-    removeChild: function(childTodoModel, collection) {
+    isRoot: function() {
+        return this.id === this.collection.rootId;
+    },
+    removeChild: function(childTodoModel) {
         if (childTodoModel.get("bullets").length > 0) {
             console.log("Cannot delete node with children.");
             return;
@@ -806,48 +808,48 @@ var TodoModel = Backbone.Model.extend({
         }});
         return this;
     },
-    remove: function(collection) {
-        this.getParent(collection).removeChild(this, collection);
+    remove: function() {
+        this.getParent().removeChild(this);
     },
-    removeAll: function(collection) {
-        if (collection.rootId == this.id) {
+    removeAll: function() {
+        if (this.isRoot()) {
             console.log("Cannot remove root node of collection");
             return;
         }
         if (this.hasChildren()) {
-            var children = _.clone(this.getChildren(collection));
+            var children = _.clone(this.getChildren());
             _.each(children, function(child) {
-                child.removeAll(collection);
+                child.removeAll();
             });
         }
-        this.remove(collection);
+        this.remove();
     },
-    addTodoBefore: function(todo, collection) {
+    addTodoBefore: function(todo) {
         // Todo always goes as the previous sibling
-        var parent = this.getParent(collection);
-        var todoModel = collection.create(_.extend(todo, {"parent": parent.id}));
+        var parent = this.getParent();
+        var todoModel = this.collection.create(_.extend(todo, {"parent": parent.id}));
         parent.insertChild(todoModel, parent.findChild(this.id));
         parent.save();
 
-        collection.trigger("add", todoModel);
+        this.collection.trigger("add", todoModel);
         return todoModel;
     },
-    addTodoAfter: function(todo, collection) {
+    addTodoAfter: function(todo) {
         // If there are children, the todo goes as the first child.
         // Otherwise, the todo goes as the next sibling
         var todoModel;
         if (this.get("bullets").length > 0) {
-            todoModel = collection.create(_.extend(todo, {"parent": this.id}));
+            todoModel = this.collection.create(_.extend(todo, {"parent": this.id}));
             this.insertChild(todoModel, 0);
             this.save();
         } else {
-            parent = this.getParent(collection);
-            todoModel = collection.create(_.extend(todo, {"parent": parent.id}));
+            parent = this.getParent();
+            todoModel = this.collection.create(_.extend(todo, {"parent": parent.id}));
             parent.insertChild(todoModel, parent.findChild(this.id)+1);
             parent.save();
         }
 
-        collection.trigger("add", todoModel);
+        this.collection.trigger("add", todoModel);
         return todoModel;
     }
 });
@@ -994,19 +996,19 @@ var AppView = Backbone.View.extend({
             console.log("View rendered more than once for todo #" + todo.id);
             return;
         }
-        var view = new TodoView({model: todo, collection: this.list});
-        if (todo.isTopLevel(this.list)) {
+        var view = new TodoView({model: todo});
+        if (todo.isTopLevel()) {
             this.setView(todo, view);
             this.$("#todo-list").append(view.render().el);
-        } else if (todo.isParentLoaded(this.list, this) && todo.getParent(this.list).findChild(todo.id) >= 0 /* because move/insert is nonatomic */) {
+        } else if (todo.isParentLoaded(this) && todo.getParent().findChild(todo.id) >= 0 /* because move/insert is nonatomic */) {
             this.setView(todo, view);
-            var parent = todo.getParent(this.list);
+            var parent = todo.getParent();
             var parentView = this.getView(parent);
             parentView.addChild(view.render().el, parent.findChild(todo.id));
         }
 
         // Find unrendered descendents and render them, too.
-        _.each(todo.getChildren(this.list), function(child) {
+        _.each(todo.getChildren(), function(child) {
             if (child && !this.getView(child)) {
                this.renderTodo(child); 
             }
index fce3cbc43e0ef86f42c165d6d66459f5b6790746..512f6d9f1f64db3a44c005ac5f0ed2cbf9f2d6c1 100644 (file)
@@ -459,21 +459,21 @@ var TodoView = Backbone.View.extend({
     } else {
         this.stopEditingText();
         this.model.toggleComplete();
-        var next = this.model.nextNode(this.model.collection, { childrenAllowed: false}) || this.model.getParent(this.model.collection, { rootAllowed: false});
+        var next = this.model.nextNode({ childrenAllowed: false}) || this.model.getParent({ rootAllowed: false});
         if (!next) return false;
         next.getView().startEditingText();
     }
     return false;
   },
   focusNext: function() {
-    var nextNode = this.model.nextNode(this.model.collection, { childrenAllowed: true });
+    var nextNode = this.model.nextNode({ childrenAllowed: true });
     if (!nextNode) return false;
     this.stopEditingText();
     nextNode.getView().startEditingText();
     return false;
   },
   focusPrevious: function() {
-    var previousNode = this.model.previousNode(this.model.collection, { childrenAllowed: true });
+    var previousNode = this.model.previousNode({ childrenAllowed: true });
     if (!previousNode) return false;
     this.stopEditingText();
     previousNode.getView().startEditingText();
@@ -483,17 +483,17 @@ var TodoView = Backbone.View.extend({
     if (this.model.hasChildren()) {
         return;
     }
-    var previousNode = this.model.previousNode(this.model.collection);
+    var previousNode = this.model.previousNode();
     if (!previousNode) {
         return;
     }
     if (this.model.get("text") === "") {
-        this.model.remove(this.model.collection);
+        this.model.remove();
         previousNode.getView().startEditingText({"atEnd":true});
         return false;
     } else if (this.isFocusAtBeginning()) {
         var text = this.model.get("text");
-        this.model.remove(this.model.collection);
+        this.model.remove();
         previousNode.setText(previousNode.get("text") + '<span class="focus"></span>' + text);
         previousNode.getView().startEditingText({"atMarker": ".focus"});
         return false;
@@ -503,17 +503,17 @@ var TodoView = Backbone.View.extend({
     if (this.model.hasChildren()) {
         return;
     }
-    var nextNode = this.model.nextNode(this.model.collection);
+    var nextNode = this.model.nextNode();
     if (!nextNode) {
         return;
     }
     if (this.model.get("text") === "") {
-        this.model.remove(this.model.collection);
+        this.model.remove();
         nextNode.getView().startEditingText();
         return false;
     } else if (this.isFocusAtEnd()) {
         var text = nextNode.get("text");
-        nextNode.remove(this.model.collection);
+        nextNode.remove();
         this.stopEditingText();
         this.model.setText(this.model.get("text") + '<span class="focus"></span>' + text);
         this.startEditingText({"atMarker": ".focus"});
@@ -523,17 +523,17 @@ var TodoView = Backbone.View.extend({
   "delete": function() {
     // Delete node and its entire subtree
     this.focusPrevious();
-    this.model.removeAll(this.model.collection);
+    this.model.removeAll();
     return false;
   },
   indent: function() {
     // TODO: maintain focus
-    this.model.indent(this.model.collection);
+    this.model.indent();
     return false;
   },
   outdent: function() {
     // TODO: maintain focus
-    this.model.outdent(this.model.collection);
+    this.model.outdent();
   },
   expand: function() {
     console.log("Expand not implemented"); // TODO
@@ -548,14 +548,13 @@ var TodoView = Backbone.View.extend({
   },
   moveDown: function() {
     // TODO: maintain focus
-    this.model.moveDown(this.model.collection);
+    this.model.moveDown();
   },
   moveUp: function() {
     // TODO: maintain focus
-    this.model.moveUp(this.model.collection);
+    this.model.moveUp();
   },
   textChange: function(e) {
-    var collection = this.model.collection;
     var lines = $(e.target).html().split(/<br\\?>/);
     if (lines.length === 0) {
         console.log("unexpected number of lines in textChange");
@@ -580,16 +579,16 @@ var TodoView = Backbone.View.extend({
         this.outdent();
      } else if ((lines.length === 2 && lines[1] === "") || (lines.length === 3 && lines[1] === "" && lines[2] === "")) { // Line break at end
         this.model.setText(this.decodeText(lines[0]));
-        var emptyAfter = this.model.addTodoAfter({text: this.decodeText(lines[1])}, collection); // Child or not depending on whether this has children
+        var emptyAfter = this.model.addTodoAfter({text: this.decodeText(lines[1])}); // Child or not depending on whether this has children
         this.stopEditingText();
         emptyAfter.getView().startEditingText();
      } else if (lines.length === 2 && lines[0] === "") { // Line break at beginning
-        var emptyBefore = this.model.addTodoBefore({text: this.decodeText(lines[0])}, collection);
+        var emptyBefore = this.model.addTodoBefore({text: this.decodeText(lines[0])});
         this.model.setText(this.decodeText(lines[1]));
         this.stopEditingText();
         emptyBefore.getView().startEditingText();
     } else if (lines.length === 2) { // Line break in middle
-        var newNode = this.model.addTodoAfter({text: this.decodeText(lines[1])}, collection);
+        var newNode = this.model.addTodoAfter({text: this.decodeText(lines[1])});
         this.model.setText(this.decodeText(lines[0]));
         this.stopEditingText(); // For re-render
         newNode.getView().startEditingText(); // Keep focus on current node (second half)
@@ -657,59 +656,59 @@ var TodoModel = Backbone.Model.extend({
     getChildrenCount: function() {
         return this.get("bullets").length;
     },
-    getChildren: function(collection) {
+    getChildren: function() {
         return _.map(this.get("bullets"), function(id) {
-            return collection.get(id);
+            return this.collection.get(id);
         }, this);
     },
-    getChild: function(collection, index) {
-        return collection.get(this.get("bullets")[index]);
+    getChild: function(index) {
+        return this.collection.get(this.get("bullets")[index]);
     },
-    getParent: function(collection, options) {
+    getParent: function(options) {
         options = _.defaults({}, options, { rootAllowed: true });
-        var parent = collection.get(this.get("parent"));
-        if (parent && parent.id == collection.rootId && !options.rootAllowed) return undefined;
+        var parent = this.collection.get(this.get("parent"));
+        if (parent && parent.isRoot() && !options.rootAllowed) return undefined;
         return parent;
     },
-    getPreviousSibling: function(collection) {
-        var parent = this.getParent(collection);
+    getPreviousSibling: function() {
+        var parent = this.getParent();
         if (!parent) return undefined;
         var index = parent.findChild(this.id);
         if (index < 0 || index === 0) return undefined;
-        return parent.getChild(collection, index - 1);
+        return parent.getChild(index - 1);
     },
-    getNextSibling: function(collection) {
-        var parent = this.getParent(collection);
+    getNextSibling: function() {
+        var parent = this.getParent();
         if (!parent) return undefined;
         var index = parent.findChild(this.id);
         var numChildren = parent.getChildrenCount();
         if (index < 0 || index === numChildren - 1) return undefined;
-        return parent.getChild(collection, index + 1);
+        return parent.getChild(index + 1);
     },
-    nextNode: function(collection, options) {
+    nextNode: function(options) {
         options = _.defaults({}, options, {childrenAllowed: true});
         if (options.childrenAllowed) {
             if (this.hasChildren()) {
-                return this.getChild(collection, 0);
+                return this.getChild(0);
             }
         }
-        for (var node = this; node && node.id !== collection.rootId; node = node.getParent(collection)) {
-            var next = node.getNextSibling(collection);
+        for (var node = this; node && !node.isRoot(); node = node.getParent()) {
+            var next = node.getNextSibling();
             if (next) return next;
         }
         return undefined;
     },
-    previousNode: function(collection, options) {
+    previousNode: function(options) {
         options = _.defaults({}, options, {childrenAllowed: true});
-        var previous = this.getPreviousSibling(collection);
+        var previous = this.getPreviousSibling();
         if (previous && options.childrenAllowed) {
             while (previous.hasChildren()) {
-                previous = previous.getChild(collection, previous.getChildrenCount() - 1);
+                previous = previous.getChild(previous.getChildrenCount() - 1);
             }
         }
-        if (!previous) previous = this.getParent(collection);
+        if (!previous) previous = this.getParent();
         if (!previous) return undefined;
-        if (previous.id === collection.rootId) {
+        if (previous.isRoot()) {
             return undefined;
         } else {
             return previous;
@@ -718,11 +717,11 @@ var TodoModel = Backbone.Model.extend({
     getView: function() { //TODO: remove
         return this.collection.app.getView(this);
     },
-    isTopLevel: function(collection) {
-        return this.get("parent") === collection.rootId;
+    isTopLevel: function() {
+        return this.get("parent") === this.collection.rootId;
     },
-    isParentLoaded: function(collection, collectionView) {
-        return this.isTopLevel(collection) ? true : (this.getParent(collection) && collectionView.getView(this.getParent(collection)));
+    isParentLoaded: function(collectionView) {
+        return this.isTopLevel() ? true : (this.getParent() && collectionView.getView(this.getParent()));
     },
     findChild: function(childId) {
         return this.get("bullets").indexOf(childId);
@@ -734,14 +733,14 @@ var TodoModel = Backbone.Model.extend({
         this.set("bullets", bullets);
         return this;
     },
-    moveTo: function(newLocation, collection) {
-        if (collection.rootId == this.id) {
+    moveTo: function(newLocation) {
+        if (this.isRoot()) {
             console.log("Cannot move root");
             return this;
         }
         var existingLocation = {
-            parent: this.getParent(collection),
-            index: this.getParent(collection).findChild(this.id),
+            parent: this.getParent(),
+            index: this.getParent().findChild(this.id),
         };
         newLocation = _.defaults({}, newLocation, existingLocation);
         var newChildren;
@@ -766,28 +765,31 @@ var TodoModel = Backbone.Model.extend({
             newLocation.parent.save();
             this.save();
         }
-        collection.trigger("move", this, existingLocation);
+        this.collection.trigger("move", this, existingLocation);
         return this;
     },
-    moveUp: function(collection) {
+    moveUp: function() {
         // Before previous sibling, then as last child of previous node of parent, then before parent, then nothing
     },
-    moveDown: function(collection) {
+    moveDown: function() {
         // After next sibling, then as first child of next node after parent, then up one level, then nothing
     },
-    indent: function(collection) {
+    indent: function() {
         // Last child of previous sibling, then nothing
-        var previous = this.getPreviousSibling(collection);
+        var previous = this.getPreviousSibling();
         if (!previous) return undefined;
         return this.moveTo({
             parent: previous,
             index: previous.getChildrenCount(),
-        }, collection);
+        });
     },
-    outdent: function(collection) {
+    outdent: function() {
         // After parent, then nothing
     },
-    removeChild: function(childTodoModel, collection) {
+    isRoot: function() {
+        return this.id === this.collection.rootId;
+    },
+    removeChild: function(childTodoModel) {
         if (childTodoModel.get("bullets").length > 0) {
             console.log("Cannot delete node with children.");
             return;
@@ -805,48 +807,48 @@ var TodoModel = Backbone.Model.extend({
         }});
         return this;
     },
-    remove: function(collection) {
-        this.getParent(collection).removeChild(this, collection);
+    remove: function() {
+        this.getParent().removeChild(this);
     },
-    removeAll: function(collection) {
-        if (collection.rootId == this.id) {
+    removeAll: function() {
+        if (this.isRoot()) {
             console.log("Cannot remove root node of collection");
             return;
         }
         if (this.hasChildren()) {
-            var children = _.clone(this.getChildren(collection));
+            var children = _.clone(this.getChildren());
             _.each(children, function(child) {
-                child.removeAll(collection);
+                child.removeAll();
             });
         }
-        this.remove(collection);
+        this.remove();
     },
-    addTodoBefore: function(todo, collection) {
+    addTodoBefore: function(todo) {
         // Todo always goes as the previous sibling
-        var parent = this.getParent(collection);
-        var todoModel = collection.create(_.extend(todo, {"parent": parent.id}));
+        var parent = this.getParent();
+        var todoModel = this.collection.create(_.extend(todo, {"parent": parent.id}));
         parent.insertChild(todoModel, parent.findChild(this.id));
         parent.save();
 
-        collection.trigger("add", todoModel);
+        this.collection.trigger("add", todoModel);
         return todoModel;
     },
-    addTodoAfter: function(todo, collection) {
+    addTodoAfter: function(todo) {
         // If there are children, the todo goes as the first child.
         // Otherwise, the todo goes as the next sibling
         var todoModel;
         if (this.get("bullets").length > 0) {
-            todoModel = collection.create(_.extend(todo, {"parent": this.id}));
+            todoModel = this.collection.create(_.extend(todo, {"parent": this.id}));
             this.insertChild(todoModel, 0);
             this.save();
         } else {
-            parent = this.getParent(collection);
-            todoModel = collection.create(_.extend(todo, {"parent": parent.id}));
+            parent = this.getParent();
+            todoModel = this.collection.create(_.extend(todo, {"parent": parent.id}));
             parent.insertChild(todoModel, parent.findChild(this.id)+1);
             parent.save();
         }
 
-        collection.trigger("add", todoModel);
+        this.collection.trigger("add", todoModel);
         return todoModel;
     }
 });
@@ -993,19 +995,19 @@ var AppView = Backbone.View.extend({
             console.log("View rendered more than once for todo #" + todo.id);
             return;
         }
-        var view = new TodoView({model: todo, collection: this.list});
-        if (todo.isTopLevel(this.list)) {
+        var view = new TodoView({model: todo});
+        if (todo.isTopLevel()) {
             this.setView(todo, view);
             this.$("#todo-list").append(view.render().el);
-        } else if (todo.isParentLoaded(this.list, this) && todo.getParent(this.list).findChild(todo.id) >= 0 /* because move/insert is nonatomic */) {
+        } else if (todo.isParentLoaded(this) && todo.getParent().findChild(todo.id) >= 0 /* because move/insert is nonatomic */) {
             this.setView(todo, view);
-            var parent = todo.getParent(this.list);
+            var parent = todo.getParent();
             var parentView = this.getView(parent);
             parentView.addChild(view.render().el, parent.findChild(todo.id));
         }
 
         // Find unrendered descendents and render them, too.
-        _.each(todo.getChildren(this.list), function(child) {
+        _.each(todo.getChildren(), function(child) {
             if (child && !this.getView(child)) {
                this.renderTodo(child); 
             }
index 58aaf63555f0d369f5421844791f90b99c4406be..dc28a52d58774884ed38a44e19179e808b142306 100644 (file)
@@ -23,59 +23,59 @@ var TodoModel = Backbone.Model.extend({
     getChildrenCount: function() {
         return this.get("bullets").length;
     },
-    getChildren: function(collection) {
+    getChildren: function() {
         return _.map(this.get("bullets"), function(id) {
-            return collection.get(id);
+            return this.collection.get(id);
         }, this);
     },
-    getChild: function(collection, index) {
-        return collection.get(this.get("bullets")[index]);
+    getChild: function(index) {
+        return this.collection.get(this.get("bullets")[index]);
     },
-    getParent: function(collection, options) {
+    getParent: function(options) {
         options = _.defaults({}, options, { rootAllowed: true });
-        var parent = collection.get(this.get("parent"));
-        if (parent && parent.id == collection.rootId && !options.rootAllowed) return undefined;
+        var parent = this.collection.get(this.get("parent"));
+        if (parent && parent.isRoot() && !options.rootAllowed) return undefined;
         return parent;
     },
-    getPreviousSibling: function(collection) {
-        var parent = this.getParent(collection);
+    getPreviousSibling: function() {
+        var parent = this.getParent();
         if (!parent) return undefined;
         var index = parent.findChild(this.id);
         if (index < 0 || index === 0) return undefined;
-        return parent.getChild(collection, index - 1);
+        return parent.getChild(index - 1);
     },
-    getNextSibling: function(collection) {
-        var parent = this.getParent(collection);
+    getNextSibling: function() {
+        var parent = this.getParent();
         if (!parent) return undefined;
         var index = parent.findChild(this.id);
         var numChildren = parent.getChildrenCount();
         if (index < 0 || index === numChildren - 1) return undefined;
-        return parent.getChild(collection, index + 1);
+        return parent.getChild(index + 1);
     },
-    nextNode: function(collection, options) {
+    nextNode: function(options) {
         options = _.defaults({}, options, {childrenAllowed: true});
         if (options.childrenAllowed) {
             if (this.hasChildren()) {
-                return this.getChild(collection, 0);
+                return this.getChild(0);
             }
         }
-        for (var node = this; node && node.id !== collection.rootId; node = node.getParent(collection)) {
-            var next = node.getNextSibling(collection);
+        for (var node = this; node && !node.isRoot(); node = node.getParent()) {
+            var next = node.getNextSibling();
             if (next) return next;
         }
         return undefined;
     },
-    previousNode: function(collection, options) {
+    previousNode: function(options) {
         options = _.defaults({}, options, {childrenAllowed: true});
-        var previous = this.getPreviousSibling(collection);
+        var previous = this.getPreviousSibling();
         if (previous && options.childrenAllowed) {
             while (previous.hasChildren()) {
-                previous = previous.getChild(collection, previous.getChildrenCount() - 1);
+                previous = previous.getChild(previous.getChildrenCount() - 1);
             }
         }
-        if (!previous) previous = this.getParent(collection);
+        if (!previous) previous = this.getParent();
         if (!previous) return undefined;
-        if (previous.id === collection.rootId) {
+        if (previous.isRoot()) {
             return undefined;
         } else {
             return previous;
@@ -84,11 +84,11 @@ var TodoModel = Backbone.Model.extend({
     getView: function() { //TODO: remove
         return this.collection.app.getView(this);
     },
-    isTopLevel: function(collection) {
-        return this.get("parent") === collection.rootId;
+    isTopLevel: function() {
+        return this.get("parent") === this.collection.rootId;
     },
-    isParentLoaded: function(collection, collectionView) {
-        return this.isTopLevel(collection) ? true : (this.getParent(collection) && collectionView.getView(this.getParent(collection)));
+    isParentLoaded: function(collectionView) {
+        return this.isTopLevel() ? true : (this.getParent() && collectionView.getView(this.getParent()));
     },
     findChild: function(childId) {
         return this.get("bullets").indexOf(childId);
@@ -100,14 +100,14 @@ var TodoModel = Backbone.Model.extend({
         this.set("bullets", bullets);
         return this;
     },
-    moveTo: function(newLocation, collection) {
-        if (collection.rootId == this.id) {
+    moveTo: function(newLocation) {
+        if (this.isRoot()) {
             console.log("Cannot move root");
             return this;
         }
         var existingLocation = {
-            parent: this.getParent(collection),
-            index: this.getParent(collection).findChild(this.id),
+            parent: this.getParent(),
+            index: this.getParent().findChild(this.id),
         };
         newLocation = _.defaults({}, newLocation, existingLocation);
         var newChildren;
@@ -132,28 +132,31 @@ var TodoModel = Backbone.Model.extend({
             newLocation.parent.save();
             this.save();
         }
-        collection.trigger("move", this, existingLocation);
+        this.collection.trigger("move", this, existingLocation);
         return this;
     },
-    moveUp: function(collection) {
+    moveUp: function() {
         // Before previous sibling, then as last child of previous node of parent, then before parent, then nothing
     },
-    moveDown: function(collection) {
+    moveDown: function() {
         // After next sibling, then as first child of next node after parent, then up one level, then nothing
     },
-    indent: function(collection) {
+    indent: function() {
         // Last child of previous sibling, then nothing
-        var previous = this.getPreviousSibling(collection);
+        var previous = this.getPreviousSibling();
         if (!previous) return undefined;
         return this.moveTo({
             parent: previous,
             index: previous.getChildrenCount(),
-        }, collection);
+        });
     },
-    outdent: function(collection) {
+    outdent: function() {
         // After parent, then nothing
     },
-    removeChild: function(childTodoModel, collection) {
+    isRoot: function() {
+        return this.id === this.collection.rootId;
+    },
+    removeChild: function(childTodoModel) {
         if (childTodoModel.get("bullets").length > 0) {
             console.log("Cannot delete node with children.");
             return;
@@ -171,48 +174,48 @@ var TodoModel = Backbone.Model.extend({
         }});
         return this;
     },
-    remove: function(collection) {
-        this.getParent(collection).removeChild(this, collection);
+    remove: function() {
+        this.getParent().removeChild(this);
     },
-    removeAll: function(collection) {
-        if (collection.rootId == this.id) {
+    removeAll: function() {
+        if (this.isRoot()) {
             console.log("Cannot remove root node of collection");
             return;
         }
         if (this.hasChildren()) {
-            var children = _.clone(this.getChildren(collection));
+            var children = _.clone(this.getChildren());
             _.each(children, function(child) {
-                child.removeAll(collection);
+                child.removeAll();
             });
         }
-        this.remove(collection);
+        this.remove();
     },
-    addTodoBefore: function(todo, collection) {
+    addTodoBefore: function(todo) {
         // Todo always goes as the previous sibling
-        var parent = this.getParent(collection);
-        var todoModel = collection.create(_.extend(todo, {"parent": parent.id}));
+        var parent = this.getParent();
+        var todoModel = this.collection.create(_.extend(todo, {"parent": parent.id}));
         parent.insertChild(todoModel, parent.findChild(this.id));
         parent.save();
 
-        collection.trigger("add", todoModel);
+        this.collection.trigger("add", todoModel);
         return todoModel;
     },
-    addTodoAfter: function(todo, collection) {
+    addTodoAfter: function(todo) {
         // If there are children, the todo goes as the first child.
         // Otherwise, the todo goes as the next sibling
         var todoModel;
         if (this.get("bullets").length > 0) {
-            todoModel = collection.create(_.extend(todo, {"parent": this.id}));
+            todoModel = this.collection.create(_.extend(todo, {"parent": this.id}));
             this.insertChild(todoModel, 0);
             this.save();
         } else {
-            parent = this.getParent(collection);
-            todoModel = collection.create(_.extend(todo, {"parent": parent.id}));
+            parent = this.getParent();
+            todoModel = this.collection.create(_.extend(todo, {"parent": parent.id}));
             parent.insertChild(todoModel, parent.findChild(this.id)+1);
             parent.save();
         }
 
-        collection.trigger("add", todoModel);
+        this.collection.trigger("add", todoModel);
         return todoModel;
     }
 });
index f515ae929a086587ea28dd3b16789be4350c0777..2d8f3670de2d8f51ae4751644edfa2602334b9b0 100644 (file)
@@ -125,19 +125,19 @@ var AppView = Backbone.View.extend({
             console.log("View rendered more than once for todo #" + todo.id);
             return;
         }
-        var view = new TodoView({model: todo, collection: this.list});
-        if (todo.isTopLevel(this.list)) {
+        var view = new TodoView({model: todo});
+        if (todo.isTopLevel()) {
             this.setView(todo, view);
             this.$("#todo-list").append(view.render().el);
-        } else if (todo.isParentLoaded(this.list, this) && todo.getParent(this.list).findChild(todo.id) >= 0 /* because move/insert is nonatomic */) {
+        } else if (todo.isParentLoaded(this) && todo.getParent().findChild(todo.id) >= 0 /* because move/insert is nonatomic */) {
             this.setView(todo, view);
-            var parent = todo.getParent(this.list);
+            var parent = todo.getParent();
             var parentView = this.getView(parent);
             parentView.addChild(view.render().el, parent.findChild(todo.id));
         }
 
         // Find unrendered descendents and render them, too.
-        _.each(todo.getChildren(this.list), function(child) {
+        _.each(todo.getChildren(), function(child) {
             if (child && !this.getView(child)) {
                this.renderTodo(child); 
             }
index a7a48f08d8d2bbe94787b287dc5de7a6bfee84fc..5c0b41dfc32e1d82b118a3bd5d8c7c898bc4d064 100644 (file)
@@ -68,21 +68,21 @@ var TodoView = Backbone.View.extend({
     } else {
         this.stopEditingText();
         this.model.toggleComplete();
-        var next = this.model.nextNode(this.model.collection, { childrenAllowed: false}) || this.model.getParent(this.model.collection, { rootAllowed: false});
+        var next = this.model.nextNode({ childrenAllowed: false}) || this.model.getParent({ rootAllowed: false});
         if (!next) return false;
         next.getView().startEditingText();
     }
     return false;
   },
   focusNext: function() {
-    var nextNode = this.model.nextNode(this.model.collection, { childrenAllowed: true });
+    var nextNode = this.model.nextNode({ childrenAllowed: true });
     if (!nextNode) return false;
     this.stopEditingText();
     nextNode.getView().startEditingText();
     return false;
   },
   focusPrevious: function() {
-    var previousNode = this.model.previousNode(this.model.collection, { childrenAllowed: true });
+    var previousNode = this.model.previousNode({ childrenAllowed: true });
     if (!previousNode) return false;
     this.stopEditingText();
     previousNode.getView().startEditingText();
@@ -92,17 +92,17 @@ var TodoView = Backbone.View.extend({
     if (this.model.hasChildren()) {
         return;
     }
-    var previousNode = this.model.previousNode(this.model.collection);
+    var previousNode = this.model.previousNode();
     if (!previousNode) {
         return;
     }
     if (this.model.get("text") === "") {
-        this.model.remove(this.model.collection);
+        this.model.remove();
         previousNode.getView().startEditingText({"atEnd":true});
         return false;
     } else if (this.isFocusAtBeginning()) {
         var text = this.model.get("text");
-        this.model.remove(this.model.collection);
+        this.model.remove();
         previousNode.setText(previousNode.get("text") + '<span class="focus"></span>' + text);
         previousNode.getView().startEditingText({"atMarker": ".focus"});
         return false;
@@ -112,17 +112,17 @@ var TodoView = Backbone.View.extend({
     if (this.model.hasChildren()) {
         return;
     }
-    var nextNode = this.model.nextNode(this.model.collection);
+    var nextNode = this.model.nextNode();
     if (!nextNode) {
         return;
     }
     if (this.model.get("text") === "") {
-        this.model.remove(this.model.collection);
+        this.model.remove();
         nextNode.getView().startEditingText();
         return false;
     } else if (this.isFocusAtEnd()) {
         var text = nextNode.get("text");
-        nextNode.remove(this.model.collection);
+        nextNode.remove();
         this.stopEditingText();
         this.model.setText(this.model.get("text") + '<span class="focus"></span>' + text);
         this.startEditingText({"atMarker": ".focus"});
@@ -132,17 +132,17 @@ var TodoView = Backbone.View.extend({
   "delete": function() {
     // Delete node and its entire subtree
     this.focusPrevious();
-    this.model.removeAll(this.model.collection);
+    this.model.removeAll();
     return false;
   },
   indent: function() {
     // TODO: maintain focus
-    this.model.indent(this.model.collection);
+    this.model.indent();
     return false;
   },
   outdent: function() {
     // TODO: maintain focus
-    this.model.outdent(this.model.collection);
+    this.model.outdent();
   },
   expand: function() {
     console.log("Expand not implemented"); // TODO
@@ -157,14 +157,13 @@ var TodoView = Backbone.View.extend({
   },
   moveDown: function() {
     // TODO: maintain focus
-    this.model.moveDown(this.model.collection);
+    this.model.moveDown();
   },
   moveUp: function() {
     // TODO: maintain focus
-    this.model.moveUp(this.model.collection);
+    this.model.moveUp();
   },
   textChange: function(e) {
-    var collection = this.model.collection;
     var lines = $(e.target).html().split(/<br\\?>/);
     if (lines.length === 0) {
         console.log("unexpected number of lines in textChange");
@@ -189,16 +188,16 @@ var TodoView = Backbone.View.extend({
         this.outdent();
      } else if ((lines.length === 2 && lines[1] === "") || (lines.length === 3 && lines[1] === "" && lines[2] === "")) { // Line break at end
         this.model.setText(this.decodeText(lines[0]));
-        var emptyAfter = this.model.addTodoAfter({text: this.decodeText(lines[1])}, collection); // Child or not depending on whether this has children
+        var emptyAfter = this.model.addTodoAfter({text: this.decodeText(lines[1])}); // Child or not depending on whether this has children
         this.stopEditingText();
         emptyAfter.getView().startEditingText();
      } else if (lines.length === 2 && lines[0] === "") { // Line break at beginning
-        var emptyBefore = this.model.addTodoBefore({text: this.decodeText(lines[0])}, collection);
+        var emptyBefore = this.model.addTodoBefore({text: this.decodeText(lines[0])});
         this.model.setText(this.decodeText(lines[1]));
         this.stopEditingText();
         emptyBefore.getView().startEditingText();
     } else if (lines.length === 2) { // Line break in middle
-        var newNode = this.model.addTodoAfter({text: this.decodeText(lines[1])}, collection);
+        var newNode = this.model.addTodoAfter({text: this.decodeText(lines[1])});
         this.model.setText(this.decodeText(lines[0]));
         this.stopEditingText(); // For re-render
         newNode.getView().startEditingText(); // Keep focus on current node (second half)