##// END OF EJS Templates
Merge pull request #6169 from tarzzz/fix-requirejs...
Min RK -
r17278:4017ee41 merge
parent child Browse files
Show More
@@ -1,200 +1,201 b''
1 1 // Copyright (c) IPython Development Team.
2 2 // Distributed under the terms of the Modified BSD License.
3 3
4 4 define([
5 5 "underscore",
6 6 "backbone",
7 "jquery",
7 8 "base/js/namespace"
8 ], function (_, Backbone, IPython) {
9 ], function (_, Backbone, $, IPython) {
9 10
10 11 //--------------------------------------------------------------------
11 12 // WidgetManager class
12 13 //--------------------------------------------------------------------
13 14 var WidgetManager = function (comm_manager, notebook) {
14 15 // Public constructor
15 16 WidgetManager._managers.push(this);
16 17
17 18 // Attach a comm manager to the
18 19 this.keyboard_manager = notebook.keyboard_manager;
19 20 this.notebook = notebook;
20 21 this.comm_manager = comm_manager;
21 22 this._models = {}; /* Dictionary of model ids and model instances */
22 23
23 24 // Register already-registered widget model types with the comm manager.
24 25 var that = this;
25 26 _.each(WidgetManager._model_types, function(model_type, model_name) {
26 27 that.comm_manager.register_target(model_name, $.proxy(that._handle_comm_open, that));
27 28 });
28 29 };
29 30
30 31 //--------------------------------------------------------------------
31 32 // Class level
32 33 //--------------------------------------------------------------------
33 34 WidgetManager._model_types = {}; /* Dictionary of model type names (target_name) and model types. */
34 35 WidgetManager._view_types = {}; /* Dictionary of view names and view types. */
35 36 WidgetManager._managers = []; /* List of widget managers */
36 37
37 38 WidgetManager.register_widget_model = function (model_name, model_type) {
38 39 // Registers a widget model by name.
39 40 WidgetManager._model_types[model_name] = model_type;
40 41
41 42 // Register the widget with the comm manager. Make sure to pass this object's context
42 43 // in so `this` works in the call back.
43 44 _.each(WidgetManager._managers, function(instance, i) {
44 45 if (instance.comm_manager !== null) {
45 46 instance.comm_manager.register_target(model_name, $.proxy(instance._handle_comm_open, instance));
46 47 }
47 48 });
48 49 };
49 50
50 51 WidgetManager.register_widget_view = function (view_name, view_type) {
51 52 // Registers a widget view by name.
52 53 WidgetManager._view_types[view_name] = view_type;
53 54 };
54 55
55 56 //--------------------------------------------------------------------
56 57 // Instance level
57 58 //--------------------------------------------------------------------
58 59 WidgetManager.prototype.display_view = function(msg, model) {
59 60 // Displays a view for a particular model.
60 61 var cell = this.get_msg_cell(msg.parent_header.msg_id);
61 62 if (cell === null) {
62 63 console.log("Could not determine where the display" +
63 64 " message was from. Widget will not be displayed");
64 65 } else {
65 66 var view = this.create_view(model, {cell: cell});
66 67 if (view === null) {
67 68 console.error("View creation failed", model);
68 69 }
69 70 this._handle_display_view(view);
70 71 if (cell.widget_subarea) {
71 72 cell.widget_subarea.append(view.$el);
72 73 }
73 74 view.trigger('displayed');
74 75 }
75 76 };
76 77
77 78 WidgetManager.prototype._handle_display_view = function (view) {
78 79 // Have the IPython keyboard manager disable its event
79 80 // handling so the widget can capture keyboard input.
80 81 // Note, this is only done on the outer most widgets.
81 82 if (this.keyboard_manager) {
82 83 this.keyboard_manager.register_events(view.$el);
83 84
84 85 if (view.additional_elements) {
85 86 for (var i = 0; i < view.additional_elements.length; i++) {
86 87 this.keyboard_manager.register_events(view.additional_elements[i]);
87 88 }
88 89 }
89 90 }
90 91 };
91 92
92 93 WidgetManager.prototype.create_view = function(model, options, view) {
93 94 // Creates a view for a particular model.
94 95 var view_name = model.get('_view_name');
95 96 var ViewType = WidgetManager._view_types[view_name];
96 97 if (ViewType) {
97 98
98 99 // If a view is passed into the method, use that view's cell as
99 100 // the cell for the view that is created.
100 101 options = options || {};
101 102 if (view !== undefined) {
102 103 options.cell = view.options.cell;
103 104 }
104 105
105 106 // Create and render the view...
106 107 var parameters = {model: model, options: options};
107 108 view = new ViewType(parameters);
108 109 view.render();
109 110 model.on('destroy', view.remove, view);
110 111 return view;
111 112 }
112 113 return null;
113 114 };
114 115
115 116 WidgetManager.prototype.get_msg_cell = function (msg_id) {
116 117 var cell = null;
117 118 // First, check to see if the msg was triggered by cell execution.
118 119 if (this.notebook) {
119 120 cell = this.notebook.get_msg_cell(msg_id);
120 121 }
121 122 if (cell !== null) {
122 123 return cell;
123 124 }
124 125 // Second, check to see if a get_cell callback was defined
125 126 // for the message. get_cell callbacks are registered for
126 127 // widget messages, so this block is actually checking to see if the
127 128 // message was triggered by a widget.
128 129 var kernel = this.comm_manager.kernel;
129 130 if (kernel) {
130 131 var callbacks = kernel.get_callbacks_for_msg(msg_id);
131 132 if (callbacks && callbacks.iopub &&
132 133 callbacks.iopub.get_cell !== undefined) {
133 134 return callbacks.iopub.get_cell();
134 135 }
135 136 }
136 137
137 138 // Not triggered by a cell or widget (no get_cell callback
138 139 // exists).
139 140 return null;
140 141 };
141 142
142 143 WidgetManager.prototype.callbacks = function (view) {
143 144 // callback handlers specific a view
144 145 var callbacks = {};
145 146 if (view && view.options.cell) {
146 147
147 148 // Try to get output handlers
148 149 var cell = view.options.cell;
149 150 var handle_output = null;
150 151 var handle_clear_output = null;
151 152 if (cell.output_area) {
152 153 handle_output = $.proxy(cell.output_area.handle_output, cell.output_area);
153 154 handle_clear_output = $.proxy(cell.output_area.handle_clear_output, cell.output_area);
154 155 }
155 156
156 157 // Create callback dict using what is known
157 158 var that = this;
158 159 callbacks = {
159 160 iopub : {
160 161 output : handle_output,
161 162 clear_output : handle_clear_output,
162 163
163 164 // Special function only registered by widget messages.
164 165 // Allows us to get the cell for a message so we know
165 166 // where to add widgets if the code requires it.
166 167 get_cell : function () {
167 168 return cell;
168 169 },
169 170 },
170 171 };
171 172 }
172 173 return callbacks;
173 174 };
174 175
175 176 WidgetManager.prototype.get_model = function (model_id) {
176 177 // Look-up a model instance by its id.
177 178 var model = this._models[model_id];
178 179 if (model !== undefined && model.id == model_id) {
179 180 return model;
180 181 }
181 182 return null;
182 183 };
183 184
184 185 WidgetManager.prototype._handle_comm_open = function (comm, msg) {
185 186 // Handle when a comm is opened.
186 187 var that = this;
187 188 var model_id = comm.comm_id;
188 189 var widget_type_name = msg.content.target_name;
189 190 var widget_model = new WidgetManager._model_types[widget_type_name](this, model_id, comm);
190 191 widget_model.on('comm:close', function () {
191 192 delete that._models[model_id];
192 193 });
193 194 this._models[model_id] = widget_model;
194 195 };
195 196
196 197 // Backwards compatability.
197 198 IPython.WidgetManager = WidgetManager;
198 199
199 200 return {'WidgetManager': WidgetManager};
200 201 });
General Comments 0
You need to be logged in to leave comments. Login now