Skip to content

Commit 7f4493e

Browse files
committed
🍰 It's working!
1 parent 5ee9835 commit 7f4493e

File tree

22 files changed

+193
-87
lines changed

22 files changed

+193
-87
lines changed

ipython_widgets/install.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env python
2+
# Thanks @takluyver for your cite2c install.py.
3+
from os.path import dirname, abspath, join as pjoin
4+
from jupyter_notebook.nbextensions import install_nbextension
5+
from jupyter_notebook.services.config import ConfigManager
6+
7+
print("Installing nbextension ...")
8+
staticdir = pjoin(dirname(abspath(__file__)), 'static')
9+
install_nbextension(staticdir, destination='widgets', user=False)
10+
11+
print("Enabling the extension ...")
12+
cm = ConfigManager()
13+
cm.update('notebook', {"load_extensions": {"widgets/notebook/js/extension": True}})
14+
15+
print("Done.")

ipython_widgets/static/notebook/js/extension.js

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,65 @@
22
// Distributed under the terms of the Modified BSD License.
33

44
define([
5-
'widgets/js/init'
6-
], function(widgetmanager) {
5+
'nbextensions/widgets/widgets/js/init',
6+
'nbextensions/widgets/notebook/js/widgetarea',
7+
'base/js/events'
8+
], function(widgetmanager, widgetarea, events) {
79
"use strict";
10+
11+
/**
12+
* Create a widget manager for a kernel instance.
13+
*/
14+
var handle_kernel = function(kernel) {
15+
if (kernel.comm_manager && kernel.widget_manager === undefined) {
16+
17+
// Create a widget manager instance. Use the global
18+
// IPython.notebook handle.
19+
var manager = new widgetmanager.WidgetManager(kernel.comm_manager, IPython.notebook);
20+
21+
// Store a handle to the manager so we know not to
22+
// another for this kernel. This also is a convinience
23+
// for the user.
24+
kernel.widget_manager = manager;
25+
}
26+
};
27+
28+
// If a kernel already exists, create a widget manager.
29+
if (IPython.notebook && IPython.notebook.kernel) {
30+
handle_kernel(IPython.notebook.kernel);
31+
}
32+
// When the kernel is created, create a widget manager.
33+
events.on('kernel_created.Kernel kernel_created.Session', function(event, data) {
34+
handle_kernel(data.kernel);
35+
});
36+
37+
/**
38+
* Creates a widgetarea for the cell if it is a CodeCell.
39+
* If the cell isn't a CodeCell, no action is taken.
40+
*/
41+
var handle_cell = function(cell) {
42+
if (cell.cell_type==='code') {
43+
var area = new widgetarea.WidgetArea(cell);
44+
cell.widgetarea = area;
45+
}
46+
};
47+
48+
// Create widget areas for cells that already exist.
49+
var cells = IPython.notebook.get_cells();
50+
for (var i = 0; i < cells.length; i++) {
51+
handle_cell(cells[i]);
52+
}
853

9-
// TODO
10-
this.widget_manager = new widgetmanager.WidgetManager(this.comm_manager, notebook);
54+
// Listen to cell creation and deletion events. When a
55+
// cell is created, create a widget area for that cell.
56+
events.on('create.Cell', function(event, data) {
57+
handle_cell(data.cell);
58+
});
59+
// When a cell is deleted, delete the widget area if it
60+
// exists.
61+
events.on('delete.Cell', function(event, data) {
62+
if (data.cell && data.cell.widgetarea) {
63+
data.cell.widgetarea.dispose();
64+
}
65+
});
1166
});

ipython_widgets/static/notebook/js/widgetarea.js

Lines changed: 82 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,65 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
13

2-
// Events that this code should rely on.
3-
// delete.Cell
4-
// selected_cell_type_changed.Notebook
5-
// create.Cell
6-
4+
define(['jquery', 'base/js/events'], function($, events) {
5+
6+
/**
7+
* WidgetArea
8+
*/
9+
var WidgetArea = function(cell) {
710
this.widget_views = [];
11+
12+
this._cell = cell;
813
this._widgets_live = true;
14+
this.disposed = false;
15+
16+
this._create_elements();
17+
this._bind_events();
18+
}
19+
20+
/**
21+
* Display a widget view in the cell.
22+
*/
23+
WidgetArea.prototype.display_widget_view = function(view_promise) {
24+
25+
// Display a dummy element
26+
var dummy = $('<div/>');
27+
this.widget_subarea.append(dummy);
28+
29+
// Display the view.
30+
var that = this;
31+
return view_promise.then(function(view) {
32+
that.widget_area.show();
33+
dummy.replaceWith(view.$el);
34+
that.widget_views.push(view);
35+
36+
// Check the live state of the view's model.
37+
if (view.model.comm_live) {
38+
that._widget_live(view);
39+
} else {
40+
that._widget_dead(view);
41+
}
42+
43+
// Listen to comm live events for the view.
44+
view.on('comm:live', that._widget_live, that);
45+
view.on('comm:dead', that._widget_dead, that);
46+
return view;
47+
});
48+
};
49+
50+
/**
51+
* Disposes of the widget area and its widgets.
52+
*/
53+
WidgetArea.prototype.dispose = function() {
54+
this._clear();
55+
this.disposed = true;
56+
};
957

58+
/**
59+
* Creates the elements of the widget area and appends them
60+
* to the associated cell.
61+
*/
62+
WidgetArea.prototype._create_elements = function() {
1063
var widget_area = $('<div/>')
1164
.addClass('widget-area')
1265
.hide();
@@ -38,42 +91,30 @@
3891
})
3992
.appendTo(widget_prompt);
4093

94+
if (this._cell.input) {
95+
this._cell.input.after(widget_area);
96+
} else {
97+
throw new Error('Cell does not have an `input` element. Is it not a CodeCell?');
98+
}
99+
}
41100

42101
/**
43-
* Display a widget view in the cell.
44-
*/
45-
CodeCell.prototype.display_widget_view = function(view_promise) {
46-
47-
// Display a dummy element
48-
var dummy = $('<div/>');
49-
this.widget_subarea.append(dummy);
50-
51-
// Display the view.
102+
* Listens to events of the cell.
103+
*/
104+
WidgetArea.prototype._bind_events = function() {
52105
var that = this;
53-
return view_promise.then(function(view) {
54-
that.widget_area.show();
55-
dummy.replaceWith(view.$el);
56-
that.widget_views.push(view);
57-
58-
// Check the live state of the view's model.
59-
if (view.model.comm_live) {
60-
that._widget_live(view);
61-
} else {
62-
that._widget_dead(view);
106+
events.on('execute.CodeCell', function(event, data) {
107+
if (data.cell===that._cell) {
108+
that._clear();
63109
}
64-
65-
// Listen to comm live events for the view.
66-
view.on('comm:live', that._widget_live, that);
67-
view.on('comm:dead', that._widget_dead, that);
68-
return view;
69110
});
70111
};
71112

72113
/**
73114
* Handles when a widget loses it's comm connection.
74-
* @param {WidgetView} view
115+
* @param {WidgetView} view
75116
*/
76-
CodeCell.prototype._widget_dead = function(view) {
117+
WidgetArea.prototype._widget_dead = function(view) {
77118
if (this._widgets_live) {
78119
this._widgets_live = false;
79120
this.widget_area.addClass('connection-problems');
@@ -83,9 +124,9 @@
83124

84125
/**
85126
* Handles when a widget is connected to a live comm.
86-
* @param {WidgetView} view
127+
* @param {WidgetView} view
87128
*/
88-
CodeCell.prototype._widget_live = function(view) {
129+
WidgetArea.prototype._widget_live = function(view) {
89130
if (!this._widgets_live) {
90131
// Check that the other widgets are live too. O(N) operation.
91132
// Abort the function at the first dead widget found.
@@ -97,8 +138,10 @@
97138
}
98139
};
99140

100-
101-
// TODO: on event execute.CodeCell
141+
/**
142+
* Clears the widgets in the widget area.
143+
*/
144+
WidgetArea.prototype._clear = function() {
102145
// Clear widget area
103146
for (var i = 0; i < this.widget_views.length; i++) {
104147
var view = this.widget_views[i];
@@ -113,4 +156,8 @@
113156
this.widget_subarea.height('');
114157
this.widget_area.height('');
115158
this.widget_area.hide();
159+
};
160+
161+
return {WidgetArea: WidgetArea};
162+
});
116163

ipython_widgets/static/widgets/js/init.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
// Distributed under the terms of the Modified BSD License.
33

44
define([
5-
"widgets/js/manager",
6-
"widgets/js/widget",
7-
"widgets/js/widget_link",
8-
"widgets/js/widget_bool",
9-
"widgets/js/widget_button",
10-
"widgets/js/widget_box",
11-
"widgets/js/widget_float",
12-
"widgets/js/widget_image",
13-
"widgets/js/widget_int",
14-
"widgets/js/widget_output",
15-
"widgets/js/widget_selection",
16-
"widgets/js/widget_selectioncontainer",
17-
"widgets/js/widget_string",
5+
"nbextensions/widgets/widgets/js/manager",
6+
"nbextensions/widgets/widgets/js/widget",
7+
"nbextensions/widgets/widgets/js/widget_link",
8+
"nbextensions/widgets/widgets/js/widget_bool",
9+
"nbextensions/widgets/widgets/js/widget_button",
10+
"nbextensions/widgets/widgets/js/widget_box",
11+
"nbextensions/widgets/widgets/js/widget_float",
12+
"nbextensions/widgets/widgets/js/widget_image",
13+
"nbextensions/widgets/widgets/js/widget_int",
14+
"nbextensions/widgets/widgets/js/widget_output",
15+
"nbextensions/widgets/widgets/js/widget_selection",
16+
"nbextensions/widgets/widgets/js/widget_selectioncontainer",
17+
"nbextensions/widgets/widgets/js/widget_string",
1818
], function(widgetmanager, widget) {
1919
// Register all of the loaded models and views with the widget manager.
2020
for (var i = 2; i < arguments.length; i++) {

ipython_widgets/static/widgets/js/manager.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ define([
140140

141141
WidgetManager.prototype.display_view_in_cell = function(cell, model) {
142142
// Displays a view in a cell.
143-
if (cell.display_widget_view) {
143+
if (cell.widgetarea) {
144144
var that = this;
145-
return cell.display_widget_view(this.create_view(model, {
145+
return cell.widgetarea.display_widget_view(this.create_view(model, {
146146
cell: cell,
147147
// Only set cell_index when view is displayed as directly.
148148
cell_index: that.notebook.find_cell_index(cell),
@@ -152,7 +152,7 @@ define([
152152
return view;
153153
}).catch(utils.reject('Could not create or display view', true));
154154
} else {
155-
return Promise.reject(new Error('Cell does not have a `display_widget_view` method'));
155+
return Promise.reject(new Error('Cell does not have a `widgetarea` defined'));
156156
}
157157
};
158158

ipython_widgets/static/widgets/js/widget.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Jupyter Development Team.
22
// Distributed under the terms of the Modified BSD License.
33

4-
define(["widgets/js/manager",
4+
define(["nbextensions/widgets/widgets/js/manager",
55
"underscore",
66
"backbone",
77
"jquery",

ipython_widgets/static/widgets/js/widget_bool.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Distributed under the terms of the Modified BSD License.
33

44
define([
5-
"widgets/js/widget",
5+
"nbextensions/widgets/widgets/js/widget",
66
"jquery",
77
"bootstrap",
88
], function(widget, $){

ipython_widgets/static/widgets/js/widget_box.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Distributed under the terms of the Modified BSD License.
33

44
define([
5-
"widgets/js/widget",
5+
"nbextensions/widgets/widgets/js/widget",
66
"jqueryui",
77
"underscore",
88
"base/js/utils",

ipython_widgets/static/widgets/js/widget_button.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Distributed under the terms of the Modified BSD License.
33

44
define([
5-
"widgets/js/widget",
5+
"nbextensions/widgets/widgets/js/widget",
66
"jquery",
77
"bootstrap",
88
], function(widget, $){

ipython_widgets/static/widgets/js/widget_float.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// Distributed under the terms of the Modified BSD License.
33

44
define([
5-
"widgets/js/widget",
6-
"widgets/js/widget_int",
5+
"nbextensions/widgets/widgets/js/widget",
6+
"nbextensions/widgets/widgets/js/widget_int",
77
], function(widget, int_widgets){
88
var IntSliderView = int_widgets.IntSliderView;
99
var IntTextView = int_widgets.IntTextView;

0 commit comments

Comments
 (0)