From bd6dda68f0544f86d9af10a386a7f8ae377d90d1 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 5 Feb 2013 00:28:13 +0400 Subject: [PATCH] Issue #1232: Scroll editor into browser view on cursor movement --- demo/scrollable-page.html | 4 +++- lib/ace/editor.js | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/demo/scrollable-page.html b/demo/scrollable-page.html index 308208ed..f96c0876 100644 --- a/demo/scrollable-page.html +++ b/demo/scrollable-page.html @@ -96,7 +96,7 @@ require("ace/commands/default_commands").commands.push({ var editor = ace.edit("editor"); editor.setTheme("ace/theme/twilight"); editor.session.setMode("ace/mode/javascript"); - +editor.setAutoScrollEditorIntoView(); var count = 1; function add() { @@ -113,6 +113,8 @@ function add() { editor = ace.edit(el) editor.setTheme(theme) editor.session.setMode("ace/mode/javascript") + + editor.setAutoScrollEditorIntoView() editor.setValue([ "this is editor number: ", count, "\n", diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 93dfd537..0bffed53 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -2109,6 +2109,47 @@ var Editor = function(renderer, session) { this.destroy = function() { this.renderer.destroy(); }; + + this.setAutoScrollEditorIntoView = function() { + var self = this; + var rect; + var shouldScroll = false; + var scrollAnchor = dom.createElement("div"); + scrollAnchor.style.cssText = "position:absolute"; + this.container.insertBefore(scrollAnchor, this.container.firstChild); + this.on("changeSelection", function() { + shouldScroll = true; + }); + // needed to not trigger sync reflow + this.renderer.on("beforeRender", function() { + if (shouldScroll) + rect = self.renderer.container.getBoundingClientRect() + }); + this.renderer.on("afterRender", function() { + if (shouldScroll && rect && self.isFocused()) { + var renderer = self.renderer; + var pos = renderer.$cursorLayer.$pixelPos; + var config = renderer.layerConfig; + var top = pos.top - config.offset; + if (pos.top >= 0 && top + rect.top < 0) { + shouldScroll = true + } else if (pos.top < config.height && + pos.top + rect.top + config.lineHeight > window.innerHeight) { + shouldScroll = false; + } else { + shouldScroll = null; + } + if (shouldScroll != null) { + scrollAnchor.style.top = top + "px"; + scrollAnchor.style.left = pos.left + "px"; + scrollAnchor.style.height = config.lineHeight + "px"; + scrollAnchor.scrollIntoView(shouldScroll); + + } + shouldScroll = rect = null; + } + }); + }; }).call(Editor.prototype);