mirror of
https://github.com/jupyter/notebook.git
synced 2025-03-13 13:17:50 +08:00
LOTS OF WIDGET CHANGES
Moved model-like code out of manager. Added parent/child API. Throttling now occurs on a model by model level. View/cell association is fixed for the most part, but there is still one assumption being made in handle_com_msg.
This commit is contained in:
parent
4c7357f4a4
commit
837ef44256
@ -20,8 +20,8 @@
|
||||
// Use require.js 'define' method so that require.js is intelligent enough to
|
||||
// syncronously load everything within this file when it is being 'required'
|
||||
// elsewhere.
|
||||
define(["static/components/underscore/underscore-min.js",
|
||||
"static/components/backbone/backbone-min.js",
|
||||
define(["../../components/underscore/underscore-min.js",
|
||||
"../../components/backbone/backbone-min.js",
|
||||
], function(){
|
||||
|
||||
// Only run once on a notebook.
|
||||
@ -31,15 +31,236 @@ define(["static/components/underscore/underscore-min.js",
|
||||
// WidgetModel class
|
||||
//--------------------------------------------------------------------
|
||||
var WidgetModel = Backbone.Model.extend({
|
||||
apply: function(sender) {
|
||||
constructor: function(comm_manager, comm, widget_view_types) {
|
||||
this.comm_manager = comm_manager;
|
||||
this.widget_view_types = widget_view_types;
|
||||
this.pending_msgs = 0;
|
||||
this.msg_throttle = 3;
|
||||
this.msg_buffer = {};
|
||||
this.views = {};
|
||||
|
||||
// Remember comm associated with the model.
|
||||
this.comm = comm;
|
||||
comm.model = this;
|
||||
|
||||
// Hook comm messages up to model.
|
||||
comm.on_close($.proxy(this.handle_comm_closed, this));
|
||||
comm.on_msg($.proxy(this.handle_comm_msg, this));
|
||||
|
||||
return Backbone.Model.apply(this);
|
||||
},
|
||||
|
||||
|
||||
update_other_views: function(caller) {
|
||||
this.last_modified_view = caller;
|
||||
this.save(this.changedAttributes(), {patch: true});
|
||||
|
||||
for (var index in this.views) {
|
||||
var view = this.views[index];
|
||||
if (view !== sender) {
|
||||
for (var cell_index in this.views) {
|
||||
var view = this.views[cell_index];
|
||||
if (view !== caller) {
|
||||
view.refresh();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
handle_status: function (output_area, msg) {
|
||||
//execution_state : ('busy', 'idle', 'starting')
|
||||
if (msg.content.execution_state=='idle') {
|
||||
|
||||
// Send buffer if this message caused another message to be
|
||||
// throttled.
|
||||
if (this.msg_throttle == this.pending_msgs &&
|
||||
this.msg_buffer.length > 0) {
|
||||
|
||||
var output_area = this._get_msg_output_area(msg);
|
||||
var callbacks = this._make_callbacks(output_area);
|
||||
var data = {sync_method: 'patch', sync_data: this.msg_buffer};
|
||||
comm.send(data, callbacks);
|
||||
this.msg_buffer = {};
|
||||
} else {
|
||||
|
||||
// Only decrease the pending message count if the buffer
|
||||
// doesn't get flushed (sent).
|
||||
--this.pending_msgs;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Custom syncronization logic.
|
||||
handle_sync: function (method, options) {
|
||||
var model_json = this.toJSON();
|
||||
|
||||
// Only send updated state if the state hasn't been changed
|
||||
// during an update.
|
||||
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') {
|
||||
for (var attr in options.attrs) {
|
||||
this.msg_buffer[attr] = options.attrs[attr];
|
||||
}
|
||||
} else {
|
||||
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 (var attr in options.attrs) {
|
||||
send_json[attr] = options.attrs[attr];
|
||||
}
|
||||
}
|
||||
|
||||
var data = {sync_method: method, sync_data: send_json};
|
||||
var output_area = this._get_view_output_area(this.last_modified_view);
|
||||
var callbacks = this._make_callbacks();
|
||||
this.comm.send(data, callbacks);
|
||||
this.pending_msgs++;
|
||||
}
|
||||
}
|
||||
|
||||
// Since the comm is a one-way communication, assume the message
|
||||
// arrived.
|
||||
return model_json;
|
||||
},
|
||||
|
||||
|
||||
// Handle incomming comm msg.
|
||||
handle_comm_msg: function (comm, msg) {
|
||||
var method = msg.content.data.method;
|
||||
switch (method){
|
||||
case 'display':
|
||||
|
||||
////////////////////////// TODO: Get cell index via currently executing cell.
|
||||
var cell_index = IPython.notebook.get_selected_index()-1;
|
||||
|
||||
this.display_view(msg.content.data.view_name,
|
||||
msg.content.data.parent,
|
||||
cell_index);
|
||||
break;
|
||||
case 'update':
|
||||
this.handle_update(msg.content.data.state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handle when a widget is updated via the python side.
|
||||
handle_update: function (state) {
|
||||
this.updating = true;
|
||||
try {
|
||||
for (var key in state) {
|
||||
if (state.hasOwnProperty(key)) {
|
||||
if (key == "_css"){
|
||||
this.css = state[key];
|
||||
} else {
|
||||
this.set(key, state[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.id = this.comm.comm_id;
|
||||
this.save();
|
||||
} finally {
|
||||
this.updating = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handle when a widget is closed.
|
||||
handle_comm_closed: function (msg) {
|
||||
for (var cell_index in this.views) {
|
||||
var view = this.views[cell_index];
|
||||
view.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create view that represents the model.
|
||||
display_view = function (view_name, parent_comm_id, cell_index) {
|
||||
var view = new this.widget_view_types[view_name]({model: this});
|
||||
view.render();
|
||||
this.views[cell_index] = view;
|
||||
view.cell_index = cell_index;
|
||||
|
||||
// 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) {
|
||||
that.comm.close();
|
||||
}
|
||||
});
|
||||
|
||||
var display_child = null;
|
||||
if (parent_comm_id != undefined) {
|
||||
var parent_comm = this.comm_manager.comms[parent_comm_id];
|
||||
var parent_model = parent_comm.model;
|
||||
var parent_view = parent_model.views[cell_id];
|
||||
if (parent_view.display_child != undefined) {
|
||||
display_child = parent_view.display_child;
|
||||
}
|
||||
}
|
||||
|
||||
if (display_child != null) {
|
||||
display_child(view.$el);
|
||||
} else {
|
||||
// No parent view is defined or exists. Add the view's
|
||||
// element to cell's widget div.
|
||||
var cell = IPython.notebook.get_cell(cell_index);
|
||||
cell.element.find('.widget_area').find('.widget_subarea')
|
||||
.append(view.$el)
|
||||
.parent().show(); // Show the widget_area (parent of widget_subarea)
|
||||
|
||||
}
|
||||
|
||||
// Update the view based on the model contents.
|
||||
view.refresh();
|
||||
}
|
||||
|
||||
|
||||
// Build a callback dict.
|
||||
_make_callbacks: function (output_area) {
|
||||
var callbacks = {};
|
||||
if (output_area != null) {
|
||||
var that = this;
|
||||
callbacks = {
|
||||
iopub : {
|
||||
output : $.proxy(output_area.handle_output, output_area),
|
||||
clear_output : $.proxy(output_area.handle_clear_output, output_area),
|
||||
status : function(msg){
|
||||
that.handle_status(output_area, msg);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
return callbacks;
|
||||
},
|
||||
|
||||
|
||||
// Get the cell output area corresponding to the view.
|
||||
_get_view_output_area : function (view) {
|
||||
return this._get_cell_output_area(view.cell_index);
|
||||
}
|
||||
|
||||
|
||||
// Get the cell output area corresponding to the cell id.
|
||||
_get_cell_output_area : function (cell_id) {
|
||||
var cell = IPython.notebook.get_cell(cell_id)
|
||||
return cell.output_area;
|
||||
}
|
||||
});
|
||||
|
||||
@ -53,8 +274,8 @@ define(["static/components/underscore/underscore-min.js",
|
||||
this.model.on('change',this.refresh,this);
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
this.update();
|
||||
update: function() {
|
||||
var results = Backbone.Model.prototype.update.call(this);
|
||||
|
||||
if (this.model.css != undefined) {
|
||||
for (var selector in this.model.css) {
|
||||
@ -79,6 +300,7 @@ define(["static/components/underscore/underscore-min.js",
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
},
|
||||
});
|
||||
|
||||
@ -86,240 +308,43 @@ define(["static/components/underscore/underscore-min.js",
|
||||
//--------------------------------------------------------------------
|
||||
// WidgetManager class
|
||||
//--------------------------------------------------------------------
|
||||
// Public constructor
|
||||
var WidgetManager = function(comm_manager){
|
||||
this.comm_manager = comm_manager;
|
||||
this.widget_model_types = {};
|
||||
this.widget_view_types = {};
|
||||
this.model_widget_views = {};
|
||||
this.pending_msgs = 0;
|
||||
this.msg_throttle = 3;
|
||||
this.msg_buffer = {};
|
||||
|
||||
var that = this;
|
||||
Backbone.sync = function(method, model, options, error) {
|
||||
var result = that.handle_sync(method, model, options);
|
||||
var result = model.handle_sync(method, options);
|
||||
if (options.success) {
|
||||
options.success(result);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Register a widget model type.
|
||||
WidgetManager.prototype.register_widget_model = function (widget_model_name, widget_model_type) {
|
||||
|
||||
WidgetManager.prototype.register_widget_model = function (widget_model_name, widget_model_type) {
|
||||
// Register the widget with the comm manager. Make sure to pass this object's context
|
||||
// in so `this` works in the call back.
|
||||
this.comm_manager.register_target(widget_model_name, $.proxy(this.handle_com_open, this));
|
||||
|
||||
// Register the types of the model and view correspong to this widget type. Later
|
||||
// the widget manager will initialize these when the comm is opened.
|
||||
this.widget_model_types[widget_model_name] = widget_model_type;
|
||||
}
|
||||
|
||||
// Register a widget view type.
|
||||
|
||||
WidgetManager.prototype.register_widget_view = function (widget_view_name, widget_view_type) {
|
||||
this.widget_view_types[widget_view_name] = widget_view_type;
|
||||
}
|
||||
|
||||
// Handle when a comm is opened.
|
||||
|
||||
WidgetManager.prototype.handle_com_open = function (comm, msg) {
|
||||
var widget_type_name = msg.content.target_name;
|
||||
|
||||
// Create the corresponding widget model.
|
||||
var widget_model = new this.widget_model_types[widget_type_name];
|
||||
|
||||
// Remember comm associated with the model.
|
||||
widget_model.comm = comm;
|
||||
comm.model = widget_model;
|
||||
|
||||
// Create an array to remember the views associated with the model.
|
||||
widget_model.views = [];
|
||||
|
||||
// Add a handle to delete the control when the comm is closed.
|
||||
var that = this;
|
||||
var handle_close = function(msg) {
|
||||
that.handle_comm_closed(comm, msg);
|
||||
}
|
||||
comm.on_close(handle_close);
|
||||
|
||||
// Handle incomming messages.
|
||||
var handle_msg = function(msg) {
|
||||
that.handle_comm_msg(comm, msg);
|
||||
}
|
||||
comm.on_msg(handle_msg);
|
||||
var widget_model = new this.widget_model_types[widget_type_name](this.comm_manager, comm, view_types);
|
||||
}
|
||||
|
||||
// Create view that represents the model.
|
||||
WidgetManager.prototype.show_view = function (widget_area, widget_model, widget_view_name) {
|
||||
var widget_view = new this.widget_view_types[widget_view_name]({model: widget_model});
|
||||
widget_view.render();
|
||||
widget_model.views.push(widget_view);
|
||||
|
||||
// Handle when the view element is remove from the page.
|
||||
widget_view.$el.on("remove", function(){
|
||||
var index = widget_model.views.indexOf(widget_view);
|
||||
if (index > -1) {
|
||||
widget_model.views.splice(index, 1);
|
||||
}
|
||||
widget_view.remove(); // Clean-up view
|
||||
|
||||
// Close the comm if there are no views left.
|
||||
if (widget_model.views.length()==0) {
|
||||
widget_model.comm.close();
|
||||
}
|
||||
});
|
||||
|
||||
// Add the view's element to cell's widget div.
|
||||
widget_area
|
||||
.append(widget_view.$el)
|
||||
.parent().show(); // Show the widget_area (parent of widget_subarea)
|
||||
|
||||
// Update the view based on the model contents.
|
||||
widget_view.refresh();
|
||||
}
|
||||
|
||||
// Handle incomming comm msg.
|
||||
WidgetManager.prototype.handle_comm_msg = function (comm, msg) {
|
||||
// Different logic for different methods.
|
||||
var method = msg.content.data.method;
|
||||
switch (method){
|
||||
case 'show':
|
||||
|
||||
// TODO: Get cell from registered output handler.
|
||||
var cell = IPython.notebook.get_cell(IPython.notebook.get_selected_index()-1);
|
||||
var widget_subarea = cell.element.find('.widget_area').find('.widget_subarea');
|
||||
|
||||
if (msg.content.data.parent != undefined) {
|
||||
var find_results = widget_subarea.find("." + msg.content.data.parent);
|
||||
if (find_results.length > 0) {
|
||||
widget_subarea = find_results;
|
||||
}
|
||||
}
|
||||
|
||||
this.show_view(widget_subarea, comm.model, msg.content.data.view_name);
|
||||
break;
|
||||
case 'update':
|
||||
this.handle_update(comm, msg.content.data.state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle when a widget is updated via the python side.
|
||||
WidgetManager.prototype.handle_update = function (comm, state) {
|
||||
this.updating = true;
|
||||
for (var key in state) {
|
||||
if (state.hasOwnProperty(key)) {
|
||||
if (key == "_css"){
|
||||
comm.model.css = state[key];
|
||||
} else {
|
||||
comm.model.set(key, state[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
comm.model.id = comm.comm_id;
|
||||
comm.model.save();
|
||||
this.updating = false;
|
||||
}
|
||||
|
||||
// Handle when a widget is closed.
|
||||
WidgetManager.prototype.handle_comm_closed = function (comm, msg) {
|
||||
for (var view_index in comm.model.views) {
|
||||
var view = comm.model.views[view_index];
|
||||
view.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle when a msg status changes in the kernel.
|
||||
WidgetManager.prototype.handle_status = function (msg) {
|
||||
//execution_state : ('busy', 'idle', 'starting')
|
||||
if (msg.content.execution_state=='idle') {
|
||||
// Send buffer if this message caused another message to be
|
||||
// throttled.
|
||||
if (this.msg_throttle == --this.pending_msgs &&
|
||||
this.msg_buffer.length > 0) {
|
||||
var outputarea = this._get_msg_outputarea(msg);
|
||||
var callbacks = this._make_callbacks(outputarea);
|
||||
var data = {sync_method: 'patch', sync_data: this.msg_buffer};
|
||||
comm.send(data, callbacks);
|
||||
this.pending_msgs++;
|
||||
this.msg_buffer = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the cell output area corresponding to the comm.
|
||||
WidgetManager.prototype._get_comm_outputarea = function (comm) {
|
||||
// TODO: get element from comm instead of guessing
|
||||
var cell = IPython.notebook.get_cell(IPython.notebook.get_selected_index())
|
||||
return cell.output_area;
|
||||
}
|
||||
|
||||
// Get the cell output area corresponding to the msg_id.
|
||||
WidgetManager.prototype._get_msg_outputarea = function (msg) {
|
||||
// TODO: get element from msg_id instead of guessing
|
||||
// msg.parent_header.msg_id
|
||||
var cell = IPython.notebook.get_cell(IPython.notebook.get_selected_index())
|
||||
return cell.output_area;
|
||||
}
|
||||
|
||||
// Build a callback dict.
|
||||
WidgetManager.prototype._make_callbacks = function (outputarea) {
|
||||
var callbacks = {};
|
||||
if (outputarea != null) {
|
||||
callbacks = {
|
||||
iopub : {
|
||||
status : $.proxy(this.handle_status, this),
|
||||
output : $.proxy(outputarea.handle_output, outputarea),
|
||||
clear_output : $.proxy(outputarea.handle_clear_output, outputarea)}
|
||||
};
|
||||
}
|
||||
return callbacks;
|
||||
}
|
||||
|
||||
// Send widget state to python backend.
|
||||
WidgetManager.prototype.handle_sync = function (method, model, options) {
|
||||
var model_json = model.toJSON();
|
||||
|
||||
// Only send updated state if the state hasn't been changed during an update.
|
||||
if (!this.updating) {
|
||||
// Create a callback for the output if the widget has an output area associate with it.
|
||||
var callbacks = this._make_callbacks(this._get_comm_outputarea(comm));
|
||||
var comm = model.comm;
|
||||
|
||||
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') {
|
||||
for (var attr in options.attrs) {
|
||||
this.msg_buffer[attr] = options.attrs[attr];
|
||||
}
|
||||
} else {
|
||||
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 (var attr in options.attrs) {
|
||||
send_json[attr] = options.attrs[attr];
|
||||
}
|
||||
}
|
||||
var data = {sync_method: method, sync_data: send_json};
|
||||
comm.send(data, callbacks);
|
||||
this.pending_msgs++;
|
||||
}
|
||||
}
|
||||
|
||||
// Since the comm is a one-way communication, assume the message
|
||||
// arrived.
|
||||
return model_json;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Init code
|
||||
//--------------------------------------------------------------------
|
||||
IPython.WidgetManager = WidgetManager;
|
||||
IPython.WidgetModel = WidgetModel;
|
||||
IPython.WidgetView = WidgetView;
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
require(["notebook/js/widget"], function(){
|
||||
require(["../static/notebook/js/widget"], function(){
|
||||
|
||||
var BoolWidgetModel = IPython.WidgetModel.extend({});
|
||||
IPython.notebook.widget_manager.register_widget_model('BoolWidgetModel', BoolWidgetModel);
|
||||
@ -9,8 +9,7 @@ require(["notebook/js/widget"], function(){
|
||||
// Called when view is rendered.
|
||||
render : function(){
|
||||
this.$el
|
||||
.html('')
|
||||
.addClass(this.model.comm.comm_id);
|
||||
.html('');
|
||||
|
||||
var $label = $('<label />')
|
||||
.addClass('checkbox')
|
||||
@ -39,7 +38,7 @@ require(["notebook/js/widget"], function(){
|
||||
handleChanged: function(e) {
|
||||
this.user_invoked_update = true;
|
||||
this.model.set('value', $(e.target).prop('checked'));
|
||||
this.model.apply(this);
|
||||
this.model.update_other_views(this);
|
||||
this.user_invoked_update = false;
|
||||
},
|
||||
});
|
||||
@ -51,8 +50,7 @@ require(["notebook/js/widget"], function(){
|
||||
// Called when view is rendered.
|
||||
render : function(){
|
||||
this.$el
|
||||
.html('')
|
||||
.addClass(this.model.comm.comm_id);
|
||||
.html('');
|
||||
|
||||
this.$button = $('<button />')
|
||||
.addClass('btn')
|
||||
@ -82,7 +80,7 @@ require(["notebook/js/widget"], function(){
|
||||
handleClick: function(e) {
|
||||
this.user_invoked_update = true;
|
||||
this.model.set('value', ! $(e.target).hasClass('active'));
|
||||
this.model.apply(this);
|
||||
this.model.update_other_views(this);
|
||||
this.user_invoked_update = false;
|
||||
},
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
require(["notebook/js/widget"], function(){
|
||||
require(["../static/notebook/js/widget"], function(){
|
||||
|
||||
var ButtonWidgetModel = IPython.WidgetModel.extend({});
|
||||
IPython.notebook.widget_manager.register_widget_model('ButtonWidgetModel', ButtonWidgetModel);
|
||||
@ -13,7 +13,7 @@ require(["notebook/js/widget"], function(){
|
||||
.addClass('btn')
|
||||
.click(function() {
|
||||
that.model.set('clicks', that.model.get('clicks') + 1);
|
||||
that.model.apply(that);
|
||||
that.model.update_other_views(that);
|
||||
});
|
||||
|
||||
this.update(); // Set defaults.
|
||||
|
@ -1,4 +1,4 @@
|
||||
require(["notebook/js/widget"], function(){
|
||||
require(["../static/notebook/js/widget"], function(){
|
||||
var ContainerModel = IPython.WidgetModel.extend({});
|
||||
IPython.notebook.widget_manager.register_widget_model('ContainerWidgetModel', ContainerModel);
|
||||
|
||||
@ -6,8 +6,7 @@ require(["notebook/js/widget"], function(){
|
||||
|
||||
render : function(){
|
||||
this.$el = $('<div />')
|
||||
.addClass('widget_container')
|
||||
.addClass(this.model.comm.comm_id);
|
||||
.addClass('widget_container');
|
||||
},
|
||||
|
||||
update : function(){
|
||||
@ -24,6 +23,10 @@ require(["notebook/js/widget"], function(){
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
display_child : function($element) {
|
||||
this.$el.append($element);
|
||||
},
|
||||
});
|
||||
|
||||
IPython.notebook.widget_manager.register_widget_view('ContainerView', ContainerView);
|
||||
|
@ -1,4 +1,4 @@
|
||||
require(["notebook/js/widget"], function(){
|
||||
require(["../static/notebook/js/widget"], function(){
|
||||
var FloatWidgetModel = IPython.WidgetModel.extend({});
|
||||
IPython.notebook.widget_manager.register_widget_model('FloatWidgetModel', FloatWidgetModel);
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
require(["notebook/js/widget"], function(){
|
||||
require(["../static/notebook/js/widget"], function(){
|
||||
var IntWidgetModel = IPython.WidgetModel.extend({});
|
||||
IPython.notebook.widget_manager.register_widget_model('IntWidgetModel', IntWidgetModel);
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
require(["notebook/js/widget"], function(){
|
||||
require(["../static/notebook/js/widget"], function(){
|
||||
var SelectionWidgetModel = IPython.WidgetModel.extend({});
|
||||
IPython.notebook.widget_manager.register_widget_model('SelectionWidgetModel', SelectionWidgetModel);
|
||||
|
||||
@ -8,8 +8,7 @@ require(["notebook/js/widget"], function(){
|
||||
render : function(){
|
||||
|
||||
this.$el
|
||||
.html('')
|
||||
.addClass(this.model.comm.comm_id);
|
||||
.html('');
|
||||
this.$buttongroup = $('<div />')
|
||||
.addClass('widget_item')
|
||||
.addClass('btn-group')
|
||||
@ -44,7 +43,7 @@ require(["notebook/js/widget"], function(){
|
||||
.html(items[index])
|
||||
.on('click', function(e){
|
||||
that.model.set('value', $(e.target).html(), this );
|
||||
that.model.apply(that);
|
||||
that.model.update_other_views(that);
|
||||
})
|
||||
|
||||
this.$droplist.append($('<li />').append(item_button))
|
||||
@ -72,8 +71,7 @@ require(["notebook/js/widget"], function(){
|
||||
// Called when view is rendered.
|
||||
render : function(){
|
||||
this.$el
|
||||
.html('')
|
||||
.addClass(this.model.comm.comm_id);
|
||||
.html('');
|
||||
this.update();
|
||||
},
|
||||
|
||||
@ -99,7 +97,7 @@ require(["notebook/js/widget"], function(){
|
||||
.prependTo($label)
|
||||
.on('click', function(e){
|
||||
that.model.set('value', $(e.target).val(), this);
|
||||
that.model.apply();
|
||||
that.model.update_other_views();
|
||||
});
|
||||
}
|
||||
|
||||
@ -137,8 +135,7 @@ require(["notebook/js/widget"], function(){
|
||||
// Called when view is rendered.
|
||||
render : function(){
|
||||
this.$el
|
||||
.html('')
|
||||
.addClass(this.model.comm.comm_id);
|
||||
.html('');
|
||||
this.$buttongroup = $('<div />')
|
||||
.addClass('btn-group')
|
||||
.attr('data-toggle', 'buttons-radio')
|
||||
@ -164,7 +161,7 @@ require(["notebook/js/widget"], function(){
|
||||
.appendTo(this.$buttongroup)
|
||||
.on('click', function(e){
|
||||
that.model.set('value', $(e.target).html(), this);
|
||||
that.model.apply();
|
||||
that.model.update_other_views();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
require(["notebook/js/widget"], function(){
|
||||
require(["../static/notebook/js/widget"], function(){
|
||||
var StringWidgetModel = IPython.WidgetModel.extend({});
|
||||
IPython.notebook.widget_manager.register_widget_model('StringWidgetModel', StringWidgetModel);
|
||||
|
||||
@ -6,8 +6,7 @@ require(["notebook/js/widget"], function(){
|
||||
|
||||
// Called when view is rendered.
|
||||
render : function(){
|
||||
this.$el = $('<div />')
|
||||
.addClass(this.model.comm.comm_id);
|
||||
this.$el = $('<div />');
|
||||
this.update(); // Set defaults.
|
||||
},
|
||||
|
||||
@ -26,8 +25,7 @@ require(["notebook/js/widget"], function(){
|
||||
// Called when view is rendered.
|
||||
render : function(){
|
||||
this.$el
|
||||
.html('')
|
||||
.addClass(this.model.comm.comm_id);
|
||||
.html('');
|
||||
this.$textbox = $('<textarea />')
|
||||
.attr('rows', 5)
|
||||
.appendTo(this.$el);
|
||||
@ -50,7 +48,7 @@ require(["notebook/js/widget"], function(){
|
||||
handleChanging: function(e) {
|
||||
this.user_invoked_update = true;
|
||||
this.model.set('value', e.target.value);
|
||||
this.model.apply(this);
|
||||
this.model.update_other_views(this);
|
||||
this.user_invoked_update = false;
|
||||
},
|
||||
});
|
||||
@ -62,8 +60,7 @@ require(["notebook/js/widget"], function(){
|
||||
// Called when view is rendered.
|
||||
render : function(){
|
||||
this.$el
|
||||
.html('')
|
||||
.addClass(this.model.comm.comm_id);
|
||||
.html('');
|
||||
this.$textbox = $('<input type="text" />')
|
||||
.addClass('input')
|
||||
.appendTo(this.$el);
|
||||
@ -86,7 +83,7 @@ require(["notebook/js/widget"], function(){
|
||||
handleChanging: function(e) {
|
||||
this.user_invoked_update = true;
|
||||
this.model.set('value', e.target.value);
|
||||
this.model.apply(this);
|
||||
this.model.update_other_views(this);
|
||||
this.user_invoked_update = false;
|
||||
},
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ def init_widget_js():
|
||||
name = filename.rsplit('.', 1)[0]
|
||||
if not (name == 'widget' or name == '__init__') and name.startswith('widget_'):
|
||||
# Remove 'widget_' from the start of the name before compiling the path.
|
||||
js_path = 'static/notebook/js/widgets/%s.js' % name[7:]
|
||||
js_path = '../static/notebook/js/widgets/%s.js' % name[7:]
|
||||
display(Javascript(data='$.getScript("%s");' % js_path))
|
||||
|
||||
|
||||
@ -141,13 +141,13 @@ class Widget(LoggingConfigurable):
|
||||
|
||||
# Show view.
|
||||
if self.parent is None:
|
||||
self.comm.send({"method": "show", "view_name": view_name})
|
||||
self.comm.send({"method": "display", "view_name": view_name})
|
||||
else:
|
||||
self.comm.send({"method": "show",
|
||||
self.comm.send({"method": "display",
|
||||
"view_name": view_name,
|
||||
"parent": self.parent.comm.comm_id})
|
||||
|
||||
# Now show children if any.
|
||||
# Now display children if any.
|
||||
for child in self.children:
|
||||
child._repr_widget_()
|
||||
return None
|
||||
|
Loading…
Reference in New Issue
Block a user