##// END OF EJS Templates
Fix rebase.
Michael Droettboom -
Show More
@@ -1,408 +1,408
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // OutputArea
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13 "use strict";
14 14
15 15 var utils = IPython.utils;
16 16
17 17 var OutputArea = function (selector, prompt_area) {
18 18 this.selector = selector;
19 19 this.element = $(selector);
20 20 this.outputs = [];
21 21 this.collapsed = false;
22 22 this.clear_out_timeout = null;
23 23 if (prompt_area === undefined) {
24 24 this.prompt_area = true;
25 25 } else {
26 26 this.prompt_area = prompt_area;
27 27 };
28 28 this.style();
29 29 };
30 30
31 31
32 32 OutputArea.prototype.style = function () {
33 33 this.element.addClass('output vbox');
34 34 this.collapse();
35 35 };
36 36
37 37
38 38 OutputArea.prototype.collapse = function () {
39 39 if (!this.collapsed) {
40 40 this.element.hide();
41 41 this.collapsed = true;
42 42 };
43 43 };
44 44
45 45
46 46 OutputArea.prototype.expand = function () {
47 47 if (this.collapsed) {
48 48 this.element.show();
49 49 this.collapsed = false;
50 50 };
51 51 };
52 52
53 53
54 54 OutputArea.prototype.toggle_output = function () {
55 55 if (this.collapsed) {
56 56 this.expand();
57 57 } else {
58 58 this.collapse();
59 59 };
60 60 };
61 61
62 62
63 63 // typeset with MathJax if MathJax is available
64 64 OutputArea.prototype.typeset = function () {
65 65 if (window.MathJax){
66 66 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
67 67 }
68 68 };
69 69
70 70
71 71 OutputArea.prototype.handle_output = function (msg_type, content) {
72 72 var json = {};
73 73 json.output_type = msg_type;
74 74 if (msg_type === "stream") {
75 75 json.text = content.data;
76 76 json.stream = content.name;
77 77 } else if (msg_type === "display_data") {
78 78 json = this.convert_mime_types(json, content.data);
79 79 } else if (msg_type === "pyout") {
80 80 json.prompt_number = content.execution_count;
81 81 json = this.convert_mime_types(json, content.data);
82 82 } else if (msg_type === "pyerr") {
83 83 json.ename = content.ename;
84 84 json.evalue = content.evalue;
85 85 json.traceback = content.traceback;
86 86 };
87 87 // append with dynamic=true
88 88 this.append_output(json, true);
89 89 };
90 90
91 91
92 92 OutputArea.prototype.convert_mime_types = function (json, data) {
93 93 if (data['text/plain'] !== undefined) {
94 94 json.text = data['text/plain'];
95 95 };
96 96 if (data['text/html'] !== undefined) {
97 97 json.html = data['text/html'];
98 98 };
99 99 if (data['image/svg+xml'] !== undefined) {
100 100 json.svg = data['image/svg+xml'];
101 101 };
102 102 if (data['image/png'] !== undefined) {
103 103 json.png = data['image/png'];
104 104 };
105 105 if (data['image/jpeg'] !== undefined) {
106 106 json.jpeg = data['image/jpeg'];
107 107 };
108 108 if (data['text/latex'] !== undefined) {
109 109 json.latex = data['text/latex'];
110 110 };
111 111 if (data['application/json'] !== undefined) {
112 112 json.json = data['application/json'];
113 113 };
114 114 if (data['application/javascript'] !== undefined) {
115 115 json.javascript = data['application/javascript'];
116 116 }
117 117 return json;
118 118 };
119 119
120 120
121 121 OutputArea.prototype.append_output = function (json, dynamic) {
122 122 // If dynamic is true, javascript output will be eval'd.
123 123 this.expand();
124 124 this.flush_clear_timeout();
125 125 if (json.output_type === 'pyout') {
126 126 this.append_pyout(json, dynamic);
127 127 } else if (json.output_type === 'pyerr') {
128 128 this.append_pyerr(json);
129 129 } else if (json.output_type === 'display_data') {
130 130 this.append_display_data(json, dynamic);
131 131 } else if (json.output_type === 'stream') {
132 132 this.append_stream(json);
133 133 };
134 134 this.outputs.push(json);
135 135 };
136 136
137 137
138 138 OutputArea.prototype.create_output_area = function () {
139 139 var oa = $("<div/>").addClass("hbox output_area");
140 140 if (this.prompt_area) {
141 141 oa.append($('<div/>').addClass('prompt'));
142 142 }
143 143 return oa;
144 144 };
145 145
146 146
147 147 OutputArea.prototype.append_pyout = function (json, dynamic) {
148 148 var n = json.prompt_number || ' ';
149 149 var toinsert = this.create_output_area();
150 150 if (this.prompt_area) {
151 151 toinsert.find('div.prompt').addClass('output_prompt').html('Out[' + n + ']:');
152 152 }
153 153 this.append_mime_type(json, toinsert, dynamic);
154 154 this.element.append(toinsert);
155 155 // If we just output latex, typeset it.
156 156 if ((json.latex !== undefined) || (json.html !== undefined)) {
157 157 this.typeset();
158 158 };
159 159 };
160 160
161 161
162 162 OutputArea.prototype.append_pyerr = function (json) {
163 163 var tb = json.traceback;
164 164 if (tb !== undefined && tb.length > 0) {
165 165 var s = '';
166 166 var len = tb.length;
167 167 for (var i=0; i<len; i++) {
168 168 s = s + tb[i] + '\n';
169 169 }
170 170 s = s + '\n';
171 171 var toinsert = this.create_output_area();
172 172 this.append_text(s, toinsert);
173 173 this.element.append(toinsert);
174 174 };
175 175 };
176 176
177 177
178 178 OutputArea.prototype.append_stream = function (json) {
179 179 // temporary fix: if stream undefined (json file written prior to this patch),
180 180 // default to most likely stdout:
181 181 if (json.stream == undefined){
182 182 json.stream = 'stdout';
183 183 }
184 var text = utils.fixConsole(json.text);
184 var text = json.text;
185 185 var subclass = "output_"+json.stream;
186 186 if (this.outputs.length > 0){
187 187 // have at least one output to consider
188 188 var last = this.outputs[this.outputs.length-1];
189 189 if (last.output_type == 'stream' && json.stream == last.stream){
190 190 // latest output was in the same stream,
191 191 // so append directly into its pre tag
192 192 // escape ANSI & HTML specials:
193 pre = this.element.find('div.'+subclass).last().find('pre');
194 html = utils.fixCarriageReturn(
193 var pre = this.element.find('div.'+subclass).last().find('pre');
194 var html = utils.fixCarriageReturn(
195 195 pre.html() + utils.fixConsole(text));
196 196 pre.html(html);
197 197 return;
198 198 }
199 199 }
200 200
201 201 if (!text.replace("\r", "")) {
202 202 // text is nothing (empty string, \r, etc.)
203 203 // so don't append any elements, which might add undesirable space
204 204 return;
205 205 }
206 206
207 207 // If we got here, attach a new div
208 208 var toinsert = this.create_output_area();
209 209 this.append_text(text, toinsert, "output_stream "+subclass);
210 210 this.element.append(toinsert);
211 211 };
212 212
213 213
214 214 OutputArea.prototype.append_display_data = function (json, dynamic) {
215 215 var toinsert = this.create_output_area();
216 216 this.append_mime_type(json, toinsert, dynamic);
217 217 this.element.append(toinsert);
218 218 // If we just output latex, typeset it.
219 219 if ( (json.latex !== undefined) || (json.html !== undefined) ) {
220 220 this.typeset();
221 221 };
222 222 };
223 223
224 224
225 225 OutputArea.prototype.append_mime_type = function (json, element, dynamic) {
226 226 if (json.javascript !== undefined && dynamic) {
227 227 this.append_javascript(json.javascript, element, dynamic);
228 228 } else if (json.html !== undefined) {
229 229 this.append_html(json.html, element);
230 230 } else if (json.latex !== undefined) {
231 231 this.append_latex(json.latex, element);
232 232 } else if (json.svg !== undefined) {
233 233 this.append_svg(json.svg, element);
234 234 } else if (json.png !== undefined) {
235 235 this.append_png(json.png, element);
236 236 } else if (json.jpeg !== undefined) {
237 237 this.append_jpeg(json.jpeg, element);
238 238 } else if (json.text !== undefined) {
239 239 this.append_text(json.text, element);
240 240 };
241 241 };
242 242
243 243
244 244 OutputArea.prototype.append_html = function (html, element) {
245 245 var toinsert = $("<div/>").addClass("box-flex1 output_subarea output_html rendered_html");
246 246 toinsert.append(html);
247 247 element.append(toinsert);
248 248 };
249 249
250 250
251 251 OutputArea.prototype.append_javascript = function (js, container) {
252 252 // We just eval the JS code, element appears in the local scope.
253 253 var element = $("<div/>").addClass("box-flex1 output_subarea");
254 254 container.append(element);
255 255 // Div for js shouldn't be drawn, as it will add empty height to the area.
256 256 container.hide();
257 257 // If the Javascript appends content to `element` that should be drawn, then
258 258 // it must also call `container.show()`.
259 259 eval(js);
260 260 }
261 261
262 262
263 263 OutputArea.prototype.append_text = function (data, element, extra_class) {
264 264 var toinsert = $("<div/>").addClass("box-flex1 output_subarea output_text");
265 265 // escape ANSI & HTML specials in plaintext:
266 266 data = utils.fixConsole(data);
267 267 data = utils.fixCarriageReturn(data);
268 268 if (extra_class){
269 269 toinsert.addClass(extra_class);
270 270 }
271 271 toinsert.append($("<pre/>").html(data));
272 272 element.append(toinsert);
273 273 };
274 274
275 275
276 276 OutputArea.prototype.append_svg = function (svg, element) {
277 277 var toinsert = $("<div/>").addClass("box-flex1 output_subarea output_svg");
278 278 toinsert.append(svg);
279 279 element.append(toinsert);
280 280 };
281 281
282 282
283 283 OutputArea.prototype.append_png = function (png, element) {
284 284 var toinsert = $("<div/>").addClass("box-flex1 output_subarea output_png");
285 285 toinsert.append($("<img/>").attr('src','data:image/png;base64,'+png));
286 286 element.append(toinsert);
287 287 };
288 288
289 289
290 290 OutputArea.prototype.append_jpeg = function (jpeg, element) {
291 291 var toinsert = $("<div/>").addClass("box-flex1 output_subarea output_jpeg");
292 292 toinsert.append($("<img/>").attr('src','data:image/jpeg;base64,'+jpeg));
293 293 element.append(toinsert);
294 294 };
295 295
296 296
297 297 OutputArea.prototype.append_latex = function (latex, element) {
298 298 // This method cannot do the typesetting because the latex first has to
299 299 // be on the page.
300 300 var toinsert = $("<div/>").addClass("box-flex1 output_subarea output_latex");
301 301 toinsert.append(latex);
302 302 element.append(toinsert);
303 303 };
304 304
305 305
306 306 OutputArea.prototype.handle_clear_output = function (content) {
307 307 this.clear_output(content.stdout, content.stderr, content.other);
308 308 }
309 309
310 310
311 311 OutputArea.prototype.clear_output = function (stdout, stderr, other) {
312 312 var that = this;
313 313 if (this.clear_out_timeout != null){
314 314 // fire previous pending clear *immediately*
315 315 clearTimeout(this.clear_out_timeout);
316 316 this.clear_out_timeout = null;
317 317 this.clear_output_callback(this._clear_stdout, this._clear_stderr, this._clear_other);
318 318 }
319 319 // store flags for flushing the timeout
320 320 this._clear_stdout = stdout;
321 321 this._clear_stderr = stderr;
322 322 this._clear_other = other;
323 323 this.clear_out_timeout = setTimeout(function() {
324 324 // really clear timeout only after a short delay
325 325 // this reduces flicker in 'clear_output; print' cases
326 326 that.clear_out_timeout = null;
327 327 that._clear_stdout = that._clear_stderr = that._clear_other = null;
328 328 that.clear_output_callback(stdout, stderr, other);
329 329 }, 500
330 330 );
331 331 };
332 332
333 333
334 334 OutputArea.prototype.clear_output_callback = function (stdout, stderr, other) {
335 335 var output_div = this.element;
336 336
337 337 if (stdout && stderr && other){
338 338 // clear all, no need for logic
339 339 output_div.html("");
340 340 this.outputs = [];
341 341 return;
342 342 }
343 343 // remove html output
344 344 // each output_subarea that has an identifying class is in an output_area
345 345 // which is the element to be removed.
346 346 if (stdout) {
347 347 output_div.find("div.output_stdout").parent().remove();
348 348 }
349 349 if (stderr) {
350 350 output_div.find("div.output_stderr").parent().remove();
351 351 }
352 352 if (other) {
353 353 output_div.find("div.output_subarea").not("div.output_stderr").not("div.output_stdout").parent().remove();
354 354 }
355 355
356 356 // remove cleared outputs from JSON list:
357 357 for (var i = this.outputs.length - 1; i >= 0; i--) {
358 358 var out = this.outputs[i];
359 359 var output_type = out.output_type;
360 360 if (output_type == "display_data" && other) {
361 361 this.outputs.splice(i,1);
362 362 } else if (output_type == "stream") {
363 363 if (stdout && out.stream == "stdout") {
364 364 this.outputs.splice(i,1);
365 365 } else if (stderr && out.stream == "stderr") {
366 366 this.outputs.splice(i,1);
367 367 }
368 368 }
369 369 }
370 370 };
371 371
372 372
373 373 OutputArea.prototype.flush_clear_timeout = function() {
374 374 var output_div = this.element;
375 375 if (this.clear_out_timeout){
376 376 clearTimeout(this.clear_out_timeout);
377 377 this.clear_out_timeout = null;
378 378 this.clear_output_callback(this._clear_stdout, this._clear_stderr, this._clear_other);
379 379 };
380 380 }
381 381
382 382
383 383 // JSON serialization
384 384
385 385 OutputArea.prototype.fromJSON = function (outputs) {
386 386 var len = outputs.length;
387 387 for (var i=0; i<len; i++) {
388 388 // append with dynamic=false.
389 389 this.append_output(outputs[i], false);
390 390 };
391 391 };
392 392
393 393
394 394 OutputArea.prototype.toJSON = function () {
395 395 var outputs = [];
396 396 var len = this.outputs.length;
397 397 for (var i=0; i<len; i++) {
398 398 outputs[i] = this.outputs[i];
399 399 };
400 400 return outputs;
401 401 };
402 402
403 403
404 404 IPython.OutputArea = OutputArea;
405 405
406 406 return IPython;
407 407
408 408 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now