From 3708014c06a74871025787334bc63b5f5a882db2 2014-07-08 15:57:56
From: Jonathan Frederic <jdfreder@calpoly.edu>
Date: 2014-07-08 15:57:56
Subject: [PATCH] Fixed buggy behavior

---

diff --git a/IPython/html/static/widgets/js/widget.js b/IPython/html/static/widgets/js/widget.js
index b90b62f..6d71364 100644
--- a/IPython/html/static/widgets/js/widget.js
+++ b/IPython/html/static/widgets/js/widget.js
@@ -321,18 +321,20 @@ function(WidgetManager, _, Backbone){
             var view_ids = this.child_model_views[child_model.id];
             if (view_ids !== undefined) {
 
-                // Remove every view associate with the model id.
-                for (var i =0; i < view_ids.length; i++) {
-                    var view_id = view_ids[i];
-                    var view = this.child_views[view_id];
-                    views.remove();
-                    delete this.child_views[view_id];
-                    child_model.views.pop(view);
+                // Only delete the first view in the list.
+                var view_id = view_ids[0];
+                var view = this.child_views[view_id];
+                delete this.child_views[view_id];
+                delete view_ids[0];
+                child_model.views.pop(view);
+            
+                // Remove the view list specific to this model if it is empty.
+                if (view_ids.length === 0) {
+                    delete this.child_model_views[child_model.id];
                 }
-
-                // Remove the view list specific to this model.
-                delete this.child_model_views[child_model.id];
+                return view;
             }
+            return null;
         },
 
         do_diff: function(old_list, new_list, removed_callback, added_callback) {
diff --git a/IPython/html/static/widgets/js/widget_container.js b/IPython/html/static/widgets/js/widget_container.js
index f7cad2a..cc05f72 100644
--- a/IPython/html/static/widgets/js/widget_container.js
+++ b/IPython/html/static/widgets/js/widget_container.js
@@ -22,9 +22,9 @@ define(["widgets/js/widget"], function(WidgetManager) {
             this.$el.addClass('widget-container')
                 .addClass('vbox');
             this.children={};
-            this.update_children([], this.model.get('_children'));
-            this.model.on('change:_children', function(model, value, options) {
-                this.update_children(model.previous('_children'), value);
+            this.update_children([], this.model.get('children'));
+            this.model.on('change:children', function(model, value, options) {
+                this.update_children(model.previous('children'), value);
             }, this);
             this.update();
 
@@ -51,8 +51,7 @@ define(["widgets/js/widget"], function(WidgetManager) {
 
         remove_child_model: function(model) {
             // Called when a model is removed from the children list.
-            this.child_views[model.id].remove();
-            this.delete_child_view(model);
+            this.delete_child_view(model).remove();
         },
 
         add_child_model: function(model) {
@@ -187,9 +186,9 @@ define(["widgets/js/widget"], function(WidgetManager) {
             this._shown_once = false;
             this.popped_out = true;
 
-            this.update_children([], this.model.get('_children'));
-            this.model.on('change:_children', function(model, value, options) {
-                this.update_children(model.previous('_children'), value);
+            this.update_children([], this.model.get('children'));
+            this.model.on('change:children', function(model, value, options) {
+                this.update_children(model.previous('children'), value);
             }, this);
             this.update();
 
@@ -257,8 +256,7 @@ define(["widgets/js/widget"], function(WidgetManager) {
 
         remove_child_model: function(model) {
             // Called when a child is removed from children list.
-            this.child_views[model.id].remove();
-            this.delete_child_view(model);
+            this.delete_child_view(model).remove();
         },
 
         add_child_model: function(model) {
diff --git a/IPython/html/static/widgets/js/widget_selectioncontainer.js b/IPython/html/static/widgets/js/widget_selectioncontainer.js
index e7981de..fc35596 100644
--- a/IPython/html/static/widgets/js/widget_selectioncontainer.js
+++ b/IPython/html/static/widgets/js/widget_selectioncontainer.js
@@ -25,9 +25,9 @@ define(["widgets/js/widget"], function(WidgetManager){
                 .addClass('panel-group');
             this.containers = [];
             this.model_containers = {};
-            this.update_children([], this.model.get('_children'));
-            this.model.on('change:_children', function(model, value, options) {
-                this.update_children(model.previous('_children'), value);
+            this.update_children([], this.model.get('children'));
+            this.model.on('change:children', function(model, value, options) {
+                this.update_children(model.previous('children'), value);
             }, this);
             this.model.on('change:selected_index', function(model, value, options) {
                 this.update_selected_index(model.previous('selected_index'), value, options);
@@ -163,9 +163,9 @@ define(["widgets/js/widget"], function(WidgetManager){
                 .addClass('tab-content')
                 .appendTo(this.$el);
             this.containers = [];
-            this.update_children([], this.model.get('_children'));
-            this.model.on('change:_children', function(model, value, options) {
-                this.update_children(model.previous('_children'), value);
+            this.update_children([], this.model.get('children'));
+            this.model.on('change:children', function(model, value, options) {
+                this.update_children(model.previous('children'), value);
             }, this);
 
             // Trigger model displayed events for any models that are child to 
@@ -190,12 +190,11 @@ define(["widgets/js/widget"], function(WidgetManager){
 
         remove_child_model: function(model) {
             // Called when a child is removed from children list.
-            var view = this.child_views[model.id];
+            var view = this.delete_child_view(model);
             this.containers.splice(view.parent_tab.tab_text_index, 1);
             view.parent_tab.remove();
             view.parent_container.remove();
             view.remove();
-            this.delete_child_view(model);
         },
 
         add_child_model: function(model) {
diff --git a/IPython/html/widgets/widget_container.py b/IPython/html/widgets/widget_container.py
index b9d12d6..dce2a2f 100644
--- a/IPython/html/widgets/widget_container.py
+++ b/IPython/html/widgets/widget_container.py
@@ -15,16 +15,14 @@ class ContainerWidget(DOMWidget):
     # Child widgets in the container.
     # Using a tuple here to force reassignment to update the list.
     # When a proper notifying-list trait exists, that is what should be used here.
-    children = Tuple()
-    _children = Tuple(sync=True)
-
+    children = Tuple(sync=True)
 
     def __init__(self, **kwargs):
         super(ContainerWidget, self).__init__(**kwargs)
         self.on_displayed(ContainerWidget._fire_children_displayed)
 
     def _fire_children_displayed(self):
-        for child in self._children:
+        for child in self.children:
             child._handle_displayed()