diff --git a/demo/scrollable-page.html b/demo/scrollable-page.html index f96c0876..dfc48eba 100644 --- a/demo/scrollable-page.html +++ b/demo/scrollable-page.html @@ -88,6 +88,7 @@ require("ace/commands/default_commands").commands.push({ exec: function(editor) { dom.toggleCssClass(document.body, "fullScreen") dom.toggleCssClass(editor.container, "fullScreen") + editor.setAutoScrollEditorIntoView() editor.resize() } }) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 0bffed53..0dd7f721 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -2110,29 +2110,37 @@ var Editor = function(renderer, session) { this.renderer.destroy(); }; - this.setAutoScrollEditorIntoView = function() { - var self = this; + /** + * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element + * @param {Boolean} enable default true + **/ + this.setAutoScrollEditorIntoView = function(enable) { + if (enable === true) + return; var rect; + var self = this; var shouldScroll = false; - var scrollAnchor = dom.createElement("div"); + if (!this.$scrollAnchor) + this.$scrollAnchor = document.createElement("div"); + var scrollAnchor = this.$scrollAnchor; scrollAnchor.style.cssText = "position:absolute"; this.container.insertBefore(scrollAnchor, this.container.firstChild); - this.on("changeSelection", function() { + var onChangeSelection = this.on("changeSelection", function() { shouldScroll = true; }); // needed to not trigger sync reflow - this.renderer.on("beforeRender", function() { + var onBeforeRender = this.renderer.on("beforeRender", function() { if (shouldScroll) - rect = self.renderer.container.getBoundingClientRect() + rect = self.renderer.container.getBoundingClientRect(); }); - this.renderer.on("afterRender", function() { + var onAfterRender = 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 + shouldScroll = true; } else if (pos.top < config.height && pos.top + rect.top + config.lineHeight > window.innerHeight) { shouldScroll = false; @@ -2144,11 +2152,18 @@ var Editor = function(renderer, session) { scrollAnchor.style.left = pos.left + "px"; scrollAnchor.style.height = config.lineHeight + "px"; scrollAnchor.scrollIntoView(shouldScroll); - } shouldScroll = rect = null; } }); + this.setAutoScrollEditorIntoView = function(enable) { + if (enable === false) + return; + delete this.setAutoScrollEditorIntoView; + this.removeEventListener("changeSelection", onChangeSelection); + this.renderer.removeEventListener("afterRender", onAfterRender); + this.renderer.removeEventListener("beforeRender", onBeforeRender); + }; }; }).call(Editor.prototype); diff --git a/lib/ace/lib/event_emitter.js b/lib/ace/lib/event_emitter.js index e572df5e..a359a9a7 100644 --- a/lib/ace/lib/event_emitter.js +++ b/lib/ace/lib/event_emitter.js @@ -106,6 +106,7 @@ EventEmitter.addEventListener = function(eventName, callback, capturing) { if (listeners.indexOf(callback) == -1) listeners[capturing ? "unshift" : "push"](callback); + return callback; }; EventEmitter.removeListener =