Merge pull request #1563 from minrk/clear_output

clear_output improvements, which allow things like progress bars and other simple animations to work well in the notebook.

* `clear_output()` clears the line, even in terminal IPython, the QtConsole and plain Python as well, by printing `\r` to streams.

* `clear_output()` avoids the flicker in the notebook by adding a delay, and firing immediately upon the next actual display message.

* `display_javascript` hides its `output_area` element, so using display to run a bunch of javascript doesn't result in ever-growing vertical space.
This commit is contained in:
Fernando Perez 2012-04-13 21:12:23 -07:00
commit 98ac51808e
2 changed files with 48 additions and 4 deletions

View File

@ -21,6 +21,7 @@ var IPython = (function (IPython) {
this.outputs = [];
this.collapsed = false;
this.tooltip_timeout = null;
this.clear_out_timeout = null;
IPython.Cell.apply(this, arguments);
};
@ -566,6 +567,7 @@ var IPython = (function (IPython) {
CodeCell.prototype.append_output = function (json, dynamic) {
// If dynamic is true, javascript output will be eval'd.
this.expand();
this.flush_clear_timeout();
if (json.output_type === 'pyout') {
this.append_pyout(json, dynamic);
} else if (json.output_type === 'pyerr') {
@ -621,6 +623,11 @@ var IPython = (function (IPython) {
if (json.stream == undefined){
json.stream = 'stdout';
}
if (!utils.fixConsole(json.text)){
// fixConsole gives nothing (empty string, \r, etc.)
// so don't append any elements, which might add undesirable space
return;
}
var subclass = "output_"+json.stream;
if (this.outputs.length > 0){
// have at least one output to consider
@ -679,10 +686,14 @@ var IPython = (function (IPython) {
};
CodeCell.prototype.append_javascript = function (js, e) {
CodeCell.prototype.append_javascript = function (js, container) {
// We just eval the JS code, element appears in the local scope.
var element = $("<div/>").addClass("box_flex1 output_subarea");
e.append(element);
container.append(element);
// Div for js shouldn't be drawn, as it will add empty height to the area.
container.hide();
// If the Javascript appends content to `element` that should be drawn, then
// it must also call `container.show()`.
eval(js);
}
@ -730,7 +741,30 @@ var IPython = (function (IPython) {
CodeCell.prototype.clear_output = function (stdout, stderr, other) {
var that = this;
if (this.clear_out_timeout != null){
// fire previous pending clear *immediately*
clearTimeout(this.clear_out_timeout);
this.clear_out_timeout = null;
this.clear_output_callback(this._clear_stdout, this._clear_stderr, this._clear_other);
}
// store flags for flushing the timeout
this._clear_stdout = stdout;
this._clear_stderr = stderr;
this._clear_other = other;
this.clear_out_timeout = setTimeout(function(){
// really clear timeout only after a short delay
// this reduces flicker in 'clear_output; print' cases
that.clear_out_timeout = null;
that._clear_stdout = that._clear_stderr = that._clear_other = null;
that.clear_output_callback(stdout, stderr, other);
}, 500
);
};
CodeCell.prototype.clear_output_callback = function (stdout, stderr, other) {
var output_div = this.element.find("div.output");
if (stdout && stderr && other){
// clear all, no need for logic
output_div.html("");
@ -770,6 +804,15 @@ var IPython = (function (IPython) {
CodeCell.prototype.clear_input = function () {
this.code_mirror.setValue('');
};
CodeCell.prototype.flush_clear_timeout = function() {
var output_div = this.element.find('div.output');
if (this.clear_out_timeout){
clearTimeout(this.clear_out_timeout);
this.clear_out_timeout = null;
this.clear_output_callback(this._clear_stdout, this._clear_stderr, this._clear_other);
};
}
CodeCell.prototype.collapse = function () {

View File

@ -52,12 +52,13 @@ IPython.utils = (function (IPython) {
// are set in the css file.
function fixConsole(txt) {
txt = xmlencode(txt);
var re = /\033\[([\d;]*?)m/;
var re = /\033\[([\dA-Fa-f;]*?)m/;
var opened = false;
var cmds = [];
var opener = "";
var closer = "";
// \r does nothing, so shouldn't be included
txt = txt.replace('\r', '');
while (re.test(txt)) {
var cmds = txt.match(re)[1].split(";");
closer = opened?"</span>":"";