diff --git a/IPython/html/static/notebook/js/widgets/string.js b/IPython/html/static/notebook/js/widgets/string.js index f221d8d..16af4bb 100644 --- a/IPython/html/static/notebook/js/widgets/string.js +++ b/IPython/html/static/notebook/js/widgets/string.js @@ -113,7 +113,7 @@ define(["notebook/js/widget"], function(widget_manager){ // Handles: Backend -> Frontend Sync // Frontent -> Frontend Sync update : function(){ - if (!this.user_invoked_update) { + if (this.$textbox.val() != this.model.get('value')) { this.$textbox.val(this.model.get('value')); } @@ -137,19 +137,15 @@ define(["notebook/js/widget"], function(widget_manager){ // Handles and validates user input. handleChanging: function(e) { - this.user_invoked_update = true; this.model.set('value', e.target.value); this.model.update_other_views(this); - this.user_invoked_update = false; }, // Handles text submition handleKeypress: function(e) { if (e.keyCode == 13) { // Return key - this.user_invoked_update = true; this.model.set('submits', this.model.get('submits') + 1); this.model.update_other_views(this); - this.user_invoked_update = false; } }, }); diff --git a/IPython/html/widgets/widget.py b/IPython/html/widgets/widget.py index 2c540eb..0a2522a 100644 --- a/IPython/html/widgets/widget.py +++ b/IPython/html/widgets/widget.py @@ -58,7 +58,7 @@ class Widget(LoggingConfigurable): old._children.remove(self) # Private/protected declarations - _property_lock = False + _property_lock = (None, None) # Last updated (key, value) from the front-end. Prevents echo. _css = Dict() # Internal CSS property dict _add_class = List() # Used to add a js class to a DOM element (call#, selector, class_name) _remove_class = List() # Used to remove a js class from a DOM element (call#, selector, class_name) @@ -153,20 +153,21 @@ class Widget(LoggingConfigurable): def _handle_recieve_state(self, sync_data): """Called when a state is recieved from the frontend.""" - self._property_lock = True - try: - - # Use _keys instead of keys - Don't get retrieve the css from the client side. - for name in self._keys: - if name in sync_data: + # Use _keys instead of keys - Don't get retrieve the css from the client side. + for name in self._keys: + if name in sync_data: + try: + self._property_lock = (name, sync_data[name]) setattr(self, name, sync_data[name]) - finally: - self._property_lock = False + finally: + self._property_lock = (None, None) def _handle_property_changed(self, name, old, new): """Called when a proeprty has been changed.""" - if not self._property_lock and self._comm is not None: + # Make sure this isn't information that the front-end just sent us. + if self._property_lock[0] != name and self._property_lock[1] != new \ + and self._comm is not None: # TODO: Validate properties. # Send new state to frontend self.send_state(key=name)