Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor #165

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"error",
"unix"
],
"lines-around-comment": "error",
"lines-around-comment": ["error", { "allowBlockStart": true }],
"lines-around-directive": "error",
"max-depth": "error",
"max-len": "error",
Expand Down
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"singleQuote": true,
"arrowParens": "avoid",
"trailingComma": "none"
}
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"husky": "^0.14.3",
"lint-staged": "^6.0.1",
"lodash.clonedeep": "^4.5.0",
"prettier": "^1.10.2",
"prettier": "^2.1.2",
"rollup": "^0.50.0",
"uglify-js": "^3.1.1"
},
Expand Down Expand Up @@ -51,9 +51,6 @@
]
}
},
"prettier": {
"singleQuote": true
},
"repository": {
"type": "git",
"url": "git+https://github.com/iamdustan/smoothscroll.git"
Expand Down
118 changes: 75 additions & 43 deletions src/smoothscroll.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
'use strict';

// types
/**
* @typedef {'X'|'Y'} Axis
*/
/**
* @typedef StepContext
* @property {Window | Element} scrollable: scrollable,
* @property {(x: number, y: number) => void} method: method,
* @property {number} startTime: startTime,
* @property {number} startX: startX,
* @property {number} startY: startY,
* @property {number} x: x,
* @property {number} y: y
*/

// polyfill
function polyfill() {
// aliases
Expand Down Expand Up @@ -27,6 +42,7 @@ function polyfill() {
};

// define timing method
/** @type {() => number} */
var now =
w.performance && w.performance.now
? w.performance.now.bind(w.performance)
Expand All @@ -35,8 +51,8 @@ function polyfill() {
/**
* indicates if a the current browser is made by Microsoft
* @method isMicrosoftBrowser
* @param {String} userAgent
* @returns {Boolean}
* @param {string} userAgent
* @returns {boolean}
*/
function isMicrosoftBrowser(userAgent) {
var userAgentPatterns = ['MSIE ', 'Trident/', 'Edge/'];
Expand All @@ -54,9 +70,9 @@ function polyfill() {
/**
* changes scroll position inside an element
* @method scrollElement
* @param {Number} x
* @param {Number} y
* @returns {undefined}
* @param {number} x
* @param {number} y
* @returns {void}
*/
function scrollElement(x, y) {
this.scrollLeft = x;
Expand All @@ -66,8 +82,8 @@ function polyfill() {
/**
* returns result of applying ease math function to a number
* @method ease
* @param {Number} k
* @returns {Number}
* @param {number} k
* @returns {number}
*/
function ease(k) {
return 0.5 * (1 - Math.cos(Math.PI * k));
Expand All @@ -76,8 +92,8 @@ function polyfill() {
/**
* indicates if a smooth behavior should be applied
* @method shouldBailOut
* @param {Number|Object} firstArg
* @returns {Boolean}
* @param {number|object} firstArg
* @returns {boolean}
*/
function shouldBailOut(firstArg) {
if (
Expand Down Expand Up @@ -109,28 +125,30 @@ function polyfill() {
* indicates if an element has scrollable space in the provided axis
* @method hasScrollableSpace
* @param {Node} el
* @param {String} axis
* @returns {Boolean}
* @param {Axis} axis
* @returns {boolean}
*/
function hasScrollableSpace(el, axis) {
if (axis === 'Y') {
return el.clientHeight + ROUNDING_TOLERANCE < el.scrollHeight;
}

if (axis === 'X') {
return el.clientWidth + ROUNDING_TOLERANCE < el.scrollWidth;
switch (axis) {
case 'X':
return el.clientWidth + ROUNDING_TOLERANCE < el.scrollWidth;
case 'Y':
return el.clientHeight + ROUNDING_TOLERANCE < el.scrollHeight;
// no default
}
}

/**
* indicates if an element has a scrollable overflow property in the axis
* @method canOverflow
* @param {Node} el
* @param {String} axis
* @returns {Boolean}
* @param {Axis} axis
* @returns {boolean}
*/
function canOverflow(el, axis) {
var overflowValue = w.getComputedStyle(el, null)['overflow' + axis];
/** @type {'overflowY' | 'overflowX'} */
var overflowProperty = 'overflow' + axis;
var overflowValue = w.getComputedStyle(el, null)[overflowProperty];

return overflowValue === 'auto' || overflowValue === 'scroll';
}
Expand All @@ -139,8 +157,8 @@ function polyfill() {
* indicates if an element can be scrolled in either axis
* @method isScrollable
* @param {Node} el
* @param {String} axis
* @returns {Boolean}
* @param {Axis} axis
* @returns {boolean}
*/
function isScrollable(el) {
var isScrollableY = hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y');
Expand All @@ -152,8 +170,8 @@ function polyfill() {
/**
* finds scrollable parent of an element
* @method findScrollableParent
* @param {Node} el
* @returns {Node} el
* @param {Element} el
* @returns {Element} el
*/
function findScrollableParent(el) {
while (el !== d.body && isScrollable(el) === false) {
Expand All @@ -166,13 +184,19 @@ function polyfill() {
/**
* self invoked function that, given a context, steps through scrolling
* @method step
* @param {Object} context
* @returns {undefined}
* @param {StepContext} context
* @returns {void}
*/
function step(context) {
var time = now();

/** @type {number} */
var value;

/** @type {number} */
var currentX;

/** @type {number} */
var currentY;
var elapsed = (time - context.startTime) / SCROLL_TIME;

Expand All @@ -196,10 +220,10 @@ function polyfill() {
/**
* scrolls window or element with a smooth behavior
* @method smoothScroll
* @param {Object|Node} el
* @param {Number} x
* @param {Number} y
* @returns {undefined}
* @param {object|Node} el
* @param {number} x
* @param {number} y
* @returns {void}
*/
function smoothScroll(el, x, y) {
var scrollable;
Expand Down Expand Up @@ -235,7 +259,7 @@ function polyfill() {

// ORIGINAL METHODS OVERRIDES
// w.scroll and w.scrollTo
w.scroll = w.scrollTo = function() {
w.scroll = w.scrollTo = function () {
// avoid action when no arguments are passed
if (arguments[0] === undefined) {
return;
Expand All @@ -248,14 +272,14 @@ function polyfill() {
arguments[0].left !== undefined
? arguments[0].left
: typeof arguments[0] !== 'object'
? arguments[0]
: w.scrollX || w.pageXOffset,
? arguments[0]
: w.scrollX || w.pageXOffset,
// use top prop, second argument if present or fallback to scrollY
arguments[0].top !== undefined
? arguments[0].top
: arguments[1] !== undefined
? arguments[1]
: w.scrollY || w.pageYOffset
? arguments[1]
: w.scrollY || w.pageYOffset
);

return;
Expand All @@ -275,7 +299,7 @@ function polyfill() {
};

// w.scrollBy
w.scrollBy = function() {
w.scrollBy = function () {
// avoid action when no arguments are passed
if (arguments[0] === undefined) {
return;
Expand All @@ -287,10 +311,14 @@ function polyfill() {
w,
arguments[0].left !== undefined
? arguments[0].left
: typeof arguments[0] !== 'object' ? arguments[0] : 0,
: typeof arguments[0] !== 'object'
? arguments[0]
: 0,
arguments[0].top !== undefined
? arguments[0].top
: arguments[1] !== undefined ? arguments[1] : 0
: arguments[1] !== undefined
? arguments[1]
: 0
);

return;
Expand All @@ -306,7 +334,7 @@ function polyfill() {
};

// Element.prototype.scroll and Element.prototype.scrollTo
Element.prototype.scroll = Element.prototype.scrollTo = function() {
Element.prototype.scroll = Element.prototype.scrollTo = function () {
// avoid action when no arguments are passed
if (arguments[0] === undefined) {
return;
Expand All @@ -324,11 +352,15 @@ function polyfill() {
// use left prop, first number argument or fallback to scrollLeft
arguments[0].left !== undefined
? ~~arguments[0].left
: typeof arguments[0] !== 'object' ? ~~arguments[0] : this.scrollLeft,
: typeof arguments[0] !== 'object'
? ~~arguments[0]
: this.scrollLeft,
// use top prop, second argument or fallback to scrollTop
arguments[0].top !== undefined
? ~~arguments[0].top
: arguments[1] !== undefined ? ~~arguments[1] : this.scrollTop
: arguments[1] !== undefined
? ~~arguments[1]
: this.scrollTop
);

return;
Expand All @@ -347,7 +379,7 @@ function polyfill() {
};

// Element.prototype.scrollBy
Element.prototype.scrollBy = function() {
Element.prototype.scrollBy = function () {
// avoid action when no arguments are passed
if (arguments[0] === undefined) {
return;
Expand Down Expand Up @@ -376,7 +408,7 @@ function polyfill() {
};

// Element.prototype.scrollIntoView
Element.prototype.scrollIntoView = function() {
Element.prototype.scrollIntoView = function () {
// avoid smooth behavior if not required
if (shouldBailOut(arguments[0]) === true) {
original.scrollIntoView.call(
Expand Down
7 changes: 4 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2709,9 +2709,10 @@ preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"

prettier@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93"
prettier@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5"
integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==

pretty-format@^21.2.1:
version "21.2.1"
Expand Down