commit
81f7dd7fbb
13 changed files with 395 additions and 256 deletions
48
demo/autoresize.html
Normal file
48
demo/autoresize.html
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<title>Editor</title>
|
||||||
|
<style type="text/css" media="screen">
|
||||||
|
|
||||||
|
.ace_editor {
|
||||||
|
position: relative !important;
|
||||||
|
border: 1px solid lightgray;
|
||||||
|
margin: auto;
|
||||||
|
height: 200px;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
.scrollmargin {
|
||||||
|
height: 100px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre id="editor">autoresizing editor</pre>
|
||||||
|
<div class="scrollmargin"></div>
|
||||||
|
<pre id="editor2">minHeight = 2 lines</pre>
|
||||||
|
|
||||||
|
<script src="../build/src/ace.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
// create first editor
|
||||||
|
var editor = ace.edit("editor");
|
||||||
|
editor.setTheme("ace/theme/tomorrow");
|
||||||
|
editor.session.setMode("ace/mode/html");
|
||||||
|
editor.setAutoScrollEditorIntoView();
|
||||||
|
editor.setOption("maxLines", 100);
|
||||||
|
|
||||||
|
var editor2 = ace.edit("editor2");
|
||||||
|
editor2.setTheme("ace/theme/tomorrow_night_blue");
|
||||||
|
editor2.session.setMode("ace/mode/html");
|
||||||
|
editor2.setAutoScrollEditorIntoView();
|
||||||
|
editor2.setOption("maxLines", 30);
|
||||||
|
editor2.setOption("minLines", 2);
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -103,11 +103,6 @@ var Split = function(){
|
||||||
exports.singleLineEditor = function(el) {
|
exports.singleLineEditor = function(el) {
|
||||||
var renderer = new Renderer(el);
|
var renderer = new Renderer(el);
|
||||||
el.style.overflow = "hidden";
|
el.style.overflow = "hidden";
|
||||||
renderer.scrollBar.element.style.top = "0";
|
|
||||||
renderer.scrollBar.element.style.display = "none";
|
|
||||||
renderer.scrollBar.orginalWidth = renderer.scrollBar.width;
|
|
||||||
renderer.scrollBar.width = 0;
|
|
||||||
renderer.content.style.height = "auto";
|
|
||||||
|
|
||||||
renderer.screenToTextCoordinates = function(x, y) {
|
renderer.screenToTextCoordinates = function(x, y) {
|
||||||
var pos = this.pixelToScreenCoordinates(x, y);
|
var pos = this.pixelToScreenCoordinates(x, y);
|
||||||
|
|
@ -117,61 +112,7 @@ exports.singleLineEditor = function(el) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderer.maxLines = 4;
|
renderer.$maxLines = 4;
|
||||||
renderer.$computeLayerConfigWithScroll = renderer.$computeLayerConfig;
|
|
||||||
renderer.$computeLayerConfig = function() {
|
|
||||||
var config = this.layerConfig;
|
|
||||||
var height = this.session.getScreenLength() * this.lineHeight;
|
|
||||||
if (config.height != height) {
|
|
||||||
var vScroll = height > this.maxLines * this.lineHeight;
|
|
||||||
|
|
||||||
if (vScroll != this.$vScroll) {
|
|
||||||
if (vScroll) {
|
|
||||||
this.scrollBar.element.style.display = "";
|
|
||||||
this.scrollBar.width = this.scrollBar.orginalWidth;
|
|
||||||
this.container.style.height = config.height + "px";
|
|
||||||
height = config.height;
|
|
||||||
this.scrollTop = height - this.maxLines * this.lineHeight;
|
|
||||||
} else {
|
|
||||||
this.scrollBar.element.style.display = "none";
|
|
||||||
this.scrollBar.width = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.onResize();
|
|
||||||
this.$vScroll = vScroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.$vScroll)
|
|
||||||
return renderer.$computeLayerConfigWithScroll();
|
|
||||||
|
|
||||||
this.container.style.height = height + "px";
|
|
||||||
this.scroller.style.height = height + "px";
|
|
||||||
this.content.style.height = height + "px";
|
|
||||||
this._emit("resize");
|
|
||||||
}
|
|
||||||
|
|
||||||
var longestLine = this.$getLongestLine();
|
|
||||||
var firstRow = 0;
|
|
||||||
var lastRow = this.session.getLength();
|
|
||||||
|
|
||||||
this.scrollTop = 0;
|
|
||||||
config.width = longestLine;
|
|
||||||
config.padding = this.$padding;
|
|
||||||
config.firstRow = 0;
|
|
||||||
config.firstRowScreen = 0;
|
|
||||||
config.lastRow = lastRow;
|
|
||||||
config.lineHeight = this.lineHeight;
|
|
||||||
config.characterWidth = this.characterWidth;
|
|
||||||
config.minHeight = height;
|
|
||||||
config.maxHeight = height;
|
|
||||||
config.offset = 0;
|
|
||||||
config.height = height;
|
|
||||||
|
|
||||||
this.$gutterLayer.element.style.marginTop = 0 + "px";
|
|
||||||
this.content.style.marginTop = 0 + "px";
|
|
||||||
this.content.style.width = longestLine + 2 * this.$padding + "px";
|
|
||||||
};
|
|
||||||
renderer.isScrollableBy=function(){return false};
|
|
||||||
|
|
||||||
renderer.setStyle("ace_one-line");
|
renderer.setStyle("ace_one-line");
|
||||||
var editor = new Editor(renderer);
|
var editor = new Editor(renderer);
|
||||||
|
|
@ -182,7 +123,6 @@ exports.singleLineEditor = function(el) {
|
||||||
editor.setShowPrintMargin(false);
|
editor.setShowPrintMargin(false);
|
||||||
editor.renderer.setShowGutter(false);
|
editor.renderer.setShowGutter(false);
|
||||||
editor.renderer.setHighlightGutterLine(false);
|
editor.renderer.setHighlightGutterLine(false);
|
||||||
|
|
||||||
editor.$mouseHandler.$focusWaitTimout = 0;
|
editor.$mouseHandler.$focusWaitTimout = 0;
|
||||||
|
|
||||||
return editor;
|
return editor;
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,6 @@ $(function() {
|
||||||
|
|
||||||
tabs.find(tab_a_selector).click(function(e) {
|
tabs.find(tab_a_selector).click(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
embedded_editor.resize();
|
|
||||||
editor.resize();
|
|
||||||
if ($(this).attr("href") === "/") {
|
if ($(this).attr("href") === "/") {
|
||||||
window.location = "http://ace.ajax.org";
|
window.location = "http://ace.ajax.org";
|
||||||
return;
|
return;
|
||||||
|
|
@ -101,6 +99,8 @@ $(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
$(this).tab("show");
|
$(this).tab("show");
|
||||||
|
embedded_editor.resize();
|
||||||
|
editor.resize();
|
||||||
|
|
||||||
var state = {};
|
var state = {};
|
||||||
state.nav = $(this).attr("href").substr(1);
|
state.nav = $(this).attr("href").substr(1);
|
||||||
|
|
|
||||||
|
|
@ -42,41 +42,7 @@ var dom = require("../lib/dom");
|
||||||
var $singleLineEditor = function(el) {
|
var $singleLineEditor = function(el) {
|
||||||
var renderer = new Renderer(el);
|
var renderer = new Renderer(el);
|
||||||
|
|
||||||
renderer.maxLines = 4;
|
renderer.$maxLines = 4;
|
||||||
renderer.$computeLayerConfigWithScroll = renderer.$computeLayerConfig;
|
|
||||||
renderer.scrollBar.orginalWidth = renderer.scrollBar.getWidth();
|
|
||||||
renderer.$computeLayerConfig = function() {
|
|
||||||
var height = this.session.getScreenLength() * this.lineHeight;
|
|
||||||
var maxHeight = this.maxLines * this.lineHeight;
|
|
||||||
var desiredHeight = Math.max(this.lineHeight, Math.min(maxHeight, height));
|
|
||||||
var vScroll = height > maxHeight;
|
|
||||||
if (desiredHeight != this.desiredHeight || vScroll != this.$vScroll) {
|
|
||||||
if (vScroll != this.$vScroll) {
|
|
||||||
if (vScroll) {
|
|
||||||
this.scrollBar.element.style.display = "";
|
|
||||||
this.scrollBar.width = this.scrollBar.orginalWidth;
|
|
||||||
|
|
||||||
height = maxHeight;
|
|
||||||
this.scrollTop = height - this.maxLines * this.lineHeight;
|
|
||||||
} else {
|
|
||||||
this.scrollBar.element.style.display = "none";
|
|
||||||
this.scrollBar.width = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$size.height = 0;
|
|
||||||
this.$size.width = 0;
|
|
||||||
|
|
||||||
this.$vScroll = vScroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.container.style.height = desiredHeight + "px";
|
|
||||||
this.onResize();
|
|
||||||
this.$loop.changes = 0;
|
|
||||||
this.desiredHeight = desiredHeight;
|
|
||||||
this.scroller.style.overflowX = "hidden";
|
|
||||||
}
|
|
||||||
return renderer.$computeLayerConfigWithScroll();
|
|
||||||
};
|
|
||||||
|
|
||||||
var editor = new Editor(renderer);
|
var editor = new Editor(renderer);
|
||||||
|
|
||||||
|
|
@ -108,7 +74,7 @@ var AcePopup = function(parentNode) {
|
||||||
popup.renderer.$cursorLayer.restartTimer = noop;
|
popup.renderer.$cursorLayer.restartTimer = noop;
|
||||||
popup.renderer.$cursorLayer.element.style.opacity = 0;
|
popup.renderer.$cursorLayer.element.style.opacity = 0;
|
||||||
|
|
||||||
popup.renderer.maxLines = 8;
|
popup.renderer.$maxLines = 8;
|
||||||
popup.renderer.$keepTextAreaAtCursor = false;
|
popup.renderer.$keepTextAreaAtCursor = false;
|
||||||
|
|
||||||
popup.setHighlightActiveLine(true);
|
popup.setHighlightActiveLine(true);
|
||||||
|
|
@ -221,6 +187,7 @@ var AcePopup = function(parentNode) {
|
||||||
|
|
||||||
el.style.left = pos.left + "px";
|
el.style.left = pos.left + "px";
|
||||||
el.style.display = "";
|
el.style.display = "";
|
||||||
|
this.renderer.$textLayer.checkForSizeChanges();
|
||||||
|
|
||||||
this._signal("show");
|
this._signal("show");
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,8 @@
|
||||||
|
|
||||||
.ace_scrollbar {
|
.ace_scrollbar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
overflow-x: hidden;
|
overflow: hidden;
|
||||||
overflow-y: scroll;
|
overflow-y: auto;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
@ -84,6 +84,22 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ace_scrollbar-h {
|
||||||
|
position: absolute;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_scrollbar-inner {
|
||||||
|
position: absolute;
|
||||||
|
height: 1px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.ace_print-margin {
|
.ace_print-margin {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
||||||
|
|
@ -990,7 +990,7 @@ var EditSession = function(text, mode) {
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.setScrollTop = function(scrollTop) {
|
this.setScrollTop = function(scrollTop) {
|
||||||
scrollTop = Math.round(Math.max(0, scrollTop));
|
scrollTop = Math.round(scrollTop);
|
||||||
if (this.$scrollTop === scrollTop || isNaN(scrollTop))
|
if (this.$scrollTop === scrollTop || isNaN(scrollTop))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1011,7 +1011,7 @@ var EditSession = function(text, mode) {
|
||||||
* [Sets the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #EditSession.setScrollLeft}
|
* [Sets the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #EditSession.setScrollLeft}
|
||||||
**/
|
**/
|
||||||
this.setScrollLeft = function(scrollLeft) {
|
this.setScrollLeft = function(scrollLeft) {
|
||||||
scrollLeft = Math.round(Math.max(0, scrollLeft));
|
scrollLeft = Math.round(scrollLeft);
|
||||||
if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))
|
if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2259,6 +2259,8 @@ config.defineOptions(Editor.prototype, "editor", {
|
||||||
displayIndentGuides: "renderer",
|
displayIndentGuides: "renderer",
|
||||||
fontSize: "renderer",
|
fontSize: "renderer",
|
||||||
fontFamily: "renderer",
|
fontFamily: "renderer",
|
||||||
|
maxLines: "renderer",
|
||||||
|
minLines: "renderer",
|
||||||
|
|
||||||
scrollSpeed: "$mouseHandler",
|
scrollSpeed: "$mouseHandler",
|
||||||
dragDelay: "$mouseHandler",
|
dragDelay: "$mouseHandler",
|
||||||
|
|
|
||||||
|
|
@ -288,21 +288,18 @@ function setupApi(editor, editorDiv, settingDiv, ace, options, loader) {
|
||||||
settingDiv.hideButton.focus();
|
settingDiv.hideButton.focus();
|
||||||
editor.on("focus", function onFocus() {
|
editor.on("focus", function onFocus() {
|
||||||
editor.removeListener("focus", onFocus);
|
editor.removeListener("focus", onFocus);
|
||||||
settingDiv.style.display = "none"
|
settingDiv.style.display = "none";
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
editor.focus();
|
editor.focus();
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
editor.$setOption = editor.setOption;
|
||||||
editor.setOption = function(key, value) {
|
editor.setOption = function(key, value) {
|
||||||
if (options[key] == value) return;
|
if (options[key] == value) return;
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "gutter":
|
|
||||||
renderer.setShowGutter(toBool(value));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "mode":
|
case "mode":
|
||||||
if (value != "text") {
|
if (value != "text") {
|
||||||
// Load the required mode file. Files get loaded only once.
|
// Load the required mode file. Files get loaded only once.
|
||||||
|
|
@ -367,17 +364,8 @@ function setupApi(editor, editorDiv, settingDiv, ace, options, loader) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "useSoftTabs":
|
default:
|
||||||
session.setUseSoftTabs(toBool(value));
|
editor.$setOption(key, toBool(value));
|
||||||
break;
|
|
||||||
|
|
||||||
case "showPrintMargin":
|
|
||||||
renderer.setShowPrintMargin(toBool(value));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "showInvisibles":
|
|
||||||
editor.setShowInvisibles(toBool(value));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options[key] = value;
|
options[key] = value;
|
||||||
|
|
@ -391,9 +379,7 @@ function setupApi(editor, editorDiv, settingDiv, ace, options, loader) {
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var option in exports.options) {
|
editor.setOptions(exports.options);
|
||||||
editor.setOption(option, exports.options[option]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
@ -493,7 +479,7 @@ function setupSettingPanel(settingDiv, settingOpener, editor, options) {
|
||||||
cValue == "true" ? "checked='true'" : "",
|
cValue == "true" ? "checked='true'" : "",
|
||||||
"'></input>"
|
"'></input>"
|
||||||
);
|
);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
builder.push("<select title='" + option + "'>");
|
builder.push("<select title='" + option + "'>");
|
||||||
for (var value in obj) {
|
for (var value in obj) {
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,6 @@ var event = require("./lib/event");
|
||||||
var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
*
|
|
||||||
* A set of methods for setting and retrieving the editor's scrollbar.
|
* A set of methods for setting and retrieving the editor's scrollbar.
|
||||||
* @class ScrollBar
|
* @class ScrollBar
|
||||||
**/
|
**/
|
||||||
|
|
@ -47,12 +45,9 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
||||||
* Creates a new `ScrollBar`. `parent` is the owner of the scroll bar.
|
* Creates a new `ScrollBar`. `parent` is the owner of the scroll bar.
|
||||||
* @param {DOMElement} parent A DOM element
|
* @param {DOMElement} parent A DOM element
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @constructor
|
* @constructor
|
||||||
**/
|
**/
|
||||||
var ScrollBar = function(parent) {
|
var ScrollBarV = function(parent) {
|
||||||
this.element = dom.createElement("div");
|
this.element = dom.createElement("div");
|
||||||
this.element.className = "ace_scrollbar";
|
this.element.className = "ace_scrollbar";
|
||||||
|
|
||||||
|
|
@ -62,38 +57,81 @@ var ScrollBar = function(parent) {
|
||||||
|
|
||||||
parent.appendChild(this.element);
|
parent.appendChild(this.element);
|
||||||
|
|
||||||
// in OSX lion the scrollbars appear to have no width. In this case resize
|
// in OSX lion the scrollbars appear to have no width. In this case resize the
|
||||||
// the to show the scrollbar but still pretend that the scrollbar has a width
|
// element to show the scrollbar but still pretend that the scrollbar has a width
|
||||||
// of 0px
|
// of 0px
|
||||||
// in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
|
// in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
|
||||||
// make element a little bit wider to retain scrollbar when page is zoomed
|
// make element a little bit wider to retain scrollbar when page is zoomed
|
||||||
this.width = dom.scrollbarWidth(parent.ownerDocument);
|
this.width = dom.scrollbarWidth(parent.ownerDocument);
|
||||||
|
this.fullWidth = this.width;
|
||||||
this.element.style.width = (this.width || 15) + 5 + "px";
|
this.element.style.width = (this.width || 15) + 5 + "px";
|
||||||
|
this.setVisible(false);
|
||||||
|
this.element.style.overflowY = "scroll";
|
||||||
|
|
||||||
event.addListener(this.element, "scroll", this.onScroll.bind(this));
|
event.addListener(this.element, "scroll", this.onScrollV.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
var ScrollBarH = function(parent) {
|
||||||
|
this.element = dom.createElement("div");
|
||||||
|
this.element.className = "ace_scrollbar-h";
|
||||||
|
|
||||||
|
this.inner = dom.createElement("div");
|
||||||
|
this.inner.className = "ace_scrollbar-inner";
|
||||||
|
this.element.appendChild(this.inner);
|
||||||
|
|
||||||
|
parent.appendChild(this.element);
|
||||||
|
|
||||||
|
// in OSX lion the scrollbars appear to have no width. In this case resize the
|
||||||
|
// element to show the scrollbar but still pretend that the scrollbar has a width
|
||||||
|
// of 0px
|
||||||
|
// in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
|
||||||
|
// make element a little bit wider to retain scrollbar when page is zoomed
|
||||||
|
this.height = dom.scrollbarWidth(parent.ownerDocument);
|
||||||
|
this.fullHeight = this.height;
|
||||||
|
this.element.style.height = (this.height || 15) + 5 + "px";
|
||||||
|
this.setVisible(false);
|
||||||
|
this.element.style.overflowX = "scroll";
|
||||||
|
|
||||||
|
event.addListener(this.element, "scroll", this.onScrollH.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
oop.implement(this, EventEmitter);
|
oop.implement(this, EventEmitter);
|
||||||
|
|
||||||
|
this.setVisible = function(show) {
|
||||||
|
if (show) {
|
||||||
|
this.element.style.display = "";
|
||||||
|
if (this.fullWidth)
|
||||||
|
this.width = this.fullWidth;
|
||||||
|
if (this.fullHeight)
|
||||||
|
this.height = this.fullHeight;
|
||||||
|
} else {
|
||||||
|
this.element.style.display = "none";
|
||||||
|
this.height = this.width = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when the scroll bar, well, scrolls.
|
* Emitted when the scroll bar, well, scrolls.
|
||||||
* @event scroll
|
* @event scroll
|
||||||
* @param {Object} e Contains one property, `"data"`, which indicates the current scroll top position
|
* @param {Object} e Contains one property, `"data"`, which indicates the current scroll top position
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.onScroll = function() {
|
this.onScrollV = function() {
|
||||||
if (!this.skipEvent) {
|
if (!this.skipEvent) {
|
||||||
this.scrollTop = this.element.scrollTop;
|
this.scrollTop = this.element.scrollTop;
|
||||||
this._emit("scroll", {data: this.scrollTop});
|
this._emit("scroll", {data: this.scrollTop});
|
||||||
}
|
}
|
||||||
this.skipEvent = false;
|
this.skipEvent = false;
|
||||||
};
|
};
|
||||||
|
this.onScrollH = function() {
|
||||||
|
if (!this.skipEvent) {
|
||||||
|
this.scrollLeft = this.element.scrollLeft;
|
||||||
|
this._emit("scroll", {data: this.scrollLeft});
|
||||||
|
}
|
||||||
|
this.skipEvent = false;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Returns the width of the scroll bar.
|
* Returns the width of the scroll bar.
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
**/
|
**/
|
||||||
|
|
@ -101,46 +139,59 @@ var ScrollBar = function(parent) {
|
||||||
return this.width;
|
return this.width;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getHeight = function() {
|
||||||
|
return this.height;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the height of the scroll bar, in pixels.
|
* Sets the height of the scroll bar, in pixels.
|
||||||
* @param {Number} height The new height
|
* @param {Number} height The new height
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.setHeight = function(height) {
|
this.setHeight = function(height) {
|
||||||
this.element.style.height = height + "px";
|
this.element.style.height = height + "px";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.setWidth = function(width) {
|
||||||
|
this.element.style.width = width + "px";
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the inner height of the scroll bar, in pixels.
|
* Sets the inner height of the scroll bar, in pixels.
|
||||||
* @param {Number} height The new inner height
|
* @param {Number} height The new inner height
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.setInnerHeight = function(height) {
|
this.setInnerHeight = function(height) {
|
||||||
this.inner.style.height = height + "px";
|
this.inner.style.height = height + "px";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.setInnerWidth = function(width) {
|
||||||
|
this.inner.style.width = width + "px";
|
||||||
|
};
|
||||||
|
|
||||||
// on chrome 17+ for small zoom levels after calling this function
|
|
||||||
// this.element.scrollTop != scrollTop which makes page to scroll up.
|
|
||||||
/**
|
/**
|
||||||
* Sets the scroll top of the scroll bar.
|
* Sets the scroll top of the scroll bar.
|
||||||
* @param {Number} scrollTop The new scroll top
|
* @param {Number} scrollTop The new scroll top
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
|
// on chrome 17+ for small zoom levels after calling this function
|
||||||
|
// this.element.scrollTop != scrollTop which makes page to scroll up.
|
||||||
this.setScrollTop = function(scrollTop) {
|
this.setScrollTop = function(scrollTop) {
|
||||||
if (this.scrollTop != scrollTop) {
|
if (this.scrollTop != scrollTop) {
|
||||||
this.skipEvent = true;
|
this.skipEvent = true;
|
||||||
this.scrollTop = this.element.scrollTop = scrollTop;
|
this.scrollTop = this.element.scrollTop = scrollTop;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.setScrollLeft = function(scrollLeft) {
|
||||||
|
if (this.scrollLeft != scrollLeft) {
|
||||||
|
this.skipEvent = true;
|
||||||
|
this.scrollLeft = this.element.scrollLeft = scrollLeft;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}).call(ScrollBar.prototype);
|
}).call(ScrollBarV.prototype);
|
||||||
|
ScrollBarH.prototype = ScrollBarV.prototype;
|
||||||
|
|
||||||
exports.ScrollBar = ScrollBar;
|
|
||||||
|
|
||||||
|
exports.ScrollBar = ScrollBarV; // backward compatibility
|
||||||
|
exports.ScrollBarV = ScrollBarV;
|
||||||
|
exports.ScrollBarH = ScrollBarH;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ snippet fora
|
||||||
${4}
|
${4}
|
||||||
}
|
}
|
||||||
# Try / Catch Block
|
# Try / Catch Block
|
||||||
snippet @try
|
snippet @try
|
||||||
@try {
|
@try {
|
||||||
${1:statements}
|
${1:statements}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ snippet ns
|
||||||
snippet use
|
snippet use
|
||||||
use ${1:Foo\Bar\Baz};
|
use ${1:Foo\Bar\Baz};
|
||||||
${2}
|
${2}
|
||||||
snippet c
|
snippet c
|
||||||
${1:abstract }class ${2:`Filename()`}
|
${1:abstract }class ${2:`Filename()`}
|
||||||
{
|
{
|
||||||
${3}
|
${3}
|
||||||
|
|
|
||||||
|
|
@ -85,13 +85,13 @@ snippet la
|
||||||
snippet l_
|
snippet l_
|
||||||
l_ply(${1:list}, ${2:function})
|
l_ply(${1:list}, ${2:function})
|
||||||
|
|
||||||
snippet md
|
snippet md
|
||||||
mdply(${1:matrix}, ${2:function})
|
mdply(${1:matrix}, ${2:function})
|
||||||
snippet ml
|
snippet ml
|
||||||
mlply(${1:matrix}, ${2:function})
|
mlply(${1:matrix}, ${2:function})
|
||||||
snippet ma
|
snippet ma
|
||||||
maply(${1:matrix}, ${2:function})
|
maply(${1:matrix}, ${2:function})
|
||||||
snippet m_
|
snippet m_
|
||||||
m_ply(${1:matrix}, ${2:function})
|
m_ply(${1:matrix}, ${2:function})
|
||||||
|
|
||||||
# plot functions
|
# plot functions
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,8 @@ var GutterLayer = require("./layer/gutter").Gutter;
|
||||||
var MarkerLayer = require("./layer/marker").Marker;
|
var MarkerLayer = require("./layer/marker").Marker;
|
||||||
var TextLayer = require("./layer/text").Text;
|
var TextLayer = require("./layer/text").Text;
|
||||||
var CursorLayer = require("./layer/cursor").Cursor;
|
var CursorLayer = require("./layer/cursor").Cursor;
|
||||||
var ScrollBar = require("./scrollbar").ScrollBar;
|
var ScrollBarH = require("./scrollbar").ScrollBarH;
|
||||||
|
var ScrollBarV = require("./scrollbar").ScrollBarV;
|
||||||
var RenderLoop = require("./renderloop").RenderLoop;
|
var RenderLoop = require("./renderloop").RenderLoop;
|
||||||
var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
||||||
var editorCss = require("./requirejs/text!./css/editor.css");
|
var editorCss = require("./requirejs/text!./css/editor.css");
|
||||||
|
|
@ -102,22 +103,23 @@ var VirtualRenderer = function(container, theme) {
|
||||||
|
|
||||||
// Indicates whether the horizontal scrollbar is visible
|
// Indicates whether the horizontal scrollbar is visible
|
||||||
this.$horizScroll = false;
|
this.$horizScroll = false;
|
||||||
|
this.$vScroll = false;
|
||||||
|
|
||||||
this.scrollBar = new ScrollBar(this.container);
|
this.scrollBar =
|
||||||
this.scrollBar.addEventListener("scroll", function(e) {
|
this.scrollBarV = new ScrollBarV(this.container);
|
||||||
|
this.scrollBarH = new ScrollBarH(this.container);
|
||||||
|
this.scrollBarV.addEventListener("scroll", function(e) {
|
||||||
if (!_self.$scrollAnimation)
|
if (!_self.$scrollAnimation)
|
||||||
_self.session.setScrollTop(e.data);
|
_self.session.setScrollTop(e.data - _self.scrollMargin.top);
|
||||||
|
});
|
||||||
|
this.scrollBarH.addEventListener("scroll", function(e) {
|
||||||
|
if (!_self.$scrollAnimation)
|
||||||
|
_self.session.setScrollLeft(e.data - _self.scrollMargin.left);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.scrollTop = 0;
|
this.scrollTop = 0;
|
||||||
this.scrollLeft = 0;
|
this.scrollLeft = 0;
|
||||||
|
|
||||||
event.addListener(this.scroller, "scroll", function() {
|
|
||||||
var scrollLeft = _self.scroller.scrollLeft;
|
|
||||||
_self.scrollLeft = scrollLeft;
|
|
||||||
_self.session.setScrollLeft(scrollLeft);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.cursorPos = {
|
this.cursorPos = {
|
||||||
row : 0,
|
row : 0,
|
||||||
column : 0
|
column : 0
|
||||||
|
|
@ -126,6 +128,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.$textLayer.addEventListener("changeCharacterSize", function() {
|
this.$textLayer.addEventListener("changeCharacterSize", function() {
|
||||||
_self.updateCharacterSize();
|
_self.updateCharacterSize();
|
||||||
_self.onResize(true);
|
_self.onResize(true);
|
||||||
|
_self._signal("changeCharacterSize");
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$size = {
|
this.$size = {
|
||||||
|
|
@ -149,6 +152,15 @@ var VirtualRenderer = function(container, theme) {
|
||||||
height : 1
|
height : 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.scrollMargin = {
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
v: 0,
|
||||||
|
h: 0
|
||||||
|
}
|
||||||
|
|
||||||
this.$loop = new RenderLoop(
|
this.$loop = new RenderLoop(
|
||||||
this.$renderChanges.bind(this),
|
this.$renderChanges.bind(this),
|
||||||
this.container.ownerDocument.defaultView
|
this.container.ownerDocument.defaultView
|
||||||
|
|
@ -175,6 +187,22 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.CHANGE_FULL = 512;
|
this.CHANGE_FULL = 512;
|
||||||
this.CHANGE_H_SCROLL = 1024;
|
this.CHANGE_H_SCROLL = 1024;
|
||||||
|
|
||||||
|
// this.$logChanges = function(changes) {
|
||||||
|
// var a = ""
|
||||||
|
// if (changes & this.CHANGE_CURSOR) a += " cursor";
|
||||||
|
// if (changes & this.CHANGE_MARKER) a += " marker";
|
||||||
|
// if (changes & this.CHANGE_GUTTER) a += " gutter";
|
||||||
|
// if (changes & this.CHANGE_SCROLL) a += " scroll";
|
||||||
|
// if (changes & this.CHANGE_LINES) a += " lines";
|
||||||
|
// if (changes & this.CHANGE_TEXT) a += " text";
|
||||||
|
// if (changes & this.CHANGE_SIZE) a += " size";
|
||||||
|
// if (changes & this.CHANGE_MARKER_BACK) a += " marker_back";
|
||||||
|
// if (changes & this.CHANGE_MARKER_FRONT) a += " marker_front";
|
||||||
|
// if (changes & this.CHANGE_FULL) a += " full";
|
||||||
|
// if (changes & this.CHANGE_H_SCROLL) a += " h_scroll";
|
||||||
|
// console.log(a.trim())
|
||||||
|
// };
|
||||||
|
|
||||||
oop.implement(this, EventEmitter);
|
oop.implement(this, EventEmitter);
|
||||||
|
|
||||||
this.updateCharacterSize = function() {
|
this.updateCharacterSize = function() {
|
||||||
|
|
@ -270,6 +298,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.$textLayer.checkForSizeChanges();
|
this.$textLayer.checkForSizeChanges();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.$changes = 0;
|
||||||
/**
|
/**
|
||||||
* [Triggers a resize of the editor.]{: #VirtualRenderer.onResize}
|
* [Triggers a resize of the editor.]{: #VirtualRenderer.onResize}
|
||||||
* @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed
|
* @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed
|
||||||
|
|
@ -280,9 +309,6 @@ var VirtualRenderer = function(container, theme) {
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.onResize = function(force, gutterWidth, width, height) {
|
this.onResize = function(force, gutterWidth, width, height) {
|
||||||
var changes = 0;
|
|
||||||
var size = this.$size;
|
|
||||||
|
|
||||||
if (this.resizing > 2)
|
if (this.resizing > 2)
|
||||||
return;
|
return;
|
||||||
else if (this.resizing > 1)
|
else if (this.resizing > 1)
|
||||||
|
|
@ -290,41 +316,11 @@ var VirtualRenderer = function(container, theme) {
|
||||||
else
|
else
|
||||||
this.resizing = force ? 1 : 0;
|
this.resizing = force ? 1 : 0;
|
||||||
if (!height)
|
if (!height)
|
||||||
height = dom.getInnerHeight(this.container);
|
height = this.container.clientHeight;
|
||||||
|
|
||||||
if (height && (force || size.height != height)) {
|
|
||||||
size.height = height;
|
|
||||||
changes = this.CHANGE_SIZE;
|
|
||||||
|
|
||||||
size.scrollerHeight = this.scroller.clientHeight;
|
|
||||||
if (force || !size.scrollerHeight) {
|
|
||||||
size.scrollerHeight = size.height;
|
|
||||||
if (this.$horizScroll)
|
|
||||||
size.scrollerHeight -= this.scrollBar.getWidth();
|
|
||||||
}
|
|
||||||
this.scrollBar.setHeight(size.scrollerHeight);
|
|
||||||
|
|
||||||
if (this.session) {
|
|
||||||
this.session.setScrollTop(this.getScrollTop());
|
|
||||||
changes = changes | this.CHANGE_FULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!width)
|
if (!width)
|
||||||
width = dom.getInnerWidth(this.container);
|
width = this.container.clientWidth;
|
||||||
|
|
||||||
if (width && (force || this.resizing > 1 || size.width != width)) {
|
var changes = this.$updateCachedSize(force, gutterWidth, width, height);
|
||||||
changes = this.CHANGE_SIZE;
|
|
||||||
size.width = width;
|
|
||||||
|
|
||||||
var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
|
|
||||||
this.scroller.style.left = gutterWidth + "px";
|
|
||||||
size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth());
|
|
||||||
this.scroller.style.right = this.scrollBar.getWidth() + "px";
|
|
||||||
|
|
||||||
if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
|
|
||||||
changes = changes | this.CHANGE_FULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.$size.scrollerHeight)
|
if (!this.$size.scrollerHeight)
|
||||||
return;
|
return;
|
||||||
|
|
@ -341,16 +337,56 @@ var VirtualRenderer = function(container, theme) {
|
||||||
delete this.resizing;
|
delete this.resizing;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.$updateCachedSize = function(force, gutterWidth, width, height) {
|
||||||
|
var changes = this.$changes || 0;
|
||||||
|
var size = this.$size;
|
||||||
|
if (height && (force || size.height != height)) {
|
||||||
|
size.height = height;
|
||||||
|
changes = this.CHANGE_SIZE;
|
||||||
|
|
||||||
|
size.scrollerHeight = size.height;
|
||||||
|
if (this.$horizScroll)
|
||||||
|
size.scrollerHeight -= this.scrollBarH.getHeight();
|
||||||
|
|
||||||
|
this.scrollBarV.setHeight(size.scrollerHeight);
|
||||||
|
|
||||||
|
if (this.session) {
|
||||||
|
this.session.setScrollTop(this.getScrollTop());
|
||||||
|
changes = changes | this.CHANGE_SCROLL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width && (force || this.resizing > 1 || size.width != width)) {
|
||||||
|
changes = this.CHANGE_SIZE;
|
||||||
|
size.width = width;
|
||||||
|
|
||||||
|
var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
|
||||||
|
this.scrollBarH.element.style.left =
|
||||||
|
this.scroller.style.left = gutterWidth + "px";
|
||||||
|
size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth());
|
||||||
|
|
||||||
|
this.scroller.style.right = this.scrollBarV.getWidth() + "px";
|
||||||
|
this.scroller.style.bottom = this.scrollBarH.getHeight() + "px";
|
||||||
|
|
||||||
|
this.scrollBarH.setWidth(size.scrollerWidth);
|
||||||
|
|
||||||
|
if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
|
||||||
|
changes = changes | this.CHANGE_FULL;
|
||||||
|
}
|
||||||
|
return changes;
|
||||||
|
};
|
||||||
|
|
||||||
this.onGutterResize = function() {
|
this.onGutterResize = function() {
|
||||||
var width = this.$size.width;
|
var width = this.$size.width;
|
||||||
var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
|
var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
|
||||||
this.scroller.style.left = gutterWidth + "px";
|
this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);
|
||||||
this.$size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth());
|
|
||||||
|
|
||||||
if (this.session.getUseWrapMode() && this.adjustWrapLimit())
|
if (this.session.getUseWrapMode() && this.adjustWrapLimit())
|
||||||
this.$loop.schedule(this.CHANGE_FULL);
|
this.$loop.schedule(this.CHANGE_FULL);
|
||||||
else
|
else {
|
||||||
|
this.$computeLayerConfig();
|
||||||
this.$loop.schedule(this.CHANGE_MARKER);
|
this.$loop.schedule(this.CHANGE_MARKER);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -619,33 +655,64 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.$updatePrintMargin();
|
this.$updatePrintMargin();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.setScrollMargin = function(top, bottom, left, right) {
|
||||||
|
var sm = this.scrollMargin;
|
||||||
|
sm.top = top|0;
|
||||||
|
sm.bottom = bottom|0;
|
||||||
|
sm.right = right|0;
|
||||||
|
sm.left = left|0;
|
||||||
|
sm.v = sm.top + sm.bottom;
|
||||||
|
sm.h = sm.left + sm.right;
|
||||||
|
this.updateFull();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Returns whether the horizontal scrollbar is set to be always visible.
|
||||||
* Returns whether the horizontal scrollbar is set to be always visible.
|
* @returns {Boolean}
|
||||||
* @returns {Boolean}
|
**/
|
||||||
**/
|
|
||||||
this.getHScrollBarAlwaysVisible = function() {
|
this.getHScrollBarAlwaysVisible = function() {
|
||||||
return this.$hScrollBarAlwaysVisible;
|
return this.$hScrollBarAlwaysVisible;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies whether you want to show the horizontal scrollbar or not.
|
* Identifies whether you want to show the horizontal scrollbar or not.
|
||||||
* @param {Boolean} alwaysVisible Set to `true` to make the horizontal scroll bar visible
|
* @param {Boolean} alwaysVisible Set to `true` to make the horizontal scroll bar visible
|
||||||
*
|
**/
|
||||||
*
|
|
||||||
**/
|
|
||||||
this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
|
this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
|
||||||
this.setOption("hScrollBarAlwaysVisible", alwaysVisible);
|
this.setOption("hScrollBarAlwaysVisible", alwaysVisible);
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Returns whether the horizontal scrollbar is set to be always visible.
|
||||||
|
* @returns {Boolean}
|
||||||
|
**/
|
||||||
|
this.getVScrollBarAlwaysVisible = function() {
|
||||||
|
return this.$hScrollBarAlwaysVisible;
|
||||||
|
};
|
||||||
|
|
||||||
this.$updateScrollBar = function() {
|
/**
|
||||||
this.scrollBar.setInnerHeight(this.layerConfig.maxHeight);
|
* Identifies whether you want to show the horizontal scrollbar or not.
|
||||||
this.scrollBar.setScrollTop(this.scrollTop);
|
* @param {Boolean} alwaysVisible Set to `true` to make the horizontal scroll bar visible
|
||||||
|
**/
|
||||||
|
this.setVScrollBarAlwaysVisible = function(alwaysVisible) {
|
||||||
|
this.setOption("vScrollBarAlwaysVisible", alwaysVisible);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$updateScrollBarV = function() {
|
||||||
|
this.scrollBarV.setInnerHeight(this.layerConfig.maxHeight + this.scrollMargin.v);
|
||||||
|
this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top);
|
||||||
|
};
|
||||||
|
this.$updateScrollBarH = function() {
|
||||||
|
this.scrollBarH.setInnerWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h);
|
||||||
|
this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$renderChanges = function(changes, force) {
|
this.$renderChanges = function(changes, force) {
|
||||||
if (!force && (!changes || !this.session || !this.container.offsetWidth))
|
if (!force && (!changes || !this.session || !this.container.offsetWidth)) {
|
||||||
|
this.$changes = changes;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this.$logChanges(changes);
|
||||||
|
|
||||||
this._signal("beforeRender");
|
this._signal("beforeRender");
|
||||||
// text, scrolling and resize changes can cause the view port size to change
|
// text, scrolling and resize changes can cause the view port size to change
|
||||||
|
|
@ -659,21 +726,17 @@ var VirtualRenderer = function(container, theme) {
|
||||||
|
|
||||||
// horizontal scrolling
|
// horizontal scrolling
|
||||||
if (changes & this.CHANGE_H_SCROLL) {
|
if (changes & this.CHANGE_H_SCROLL) {
|
||||||
this.scroller.scrollLeft = this.scrollLeft;
|
this.$updateScrollBarH();
|
||||||
|
this.content.style.marginLeft = -this.scrollLeft + "px";
|
||||||
// read the value after writing it since the value might get clipped
|
this.scroller.className = this.scrollLeft <= 0 ? "ace_scroller" : "ace_scroller ace_scroll-left";
|
||||||
var scrollLeft = this.scroller.scrollLeft;
|
|
||||||
this.scrollLeft = scrollLeft;
|
|
||||||
this.session.setScrollLeft(scrollLeft);
|
|
||||||
|
|
||||||
this.scroller.className = this.scrollLeft == 0 ? "ace_scroller" : "ace_scroller ace_scroll-left";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// full
|
// full
|
||||||
if (changes & this.CHANGE_FULL) {
|
if (changes & this.CHANGE_FULL) {
|
||||||
this.$textLayer.checkForSizeChanges();
|
this.$textLayer.checkForSizeChanges();
|
||||||
// update scrollbar first to not lose scroll position when gutter calls resize
|
// update scrollbar first to not lose scroll position when gutter calls resize
|
||||||
this.$updateScrollBar();
|
this.$updateScrollBarV();
|
||||||
|
this.$updateScrollBarH();
|
||||||
this.$textLayer.update(this.layerConfig);
|
this.$textLayer.update(this.layerConfig);
|
||||||
if (this.$showGutter)
|
if (this.$showGutter)
|
||||||
this.$gutterLayer.update(this.layerConfig);
|
this.$gutterLayer.update(this.layerConfig);
|
||||||
|
|
@ -688,6 +751,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
|
|
||||||
// scrolling
|
// scrolling
|
||||||
if (changes & this.CHANGE_SCROLL) {
|
if (changes & this.CHANGE_SCROLL) {
|
||||||
|
this.$updateScrollBarV();
|
||||||
if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)
|
if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)
|
||||||
this.$textLayer.update(this.layerConfig);
|
this.$textLayer.update(this.layerConfig);
|
||||||
else
|
else
|
||||||
|
|
@ -700,7 +764,6 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.$cursorLayer.update(this.layerConfig);
|
this.$cursorLayer.update(this.layerConfig);
|
||||||
this.$highlightGutterLine && this.$updateGutterLineHighlight();
|
this.$highlightGutterLine && this.$updateGutterLineHighlight();
|
||||||
this.$moveTextAreaToCursor();
|
this.$moveTextAreaToCursor();
|
||||||
this.$updateScrollBar();
|
|
||||||
this._signal("afterRender");
|
this._signal("afterRender");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -733,35 +796,79 @@ var VirtualRenderer = function(container, theme) {
|
||||||
this.$markerBack.update(this.layerConfig);
|
this.$markerBack.update(this.layerConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changes & this.CHANGE_SIZE)
|
if (changes & this.CHANGE_SIZE || changes & this.CHANGE_LINES) {
|
||||||
this.$updateScrollBar();
|
this.$updateScrollBarV();
|
||||||
|
this.$updateScrollBarH();
|
||||||
|
}
|
||||||
|
|
||||||
this._signal("afterRender");
|
this._signal("afterRender");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.$autosize = function(height, width) {
|
||||||
|
var height = this.session.getScreenLength() * this.lineHeight;
|
||||||
|
var maxHeight = this.$maxLines * this.lineHeight;
|
||||||
|
var desiredHeight = Math.max(
|
||||||
|
(this.$minLines||1) * this.lineHeight,
|
||||||
|
Math.min(maxHeight, height)
|
||||||
|
);
|
||||||
|
var vScroll = height > maxHeight;
|
||||||
|
|
||||||
|
if (desiredHeight != this.desiredHeight ||
|
||||||
|
this.$size.height != this.desiredHeight || vScroll != this.$vScroll) {
|
||||||
|
if (vScroll != this.$vScroll) {
|
||||||
|
this.$vScroll = vScroll;
|
||||||
|
this.scrollBarV.setVisible(vScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
var w = this.container.clientWidth;
|
||||||
|
this.container.style.height = desiredHeight + "px";
|
||||||
|
this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight);
|
||||||
|
// this.$loop.changes = 0;
|
||||||
|
this.desiredHeight = desiredHeight;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.$computeLayerConfig = function() {
|
this.$computeLayerConfig = function() {
|
||||||
|
if (this.$maxLines && this.lineHeight > 1)
|
||||||
|
this.$autosize();
|
||||||
|
|
||||||
if (!this.$size.scrollerHeight)
|
if (!this.$size.scrollerHeight)
|
||||||
return this.onResize(true);
|
return this.onResize(true);
|
||||||
|
|
||||||
var session = this.session;
|
var session = this.session;
|
||||||
|
|
||||||
|
var hideScrollbars = this.$size.height <= 2 * this.lineHeight;
|
||||||
|
var screenLines = this.session.getScreenLength()
|
||||||
|
var maxHeight = screenLines * this.lineHeight;
|
||||||
|
|
||||||
var offset = this.scrollTop % this.lineHeight;
|
var offset = this.scrollTop % this.lineHeight;
|
||||||
var minHeight = this.$size.scrollerHeight + this.lineHeight;
|
var minHeight = this.$size.scrollerHeight + this.lineHeight;
|
||||||
|
|
||||||
var longestLine = this.$getLongestLine();
|
var longestLine = this.$getLongestLine();
|
||||||
|
|
||||||
var horizScroll = this.$hScrollBarAlwaysVisible || this.$size.scrollerWidth - longestLine < 0;
|
var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible ||
|
||||||
var horizScrollChanged = this.$horizScroll !== horizScroll;
|
this.$size.scrollerWidth - longestLine - 2 * this.$padding < 0);
|
||||||
this.$horizScroll = horizScroll;
|
|
||||||
if (horizScrollChanged) {
|
var hScrollChanged = this.$horizScroll !== horizScroll;
|
||||||
this.scroller.style.overflowX = horizScroll ? "scroll" : "hidden";
|
if (hScrollChanged) {
|
||||||
// when we hide scrollbar scroll event isn't emited
|
this.$horizScroll = horizScroll;
|
||||||
// leaving session with wrong scrollLeft value
|
this.scrollBarH.setVisible(horizScroll);
|
||||||
if (!horizScroll)
|
|
||||||
this.session.setScrollLeft(0);
|
|
||||||
}
|
}
|
||||||
var maxHeight = this.session.getScreenLength() * this.lineHeight;
|
|
||||||
this.session.setScrollTop(Math.max(0, Math.min(this.scrollTop, maxHeight - this.$size.scrollerHeight)));
|
var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible ||
|
||||||
|
this.$size.scrollerHeight - maxHeight < 0);
|
||||||
|
var vScrollChanged = this.$vScroll !== vScroll;
|
||||||
|
if (vScrollChanged) {
|
||||||
|
this.$vScroll = vScroll;
|
||||||
|
this.scrollBarV.setVisible(vScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.session.setScrollTop(Math.max(-this.scrollMargin.top,
|
||||||
|
Math.min(this.scrollTop, maxHeight - this.$size.scrollerHeight + this.scrollMargin.v)));
|
||||||
|
|
||||||
|
this.session.setScrollLeft(Math.max(-this.scrollMargin.left, Math.min(this.scrollLeft,
|
||||||
|
longestLine + 2 * this.$padding - this.$size.scrollerWidth + this.scrollMargin.h)));
|
||||||
|
|
||||||
var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;
|
var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;
|
||||||
var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
|
var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
|
||||||
|
|
@ -812,8 +919,10 @@ var VirtualRenderer = function(container, theme) {
|
||||||
|
|
||||||
// Horizontal scrollbar visibility may have changed, which changes
|
// Horizontal scrollbar visibility may have changed, which changes
|
||||||
// the client height of the scroller
|
// the client height of the scroller
|
||||||
if (horizScrollChanged)
|
if (hScrollChanged || vScrollChanged) {
|
||||||
this.onResize(true);
|
this.onResize(true);
|
||||||
|
this._signal("scrollbarVisibilityChanged");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$updateLines = function() {
|
this.$updateLines = function() {
|
||||||
|
|
@ -949,6 +1058,10 @@ var VirtualRenderer = function(container, theme) {
|
||||||
if (this.scrollTop > top) {
|
if (this.scrollTop > top) {
|
||||||
if (offset)
|
if (offset)
|
||||||
top -= offset * this.$size.scrollerHeight;
|
top -= offset * this.$size.scrollerHeight;
|
||||||
|
if (top == 0)
|
||||||
|
top = - this.scrollMargin.top;
|
||||||
|
else if (top == 0)
|
||||||
|
top = + this.scrollMargin.bottom;
|
||||||
this.session.setScrollTop(top);
|
this.session.setScrollTop(top);
|
||||||
} else if (this.scrollTop + this.$size.scrollerHeight < top + this.lineHeight) {
|
} else if (this.scrollTop + this.$size.scrollerHeight < top + this.lineHeight) {
|
||||||
if (offset)
|
if (offset)
|
||||||
|
|
@ -960,10 +1073,12 @@ var VirtualRenderer = function(container, theme) {
|
||||||
|
|
||||||
if (scrollLeft > left) {
|
if (scrollLeft > left) {
|
||||||
if (left < this.$padding + 2 * this.layerConfig.characterWidth)
|
if (left < this.$padding + 2 * this.layerConfig.characterWidth)
|
||||||
left = 0;
|
left = -this.scrollMargin.left;
|
||||||
this.session.setScrollLeft(left);
|
this.session.setScrollLeft(left);
|
||||||
} else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
|
} else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
|
||||||
this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
|
this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
|
||||||
|
} else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) {
|
||||||
|
this.session.setScrollLeft(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1116,9 +1231,6 @@ var VirtualRenderer = function(container, theme) {
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
**/
|
**/
|
||||||
this.scrollToX = function(scrollLeft) {
|
this.scrollToX = function(scrollLeft) {
|
||||||
if (scrollLeft < 0)
|
|
||||||
scrollLeft = 0;
|
|
||||||
|
|
||||||
if (this.scrollLeft !== scrollLeft)
|
if (this.scrollLeft !== scrollLeft)
|
||||||
this.scrollLeft = scrollLeft;
|
this.scrollLeft = scrollLeft;
|
||||||
this.$loop.schedule(this.CHANGE_H_SCROLL);
|
this.$loop.schedule(this.CHANGE_H_SCROLL);
|
||||||
|
|
@ -1145,9 +1257,10 @@ var VirtualRenderer = function(container, theme) {
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
**/
|
**/
|
||||||
this.isScrollableBy = function(deltaX, deltaY) {
|
this.isScrollableBy = function(deltaX, deltaY) {
|
||||||
if (deltaY < 0 && this.session.getScrollTop() >= 1)
|
if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top)
|
||||||
return true;
|
return true;
|
||||||
if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight - this.layerConfig.maxHeight < -1)
|
if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight
|
||||||
|
- this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom)
|
||||||
return true;
|
return true;
|
||||||
// todo: handle horizontal scrolling
|
// todo: handle horizontal scrolling
|
||||||
};
|
};
|
||||||
|
|
@ -1422,13 +1535,19 @@ config.defineOptions(VirtualRenderer.prototype, "renderer", {
|
||||||
value: true
|
value: true
|
||||||
},
|
},
|
||||||
hScrollBarAlwaysVisible: {
|
hScrollBarAlwaysVisible: {
|
||||||
set: function(alwaysVisible) {
|
set: function(val) {
|
||||||
this.$hScrollBarAlwaysVisible = alwaysVisible;
|
|
||||||
if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll)
|
if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll)
|
||||||
this.$loop.schedule(this.CHANGE_SCROLL);
|
this.$loop.schedule(this.CHANGE_SCROLL);
|
||||||
},
|
},
|
||||||
initialValue: false
|
initialValue: false
|
||||||
},
|
},
|
||||||
|
vScrollBarAlwaysVisible: {
|
||||||
|
set: function(val) {
|
||||||
|
if (!this.$vScrollBarAlwaysVisible || !this.$vScroll)
|
||||||
|
this.$loop.schedule(this.CHANGE_SCROLL);
|
||||||
|
},
|
||||||
|
initialValue: false
|
||||||
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
set: function(size) {
|
set: function(size) {
|
||||||
if (typeof size == "number")
|
if (typeof size == "number")
|
||||||
|
|
@ -1443,6 +1562,16 @@ config.defineOptions(VirtualRenderer.prototype, "renderer", {
|
||||||
this.container.style.fontFamily = name;
|
this.container.style.fontFamily = name;
|
||||||
this.updateFontSize();
|
this.updateFontSize();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
maxLines: {
|
||||||
|
set: function(val) {
|
||||||
|
this.updateFull();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
minLines: {
|
||||||
|
set: function(name) {
|
||||||
|
this.updateFull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue