From 0db985a3d79377b4ea197382364ea6870166faa8 Mon Sep 17 00:00:00 2001 From: nightwing Date: Fri, 15 May 2015 01:53:19 +0400 Subject: [PATCH 1/4] fix #2495 editor freezes when setting scrollmargin and maxLines together --- lib/ace/virtual_renderer.js | 11 +++++---- lib/ace/virtual_renderer_test.js | 42 +++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 5696745c..27da0dcb 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -968,14 +968,15 @@ var VirtualRenderer = function(container, theme) { : 0; maxHeight += scrollPastEnd; - this.session.setScrollTop(Math.max(-this.scrollMargin.top, - Math.min(this.scrollTop, maxHeight - size.scrollerHeight + this.scrollMargin.bottom))); + var sm = this.scrollMargin; + this.session.setScrollTop(Math.max(-sm.top, + Math.min(this.scrollTop, maxHeight - size.scrollerHeight + sm.bottom))); - this.session.setScrollLeft(Math.max(-this.scrollMargin.left, Math.min(this.scrollLeft, - longestLine + 2 * this.$padding - size.scrollerWidth + this.scrollMargin.right))); + this.session.setScrollLeft(Math.max(-sm.left, Math.min(this.scrollLeft, + longestLine + 2 * this.$padding - size.scrollerWidth + sm.right))); var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible || - size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop); + size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop > sm.top); var vScrollChanged = this.$vScroll !== vScroll; if (vScrollChanged) { this.$vScroll = vScroll; diff --git a/lib/ace/virtual_renderer_test.js b/lib/ace/virtual_renderer_test.js index e8a8fcbd..104c46c0 100644 --- a/lib/ace/virtual_renderer_test.js +++ b/lib/ace/virtual_renderer_test.js @@ -36,26 +36,40 @@ if (typeof process !== "undefined") { define(function(require, exports, module) { "use strict"; +var Editor = require("./edit_session").Editor; var EditSession = require("./edit_session").EditSession; var VirtualRenderer = require("./virtual_renderer").VirtualRenderer; var assert = require("./test/assertions"); +var editor = null; module.exports = { - "test: screen2text the column should be rounded to the next character edge" : function() { + setUp: function() { + if (editor) + editor.destroy() var el = document.createElement("div"); - if (!el.getBoundingClientRect) { console.log("Skipping test: This test only runs in the browser"); return; } - el.style.left = "20px"; el.style.top = "30px"; el.style.width = "300px"; el.style.height = "100px"; document.body.appendChild(el); - var renderer = new VirtualRenderer(el); + var editor = new Editor(renderer); + editor.on("destroy", function() { + document.body.removeChild(el); + }); + }, + tearDown: function() { + editor && editor.destroy(); + editor = null; + }, + "test: screen2text the column should be rounded to the next character edge" : function() { + if (!editor) return; + var renderer = editor.renderer; + renderer.setPadding(0); renderer.setSession(new EditSession("1234")); @@ -72,8 +86,24 @@ module.exports = { testPixelToText(9, 0, 0, 1); testPixelToText(10, 0, 0, 1); testPixelToText(14, 0, 0, 1); - testPixelToText(15, 0, 0, 2); - document.body.removeChild(el); + testPixelToText(15, 0, 0, 2); + }, + + "test scrollmargin + autosize": function(done) { + var editor = initAce(); + if (!editor) return; + editor.setOptions({ + maxLines: 100, + useWrapMode: true + }); + editor.renderer.setScrollMargin(10, 10); + editor.setValue("\n\n"); + editor.setValue("\n\n\n\n"); + editor.renderer.once("afterRender", function() { + setTimeout(function() { + done(); + }, 0); + }); } // change tab size after setDocument (for text layer) From 93c39ca5b02e1df83c105e6b97b4319f0b245ede Mon Sep 17 00:00:00 2001 From: nightwing Date: Fri, 15 May 2015 02:43:41 +0400 Subject: [PATCH 2/4] handle hscrollbar change during autoresize --- demo/autoresize.html | 13 +++++++++++-- lib/ace/virtual_renderer.js | 14 ++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/demo/autoresize.html b/demo/autoresize.html index 73a87599..ef4cbe04 100644 --- a/demo/autoresize.html +++ b/demo/autoresize.html @@ -7,14 +7,13 @@ @@ -24,6 +23,8 @@
minHeight = 2 lines
+

+

 
 
@@ -46,6 +47,14 @@ require(["ace/ace"], function(ace) {
     editor2.setOption("maxLines", 30);
     editor2.setOption("minLines", 2);
 
+    var editor = ace.edit("editor3");
+    editor.setOptions({
+        maxLines: 100,
+        autoScrollEditorIntoView: true,
+        maxLines: 8
+    });
+    editor.renderer.setScrollMargin(10, 10, 10, 10);
+    
     var editor = ace.edit("editor");
     editor.setTheme("ace/theme/tomorrow");
     editor.session.setMode("ace/mode/html");
diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js
index 27da0dcb..386bbf00 100644
--- a/lib/ace/virtual_renderer.js
+++ b/lib/ace/virtual_renderer.js
@@ -919,6 +919,8 @@ var VirtualRenderer = function(container, theme) {
             (this.$minLines||1) * this.lineHeight,
             Math.min(maxHeight, height)
         ) + this.scrollMargin.v + (this.$extraHeight || 0);
+        if (this.$horizScroll)
+            desiredHeight += this.scrollBarH.getHeight();
         var vScroll = height > maxHeight;
         
         if (desiredHeight != this.desiredHeight ||
@@ -939,9 +941,6 @@ var VirtualRenderer = function(container, theme) {
     };
     
     this.$computeLayerConfig = function() {
-        if (this.$maxLines && this.lineHeight > 1)
-            this.$autosize();
-
         var session = this.session;
         var size = this.$size;
         
@@ -949,9 +948,6 @@ var VirtualRenderer = function(container, theme) {
         var screenLines = this.session.getScreenLength();
         var maxHeight = screenLines * this.lineHeight;
 
-        var offset = this.scrollTop % this.lineHeight;
-        var minHeight = size.scrollerHeight + this.lineHeight;
-
         var longestLine = this.$getLongestLine();
         
         var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible ||
@@ -962,6 +958,12 @@ var VirtualRenderer = function(container, theme) {
             this.$horizScroll = horizScroll;
             this.scrollBarH.setVisible(horizScroll);
         }
+        // autoresize only after updating hscroll to include scrollbar height in desired height
+        if (this.$maxLines && this.lineHeight > 1)
+            this.$autosize();
+
+        var offset = this.scrollTop % this.lineHeight;
+        var minHeight = size.scrollerHeight + this.lineHeight;
         
         var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd
             ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd

From 9e9aa8f32852c54742630d6c8ffb5eeace93fc65 Mon Sep 17 00:00:00 2001
From: nightwing 
Date: Fri, 15 May 2015 02:44:24 +0400
Subject: [PATCH 3/4] use scroller as mousetarget to not miss mouse events on
 scrollmargin

---
 lib/ace/virtual_renderer.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js
index 386bbf00..45226a1d 100644
--- a/lib/ace/virtual_renderer.js
+++ b/lib/ace/virtual_renderer.js
@@ -615,7 +615,7 @@ var VirtualRenderer = function(container, theme) {
     * @returns {DOMElement}
     **/
     this.getMouseEventTarget = function() {
-        return this.content;
+        return this.scroller;
     };
 
     /**

From 88d8cf34476b8d261b733ff738d4bbcadc72b158 Mon Sep 17 00:00:00 2001
From: nightwing 
Date: Fri, 15 May 2015 02:48:03 +0400
Subject: [PATCH 4/4] fix renderer test

---
 lib/ace/virtual_renderer_test.js | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/ace/virtual_renderer_test.js b/lib/ace/virtual_renderer_test.js
index 104c46c0..9b1ed866 100644
--- a/lib/ace/virtual_renderer_test.js
+++ b/lib/ace/virtual_renderer_test.js
@@ -66,8 +66,8 @@ module.exports = {
         editor && editor.destroy();
         editor = null;
     },
-    "test: screen2text the column should be rounded to the next character edge" : function() {
-        if (!editor) return;
+    "test: screen2text the column should be rounded to the next character edge" : function(done) {
+        if (!editor) return done();
         var renderer = editor.renderer;
 
         renderer.setPadding(0);
@@ -86,12 +86,12 @@ module.exports = {
         testPixelToText(9, 0, 0, 1);
         testPixelToText(10, 0, 0, 1);
         testPixelToText(14, 0, 0, 1);
-        testPixelToText(15, 0, 0, 2);        
+        testPixelToText(15, 0, 0, 2);
+        done();
     },
     
     "test scrollmargin + autosize": function(done) {
-        var editor = initAce();
-        if (!editor) return;
+        if (!editor) return done();
         editor.setOptions({
             maxLines: 100,
             useWrapMode: true