diff --git a/IPython/html/static/notebook/js/widgets/widget.js b/IPython/html/static/notebook/js/widgets/widget.js
index cc9a746..41419ad 100644
--- a/IPython/html/static/notebook/js/widgets/widget.js
+++ b/IPython/html/static/notebook/js/widgets/widget.js
@@ -38,6 +38,7 @@ function(widget_manager, underscore, backbone){
this.pending_msgs = 0;
this.msg_throttle = 3;
this.msg_buffer = null;
+ this.key_value_lock = null;
this.id = model_id;
this.views = [];
@@ -89,18 +90,20 @@ function(widget_manager, underscore, backbone){
// Handle when a widget is updated via the python side.
apply_update: function (state) {
- this.updating = true;
- try {
- for (var key in state) {
- if (state.hasOwnProperty(key)) {
- this.set(key, state[key]);
+ //this.updating = true;
+ for (var key in state) {
+ if (state.hasOwnProperty(key)) {
+ var value = state[key];
+ this.key_value_lock = [key, value];
+ try {
+ this.set(key, state[key]);
+ } finally {
+ this.key_value_lock = null;
}
}
- //TODO: are there callbacks that make sense in this case? If so, attach them here as an option
- this.save();
- } finally {
- this.updating = false;
}
+ //TODO: are there callbacks that make sense in this case? If so, attach them here as an option
+ this.save();
},
@@ -130,39 +133,43 @@ function(widget_manager, underscore, backbone){
// Only send updated state if the state hasn't been changed
// during an update.
- if (this.comm !== undefined) {
- if (!this.updating) {
- if (this.pending_msgs >= this.msg_throttle) {
- // The throttle has been exceeded, buffer the current msg so
- // it can be sent once the kernel has finished processing
- // some of the existing messages.
- if (method=='patch') {
- if (this.msg_buffer === null) {
- this.msg_buffer = $.extend({}, model_json); // Copy
- }
- for (attr in options.attrs) {
- this.msg_buffer[attr] = options.attrs[attr];
- }
- } else {
+ if (this.comm !== undefined) {
+ if (this.pending_msgs >= this.msg_throttle) {
+ // The throttle has been exceeded, buffer the current msg so
+ // it can be sent once the kernel has finished processing
+ // some of the existing messages.
+ if (method=='patch') {
+ if (this.msg_buffer === null) {
this.msg_buffer = $.extend({}, model_json); // Copy
}
-
- } else {
- // We haven't exceeded the throttle, send the message like
- // normal. If this is a patch operation, just send the
- // changes.
- var send_json = model_json;
- if (method =='patch') {
- send_json = {};
- for (attr in options.attrs) {
- send_json[attr] = options.attrs[attr];
+ for (attr in options.attrs) {
+ var value = options.attrs[attr];
+ if (this.key_value_lock === null || attr != this.key_value_lock[0] || value != this.key_value_lock[1]) {
+ this.msg_buffer[attr] = value;
}
}
+ } else {
+ this.msg_buffer = $.extend({}, model_json); // Copy
+ }
- var data = {method: 'backbone', sync_data: send_json};
- this.comm.send(data, options.callbacks);
- this.pending_msgs++;
+ } else {
+ // We haven't exceeded the throttle, send the message like
+ // normal. If this is a patch operation, just send the
+ // changes.
+ var send_json = model_json;
+ if (method =='patch') {
+ send_json = {};
+ for (attr in options.attrs) {
+ var value = options.attrs[attr];
+ if (this.key_value_lock === null || attr != this.key_value_lock[0] || value != this.key_value_lock[1]) {
+ send_json[attr] = value;
+ }
+ }
}
+
+ var data = {method: 'backbone', sync_data: send_json};
+ this.comm.send(data, options.callbacks);
+ this.pending_msgs++;
}
}