allow users to set scroll state

and persist that state in metadata.

When user toggles the scroll state,
the choice is remembered and persisted.

There are three states:

- 'auto' (default, only state in master)
- true (always scroll if above minimum_scroll_threshold)
- false (never scroll)

true or false is persisted in cell.metadata.scrolled.
"auto" may be persisted, but isn't currently because it's the default state.
This commit is contained in:
Min RK 2014-11-13 16:23:26 -08:00
parent e1926b2f12
commit 66450cf2b3
2 changed files with 48 additions and 47 deletions

View File

@ -624,14 +624,7 @@ define([
} }
this.set_input_prompt(data.execution_count); this.set_input_prompt(data.execution_count);
this.output_area.trusted = data.metadata.trusted || false; this.output_area.trusted = data.metadata.trusted || false;
this.output_area.fromJSON(data.outputs); this.output_area.fromJSON(data.outputs, data.metadata);
if (data.metadata.collapsed !== undefined) {
if (data.metadata.collapsed) {
this.collapse_output();
} else {
this.expand_output();
}
}
} }
}; };
@ -649,6 +642,11 @@ define([
data.outputs = outputs; data.outputs = outputs;
data.metadata.trusted = this.output_area.trusted; data.metadata.trusted = this.output_area.trusted;
data.metadata.collapsed = this.output_area.collapsed; 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; return data;
}; };

View File

@ -26,6 +26,7 @@ define([
this.outputs = []; this.outputs = [];
this.collapsed = false; this.collapsed = false;
this.scrolled = false; this.scrolled = false;
this.scroll_state = 'auto';
this.trusted = true; this.trusted = true;
this.clear_queued = null; this.clear_queued = null;
if (options.prompt_area === undefined) { if (options.prompt_area === undefined) {
@ -72,24 +73,28 @@ define([
/** /**
* Should the OutputArea scroll? * Should the OutputArea scroll?
* Returns whether the height (in lines) exceeds a threshold. * Returns whether the height (in lines) exceeds the current threshold.
* * Threshold will be OutputArea.minimum_scroll_threshold if scroll_state=true (manually requested)
* @private * or OutputArea.auto_scroll_threshold if scroll_state='auto'.
* @method _should_scroll * This will always return false if scroll_state=false (scroll disabled).
* @param [lines=100]{Integer}
* @return {Bool}
* *
*/ */
OutputArea.prototype._should_scroll = function (lines) { OutputArea.prototype._should_scroll = function () {
if (lines <=0 ){ return; } var threshold;
if (!lines) { if (this.scroll_state === false) {
lines = 100; 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 // line-height from http://stackoverflow.com/questions/1185151
var fontSize = this.element.css('font-size'); var fontSize = this.element.css('font-size');
var lineHeight = Math.floor(parseInt(fontSize.replace('px','')) * 1.5); var lineHeight = Math.floor(parseInt(fontSize.replace('px','')) * 1.5);
return (this.element.height() > threshold * lineHeight);
return (this.element.height() > lines * lineHeight);
}; };
@ -105,7 +110,7 @@ define([
} }
// maybe scroll output, // maybe scroll output,
// if it's grown large enough and hasn't already been scrolled. // 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(); that.scroll_area();
} }
}); });
@ -123,6 +128,8 @@ define([
this.collapse_button.show(); this.collapse_button.show();
} }
this.collapsed = true; this.collapsed = true;
// collapsing output clears scroll state
this.scroll_state = 'auto';
} }
}; };
@ -133,6 +140,7 @@ define([
this.element.show(); this.element.show();
this.prompt_overlay.show(); this.prompt_overlay.show();
this.collapsed = false; 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 OutputArea.minimum_scroll_threshold if scroll_state = true,
* * OutputArea.auto_scroll_threshold if scroll_state='auto'.
* 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`.
* *
**/ **/
OutputArea.prototype.scroll_if_long = function (lines) { OutputArea.prototype.scroll_if_long = function () {
var n = lines || OutputArea.minimum_scroll_threshold; var should_scroll = this._should_scroll();
if(n <= 0){ if (!this.scrolled && should_scroll) {
return;
}
if (this._should_scroll(n)) {
// only allow scrolling long-enough output // only allow scrolling long-enough output
this.scroll_area(); this.scroll_area();
} else if (this.scrolled && !should_scroll) {
// scrolled and shouldn't be
this.unscroll_area();
} }
}; };
OutputArea.prototype.toggle_scroll = function () { OutputArea.prototype.toggle_scroll = function () {
if (this.scroll_state == 'auto') {
this.scroll_state = false;
} else {
this.scroll_state = !this.scroll_state;
}
if (this.scrolled) { if (this.scrolled) {
this.unscroll_area(); this.unscroll_area();
} else { } else {
@ -517,7 +521,7 @@ define([
.attr("href", "#") .attr("href", "#")
.text("Unrecognized output: " + json.output_type) .text("Unrecognized output: " + json.output_type)
.click(function () { .click(function () {
that.events.trigger('unrecognized_output.OutputArea', {output: json}) that.events.trigger('unrecognized_output.OutputArea', {output: json});
}) })
); );
this._safe_append(toinsert); this._safe_append(toinsert);
@ -905,19 +909,18 @@ define([
for (var i=0; i<len; i++) { for (var i=0; i<len; i++) {
this.append_output(outputs[i]); this.append_output(outputs[i]);
} }
if (metadata.collapsed !== undefined) { if (metadata.collapsed !== undefined) {
this.collapsed = metadata.collapsed; this.collapsed = metadata.collapsed;
if (metadata.collapsed) { if (metadata.collapsed) {
this.collapse_output(); this.collapse();
} }
} }
if (metadata.autoscroll !== undefined) { if (metadata.scrolled !== undefined) {
this.collapsed = metadata.collapsed; this.scroll_state = metadata.scrolled;
if (metadata.collapsed) { if (metadata.scrolled) {
this.collapse_output(); this.scroll_if_long();
} else { } else {
this.expand_output(); this.unscroll_area();
} }
} }
}; };