##// END OF EJS Templates
Review #2
Jonathan Frederic -
Show More
@@ -1,161 +1,161
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2013 The IPython Development Team
2 // Copyright (C) 2013 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 // Utility for modal dialogs with bootstrap
9 // Utility for modal dialogs with bootstrap
10 //============================================================================
10 //============================================================================
11
11
12 IPython.namespace('IPython.dialog');
12 IPython.namespace('IPython.dialog');
13
13
14 IPython.dialog = (function (IPython) {
14 IPython.dialog = (function (IPython) {
15 "use strict";
15 "use strict";
16
16
17 var modal = function (options) {
17 var modal = function (options) {
18 var modal = $("<div/>")
18 var modal = $("<div/>")
19 .addClass("modal")
19 .addClass("modal")
20 .addClass("fade")
20 .addClass("fade")
21 .attr("role", "dialog");
21 .attr("role", "dialog");
22 var dialog = $("<div/>")
22 var dialog = $("<div/>")
23 .addClass("modal-dialog")
23 .addClass("modal-dialog")
24 .appendTo(modal);
24 .appendTo(modal);
25 var dialog_content = $("<div/>")
25 var dialog_content = $("<div/>")
26 .addClass("modal-content")
26 .addClass("modal-content")
27 .appendTo(dialog);
27 .appendTo(dialog);
28 dialog_content.append(
28 dialog_content.append(
29 $("<div/>")
29 $("<div/>")
30 .addClass("modal-header")
30 .addClass("modal-header")
31 .append($("<button>")
31 .append($("<button>")
32 .attr("type", "button")
32 .attr("type", "button")
33 .addClass("close")
33 .addClass("close")
34 .attr("data-dismiss", "modal")
34 .attr("data-dismiss", "modal")
35 .attr("aria-hidden", "true")
35 .attr("aria-hidden", "true")
36 .html("&times;")
36 .html("&times;")
37 ).append(
37 ).append(
38 $("<h4/>")
38 $("<h4/>")
39 .addClass('modal-title')
39 .addClass('modal-title')
40 .text(options.title || "")
40 .text(options.title || "")
41 )
41 )
42 ).append(
42 ).append(
43 $("<div/>").addClass("modal-body").append(
43 $("<div/>").addClass("modal-body").append(
44 options.body || $("<p/>")
44 options.body || $("<p/>")
45 )
45 )
46 );
46 );
47
47
48 var footer = $("<div/>").addClass("modal-footer");
48 var footer = $("<div/>").addClass("modal-footer");
49
49
50 for (var label in options.buttons) {
50 for (var label in options.buttons) {
51 var btn_opts = options.buttons[label];
51 var btn_opts = options.buttons[label];
52 var button = $("<button/>")
52 var button = $("<button/>")
53 .addClass("btn btn-default")
53 .addClass("btn btn-default btn-sm")
54 .attr("data-dismiss", "modal")
54 .attr("data-dismiss", "modal")
55 .text(label);
55 .text(label);
56 if (btn_opts.click) {
56 if (btn_opts.click) {
57 button.click($.proxy(btn_opts.click, dialog_content));
57 button.click($.proxy(btn_opts.click, dialog_content));
58 }
58 }
59 if (btn_opts.class) {
59 if (btn_opts.class) {
60 button.addClass(btn_opts.class);
60 button.addClass(btn_opts.class);
61 }
61 }
62 footer.append(button);
62 footer.append(button);
63 }
63 }
64 dialog_content.append(footer);
64 dialog_content.append(footer);
65 // hook up on-open event
65 // hook up on-open event
66 modal.on("shown.bs.modal", function() {
66 modal.on("shown.bs.modal", function() {
67 setTimeout(function() {
67 setTimeout(function() {
68 footer.find("button").last().focus();
68 footer.find("button").last().focus();
69 if (options.open) {
69 if (options.open) {
70 $.proxy(options.open, modal)();
70 $.proxy(options.open, modal)();
71 }
71 }
72 }, 0);
72 }, 0);
73 });
73 });
74
74
75 // destroy modal on hide, unless explicitly asked not to
75 // destroy modal on hide, unless explicitly asked not to
76 if (options.destroy === undefined || options.destroy) {
76 if (options.destroy === undefined || options.destroy) {
77 modal.on("hidden.bs.modal", function () {
77 modal.on("hidden.bs.modal", function () {
78 modal.remove();
78 modal.remove();
79 });
79 });
80 }
80 }
81 modal.on("hidden.bs.modal", function () {
81 modal.on("hidden.bs.modal", function () {
82 if (IPython.notebook) {
82 if (IPython.notebook) {
83 var cell = IPython.notebook.get_selected_cell();
83 var cell = IPython.notebook.get_selected_cell();
84 if (cell) cell.select();
84 if (cell) cell.select();
85 IPython.keyboard_manager.enable();
85 IPython.keyboard_manager.enable();
86 IPython.keyboard_manager.command_mode();
86 IPython.keyboard_manager.command_mode();
87 }
87 }
88 });
88 });
89
89
90 if (IPython.keyboard_manager) {
90 if (IPython.keyboard_manager) {
91 IPython.keyboard_manager.disable();
91 IPython.keyboard_manager.disable();
92 }
92 }
93
93
94 return modal.modal(options);
94 return modal.modal(options);
95 };
95 };
96
96
97 var edit_metadata = function (md, callback, name) {
97 var edit_metadata = function (md, callback, name) {
98 name = name || "Cell";
98 name = name || "Cell";
99 var error_div = $('<div/>').css('color', 'red');
99 var error_div = $('<div/>').css('color', 'red');
100 var message =
100 var message =
101 "Manually edit the JSON below to manipulate the metadata for this " + name + "." +
101 "Manually edit the JSON below to manipulate the metadata for this " + name + "." +
102 " We recommend putting custom metadata attributes in an appropriately named sub-structure," +
102 " We recommend putting custom metadata attributes in an appropriately named sub-structure," +
103 " so they don't conflict with those of others.";
103 " so they don't conflict with those of others.";
104
104
105 var textarea = $('<textarea/>')
105 var textarea = $('<textarea/>')
106 .attr('rows', '13')
106 .attr('rows', '13')
107 .attr('cols', '80')
107 .attr('cols', '80')
108 .attr('name', 'metadata')
108 .attr('name', 'metadata')
109 .text(JSON.stringify(md || {}, null, 2));
109 .text(JSON.stringify(md || {}, null, 2));
110
110
111 var dialogform = $('<div/>').attr('title', 'Edit the metadata')
111 var dialogform = $('<div/>').attr('title', 'Edit the metadata')
112 .append(
112 .append(
113 $('<form/>').append(
113 $('<form/>').append(
114 $('<fieldset/>').append(
114 $('<fieldset/>').append(
115 $('<label/>')
115 $('<label/>')
116 .attr('for','metadata')
116 .attr('for','metadata')
117 .text(message)
117 .text(message)
118 )
118 )
119 .append(error_div)
119 .append(error_div)
120 .append($('<br/>'))
120 .append($('<br/>'))
121 .append(textarea)
121 .append(textarea)
122 )
122 )
123 );
123 );
124 var editor = CodeMirror.fromTextArea(textarea[0], {
124 var editor = CodeMirror.fromTextArea(textarea[0], {
125 lineNumbers: true,
125 lineNumbers: true,
126 matchBrackets: true,
126 matchBrackets: true,
127 indentUnit: 2,
127 indentUnit: 2,
128 autoIndent: true,
128 autoIndent: true,
129 mode: 'application/json',
129 mode: 'application/json',
130 });
130 });
131 var modal = IPython.dialog.modal({
131 var modal = IPython.dialog.modal({
132 title: "Edit " + name + " Metadata",
132 title: "Edit " + name + " Metadata",
133 body: dialogform,
133 body: dialogform,
134 buttons: {
134 buttons: {
135 OK: { class : "btn-primary",
135 OK: { class : "btn-primary",
136 click: function() {
136 click: function() {
137 // validate json and set it
137 // validate json and set it
138 var new_md;
138 var new_md;
139 try {
139 try {
140 new_md = JSON.parse(editor.getValue());
140 new_md = JSON.parse(editor.getValue());
141 } catch(e) {
141 } catch(e) {
142 console.log(e);
142 console.log(e);
143 error_div.text('WARNING: Could not save invalid JSON.');
143 error_div.text('WARNING: Could not save invalid JSON.');
144 return false;
144 return false;
145 }
145 }
146 callback(new_md);
146 callback(new_md);
147 }
147 }
148 },
148 },
149 Cancel: {}
149 Cancel: {}
150 }
150 }
151 });
151 });
152
152
153 modal.on('shown.bs.modal', function(){ editor.refresh(); });
153 modal.on('shown.bs.modal', function(){ editor.refresh(); });
154 };
154 };
155
155
156 return {
156 return {
157 modal : modal,
157 modal : modal,
158 edit_metadata : edit_metadata,
158 edit_metadata : edit_metadata,
159 };
159 };
160
160
161 }(IPython));
161 }(IPython));
@@ -1,42 +1,38
1 // Our customizations to bootstrap go here.
1 // Our customizations to bootstrap go here.
2
2
3 @black: #000;
3 @black: #000;
4 @text-color: @black;
4 @text-color: @black;
5 @font-size-base: 13px;
5 @font-size-base: 13px;
6 @font-family-monospace: monospace; // to allow user to customize their fonts
6 @font-family-monospace: monospace; // to allow user to customize their fonts
7 @navbar-height: 36px;
7 @navbar-height: 36px;
8 @breadcrumb-color: darken(@border_color, 30%);
8 @breadcrumb-color: darken(@border_color, 30%);
9 @blockquote-font-size: inherit;
9 @blockquote-font-size: inherit;
10
10 @modal-inner-padding: 15px;
11 // Override the modal footer padding that BS3 uses.
12 .modal-footer {
13 padding: 7px;
14 }
15
11
16 // Disable modal slide-in from top animation.
12 // Disable modal slide-in from top animation.
17 .modal {
13 .modal {
18 &.fade .modal-dialog {
14 &.fade .modal-dialog {
19 .translate(0, 0);
15 .translate(0, 0);
20 }
16 }
21 }
17 }
22
18
23 // Set the default code color.
19 // Set the default code color.
24 code {
20 code {
25 color: @black; // default code color in bootstrap is #d14 (crimson / amaranth)
21 color: @black; // default code color in bootstrap is #d14 (crimson / amaranth)
26 }
22 }
27
23
28 // Override bootstrap pre element styling.
24 // Override bootstrap pre element styling.
29 pre {
25 pre {
30 // bootstrap has pre defaults that we don't want to inherit.
26 // bootstrap has pre defaults that we don't want to inherit.
31 // start pre tag defaults based on the surrounding context instead.
27 // start pre tag defaults based on the surrounding context instead.
32 font-size: inherit;
28 font-size: inherit;
33 line-height: inherit;
29 line-height: inherit;
34 }
30 }
35
31
36 // Disable bold labels in BS3
32 // Disable bold labels in BS3
37 label {
33 label {
38 font-weight: normal;
34 font-weight: normal;
39 }
35 }
40
36
41 // Our own global variables for all pages go here
37 // Our own global variables for all pages go here
42
38
@@ -1,48 +1,49
1 /* CSS for the cell toolbar */
1 /* CSS for the cell toolbar */
2 @celltoolbar-height: 29px;
2 @celltoolbar-height: 29px;
3
3
4 .celltoolbar {
4 .celltoolbar {
5 border: thin solid #CFCFCF;
5 border: thin solid #CFCFCF;
6 border-bottom: none;
6 border-bottom: none;
7 background : #EEE;
7 background : #EEE;
8 border-radius : 3px 3px 0px 0px;
8 border-radius : 3px 3px 0px 0px;
9 width:100%;
9 width:100%;
10 -webkit-box-pack: end;
10 -webkit-box-pack: end;
11 height: @celltoolbar-height;
11 height: @celltoolbar-height;
12 padding-right: 4px;
12 padding-right: 4px;
13 .hbox();
13 .hbox();
14 .reverse();
14 .reverse();
15 }
15 }
16
16
17 .ctb_hideshow {
17 .ctb_hideshow {
18 display:none;
18 display:none;
19 vertical-align:bottom;
19 vertical-align:bottom;
20 }
20 }
21
21
22 /* ctb_show is added to the ctb_hideshow div to show the cell toolbar.
22 /* ctb_show is added to the ctb_hideshow div to show the cell toolbar.
23 Cell toolbars are only shown when the ctb_global_show class is also set.
23 Cell toolbars are only shown when the ctb_global_show class is also set.
24 */
24 */
25 .ctb_global_show .ctb_show.ctb_hideshow {
25 .ctb_global_show .ctb_show.ctb_hideshow {
26 display: block;
26 display: block;
27 }
27 }
28
28
29 .ctb_global_show .ctb_show + .input_area,
29 .ctb_global_show .ctb_show + .input_area,
30 .ctb_global_show .ctb_show + div.text_cell_input
30 .ctb_global_show .ctb_show + div.text_cell_input
31 {
31 {
32 border-top-right-radius: 0px;
32 border-top-right-radius: 0px;
33 border-top-left-radius: 0px;
33 border-top-left-radius: 0px;
34 }
34 }
35
35
36 .celltoolbar {
36 .celltoolbar {
37 font-size: 87%;
37 font-size: 87%;
38 padding-top: 3px;
38 padding-top: 3px;
39 }
39 }
40
40
41 .celltoolbar select {
41 .celltoolbar select {
42 font-size: 87%;
42 font-size: 87%;
43 height: 22px;
43 }
44 }
44
45
45 .celltoolbar label {
46 .celltoolbar label {
46 margin-left: 5px;
47 margin-left: 5px;
47 margin-right: 5px;
48 margin-right: 5px;
48 }
49 }
General Comments 0
You need to be logged in to leave comments. Login now