##// END OF EJS Templates
fixes #6473
Bussonnier Matthias -
Show More
@@ -1,413 +1,414 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2012 The IPython Development Team
2 // Copyright (C) 2012 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 // CellToolbar
9 // CellToolbar
10 //============================================================================
10 //============================================================================
11
11
12
12
13 /**
13 /**
14 * A Module to control the per-cell toolbar.
14 * A Module to control the per-cell toolbar.
15 * @module IPython
15 * @module IPython
16 * @namespace IPython
16 * @namespace IPython
17 * @submodule CellToolbar
17 * @submodule CellToolbar
18 */
18 */
19 var IPython = (function (IPython) {
19 var IPython = (function (IPython) {
20 "use strict";
20 "use strict";
21
21
22 /**
22 /**
23 * @constructor
23 * @constructor
24 * @class CellToolbar
24 * @class CellToolbar
25 * @param {The cell to attach the metadata UI to} cell
25 * @param {The cell to attach the metadata UI to} cell
26 */
26 */
27 var CellToolbar = function (cell) {
27 var CellToolbar = function (cell) {
28 CellToolbar._instances.push(this);
28 CellToolbar._instances.push(this);
29 this.cell = cell;
29 this.cell = cell;
30 this.create_element();
30 this.create_element();
31 this.rebuild();
31 this.rebuild();
32 return this;
32 return this;
33 };
33 };
34
34
35
35
36 CellToolbar.prototype.create_element = function () {
36 CellToolbar.prototype.create_element = function () {
37 this.inner_element = $('<div/>').addClass('celltoolbar')
37 this.inner_element = $('<div/>').addClass('celltoolbar')
38 this.element = $('<div/>').addClass('ctb_hideshow')
38 this.element = $('<div/>').addClass('ctb_hideshow')
39 .append(this.inner_element);
39 .append(this.inner_element);
40 this.show();
40 this.show();
41 };
41 };
42
42
43
43
44 // The default css style for the outer celltoolbar div
44 // The default css style for the outer celltoolbar div
45 // (ctb_hideshow) is display: none.
45 // (ctb_hideshow) is display: none.
46 // To show the cell toolbar, *both* of the following conditions must be met:
46 // To show the cell toolbar, *both* of the following conditions must be met:
47 // - A parent container has class `ctb_global_show`
47 // - A parent container has class `ctb_global_show`
48 // - The celltoolbar has the class `ctb_show`
48 // - The celltoolbar has the class `ctb_show`
49 // This allows global show/hide, as well as per-cell show/hide.
49 // This allows global show/hide, as well as per-cell show/hide.
50
50
51 CellToolbar.global_hide = function () {
51 CellToolbar.global_hide = function () {
52 $('body').removeClass('ctb_global_show');
52 $('body').removeClass('ctb_global_show');
53 };
53 };
54
54
55
55
56 CellToolbar.global_show = function () {
56 CellToolbar.global_show = function () {
57 $('body').addClass('ctb_global_show');
57 $('body').addClass('ctb_global_show');
58 };
58 };
59
59
60
60
61 CellToolbar.prototype.hide = function () {
61 CellToolbar.prototype.hide = function () {
62 this.element.removeClass('ctb_show');
62 this.element.removeClass('ctb_show');
63 };
63 };
64
64
65
65
66 CellToolbar.prototype.show = function () {
66 CellToolbar.prototype.show = function () {
67 this.element.addClass('ctb_show');
67 this.element.addClass('ctb_show');
68 };
68 };
69
69
70
70
71 /**
71 /**
72 * Class variable that should contain a dict of all available callback
72 * Class variable that should contain a dict of all available callback
73 * we need to think of wether or not we allow nested namespace
73 * we need to think of wether or not we allow nested namespace
74 * @property _callback_dict
74 * @property _callback_dict
75 * @private
75 * @private
76 * @static
76 * @static
77 * @type Dict
77 * @type Dict
78 */
78 */
79 CellToolbar._callback_dict = {};
79 CellToolbar._callback_dict = {};
80
80
81
81
82 /**
82 /**
83 * Class variable that should contain the reverse order list of the button
83 * Class variable that should contain the reverse order list of the button
84 * to add to the toolbar of each cell
84 * to add to the toolbar of each cell
85 * @property _ui_controls_list
85 * @property _ui_controls_list
86 * @private
86 * @private
87 * @static
87 * @static
88 * @type List
88 * @type List
89 */
89 */
90 CellToolbar._ui_controls_list = [];
90 CellToolbar._ui_controls_list = [];
91
91
92
92
93 /**
93 /**
94 * Class variable that should contain the CellToolbar instances for each
94 * Class variable that should contain the CellToolbar instances for each
95 * cell of the notebook
95 * cell of the notebook
96 *
96 *
97 * @private
97 * @private
98 * @property _instances
98 * @property _instances
99 * @static
99 * @static
100 * @type List
100 * @type List
101 */
101 */
102 CellToolbar._instances = [];
102 CellToolbar._instances = [];
103
103
104
104
105 /**
105 /**
106 * keep a list of all the available presets for the toolbar
106 * keep a list of all the available presets for the toolbar
107 * @private
107 * @private
108 * @property _presets
108 * @property _presets
109 * @static
109 * @static
110 * @type Dict
110 * @type Dict
111 */
111 */
112 CellToolbar._presets = {};
112 CellToolbar._presets = {};
113
113
114
114
115 // this is by design not a prototype.
115 // this is by design not a prototype.
116 /**
116 /**
117 * Register a callback to create an UI element in a cell toolbar.
117 * Register a callback to create an UI element in a cell toolbar.
118 * @method register_callback
118 * @method register_callback
119 * @param name {String} name to use to refer to the callback. It is advised to use a prefix with the name
119 * @param name {String} name to use to refer to the callback. It is advised to use a prefix with the name
120 * for easier sorting and avoid collision
120 * for easier sorting and avoid collision
121 * @param callback {function(div, cell)} callback that will be called to generate the ui element
121 * @param callback {function(div, cell)} callback that will be called to generate the ui element
122 *
122 *
123 *
123 *
124 * The callback will receive the following element :
124 * The callback will receive the following element :
125 *
125 *
126 * * a div in which to add element.
126 * * a div in which to add element.
127 * * the cell it is responsible from
127 * * the cell it is responsible from
128 *
128 *
129 * @example
129 * @example
130 *
130 *
131 * Example that create callback for a button that toggle between `true` and `false` label,
131 * Example that create callback for a button that toggle between `true` and `false` label,
132 * with the metadata under the key 'foo' to reflect the status of the button.
132 * with the metadata under the key 'foo' to reflect the status of the button.
133 *
133 *
134 * // first param reference to a DOM div
134 * // first param reference to a DOM div
135 * // second param reference to the cell.
135 * // second param reference to the cell.
136 * var toggle = function(div, cell) {
136 * var toggle = function(div, cell) {
137 * var button_container = $(div)
137 * var button_container = $(div)
138 *
138 *
139 * // let's create a button that show the current value of the metadata
139 * // let's create a button that show the current value of the metadata
140 * var button = $('<div/>').button({label:String(cell.metadata.foo)});
140 * var button = $('<div/>').button({label:String(cell.metadata.foo)});
141 *
141 *
142 * // On click, change the metadata value and update the button label
142 * // On click, change the metadata value and update the button label
143 * button.click(function(){
143 * button.click(function(){
144 * var v = cell.metadata.foo;
144 * var v = cell.metadata.foo;
145 * cell.metadata.foo = !v;
145 * cell.metadata.foo = !v;
146 * button.button("option", "label", String(!v));
146 * button.button("option", "label", String(!v));
147 * })
147 * })
148 *
148 *
149 * // add the button to the DOM div.
149 * // add the button to the DOM div.
150 * button_container.append(button);
150 * button_container.append(button);
151 * }
151 * }
152 *
152 *
153 * // now we register the callback under the name `foo` to give the
153 * // now we register the callback under the name `foo` to give the
154 * // user the ability to use it later
154 * // user the ability to use it later
155 * CellToolbar.register_callback('foo', toggle);
155 * CellToolbar.register_callback('foo', toggle);
156 */
156 */
157 CellToolbar.register_callback = function(name, callback){
157 CellToolbar.register_callback = function(name, callback){
158 // Overwrite if it already exists.
158 // Overwrite if it already exists.
159 CellToolbar._callback_dict[name] = callback;
159 CellToolbar._callback_dict[name] = callback;
160 };
160 };
161
161
162
162
163 /**
163 /**
164 * Register a preset of UI element in a cell toolbar.
164 * Register a preset of UI element in a cell toolbar.
165 * Not supported Yet.
165 * Not supported Yet.
166 * @method register_preset
166 * @method register_preset
167 * @param name {String} name to use to refer to the preset. It is advised to use a prefix with the name
167 * @param name {String} name to use to refer to the preset. It is advised to use a prefix with the name
168 * for easier sorting and avoid collision
168 * for easier sorting and avoid collision
169 * @param preset_list {List of String} reverse order of the button in the toolbar. Each String of the list
169 * @param preset_list {List of String} reverse order of the button in the toolbar. Each String of the list
170 * should correspond to a name of a registerd callback.
170 * should correspond to a name of a registerd callback.
171 *
171 *
172 * @private
172 * @private
173 * @example
173 * @example
174 *
174 *
175 * CellToolbar.register_callback('foo.c1', function(div, cell){...});
175 * CellToolbar.register_callback('foo.c1', function(div, cell){...});
176 * CellToolbar.register_callback('foo.c2', function(div, cell){...});
176 * CellToolbar.register_callback('foo.c2', function(div, cell){...});
177 * CellToolbar.register_callback('foo.c3', function(div, cell){...});
177 * CellToolbar.register_callback('foo.c3', function(div, cell){...});
178 * CellToolbar.register_callback('foo.c4', function(div, cell){...});
178 * CellToolbar.register_callback('foo.c4', function(div, cell){...});
179 * CellToolbar.register_callback('foo.c5', function(div, cell){...});
179 * CellToolbar.register_callback('foo.c5', function(div, cell){...});
180 *
180 *
181 * CellToolbar.register_preset('foo.foo_preset1', ['foo.c1', 'foo.c2', 'foo.c5'])
181 * CellToolbar.register_preset('foo.foo_preset1', ['foo.c1', 'foo.c2', 'foo.c5'])
182 * CellToolbar.register_preset('foo.foo_preset2', ['foo.c4', 'foo.c5'])
182 * CellToolbar.register_preset('foo.foo_preset2', ['foo.c4', 'foo.c5'])
183 */
183 */
184 CellToolbar.register_preset = function(name, preset_list) {
184 CellToolbar.register_preset = function(name, preset_list) {
185 CellToolbar._presets[name] = preset_list;
185 CellToolbar._presets[name] = preset_list;
186 $([IPython.events]).trigger('preset_added.CellToolbar', {name: name});
186 $([IPython.events]).trigger('preset_added.CellToolbar', {name: name});
187 // When "register_callback" is called by a custom extension, it may be executed after notebook is loaded.
187 // When "register_callback" is called by a custom extension, it may be executed after notebook is loaded.
188 // In that case, activate the preset if needed.
188 // In that case, activate the preset if needed.
189 if (IPython.notebook && IPython.notebook.metadata && IPython.notebook.metadata.celltoolbar === name)
189 if (IPython.notebook && IPython.notebook.metadata && IPython.notebook.metadata.celltoolbar === name)
190 this.activate_preset(name);
190 this.activate_preset(name);
191 };
191 };
192
192
193
193
194 /**
194 /**
195 * List the names of the presets that are currently registered.
195 * List the names of the presets that are currently registered.
196 *
196 *
197 * @method list_presets
197 * @method list_presets
198 * @static
198 * @static
199 */
199 */
200 CellToolbar.list_presets = function() {
200 CellToolbar.list_presets = function() {
201 var keys = [];
201 var keys = [];
202 for (var k in CellToolbar._presets) {
202 for (var k in CellToolbar._presets) {
203 keys.push(k);
203 keys.push(k);
204 }
204 }
205 return keys;
205 return keys;
206 };
206 };
207
207
208
208
209 /**
209 /**
210 * Activate an UI preset from `register_preset`
210 * Activate an UI preset from `register_preset`
211 *
211 *
212 * This does not update the selection UI.
212 * This does not update the selection UI.
213 *
213 *
214 * @method activate_preset
214 * @method activate_preset
215 * @param preset_name {String} string corresponding to the preset name
215 * @param preset_name {String} string corresponding to the preset name
216 *
216 *
217 * @static
217 * @static
218 * @private
218 * @private
219 * @example
219 * @example
220 *
220 *
221 * CellToolbar.activate_preset('foo.foo_preset1');
221 * CellToolbar.activate_preset('foo.foo_preset1');
222 */
222 */
223 CellToolbar.activate_preset = function(preset_name){
223 CellToolbar.activate_preset = function(preset_name){
224 var preset = CellToolbar._presets[preset_name];
224 var preset = CellToolbar._presets[preset_name];
225
225
226 if(preset !== undefined){
226 if(preset !== undefined){
227 CellToolbar._ui_controls_list = preset;
227 CellToolbar._ui_controls_list = preset;
228 CellToolbar.rebuild_all();
228 CellToolbar.rebuild_all();
229 }
229 }
230
230
231 $([IPython.events]).trigger('preset_activated.CellToolbar', {name: preset_name});
231 $([IPython.events]).trigger('preset_activated.CellToolbar', {name: preset_name});
232 };
232 };
233
233
234
234
235 /**
235 /**
236 * This should be called on the class and not on a instance as it will trigger
236 * This should be called on the class and not on a instance as it will trigger
237 * rebuild of all the instances.
237 * rebuild of all the instances.
238 * @method rebuild_all
238 * @method rebuild_all
239 * @static
239 * @static
240 *
240 *
241 */
241 */
242 CellToolbar.rebuild_all = function(){
242 CellToolbar.rebuild_all = function(){
243 for(var i=0; i < CellToolbar._instances.length; i++){
243 for(var i=0; i < CellToolbar._instances.length; i++){
244 CellToolbar._instances[i].rebuild();
244 CellToolbar._instances[i].rebuild();
245 }
245 }
246 };
246 };
247
247
248 /**
248 /**
249 * Rebuild all the button on the toolbar to update its state.
249 * Rebuild all the button on the toolbar to update its state.
250 * @method rebuild
250 * @method rebuild
251 */
251 */
252 CellToolbar.prototype.rebuild = function(){
252 CellToolbar.prototype.rebuild = function(){
253 // strip evrything from the div
253 // strip evrything from the div
254 // which is probably inner_element
254 // which is probably inner_element
255 // or this.element.
255 // or this.element.
256 this.inner_element.empty();
256 this.inner_element.empty();
257 this.show();
257
258
258 var callbacks = CellToolbar._callback_dict;
259 var callbacks = CellToolbar._callback_dict;
259 var preset = CellToolbar._ui_controls_list;
260 var preset = CellToolbar._ui_controls_list;
260 // Yes we iterate on the class variable, not the instance one.
261 // Yes we iterate on the class variable, not the instance one.
261 for (var i=0; i < preset.length; i++) {
262 for (var i=0; i < preset.length; i++) {
262 var key = preset[i];
263 var key = preset[i];
263 var callback = callbacks[key];
264 var callback = callbacks[key];
264 if (!callback) continue;
265 if (!callback) continue;
265
266
266 var local_div = $('<div/>').addClass('button_container');
267 var local_div = $('<div/>').addClass('button_container');
267 try {
268 try {
268 callback(local_div, this.cell, this);
269 callback(local_div, this.cell, this);
269 } catch (e) {
270 } catch (e) {
270 console.log("Error in cell toolbar callback " + key, e);
271 console.log("Error in cell toolbar callback " + key, e);
271 continue;
272 continue;
272 }
273 }
273 // only append if callback succeeded.
274 // only append if callback succeeded.
274 this.inner_element.append(local_div);
275 this.inner_element.append(local_div);
275 }
276 }
276 };
277 };
277
278
278
279
279 /**
280 /**
280 */
281 */
281 CellToolbar.utils = {};
282 CellToolbar.utils = {};
282
283
283
284
284 /**
285 /**
285 * A utility function to generate bindings between a checkbox and cell/metadata
286 * A utility function to generate bindings between a checkbox and cell/metadata
286 * @method utils.checkbox_ui_generator
287 * @method utils.checkbox_ui_generator
287 * @static
288 * @static
288 *
289 *
289 * @param name {string} Label in front of the checkbox
290 * @param name {string} Label in front of the checkbox
290 * @param setter {function( cell, newValue )}
291 * @param setter {function( cell, newValue )}
291 * A setter method to set the newValue
292 * A setter method to set the newValue
292 * @param getter {function( cell )}
293 * @param getter {function( cell )}
293 * A getter methods which return the current value.
294 * A getter methods which return the current value.
294 *
295 *
295 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
296 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
296 *
297 *
297 * @example
298 * @example
298 *
299 *
299 * An exmple that bind the subkey `slideshow.isSectionStart` to a checkbox with a `New Slide` label
300 * An exmple that bind the subkey `slideshow.isSectionStart` to a checkbox with a `New Slide` label
300 *
301 *
301 * var newSlide = CellToolbar.utils.checkbox_ui_generator('New Slide',
302 * var newSlide = CellToolbar.utils.checkbox_ui_generator('New Slide',
302 * // setter
303 * // setter
303 * function(cell, value){
304 * function(cell, value){
304 * // we check that the slideshow namespace exist and create it if needed
305 * // we check that the slideshow namespace exist and create it if needed
305 * if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
306 * if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
306 * // set the value
307 * // set the value
307 * cell.metadata.slideshow.isSectionStart = value
308 * cell.metadata.slideshow.isSectionStart = value
308 * },
309 * },
309 * //geter
310 * //geter
310 * function(cell){ var ns = cell.metadata.slideshow;
311 * function(cell){ var ns = cell.metadata.slideshow;
311 * // if the slideshow namespace does not exist return `undefined`
312 * // if the slideshow namespace does not exist return `undefined`
312 * // (will be interpreted as `false` by checkbox) otherwise
313 * // (will be interpreted as `false` by checkbox) otherwise
313 * // return the value
314 * // return the value
314 * return (ns == undefined)? undefined: ns.isSectionStart
315 * return (ns == undefined)? undefined: ns.isSectionStart
315 * }
316 * }
316 * );
317 * );
317 *
318 *
318 * CellToolbar.register_callback('newSlide', newSlide);
319 * CellToolbar.register_callback('newSlide', newSlide);
319 *
320 *
320 */
321 */
321 CellToolbar.utils.checkbox_ui_generator = function(name, setter, getter){
322 CellToolbar.utils.checkbox_ui_generator = function(name, setter, getter){
322 return function(div, cell, celltoolbar) {
323 return function(div, cell, celltoolbar) {
323 var button_container = $(div);
324 var button_container = $(div);
324
325
325 var chkb = $('<input/>').attr('type', 'checkbox');
326 var chkb = $('<input/>').attr('type', 'checkbox');
326 var lbl = $('<label/>').append($('<span/>').text(name));
327 var lbl = $('<label/>').append($('<span/>').text(name));
327 lbl.append(chkb);
328 lbl.append(chkb);
328 chkb.attr("checked", getter(cell));
329 chkb.attr("checked", getter(cell));
329
330
330 chkb.click(function(){
331 chkb.click(function(){
331 var v = getter(cell);
332 var v = getter(cell);
332 setter(cell, !v);
333 setter(cell, !v);
333 chkb.attr("checked", !v);
334 chkb.attr("checked", !v);
334 });
335 });
335 button_container.append($('<div/>').append(lbl));
336 button_container.append($('<div/>').append(lbl));
336 };
337 };
337 };
338 };
338
339
339
340
340 /**
341 /**
341 * A utility function to generate bindings between a dropdown list cell
342 * A utility function to generate bindings between a dropdown list cell
342 * @method utils.select_ui_generator
343 * @method utils.select_ui_generator
343 * @static
344 * @static
344 *
345 *
345 * @param list_list {list of sublist} List of sublist of metadata value and name in the dropdown list.
346 * @param list_list {list of sublist} List of sublist of metadata value and name in the dropdown list.
346 * subslit shoud contain 2 element each, first a string that woul be displayed in the dropdown list,
347 * subslit shoud contain 2 element each, first a string that woul be displayed in the dropdown list,
347 * and second the corresponding value to be passed to setter/return by getter. the corresponding value
348 * and second the corresponding value to be passed to setter/return by getter. the corresponding value
348 * should not be "undefined" or behavior can be unexpected.
349 * should not be "undefined" or behavior can be unexpected.
349 * @param setter {function( cell, newValue )}
350 * @param setter {function( cell, newValue )}
350 * A setter method to set the newValue
351 * A setter method to set the newValue
351 * @param getter {function( cell )}
352 * @param getter {function( cell )}
352 * A getter methods which return the current value of the metadata.
353 * A getter methods which return the current value of the metadata.
353 * @param [label=""] {String} optionnal label for the dropdown menu
354 * @param [label=""] {String} optionnal label for the dropdown menu
354 *
355 *
355 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
356 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
356 *
357 *
357 * @example
358 * @example
358 *
359 *
359 * var select_type = CellToolbar.utils.select_ui_generator([
360 * var select_type = CellToolbar.utils.select_ui_generator([
360 * ["<None>" , "None" ],
361 * ["<None>" , "None" ],
361 * ["Header Slide" , "header_slide" ],
362 * ["Header Slide" , "header_slide" ],
362 * ["Slide" , "slide" ],
363 * ["Slide" , "slide" ],
363 * ["Fragment" , "fragment" ],
364 * ["Fragment" , "fragment" ],
364 * ["Skip" , "skip" ],
365 * ["Skip" , "skip" ],
365 * ],
366 * ],
366 * // setter
367 * // setter
367 * function(cell, value){
368 * function(cell, value){
368 * // we check that the slideshow namespace exist and create it if needed
369 * // we check that the slideshow namespace exist and create it if needed
369 * if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
370 * if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
370 * // set the value
371 * // set the value
371 * cell.metadata.slideshow.slide_type = value
372 * cell.metadata.slideshow.slide_type = value
372 * },
373 * },
373 * //geter
374 * //geter
374 * function(cell){ var ns = cell.metadata.slideshow;
375 * function(cell){ var ns = cell.metadata.slideshow;
375 * // if the slideshow namespace does not exist return `undefined`
376 * // if the slideshow namespace does not exist return `undefined`
376 * // (will be interpreted as `false` by checkbox) otherwise
377 * // (will be interpreted as `false` by checkbox) otherwise
377 * // return the value
378 * // return the value
378 * return (ns == undefined)? undefined: ns.slide_type
379 * return (ns == undefined)? undefined: ns.slide_type
379 * }
380 * }
380 * CellToolbar.register_callback('slideshow.select', select_type);
381 * CellToolbar.register_callback('slideshow.select', select_type);
381 *
382 *
382 */
383 */
383 CellToolbar.utils.select_ui_generator = function(list_list, setter, getter, label, cell_types){
384 CellToolbar.utils.select_ui_generator = function(list_list, setter, getter, label, cell_types){
384 label = label || "";
385 label = label || "";
385 return function(div, cell, celltoolbar) {
386 return function(div, cell, celltoolbar) {
386 var button_container = $(div);
387 var button_container = $(div);
387 var lbl = $("<label/>").append($('<span/>').text(label));
388 var lbl = $("<label/>").append($('<span/>').text(label));
388 var select = $('<select/>').addClass('ui-widget ui-widget-content');
389 var select = $('<select/>').addClass('ui-widget ui-widget-content');
389 for(var i=0; i < list_list.length; i++){
390 for(var i=0; i < list_list.length; i++){
390 var opt = $('<option/>')
391 var opt = $('<option/>')
391 .attr('value', list_list[i][1])
392 .attr('value', list_list[i][1])
392 .text(list_list[i][0]);
393 .text(list_list[i][0]);
393 select.append(opt);
394 select.append(opt);
394 }
395 }
395 select.val(getter(cell));
396 select.val(getter(cell));
396 select.change(function(){
397 select.change(function(){
397 setter(cell, select.val());
398 setter(cell, select.val());
398 });
399 });
399 button_container.append($('<div/>').append(lbl).append(select));
400 button_container.append($('<div/>').append(lbl).append(select));
400 if (cell_types && cell_types.indexOf(cell.cell_type) == -1) {
401 if (cell_types && cell_types.indexOf(cell.cell_type) == -1) {
401 celltoolbar.hide();
402 celltoolbar.hide();
402 } else {
403 } else {
403 celltoolbar.show();
404 celltoolbar.show();
404 }
405 }
405
406
406 };
407 };
407 };
408 };
408
409
409
410
410 IPython.CellToolbar = CellToolbar;
411 IPython.CellToolbar = CellToolbar;
411
412
412 return IPython;
413 return IPython;
413 }(IPython));
414 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now