##// END OF EJS Templates
At least log an error if there is no create or remove defined....
At least log an error if there is no create or remove defined. We might just remove this...

File last commit:

r18986:79b1d051
r19034:a04cc775
Show More
manager.js
240 lines | 9.5 KiB | application/javascript | JavascriptLexer
Jonathan Frederic
Almost done!...
r17198 // Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.
define([
"underscore",
Jonathan Frederic
Done with major changes,...
r17199 "backbone",
Tarun Gaba
Added jquery in define
r17273 "jquery",
Jonathan Frederic
Initial stab at adding promises to the widget framework.
r18882 "base/js/utils",
Jonathan Frederic
Use rsvp.js for Promises
r18897 "base/js/namespace",
Jonathan Frederic
use es6
r18907 ], function (_, Backbone, $, utils, IPython) {
Thomas Kluyver
Clean up some JS code
r18146 "use strict";
Jonathan Frederic
Done with major changes,...
r17199 //--------------------------------------------------------------------
// WidgetManager class
//--------------------------------------------------------------------
Jonathan Frederic
MWE,...
r17200 var WidgetManager = function (comm_manager, notebook) {
Jonathan Frederic
Done with major changes,...
r17199 // Public constructor
WidgetManager._managers.push(this);
// Attach a comm manager to the
Jonathan Frederic
MWE,...
r17200 this.keyboard_manager = notebook.keyboard_manager;
Jonathan Frederic
Done with major changes,...
r17199 this.notebook = notebook;
this.comm_manager = comm_manager;
this._models = {}; /* Dictionary of model ids and model instances */
Jonathan Frederic
Separate widget model name from com target name.
r18264 // Register with the comm manager.
this.comm_manager.register_target('ipython.widget', $.proxy(this._handle_comm_open, this));
Jonathan Frederic
Done with major changes,...
r17199 };
//--------------------------------------------------------------------
// Class level
//--------------------------------------------------------------------
WidgetManager._model_types = {}; /* Dictionary of model type names (target_name) and model types. */
WidgetManager._view_types = {}; /* Dictionary of view names and view types. */
WidgetManager._managers = []; /* List of widget managers */
WidgetManager.register_widget_model = function (model_name, model_type) {
// Registers a widget model by name.
WidgetManager._model_types[model_name] = model_type;
};
WidgetManager.register_widget_view = function (view_name, view_type) {
// Registers a widget view by name.
WidgetManager._view_types[view_name] = view_type;
};
//--------------------------------------------------------------------
// Instance level
//--------------------------------------------------------------------
WidgetManager.prototype.display_view = function(msg, model) {
// Displays a view for a particular model.
Jonathan Frederic
Bug fixes
r18898 var that = this;
Jason Grout
Clean up promises code some more.
r18984 var cell = this.get_msg_cell(msg.parent_header.msg_id);
if (cell === null) {
return Promise.reject(new Error("Could not determine where the display" +
" message was from. Widget will not be displayed"));
} else if (cell.widget_subarea) {
var dummy = $('<div />');
cell.widget_subarea.append(dummy);
return this.create_view(model, {cell: cell}).then(
function(view) {
Jonathan Frederic
Add a WrappedError class
r18895 that._handle_display_view(view);
Jonathan Frederic
Address @takluyver 's review comments
r18935 dummy.replaceWith(view.$el);
Jonathan Frederic
Add a WrappedError class
r18895 view.trigger('displayed');
Jason Grout
Clean up promises code some more.
r18984 return view;
Jason Grout
Simplify error-handling code...
r18986 }, utils.reject('Could not display view'));
Jason Grout
Clean up promises code some more.
r18984 }
Jonathan Frederic
Done with major changes,...
r17199 };
WidgetManager.prototype._handle_display_view = function (view) {
// Have the IPython keyboard manager disable its event
// handling so the widget can capture keyboard input.
// Note, this is only done on the outer most widgets.
if (this.keyboard_manager) {
this.keyboard_manager.register_events(view.$el);
Jonathan Frederic
Initial stab at adding promises to the widget framework.
r18882 if (view.additional_elements) {
for (var i = 0; i < view.additional_elements.length; i++) {
Jonathan Frederic
Add a WrappedError class
r18895 this.keyboard_manager.register_events(view.additional_elements[i]);
Jonathan Frederic
Initial stab at adding promises to the widget framework.
r18882 }
}
Jonathan Frederic
Done with major changes,...
r17199 }
};
Thomas Kluyver
Allow widget views to be loaded from require modules...
r18142
Thomas Kluyver
Clean up some JS code
r18146 WidgetManager.prototype.create_view = function(model, options) {
Jason Grout
Simplify code by using Promises in a better way; try_load -> load
r18887 // Creates a promise for a view of a given model
Jonathan Frederic
Move the display Promise into a lower level method,...
r18905
// Make sure the view creation is not out of order with
// any state updates.
model.state_change = model.state_change.then(function() {
Jonathan Frederic
Current state with lots and lots of debugging junk
r18906
Jonathan Frederic
Move the display Promise into a lower level method,...
r18905 return utils.load_class(model.get('_view_name'), model.get('_view_module'),
Jonathan Frederic
Make display also pend on set_state.
r18894 WidgetManager._view_types).then(function(ViewType) {
// If a view is passed into the method, use that view's cell as
// the cell for the view that is created.
options = options || {};
if (options.parent !== undefined) {
options.cell = options.parent.options.cell;
}
// Create and render the view...
var parameters = {model: model, options: options};
var view = new ViewType(parameters);
view.listenTo(model, 'destroy', view.remove);
view.render();
return view;
Jonathan Frederic
Add a WrappedError class
r18895 }, utils.reject("Couldn't create a view for model id '" + String(model.id) + "'"));
Jonathan Frederic
Move the display Promise into a lower level method,...
r18905 });
return model.state_change;
Jonathan Frederic
Done with major changes,...
r17199 };
WidgetManager.prototype.get_msg_cell = function (msg_id) {
var cell = null;
// First, check to see if the msg was triggered by cell execution.
if (this.notebook) {
cell = this.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.comm_manager.kernel;
if (kernel) {
var callbacks = kernel.get_callbacks_for_msg(msg_id);
if (callbacks && callbacks.iopub &&
callbacks.iopub.get_cell !== undefined) {
return callbacks.iopub.get_cell();
Jonathan Frederic
Completely remove cell from model and view.
r14534 }
Jonathan Frederic
Done with major changes,...
r17199 }
// Not triggered by a cell or widget (no get_cell callback
// exists).
return null;
};
WidgetManager.prototype.callbacks = function (view) {
// callback handlers specific a view
var callbacks = {};
if (view && view.options.cell) {
// Try to get output handlers
var cell = view.options.cell;
var handle_output = null;
var handle_clear_output = null;
if (cell.output_area) {
handle_output = $.proxy(cell.output_area.handle_output, cell.output_area);
handle_clear_output = $.proxy(cell.output_area.handle_clear_output, cell.output_area);
Jonathan Frederic
Removed comm dependency of widget model and view
r14469 }
Jonathan Frederic
Rebase fixes
r18517 // Create callback dictionary using what is known
Brian E. Granger
Remove model from WidgetManager._model on comm:close.
r16652 var that = this;
Jonathan Frederic
Done with major changes,...
r17199 callbacks = {
iopub : {
output : handle_output,
clear_output : handle_clear_output,
// Special function only registered by widget messages.
// Allows us to get the cell for a message so we know
// where to add widgets if the code requires it.
get_cell : function () {
return cell;
},
},
};
}
return callbacks;
};
WidgetManager.prototype.get_model = function (model_id) {
Jonathan Frederic
Address @takluyver 's review comments
r18935 // Get a promise for a model by model id.
Jonathan Frederic
Bug fixes
r18898 return this._models[model_id];
Jonathan Frederic
Done with major changes,...
r17199 };
WidgetManager.prototype._handle_comm_open = function (comm, msg) {
// Handle when a comm is opened.
Jonathan Frederic
Remove message promise.
r18916 return this.create_model({
Jonathan Frederic
Rebase fixes
r18517 model_name: msg.content.data.model_name,
model_module: msg.content.data.model_module,
Jonathan Frederic
Address review comments
r18917 comm: comm}).catch(utils.reject("Couldn't create a model."));
Jonathan Frederic
Enable widget instanciation from front-end.
r18506 };
Jonathan Frederic
Clarified API for the create_model function,...
r18512 WidgetManager.prototype.create_model = function (options) {
Jason Grout
Simplify code by using Promises in a better way; try_load -> load
r18887 // Create and return a promise for a new widget model
Jonathan Frederic
Enable widget instanciation from front-end.
r18506 //
Jonathan Frederic
s/target_name/widget_class
r18515 // Minimally, one must provide the model_name and widget_class
Jonathan Frederic
Clarified API for the create_model function,...
r18512 // parameters to create a model from Javascript.
//
// Example
// --------
// JS:
Jonathan Frederic
Rebase fixes
r18517 // IPython.notebook.kernel.widget_manager.create_model({
Jonathan Frederic
Clarified API for the create_model function,...
r18512 // model_name: 'WidgetModel',
Jonathan Frederic
Initial stab at adding promises to the widget framework.
r18882 // widget_class: 'IPython.html.widgets.widget_int.IntSlider'})
// .then(function(model) { console.log('Create success!', model); },
Jonathan Frederic
Proxy console.error calls
r18886 // $.proxy(console.error, console));
Jonathan Frederic
Enable widget instanciation from front-end.
r18506 //
// Parameters
// ----------
// options: dictionary
// Dictionary of options with the following contents:
// model_name: string
// Target name of the widget model to create.
Jonathan Frederic
Rebase fixes
r18517 // model_module: (optional) string
// Module name of the widget model to create.
Jonathan Frederic
s/target_name/widget_class
r18515 // widget_class: (optional) string
Jonathan Frederic
Enable widget instanciation from front-end.
r18506 // Target name of the widget in the back-end.
// comm: (optional) Comm
Jonathan Frederic
Add Promise support to models.
r18884
// Create a comm if it wasn't provided.
var comm = options.comm;
if (!comm) {
comm = this.comm_manager.new_comm('ipython.widget', {'widget_class': options.widget_class});
}
var that = this;
var model_id = comm.comm_id;
Jonathan Frederic
Add a WrappedError class
r18895 var model_promise = utils.load_class(options.model_name, options.model_module, WidgetManager._model_types)
Jason Grout
Simplify code by using Promises in a better way; try_load -> load
r18887 .then(function(ModelType) {
var widget_model = new ModelType(that, model_id, comm);
widget_model.once('comm:close', function () {
delete that._models[model_id];
});
return widget_model;
Jonathan Frederic
Add a WrappedError class
r18895
Jason Grout
Add some error handling for creating views and models
r18889 }, function(error) {
delete that._models[model_id];
Jonathan Frederic
Add a WrappedError class
r18895 var wrapped_error = new utils.WrappedError("Couldn't create model", error);
Jonathan Frederic
use es6
r18907 return Promise.reject(wrapped_error);
Jason Grout
Simplify code by using Promises in a better way; try_load -> load
r18887 });
this._models[model_id] = model_promise;
return model_promise;
Jonathan Frederic
Done with major changes,...
r17199 };
Jonathan Frederic
Almost done!...
r17198
Jonathan Frederic
Initial stab at adding promises to the widget framework.
r18882 // Backwards compatibility.
Jonathan Frederic
Fix all the tests
r17216 IPython.WidgetManager = WidgetManager;
Jonathan Frederic
Fix all the bugs!
r17203 return {'WidgetManager': WidgetManager};
Jonathan Frederic
Done with major changes,...
r17199 });