##// END OF EJS Templates
Merge pull request #6700 from Carreau/actions-2...
Min RK -
r19499:baf65dc2 merge
parent child Browse files
Show More
@@ -38,6 +38,14 b' define(['
38 // for this particular combination
38 // for this particular combination
39 this.element.addClass('notification_widget btn btn-xs navbar-btn');
39 this.element.addClass('notification_widget btn btn-xs navbar-btn');
40 };
40 };
41
42 /**
43 * hide the widget and empty the text
44 **/
45 NotificationWidget.prototype.hide = function () {
46 var that = this;
47 this.element.fadeOut(100, function(){that.inner.text('');});
48 };
41
49
42 /**
50 /**
43 * Set the notification widget message to display for a certain
51 * Set the notification widget message to display for a certain
@@ -2,11 +2,12 b''
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'require',
5 'base/js/namespace',
6 'base/js/namespace',
6 'jquery',
7 'jquery',
7 'notebook/js/toolbar',
8 './toolbar',
8 'notebook/js/celltoolbar',
9 './celltoolbar'
9 ], function(IPython, $, toolbar, celltoolbar) {
10 ], function(require, IPython, $, toolbar, celltoolbar) {
10 "use strict";
11 "use strict";
11
12
12 var MainToolBar = function (selector, options) {
13 var MainToolBar = function (selector, options) {
@@ -19,141 +20,97 b' define(['
19 * Dictionary of keyword arguments.
20 * Dictionary of keyword arguments.
20 * events: $(Events) instance
21 * events: $(Events) instance
21 * notebook: Notebook instance
22 * notebook: Notebook instance
22 */
23 **/
23 toolbar.ToolBar.apply(this, arguments);
24 toolbar.ToolBar.apply(this, [selector, options] );
24 this.events = options.events;
25 this.events = options.events;
25 this.notebook = options.notebook;
26 this.notebook = options.notebook;
26 this.construct();
27 this._make();
27 this.add_celltype_list();
28 Object.seal(this);
28 this.add_celltoolbar_list();
29 this.bind_events();
30 };
29 };
31
30
32 MainToolBar.prototype = Object.create(toolbar.ToolBar.prototype);
31 MainToolBar.prototype = Object.create(toolbar.ToolBar.prototype);
33
32
34 MainToolBar.prototype.construct = function () {
33 MainToolBar.prototype._make = function () {
35 var that = this;
34 var grps = [
36 this.add_buttons_group([
35 [
37 {
36 ['ipython.save-notebook'],
38 id : 'save_b',
37 'save-notbook'
39 label : 'Save and Checkpoint',
38 ],
40 icon : 'fa-save',
39 [
41 callback : function () {
40 ['ipython.insert-cell-after'],
42 that.notebook.save_checkpoint();
41 'insert_above_below'],
43 }
42 [
44 }
43 ['ipython.cut-selected-cell',
45 ]);
44 'ipython.copy-selected-cell',
46
45 'ipython.paste-cell-after'
47 this.add_buttons_group([
46 ] ,
48 {
47 'cut_copy_paste'],
49 id : 'insert_below_b',
48 [
50 label : 'Insert Cell Below',
49 ['ipython.move-selected-cell-up',
51 icon : 'fa-plus',
50 'ipython.move-selected-cell-down'
52 callback : function () {
51 ],
53 that.notebook.insert_cell_below('code');
52 'move_up_down'],
54 that.notebook.select_next();
53 [ ['ipython.run-select-next',
55 that.notebook.focus_cell();
54 'ipython.interrupt-kernel',
56 }
55 'ipython.restart-kernel'
57 }
56 ],
58 ],'insert_above_below');
57 'run_int'],
59
58 ['<add_celltype_list>'],
60 this.add_buttons_group([
59 ['<add_celltoolbar_list>']
61 {
60 ];
62 id : 'cut_b',
61 this.construct(grps);
63 label : 'Cut Cell',
64 icon : 'fa-cut',
65 callback : function () {
66 that.notebook.cut_cell();
67 }
68 },
69 {
70 id : 'copy_b',
71 label : 'Copy Cell',
72 icon : 'fa-copy',
73 callback : function () {
74 that.notebook.copy_cell();
75 }
76 },
77 {
78 id : 'paste_b',
79 label : 'Paste Cell Below',
80 icon : 'fa-paste',
81 callback : function () {
82 that.notebook.paste_cell_below();
83 }
84 }
85 ],'cut_copy_paste');
86
87 this.add_buttons_group([
88 {
89 id : 'move_up_b',
90 label : 'Move Cell Up',
91 icon : 'fa-arrow-up',
92 callback : function () {
93 that.notebook.move_cell_up();
94 }
95 },
96 {
97 id : 'move_down_b',
98 label : 'Move Cell Down',
99 icon : 'fa-arrow-down',
100 callback : function () {
101 that.notebook.move_cell_down();
102 }
103 }
104 ],'move_up_down');
105
106
107 this.add_buttons_group([
108 {
109 id : 'run_b',
110 label : 'Run Cell',
111 icon : 'fa-play',
112 callback : function () {
113 /**
114 * emulate default shift-enter behavior
115 */
116 that.notebook.execute_cell_and_select_below();
117 }
118 },
119 {
120 id : 'interrupt_b',
121 label : 'Interrupt',
122 icon : 'fa-stop',
123 callback : function () {
124 that.notebook.kernel.interrupt();
125 }
126 },
127 {
128 id : 'repeat_b',
129 label : 'Restart Kernel',
130 icon : 'fa-repeat',
131 callback : function () {
132 that.notebook.restart_kernel();
133 }
134 }
135 ],'run_int');
136 };
62 };
137
63
138 MainToolBar.prototype.add_celltype_list = function () {
64 // add a cell type drop down to the maintoolbar.
139 this.element
65 // triggered when the pseudo action `<add_celltype_list>` is
140 .append($('<select/>')
66 // encountered when building a toolbar.
141 .attr('id','cell_type')
67 MainToolBar.prototype._pseudo_actions.add_celltype_list = function () {
142 .addClass('form-control select-xs')
68 var that = this;
143 .append($('<option/>').attr('value','code').text('Code'))
69 var sel = $('<select/>')
144 .append($('<option/>').attr('value','markdown').text('Markdown'))
70 .attr('id','cell_type')
145 .append($('<option/>').attr('value','raw').text('Raw NBConvert'))
71 .addClass('form-control select-xs')
146 .append($('<option/>').attr('value','heading').text('Heading'))
72 .append($('<option/>').attr('value','code').text('Code'))
147 );
73 .append($('<option/>').attr('value','markdown').text('Markdown'))
74 .append($('<option/>').attr('value','raw').text('Raw NBConvert'))
75 .append($('<option/>').attr('value','heading').text('Heading'));
76 this.events.on('selected_cell_type_changed.Notebook', function (event, data) {
77 if (data.cell_type === 'heading') {
78 sel.val('Markdown');
79 } else {
80 sel.val(data.cell_type);
81 }
82 });
83 sel.change(function () {
84 var cell_type = $(this).val();
85 switch (cell_type) {
86 case 'code':
87 that.notebook.to_code();
88 break;
89 case 'markdown':
90 that.notebook.to_markdown();
91 break;
92 case 'raw':
93 that.notebook.to_raw();
94 break;
95 case 'heading':
96 that.notebook._warn_heading();
97 that.notebook.to_heading();
98 sel.val('markdown');
99 break;
100 default:
101 console.log("unrecognized cell type:", cell_type);
102 }
103 });
104 return sel;
105
148 };
106 };
149
107
150 MainToolBar.prototype.add_celltoolbar_list = function () {
108 MainToolBar.prototype._pseudo_actions.add_celltoolbar_list = function () {
151 var label = $('<span/>').addClass("navbar-text").text('Cell Toolbar:');
109 var label = $('<span/>').addClass("navbar-text").text('Cell Toolbar:');
152 var select = $('<select/>')
110 var select = $('<select/>')
153 .attr('id', 'ctb_select')
111 .attr('id', 'ctb_select')
154 .addClass('form-control select-xs')
112 .addClass('form-control select-xs')
155 .append($('<option/>').attr('value', '').text('None'));
113 .append($('<option/>').attr('value', '').text('None'));
156 this.element.append(label).append(select);
157 var that = this;
114 var that = this;
158 select.change(function() {
115 select.change(function() {
159 var val = $(this).val();
116 var val = $(this).val();
@@ -182,42 +139,13 b' define(['
182 if (select.val() !== data.name)
139 if (select.val() !== data.name)
183 select.val(data.name);
140 select.val(data.name);
184 });
141 });
185 };
186
142
187 MainToolBar.prototype.bind_events = function () {
143 var wrapper = $('<div/>').addClass('btn-group');
188 var that = this;
144 wrapper.append(label).append(select);
189
145 return wrapper;
190 this.element.find('#cell_type').change(function () {
191 var cell_type = $(this).val();
192 switch (cell_type) {
193 case 'code':
194 that.notebook.to_code();
195 break;
196 case 'markdown':
197 that.notebook.to_markdown();
198 break;
199 case 'raw':
200 that.notebook.to_raw();
201 break;
202 case 'heading':
203 that.notebook._warn_heading();
204 that.notebook.to_heading();
205 that.element.find('#cell_type').val("markdown");
206 break;
207 default:
208 console.log("unrecognized cell type:", cell_type);
209 }
210 });
211 this.events.on('selected_cell_type_changed.Notebook', function (event, data) {
212 if (data.cell_type === 'heading') {
213 that.element.find('#cell_type').val(data.cell_type+data.level);
214 } else {
215 that.element.find('#cell_type').val(data.cell_type);
216 }
217 });
218 };
146 };
219
147
220 // Backwards compatability.
148 // Backwards compatibility.
221 IPython.MainToolBar = MainToolBar;
149 IPython.MainToolBar = MainToolBar;
222
150
223 return {'MainToolBar': MainToolBar};
151 return {'MainToolBar': MainToolBar};
@@ -65,6 +65,86 b' define(['
65 { shortcut: cmd_ctrl + "Shift-z", help:"redo" },
65 { shortcut: cmd_ctrl + "Shift-z", help:"redo" },
66 { shortcut: cmd_ctrl + "y", help:"redo" },
66 { shortcut: cmd_ctrl + "y", help:"redo" },
67 ].concat( platform_specific );
67 ].concat( platform_specific );
68
69 var mac_humanize_map = {
70 // all these are unicode, will probably display badly on anything except macs.
71 // these are the standard symbol that are used in MacOS native menus
72 // cf http://apple.stackexchange.com/questions/55727/
73 // for htmlentities and/or unicode value
74 'cmd':'⌘',
75 'shift':'⇧',
76 'alt':'⌥',
77 'up':'↑',
78 'down':'↓',
79 'left':'←',
80 'right':'→',
81 'eject':'⏏',
82 'tab':'⇥',
83 'backtab':'⇤',
84 'capslock':'⇪',
85 'esc':'⎋',
86 'ctrl':'⌃',
87 'enter':'↩',
88 'pageup':'⇞',
89 'pagedown':'⇟',
90 'home':'↖',
91 'end':'↘',
92 'altenter':'⌤',
93 'space':'␣',
94 'delete':'⌦',
95 'backspace':'⌫',
96 'apple':'',
97 };
98
99 var default_humanize_map = {
100 'shift':'Shift',
101 'alt':'Alt',
102 'up':'Up',
103 'down':'Down',
104 'left':'Left',
105 'right':'Right',
106 'tab':'Tab',
107 'capslock':'Caps Lock',
108 'esc':'Esc',
109 'ctrl':'Ctrl',
110 'enter':'Enter',
111 'pageup':'Page Up',
112 'pagedown':'Page Down',
113 'home':'Home',
114 'end':'End',
115 'space':'Space',
116 'backspace':'Backspace',
117 };
118
119 var humanize_map;
120
121 if (platform === 'MacOS'){
122 humanize_map = mac_humanize_map;
123 } else {
124 humanize_map = default_humanize_map;
125 }
126
127 function humanize_key(key){
128 if (key.length === 1){
129 key = key.toUpperCase();
130 }
131 return humanize_map[key.toLowerCase()]||key;
132 }
133
134 function humanize_sequence(sequence){
135 var joinchar = ',';
136 var hum = _.map(sequence.replace(/meta/g, 'cmd').split(','), humanize_shortcut).join(joinchar);
137 return hum;
138 }
139
140 function humanize_shortcut(shortcut){
141 var joinchar = '-';
142 if (platform === 'MacOS'){
143 joinchar = '';
144 }
145 var sh = _.map(shortcut.split('-'), humanize_key ).join(joinchar);
146 return sh;
147 }
68
148
69
149
70 QuickHelp.prototype.show_keyboard_shortcuts = function () {
150 QuickHelp.prototype.show_keyboard_shortcuts = function () {
@@ -157,7 +237,10 b' define(['
157
237
158 var build_one = function (s) {
238 var build_one = function (s) {
159 var help = s.help;
239 var help = s.help;
160 var shortcut = prettify(s.shortcut);
240 var shortcut = '';
241 if(s.shortcut){
242 shortcut = prettify(humanize_sequence(s.shortcut));
243 }
161 return $('<div>').addClass('quickhelp').
244 return $('<div>').addClass('quickhelp').
162 append($('<span/>').addClass('shortcut_key').append($(shortcut))).
245 append($('<span/>').addClass('shortcut_key').append($(shortcut))).
163 append($('<span/>').addClass('shortcut_descr').text(' : ' + help));
246 append($('<span/>').addClass('shortcut_descr').text(' : ' + help));
@@ -3,7 +3,7 b''
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery'
7 ], function(IPython, $) {
7 ], function(IPython, $) {
8 "use strict";
8 "use strict";
9
9
@@ -11,22 +11,52 b' define(['
11 * A generic toolbar on which one can add button
11 * A generic toolbar on which one can add button
12 * @class ToolBar
12 * @class ToolBar
13 * @constructor
13 * @constructor
14 * @param {Dom object} selector
14 * @param {Dom_object} selector
15 */
15 */
16 var ToolBar = function (selector) {
16 var ToolBar = function (selector, options) {
17 this.selector = selector;
17 this.selector = selector;
18 this.actions = (options||{}).actions;
18 if (this.selector !== undefined) {
19 if (this.selector !== undefined) {
19 this.element = $(selector);
20 this.element = $(selector);
20 this.style();
21 this.style();
21 }
22 }
22 };
23 };
23
24
25 ToolBar.prototype._pseudo_actions={};
26
27
28 ToolBar.prototype.construct = function (config) {
29 for(var k in config){
30 this.add_buttons_group(config[k][0],k[1]);
31 }
32 };
33
24 /**
34 /**
25 * add a group of button into the current toolbar.
35 * Add a group of button into the current toolbar.
26 *
36 *
37 * Use a [dict of [list of action name]] to trigger
38 * on click to the button
27 *
39 *
28 * @example
40 * @example
29 *
41 *
42 * ... todo, maybe use a list of list to keep ordering.
43 *
44 * [
45 * [
46 * [
47 * action_name_1,
48 * action_name_2,
49 * action_name_3,
50 * ],
51 * optional_group_name
52 * ],
53 * ...
54 * ]
55 *
56 * For backward compatibility this also support the
57 * old methods of adding busson directly bound to callbacks:
58 * @example
59 * # deprecate, do not use
30 * IPython.toolbar.add_buttons_group([
60 * IPython.toolbar.add_buttons_group([
31 * {
61 * {
32 * label:'my button',
62 * label:'my button',
@@ -52,27 +82,62 b' define(['
52 * @param [list.id] {String} id to give to the button
82 * @param [list.id] {String} id to give to the button
53 * @param [group_id] {String} optionnal id to give to the group
83 * @param [group_id] {String} optionnal id to give to the group
54 *
84 *
85 *
86 * for private usage, the key can also be strings starting with '<' and ending with '>' to inject custom element that cannot
87 * be bound to an action.
88 *
55 */
89 */
90 // TODO JUPYTER:
91 // get rid of legacy code that handle things that are not actions.
56 ToolBar.prototype.add_buttons_group = function (list, group_id) {
92 ToolBar.prototype.add_buttons_group = function (list, group_id) {
93 // handle custom call of pseudoaction binding.
94 if(typeof(list) === 'string' && list.slice(0,1) === '<' && list.slice(-1) === '>'){
95 var _pseudo_action;
96 try{
97 _pseudo_action = list.slice(1,-1);
98 this.element.append(this._pseudo_actions[_pseudo_action].call(this));
99 } catch (e) {
100 console.warn('ouch, calling ', _pseudo_action, 'does not seem to work...:', e);
101 }
102 return ;
103 }
104 var that = this;
57 var btn_group = $('<div/>').addClass("btn-group");
105 var btn_group = $('<div/>').addClass("btn-group");
58 if( group_id !== undefined ) {
106 if( group_id !== undefined ) {
59 btn_group.attr('id',group_id);
107 btn_group.attr('id',group_id);
60 }
108 }
61 var el;
62 for(var i=0; i < list.length; i++) {
109 for(var i=0; i < list.length; i++) {
63 el = list[i];
110
64 var button = $('<button/>')
111 // IIFE because javascript don't have loop scope so
65 .addClass('btn btn-default')
112 // action_name would otherwise be the same on all iteration
66 .attr("title", el.label)
113 // of the loop
67 .append(
114 (function(i,list){
68 $("<i/>").addClass(el.icon).addClass('fa')
115 var el = list[i];
69 );
116 var action_name;
70 var id = el.id;
117 var action;
71 if( id !== undefined )
118 if(typeof(el) === 'string'){
72 button.attr('id',id);
119 action = that.actions.get(el);
73 var fun = el.callback;
120 action_name = el;
74 button.click(fun);
121
75 btn_group.append(button);
122 }
123 var button = $('<button/>')
124 .addClass('btn btn-default')
125 .attr("title", el.label||action.help)
126 .append(
127 $("<i/>").addClass(el.icon||action.icon).addClass('fa')
128 );
129 var id = el.id;
130 if( id !== undefined ){
131 button.attr('id',id);
132 }
133 button.attr('data-jupyter-action', action_name);
134 var fun = el.callback|| function(){
135 that.actions.call(action_name);
136 };
137 button.click(fun);
138 btn_group.append(button);
139 })(i,list);
140 // END IIFE
76 }
141 }
77 $(this.selector).append(btn_group);
142 $(this.selector).append(btn_group);
78 };
143 };
@@ -66,7 +66,7 b' casper.notebook_test(function () {'
66 IPython.notebook.select(0);
66 IPython.notebook.select(0);
67 cell.clear_output();
67 cell.clear_output();
68 cell.set_text('a=13; print(a)');
68 cell.set_text('a=13; print(a)');
69 $('#run_b').click();
69 $("button[data-jupyter-action='ipython.run-select-next']")[0].click()
70 });
70 });
71
71
72 this.wait_for_output(0);
72 this.wait_for_output(0);
@@ -29,7 +29,7 b' casper.notebook_test(function () {'
29 $('#cell_type').val('markdown').change();
29 $('#cell_type').val('markdown').change();
30 var cell = IPython.notebook.get_selected_cell();
30 var cell = IPython.notebook.get_selected_cell();
31 cell.set_text('*Baz*');
31 cell.set_text('*Baz*');
32 $('#run_b').click();
32 $("button[data-jupyter-action='ipython.run-select-next']")[0].click();
33 return cell.get_rendered();
33 return cell.get_rendered();
34 });
34 });
35 this.test.assertEquals(output.trim(), '<p><em>Baz</em></p>', 'Markdown toolbar items work.');
35 this.test.assertEquals(output.trim(), '<p><em>Baz</em></p>', 'Markdown toolbar items work.');
General Comments 0
You need to be logged in to leave comments. Login now