Skip to content

Commit 9c19820

Browse files
authored
Merge pull request #5 from sateffen/develop
v1.0.1
2 parents b7216a5 + b5202c1 commit 9c19820

File tree

6 files changed

+219
-176
lines changed

6 files changed

+219
-176
lines changed

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "poc-scrollbar",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "A simple scrollbar, that just works",
55
"homepage": "https://github.com/sateffen/poc-scrollbar",
66
"bugs": "https://github.com/sateffen/poc-scrollbar/issues",
@@ -23,16 +23,16 @@
2323
},
2424
"license": "MIT",
2525
"devDependencies": {
26-
"eslint": "~3.12.2",
27-
"eslint-config-airbnb-base": "~11.0.0",
26+
"eslint": "~3.14.0",
27+
"eslint-config-airbnb-base": "~11.0.1",
2828
"eslint-plugin-import": "~2.2.0",
2929
"jasmine-core": "~2.5.2",
30-
"karma": "~1.3.0",
30+
"karma": "~1.4.0",
3131
"karma-chrome-launcher": "~2.0.0",
3232
"karma-jasmine": "~1.1.0",
3333
"karma-rollup-plugin": "~0.2.4",
34-
"rollup": "~0.38.0",
34+
"rollup": "~0.41.4",
3535
"rollup-plugin-buble": "~0.15.0",
36-
"rollup-watch": "~2.5.0"
36+
"rollup-watch": "~3.2.2"
3737
}
3838
}

rollup.config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
/* global require, module*/
22
const buble = require('rollup-plugin-buble');
3+
const pkg = require('./package.json');
34

45
module.exports = {
56
entry: 'src/pocscrollbar.js',
67
format: 'umd',
8+
banner: `/* Name: ${pkg.name}, Version: ${pkg.version}, License: ${pkg.license}*/`,
79
moduleName: 'PocScrollbar',
810
dest: 'dist/pocscrollbar.js',
911
plugins: [

src/helper.js

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11

2+
/**
3+
* This constant is one possible option for the deltaMode property of a wheel event.
4+
* This deltaMode measures the delta values in pixels.
5+
*
6+
* @type {number}
7+
*/
8+
const DOM_DELTA_PIXEL = (window.WheelEvent && window.WheelEvent.DOM_DELTA_PIXEL) || 0x00;
9+
10+
/**
11+
* This constant is one possible option for the deltaMode property of a wheel event.
12+
* This deltaMode measures the delta values in lines.
13+
*
14+
* @type {number}
15+
*/
16+
const DOM_DELTA_LINE = (window.WheelEvent && window.WheelEvent.DOM_DELTA_LINE) || 0x01;
17+
18+
/**
19+
* This constant is one possible option for the deltaMode property of a wheel event.
20+
* This deltaMode measures the delta values in pages.
21+
*
22+
* @type {number}
23+
*/
24+
const DOM_DELTA_PAGE = (window.WheelEvent && window.WheelEvent.DOM_DELTA_PAGE) || 0x02;
25+
226
/**
327
* This constant tells the browsers line height for one line. This is used for calculating the distance
428
* to scroll in a wheel event
@@ -47,15 +71,21 @@ export function applyOptionsToScrollBarElement(aElement, aElementName, aOptions)
4771
*
4872
* @param {Function} aCallback The callback to call debounced
4973
* @param {number} aWaitTime The time to wait till calling the callback
50-
* @return {Function} The replacement function
74+
* @return {Array.<Function>} An array with two functions. The first is the debounced callback,
75+
* the second is a destroy callback
5176
*/
5277
export function debounce(aCallback, aWaitTime) {
5378
let pointer = null;
5479

55-
return () => {
56-
window.clearTimeout(pointer);
57-
pointer = window.setTimeout(aCallback, aWaitTime);
58-
};
80+
return [
81+
() => {
82+
window.clearTimeout(pointer);
83+
pointer = window.setTimeout(aCallback, aWaitTime);
84+
},
85+
() => {
86+
window.clearTimeout(pointer);
87+
}
88+
];
5989
}
6090

6191
/**
@@ -74,10 +104,11 @@ export function getWheelDeltaAsPixel(aIsX, aDeltaOption, aDeltaMode, aDeltaValue
74104
}
75105

76106
switch (aDeltaMode) {
77-
case 1:
107+
case DOM_DELTA_LINE:
78108
return aDeltaValue * browsersLineHeight;
79-
case 2:
109+
case DOM_DELTA_PAGE:
80110
return aDeltaValue * (aIsX ? aScrollContainer.clientWidth : aScrollContainer.clientHeight);
111+
case DOM_DELTA_PIXEL:
81112
default:
82113
return aDeltaValue;
83114
}

src/pocscrollbar.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export default class PocScrollbar {
7373

7474
// and then we setup the corresponding mutation handler and its destroy callback
7575
if (this._options.useMutationObserver) {
76-
const debouncedMutationHandler = debounce(mutationHandler, checkInterval);
76+
const [debouncedMutationHandler, destroyCallback] = debounce(mutationHandler, checkInterval);
7777
const mutationObserver = new MutationObserver(debouncedMutationHandler);
7878

7979
window.addEventListener('resize', debouncedMutationHandler);
@@ -82,6 +82,7 @@ export default class PocScrollbar {
8282
});
8383

8484
this._destroyCallbacks.push(() => {
85+
destroyCallback();
8586
mutationObserver.disconnect();
8687
window.removeEventListener('resize', debouncedMutationHandler);
8788
});
@@ -237,6 +238,11 @@ export default class PocScrollbar {
237238

238239
// then return the closure function
239240
return () => {
241+
// if the container doesn't exist anymore, we can't do anything
242+
if (this._container === null) {
243+
return;
244+
}
245+
240246
// search for the root element of this element
241247
let potentialRootElement = this._container.parentElement;
242248
while (potentialRootElement !== null &&

test/unit/helper.spec.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@ describe('Helper functions', () => {
3434
expect(typeof debounce).toBe('function');
3535
});
3636

37-
it('should return a function', () => {
38-
expect(typeof debounce()).toBe('function');
37+
it('should return an array with two functions', () => {
38+
const returnValue = debounce();
39+
40+
expect(Array.isArray(returnValue)).toBe(true);
41+
expect(returnValue.length).toBe(2);
42+
expect(typeof returnValue[0]).toBe('function');
43+
expect(typeof returnValue[1]).toBe('function');
3944
});
4045

4146
it('should not call clearTimeout initially', () => {
@@ -49,25 +54,32 @@ describe('Helper functions', () => {
4954
});
5055

5156
it('should call clearTimeout with null on first call', () => {
52-
debounce()();
57+
debounce()[0]();
5358
expect(window.clearTimeout).toHaveBeenCalledTimes(1);
5459
expect(window.clearTimeout).toHaveBeenCalledWith(null);
5560
});
5661

5762
it('should call clearTimeout with the returned setTimeout pointer from prev call at second call', () => {
58-
const callback = debounce();
63+
const [callback] = debounce();
5964
callback();
6065
callback();
6166

6267
expect(window.clearTimeout).toHaveBeenCalledTimes(2);
6368
expect(window.clearTimeout.calls.mostRecent().args[0]).toBe(setTimeoutReturnValue);
6469
});
6570

71+
it('should have called clearTimeout when calling the destroyCallback', () => {
72+
debounce()[1]();
73+
expect(window.clearTimeout).toHaveBeenCalledTimes(1);
74+
expect(window.clearTimeout).toHaveBeenCalledWith(null);
75+
});
76+
6677
it('should call setTimeout with a function as first argument and the given time as second argument', () => {
6778
const spyCallback = jasmine.createSpy('spyCallback');
6879
const waitTime = Math.round(Math.random() * 100);
69-
debounce(spyCallback, waitTime)();
80+
debounce(spyCallback, waitTime)[0]();
7081

82+
expect(window.setTimeout).toHaveBeenCalledTimes(1);
7183
expect(window.setTimeout).toHaveBeenCalledWith(spyCallback, waitTime);
7284
});
7385
});

0 commit comments

Comments
 (0)