##// END OF EJS Templates
Better comments in _display_view
Jonathan Frederic -
Show More
@@ -1,508 +1,510 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2013 The IPython Development Team
2 // Copyright (C) 2013 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // WidgetModel, WidgetView, and WidgetManager
9 // WidgetModel, WidgetView, and WidgetManager
10 //============================================================================
10 //============================================================================
11 /**
11 /**
12 * Base Widget classes
12 * Base Widget classes
13 * @module IPython
13 * @module IPython
14 * @namespace IPython
14 * @namespace IPython
15 * @submodule widget
15 * @submodule widget
16 */
16 */
17
17
18 "use strict";
18 "use strict";
19
19
20 // Use require.js 'define' method so that require.js is intelligent enough to
20 // Use require.js 'define' method so that require.js is intelligent enough to
21 // syncronously load everything within this file when it is being 'required'
21 // syncronously load everything within this file when it is being 'required'
22 // elsewhere.
22 // elsewhere.
23 define(["components/underscore/underscore-min",
23 define(["components/underscore/underscore-min",
24 "components/backbone/backbone-min",
24 "components/backbone/backbone-min",
25 ], function(underscore, backbone){
25 ], function(underscore, backbone){
26
26
27
27
28 //--------------------------------------------------------------------
28 //--------------------------------------------------------------------
29 // WidgetModel class
29 // WidgetModel class
30 //--------------------------------------------------------------------
30 //--------------------------------------------------------------------
31 var WidgetModel = Backbone.Model.extend({
31 var WidgetModel = Backbone.Model.extend({
32 constructor: function(comm_manager, comm, widget_manager) {
32 constructor: function(comm_manager, comm, widget_manager) {
33 this.comm_manager = comm_manager;
33 this.comm_manager = comm_manager;
34 this.widget_manager = widget_manager;
34 this.widget_manager = widget_manager;
35 this.pending_msgs = 0;
35 this.pending_msgs = 0;
36 this.msg_throttle = 3;
36 this.msg_throttle = 3;
37 this.msg_buffer = null;
37 this.msg_buffer = null;
38 this.views = {};
38 this.views = {};
39
39
40 // Remember comm associated with the model.
40 // Remember comm associated with the model.
41 this.comm = comm;
41 this.comm = comm;
42 comm.model = this;
42 comm.model = this;
43
43
44 // Hook comm messages up to model.
44 // Hook comm messages up to model.
45 comm.on_close($.proxy(this._handle_comm_closed, this));
45 comm.on_close($.proxy(this._handle_comm_closed, this));
46 comm.on_msg($.proxy(this._handle_comm_msg, this));
46 comm.on_msg($.proxy(this._handle_comm_msg, this));
47
47
48 return Backbone.Model.apply(this);
48 return Backbone.Model.apply(this);
49 },
49 },
50
50
51
51
52 update_other_views: function(caller) {
52 update_other_views: function(caller) {
53 this.last_modified_view = caller;
53 this.last_modified_view = caller;
54 this.save(this.changedAttributes(), {patch: true});
54 this.save(this.changedAttributes(), {patch: true});
55
55
56 for (var cell in this.views) {
56 for (var cell in this.views) {
57 var views = this.views[cell];
57 var views = this.views[cell];
58 for (var view_index in views) {
58 for (var view_index in views) {
59 var view = views[view_index];
59 var view = views[view_index];
60 if (view !== caller) {
60 if (view !== caller) {
61 view.update();
61 view.update();
62 }
62 }
63 }
63 }
64 }
64 }
65 },
65 },
66
66
67
67
68 // Handle when a widget is closed.
68 // Handle when a widget is closed.
69 _handle_comm_closed: function (msg) {
69 _handle_comm_closed: function (msg) {
70 for (var cell in this.views) {
70 for (var cell in this.views) {
71 var views = this.views[cell];
71 var views = this.views[cell];
72 for (var view_index in views) {
72 for (var view_index in views) {
73 var view = views[view_index];
73 var view = views[view_index];
74 view.remove();
74 view.remove();
75 }
75 }
76 }
76 }
77 },
77 },
78
78
79
79
80 // Handle incomming comm msg.
80 // Handle incomming comm msg.
81 _handle_comm_msg: function (msg) {
81 _handle_comm_msg: function (msg) {
82 var method = msg.content.data.method;
82 var method = msg.content.data.method;
83 switch (method){
83 switch (method){
84 case 'display':
84 case 'display':
85
85
86 // Try to get the cell index.
86 // Try to get the cell index.
87 var cell = this._get_msg_cell(msg.parent_header.msg_id);
87 var cell = this._get_msg_cell(msg.parent_header.msg_id);
88 if (cell == null) {
88 if (cell == null) {
89 console.log("Could not determine where the display" +
89 console.log("Could not determine where the display" +
90 " message was from. Widget will not be displayed")
90 " message was from. Widget will not be displayed")
91 } else {
91 } else {
92 this._display_view(msg.content.data.view_name,
92 this._display_view(msg.content.data.view_name,
93 msg.content.data.parent,
93 msg.content.data.parent,
94 cell);
94 cell);
95 }
95 }
96 break;
96 break;
97 case 'update':
97 case 'update':
98 this._handle_update(msg.content.data.state);
98 this._handle_update(msg.content.data.state);
99 break;
99 break;
100 }
100 }
101 },
101 },
102
102
103
103
104 // Handle when a widget is updated via the python side.
104 // Handle when a widget is updated via the python side.
105 _handle_update: function (state) {
105 _handle_update: function (state) {
106 this.updating = true;
106 this.updating = true;
107 try {
107 try {
108 for (var key in state) {
108 for (var key in state) {
109 if (state.hasOwnProperty(key)) {
109 if (state.hasOwnProperty(key)) {
110 if (key == "_css"){
110 if (key == "_css"){
111 this.css = state[key];
111 this.css = state[key];
112 } else {
112 } else {
113 this.set(key, state[key]);
113 this.set(key, state[key]);
114 }
114 }
115 }
115 }
116 }
116 }
117 this.id = this.comm.comm_id;
117 this.id = this.comm.comm_id;
118 this.save();
118 this.save();
119 } finally {
119 } finally {
120 this.updating = false;
120 this.updating = false;
121 }
121 }
122 },
122 },
123
123
124
124
125 _handle_status: function (cell, msg) {
125 _handle_status: function (cell, msg) {
126 //execution_state : ('busy', 'idle', 'starting')
126 //execution_state : ('busy', 'idle', 'starting')
127 if (msg.content.execution_state=='idle') {
127 if (msg.content.execution_state=='idle') {
128
128
129 // Send buffer if this message caused another message to be
129 // Send buffer if this message caused another message to be
130 // throttled.
130 // throttled.
131 if (this.msg_buffer != null &&
131 if (this.msg_buffer != null &&
132 this.msg_throttle == this.pending_msgs) {
132 this.msg_throttle == this.pending_msgs) {
133
133
134 var cell = this._get_msg_cell(msg.parent_header.msg_id);
134 var cell = this._get_msg_cell(msg.parent_header.msg_id);
135 var callbacks = this._make_callbacks(cell);
135 var callbacks = this._make_callbacks(cell);
136 var data = {sync_method: 'update', sync_data: this.msg_buffer};
136 var data = {sync_method: 'update', sync_data: this.msg_buffer};
137 this.comm.send(data, callbacks);
137 this.comm.send(data, callbacks);
138 this.msg_buffer = null;
138 this.msg_buffer = null;
139 } else {
139 } else {
140
140
141 // Only decrease the pending message count if the buffer
141 // Only decrease the pending message count if the buffer
142 // doesn't get flushed (sent).
142 // doesn't get flushed (sent).
143 --this.pending_msgs;
143 --this.pending_msgs;
144 }
144 }
145 }
145 }
146 },
146 },
147
147
148
148
149 // Custom syncronization logic.
149 // Custom syncronization logic.
150 _handle_sync: function (method, options) {
150 _handle_sync: function (method, options) {
151 var model_json = this.toJSON();
151 var model_json = this.toJSON();
152
152
153 // Only send updated state if the state hasn't been changed
153 // Only send updated state if the state hasn't been changed
154 // during an update.
154 // during an update.
155 if (!this.updating) {
155 if (!this.updating) {
156 if (this.pending_msgs >= this.msg_throttle) {
156 if (this.pending_msgs >= this.msg_throttle) {
157 // The throttle has been exceeded, buffer the current msg so
157 // The throttle has been exceeded, buffer the current msg so
158 // it can be sent once the kernel has finished processing
158 // it can be sent once the kernel has finished processing
159 // some of the existing messages.
159 // some of the existing messages.
160 if (method=='patch') {
160 if (method=='patch') {
161 if (this.msg_buffer == null) {
161 if (this.msg_buffer == null) {
162 this.msg_buffer = $.extend({}, model_json); // Copy
162 this.msg_buffer = $.extend({}, model_json); // Copy
163 }
163 }
164 for (var attr in options.attrs) {
164 for (var attr in options.attrs) {
165 this.msg_buffer[attr] = options.attrs[attr];
165 this.msg_buffer[attr] = options.attrs[attr];
166 }
166 }
167 } else {
167 } else {
168 this.msg_buffer = $.extend({}, model_json); // Copy
168 this.msg_buffer = $.extend({}, model_json); // Copy
169 }
169 }
170
170
171 } else {
171 } else {
172 // We haven't exceeded the throttle, send the message like
172 // We haven't exceeded the throttle, send the message like
173 // normal. If this is a patch operation, just send the
173 // normal. If this is a patch operation, just send the
174 // changes.
174 // changes.
175 var send_json = model_json;
175 var send_json = model_json;
176 if (method=='patch') {
176 if (method=='patch') {
177 send_json = {};
177 send_json = {};
178 for (var attr in options.attrs) {
178 for (var attr in options.attrs) {
179 send_json[attr] = options.attrs[attr];
179 send_json[attr] = options.attrs[attr];
180 }
180 }
181 }
181 }
182
182
183 var data = {sync_method: method, sync_data: send_json};
183 var data = {sync_method: method, sync_data: send_json};
184
184
185 var cell = null;
185 var cell = null;
186 if (this.last_modified_view != undefined && this.last_modified_view != null) {
186 if (this.last_modified_view != undefined && this.last_modified_view != null) {
187 cell = this.last_modified_view.cell;
187 cell = this.last_modified_view.cell;
188 }
188 }
189
189
190 var callbacks = this._make_callbacks(cell);
190 var callbacks = this._make_callbacks(cell);
191 this.comm.send(data, callbacks);
191 this.comm.send(data, callbacks);
192 this.pending_msgs++;
192 this.pending_msgs++;
193 }
193 }
194 }
194 }
195
195
196 // Since the comm is a one-way communication, assume the message
196 // Since the comm is a one-way communication, assume the message
197 // arrived.
197 // arrived.
198 return model_json;
198 return model_json;
199 },
199 },
200
200
201
201
202 // Create view that represents the model.
202 // Create view that represents the model.
203 _display_view: function (view_name, parent_comm_id, cell) {
203 _display_view: function (view_name, parent_comm_id, cell) {
204 var new_views = [];
204 var new_views = [];
205
205
206 // Try creating and adding the view to it's parent.
206 var displayed = false;
207 var displayed = false;
207 if (parent_comm_id != undefined) {
208 if (parent_comm_id != undefined) {
208 var parent_comm = this.comm_manager.comms[parent_comm_id];
209 var parent_comm = this.comm_manager.comms[parent_comm_id];
209 var parent_model = parent_comm.model;
210 var parent_model = parent_comm.model;
210 var parent_views = parent_model.views[cell];
211 var parent_views = parent_model.views[cell];
211 for (var parent_view_index in parent_views) {
212 for (var parent_view_index in parent_views) {
212 var parent_view = parent_views[parent_view_index];
213 var parent_view = parent_views[parent_view_index];
213 if (parent_view.display_child != undefined) {
214 if (parent_view.display_child != undefined) {
214 var view = this._create_view(view_name, cell);
215 var view = this._create_view(view_name, cell);
215 if (view != null) {
216 if (view != null) {
216 new_views.push(view);
217 new_views.push(view);
217 parent_view.display_child(view);
218 parent_view.display_child(view);
218 displayed = true;
219 displayed = true;
219 }
220 }
220 }
221 }
221 }
222 }
222 }
223 }
223
224
224 if (!displayed) {
225 // If no parent view is defined or exists. Add the view's
225 // No parent view is defined or exists. Add the view's
226 // element to cell's widget div.
226 // element to cell's widget div.
227 if (!displayed) {
227 var view = this._create_view(view_name, cell);
228 var view = this._create_view(view_name, cell);
228 if (view != null) {
229 if (view != null) {
229 new_views.push(view);
230 new_views.push(view);
230
231
231 if (cell.widget_subarea != undefined && cell.widget_subarea != null) {
232 if (cell.widget_subarea != undefined && cell.widget_subarea != null) {
232 cell.widget_area.show();
233 cell.widget_area.show();
233 cell.widget_subarea.append(view.$el);
234 cell.widget_subarea.append(view.$el);
234 }
235 }
235 }
236 }
236 }
237 }
237
238
239 // Force the new view(s) to update their selves
238 for (var view_index in new_views) {
240 for (var view_index in new_views) {
239 var view = new_views[view_index];
241 var view = new_views[view_index];
240 view.update();
242 view.update();
241 }
243 }
242 },
244 },
243
245
244
246
245 // Create a view
247 // Create a view
246 _create_view: function (view_name, cell) {
248 _create_view: function (view_name, cell) {
247 var view_type = this.widget_manager.widget_view_types[view_name];
249 var view_type = this.widget_manager.widget_view_types[view_name];
248 if (view_type != undefined && view_type != null) {
250 if (view_type != undefined && view_type != null) {
249 var view = new view_type({model: this});
251 var view = new view_type({model: this});
250 view.render();
252 view.render();
251 if (this.views[cell]==undefined) {
253 if (this.views[cell]==undefined) {
252 this.views[cell] = []
254 this.views[cell] = []
253 }
255 }
254 this.views[cell].push(view);
256 this.views[cell].push(view);
255 view.cell = cell;
257 view.cell = cell;
256
258
257 // Handle when the view element is remove from the page.
259 // Handle when the view element is remove from the page.
258 var that = this;
260 var that = this;
259 view.$el.on("remove", function(){
261 view.$el.on("remove", function(){
260 var index = that.views[cell].indexOf(view);
262 var index = that.views[cell].indexOf(view);
261 if (index > -1) {
263 if (index > -1) {
262 that.views[cell].splice(index, 1);
264 that.views[cell].splice(index, 1);
263 }
265 }
264 view.remove(); // Clean-up view
266 view.remove(); // Clean-up view
265 if (that.views[cell].length()==0) {
267 if (that.views[cell].length()==0) {
266 delete that.views[cell];
268 delete that.views[cell];
267 }
269 }
268
270
269 // Close the comm if there are no views left.
271 // Close the comm if there are no views left.
270 if (that.views.length()==0) {
272 if (that.views.length()==0) {
271 that.comm.close();
273 that.comm.close();
272 }
274 }
273 });
275 });
274 return view;
276 return view;
275 }
277 }
276 return null;
278 return null;
277 },
279 },
278
280
279
281
280 // Build a callback dict.
282 // Build a callback dict.
281 _make_callbacks: function (cell) {
283 _make_callbacks: function (cell) {
282 var callbacks = {};
284 var callbacks = {};
283 if (cell != null && cell.output_area != undefined && cell.output_area != null) {
285 if (cell != null && cell.output_area != undefined && cell.output_area != null) {
284 var that = this;
286 var that = this;
285 callbacks = {
287 callbacks = {
286 iopub : {
288 iopub : {
287 output : $.proxy(cell.output_area.handle_output, cell.output_area),
289 output : $.proxy(cell.output_area.handle_output, cell.output_area),
288 clear_output : $.proxy(cell.output_area.handle_clear_output, cell.output_area),
290 clear_output : $.proxy(cell.output_area.handle_clear_output, cell.output_area),
289 status : function(msg){
291 status : function(msg){
290 that._handle_status(cell, msg);
292 that._handle_status(cell, msg);
291 },
293 },
292 get_cell : function() {
294 get_cell : function() {
293 if (that.last_modified_view != undefined &&
295 if (that.last_modified_view != undefined &&
294 that.last_modified_view.cell != undefined) {
296 that.last_modified_view.cell != undefined) {
295 return that.last_modified_view.cell;
297 return that.last_modified_view.cell;
296 } else {
298 } else {
297 return null
299 return null
298 }
300 }
299 },
301 },
300 },
302 },
301 };
303 };
302 }
304 }
303 return callbacks;
305 return callbacks;
304 },
306 },
305
307
306
308
307 // Get the output area corresponding to the msg_id.
309 // Get the output area corresponding to the msg_id.
308 // cell is an instance of IPython.Cell
310 // cell is an instance of IPython.Cell
309 _get_msg_cell: function (msg_id) {
311 _get_msg_cell: function (msg_id) {
310
312
311 // First, check to see if the msg was triggered by cell execution.
313 // First, check to see if the msg was triggered by cell execution.
312 var cell = this.widget_manager.get_msg_cell(msg_id);
314 var cell = this.widget_manager.get_msg_cell(msg_id);
313 if (cell != null) {
315 if (cell != null) {
314 return cell;
316 return cell;
315 }
317 }
316
318
317 // Second, check to see if a get_cell callback was defined
319 // Second, check to see if a get_cell callback was defined
318 // for the message. get_cell callbacks are registered for
320 // for the message. get_cell callbacks are registered for
319 // widget messages, so this block is actually checking to see if the
321 // widget messages, so this block is actually checking to see if the
320 // message was triggered by a widget.
322 // message was triggered by a widget.
321 var kernel = this.comm_manager.kernel;
323 var kernel = this.comm_manager.kernel;
322 var callbacks = kernel.get_callbacks_for_msg(msg_id);
324 var callbacks = kernel.get_callbacks_for_msg(msg_id);
323 if (callbacks != undefined &&
325 if (callbacks != undefined &&
324 callbacks.iopub != undefined &&
326 callbacks.iopub != undefined &&
325 callbacks.iopub.get_cell != undefined) {
327 callbacks.iopub.get_cell != undefined) {
326
328
327 return callbacks.iopub.get_cell();
329 return callbacks.iopub.get_cell();
328 }
330 }
329
331
330 // Not triggered by a cell or widget (no get_cell callback
332 // Not triggered by a cell or widget (no get_cell callback
331 // exists).
333 // exists).
332 return null;
334 return null;
333 },
335 },
334
336
335 });
337 });
336
338
337
339
338 //--------------------------------------------------------------------
340 //--------------------------------------------------------------------
339 // WidgetView class
341 // WidgetView class
340 //--------------------------------------------------------------------
342 //--------------------------------------------------------------------
341 var WidgetView = Backbone.View.extend({
343 var WidgetView = Backbone.View.extend({
342
344
343 initialize: function() {
345 initialize: function() {
344 this.visible = true;
346 this.visible = true;
345 this.model.on('change',this.update,this);
347 this.model.on('change',this.update,this);
346 this._add_class_calls = this.model.get('_add_class')[0];
348 this._add_class_calls = this.model.get('_add_class')[0];
347 this._remove_class_calls = this.model.get('_remove_class')[0];
349 this._remove_class_calls = this.model.get('_remove_class')[0];
348 },
350 },
349
351
350 update: function() {
352 update: function() {
351 if (this.model.get('visible') != undefined) {
353 if (this.model.get('visible') != undefined) {
352 if (this.visible != this.model.get('visible')) {
354 if (this.visible != this.model.get('visible')) {
353 this.visible = this.model.get('visible');
355 this.visible = this.model.get('visible');
354 if (this.visible) {
356 if (this.visible) {
355 this.$el.show();
357 this.$el.show();
356 } else {
358 } else {
357 this.$el.hide();
359 this.$el.hide();
358 }
360 }
359 }
361 }
360 }
362 }
361
363
362 if (this.model.css != undefined) {
364 if (this.model.css != undefined) {
363 for (var selector in this.model.css) {
365 for (var selector in this.model.css) {
364 if (this.model.css.hasOwnProperty(selector)) {
366 if (this.model.css.hasOwnProperty(selector)) {
365
367
366 // Apply the css traits to all elements that match the selector.
368 // Apply the css traits to all elements that match the selector.
367 var elements = this._get_selector_element(selector);
369 var elements = this._get_selector_element(selector);
368 if (elements.length > 0) {
370 if (elements.length > 0) {
369 var css_traits = this.model.css[selector];
371 var css_traits = this.model.css[selector];
370 for (var css_key in css_traits) {
372 for (var css_key in css_traits) {
371 if (css_traits.hasOwnProperty(css_key)) {
373 if (css_traits.hasOwnProperty(css_key)) {
372 elements.css(css_key, css_traits[css_key]);
374 elements.css(css_key, css_traits[css_key]);
373 }
375 }
374 }
376 }
375 }
377 }
376 }
378 }
377 }
379 }
378 }
380 }
379
381
380 var add_class = this.model.get('_add_class');
382 var add_class = this.model.get('_add_class');
381 if (add_class != undefined){
383 if (add_class != undefined){
382 var add_class_calls = add_class[0];
384 var add_class_calls = add_class[0];
383 if (add_class_calls > this._add_class_calls) {
385 if (add_class_calls > this._add_class_calls) {
384 this._add_class_calls = add_class_calls;
386 this._add_class_calls = add_class_calls;
385 var elements = this._get_selector_element(add_class[1]);
387 var elements = this._get_selector_element(add_class[1]);
386 if (elements.length > 0) {
388 if (elements.length > 0) {
387 elements.addClass(add_class[2]);
389 elements.addClass(add_class[2]);
388 }
390 }
389 }
391 }
390 }
392 }
391
393
392 var remove_class = this.model.get('_remove_class');
394 var remove_class = this.model.get('_remove_class');
393 if (remove_class != undefined){
395 if (remove_class != undefined){
394 var remove_class_calls = remove_class[0];
396 var remove_class_calls = remove_class[0];
395 if (remove_class_calls > this._remove_class_calls) {
397 if (remove_class_calls > this._remove_class_calls) {
396 this._remove_class_calls = remove_class_calls;
398 this._remove_class_calls = remove_class_calls;
397 var elements = this._get_selector_element(remove_class[1]);
399 var elements = this._get_selector_element(remove_class[1]);
398 if (elements.length > 0) {
400 if (elements.length > 0) {
399 elements.removeClass(remove_class[2]);
401 elements.removeClass(remove_class[2]);
400 }
402 }
401 }
403 }
402 }
404 }
403 },
405 },
404
406
405 _get_selector_element: function(selector) {
407 _get_selector_element: function(selector) {
406 // Get the elements via the css selector. If the selector is
408 // Get the elements via the css selector. If the selector is
407 // blank, apply the style to the $el_to_style element. If
409 // blank, apply the style to the $el_to_style element. If
408 // the $el_to_style element is not defined, use apply the
410 // the $el_to_style element is not defined, use apply the
409 // style to the view's element.
411 // style to the view's element.
410 var elements = this.$el.find(selector);
412 var elements = this.$el.find(selector);
411 if (selector=='') {
413 if (selector=='') {
412 if (this.$el_to_style == undefined) {
414 if (this.$el_to_style == undefined) {
413 elements = this.$el;
415 elements = this.$el;
414 } else {
416 } else {
415 elements = this.$el_to_style;
417 elements = this.$el_to_style;
416 }
418 }
417 }
419 }
418 return elements;
420 return elements;
419 },
421 },
420 });
422 });
421
423
422
424
423 //--------------------------------------------------------------------
425 //--------------------------------------------------------------------
424 // WidgetManager class
426 // WidgetManager class
425 //--------------------------------------------------------------------
427 //--------------------------------------------------------------------
426 var WidgetManager = function(){
428 var WidgetManager = function(){
427 this.comm_manager = null;
429 this.comm_manager = null;
428 this.widget_model_types = {};
430 this.widget_model_types = {};
429 this.widget_view_types = {};
431 this.widget_view_types = {};
430
432
431 var that = this;
433 var that = this;
432 Backbone.sync = function(method, model, options, error) {
434 Backbone.sync = function(method, model, options, error) {
433 var result = model._handle_sync(method, options);
435 var result = model._handle_sync(method, options);
434 if (options.success) {
436 if (options.success) {
435 options.success(result);
437 options.success(result);
436 }
438 }
437 };
439 };
438 }
440 }
439
441
440
442
441 WidgetManager.prototype.attach_comm_manager = function (comm_manager) {
443 WidgetManager.prototype.attach_comm_manager = function (comm_manager) {
442 this.comm_manager = comm_manager;
444 this.comm_manager = comm_manager;
443
445
444 // Register already register widget model types with the comm manager.
446 // Register already register widget model types with the comm manager.
445 for (var widget_model_name in this.widget_model_types) {
447 for (var widget_model_name in this.widget_model_types) {
446 this.comm_manager.register_target(widget_model_name, $.proxy(this._handle_com_open, this));
448 this.comm_manager.register_target(widget_model_name, $.proxy(this._handle_com_open, this));
447 }
449 }
448 }
450 }
449
451
450
452
451 WidgetManager.prototype.register_widget_model = function (widget_model_name, widget_model_type) {
453 WidgetManager.prototype.register_widget_model = function (widget_model_name, widget_model_type) {
452 // Register the widget with the comm manager. Make sure to pass this object's context
454 // Register the widget with the comm manager. Make sure to pass this object's context
453 // in so `this` works in the call back.
455 // in so `this` works in the call back.
454 if (this.comm_manager!=null) {
456 if (this.comm_manager!=null) {
455 this.comm_manager.register_target(widget_model_name, $.proxy(this._handle_com_open, this));
457 this.comm_manager.register_target(widget_model_name, $.proxy(this._handle_com_open, this));
456 }
458 }
457 this.widget_model_types[widget_model_name] = widget_model_type;
459 this.widget_model_types[widget_model_name] = widget_model_type;
458 }
460 }
459
461
460
462
461 WidgetManager.prototype.register_widget_view = function (widget_view_name, widget_view_type) {
463 WidgetManager.prototype.register_widget_view = function (widget_view_name, widget_view_type) {
462 this.widget_view_types[widget_view_name] = widget_view_type;
464 this.widget_view_types[widget_view_name] = widget_view_type;
463 }
465 }
464
466
465
467
466 WidgetManager.prototype.get_msg_cell = function (msg_id) {
468 WidgetManager.prototype.get_msg_cell = function (msg_id) {
467 if (IPython.notebook != undefined && IPython.notebook != null) {
469 if (IPython.notebook != undefined && IPython.notebook != null) {
468 return IPython.notebook.get_msg_cell(msg_id);
470 return IPython.notebook.get_msg_cell(msg_id);
469 }
471 }
470 }
472 }
471
473
472
474
473 WidgetManager.prototype.on_create_widget = function (callback) {
475 WidgetManager.prototype.on_create_widget = function (callback) {
474 this._create_widget_callback = callback;
476 this._create_widget_callback = callback;
475 }
477 }
476
478
477
479
478 WidgetManager.prototype._handle_create_widget = function (widget_model) {
480 WidgetManager.prototype._handle_create_widget = function (widget_model) {
479 if (this._create_widget_callback) {
481 if (this._create_widget_callback) {
480 try {
482 try {
481 this._create_widget_callback(widget_model);
483 this._create_widget_callback(widget_model);
482 } catch (e) {
484 } catch (e) {
483 console.log("Exception in WidgetManager callback", e, widget_model);
485 console.log("Exception in WidgetManager callback", e, widget_model);
484 }
486 }
485 }
487 }
486 }
488 }
487
489
488
490
489 WidgetManager.prototype._handle_com_open = function (comm, msg) {
491 WidgetManager.prototype._handle_com_open = function (comm, msg) {
490 var widget_type_name = msg.content.target_name;
492 var widget_type_name = msg.content.target_name;
491 var widget_model = new this.widget_model_types[widget_type_name](this.comm_manager, comm, this);
493 var widget_model = new this.widget_model_types[widget_type_name](this.comm_manager, comm, this);
492 this._handle_create_widget(widget_model);
494 this._handle_create_widget(widget_model);
493 }
495 }
494
496
495
497
496 //--------------------------------------------------------------------
498 //--------------------------------------------------------------------
497 // Init code
499 // Init code
498 //--------------------------------------------------------------------
500 //--------------------------------------------------------------------
499 IPython.WidgetManager = WidgetManager;
501 IPython.WidgetManager = WidgetManager;
500 IPython.WidgetModel = WidgetModel;
502 IPython.WidgetModel = WidgetModel;
501 IPython.WidgetView = WidgetView;
503 IPython.WidgetView = WidgetView;
502
504
503 if (IPython.widget_manager==undefined || IPython.widget_manager==null) {
505 if (IPython.widget_manager==undefined || IPython.widget_manager==null) {
504 IPython.widget_manager = new WidgetManager();
506 IPython.widget_manager = new WidgetManager();
505 }
507 }
506
508
507 return IPython.widget_manager;
509 return IPython.widget_manager;
508 });
510 });
General Comments 0
You need to be logged in to leave comments. Login now