diff --git a/IPython/html/static/widgets/js/types.js b/IPython/html/static/widgets/js/types.js
new file mode 100644
index 0000000..5cc10b3
--- /dev/null
+++ b/IPython/html/static/widgets/js/types.js
@@ -0,0 +1,50 @@
+// Copyright (c) IPython Development Team.
+// Distributed under the terms of the Modified BSD License.
+
+define([
+ "base/js/utils"
+], function(utils){
+
+ return {
+ widget_serialization: {
+ deserialize: function deserialize_models(value, model) {
+ /**
+ * Replace model ids with models recursively.
+ */
+ var unpacked;
+ if ($.isArray(value)) {
+ unpacked = [];
+ _.each(value, function(sub_value, key) {
+ unpacked.push(deserialize_models(sub_value, model));
+ });
+ return Promise.all(unpacked);
+ } else if (value instanceof Object) {
+ unpacked = {};
+ _.each(value, function(sub_value, key) {
+ unpacked[key] = deserialize_models(sub_value, model);
+ });
+ return utils.resolve_promises_dict(unpacked);
+ } else if (typeof value === 'string' && value.slice(0,10) === "IPY_MODEL_") {
+ // get_model returns a promise already
+ return model.widget_manager.get_model(value.slice(10, value.length));
+ } else {
+ return Promise.resolve(value);
+ }
+ },
+ },
+
+ list_of_numbers: {
+ deserialize: function (value, model) {
+ /* value is a DataView */
+ /* create a float64 typed array */
+ return new Float64Array(value.buffer)
+ },
+ serialize: function (value, model) {
+ return value;
+ },
+ }
+ }
+
+
+
+});
diff --git a/IPython/html/static/widgets/js/widget.js b/IPython/html/static/widgets/js/widget.js
index e5f758d..b837f57 100644
--- a/IPython/html/static/widgets/js/widget.js
+++ b/IPython/html/static/widgets/js/widget.js
@@ -32,6 +32,7 @@ define(["widgets/js/manager",
this.state_lock = null;
this.id = model_id;
this.views = {};
+ this.serializers = {};
this._resolve_received_state = {};
if (comm !== undefined) {
@@ -62,13 +63,13 @@ define(["widgets/js/manager",
return Backbone.Model.apply(this);
},
- send: function (content, callbacks) {
+ send: function (content, callbacks, buffers) {
/**
* Send a custom msg over the comm.
*/
if (this.comm !== undefined) {
var data = {method: 'custom', content: content};
- this.comm.send(data, callbacks);
+ this.comm.send(data, callbacks, {}, buffers);
this.pending_msgs++;
}
},
@@ -136,12 +137,37 @@ define(["widgets/js/manager",
* Handle incoming comm msg.
*/
var method = msg.content.data.method;
+
var that = this;
switch (method) {
case 'update':
this.state_change = this.state_change
.then(function() {
- return that.set_state(msg.content.data.state);
+ var state = msg.content.data.state || {};
+ var buffer_keys = msg.content.data.buffers || [];
+ var buffers = msg.buffers || [];
+ var metadata = msg.content.data.metadata || {};
+ var i,k;
+ for (var i=0; i 0) {
// If this message was sent via backbone itself, it will not
@@ -297,9 +346,7 @@ define(["widgets/js/manager",
} else {
// We haven't exceeded the throttle, send the message like
// normal.
- var data = {method: 'backbone', sync_data: attrs};
- this.comm.send(data, callbacks);
- this.pending_msgs++;
+ this.send_sync_message(attrs, callbacks);
}
}
// Since the comm is a one-way communication, assume the message
@@ -308,68 +355,71 @@ define(["widgets/js/manager",
this._buffered_state_diff = {};
},
- save_changes: function(callbacks) {
- /**
- * Push this model's state to the back-end
- *
- * This invokes a Backbone.Sync.
- */
- this.save(this._buffered_state_diff, {patch: true, callbacks: callbacks});
- },
- _pack_models: function(value) {
- /**
- * Replace models with model ids recursively.
- */
+ send_sync_message: function(attrs, callbacks) {
+ // prepare and send a comm message syncing attrs
var that = this;
- var packed;
- if (value instanceof Backbone.Model) {
- return "IPY_MODEL_" + value.id;
-
- } else if ($.isArray(value)) {
- packed = [];
- _.each(value, function(sub_value, key) {
- packed.push(that._pack_models(sub_value));
- });
- return packed;
- } else if (value instanceof Date || value instanceof String) {
- return value;
- } else if (value instanceof Object) {
- packed = {};
- _.each(value, function(sub_value, key) {
- packed[key] = that._pack_models(sub_value);
- });
- return packed;
-
- } else {
- return value;
+ // first, build a state dictionary with key=the attribute and the value
+ // being the value or the promise of the serialized value
+ var state_promise_dict = {};
+ var keys = Object.keys(attrs);
+ for (var i=0; i