##// END OF EJS Templates
Adding new HeadingCell.
Brian Granger -
Show More
@@ -1,298 +1,336
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 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 // TextCell
9 // TextCell
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 // TextCell base class
14 // TextCell base class
15
15
16 var TextCell = function (notebook) {
16 var TextCell = function (notebook) {
17 this.code_mirror_mode = this.code_mirror_mode || 'htmlmixed';
17 this.code_mirror_mode = this.code_mirror_mode || 'htmlmixed';
18 IPython.Cell.apply(this, arguments);
18 IPython.Cell.apply(this, arguments);
19 this.rendered = false;
19 this.rendered = false;
20 this.cell_type = this.cell_type || 'text';
20 this.cell_type = this.cell_type || 'text';
21 };
21 };
22
22
23
23
24 TextCell.prototype = new IPython.Cell();
24 TextCell.prototype = new IPython.Cell();
25
25
26
26
27 TextCell.prototype.create_element = function () {
27 TextCell.prototype.create_element = function () {
28 var cell = $("<div>").addClass('cell text_cell border-box-sizing');
28 var cell = $("<div>").addClass('cell text_cell border-box-sizing');
29 cell.attr('tabindex','2');
29 cell.attr('tabindex','2');
30 var input_area = $('<div/>').addClass('text_cell_input border-box-sizing');
30 var input_area = $('<div/>').addClass('text_cell_input border-box-sizing');
31 this.code_mirror = CodeMirror(input_area.get(0), {
31 this.code_mirror = CodeMirror(input_area.get(0), {
32 indentUnit : 4,
32 indentUnit : 4,
33 mode: this.code_mirror_mode,
33 mode: this.code_mirror_mode,
34 theme: 'default',
34 theme: 'default',
35 value: this.placeholder,
35 value: this.placeholder,
36 readOnly: this.read_only,
36 readOnly: this.read_only,
37 lineWrapping : true,
37 lineWrapping : true,
38 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
38 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
39 });
39 });
40 // The tabindex=-1 makes this div focusable.
40 // The tabindex=-1 makes this div focusable.
41 var render_area = $('<div/>').addClass('text_cell_render border-box-sizing').
41 var render_area = $('<div/>').addClass('text_cell_render border-box-sizing').
42 addClass('rendered_html').attr('tabindex','-1');
42 addClass('rendered_html').attr('tabindex','-1');
43 cell.append(input_area).append(render_area);
43 cell.append(input_area).append(render_area);
44 this.element = cell;
44 this.element = cell;
45 };
45 };
46
46
47
47
48 TextCell.prototype.bind_events = function () {
48 TextCell.prototype.bind_events = function () {
49 IPython.Cell.prototype.bind_events.apply(this);
49 IPython.Cell.prototype.bind_events.apply(this);
50 var that = this;
50 var that = this;
51 this.element.keydown(function (event) {
51 this.element.keydown(function (event) {
52 if (event.which === 13) {
52 if (event.which === 13) {
53 if (that.rendered) {
53 if (that.rendered) {
54 that.edit();
54 that.edit();
55 return false;
55 return false;
56 };
56 };
57 };
57 };
58 });
58 });
59 this.element.dblclick(function () {
59 this.element.dblclick(function () {
60 that.edit();
60 that.edit();
61 });
61 });
62 };
62 };
63
63
64
64
65 TextCell.prototype.handle_codemirror_keyevent = function (editor, event) {
65 TextCell.prototype.handle_codemirror_keyevent = function (editor, event) {
66 // This method gets called in CodeMirror's onKeyDown/onKeyPress
66 // This method gets called in CodeMirror's onKeyDown/onKeyPress
67 // handlers and is used to provide custom key handling. Its return
67 // handlers and is used to provide custom key handling. Its return
68 // value is used to determine if CodeMirror should ignore the event:
68 // value is used to determine if CodeMirror should ignore the event:
69 // true = ignore, false = don't ignore.
69 // true = ignore, false = don't ignore.
70
70
71 if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
71 if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
72 // Always ignore shift-enter in CodeMirror as we handle it.
72 // Always ignore shift-enter in CodeMirror as we handle it.
73 return true;
73 return true;
74 }
74 }
75 return false;
75 return false;
76 };
76 };
77
77
78
78
79 TextCell.prototype.select = function () {
79 TextCell.prototype.select = function () {
80 IPython.Cell.prototype.select.apply(this);
80 IPython.Cell.prototype.select.apply(this);
81 var output = this.element.find("div.text_cell_render");
81 var output = this.element.find("div.text_cell_render");
82 output.trigger('focus');
82 output.trigger('focus');
83 };
83 };
84
84
85
85
86 TextCell.prototype.unselect = function() {
86 TextCell.prototype.unselect = function() {
87 // render on selection of another cell
87 // render on selection of another cell
88 this.render();
88 this.render();
89 IPython.Cell.prototype.unselect.apply(this);
89 IPython.Cell.prototype.unselect.apply(this);
90 };
90 };
91
91
92
92
93 TextCell.prototype.edit = function () {
93 TextCell.prototype.edit = function () {
94 if ( this.read_only ) return;
94 if ( this.read_only ) return;
95 if (this.rendered === true) {
95 if (this.rendered === true) {
96 var text_cell = this.element;
96 var text_cell = this.element;
97 var output = text_cell.find("div.text_cell_render");
97 var output = text_cell.find("div.text_cell_render");
98 output.hide();
98 output.hide();
99 text_cell.find('div.text_cell_input').show();
99 text_cell.find('div.text_cell_input').show();
100 this.code_mirror.refresh();
100 this.code_mirror.refresh();
101 this.code_mirror.focus();
101 this.code_mirror.focus();
102 // We used to need an additional refresh() after the focus, but
102 // We used to need an additional refresh() after the focus, but
103 // it appears that this has been fixed in CM. This bug would show
103 // it appears that this has been fixed in CM. This bug would show
104 // up on FF when a newly loaded markdown cell was edited.
104 // up on FF when a newly loaded markdown cell was edited.
105 this.rendered = false;
105 this.rendered = false;
106 if (this.get_text() === this.placeholder) {
106 if (this.get_text() === this.placeholder) {
107 this.set_text('');
107 this.set_text('');
108 this.refresh();
108 this.refresh();
109 }
109 }
110 }
110 }
111 };
111 };
112
112
113
113
114 // Subclasses must define render.
114 // Subclasses must define render.
115 TextCell.prototype.render = function () {};
115 TextCell.prototype.render = function () {};
116
116
117
117
118 TextCell.prototype.get_text = function() {
118 TextCell.prototype.get_text = function() {
119 return this.code_mirror.getValue();
119 return this.code_mirror.getValue();
120 };
120 };
121
121
122
122
123 TextCell.prototype.set_text = function(text) {
123 TextCell.prototype.set_text = function(text) {
124 this.code_mirror.setValue(text);
124 this.code_mirror.setValue(text);
125 this.code_mirror.refresh();
125 this.code_mirror.refresh();
126 };
126 };
127
127
128
128
129 TextCell.prototype.get_rendered = function() {
129 TextCell.prototype.get_rendered = function() {
130 return this.element.find('div.text_cell_render').html();
130 return this.element.find('div.text_cell_render').html();
131 };
131 };
132
132
133
133
134 TextCell.prototype.set_rendered = function(text) {
134 TextCell.prototype.set_rendered = function(text) {
135 this.element.find('div.text_cell_render').html(text);
135 this.element.find('div.text_cell_render').html(text);
136 };
136 };
137
137
138
138
139 TextCell.prototype.at_top = function () {
139 TextCell.prototype.at_top = function () {
140 if (this.rendered) {
140 if (this.rendered) {
141 return true;
141 return true;
142 } else {
142 } else {
143 return false;
143 return false;
144 }
144 }
145 };
145 };
146
146
147
147
148 TextCell.prototype.at_bottom = function () {
148 TextCell.prototype.at_bottom = function () {
149 if (this.rendered) {
149 if (this.rendered) {
150 return true;
150 return true;
151 } else {
151 } else {
152 return false;
152 return false;
153 }
153 }
154 };
154 };
155
155
156
156
157 TextCell.prototype.fromJSON = function (data) {
157 TextCell.prototype.fromJSON = function (data) {
158 if (data.cell_type === this.cell_type) {
158 if (data.cell_type === this.cell_type) {
159 if (data.source !== undefined) {
159 if (data.source !== undefined) {
160 this.set_text(data.source);
160 this.set_text(data.source);
161 this.set_rendered(data.rendered || '');
161 this.set_rendered(data.rendered || '');
162 this.rendered = false;
162 this.rendered = false;
163 this.render();
163 this.render();
164 }
164 }
165 }
165 }
166 };
166 };
167
167
168
168
169 TextCell.prototype.toJSON = function () {
169 TextCell.prototype.toJSON = function () {
170 var data = {};
170 var data = {};
171 data.cell_type = this.cell_type;
171 data.cell_type = this.cell_type;
172 data.source = this.get_text();
172 data.source = this.get_text();
173 return data;
173 return data;
174 };
174 };
175
175
176
176
177 // HTMLCell
177 // HTMLCell
178
178
179 var HTMLCell = function (notebook) {
179 var HTMLCell = function (notebook) {
180 this.placeholder = "Type <strong>HTML</strong> and LaTeX: $\\alpha^2$";
180 this.placeholder = "Type <strong>HTML</strong> and LaTeX: $\\alpha^2$";
181 IPython.TextCell.apply(this, arguments);
181 IPython.TextCell.apply(this, arguments);
182 this.cell_type = 'html';
182 this.cell_type = 'html';
183 };
183 };
184
184
185
185
186 HTMLCell.prototype = new TextCell();
186 HTMLCell.prototype = new TextCell();
187
187
188
188
189 HTMLCell.prototype.render = function () {
189 HTMLCell.prototype.render = function () {
190 if (this.rendered === false) {
190 if (this.rendered === false) {
191 var text = this.get_text();
191 var text = this.get_text();
192 if (text === "") { text = this.placeholder; }
192 if (text === "") { text = this.placeholder; }
193 this.set_rendered(text);
193 this.set_rendered(text);
194 this.typeset();
194 this.typeset();
195 this.element.find('div.text_cell_input').hide();
195 this.element.find('div.text_cell_input').hide();
196 this.element.find("div.text_cell_render").show();
196 this.element.find("div.text_cell_render").show();
197 this.rendered = true;
197 this.rendered = true;
198 }
198 }
199 };
199 };
200
200
201
201
202 // MarkdownCell
202 // MarkdownCell
203
203
204 var MarkdownCell = function (notebook) {
204 var MarkdownCell = function (notebook) {
205 this.placeholder = "Type *Markdown* and LaTeX: $\\alpha^2$";
205 this.placeholder = "Type *Markdown* and LaTeX: $\\alpha^2$";
206 IPython.TextCell.apply(this, arguments);
206 IPython.TextCell.apply(this, arguments);
207 this.cell_type = 'markdown';
207 this.cell_type = 'markdown';
208 };
208 };
209
209
210
210
211 MarkdownCell.prototype = new TextCell();
211 MarkdownCell.prototype = new TextCell();
212
212
213
213
214 MarkdownCell.prototype.render = function () {
214 MarkdownCell.prototype.render = function () {
215 if (this.rendered === false) {
215 if (this.rendered === false) {
216 var text = this.get_text();
216 var text = this.get_text();
217 if (text === "") { text = this.placeholder; }
217 if (text === "") { text = this.placeholder; }
218 var html = IPython.markdown_converter.makeHtml(text);
218 var html = IPython.markdown_converter.makeHtml(text);
219 this.set_rendered(html);
219 this.set_rendered(html);
220 this.typeset()
220 this.typeset()
221 this.element.find('div.text_cell_input').hide();
221 this.element.find('div.text_cell_input').hide();
222 this.element.find("div.text_cell_render").show();
222 this.element.find("div.text_cell_render").show();
223 var code_snippets = this.element.find("pre > code");
223 var code_snippets = this.element.find("pre > code");
224 code_snippets.replaceWith(function () {
224 code_snippets.replaceWith(function () {
225 var code = $(this).html();
225 var code = $(this).html();
226 /* Substitute br for newlines and &nbsp; for spaces
226 /* Substitute br for newlines and &nbsp; for spaces
227 before highlighting, since prettify doesn't
227 before highlighting, since prettify doesn't
228 preserve those on all browsers */
228 preserve those on all browsers */
229 code = code.replace(/(\r\n|\n|\r)/gm, "<br/>");
229 code = code.replace(/(\r\n|\n|\r)/gm, "<br/>");
230 code = code.replace(/ /gm, '&nbsp;');
230 code = code.replace(/ /gm, '&nbsp;');
231 code = prettyPrintOne(code);
231 code = prettyPrintOne(code);
232
232
233 return '<code class="prettyprint">' + code + '</code>';
233 return '<code class="prettyprint">' + code + '</code>';
234 });
234 });
235 this.rendered = true;
235 this.rendered = true;
236 }
236 }
237 };
237 };
238
238
239
239
240 // RSTCell
240 // RSTCell
241
241
242 var RSTCell = function (notebook) {
242 var RSTCell = function (notebook) {
243 this.placeholder = "Type *ReStructured Text* and LaTeX: $\\alpha^2$";
243 this.placeholder = "Type *ReStructured Text* and LaTeX: $\\alpha^2$";
244 this.code_mirror_mode = 'rst';
244 this.code_mirror_mode = 'rst';
245 IPython.TextCell.apply(this, arguments);
245 IPython.TextCell.apply(this, arguments);
246 this.cell_type = 'rst';
246 this.cell_type = 'rst';
247 };
247 };
248
248
249
249
250 RSTCell.prototype = new TextCell();
250 RSTCell.prototype = new TextCell();
251
251
252
252
253 RSTCell.prototype.render = function () {
253 RSTCell.prototype.render = function () {
254 this.rendered = true;
254 this.rendered = true;
255 this.edit();
255 this.edit();
256 };
256 };
257
257
258
258
259 RSTCell.prototype.select = function () {
259 RSTCell.prototype.select = function () {
260 IPython.Cell.prototype.select.apply(this);
260 IPython.Cell.prototype.select.apply(this);
261 // In some cases (inserting a new cell) we need a refresh before and
261 // In some cases (inserting a new cell) we need a refresh before and
262 // after the focus. Not sure why this is the case.
262 // after the focus. Not sure why this is the case.
263 this.code_mirror.refresh();
263 this.code_mirror.refresh();
264 this.code_mirror.focus();
264 this.code_mirror.focus();
265 this.code_mirror.refresh();
265 this.code_mirror.refresh();
266 };
266 };
267
267
268
268
269 RSTCell.prototype.at_top = function () {
269 RSTCell.prototype.at_top = function () {
270 var cursor = this.code_mirror.getCursor();
270 var cursor = this.code_mirror.getCursor();
271 if (cursor.line === 0) {
271 if (cursor.line === 0) {
272 return true;
272 return true;
273 } else {
273 } else {
274 return false;
274 return false;
275 }
275 }
276 };
276 };
277
277
278
278
279 RSTCell.prototype.at_bottom = function () {
279 RSTCell.prototype.at_bottom = function () {
280 var cursor = this.code_mirror.getCursor();
280 var cursor = this.code_mirror.getCursor();
281 if (cursor.line === (this.code_mirror.lineCount()-1)) {
281 if (cursor.line === (this.code_mirror.lineCount()-1)) {
282 return true;
282 return true;
283 } else {
283 } else {
284 return false;
284 return false;
285 }
285 }
286 };
286 };
287
287
288
288
289 // HTMLCell
290
291 var HeadingCell = function (notebook) {
292 this.placeholder = "Type Heading Here";
293 IPython.TextCell.apply(this, arguments);
294 this.cell_type = 'heading';
295 this.level = 1;
296 };
297
298
299 HeadingCell.prototype = new TextCell();
300
301
302 HeadingCell.prototype.set_rendered = function (text) {
303 var r = this.element.find("div.text_cell_render");
304 r.empty();
305 r.append($('<h1/>').html(text));
306 }
307
308
309 HeadingCell.prototype.get_rendered = function () {
310 var r = this.element.find("div.text_cell_render");
311 return r.children().first().html();
312 }
313
314
315 HeadingCell.prototype.render = function () {
316 if (this.rendered === false) {
317 var text = this.get_text();
318 if (text === "") { text = this.placeholder; }
319 this.set_rendered(text);
320 this.typeset();
321 this.element.find('div.text_cell_input').hide();
322 this.element.find("div.text_cell_render").show();
323 this.rendered = true;
324 }
325 };
326
289 IPython.TextCell = TextCell;
327 IPython.TextCell = TextCell;
290 IPython.HTMLCell = HTMLCell;
328 IPython.HTMLCell = HTMLCell;
291 IPython.MarkdownCell = MarkdownCell;
329 IPython.MarkdownCell = MarkdownCell;
292 IPython.RSTCell = RSTCell;
330 IPython.RSTCell = RSTCell;
293
331
294
332
295 return IPython;
333 return IPython;
296
334
297 }(IPython));
335 }(IPython));
298
336
General Comments 0
You need to be logged in to leave comments. Login now