mirror of
https://github.com/jupyter/notebook.git
synced 2025-03-13 13:17:50 +08:00
Intermediate changes to javascript side of backbone widgets
This commit is contained in:
parent
518cb4c647
commit
ad1e23bfc2
@ -46,9 +46,9 @@
|
||||
WidgetManager.prototype.attach_comm_manager = function (comm_manager) {
|
||||
this.comm_manager = comm_manager;
|
||||
|
||||
// Register already register widget model types with the comm manager.
|
||||
// Register already-registered widget model types with the comm manager.
|
||||
for (var widget_model_name in this.widget_model_types) {
|
||||
this.comm_manager.register_target(widget_model_name, $.proxy(this._handle_com_open, this));
|
||||
this.comm_manager.register_target(widget_model_name, $.proxy(this._handle_comm_open, this));
|
||||
}
|
||||
};
|
||||
|
||||
@ -57,7 +57,7 @@
|
||||
// Register the widget with the comm manager. Make sure to pass this object's context
|
||||
// in so `this` works in the call back.
|
||||
if (this.comm_manager !== null) {
|
||||
this.comm_manager.register_target(widget_model_name, $.proxy(this._handle_com_open, this));
|
||||
this.comm_manager.register_target(widget_model_name, $.proxy(this._handle_comm_open, this));
|
||||
}
|
||||
this.widget_model_types[widget_model_name] = widget_model_type;
|
||||
};
|
||||
@ -66,12 +66,97 @@
|
||||
WidgetManager.prototype.register_widget_view = function (widget_view_name, widget_view_type) {
|
||||
this.widget_view_types[widget_view_name] = widget_view_type;
|
||||
};
|
||||
WidgetManager.prototype.handle_msg = function(msg, model) {
|
||||
var method = msg.content.data.method;
|
||||
switch (method) {
|
||||
case 'display':
|
||||
var cell = this.get_msg_cell(msg.parent_header.msg_id);
|
||||
if (cell === null) {
|
||||
console.log("Could not determine where the display" +
|
||||
" message was from. Widget will not be displayed");
|
||||
} else {
|
||||
var view = this.create_view(model,
|
||||
msg.content.data.view_name, cell);
|
||||
if (view !== undefined
|
||||
&& cell.widget_subarea !== undefined
|
||||
&& cell.widget_subarea !== null) {
|
||||
cell.widget_area.show();
|
||||
cell.widget_subarea.append(view.$el);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'set_snapshot':
|
||||
var cell = this.get_msg_cell(msg.parent_header.msg_id);
|
||||
cell.metadata.snapshot = msg.content.data.snapshot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WidgetManager.prototype.create_view = function(model, view_name, cell) {
|
||||
view_name = view_name || model.get('default_view_name');
|
||||
var ViewType = this.widget_view_types[view_name];
|
||||
if (ViewType !== undefined && ViewType !== null) {
|
||||
var view = new ViewType({model: model, widget_manager: this, cell: cell});
|
||||
view.render();
|
||||
//this.views.push(view);
|
||||
|
||||
/*
|
||||
// jng: Handle when the view element is remove from the page.
|
||||
// observe the view destruction event and do this. We may need
|
||||
// to override the view's remove method to trigger this event.
|
||||
var that = this;
|
||||
view.$el.on("remove", function () {
|
||||
var index = that.views.indexOf(view);
|
||||
if (index > -1) {
|
||||
that.views.splice(index, 1);
|
||||
}
|
||||
view.remove(); // Clean-up view
|
||||
|
||||
// Close the comm if there are no views left.
|
||||
if (that.views.length() === 0) {
|
||||
//jng: trigger comm close event
|
||||
}
|
||||
|
||||
|
||||
if (that.comm !== undefined) {
|
||||
that.comm.close();
|
||||
delete that.comm.model; // Delete ref so GC will collect widget model.
|
||||
delete that.comm;
|
||||
}
|
||||
delete that.widget_id; // Delete id from model so widget manager cleans up.
|
||||
});
|
||||
*/
|
||||
return view;
|
||||
}
|
||||
},
|
||||
|
||||
WidgetManager.prototype.get_msg_cell = function (msg_id) {
|
||||
var cell = null;
|
||||
// First, check to see if the msg was triggered by cell execution.
|
||||
if (IPython.notebook !== undefined && IPython.notebook !== null) {
|
||||
return IPython.notebook.get_msg_cell(msg_id);
|
||||
cell = IPython.notebook.get_msg_cell(msg_id);
|
||||
}
|
||||
if (cell !== null) {
|
||||
return cell
|
||||
}
|
||||
// Second, check to see if a get_cell callback was defined
|
||||
// for the message. get_cell callbacks are registered for
|
||||
// widget messages, so this block is actually checking to see if the
|
||||
// message was triggered by a widget.
|
||||
var kernel = this.get_kernel();
|
||||
if (kernel !== undefined && kernel !== null) {
|
||||
var callbacks = kernel.get_callbacks_for_msg(msg_id);
|
||||
if (callbacks !== undefined &&
|
||||
callbacks.iopub !== undefined &&
|
||||
callbacks.iopub.get_cell !== undefined) {
|
||||
|
||||
return callbacks.iopub.get_cell();
|
||||
}
|
||||
}
|
||||
|
||||
// Not triggered by a cell or widget (no get_cell callback
|
||||
// exists).
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
@ -109,7 +194,7 @@
|
||||
};
|
||||
|
||||
|
||||
WidgetManager.prototype._handle_com_open = function (comm, msg) {
|
||||
WidgetManager.prototype._handle_comm_open = function (comm, msg) {
|
||||
var widget_type_name = msg.content.target_name;
|
||||
var widget_model = new this.widget_model_types[widget_type_name](this, comm.comm_id, comm);
|
||||
this._model_instances[comm.comm_id] = widget_model;
|
||||
@ -126,4 +211,4 @@
|
||||
|
||||
return IPython.widget_manager;
|
||||
});
|
||||
}());
|
||||
}());
|
||||
|
@ -28,17 +28,15 @@ function(widget_manager, underscore, backbone){
|
||||
this.pending_msgs = 0;
|
||||
this.msg_throttle = 3;
|
||||
this.msg_buffer = null;
|
||||
this.views = [];
|
||||
this.id = widget_id;
|
||||
this._custom_msg_callbacks = [];
|
||||
|
||||
if (comm !== undefined) {
|
||||
|
||||
// Remember comm associated with the model.
|
||||
this.comm = comm;
|
||||
comm.model = this;
|
||||
|
||||
// Hook comm messages up to model.
|
||||
var that = this;
|
||||
comm.on_close($.proxy(this._handle_comm_closed, this));
|
||||
comm.on_msg($.proxy(this._handle_comm_msg, this));
|
||||
}
|
||||
@ -47,68 +45,18 @@ function(widget_manager, underscore, backbone){
|
||||
},
|
||||
|
||||
|
||||
send: function (content, cell) {
|
||||
if (this._has_comm()) {
|
||||
// Used the last modified view as the sender of the message. This
|
||||
// will insure that any python code triggered by the sent message
|
||||
// can create and display widgets and output.
|
||||
if (cell === undefined) {
|
||||
if (this.last_modified_view !== undefined &&
|
||||
this.last_modified_view.cell !== undefined) {
|
||||
cell = this.last_modified_view.cell;
|
||||
}
|
||||
}
|
||||
var callbacks = this._make_callbacks(cell);
|
||||
send: function (content, callbacks) {
|
||||
console.log('send',content, callbacks);
|
||||
if (this.comm !== undefined) {
|
||||
var data = {method: 'custom', custom_content: content};
|
||||
|
||||
this.comm.send(data, callbacks);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
on_view_created: function (callback) {
|
||||
this._view_created_callback = callback;
|
||||
},
|
||||
|
||||
|
||||
on_close: function (callback) {
|
||||
this._close_callback = callback;
|
||||
},
|
||||
|
||||
|
||||
on_msg: function (callback, remove) {
|
||||
if (remove) {
|
||||
var found_index = -1;
|
||||
for (var index in this._custom_msg_callbacks) {
|
||||
if (callback === this._custom_msg_callbacks[index]) {
|
||||
found_index = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_index >= 0) {
|
||||
this._custom_msg_callbacks.splice(found_index, 1);
|
||||
}
|
||||
} else {
|
||||
this._custom_msg_callbacks.push(callback);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
_handle_custom_msg: function (content) {
|
||||
for (var index in this._custom_msg_callbacks) {
|
||||
try {
|
||||
this._custom_msg_callbacks[index](content);
|
||||
} catch (e) {
|
||||
console.log("Exception in widget model msg callback", e, content);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Handle when a widget is closed.
|
||||
_handle_comm_closed: function (msg) {
|
||||
this._execute_views_method('remove');
|
||||
// jng: widget manager should observe the comm_close event and delete views when triggered
|
||||
this.trigger('comm:close');
|
||||
if (this._has_comm()) {
|
||||
delete this.comm.model; // Delete ref so GC will collect widget model.
|
||||
delete this.comm;
|
||||
@ -117,43 +65,19 @@ function(widget_manager, underscore, backbone){
|
||||
},
|
||||
|
||||
|
||||
// Handle incomming comm msg.
|
||||
// Handle incoming comm msg.
|
||||
_handle_comm_msg: function (msg) {
|
||||
var method = msg.content.data.method;
|
||||
switch (method) {
|
||||
case 'display':
|
||||
|
||||
// Try to get the cell.
|
||||
var cell = this._get_msg_cell(msg.parent_header.msg_id);
|
||||
if (cell === null) {
|
||||
console.log("Could not determine where the display" +
|
||||
" message was from. Widget will not be displayed");
|
||||
} else {
|
||||
this.create_views(msg.content.data.view_name,
|
||||
msg.content.data.parent,
|
||||
cell);
|
||||
}
|
||||
break;
|
||||
case 'update':
|
||||
this.apply_update(msg.content.data.state);
|
||||
break;
|
||||
case 'add_class':
|
||||
case 'remove_class':
|
||||
var selector = msg.content.data.selector;
|
||||
if (selector === undefined) {
|
||||
selector = '';
|
||||
}
|
||||
|
||||
var class_list = msg.content.data.class_list;
|
||||
this._execute_views_method(method, selector, class_list);
|
||||
break;
|
||||
case 'set_snapshot':
|
||||
var cell = this._get_msg_cell(msg.parent_header.msg_id);
|
||||
cell.metadata.snapshot = msg.content.data.snapshot;
|
||||
break;
|
||||
case 'custom':
|
||||
this._handle_custom_msg(msg.content.data.custom_content);
|
||||
this.trigger('msg:custom', msg.content.data.custom_content);
|
||||
break;
|
||||
default:
|
||||
// pass on to widget manager
|
||||
this.widget_manager.handle_msg(msg, this);
|
||||
}
|
||||
},
|
||||
|
||||
@ -164,18 +88,7 @@ function(widget_manager, underscore, backbone){
|
||||
try {
|
||||
for (var key in state) {
|
||||
if (state.hasOwnProperty(key)) {
|
||||
if (key == "_css") {
|
||||
|
||||
// Set the css value of the model as an attribute
|
||||
// instead of a backbone trait because we are only
|
||||
// interested in backend css -> frontend css. In
|
||||
// other words, if the css dict changes in the
|
||||
// frontend, we don't need to push the changes to
|
||||
// the backend.
|
||||
this.css = state[key];
|
||||
} else {
|
||||
this.set(key, state[key]);
|
||||
}
|
||||
this.set(key, state[key]);
|
||||
}
|
||||
}
|
||||
this.save();
|
||||
@ -185,17 +98,15 @@ function(widget_manager, underscore, backbone){
|
||||
},
|
||||
|
||||
|
||||
_handle_status: function (cell, msg) {
|
||||
_handle_status: function (msg, callbacks) {
|
||||
//execution_state : ('busy', 'idle', 'starting')
|
||||
if (this._has_comm()) {
|
||||
if (msg.content.execution_state=='idle') {
|
||||
if (this.comm !== undefined) {
|
||||
if (msg.content.execution_state ==='idle') {
|
||||
|
||||
// Send buffer if this message caused another message to be
|
||||
// throttled.
|
||||
if (this.msg_buffer !== null &&
|
||||
this.msg_throttle == this.pending_msgs) {
|
||||
|
||||
var callbacks = this._make_callbacks(cell);
|
||||
this.msg_throttle === this.pending_msgs) {
|
||||
var data = {method: 'backbone', sync_method: 'update', sync_data: this.msg_buffer};
|
||||
this.comm.send(data, callbacks);
|
||||
this.msg_buffer = null;
|
||||
@ -217,7 +128,7 @@ function(widget_manager, underscore, backbone){
|
||||
|
||||
// Only send updated state if the state hasn't been changed
|
||||
// during an update.
|
||||
if (this._has_comm()) {
|
||||
if (this.comm !== undefined) {
|
||||
if (!this.updating) {
|
||||
if (this.pending_msgs >= this.msg_throttle) {
|
||||
// The throttle has been exceeded, buffer the current msg so
|
||||
@ -247,14 +158,7 @@ function(widget_manager, underscore, backbone){
|
||||
}
|
||||
|
||||
var data = {method: 'backbone', sync_method: method, sync_data: send_json};
|
||||
|
||||
var cell = null;
|
||||
if (this.last_modified_view !== undefined && this.last_modified_view !== null) {
|
||||
cell = this.last_modified_view.cell;
|
||||
}
|
||||
|
||||
var callbacks = this._make_callbacks(cell);
|
||||
this.comm.send(data, callbacks);
|
||||
this.comm.send(data, this.cell_callbacks());
|
||||
this.pending_msgs++;
|
||||
}
|
||||
}
|
||||
@ -265,133 +169,22 @@ function(widget_manager, underscore, backbone){
|
||||
return model_json;
|
||||
},
|
||||
|
||||
|
||||
_handle_view_created: function (view) {
|
||||
if (this._view_created_callback) {
|
||||
try {
|
||||
this._view_created_callback(view);
|
||||
} catch (e) {
|
||||
console.log("Exception in widget model view displayed callback", e, view, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
_execute_views_method: function (/* method_name, [argument0], [argument1], [...] */) {
|
||||
var method_name = arguments[0];
|
||||
var args = null;
|
||||
if (arguments.length > 1) {
|
||||
args = [].splice.call(arguments,1);
|
||||
}
|
||||
|
||||
for (var view_index in this.views) {
|
||||
var view = this.views[view_index];
|
||||
var method = view[method_name];
|
||||
if (args === null) {
|
||||
method.apply(view);
|
||||
} else {
|
||||
method.apply(view, args);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Create view that represents the model.
|
||||
create_views: function (view_name, parent_id, cell) {
|
||||
var new_views = [];
|
||||
var view;
|
||||
|
||||
// Try creating and adding the view to it's parent.
|
||||
var displayed = false;
|
||||
if (parent_id !== undefined) {
|
||||
var parent_model = this.widget_manager.get_model(parent_id);
|
||||
if (parent_model !== null) {
|
||||
var parent_views = parent_model.views;
|
||||
for (var parent_view_index in parent_views) {
|
||||
var parent_view = parent_views[parent_view_index];
|
||||
if (parent_view.cell === cell) {
|
||||
if (parent_view.display_child !== undefined) {
|
||||
view = this._create_view(view_name, cell);
|
||||
if (view !== null) {
|
||||
new_views.push(view);
|
||||
parent_view.display_child(view);
|
||||
displayed = true;
|
||||
this._handle_view_created(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no parent view is defined or exists. Add the view's
|
||||
// element to cell's widget div.
|
||||
if (!displayed) {
|
||||
view = this._create_view(view_name, cell);
|
||||
if (view !== null) {
|
||||
new_views.push(view);
|
||||
|
||||
if (cell.widget_subarea !== undefined && cell.widget_subarea !== null) {
|
||||
cell.widget_area.show();
|
||||
cell.widget_subarea.append(view.$el);
|
||||
this._handle_view_created(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Force the new view(s) to update their selves
|
||||
for (var view_index in new_views) {
|
||||
view = new_views[view_index];
|
||||
view.update();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Create a view
|
||||
_create_view: function (view_name, cell) {
|
||||
var ViewType = this.widget_manager.widget_view_types[view_name];
|
||||
if (ViewType !== undefined && ViewType !== null) {
|
||||
var view = new ViewType({model: this});
|
||||
view.render();
|
||||
this.views.push(view);
|
||||
view.cell = cell;
|
||||
|
||||
// Handle when the view element is remove from the page.
|
||||
var that = this;
|
||||
view.$el.on("remove", function () {
|
||||
var index = that.views.indexOf(view);
|
||||
if (index > -1) {
|
||||
that.views.splice(index, 1);
|
||||
}
|
||||
view.remove(); // Clean-up view
|
||||
|
||||
// Close the comm if there are no views left.
|
||||
if (that.views.length() === 0) {
|
||||
if (that._close_callback) {
|
||||
try {
|
||||
that._close_callback(that);
|
||||
} catch (e) {
|
||||
console.log("Exception in widget model close callback", e, that);
|
||||
}
|
||||
}
|
||||
|
||||
if (that._has_comm()) {
|
||||
that.comm.close();
|
||||
delete that.comm.model; // Delete ref so GC will collect widget model.
|
||||
delete that.comm;
|
||||
}
|
||||
delete that.widget_id; // Delete id from model so widget manager cleans up.
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
// Build a callback dict.
|
||||
_make_callbacks: function (cell) {
|
||||
cell_callbacks: function (cell) {
|
||||
var callbacks = {};
|
||||
console.log('cell_callbacks A', cell);
|
||||
if (cell === undefined) {
|
||||
// Used the last modified view as the sender of the message. This
|
||||
// will insure that any python code triggered by the sent message
|
||||
// can create and display widgets and output.
|
||||
if (this.last_modified_view !== undefined &&
|
||||
this.last_modified_view.cell !== undefined) {
|
||||
cell = this.last_modified_view.cell;
|
||||
} else {
|
||||
cell = null;
|
||||
}
|
||||
}
|
||||
console.log('cell_callbacks B', cell);
|
||||
if (cell !== null) {
|
||||
|
||||
// Try to get output handlers
|
||||
@ -402,7 +195,7 @@ function(widget_manager, underscore, backbone){
|
||||
handle_clear_output = $.proxy(cell.output_area.handle_clear_output, cell.output_area);
|
||||
}
|
||||
|
||||
// Create callback dict usign what is known
|
||||
// Create callback dict using what is known
|
||||
var that = this;
|
||||
callbacks = {
|
||||
iopub : {
|
||||
@ -410,7 +203,7 @@ function(widget_manager, underscore, backbone){
|
||||
clear_output : handle_clear_output,
|
||||
|
||||
status : function (msg) {
|
||||
that._handle_status(cell, msg);
|
||||
that._handle_status(msg, that.cell_callbacks(cell));
|
||||
},
|
||||
|
||||
// Special function only registered by widget messages.
|
||||
@ -422,57 +215,86 @@ function(widget_manager, underscore, backbone){
|
||||
},
|
||||
};
|
||||
}
|
||||
console.log('constructed callbacks for',cell);
|
||||
return callbacks;
|
||||
},
|
||||
|
||||
|
||||
// Get the output area corresponding to the msg_id.
|
||||
// cell is an instance of IPython.Cell
|
||||
_get_msg_cell: function (msg_id) {
|
||||
|
||||
// First, check to see if the msg was triggered by cell execution.
|
||||
var cell = this.widget_manager.get_msg_cell(msg_id);
|
||||
if (cell !== null) {
|
||||
return cell;
|
||||
}
|
||||
|
||||
// Second, check to see if a get_cell callback was defined
|
||||
// for the message. get_cell callbacks are registered for
|
||||
// widget messages, so this block is actually checking to see if the
|
||||
// message was triggered by a widget.
|
||||
var kernel = this.widget_manager.get_kernel();
|
||||
if (kernel !== undefined && kernel !== null) {
|
||||
var callbacks = kernel.get_callbacks_for_msg(msg_id);
|
||||
if (callbacks !== undefined &&
|
||||
callbacks.iopub !== undefined &&
|
||||
callbacks.iopub.get_cell !== undefined) {
|
||||
|
||||
return callbacks.iopub.get_cell();
|
||||
}
|
||||
}
|
||||
|
||||
// Not triggered by a cell or widget (no get_cell callback
|
||||
// exists).
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
// Function that checks if a comm has been attached to this widget
|
||||
// model. Returns True if a valid comm is attached.
|
||||
_has_comm: function() {
|
||||
return this.comm !== undefined && this.comm !== null;
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// WidgetView class
|
||||
//--------------------------------------------------------------------
|
||||
var WidgetView = Backbone.View.extend({
|
||||
|
||||
initialize: function () {
|
||||
var BaseWidgetView = Backbone.View.extend({
|
||||
initialize: function(options) {
|
||||
this.model.on('change',this.update,this);
|
||||
this.widget_manager = options.widget_manager;
|
||||
this.comm_manager = options.widget_manager.comm_manager;
|
||||
this.cell = options.cell
|
||||
this.render();
|
||||
// jng: maybe the following shouldn't be automatic---maybe the render method should take
|
||||
// care of knowing what needs to be added as a child?
|
||||
var children_attr = this.model.get('_children_attr');
|
||||
for (var i in children_attr) {
|
||||
var child_attr = children_attr[i];
|
||||
var child_model = this.comm_manager.comms[this.model.get(child_attr)].model;
|
||||
var child_view_name = this.child_view_name(child_attr, child_model);
|
||||
var child_view = this.widget_manager.create_view(child_model, child_view_name, this.cell);
|
||||
this.add_child_view(child_attr, child_view);
|
||||
}
|
||||
var children_lists_attr = this.model.get('_children_lists_attr')
|
||||
for (var i in children_lists_attr) {
|
||||
var child_attr = children_lists_attr[i];
|
||||
var child_list = this.model.get(child_attr);
|
||||
for (var j in child_list) {
|
||||
var child_model = this.comm_manager.comms[child_list[j]].model;
|
||||
var child_view_name = this.child_view_name(child_attr, child_model);
|
||||
var child_view = this.widget_manager.create_view(child_model, child_view_name, this.cell);
|
||||
this.add_child_view(child_attr, child_view);
|
||||
}
|
||||
}
|
||||
},
|
||||
update: function(){
|
||||
// update thyself to be consistent with this.model
|
||||
},
|
||||
|
||||
child_view: function(attr, viewname) {
|
||||
var child_model = this.comm_manager.comms[this.model.get(attr)].model;
|
||||
var child_view = this.widget_manager.create_view(child_model, view_name, this.cell);
|
||||
return child_view;
|
||||
},
|
||||
|
||||
render: function(){
|
||||
// render thyself
|
||||
},
|
||||
child_view_name: function(attr, model) {
|
||||
// attr is the name of the attribute we are constructing a view for
|
||||
// model is the model stored in that attribute
|
||||
// return a valid view_name to construct a view of that type
|
||||
// or null for the default view for the model
|
||||
return null;
|
||||
},
|
||||
add_child_view: function(attr, view) {
|
||||
//attr is the name of the attribute containing a reference to this child
|
||||
//view is the child view that has been constructed
|
||||
//typically this will just add the child view's view.el attribute to some dom element
|
||||
},
|
||||
|
||||
send: function (content) {
|
||||
this.model.send(content, this.model.cell_callbacks(this.cell));
|
||||
},
|
||||
|
||||
touch: function () {
|
||||
this.model.last_modified_view = this;
|
||||
this.model.save(this.model.changedAttributes(), {patch: true});
|
||||
},
|
||||
|
||||
|
||||
});
|
||||
|
||||
var WidgetView = BaseWidgetView.extend({
|
||||
initialize: function (options) {
|
||||
this.visible = true;
|
||||
this.model.on('sync',this.update,this);
|
||||
BaseWidgetView.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
add_class: function (selector, class_list) {
|
||||
@ -489,27 +311,12 @@ function(widget_manager, underscore, backbone){
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
send: function (content) {
|
||||
this.model.send(content, this.cell);
|
||||
},
|
||||
|
||||
|
||||
touch: function () {
|
||||
this.model.last_modified_view = this;
|
||||
this.model.save(this.model.changedAttributes(), {patch: true});
|
||||
},
|
||||
|
||||
update: function () {
|
||||
if (this.model.get('visible') !== undefined) {
|
||||
if (this.visible != this.model.get('visible')) {
|
||||
this.visible = this.model.get('visible');
|
||||
if (this.visible) {
|
||||
this.$el.show();
|
||||
} else {
|
||||
this.$el.hide();
|
||||
}
|
||||
}
|
||||
// jng: hook into change:visible trigger
|
||||
var visible = this.model.get('visible');
|
||||
if (visible !== undefined && this.visible !== visible) {
|
||||
this.visible = visible;
|
||||
this.$el.toggle(visible)
|
||||
}
|
||||
|
||||
if (this.model.css !== undefined) {
|
||||
@ -552,4 +359,4 @@ function(widget_manager, underscore, backbone){
|
||||
IPython.WidgetView = WidgetView;
|
||||
|
||||
return widget_manager;
|
||||
});
|
||||
});
|
||||
|
@ -52,16 +52,21 @@ define(["notebook/js/widgets/base"], function(widget_manager) {
|
||||
render: function(){
|
||||
this.$el
|
||||
.addClass('widget-container');
|
||||
var children = this.model.get('children')
|
||||
for(var i in this.model.get('children')) {
|
||||
|
||||
this.update()
|
||||
},
|
||||
|
||||
update: function(){
|
||||
set_flex_properties(this, this.$el);
|
||||
return IPython.WidgetView.prototype.update.call(this);
|
||||
},
|
||||
|
||||
display_child: function(view) {
|
||||
this.$el.append(view.$el);
|
||||
},
|
||||
add_child_view: function(attr, view) {
|
||||
if (attr==='children') {
|
||||
this.$el.append(view.$el);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
widget_manager.register_widget_view('ContainerView', ContainerView);
|
||||
@ -229,8 +234,10 @@ define(["notebook/js/widgets/base"], function(widget_manager) {
|
||||
return IPython.WidgetView.prototype.update.call(this);
|
||||
},
|
||||
|
||||
display_child: function(view) {
|
||||
this.$body.append(view.$el);
|
||||
add_child_view: function(attr, view) {
|
||||
if (attr==='children') {
|
||||
this.$body.append(view.$el);
|
||||
}
|
||||
},
|
||||
|
||||
_get_selector_element: function(selector) {
|
||||
|
@ -27,7 +27,6 @@ define(["notebook/js/widgets/base"], function(widget_manager){
|
||||
.addClass('accordion');
|
||||
this.containers = [];
|
||||
},
|
||||
|
||||
update: function() {
|
||||
// Set tab titles
|
||||
var titles = this.model.get('_titles');
|
||||
@ -58,7 +57,7 @@ define(["notebook/js/widgets/base"], function(widget_manager){
|
||||
return IPython.WidgetView.prototype.update.call(this);
|
||||
},
|
||||
|
||||
display_child: function(view) {
|
||||
add_child_view: function(attr, view) {
|
||||
|
||||
var index = this.containers.length;
|
||||
var uuid = IPython.utils.uuid();
|
||||
@ -103,7 +102,13 @@ define(["notebook/js/widgets/base"], function(widget_manager){
|
||||
|
||||
var TabView = IPython.WidgetView.extend({
|
||||
|
||||
initialize: function() {
|
||||
this.containers = [];
|
||||
IPython.WidgetView.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
render: function(){
|
||||
console.log('rendering tabs', this);
|
||||
var uuid = 'tabs'+IPython.utils.uuid();
|
||||
var that = this;
|
||||
this.$tabs = $('<div />', {id: uuid})
|
||||
@ -113,8 +118,7 @@ define(["notebook/js/widgets/base"], function(widget_manager){
|
||||
this.$tab_contents = $('<div />', {id: uuid + 'Content'})
|
||||
.addClass('tab-content')
|
||||
.appendTo(this.$el);
|
||||
|
||||
this.containers = [];
|
||||
this.update();
|
||||
},
|
||||
|
||||
update: function() {
|
||||
@ -135,8 +139,8 @@ define(["notebook/js/widgets/base"], function(widget_manager){
|
||||
return IPython.WidgetView.prototype.update.call(this);
|
||||
},
|
||||
|
||||
display_child: function(view) {
|
||||
|
||||
add_child_view: function(attr, view) {
|
||||
console.log('adding child view', attr, view);
|
||||
var index = this.containers.length;
|
||||
var uuid = IPython.utils.uuid();
|
||||
|
||||
|
@ -86,7 +86,7 @@ var IPython = (function (IPython) {
|
||||
try {
|
||||
f(comm, msg);
|
||||
} catch (e) {
|
||||
console.log("Exception opening new comm:", e, msg);
|
||||
console.log("Exception opening new comm:", e, e.stack, msg);
|
||||
comm.close();
|
||||
this.unregister_comm(comm);
|
||||
}
|
||||
@ -102,7 +102,7 @@ var IPython = (function (IPython) {
|
||||
try {
|
||||
comm.handle_close(msg);
|
||||
} catch (e) {
|
||||
console.log("Exception closing comm: ", e, msg);
|
||||
console.log("Exception closing comm: ", e, e.stack, msg);
|
||||
}
|
||||
};
|
||||
|
||||
@ -115,7 +115,7 @@ var IPython = (function (IPython) {
|
||||
try {
|
||||
comm.handle_msg(msg);
|
||||
} catch (e) {
|
||||
console.log("Exception handling comm msg: ", e, msg);
|
||||
console.log("Exception handling comm msg: ", e, e.stack, msg);
|
||||
}
|
||||
};
|
||||
|
||||
@ -176,7 +176,7 @@ var IPython = (function (IPython) {
|
||||
try {
|
||||
callback(msg);
|
||||
} catch (e) {
|
||||
console.log("Exception in Comm callback", e, msg);
|
||||
console.log("Exception in Comm callback", e, e.stack, msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -34,9 +34,13 @@ from IPython.utils.py3compat import string_types
|
||||
class BaseWidget(LoggingConfigurable):
|
||||
|
||||
# Shared declarations (Class level)
|
||||
_keys = List(Unicode, help="List of keys comprising the state of the model.")
|
||||
_children_attr = List(Unicode, help="List of keys of children objects of the model.")
|
||||
_children_lists_attr = List(Unicode, help="List of keys containing lists of children objects of the model.")
|
||||
_keys = List(Unicode, default_value = [],
|
||||
help="List of keys comprising the state of the model.", allow_none=False)
|
||||
_children_attr = List(Unicode, default_value = [],
|
||||
help="List of keys of children objects of the model.", allow_none=False)
|
||||
_children_lists_attr = List(Unicode, default_value = [],
|
||||
help="List of keys containing lists of children objects of the model.",
|
||||
allow_none=False)
|
||||
widget_construction_callback = None
|
||||
|
||||
def on_widget_constructed(callback):
|
||||
@ -59,9 +63,10 @@ class BaseWidget(LoggingConfigurable):
|
||||
to use to represent the widget.""")
|
||||
|
||||
# Private/protected declarations
|
||||
# todo: change this to a context manager
|
||||
_property_lock = (None, None) # Last updated (key, value) from the front-end. Prevents echo.
|
||||
_displayed = False
|
||||
_comm = None
|
||||
_comm = Instance('IPython.kernel.comm.Comm')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Public constructor
|
||||
@ -72,6 +77,7 @@ class BaseWidget(LoggingConfigurable):
|
||||
|
||||
# Register after init to allow default values to be specified
|
||||
# TODO: register three different handlers, one for each list, and abstract out the common parts
|
||||
#print self.keys, self._children_attr, self._children_lists_attr
|
||||
self.on_trait_change(self._handle_property_changed, self.keys+self._children_attr+self._children_lists_attr)
|
||||
Widget._handle_widget_constructed(self)
|
||||
|
||||
@ -90,7 +96,7 @@ class BaseWidget(LoggingConfigurable):
|
||||
# Properties
|
||||
@property
|
||||
def keys(self):
|
||||
keys = ['_children_attr', '_children_lists_attr']
|
||||
keys = ['_children_attr', '_children_lists_attr', 'default_view_name']
|
||||
keys.extend(self._keys)
|
||||
return keys
|
||||
|
||||
@ -118,7 +124,6 @@ class BaseWidget(LoggingConfigurable):
|
||||
if 'custom_content' in data:
|
||||
self._handle_custom_msg(data['custom_content'])
|
||||
|
||||
|
||||
def _handle_custom_msg(self, content):
|
||||
"""Called when a custom msg is recieved."""
|
||||
for handler in self._msg_callbacks:
|
||||
@ -153,7 +158,7 @@ class BaseWidget(LoggingConfigurable):
|
||||
|
||||
|
||||
def _handle_property_changed(self, name, old, new):
|
||||
"""Called when a proeprty has been changed."""
|
||||
"""Called when a property has been changed."""
|
||||
# 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:
|
||||
# Send new state to frontend
|
||||
@ -197,7 +202,7 @@ class BaseWidget(LoggingConfigurable):
|
||||
self._send({"method": "update",
|
||||
"state": self.get_state()})
|
||||
|
||||
def get_state(self, key=None)
|
||||
def get_state(self, key=None):
|
||||
"""Gets the widget state, or a piece of it.
|
||||
|
||||
Parameters
|
||||
@ -308,15 +313,18 @@ class BaseWidget(LoggingConfigurable):
|
||||
def _open_communication(self):
|
||||
"""Opens a communication with the front-end."""
|
||||
# Create a comm.
|
||||
if not hasattr(self, '_comm') or self._comm is None:
|
||||
if self._comm is None:
|
||||
self._comm = Comm(target_name=self.target_name)
|
||||
self._comm.on_msg(self._handle_msg)
|
||||
self._comm.on_close(self._close_communication)
|
||||
|
||||
# first update
|
||||
self.send_state()
|
||||
|
||||
|
||||
def _close_communication(self):
|
||||
"""Closes a communication with the front-end."""
|
||||
if hasattr(self, '_comm') and self._comm is not None:
|
||||
if self._comm is not None:
|
||||
try:
|
||||
self._comm.close()
|
||||
finally:
|
||||
@ -332,9 +340,6 @@ class BaseWidget(LoggingConfigurable):
|
||||
return False
|
||||
|
||||
class Widget(BaseWidget):
|
||||
|
||||
_children = List(Instance('IPython.html.widgets.widget.Widget'))
|
||||
_children_lists_attr = List(Unicode, ['_children'])
|
||||
visible = Bool(True, help="Whether or not the widget is visible.")
|
||||
|
||||
# Private/protected declarations
|
||||
|
@ -59,7 +59,7 @@ class ButtonWidget(Widget):
|
||||
|
||||
|
||||
def _handle_button_msg(self, content):
|
||||
"""Hanlde a msg from the front-end
|
||||
"""Handle a msg from the front-end
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -14,7 +14,7 @@ Represents a container that can be used to group other widgets.
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
from .widget import Widget
|
||||
from IPython.utils.traitlets import Unicode, Bool
|
||||
from IPython.utils.traitlets import Unicode, Bool, List, Instance
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Classes
|
||||
@ -23,6 +23,9 @@ class ContainerWidget(Widget):
|
||||
target_name = Unicode('ContainerWidgetModel')
|
||||
default_view_name = Unicode('ContainerView')
|
||||
|
||||
children = []#List(Instance('IPython.html.widgets.widget.Widget'))
|
||||
_children_lists_attr = List(Unicode, ['children'])
|
||||
|
||||
# Keys, all private and managed by helper methods. Flexible box model
|
||||
# classes...
|
||||
_keys = ['_vbox', '_hbox', '_align_start', '_align_end', '_align_center',
|
||||
|
@ -15,7 +15,7 @@ pages.
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
from .widget import Widget
|
||||
from IPython.utils.traitlets import Unicode, Dict, Int
|
||||
from IPython.utils.traitlets import Unicode, Dict, Int, List, Instance
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Classes
|
||||
@ -29,9 +29,12 @@ class MulticontainerWidget(Widget):
|
||||
_titles = Dict(help="Titles of the pages")
|
||||
selected_index = Int(0)
|
||||
|
||||
children = []#List(Instance('IPython.html.widgets.widget.Widget'))
|
||||
_children_lists_attr = List(Unicode, ['children'])
|
||||
|
||||
# Public methods
|
||||
def set_title(self, index, title):
|
||||
"""Sets the title of a container pages
|
||||
"""Sets the title of a container page
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -110,7 +110,17 @@
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'value', 'step', 'max', 'min', 'disabled', 'orientation', 'description']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
},
|
||||
{
|
||||
@ -131,6 +141,26 @@
|
||||
"outputs": [],
|
||||
"prompt_number": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"mywidget.value"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 13,
|
||||
"text": [
|
||||
"55.1"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 13
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@ -152,10 +182,13 @@
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 5,
|
||||
"prompt_number": 11,
|
||||
"text": [
|
||||
"['visible',\n",
|
||||
" '_css',\n",
|
||||
" '_children_attr',\n",
|
||||
" '_children_lists_attr',\n",
|
||||
" 'default_view_name',\n",
|
||||
" 'value',\n",
|
||||
" 'step',\n",
|
||||
" 'max',\n",
|
||||
@ -166,7 +199,7 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 5
|
||||
"prompt_number": 11
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@ -184,7 +217,7 @@
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 6
|
||||
"prompt_number": 12
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@ -205,13 +238,13 @@
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 7,
|
||||
"prompt_number": 30,
|
||||
"text": [
|
||||
"0.0"
|
||||
"25.0"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 7
|
||||
"prompt_number": 30
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@ -229,8 +262,38 @@
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 8
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'value', 'values', 'disabled', 'description']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 14
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"mysecondwidget.value"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 15,
|
||||
"text": [
|
||||
"u'Item C'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 15
|
||||
},
|
||||
{
|
||||
"cell_type": "heading",
|
||||
@ -259,13 +322,13 @@
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 9,
|
||||
"prompt_number": 16,
|
||||
"text": [
|
||||
"u'FloatSliderView'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 9
|
||||
"prompt_number": 16
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@ -284,7 +347,7 @@
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 10
|
||||
"prompt_number": 17
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
|
@ -108,7 +108,7 @@
|
||||
"def on_value_change(name, value):\n",
|
||||
" print(value)\n",
|
||||
"\n",
|
||||
"intrange.on_trait_change(on_value_change, 'value')"
|
||||
"#intrange.on_trait_change(on_value_change, 'value')"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
@ -117,25 +117,13 @@
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"28\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"55\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"94\n"
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'value', 'step', 'max', 'min', 'disabled', 'orientation', 'description']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
"prompt_number": 9
|
||||
},
|
||||
{
|
||||
"cell_type": "heading",
|
||||
@ -196,6 +184,26 @@
|
||||
"Button clicks are transmitted from the front-end to the back-end using custom messages. By using the `on_click` method, a button that prints a message when it has been clicked is shown below."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"display(intrange)\n",
|
||||
"print('hi')"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"hi\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 5
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
@ -205,12 +213,29 @@
|
||||
"\n",
|
||||
"def on_button_clicked(sender):\n",
|
||||
" print(\"Button clicked.\")\n",
|
||||
" intrange.value +=1\n",
|
||||
"\n",
|
||||
"button.on_click(on_button_clicked)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"Button clicked.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
@ -233,7 +258,7 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 5
|
||||
"prompt_number": 12
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@ -242,6 +267,36 @@
|
||||
"Event handlers can also be used to create widgets. In the example below, clicking a button spawns another button with a description equal to how many times the parent button had been clicked at the time."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 11,
|
||||
"text": [
|
||||
"{'content': {'data': \"{'parent_header': {}, 'msg_type': u'comm_msg', 'msg_id': u'3DBB06AD83C942DD85DC6477B08F1FBF', 'content': {u'data': {u'method': u'custom', u'custom_content': {u'event': u'click'}}, u'comm_id': u'eea5f11ae7aa473993dd0c81d6016648'}, 'header': {u'username': u'username', u'msg_id': u'3DBB06AD83C942DD85DC6477B08F1FBF', u'msg_type': u'comm_msg', u'session': u'0F6D6BE728DA47A38CFC4BDEACF34FC4'}, 'buffers': [], 'metadata': {}}\\ncustom message {'parent_header': {}, 'msg_type': u'comm_msg', 'msg_id': u'3DBB06AD83C942DD85DC6477B08F1FBF', 'content': {u'data': {u'method': u'custom', u'custom_content': {u'event': u'click'}}, u'comm_id': u'eea5f11ae7aa473993dd0c81d6016648'}, 'header': {u'username': u'username', u'msg_id': u'3DBB06AD83C942DD85DC6477B08F1FBF', u'msg_type': u'comm_msg', u'session': u'0F6D6BE728DA47A38CFC4BDEACF34FC4'}, 'buffers': [], 'metadata': {}}\\nhandling click\\n{u'event': u'click'}\\nButton clicked.\\n2\\n\",\n",
|
||||
" 'name': 'stdout'},\n",
|
||||
" 'header': {'msg_id': 'd9dc144a-d86c-42c1-8bab-f8a6bc525723',\n",
|
||||
" 'msg_type': 'stream',\n",
|
||||
" 'session': '9b9408d8-7420-4e0c-976d-cdda9f8d2564',\n",
|
||||
" 'username': 'kernel'},\n",
|
||||
" 'metadata': {},\n",
|
||||
" 'msg_id': 'd9dc144a-d86c-42c1-8bab-f8a6bc525723',\n",
|
||||
" 'msg_type': 'stream',\n",
|
||||
" 'parent_header': {'msg_id': '3DBB06AD83C942DD85DC6477B08F1FBF',\n",
|
||||
" 'msg_type': 'comm_msg',\n",
|
||||
" 'session': '0F6D6BE728DA47A38CFC4BDEACF34FC4',\n",
|
||||
" 'username': 'username'}}"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 11
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
@ -261,8 +316,161 @@
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 6
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"['visible', '_css', '_children_attr', '_children_lists_attr', 'default_view_name', 'description', 'disabled']\n",
|
||||
"[]\n",
|
||||
"[]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 7
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
|
Loading…
Reference in New Issue
Block a user