diff --git a/IPython/html/static/notebook/js/codecell.js b/IPython/html/static/notebook/js/codecell.js
index 029d24e..bd2fede 100644
--- a/IPython/html/static/notebook/js/codecell.js
+++ b/IPython/html/static/notebook/js/codecell.js
@@ -600,14 +600,7 @@ define([
}
this.set_input_prompt(data.execution_count);
this.output_area.trusted = data.metadata.trusted || false;
- this.output_area.fromJSON(data.outputs);
- if (data.metadata.collapsed !== undefined) {
- if (data.metadata.collapsed) {
- this.collapse_output();
- } else {
- this.expand_output();
- }
- }
+ this.output_area.fromJSON(data.outputs, data.metadata);
}
};
@@ -625,6 +618,11 @@ define([
data.outputs = outputs;
data.metadata.trusted = this.output_area.trusted;
data.metadata.collapsed = this.output_area.collapsed;
+ if (this.output_area.scroll_state === 'auto') {
+ delete data.metadata.scrolled;
+ } else {
+ data.metadata.scrolled = this.output_area.scroll_state;
+ }
return data;
};
diff --git a/IPython/html/static/notebook/js/outputarea.js b/IPython/html/static/notebook/js/outputarea.js
index 91a4322..cb8d7b3 100644
--- a/IPython/html/static/notebook/js/outputarea.js
+++ b/IPython/html/static/notebook/js/outputarea.js
@@ -26,6 +26,7 @@ define([
this.outputs = [];
this.collapsed = false;
this.scrolled = false;
+ this.scroll_state = 'auto';
this.trusted = true;
this.clear_queued = null;
if (options.prompt_area === undefined) {
@@ -72,24 +73,28 @@ define([
/**
* Should the OutputArea scroll?
- * Returns whether the height (in lines) exceeds a threshold.
- *
- * @private
- * @method _should_scroll
- * @param [lines=100]{Integer}
- * @return {Bool}
+ * Returns whether the height (in lines) exceeds the current threshold.
+ * Threshold will be OutputArea.minimum_scroll_threshold if scroll_state=true (manually requested)
+ * or OutputArea.auto_scroll_threshold if scroll_state='auto'.
+ * This will always return false if scroll_state=false (scroll disabled).
*
*/
- OutputArea.prototype._should_scroll = function (lines) {
- if (lines <=0 ){ return; }
- if (!lines) {
- lines = 100;
+ OutputArea.prototype._should_scroll = function () {
+ var threshold;
+ if (this.scroll_state === false) {
+ return false;
+ } else if (this.scroll_state === true) {
+ threshold = OutputArea.minimum_scroll_threshold;
+ } else {
+ threshold = OutputArea.auto_scroll_threshold;
+ }
+ if (threshold <=0) {
+ return false;
}
// line-height from http://stackoverflow.com/questions/1185151
var fontSize = this.element.css('font-size');
var lineHeight = Math.floor(parseInt(fontSize.replace('px','')) * 1.5);
-
- return (this.element.height() > lines * lineHeight);
+ return (this.element.height() > threshold * lineHeight);
};
@@ -105,7 +110,7 @@ define([
}
// maybe scroll output,
// if it's grown large enough and hasn't already been scrolled.
- if ( !that.scrolled && that._should_scroll(OutputArea.auto_scroll_threshold)) {
+ if (!that.scrolled && that._should_scroll()) {
that.scroll_area();
}
});
@@ -123,6 +128,8 @@ define([
this.collapse_button.show();
}
this.collapsed = true;
+ // collapsing output clears scroll state
+ this.scroll_state = 'auto';
}
};
@@ -133,6 +140,7 @@ define([
this.element.show();
this.prompt_overlay.show();
this.collapsed = false;
+ this.scroll_if_long();
}
};
@@ -160,34 +168,30 @@ define([
};
/**
+ * Scroll OutputArea if height exceeds a threshold.
*
- * Scroll OutputArea if height supperior than a threshold (in lines).
- *
- * Threshold is a maximum number of lines. If unspecified, defaults to
- * OutputArea.minimum_scroll_threshold.
- *
- * Negative threshold will prevent the OutputArea from ever scrolling.
- *
- * @method scroll_if_long
- *
- * @param [lines=20]{Number} Default to 20 if not set,
- * behavior undefined for value of `0`.
+ * Threshold is OutputArea.minimum_scroll_threshold if scroll_state = true,
+ * OutputArea.auto_scroll_threshold if scroll_state='auto'.
*
**/
- OutputArea.prototype.scroll_if_long = function (lines) {
- var n = lines || OutputArea.minimum_scroll_threshold;
- if(n <= 0){
- return;
- }
-
- if (this._should_scroll(n)) {
+ OutputArea.prototype.scroll_if_long = function () {
+ var should_scroll = this._should_scroll();
+ if (!this.scrolled && should_scroll) {
// only allow scrolling long-enough output
this.scroll_area();
+ } else if (this.scrolled && !should_scroll) {
+ // scrolled and shouldn't be
+ this.unscroll_area();
}
};
OutputArea.prototype.toggle_scroll = function () {
+ if (this.scroll_state == 'auto') {
+ this.scroll_state = !this.scrolled;
+ } else {
+ this.scroll_state = !this.scroll_state;
+ }
if (this.scrolled) {
this.unscroll_area();
} else {
@@ -515,7 +519,7 @@ define([
.attr("href", "#")
.text("Unrecognized output: " + json.output_type)
.click(function () {
- that.events.trigger('unrecognized_output.OutputArea', {output: json})
+ that.events.trigger('unrecognized_output.OutputArea', {output: json});
})
);
this._safe_append(toinsert);
@@ -903,19 +907,18 @@ define([
for (var i=0; i