Skip to content

Commit 51d5e4d

Browse files
committed
feat: add ResizeObserver to make calling editor.resize optional
1 parent a2e89b9 commit 51d5e4d

File tree

6 files changed

+95
-11
lines changed

6 files changed

+95
-11
lines changed

doc/site/js/main.js

-6
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,6 @@ $(function() {
153153
$.bbq.pushState(state);
154154
});
155155

156-
$('#tabnav a[data-toggle="tab"]').on('shown', function (e) {
157-
$(".tab-content .tab-pane.active .ace_editor").each(function(i, el){
158-
el.env.onResize();
159-
});
160-
});
161-
162156
$(window).on("hashchange", function(e) {
163157
_gaq.push(['_trackPageview',location.pathname + location.search + location.hash]);
164158
tabs.each(function() {

doc/site/style.css

+3-1
Original file line numberDiff line numberDiff line change
@@ -496,4 +496,6 @@ img {
496496

497497
.nav>li>a.external-nav:hover {
498498
text-decoration: underline;
499-
}
499+
}
500+
501+
pre { background-color: white!important }

src/ace.js

-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
"include loader_build";
99

1010
var dom = require("./lib/dom");
11-
var event = require("./lib/event");
1211

1312
var Range = require("./range").Range;
1413
var Editor = require("./editor").Editor;
@@ -66,9 +65,7 @@ exports.edit = function(el, options) {
6665
onResize: editor.resize.bind(editor, null)
6766
};
6867
if (oldNode) env.textarea = oldNode;
69-
event.addListener(window, "resize", env.onResize);
7068
editor.on("destroy", function() {
71-
event.removeListener(window, "resize", env.onResize);
7269
env.editor.container.env = null; // prevent memory leak on old ie
7370
});
7471
editor.container.env = editor.env = env;

src/ace_test.js

+55-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
if (typeof process !== "undefined") {
2-
require("amd-loader");
32
require("./test/mockdom");
43
}
54

@@ -102,6 +101,61 @@ module.exports = {
102101
ace.config.set("useStrictCSP", false);
103102
assert.ok(getStyleNode());
104103
},
104+
"test: resizeObserver": function(done) {
105+
var mockObserver = {
106+
disconnect: function() { mockObserver.target = null; },
107+
observe: function(el) {
108+
mockObserver.target = el;
109+
},
110+
$create: function(fn) {
111+
mockObserver.callback = fn;
112+
return mockObserver;
113+
},
114+
call: function() {
115+
setTimeout(function() {
116+
if (mockObserver.target)
117+
mockObserver.callback([{contentRect: mockObserver.target.getBoundingClientRect()}]);
118+
});
119+
}
120+
};
121+
if (!window.ResizeObserver) {
122+
window.ResizeObserver = mockObserver.$create;
123+
}
124+
var editor = ace.edit(null);
125+
document.body.appendChild(editor.container);
126+
editor.container.style.width = "100px";
127+
editor.container.style.height = "100px";
128+
mockObserver.call();
129+
editor.resize(true);
130+
assert.ok(!editor.renderer.$resizeTimer.isPending());
131+
assert.equal(editor.renderer.$size.width, 100);
132+
editor.container.style.width = "200px";
133+
mockObserver.call();
134+
setTimeout(function() {
135+
if (editor.renderer.$resizeTimer.isPending())
136+
editor.renderer.$resizeTimer.call();
137+
assert.equal(editor.renderer.$size.width, 200);
138+
editor.container.style.height = "200px";
139+
mockObserver.call();
140+
setTimeout(function() {
141+
assert.ok(editor.renderer.$resizeTimer.isPending());
142+
editor.container.style.height = "100px";
143+
mockObserver.call();
144+
setTimeout(function() {
145+
assert.ok(!editor.renderer.$resizeTimer.isPending());
146+
editor.setOption("useResizeObserver", false);
147+
editor.container.style.height = "300px";
148+
mockObserver.call();
149+
assert.ok(!editor.renderer.$resizeObserver);
150+
editor.setOption("useResizeObserver", true);
151+
assert.ok(editor.renderer.$resizeObserver);
152+
if (window.ResizeObserver === mockObserver.$create)
153+
window.ResizeObserver = undefined;
154+
done();
155+
}, 15);
156+
}, 15);
157+
}, 15);
158+
},
105159
"test: edit template" : function() {
106160
var template = document.createElement("template");
107161
var div = document.createElement("div");

src/editor.js

+1
Original file line numberDiff line numberDiff line change
@@ -2897,6 +2897,7 @@ config.defineOptions(Editor.prototype, "editor", {
28972897
hasCssTransforms: "renderer",
28982898
maxPixelHeight: "renderer",
28992899
useTextareaForIME: "renderer",
2900+
useResizeObserver: "renderer",
29002901

29012902
scrollSpeed: "$mouseHandler",
29022903
dragDelay: "$mouseHandler",

src/virtual_renderer.js

+36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
var oop = require("./lib/oop");
44
var dom = require("./lib/dom");
5+
var lang = require("./lib/lang");
56
var config = require("./config");
67
var GutterLayer = require("./layer/gutter").Gutter;
78
var MarkerLayer = require("./layer/marker").Marker;
@@ -157,6 +158,7 @@ var VirtualRenderer = function(container, theme) {
157158

158159
this.updateCharacterSize();
159160
this.setPadding(4);
161+
this.$addResizeObserver();
160162
config.resetOptions(this);
161163
config._signal("renderer", this);
162164
};
@@ -344,6 +346,7 @@ var VirtualRenderer = function(container, theme) {
344346
width = el.clientWidth || el.scrollWidth;
345347
var changes = this.$updateCachedSize(force, gutterWidth, width, height);
346348

349+
if (this.$resizeTimer) this.$resizeTimer.cancel();
347350

348351
if (!this.$size.scrollerHeight || (!width && !height))
349352
return this.resizing = 0;
@@ -1799,6 +1802,7 @@ var VirtualRenderer = function(container, theme) {
17991802
this.$cursorLayer.destroy();
18001803
this.removeAllListeners();
18011804
this.container.textContent = "";
1805+
this.setOption("useResizeObserver", false);
18021806
};
18031807

18041808
this.$updateCustomScrollbar = function (val) {
@@ -1836,10 +1840,42 @@ var VirtualRenderer = function(container, theme) {
18361840
}
18371841
};
18381842

1843+
this.$addResizeObserver = function() {
1844+
if (!window.ResizeObserver || this.$resizeObserver) return;
1845+
var self = this;
1846+
this.$resizeTimer = lang.delayedCall(function() {
1847+
if (!self.destroyed) self.onResize();
1848+
}, 50);
1849+
this.$resizeObserver = new window.ResizeObserver(function(e) {
1850+
var w = e[0].contentRect.width;
1851+
var h = e[0].contentRect.height;
1852+
if (
1853+
Math.abs(self.$size.width - w) > 1
1854+
|| Math.abs(self.$size.height - h) > 1
1855+
) {
1856+
self.$resizeTimer.delay();
1857+
} else {
1858+
self.$resizeTimer.cancel();
1859+
}
1860+
});
1861+
this.$resizeObserver.observe(this.container);
1862+
};
1863+
18391864
}).call(VirtualRenderer.prototype);
18401865

18411866

18421867
config.defineOptions(VirtualRenderer.prototype, "renderer", {
1868+
useResizeObserver: {
1869+
set: function(value) {
1870+
if (!value && this.$resizeObserver) {
1871+
this.$resizeObserver.disconnect();
1872+
this.$resizeTimer.cancel();
1873+
this.$resizeTimer = this.$resizeObserver = null;
1874+
} else if (value && !this.$resizeObserver) {
1875+
this.$addResizeObserver();
1876+
}
1877+
}
1878+
},
18431879
animatedScroll: {initialValue: false},
18441880
showInvisibles: {
18451881
set: function(value) {

0 commit comments

Comments
 (0)