lampuotomatis/public/build/libs/dom-autoscroller/dom-autoscroller.js

1037 lines
29 KiB
JavaScript

var autoScroll = (function () {
'use strict';
function getDef(f, d) {
if (typeof f === 'undefined') {
return typeof d === 'undefined' ? f : d;
}
return f;
}
function boolean(func, def) {
func = getDef(func, def);
if (typeof func === 'function') {
return function f() {
var arguments$1 = arguments;
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments$1[_key];
}
return !!func.apply(this, args);
};
}
return !!func ? function () {
return true;
} : function () {
return false;
};
}
var prefix = ['webkit', 'moz', 'ms', 'o'];
var requestAnimationFrame = function () {
for (var i = 0, limit = prefix.length; i < limit && !window.requestAnimationFrame; ++i) {
window.requestAnimationFrame = window[prefix[i] + 'RequestAnimationFrame'];
}
if (!window.requestAnimationFrame) {
(function () {
var lastTime = 0;
window.requestAnimationFrame = function (callback) {
var now = new Date().getTime();
var ttc = Math.max(0, 16 - now - lastTime);
var timer = window.setTimeout(function () {
return callback(now + ttc);
}, ttc);
lastTime = now + ttc;
return timer;
};
})();
}
return window.requestAnimationFrame.bind(window);
}();
var cancelAnimationFrame = function () {
for (var i = 0, limit = prefix.length; i < limit && !window.cancelAnimationFrame; ++i) {
window.cancelAnimationFrame = window[prefix[i] + 'CancelAnimationFrame'] || window[prefix[i] + 'CancelRequestAnimationFrame'];
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function (timer) {
window.clearTimeout(timer);
};
}
return window.cancelAnimationFrame.bind(window);
}();
// Production steps of ECMA-262, Edition 6, 22.1.2.1
// Reference: http://www.ecma-international.org/ecma-262/6.0/#sec-array.from
var polyfill = (function() {
var isCallable = function(fn) {
return typeof fn === 'function';
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
var iteratorProp = function(value) {
if(value != null) {
if(['string','number','boolean','symbol'].indexOf(typeof value) > -1){
return Symbol.iterator;
} else if (
(typeof Symbol !== 'undefined') &&
('iterator' in Symbol) &&
(Symbol.iterator in value)
) {
return Symbol.iterator;
}
// Support "@@iterator" placeholder, Gecko 27 to Gecko 35
else if ('@@iterator' in value) {
return '@@iterator';
}
}
};
var getMethod = function(O, P) {
// Assert: IsPropertyKey(P) is true.
if (O != null && P != null) {
// Let func be GetV(O, P).
var func = O[P];
// ReturnIfAbrupt(func).
// If func is either undefined or null, return undefined.
if(func == null) {
return void 0;
}
// If IsCallable(func) is false, throw a TypeError exception.
if (!isCallable(func)) {
throw new TypeError(func + ' is not a function');
}
return func;
}
};
var iteratorStep = function(iterator) {
// Let result be IteratorNext(iterator).
// ReturnIfAbrupt(result).
var result = iterator.next();
// Let done be IteratorComplete(result).
// ReturnIfAbrupt(done).
var done = Boolean(result.done);
// If done is true, return false.
if(done) {
return false;
}
// Return result.
return result;
};
// The length property of the from method is 1.
return function from(items /*, mapFn, thisArg */ ) {
'use strict';
// 1. Let C be the this value.
var C = this;
// 2. If mapfn is undefined, let mapping be false.
var mapFn = arguments.length > 1 ? arguments[1] : void 0;
var T;
if (typeof mapFn !== 'undefined') {
// 3. else
// a. If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError(
'Array.from: when provided, the second argument must be a function'
);
}
// b. If thisArg was supplied, let T be thisArg; else let T
// be undefined.
if (arguments.length > 2) {
T = arguments[2];
}
// c. Let mapping be true (implied by mapFn)
}
var A, k;
// 4. Let usingIterator be GetMethod(items, @@iterator).
// 5. ReturnIfAbrupt(usingIterator).
var usingIterator = getMethod(items, iteratorProp(items));
// 6. If usingIterator is not undefined, then
if (usingIterator !== void 0) {
// a. If IsConstructor(C) is true, then
// i. Let A be the result of calling the [[Construct]]
// internal method of C with an empty argument list.
// b. Else,
// i. Let A be the result of the abstract operation ArrayCreate
// with argument 0.
// c. ReturnIfAbrupt(A).
A = isCallable(C) ? Object(new C()) : [];
// d. Let iterator be GetIterator(items, usingIterator).
var iterator = usingIterator.call(items);
// e. ReturnIfAbrupt(iterator).
if (iterator == null) {
throw new TypeError(
'Array.from requires an array-like or iterable object'
);
}
// f. Let k be 0.
k = 0;
// g. Repeat
var next, nextValue;
while (true) {
// i. Let Pk be ToString(k).
// ii. Let next be IteratorStep(iterator).
// iii. ReturnIfAbrupt(next).
next = iteratorStep(iterator);
// iv. If next is false, then
if (!next) {
// 1. Let setStatus be Set(A, "length", k, true).
// 2. ReturnIfAbrupt(setStatus).
A.length = k;
// 3. Return A.
return A;
}
// v. Let nextValue be IteratorValue(next).
// vi. ReturnIfAbrupt(nextValue)
nextValue = next.value;
// vii. If mapping is true, then
// 1. Let mappedValue be Call(mapfn, T, «nextValue, k»).
// 2. If mappedValue is an abrupt completion, return
// IteratorClose(iterator, mappedValue).
// 3. Let mappedValue be mappedValue.[[value]].
// viii. Else, let mappedValue be nextValue.
// ix. Let defineStatus be the result of
// CreateDataPropertyOrThrow(A, Pk, mappedValue).
// x. [TODO] If defineStatus is an abrupt completion, return
// IteratorClose(iterator, defineStatus).
if (mapFn) {
A[k] = mapFn.call(T, nextValue, k);
}
else {
A[k] = nextValue;
}
// xi. Increase k by 1.
k++;
}
// 7. Assert: items is not an Iterable so assume it is
// an array-like object.
} else {
// 8. Let arrayLike be ToObject(items).
var arrayLike = Object(items);
// 9. ReturnIfAbrupt(items).
if (items == null) {
throw new TypeError(
'Array.from requires an array-like object - not null or undefined'
);
}
// 10. Let len be ToLength(Get(arrayLike, "length")).
// 11. ReturnIfAbrupt(len).
var len = toLength(arrayLike.length);
// 12. If IsConstructor(C) is true, then
// a. Let A be Construct(C, «len»).
// 13. Else
// a. Let A be ArrayCreate(len).
// 14. ReturnIfAbrupt(A).
A = isCallable(C) ? Object(new C(len)) : new Array(len);
// 15. Let k be 0.
k = 0;
// 16. Repeat, while k < len… (also steps a - h)
var kValue;
while (k < len) {
kValue = arrayLike[k];
if (mapFn) {
A[k] = mapFn.call(T, kValue, k);
}
else {
A[k] = kValue;
}
k++;
}
// 17. Let setStatus be Set(A, "length", len, true).
// 18. ReturnIfAbrupt(setStatus).
A.length = len;
// 19. Return A.
}
return A;
};
})();
var index = (typeof Array.from === 'function' ?
Array.from :
polyfill
);
/**
* isArray
*/
var isArray = Array.isArray;
/**
* toString
*/
var str = Object.prototype.toString;
/**
* Whether or not the given `val`
* is an array.
*
* example:
*
* isArray([]);
* // > true
* isArray(arguments);
* // > false
* isArray('');
* // > false
*
* @param {mixed} val
* @return {bool}
*/
var index$1 = isArray || function (val) {
return !! val && '[object Array]' == str.call(val);
};
/**
* Returns `true` if provided input is Element.
* @name isElement
* @param {*} [input]
* @returns {boolean}
*/
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
/**
* Returns `true` if provided input is Element.
* @name isElement
* @param {*} [input]
* @returns {boolean}
*/
var isElement$1 = function (input) {
return input != null && (typeof input === 'undefined' ? 'undefined' : _typeof(input)) === 'object' && input.nodeType === 1 && _typeof(input.style) === 'object' && _typeof(input.ownerDocument) === 'object';
};
function indexOfElement(elements, element){
element = resolveElement(element, true);
if(!isElement$1(element)) { return -1; }
for(var i=0; i<elements.length; i++){
if(elements[i] === element){
return i;
}
}
return -1;
}
function hasElement(elements, element){
return -1 !== indexOfElement(elements, element);
}
function domListOf(arr){
if(!arr) { return []; }
try{
if(typeof arr === 'string'){
return index(document.querySelectorAll(arr));
}else if(index$1(arr)){
return arr.map(resolveElement);
}else{
if(typeof arr.length === 'undefined'){
return [resolveElement(arr)];
}
return index(arr, resolveElement);
}
}catch(e){
throw new Error(e);
}
}
function pushElements(elements, toAdd){
for(var i=0; i<toAdd.length; i++){
if(!hasElement(elements, toAdd[i]))
{ elements.push(toAdd[i]); }
}
return toAdd;
}
function addElements(elements){
var arguments$1 = arguments;
var toAdd = [], len = arguments.length - 1;
while ( len-- > 0 ) { toAdd[ len ] = arguments$1[ len + 1 ]; }
toAdd = toAdd.map(resolveElement);
return pushElements(elements, toAdd);
}
function removeElements(elements){
var arguments$1 = arguments;
var toRemove = [], len = arguments.length - 1;
while ( len-- > 0 ) { toRemove[ len ] = arguments$1[ len + 1 ]; }
return toRemove.map(resolveElement).reduce(function (last, e){
var index$$1 = indexOfElement(elements, e);
if(index$$1 !== -1)
{ return last.concat(elements.splice(index$$1, 1)); }
return last;
}, []);
}
function resolveElement(element, noThrow){
if(typeof element === 'string'){
try{
return document.querySelector(element);
}catch(e){
throw e;
}
}
if(!isElement$1(element) && !noThrow){
throw new TypeError((element + " is not a DOM element."));
}
return element;
}
function createPointCB(object, options) {
// A persistent object (as opposed to returned object) is used to save memory
// This is good to prevent layout thrashing, or for games, and such
// NOTE
// This uses IE fixes which should be OK to remove some day. :)
// Some speed will be gained by removal of these.
// pointCB should be saved in a variable on return
// This allows the usage of element.removeEventListener
options = options || {};
var allowUpdate = boolean(options.allowUpdate, true);
/*if(typeof options.allowUpdate === 'function'){
allowUpdate = options.allowUpdate;
}else{
allowUpdate = function(){return true;};
}*/
return function pointCB(event) {
event = event || window.event; // IE-ism
object.target = event.target || event.srcElement || event.originalTarget;
object.element = this;
object.type = event.type;
if (!allowUpdate(event)) {
return;
}
// Support touch
// http://www.creativebloq.com/javascript/make-your-site-work-touch-devices-51411644
if (event.targetTouches) {
object.x = event.targetTouches[0].clientX;
object.y = event.targetTouches[0].clientY;
object.pageX = event.targetTouches[0].pageX;
object.pageY = event.targetTouches[0].pageY;
object.screenX = event.targetTouches[0].screenX;
object.screenY = event.targetTouches[0].screenY;
} else {
// If pageX/Y aren't available and clientX/Y are,
// calculate pageX/Y - logic taken from jQuery.
// (This is to support old IE)
// NOTE Hopefully this can be removed soon.
if (event.pageX === null && event.clientX !== null) {
var eventDoc = event.target && event.target.ownerDocument || document;
var doc = eventDoc.documentElement;
var body = eventDoc.body;
object.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
object.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
} else {
object.pageX = event.pageX;
object.pageY = event.pageY;
}
// pageX, and pageY change with page scroll
// so we're not going to use those for x, and y.
// NOTE Most browsers also alias clientX/Y with x/y
// so that's something to consider down the road.
object.x = event.clientX;
object.y = event.clientY;
object.screenX = event.screenX;
object.screenY = event.screenY;
}
object.clientX = object.x;
object.clientY = object.y;
};
//NOTE Remember accessibility, Aria roles, and labels.
}
function createWindowRect() {
var props = {
top: { value: 0, enumerable: true },
left: { value: 0, enumerable: true },
right: { value: window.innerWidth, enumerable: true },
bottom: { value: window.innerHeight, enumerable: true },
width: { value: window.innerWidth, enumerable: true },
height: { value: window.innerHeight, enumerable: true },
x: { value: 0, enumerable: true },
y: { value: 0, enumerable: true }
};
if (Object.create) {
return Object.create({}, props);
} else {
var rect = {};
Object.defineProperties(rect, props);
return rect;
}
}
function getClientRect(el) {
if (el === window) {
return createWindowRect();
} else {
try {
var rect = el.getBoundingClientRect();
if (rect.x === undefined) {
rect.x = rect.left;
rect.y = rect.top;
}
return rect;
} catch (e) {
throw new TypeError("Can't call getBoundingClientRect on " + el);
}
}
}
function pointInside(point, el) {
var rect = getClientRect(el);
return point.y > rect.top && point.y < rect.bottom && point.x > rect.left && point.x < rect.right;
}
var objectCreate = void 0;
if (typeof Object.create != 'function') {
objectCreate = function (undefined) {
var Temp = function Temp() {};
return function (prototype, propertiesObject) {
if (prototype !== Object(prototype) && prototype !== null) {
throw TypeError('Argument must be an object, or null');
}
Temp.prototype = prototype || {};
var result = new Temp();
Temp.prototype = null;
if (propertiesObject !== undefined) {
Object.defineProperties(result, propertiesObject);
}
// to imitate the case of Object.create(null)
if (prototype === null) {
result.__proto__ = null;
}
return result;
};
}();
} else {
objectCreate = Object.create;
}
var objectCreate$1 = objectCreate;
var mouseEventProps = ['altKey', 'button', 'buttons', 'clientX', 'clientY', 'ctrlKey', 'metaKey', 'movementX', 'movementY', 'offsetX', 'offsetY', 'pageX', 'pageY', 'region', 'relatedTarget', 'screenX', 'screenY', 'shiftKey', 'which', 'x', 'y'];
function createDispatcher(element) {
var defaultSettings = {
screenX: 0,
screenY: 0,
clientX: 0,
clientY: 0,
ctrlKey: false,
shiftKey: false,
altKey: false,
metaKey: false,
button: 0,
buttons: 1,
relatedTarget: null,
region: null
};
if (element !== undefined) {
element.addEventListener('mousemove', onMove);
}
function onMove(e) {
for (var i = 0; i < mouseEventProps.length; i++) {
defaultSettings[mouseEventProps[i]] = e[mouseEventProps[i]];
}
}
var dispatch = function () {
if (MouseEvent) {
return function m1(element, initMove, data) {
var evt = new MouseEvent('mousemove', createMoveInit(defaultSettings, initMove));
//evt.dispatched = 'mousemove';
setSpecial(evt, data);
return element.dispatchEvent(evt);
};
} else if (typeof document.createEvent === 'function') {
return function m2(element, initMove, data) {
var settings = createMoveInit(defaultSettings, initMove);
var evt = document.createEvent('MouseEvents');
evt.initMouseEvent("mousemove", true, //can bubble
true, //cancelable
window, //view
0, //detail
settings.screenX, //0, //screenX
settings.screenY, //0, //screenY
settings.clientX, //80, //clientX
settings.clientY, //20, //clientY
settings.ctrlKey, //false, //ctrlKey
settings.altKey, //false, //altKey
settings.shiftKey, //false, //shiftKey
settings.metaKey, //false, //metaKey
settings.button, //0, //button
settings.relatedTarget //null //relatedTarget
);
//evt.dispatched = 'mousemove';
setSpecial(evt, data);
return element.dispatchEvent(evt);
};
} else if (typeof document.createEventObject === 'function') {
return function m3(element, initMove, data) {
var evt = document.createEventObject();
var settings = createMoveInit(defaultSettings, initMove);
for (var name in settings) {
evt[name] = settings[name];
}
//evt.dispatched = 'mousemove';
setSpecial(evt, data);
return element.dispatchEvent(evt);
};
}
}();
function destroy() {
if (element) { element.removeEventListener('mousemove', onMove, false); }
defaultSettings = null;
}
return {
destroy: destroy,
dispatch: dispatch
};
}
function createMoveInit(defaultSettings, initMove) {
initMove = initMove || {};
var settings = objectCreate$1(defaultSettings);
for (var i = 0; i < mouseEventProps.length; i++) {
if (initMove[mouseEventProps[i]] !== undefined) { settings[mouseEventProps[i]] = initMove[mouseEventProps[i]]; }
}
return settings;
}
function setSpecial(e, data) {
console.log('data ', data);
e.data = data || {};
e.dispatched = 'mousemove';
}
function AutoScroller(elements, options){
if ( options === void 0 ) options = {};
var self = this;
var maxSpeed = 4, scrolling = false;
this.margin = options.margin || -1;
//this.scrolling = false;
this.scrollWhenOutside = options.scrollWhenOutside || false;
var point = {},
pointCB = createPointCB(point),
dispatcher = createDispatcher(),
down = false;
window.addEventListener('mousemove', pointCB, false);
window.addEventListener('touchmove', pointCB, false);
if(!isNaN(options.maxSpeed)){
maxSpeed = options.maxSpeed;
}
this.autoScroll = boolean(options.autoScroll);
this.syncMove = boolean(options.syncMove, false);
this.destroy = function(forceCleanAnimation) {
window.removeEventListener('mousemove', pointCB, false);
window.removeEventListener('touchmove', pointCB, false);
window.removeEventListener('mousedown', onDown, false);
window.removeEventListener('touchstart', onDown, false);
window.removeEventListener('mouseup', onUp, false);
window.removeEventListener('touchend', onUp, false);
window.removeEventListener('pointerup', onUp, false);
window.removeEventListener('mouseleave', onMouseOut, false);
window.removeEventListener('mousemove', onMove, false);
window.removeEventListener('touchmove', onMove, false);
window.removeEventListener('scroll', setScroll, true);
elements = [];
if(forceCleanAnimation){
cleanAnimation();
}
};
this.add = function(){
var element = [], len = arguments.length;
while ( len-- ) element[ len ] = arguments[ len ];
addElements.apply(void 0, [ elements ].concat( element ));
return this;
};
this.remove = function(){
var element = [], len = arguments.length;
while ( len-- ) element[ len ] = arguments[ len ];
return removeElements.apply(void 0, [ elements ].concat( element ));
};
var hasWindow = null, windowAnimationFrame;
if(Object.prototype.toString.call(elements) !== '[object Array]'){
elements = [elements];
}
(function(temp){
elements = [];
temp.forEach(function(element){
if(element === window){
hasWindow = window;
}else{
self.add(element);
}
});
}(elements));
Object.defineProperties(this, {
down: {
get: function(){ return down; }
},
maxSpeed: {
get: function(){ return maxSpeed; }
},
point: {
get: function(){ return point; }
},
scrolling: {
get: function(){ return scrolling; }
}
});
var n = 0, current = null, animationFrame;
window.addEventListener('mousedown', onDown, false);
window.addEventListener('touchstart', onDown, false);
window.addEventListener('mouseup', onUp, false);
window.addEventListener('touchend', onUp, false);
/*
IE does not trigger mouseup event when scrolling.
It is a known issue that Microsoft won't fix.
https://connect.microsoft.com/IE/feedback/details/783058/scrollbar-trigger-mousedown-but-not-mouseup
IE supports pointer events instead
*/
window.addEventListener('pointerup', onUp, false);
window.addEventListener('mousemove', onMove, false);
window.addEventListener('touchmove', onMove, false);
window.addEventListener('mouseleave', onMouseOut, false);
window.addEventListener('scroll', setScroll, true);
function setScroll(e){
for(var i=0; i<elements.length; i++){
if(elements[i] === e.target){
scrolling = true;
break;
}
}
if(scrolling){
requestAnimationFrame(function (){ return scrolling = false; });
}
}
function onDown(){
down = true;
}
function onUp(){
down = false;
cleanAnimation();
}
function cleanAnimation(){
cancelAnimationFrame(animationFrame);
cancelAnimationFrame(windowAnimationFrame);
}
function onMouseOut(){
down = false;
}
function getTarget(target){
if(!target){
return null;
}
if(current === target){
return target;
}
if(hasElement(elements, target)){
return target;
}
while(target = target.parentNode){
if(hasElement(elements, target)){
return target;
}
}
return null;
}
function getElementUnderPoint(){
var underPoint = null;
for(var i=0; i<elements.length; i++){
if(inside(point, elements[i])){
underPoint = elements[i];
}
}
return underPoint;
}
function onMove(event){
if(!self.autoScroll()) { return; }
if(event['dispatched']){ return; }
var target = event.target, body = document.body;
if(current && !inside(point, current)){
if(!self.scrollWhenOutside){
current = null;
}
}
if(target && target.parentNode === body){
//The special condition to improve speed.
target = getElementUnderPoint();
}else{
target = getTarget(target);
if(!target){
target = getElementUnderPoint();
}
}
if(target && target !== current){
current = target;
}
if(hasWindow){
cancelAnimationFrame(windowAnimationFrame);
windowAnimationFrame = requestAnimationFrame(scrollWindow);
}
if(!current){
return;
}
cancelAnimationFrame(animationFrame);
animationFrame = requestAnimationFrame(scrollTick);
}
function scrollWindow(){
autoScroll(hasWindow);
cancelAnimationFrame(windowAnimationFrame);
windowAnimationFrame = requestAnimationFrame(scrollWindow);
}
function scrollTick(){
if(!current){
return;
}
autoScroll(current);
cancelAnimationFrame(animationFrame);
animationFrame = requestAnimationFrame(scrollTick);
}
function autoScroll(el){
var rect = getClientRect(el), scrollx, scrolly;
if(point.x < rect.left + self.margin){
scrollx = Math.floor(
Math.max(-1, (point.x - rect.left) / self.margin - 1) * self.maxSpeed
);
}else if(point.x > rect.right - self.margin){
scrollx = Math.ceil(
Math.min(1, (point.x - rect.right) / self.margin + 1) * self.maxSpeed
);
}else{
scrollx = 0;
}
if(point.y < rect.top + self.margin){
scrolly = Math.floor(
Math.max(-1, (point.y - rect.top) / self.margin - 1) * self.maxSpeed
);
}else if(point.y > rect.bottom - self.margin){
scrolly = Math.ceil(
Math.min(1, (point.y - rect.bottom) / self.margin + 1) * self.maxSpeed
);
}else{
scrolly = 0;
}
if(self.syncMove()){
/*
Notes about mousemove event dispatch.
screen(X/Y) should need to be updated.
Some other properties might need to be set.
Keep the syncMove option default false until all inconsistencies are taken care of.
*/
dispatcher.dispatch(el, {
pageX: point.pageX + scrollx,
pageY: point.pageY + scrolly,
clientX: point.x + scrollx,
clientY: point.y + scrolly
});
}
setTimeout(function (){
if(scrolly){
scrollY(el, scrolly);
}
if(scrollx){
scrollX(el, scrollx);
}
});
}
function scrollY(el, amount){
if(el === window){
window.scrollTo(el.pageXOffset, el.pageYOffset + amount);
}else{
el.scrollTop += amount;
}
}
function scrollX(el, amount){
if(el === window){
window.scrollTo(el.pageXOffset + amount, el.pageYOffset);
}else{
el.scrollLeft += amount;
}
}
}
function AutoScrollerFactory(element, options){
return new AutoScroller(element, options);
}
function inside(point, el, rect){
if(!rect){
return pointInside(point, el);
}else{
return (point.y > rect.top && point.y < rect.bottom &&
point.x > rect.left && point.x < rect.right);
}
}
/*
git remote add origin https://github.com/hollowdoor/dom_autoscroller.git
git push -u origin master
*/
return AutoScrollerFactory;
}());
//# sourceMappingURL=dom-autoscroller.js.map