Skip to content

Commit bce709d

Browse files
committed
Refactor $size event behavior
- Replace interval-based size update with a ResizeObserver instance - Use the body element to measure size, to avoid issues that come with using the document element - Add "overflow:scroll" to the View widget content holder element
1 parent 18cdb1b commit bce709d

File tree

5 files changed

+49
-41
lines changed

5 files changed

+49
-41
lines changed

components/src/core/injector/core/Core.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,4 @@ export default class {
2121

2222
if (has('*', this.watchers)) this.watchers['*'].forEach(call);
2323
}
24-
25-
size() {
26-
return {
27-
height: Math.max(document.documentElement.offsetHeight, document.documentElement.scrollHeight),
28-
width: Math.max(document.documentElement.offsetWidth, document.documentElement.scrollWidth),
29-
};
30-
}
3124
}

components/src/core/injector/core/Core.spec.js

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,4 @@ describe('Core', () => {
8282
expect(core.watchers['*'][0]).toHaveBeenCalled();
8383
});
8484
});
85-
86-
describe('#size', () => {
87-
it('should return document size in proper format', () => {
88-
jest.spyOn(global.document.documentElement, 'scrollHeight', 'get').mockReturnValue(100)
89-
jest.spyOn(global.document.documentElement, 'scrollWidth', 'get').mockReturnValue(300)
90-
jest.spyOn(global.document.documentElement, 'offsetHeight', 'get').mockReturnValue(200)
91-
jest.spyOn(global.document.documentElement, 'offsetWidth', 'get').mockReturnValue(200)
92-
93-
expect(core.size()).toEqual({
94-
width: 300,
95-
height: 200,
96-
});
97-
});
98-
});
99-
});
85+
});

components/src/core/injector/core/launcher.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ export default (injector, core, options = {}) => new Promise((resolve) => {
1010
core.state = data;
1111

1212
if (!options?.disableAutoResizing) {
13-
injector.emit('$size', core.size());
14-
setInterval(() => injector.emit('$size', core.size()), 300);
13+
const resizeObserver = new ResizeObserver((entries) => {
14+
const [{ contentRect }] = entries;
15+
injector.emit('$size', { height: contentRect.height, width: contentRect.width });
16+
});
17+
18+
resizeObserver.observe(document.body);
1519
}
1620

1721
resolve();
@@ -20,7 +24,10 @@ export default (injector, core, options = {}) => new Promise((resolve) => {
2024
window.addEventListener('$injector', ({ detail }) => {
2125
let { type, data } = detail;
2226

23-
if (type === '$size') data = core.size();
27+
if (type === '$size') {
28+
const { height, width } = document.body.getBoundingClientRect();
29+
data = { height, width };
30+
}
2431

2532
injector.emit(type, data);
2633
});

components/src/core/injector/core/launcher.spec.js

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
import launch from './launcher';
22

33

4+
const resizeObserverCtorSpy = jest.fn();
5+
const resizeObserverObserveSpy = jest.fn();
6+
const resizeObserverEntriesStub = [
7+
{
8+
contentRect: {
9+
height: 400,
10+
width: 800,
11+
},
12+
},
13+
];
14+
const ResizeObserverMock = function ResizeObserverMock(callback) {
15+
resizeObserverCtorSpy(callback);
16+
17+
callback(resizeObserverEntriesStub);
18+
19+
return {
20+
observe: resizeObserverObserveSpy,
21+
};
22+
};
23+
Object.defineProperty(global, 'ResizeObserver', {
24+
writable: true,
25+
value: ResizeObserverMock,
26+
});
27+
428
describe('$init', () => {
529
let injector;
630
let core;
@@ -9,7 +33,6 @@ describe('$init', () => {
933
beforeEach(() => {
1034
global.window.addEventListener = jest.fn();
1135
global.window.name = 'XXX';
12-
global.setInterval = jest.fn();
1336
global.crypto = {
1437
getRandomValues: jest.fn(() => ['abc']),
1538
};
@@ -57,27 +80,22 @@ describe('$init', () => {
5780
it('should emit "$size" event', () => {
5881
handler({}, {});
5982

60-
expect(injector.emit.mock.calls[2]).toEqual(['$size', 'SIZE']);
61-
});
62-
63-
it('should get sizes from $size method', () => {
64-
handler({}, {});
65-
66-
expect(core.size).toHaveBeenCalled();
83+
expect(injector.emit.mock.calls[2]).toEqual(['$size', {
84+
height: 400,
85+
width: 800,
86+
}]);
6787
});
6888

69-
it('should set interval', () => {
89+
it('should create a ResizeObserver instance', () => {
7090
handler({}, {});
7191

72-
expect(setInterval).toHaveBeenCalledWith(expect.any(Function), 300);
92+
expect(resizeObserverCtorSpy).toHaveBeenCalledWith(expect.any(Function));
7393
});
7494

75-
it('should set interval for sizing', () => {
95+
it('should call the resize observer\'s observe method with the document body', () => {
7696
handler({}, {});
77-
injector.emit.mock.calls = [];
78-
setInterval.mock.calls[0][0]();
7997

80-
expect(injector.emit).toHaveBeenCalledWith('$size', 'SIZE');
98+
expect(resizeObserverObserveSpy).toHaveBeenCalledWith(document.body);
8199
});
82100
});
83101

@@ -104,7 +122,10 @@ describe('$init', () => {
104122
it('should fill size for $size type', () => {
105123
handler({ detail: { type: '$size' } });
106124

107-
expect(injector.emit.mock.calls[2]).toEqual(['$size', 'SIZE']);
125+
expect(injector.emit.mock.calls[2]).toEqual(['$size', {
126+
height: 0,
127+
width: 0,
128+
}]);
108129
});
109130
});
110131

@@ -170,4 +191,4 @@ describe('$init', () => {
170191
expect(injector.emit).toHaveBeenCalledWith('$mounted');
171192
});
172193
});
173-
});
194+
});

components/src/widgets/view/widget.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ export default {
149149
&__content-holder {
150150
position: relative;
151151
grid-area: c;
152+
overflow: scroll;
152153
}
153154
154155
&__content {

0 commit comments

Comments
 (0)