From d790d39ef4a0f0c69e2599d3d4fc5f22af69b49b 2014-02-05 00:43:50 From: Brian E. Granger Date: 2014-02-05 00:43:50 Subject: [PATCH] Merge pull request #5023 from jdfreder/widget-arrays Widgets- add ability to pack and unpack arrays on JS side. --- diff --git a/IPython/html/static/notebook/js/widgets/widget.js b/IPython/html/static/notebook/js/widgets/widget.js index 9d05c57..17eb1f1 100644 --- a/IPython/html/static/notebook/js/widgets/widget.js +++ b/IPython/html/static/notebook/js/widgets/widget.js @@ -210,6 +210,15 @@ function(WidgetManager, _, Backbone){ // Replace models with model ids recursively. if (value instanceof Backbone.Model) { return value.id; + + } else if ($.isArray(value)) { + var packed = []; + var that = this; + _.each(value, function(sub_value, key) { + packed.push(that._pack_models(sub_value)); + }); + return packed; + } else if (value instanceof Object) { var packed = {}; var that = this; @@ -217,6 +226,7 @@ function(WidgetManager, _, Backbone){ packed[key] = that._pack_models(sub_value); }); return packed; + } else { return value; } @@ -224,13 +234,22 @@ function(WidgetManager, _, Backbone){ _unpack_models: function(value) { // Replace model ids with models recursively. - if (value instanceof Object) { + if ($.isArray(value)) { + var unpacked = []; + var that = this; + _.each(value, function(sub_value, key) { + unpacked.push(that._unpack_models(sub_value)); + }); + return unpacked; + + } else if (value instanceof Object) { var unpacked = {}; var that = this; _.each(value, function(sub_value, key) { unpacked[key] = that._unpack_models(sub_value); }); return unpacked; + } else { var model = this.widget_manager.get_model(value); if (model) { diff --git a/IPython/html/tests/casperjs/test_cases/widgets.js b/IPython/html/tests/casperjs/test_cases/widgets.js index 9943dd4..db26f99 100644 --- a/IPython/html/tests/casperjs/test_cases/widgets.js +++ b/IPython/html/tests/casperjs/test_cases/widgets.js @@ -1,3 +1,33 @@ +var xor = function (a, b) {return !a ^ !b;}; +var isArray = function (a) {return toString.call(a) === "[object Array]" || toString.call(a) === "[object RuntimeArray]";}; +var recursive_compare = function(a, b) { + // Recursively compare two objects. + var same = true; + same = same && !xor(a instanceof Object, b instanceof Object); + same = same && !xor(isArray(a), isArray(b)); + + if (same) { + if (a instanceof Object) { + for (var key in a) { + if (a.hasOwnProperty(key) && !recursive_compare(a[key], b[key])) { + same = false; + break; + } + } + for (var key in b) { + if (b.hasOwnProperty(key) && !recursive_compare(a[key], b[key])) { + same = false; + break; + } + } + } else { + return a === b; + } + } + + return same; +} + // Test the widget framework. casper.notebook_test(function () { var index; @@ -21,6 +51,43 @@ casper.notebook_test(function () { this.test.assert(this.evaluate(function() { return IPython.notebook.kernel.widget_manager !== undefined; }), 'Notebook widget manager instantiated'); + + // Functions that can be used to test the packing and unpacking APIs + var that = this; + var test_pack = function (input) { + var output = that.evaluate(function(input) { + var model = new IPython.WidgetModel(IPython.notebook.kernel.widget_manager, undefined); + var results = model._pack_models(input); + delete model; + return results; + }, {input: input}); + that.test.assert(recursive_compare(input, output), + JSON.stringify(input) + ' passed through Model._pack_model unchanged'); + }; + var test_unpack = function (input) { + var output = that.evaluate(function(input) { + var model = new IPython.WidgetModel(IPython.notebook.kernel.widget_manager, undefined); + var results = model._unpack_models(input); + delete model; + return results; + }, {input: input}); + that.test.assert(recursive_compare(input, output), + JSON.stringify(input) + ' passed through Model._unpack_model unchanged'); + }; + var test_packing = function(input) { + test_pack(input); + test_unpack(input); + }; + + test_packing({0: 'hi', 1: 'bye'}) + test_packing(['hi', 'bye']) + test_packing(['hi', 5]) + test_packing(['hi', '5']) + test_packing([1.0, 0]) + test_packing([1.0, false]) + test_packing([1, false]) + test_packing([1, false, {a: 'hi'}]) + test_packing([1, false, ['hi']]) }); var textbox = {};