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