Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

angular-snapscroll

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

angular-snapscroll - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

2

bower.json
{
"name": "angular-snapscroll",
"version": "1.2.0",
"version": "1.3.0",
"authors": [

@@ -5,0 +5,0 @@ "Joel Mukuthu <joelmukuthu@gmail.com>"

@@ -0,1 +1,6 @@

## 1.3.0
### Features
- Add module exports (https://github.com/joelmukuthu/angular-snapscroll/issues/46)
## 1.2.0

@@ -63,1 +68,11 @@

- Change angular dep version to the lowest supported version (`1.2.24`)
## 0.2.5
### Features
- Support for installation with npm
## 0.2.4
### Fixes
- Fix wheel event when jQuery is also included on the page
/**
* angular-snapscroll
* Version: 1.2.0
* (c) 2014-2016 Joel Mukuthu
* Version: 1.3.0
* (c) 2014-2017 Joel Mukuthu
* MIT License
* Built on: 12-12-2016 21:13:13 GMT+0100
* Built on: 06-03-2017 12:22:02 GMT+0100
**/
(function () {
angular
.module('snapscroll', ['wheelie', 'scrollie'])
.value('defaultSnapscrollScrollEasing', undefined)
.value('defaultSnapscrollScrollDelay', 250)
.value('defaultSnapscrollSnapDuration', 800)
.value('defaultSnapscrollResizeDelay', 400)
.value('defaultSnapscrollBindScrollTimeout', 400)
.value('defaultSnapscrollPreventDoubleSnapDelay', 1000);
})();
if (typeof exports === 'object') {
module.exports = 'snapscroll';
}
(function () {
angular.module('snapscroll')
.directive('fitWindowHeight', [
'$window',
'$timeout',
'defaultSnapscrollResizeDelay',
function (
$window,
$timeout,
defaultSnapscrollResizeDelay
) {
return {
restrict: 'A',
require: 'snapscroll',
link: function (scope, element, attributes, snapscroll) {
var windowElement,
resizePromise,
resizeDelay = attributes.resizeDelay;
angular
.module('snapscroll', ['wheelie', 'scrollie'])
.value('defaultSnapscrollScrollEasing', undefined)
.value('defaultSnapscrollScrollDelay', 250)
.value('defaultSnapscrollSnapDuration', 800)
.value('defaultSnapscrollResizeDelay', 400)
.value('defaultSnapscrollBindScrollTimeout', 400)
.value('defaultSnapscrollPreventDoubleSnapDelay', 1000);
function onWindowResize() {
if (resizeDelay === false) {
angular.module('snapscroll').directive('fitWindowHeight', [
'$window',
'$timeout',
'defaultSnapscrollResizeDelay',
function (
$window,
$timeout,
defaultSnapscrollResizeDelay
) {
return {
restrict: 'A',
require: 'snapscroll',
link: function (scope, element, attributes, snapscroll) {
var windowElement,
resizePromise,
resizeDelay = attributes.resizeDelay;
function onWindowResize() {
if (resizeDelay === false) {
snapscroll.setSnapHeight($window.innerHeight);
} else {
$timeout.cancel(resizePromise);
resizePromise = $timeout(function () {
snapscroll.setSnapHeight($window.innerHeight);
} else {
$timeout.cancel(resizePromise);
resizePromise = $timeout(function () {
snapscroll.setSnapHeight($window.innerHeight);
}, resizeDelay);
}
}, resizeDelay);
}
}
function init() {
if (resizeDelay === 'false') {
resizeDelay = false;
} else {
resizeDelay = parseInt(resizeDelay, 10);
if (isNaN(resizeDelay)) {
resizeDelay = defaultSnapscrollResizeDelay;
}
function init() {
if (resizeDelay === 'false') {
resizeDelay = false;
} else {
resizeDelay = parseInt(resizeDelay, 10);
if (isNaN(resizeDelay)) {
resizeDelay = defaultSnapscrollResizeDelay;
}
}
// set initial snapHeight
snapscroll.setSnapHeight($window.innerHeight);
// set initial snapHeight
snapscroll.setSnapHeight($window.innerHeight);
// update snapHeight on window resize
windowElement = angular.element($window);
windowElement.on('resize', onWindowResize);
scope.$on('$destroy', function () {
windowElement.off('resize');
});
}
init();
// update snapHeight on window resize
windowElement = angular.element($window);
windowElement.on('resize', onWindowResize);
scope.$on('$destroy', function () {
windowElement.off('resize');
});
}
};
}]);
})();
(function () {
function isNumber(value) {
return angular.isNumber(value) && !isNaN(value);
init();
}
};
}
]);
var isDefined = angular.isDefined;
var isUndefined = angular.isUndefined;
var isFunction = angular.isFunction;
var forEach = angular.forEach;
angular.module('snapscroll').directive('snapscroll', [
'$timeout',
'$document',
'wheelie',
'scrollie',
'defaultSnapscrollScrollEasing',
'defaultSnapscrollScrollDelay',
'defaultSnapscrollSnapDuration',
'defaultSnapscrollBindScrollTimeout',
'defaultSnapscrollPreventDoubleSnapDelay',
function (
$timeout,
$document,
wheelie,
scrollie,
defaultSnapscrollScrollEasing,
defaultSnapscrollScrollDelay,
defaultSnapscrollSnapDuration,
defaultSnapscrollBindScrollTimeout,
defaultSnapscrollPreventDoubleSnapDelay
) {
function isNumber(value) {
return angular.isNumber(value) && !isNaN(value);
}
var scopeObject = {
enabled: '=snapscroll',
snapIndex: '=?',
snapHeight: '=?',
beforeSnap: '&',
afterSnap: '&',
snapAnimation: '=?'
};
var isDefined = angular.isDefined;
var isUndefined = angular.isUndefined;
var isFunction = angular.isFunction;
var forEach = angular.forEach;
var controller = ['$scope', function ($scope) {
this.setSnapHeight = function (height) {
$scope.snapHeight = height;
};
}];
return {
restrict: 'A',
scope: {
enabled: '=snapscroll',
snapIndex: '=?',
snapHeight: '=?',
beforeSnap: '&',
afterSnap: '&',
snapAnimation: '=?'
},
controller: ['$scope', function ($scope) {
this.setSnapHeight = function (height) {
$scope.snapHeight = height;
};
}],
link: function (scope, element, attributes) {
function getChildren() {
return element.children();
}
var snapscrollAsAnAttribute = [
'$timeout',
'$document',
'wheelie',
'scrollie',
'defaultSnapscrollScrollEasing',
'defaultSnapscrollScrollDelay',
'defaultSnapscrollSnapDuration',
'defaultSnapscrollBindScrollTimeout',
'defaultSnapscrollPreventDoubleSnapDelay',
function (
$timeout,
$document,
wheelie,
scrollie,
defaultSnapscrollScrollEasing,
defaultSnapscrollScrollDelay,
defaultSnapscrollSnapDuration,
defaultSnapscrollBindScrollTimeout,
defaultSnapscrollPreventDoubleSnapDelay
) {
return {
restrict: 'A',
scope: scopeObject,
controller: controller,
link: function (scope, element, attributes) {
function getChildren() {
return element.children();
}
function getHeight(domElement) {
return domElement.offsetHeight;
}
function getHeight(domElement) {
return domElement.offsetHeight;
}
function getChildHeight(snapIndex) {
return getHeight(getChildren()[snapIndex]);
}
function getChildHeight(snapIndex) {
return getHeight(getChildren()[snapIndex]);
function getSnapHeight() {
return getHeight(element[0]);
}
function getScrollHeight() {
return element[0].scrollHeight;
}
function rectifyScrollTop(scrollTop) {
var maxScrollTop = getScrollHeight() - getSnapHeight();
if (scrollTop > maxScrollTop) {
return maxScrollTop;
}
return scrollTop;
}
function getSnapHeight() {
return getHeight(element[0]);
function getScrollTop(compositeIndex, previousCompositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
var scrollTop = 0;
var children = getChildren();
for (var i = 0; i < snapIndex; i++) {
scrollTop += getHeight(children[i]);
}
function getScrollHeight() {
return element[0].scrollHeight;
if (innerSnapIndex === 0) {
return rectifyScrollTop(scrollTop);
}
function rectifyScrollTop(scrollTop) {
var maxScrollTop = getScrollHeight() - getSnapHeight();
if (scrollTop > maxScrollTop) {
return maxScrollTop;
var snapHeight = getSnapHeight();
var childHeight = getHeight(children[snapIndex]);
var innerScrollTop;
if (isDefined(previousCompositeIndex) &&
innerSnapIndex < previousCompositeIndex[1]) {
innerScrollTop = childHeight;
for (var j = innerSnapIndex; j >= 0; j--) {
innerScrollTop -= snapHeight;
}
return scrollTop;
} else {
innerScrollTop = 0;
for (var k = 0; k < innerSnapIndex; k++) {
innerScrollTop += snapHeight;
}
var overflow = innerScrollTop + snapHeight - childHeight;
if (overflow > 0) {
innerScrollTop -= overflow;
}
}
function getScrollTop(compositeIndex, previousCompositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
return rectifyScrollTop(scrollTop + innerScrollTop);
}
var scrollTop = 0;
var children = getChildren();
for (var i = 0; i < snapIndex; i++) {
scrollTop += getHeight(children[i]);
function snapTo(compositeIndex, previousCompositeIndex) {
var snapIndex = compositeIndex[0];
var isSnapIndexChanged = isUndefined(previousCompositeIndex) ||
snapIndex !== previousCompositeIndex[0];
if (isSnapIndexChanged) {
var returnValue = scope.beforeSnap({
snapIndex: snapIndex,
$event: scope.sourceEvent
});
if (returnValue === false) {
if (isDefined(previousCompositeIndex)) {
scope.ignoreCompositeIndexChange = true;
scope.compositeIndex = previousCompositeIndex;
}
return;
}
if (innerSnapIndex === 0) {
return rectifyScrollTop(scrollTop);
if (isNumber(returnValue)) {
scope.snapIndex = returnValue;
return;
}
var snapHeight = getSnapHeight();
var childHeight = getHeight(children[snapIndex]);
var innerScrollTop;
if (isDefined(previousCompositeIndex) &&
innerSnapIndex < previousCompositeIndex[1]) {
innerScrollTop = childHeight;
for (var j = innerSnapIndex; j >= 0; j--) {
innerScrollTop -= snapHeight;
}
} else {
innerScrollTop = 0;
for (var k = 0; k < innerSnapIndex; k++) {
innerScrollTop += snapHeight;
}
var overflow = innerScrollTop + snapHeight - childHeight;
if (overflow > 0) {
innerScrollTop -= overflow;
}
}
return rectifyScrollTop(scrollTop + innerScrollTop);
}
function snapTo(compositeIndex, previousCompositeIndex) {
var snapIndex = compositeIndex[0];
var isSnapIndexChanged = isUndefined(previousCompositeIndex) ||
snapIndex !== previousCompositeIndex[0];
return scrollTo(getScrollTop(
compositeIndex,
previousCompositeIndex
)).then(function () {
if (isSnapIndexChanged) {
var returnValue = scope.beforeSnap({
scope.afterSnap({
snapIndex: snapIndex,
$event: scope.sourceEvent
});
if (returnValue === false) {
if (isDefined(previousCompositeIndex)) {
scope.ignoreCompositeIndexChange = true;
scope.compositeIndex = previousCompositeIndex;
}
return;
}
if (isNumber(returnValue)) {
scope.snapIndex = returnValue;
return;
}
}
scope.sourceEvent = undefined;
});
}
return scrollTo(getScrollTop(
compositeIndex,
previousCompositeIndex
)).then(function () {
if (isSnapIndexChanged) {
scope.afterSnap({
snapIndex: snapIndex,
$event: scope.sourceEvent
});
}
scope.sourceEvent = undefined;
});
function getCurrentScrollTop() {
return element[0].scrollTop;
}
function scrollTo(scrollTop) {
var args;
if (!scope.snapAnimation) {
args = [
element,
scrollTop
];
} else if (isUndefined(scope.snapEasing)) {
// TODO: add tests for this. Will require refactoring
// the default values into an object, which is a good
// change anyway
args = [
element,
scrollTop,
scope.snapDuration
];
} else {
args = [
element,
scrollTop,
scope.snapDuration,
scope.snapEasing
];
}
function getCurrentScrollTop() {
return element[0].scrollTop;
var currentScrollTop = getCurrentScrollTop();
if (scrollTop > currentScrollTop) {
scope.snapDirection = 'down';
} else if (scrollTop < currentScrollTop) {
scope.snapDirection = 'up';
} else {
scope.snapDirection = 'same';
}
function scrollTo(scrollTop) {
var args;
if (!scope.snapAnimation) {
args = [
element,
scrollTop
];
} else if (isUndefined(scope.snapEasing)) {
// TODO: add tests for this. Will require refactoring
// the default values into an object, which is a good
// change anyway
args = [
element,
scrollTop,
scope.snapDuration
];
} else {
args = [
element,
scrollTop,
scope.snapDuration,
scope.snapEasing
];
}
unbindScroll();
return scrollie.to.apply(scrollie, args).then(function () {
scope.snapDirection = undefined;
bindScrollAfterDelay();
allowNextSnapAfterDelay();
});
}
var currentScrollTop = getCurrentScrollTop();
if (scrollTop > currentScrollTop) {
scope.snapDirection = 'down';
} else if (scrollTop < currentScrollTop) {
scope.snapDirection = 'up';
function allowNextSnapAfterDelay() {
function allowNextSnap() {
scope.preventUp = false;
scope.preventDown = false;
}
if (scope.preventUp || scope.preventDown) {
if (scope.preventDoubleSnapDelay === false) {
allowNextSnap();
} else {
scope.snapDirection = 'same';
$timeout(
allowNextSnap,
scope.preventDoubleSnapDelay
);
}
}
}
unbindScroll();
return scrollie.to.apply(scrollie, args).then(function () {
scope.snapDirection = undefined;
bindScrollAfterDelay();
allowNextSnapAfterDelay();
});
function isScrollable() {
var snapHeight = getSnapHeight();
if (!snapHeight) {
return false;
}
var children = getChildren();
if (!children.length) {
return false;
}
var totalHeight = 0;
forEach(children, function (child) {
totalHeight += getHeight(child);
});
if (totalHeight < snapHeight) {
return false;
}
return true;
}
function allowNextSnapAfterDelay() {
function allowNextSnap() {
scope.preventUp = false;
scope.preventDown = false;
function isSnapIndexValid(snapIndex) {
return snapIndex >= 0 &&
snapIndex <= getChildren().length - 1;
}
function snapIndexChanged(current, previous) {
if (!isScrollable()) {
return;
}
if (isUndefined(current)) {
scope.snapIndex = 0;
return;
}
if (!isNumber(current)) {
if (!isNumber(previous)) {
previous = 0;
}
if (scope.preventUp || scope.preventDown) {
if (scope.preventDoubleSnapDelay === false) {
allowNextSnap();
} else {
$timeout(
allowNextSnap,
scope.preventDoubleSnapDelay
);
}
}
scope.snapIndex = previous;
return;
}
function isScrollable() {
var snapHeight = getSnapHeight();
if (!snapHeight) {
return false;
if (current % 1 !== 0) {
scope.snapIndex = Math.round(current);
return;
}
if (scope.ignoreSnapIndexChange === true) {
scope.ignoreSnapIndexChange = undefined;
return;
}
if (!isSnapIndexValid(current)) {
if (!isSnapIndexValid(previous)) {
previous = 0;
}
var children = getChildren();
if (!children.length) {
return false;
}
var totalHeight = 0;
forEach(children, function (child) {
totalHeight += getHeight(child);
});
if (totalHeight < snapHeight) {
return false;
}
return true;
scope.ignoreSnapIndexChange = true;
scope.snapIndex = previous;
return;
}
scope.compositeIndex = [current, 0];
}
function isSnapIndexValid(snapIndex) {
return snapIndex >= 0 &&
snapIndex <= getChildren().length - 1;
function watchSnapIndex() {
scope.unwatchSnapIndex = scope.$watch(
'snapIndex',
snapIndexChanged
);
}
function unwatchSnapIndex() {
if (!isFunction(scope.unwatchSnapIndex)) {
return;
}
scope.unwatchSnapIndex();
scope.unwatchSnapIndex = undefined;
}
function snapIndexChanged(current, previous) {
if (!isScrollable()) {
return;
}
if (isUndefined(current)) {
scope.snapIndex = 0;
return;
}
if (!isNumber(current)) {
if (!isNumber(previous)) {
previous = 0;
}
scope.snapIndex = previous;
return;
}
if (current % 1 !== 0) {
scope.snapIndex = Math.round(current);
return;
}
if (scope.ignoreSnapIndexChange === true) {
scope.ignoreSnapIndexChange = undefined;
return;
}
if (!isSnapIndexValid(current)) {
if (!isSnapIndexValid(previous)) {
previous = 0;
}
scope.ignoreSnapIndexChange = true;
scope.snapIndex = previous;
return;
}
scope.compositeIndex = [current, 0];
function compositeIndexChanged(current, previous) {
if (isUndefined(current)) {
return;
}
var snapIndex = current[0];
if (scope.snapIndex !== snapIndex) {
scope.ignoreSnapIndexChange = true;
scope.snapIndex = snapIndex;
}
if (scope.ignoreCompositeIndexChange === true) {
scope.ignoreCompositeIndexChange = undefined;
return;
}
snapTo(current, previous);
}
function watchSnapIndex() {
scope.unwatchSnapIndex = scope.$watch(
'snapIndex',
snapIndexChanged
);
function watchCompositeIndex() {
scope.unwatchCompositeIndex = scope.$watchCollection(
'compositeIndex',
compositeIndexChanged
);
}
function unwatchCompositeIndex() {
if (!isFunction(scope.unwatchCompositeIndex)) {
return;
}
scope.unwatchCompositeIndex();
scope.unwatchCompositeIndex = undefined;
}
function unwatchSnapIndex() {
if (!isFunction(scope.unwatchSnapIndex)) {
return;
}
scope.unwatchSnapIndex();
scope.unwatchSnapIndex = undefined;
function getMaxInnerSnapIndex(snapIndex) {
var snapHeight = getSnapHeight();
var childHeight = getChildHeight(snapIndex);
if (childHeight <= snapHeight) {
return 0;
}
var max = parseInt((childHeight / snapHeight), 10);
if (childHeight % snapHeight === 0) {
max -= 1;
}
return max;
}
function compositeIndexChanged(current, previous) {
if (isUndefined(current)) {
return;
}
var snapIndex = current[0];
if (scope.snapIndex !== snapIndex) {
scope.ignoreSnapIndexChange = true;
scope.snapIndex = snapIndex;
}
if (scope.ignoreCompositeIndexChange === true) {
scope.ignoreCompositeIndexChange = undefined;
return;
}
snapTo(current, previous);
function isCompositeIndexValid(compositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
if (innerSnapIndex < 0) {
return isSnapIndexValid(snapIndex - 1);
}
if (innerSnapIndex > getMaxInnerSnapIndex(snapIndex)) {
return isSnapIndexValid(snapIndex + 1);
}
return true;
}
function watchCompositeIndex() {
scope.unwatchCompositeIndex = scope.$watchCollection(
'compositeIndex',
compositeIndexChanged
);
function rectifyCompositeIndex(compositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
if (innerSnapIndex < 0) {
return [
snapIndex - 1,
getMaxInnerSnapIndex(snapIndex - 1)
];
}
if (innerSnapIndex > getMaxInnerSnapIndex(snapIndex)) {
return [snapIndex + 1, 0];
}
return compositeIndex;
}
function unwatchCompositeIndex() {
if (!isFunction(scope.unwatchCompositeIndex)) {
return;
}
scope.unwatchCompositeIndex();
scope.unwatchCompositeIndex = undefined;
function snap(direction, event) {
if (!isScrollable()) {
return;
}
function getMaxInnerSnapIndex(snapIndex) {
var snapHeight = getSnapHeight();
var childHeight = getChildHeight(snapIndex);
if (childHeight <= snapHeight) {
return 0;
}
var max = parseInt((childHeight / snapHeight), 10);
if (childHeight % snapHeight === 0) {
max -= 1;
}
return max;
direction === 'up' && (scope.preventDown = false);
direction === 'down' && (scope.preventUp = false);
if (scope.snapDirection === direction) {
return true;
}
function isCompositeIndexValid(compositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
if (innerSnapIndex < 0) {
return isSnapIndexValid(snapIndex - 1);
}
if (innerSnapIndex > getMaxInnerSnapIndex(snapIndex)) {
return isSnapIndexValid(snapIndex + 1);
}
if (scope.preventUp || scope.preventDown) {
return true;
}
function rectifyCompositeIndex(compositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
if (innerSnapIndex < 0) {
return [
snapIndex - 1,
getMaxInnerSnapIndex(snapIndex - 1)
];
}
if (innerSnapIndex > getMaxInnerSnapIndex(snapIndex)) {
return [snapIndex + 1, 0];
}
return compositeIndex;
var snapIndex = scope.compositeIndex[0];
var innerSnapIndex = scope.compositeIndex[1];
var newInnerSnapIndex;
if (direction === 'up') {
newInnerSnapIndex = innerSnapIndex - 1;
}
if (direction === 'down') {
newInnerSnapIndex = innerSnapIndex + 1;
}
function snap(direction, event) {
if (!isScrollable()) {
return;
}
var newCompositeIndex = [snapIndex, newInnerSnapIndex];
if (!isCompositeIndexValid(newCompositeIndex)) {
return;
}
direction === 'up' && (scope.preventDown = false);
direction === 'down' && (scope.preventUp = false);
if (event.type === 'wheel') {
direction === 'up' && (scope.preventUp = true);
direction === 'down' && (scope.preventDown = true);
}
if (scope.snapDirection === direction) {
return true;
}
scope.$apply(function () {
scope.sourceEvent = event;
scope.compositeIndex = rectifyCompositeIndex(
newCompositeIndex
);
});
if (scope.preventUp || scope.preventDown) {
return true;
}
return true;
}
var snapIndex = scope.compositeIndex[0];
var innerSnapIndex = scope.compositeIndex[1];
var newInnerSnapIndex;
if (direction === 'up') {
newInnerSnapIndex = innerSnapIndex - 1;
}
if (direction === 'down') {
newInnerSnapIndex = innerSnapIndex + 1;
}
function snapUp(event) {
return snap('up', event);
}
var newCompositeIndex = [snapIndex, newInnerSnapIndex];
if (!isCompositeIndexValid(newCompositeIndex)) {
return;
}
function snapDown(event) {
return snap('down', event);
}
if (event.type === 'wheel') {
direction === 'up' && (scope.preventUp = true);
direction === 'down' && (scope.preventDown = true);
function bindWheel() {
if (scope.disableWheelBinding || scope.wheelBound) {
return;
}
wheelie.bind(element, {
up: function (e) {
e.preventDefault();
if (snapUp(e)) {
e.stopPropagation();
}
},
down: function (e) {
e.preventDefault();
if (snapDown(e)) {
e.stopPropagation();
}
}
}, scope.ignoreWheelClass);
scope.wheelBound = true;
}
scope.$apply(function () {
scope.sourceEvent = event;
scope.compositeIndex = rectifyCompositeIndex(
newCompositeIndex
);
});
return true;
function unbindWheel() {
if (!scope.wheelBound) {
return;
}
wheelie.unbind(element);
scope.wheelBound = false;
}
function snapUp(event) {
return snap('up', event);
}
function setHeight(angularElement, height) {
angularElement.css('height', height + 'px');
}
function snapDown(event) {
return snap('down', event);
function snapHeightChanged(current, previous) {
if (isUndefined(current)) {
return;
}
function bindWheel() {
if (scope.disableWheelBinding || scope.wheelBound) {
return;
if (!isNumber(current)) {
if (isNumber(previous)) {
scope.snapHeight = previous;
}
wheelie.bind(element, {
up: function (e) {
e.preventDefault();
if (snapUp(e)) {
e.stopPropagation();
}
},
down: function (e) {
e.preventDefault();
if (snapDown(e)) {
e.stopPropagation();
}
}
}, scope.ignoreWheelClass);
scope.wheelBound = true;
return;
}
function unbindWheel() {
if (!scope.wheelBound) {
return;
setHeight(element, current);
forEach(getChildren(), function (child) {
setHeight(angular.element(child), current);
});
if (isDefined(scope.snapIndex)) {
if (isUndefined(scope.compositeIndex)) {
scope.compositeIndex = [scope.snapIndex, 0];
}
wheelie.unbind(element);
scope.wheelBound = false;
snapTo(scope.compositeIndex);
}
}
function setHeight(angularElement, height) {
angularElement.css('height', height + 'px');
function watchSnapHeight() {
scope.unwatchSnapHeight = scope.$watch(
'snapHeight',
snapHeightChanged
);
}
function unwatchSnapHeight() {
if (!isFunction(scope.unwatchSnapHeight)) {
return;
}
scope.unwatchSnapHeight();
scope.unwatchSnapHeight = undefined;
}
function snapHeightChanged(current, previous) {
if (isUndefined(current)) {
return;
function getCompositeIndex(scrollTop) {
var snapIndex = 0;
var innerSnapIndex = 0;
if (scrollTop > 0) {
snapIndex = -1;
var children = getChildren();
var childHeight;
while (scrollTop > 0) {
childHeight = getHeight(children[++snapIndex]);
scrollTop -= childHeight;
}
if (!isNumber(current)) {
if (isNumber(previous)) {
scope.snapHeight = previous;
var snapHeight = getSnapHeight();
if (childHeight > snapHeight) {
scrollTop += childHeight - snapHeight;
if (scrollTop >= snapHeight) {
innerSnapIndex++;
}
return;
while (scrollTop > 0) {
innerSnapIndex++;
scrollTop -= snapHeight;
}
if ((snapHeight / 2) >= -scrollTop) {
innerSnapIndex += 1;
}
} else if ((childHeight / 2) >= -scrollTop) {
snapIndex += 1;
}
}
setHeight(element, current);
forEach(getChildren(), function (child) {
setHeight(angular.element(child), current);
});
return rectifyCompositeIndex([snapIndex, innerSnapIndex]);
}
if (isDefined(scope.snapIndex)) {
if (isUndefined(scope.compositeIndex)) {
scope.compositeIndex = [scope.snapIndex, 0];
}
function onScroll() {
function snapFromSrollTop() {
var compositeIndex = getCompositeIndex(
getCurrentScrollTop()
);
if (scope.compositeIndex[0] === compositeIndex[0] &&
scope.compositeIndex[1] === compositeIndex[1]) {
snapTo(scope.compositeIndex);
} else {
scope.$apply(function () {
scope.compositeIndex = compositeIndex;
});
}
}
function watchSnapHeight() {
scope.unwatchSnapHeight = scope.$watch(
'snapHeight',
snapHeightChanged
scrollie.stop(element);
if (scope.scrollDelay === false) {
snapFromSrollTop();
} else {
$timeout.cancel(scope.scrollPromise);
scope.scrollPromise = $timeout(
function () {
snapFromSrollTop();
scope.scrollPromise = undefined;
},
scope.scrollDelay
);
}
}
function unwatchSnapHeight() {
if (!isFunction(scope.unwatchSnapHeight)) {
return;
}
scope.unwatchSnapHeight();
scope.unwatchSnapHeight = undefined;
function bindScroll() {
if (scope.preventSnappingAfterManualScroll ||
scope.scrollBound) {
return;
}
function getCompositeIndex(scrollTop) {
var snapIndex = 0;
var innerSnapIndex = 0;
if (scrollTop > 0) {
snapIndex = -1;
var children = getChildren();
var childHeight;
while (scrollTop > 0) {
childHeight = getHeight(children[++snapIndex]);
scrollTop -= childHeight;
}
var snapHeight = getSnapHeight();
if (childHeight > snapHeight) {
scrollTop += childHeight - snapHeight;
if (scrollTop >= snapHeight) {
innerSnapIndex++;
}
while (scrollTop > 0) {
innerSnapIndex++;
scrollTop -= snapHeight;
}
if ((snapHeight / 2) >= -scrollTop) {
innerSnapIndex += 1;
}
} else if ((childHeight / 2) >= -scrollTop) {
snapIndex += 1;
}
}
return rectifyCompositeIndex([snapIndex, innerSnapIndex]);
if (isDefined(scope.snapDirection)) { // still snapping
// TODO: add tests for this
bindScrollAfterDelay();
return;
}
element.on('scroll', onScroll);
scope.scrollBound = true;
}
function onScroll() {
function snapFromSrollTop() {
var compositeIndex = getCompositeIndex(
getCurrentScrollTop()
);
if (scope.compositeIndex[0] === compositeIndex[0] &&
scope.compositeIndex[1] === compositeIndex[1]) {
snapTo(scope.compositeIndex);
} else {
scope.$apply(function () {
scope.compositeIndex = compositeIndex;
});
}
}
scrollie.stop(element);
if (scope.scrollDelay === false) {
snapFromSrollTop();
} else {
$timeout.cancel(scope.scrollPromise);
scope.scrollPromise = $timeout(
function () {
snapFromSrollTop();
scope.scrollPromise = undefined;
},
scope.scrollDelay
);
}
function unbindScroll() {
if (!scope.scrollBound) {
return;
}
element.off('scroll', onScroll);
scope.scrollBound = false;
}
function bindScroll() {
if (scope.preventSnappingAfterManualScroll ||
scope.scrollBound) {
return;
}
if (isDefined(scope.snapDirection)) { // still snapping
// TODO: add tests for this
bindScrollAfterDelay();
return;
}
element.on('scroll', onScroll);
scope.scrollBound = true;
function bindScrollAfterDelay() {
if (scope.preventSnappingAfterManualScroll) {
return;
}
function unbindScroll() {
if (!scope.scrollBound) {
return;
}
element.off('scroll', onScroll);
scope.scrollBound = false;
if (scope.bindScrollPromise) {
$timeout.cancel(scope.bindScrollPromise);
}
scope.bindScrollPromise = $timeout(
function () {
bindScroll();
scope.bindScrollPromise = undefined;
},
defaultSnapscrollBindScrollTimeout
);
}
function bindScrollAfterDelay() {
if (scope.preventSnappingAfterManualScroll) {
return;
}
if (scope.bindScrollPromise) {
$timeout.cancel(scope.bindScrollPromise);
}
scope.bindScrollPromise = $timeout(
function () {
bindScroll();
scope.bindScrollPromise = undefined;
},
defaultSnapscrollBindScrollTimeout
);
function onKeyDown(e) {
if (e.originalEvent) {
e = e.originalEvent;
}
var handler;
var keyCode = e.keyCode;
if (keyCode === 38) {
handler = snapUp;
}
if (keyCode === 40) {
handler = snapDown;
}
if (handler) {
e.preventDefault();
handler(e);
}
}
function onKeyDown(e) {
if (e.originalEvent) {
e = e.originalEvent;
}
var handler;
var keyCode = e.keyCode;
if (keyCode === 38) {
handler = snapUp;
}
if (keyCode === 40) {
handler = snapDown;
}
if (handler) {
e.preventDefault();
handler(e);
}
function bindArrowKeys() {
if (!scope.enableArrowKeys || scope.arrowKeysBound) {
return;
}
$document.on('keydown', onKeyDown);
scope.arrowKeysBound = true;
}
function bindArrowKeys() {
if (!scope.enableArrowKeys || scope.arrowKeysBound) {
return;
}
$document.on('keydown', onKeyDown);
scope.arrowKeysBound = true;
function unbindArrowKeys() {
if (!scope.arrowKeysBound) {
return;
}
$document.off('keydown', onKeyDown);
scope.arrowKeysBound = false;
}
function unbindArrowKeys() {
if (!scope.arrowKeysBound) {
return;
function init() {
var scrollDelay = attributes.scrollDelay;
if (scrollDelay === 'false') {
scope.scrollDelay = false;
} else {
scrollDelay = parseInt(scrollDelay, 10);
if (isNaN(scrollDelay)) {
scrollDelay = defaultSnapscrollScrollDelay;
}
$document.off('keydown', onKeyDown);
scope.arrowKeysBound = false;
scope.scrollDelay = scrollDelay;
}
function init() {
var scrollDelay = attributes.scrollDelay;
if (scrollDelay === 'false') {
scope.scrollDelay = false;
} else {
scrollDelay = parseInt(scrollDelay, 10);
if (isNaN(scrollDelay)) {
scrollDelay = defaultSnapscrollScrollDelay;
}
scope.scrollDelay = scrollDelay;
}
var preventDoubleSnapDelay = (
attributes.preventDoubleSnapDelay
var preventDoubleSnapDelay = (
attributes.preventDoubleSnapDelay
);
if (preventDoubleSnapDelay === 'false') {
scope.preventDoubleSnapDelay = false;
} else {
preventDoubleSnapDelay = parseInt(
preventDoubleSnapDelay,
10
);
if (preventDoubleSnapDelay === 'false') {
scope.preventDoubleSnapDelay = false;
} else {
preventDoubleSnapDelay = parseInt(
preventDoubleSnapDelay,
10
if (isNaN(preventDoubleSnapDelay)) {
preventDoubleSnapDelay = (
defaultSnapscrollPreventDoubleSnapDelay
);
if (isNaN(preventDoubleSnapDelay)) {
preventDoubleSnapDelay = (
defaultSnapscrollPreventDoubleSnapDelay
);
}
scope.preventDoubleSnapDelay = preventDoubleSnapDelay;
}
scope.preventDoubleSnapDelay = preventDoubleSnapDelay;
}
var snapEasing = attributes.snapEasing;
if (isDefined(snapEasing)) {
scope.snapEasing = scope.$parent.$eval(snapEasing);
} else if (isFunction(defaultSnapscrollScrollEasing)) {
scope.snapEasing = defaultSnapscrollScrollEasing;
}
var snapEasing = attributes.snapEasing;
if (isDefined(snapEasing)) {
scope.snapEasing = scope.$parent.$eval(snapEasing);
} else if (isFunction(defaultSnapscrollScrollEasing)) {
scope.snapEasing = defaultSnapscrollScrollEasing;
}
var snapDuration = parseInt(attributes.snapDuration, 10);
if (isNaN(snapDuration)) {
snapDuration = defaultSnapscrollSnapDuration;
}
scope.snapDuration = snapDuration;
var snapDuration = parseInt(attributes.snapDuration, 10);
if (isNaN(snapDuration)) {
snapDuration = defaultSnapscrollSnapDuration;
}
scope.snapDuration = snapDuration;
// TODO: perform initial snap without animation
if (isUndefined(scope.snapAnimation)) {
scope.snapAnimation = true;
}
// TODO: perform initial snap without animation
if (isUndefined(scope.snapAnimation)) {
scope.snapAnimation = true;
}
scope.disableWheelBinding = isDefined(
attributes.disableWheelBinding
);
scope.disableWheelBinding = isDefined(
attributes.disableWheelBinding
);
scope.enableArrowKeys = isDefined(
attributes.enableArrowKeys
);
scope.enableArrowKeys = isDefined(
attributes.enableArrowKeys
);
scope.preventSnappingAfterManualScroll = isDefined(
attributes.preventSnappingAfterManualScroll
);
scope.preventSnappingAfterManualScroll = isDefined(
attributes.preventSnappingAfterManualScroll
);
scope.ignoreWheelClass = attributes.ignoreWheelClass;
scope.ignoreWheelClass = attributes.ignoreWheelClass;
if (element.css('overflowY') !== 'scroll') {
element.css('overflowY', 'auto');
}
if (element.css('overflowY') !== 'scroll') {
element.css('overflowY', 'auto');
}
scope.$watch('enabled', function (current, previous) {
function updateCompositeIndexFromScrollTop() {
if (scope.preventSnappingAfterManualScroll) {
return;
}
scope.compositeIndex = getCompositeIndex(
getCurrentScrollTop()
);
scope.$watch('enabled', function (current, previous) {
function updateCompositeIndexFromScrollTop() {
if (scope.preventSnappingAfterManualScroll) {
return;
}
if (current !== false) {
if (previous === false) {
updateCompositeIndexFromScrollTop();
}
watchCompositeIndex();
watchSnapIndex();
watchSnapHeight();
bindScroll();
bindWheel();
bindArrowKeys();
} else {
unwatchCompositeIndex();
unwatchSnapIndex();
unwatchSnapHeight();
unbindScroll();
unbindWheel();
unbindArrowKeys();
scope.compositeIndex = getCompositeIndex(
getCurrentScrollTop()
);
}
if (current !== false) {
if (previous === false) {
updateCompositeIndexFromScrollTop();
}
});
watchCompositeIndex();
watchSnapIndex();
watchSnapHeight();
bindScroll();
bindWheel();
bindArrowKeys();
} else {
unwatchCompositeIndex();
unwatchSnapIndex();
unwatchSnapHeight();
unbindScroll();
unbindWheel();
unbindArrowKeys();
}
});
scope.$on('$destroy', function () {
if (scope.enabled !== false) {
unbindScroll();
unbindWheel();
unbindArrowKeys();
}
});
}
init();
scope.$on('$destroy', function () {
if (scope.enabled !== false) {
unbindScroll();
unbindWheel();
unbindArrowKeys();
}
});
}
};
}
];
angular.module('snapscroll')
.directive('snapscroll', snapscrollAsAnAttribute);
})();
init();
}
};
}
]);

@@ -1,2 +0,2 @@

/* angular-snapscroll v1.2.0, (c) 2014-2016 Joel Mukuthu, MIT License, built: 12-12-2016 21:13:13 GMT+0100 */
!function(){angular.module("snapscroll",["wheelie","scrollie"]).value("defaultSnapscrollScrollEasing",void 0).value("defaultSnapscrollScrollDelay",250).value("defaultSnapscrollSnapDuration",800).value("defaultSnapscrollResizeDelay",400).value("defaultSnapscrollBindScrollTimeout",400).value("defaultSnapscrollPreventDoubleSnapDelay",1e3)}(),function(){angular.module("snapscroll").directive("fitWindowHeight",["$window","$timeout","defaultSnapscrollResizeDelay",function(a,b,c){return{restrict:"A",require:"snapscroll",link:function(d,e,f,g){function h(){l===!1?g.setSnapHeight(a.innerHeight):(b.cancel(k),k=b(function(){g.setSnapHeight(a.innerHeight)},l))}function i(){"false"===l?l=!1:(l=parseInt(l,10),isNaN(l)&&(l=c)),g.setSnapHeight(a.innerHeight),j=angular.element(a),j.on("resize",h),d.$on("$destroy",function(){j.off("resize")})}var j,k,l=f.resizeDelay;i()}}}])}(),function(){function a(a){return angular.isNumber(a)&&!isNaN(a)}var b=angular.isDefined,c=angular.isUndefined,d=angular.isFunction,e=angular.forEach,f={enabled:"=snapscroll",snapIndex:"=?",snapHeight:"=?",beforeSnap:"&",afterSnap:"&",snapAnimation:"=?"},g=["$scope",function(a){this.setSnapHeight=function(b){a.snapHeight=b}}],h=["$timeout","$document","wheelie","scrollie","defaultSnapscrollScrollEasing","defaultSnapscrollScrollDelay","defaultSnapscrollSnapDuration","defaultSnapscrollBindScrollTimeout","defaultSnapscrollPreventDoubleSnapDelay",function(h,i,j,k,l,m,n,o,p){return{restrict:"A",scope:f,controller:g,link:function(f,g,q){function r(){return g.children()}function s(a){return a.offsetHeight}function t(a){return s(r()[a])}function u(){return s(g[0])}function v(){return g[0].scrollHeight}function w(a){var b=v()-u();return a>b?b:a}function x(a,c){for(var d=a[0],e=a[1],f=0,g=r(),h=0;h<d;h++)f+=s(g[h]);if(0===e)return w(f);var i,j=u(),k=s(g[d]);if(b(c)&&e<c[1]){i=k;for(var l=e;l>=0;l--)i-=j}else{i=0;for(var m=0;m<e;m++)i+=j;var n=i+j-k;n>0&&(i-=n)}return w(f+i)}function y(d,e){var g=d[0],h=c(e)||g!==e[0];if(h){var i=f.beforeSnap({snapIndex:g,$event:f.sourceEvent});if(i===!1)return void(b(e)&&(f.ignoreCompositeIndexChange=!0,f.compositeIndex=e));if(a(i))return void(f.snapIndex=i)}return A(x(d,e)).then(function(){h&&f.afterSnap({snapIndex:g,$event:f.sourceEvent}),f.sourceEvent=void 0})}function z(){return g[0].scrollTop}function A(a){var b;b=f.snapAnimation?c(f.snapEasing)?[g,a,f.snapDuration]:[g,a,f.snapDuration,f.snapEasing]:[g,a];var d=z();return a>d?f.snapDirection="down":a<d?f.snapDirection="up":f.snapDirection="same",Z(),k.to.apply(k,b).then(function(){f.snapDirection=void 0,$(),B()})}function B(){function a(){f.preventUp=!1,f.preventDown=!1}(f.preventUp||f.preventDown)&&(f.preventDoubleSnapDelay===!1?a():h(a,f.preventDoubleSnapDelay))}function C(){var a=u();if(!a)return!1;var b=r();if(!b.length)return!1;var c=0;return e(b,function(a){c+=s(a)}),!(c<a)}function D(a){return a>=0&&a<=r().length-1}function E(b,d){if(C())return c(b)?void(f.snapIndex=0):a(b)?b%1!==0?void(f.snapIndex=Math.round(b)):f.ignoreSnapIndexChange===!0?void(f.ignoreSnapIndexChange=void 0):D(b)?void(f.compositeIndex=[b,0]):(D(d)||(d=0),f.ignoreSnapIndexChange=!0,void(f.snapIndex=d)):(a(d)||(d=0),void(f.snapIndex=d))}function F(){f.unwatchSnapIndex=f.$watch("snapIndex",E)}function G(){d(f.unwatchSnapIndex)&&(f.unwatchSnapIndex(),f.unwatchSnapIndex=void 0)}function H(a,b){if(!c(a)){var d=a[0];return f.snapIndex!==d&&(f.ignoreSnapIndexChange=!0,f.snapIndex=d),f.ignoreCompositeIndexChange===!0?void(f.ignoreCompositeIndexChange=void 0):void y(a,b)}}function I(){f.unwatchCompositeIndex=f.$watchCollection("compositeIndex",H)}function J(){d(f.unwatchCompositeIndex)&&(f.unwatchCompositeIndex(),f.unwatchCompositeIndex=void 0)}function K(a){var b=u(),c=t(a);if(c<=b)return 0;var d=parseInt(c/b,10);return c%b===0&&(d-=1),d}function L(a){var b=a[0],c=a[1];return c<0?D(b-1):!(c>K(b))||D(b+1)}function M(a){var b=a[0],c=a[1];return c<0?[b-1,K(b-1)]:c>K(b)?[b+1,0]:a}function N(a,b){if(C()){if("up"===a&&(f.preventDown=!1),"down"===a&&(f.preventUp=!1),f.snapDirection===a)return!0;if(f.preventUp||f.preventDown)return!0;var c,d=f.compositeIndex[0],e=f.compositeIndex[1];"up"===a&&(c=e-1),"down"===a&&(c=e+1);var g=[d,c];if(L(g))return"wheel"===b.type&&("up"===a&&(f.preventUp=!0),"down"===a&&(f.preventDown=!0)),f.$apply(function(){f.sourceEvent=b,f.compositeIndex=M(g)}),!0}}function O(a){return N("up",a)}function P(a){return N("down",a)}function Q(){f.disableWheelBinding||f.wheelBound||(j.bind(g,{up:function(a){a.preventDefault(),O(a)&&a.stopPropagation()},down:function(a){a.preventDefault(),P(a)&&a.stopPropagation()}},f.ignoreWheelClass),f.wheelBound=!0)}function R(){f.wheelBound&&(j.unbind(g),f.wheelBound=!1)}function S(a,b){a.css("height",b+"px")}function T(d,h){if(!c(d)){if(!a(d))return void(a(h)&&(f.snapHeight=h));S(g,d),e(r(),function(a){S(angular.element(a),d)}),b(f.snapIndex)&&(c(f.compositeIndex)&&(f.compositeIndex=[f.snapIndex,0]),y(f.compositeIndex))}}function U(){f.unwatchSnapHeight=f.$watch("snapHeight",T)}function V(){d(f.unwatchSnapHeight)&&(f.unwatchSnapHeight(),f.unwatchSnapHeight=void 0)}function W(a){var b=0,c=0;if(a>0){b=-1;for(var d,e=r();a>0;)d=s(e[++b]),a-=d;var f=u();if(d>f){for(a+=d-f,a>=f&&c++;a>0;)c++,a-=f;f/2>=-a&&(c+=1)}else d/2>=-a&&(b+=1)}return M([b,c])}function X(){function a(){var a=W(z());f.compositeIndex[0]===a[0]&&f.compositeIndex[1]===a[1]?y(f.compositeIndex):f.$apply(function(){f.compositeIndex=a})}k.stop(g),f.scrollDelay===!1?a():(h.cancel(f.scrollPromise),f.scrollPromise=h(function(){a(),f.scrollPromise=void 0},f.scrollDelay))}function Y(){if(!f.preventSnappingAfterManualScroll&&!f.scrollBound){if(b(f.snapDirection))return void $();g.on("scroll",X),f.scrollBound=!0}}function Z(){f.scrollBound&&(g.off("scroll",X),f.scrollBound=!1)}function $(){f.preventSnappingAfterManualScroll||(f.bindScrollPromise&&h.cancel(f.bindScrollPromise),f.bindScrollPromise=h(function(){Y(),f.bindScrollPromise=void 0},o))}function _(a){a.originalEvent&&(a=a.originalEvent);var b,c=a.keyCode;38===c&&(b=O),40===c&&(b=P),b&&(a.preventDefault(),b(a))}function aa(){f.enableArrowKeys&&!f.arrowKeysBound&&(i.on("keydown",_),f.arrowKeysBound=!0)}function ba(){f.arrowKeysBound&&(i.off("keydown",_),f.arrowKeysBound=!1)}function ca(){var a=q.scrollDelay;"false"===a?f.scrollDelay=!1:(a=parseInt(a,10),isNaN(a)&&(a=m),f.scrollDelay=a);var e=q.preventDoubleSnapDelay;"false"===e?f.preventDoubleSnapDelay=!1:(e=parseInt(e,10),isNaN(e)&&(e=p),f.preventDoubleSnapDelay=e);var h=q.snapEasing;b(h)?f.snapEasing=f.$parent.$eval(h):d(l)&&(f.snapEasing=l);var i=parseInt(q.snapDuration,10);isNaN(i)&&(i=n),f.snapDuration=i,c(f.snapAnimation)&&(f.snapAnimation=!0),f.disableWheelBinding=b(q.disableWheelBinding),f.enableArrowKeys=b(q.enableArrowKeys),f.preventSnappingAfterManualScroll=b(q.preventSnappingAfterManualScroll),f.ignoreWheelClass=q.ignoreWheelClass,"scroll"!==g.css("overflowY")&&g.css("overflowY","auto"),f.$watch("enabled",function(a,b){function c(){f.preventSnappingAfterManualScroll||(f.compositeIndex=W(z()))}a!==!1?(b===!1&&c(),I(),F(),U(),Y(),Q(),aa()):(J(),G(),V(),Z(),R(),ba())}),f.$on("$destroy",function(){f.enabled!==!1&&(Z(),R(),ba())})}ca()}}}];angular.module("snapscroll").directive("snapscroll",h)}();
/* angular-snapscroll v1.3.0, (c) 2014-2017 Joel Mukuthu, MIT License, built: 06-03-2017 12:22:02 GMT+0100 */
"object"==typeof exports&&(module.exports="snapscroll"),angular.module("snapscroll",["wheelie","scrollie"]).value("defaultSnapscrollScrollEasing",void 0).value("defaultSnapscrollScrollDelay",250).value("defaultSnapscrollSnapDuration",800).value("defaultSnapscrollResizeDelay",400).value("defaultSnapscrollBindScrollTimeout",400).value("defaultSnapscrollPreventDoubleSnapDelay",1e3),angular.module("snapscroll").directive("fitWindowHeight",["$window","$timeout","defaultSnapscrollResizeDelay",function(a,b,c){return{restrict:"A",require:"snapscroll",link:function(d,e,f,g){function h(){l===!1?g.setSnapHeight(a.innerHeight):(b.cancel(k),k=b(function(){g.setSnapHeight(a.innerHeight)},l))}function i(){"false"===l?l=!1:(l=parseInt(l,10),isNaN(l)&&(l=c)),g.setSnapHeight(a.innerHeight),j=angular.element(a),j.on("resize",h),d.$on("$destroy",function(){j.off("resize")})}var j,k,l=f.resizeDelay;i()}}}]),angular.module("snapscroll").directive("snapscroll",["$timeout","$document","wheelie","scrollie","defaultSnapscrollScrollEasing","defaultSnapscrollScrollDelay","defaultSnapscrollSnapDuration","defaultSnapscrollBindScrollTimeout","defaultSnapscrollPreventDoubleSnapDelay",function(a,b,c,d,e,f,g,h,i){function j(a){return angular.isNumber(a)&&!isNaN(a)}var k=angular.isDefined,l=angular.isUndefined,m=angular.isFunction,n=angular.forEach;return{restrict:"A",scope:{enabled:"=snapscroll",snapIndex:"=?",snapHeight:"=?",beforeSnap:"&",afterSnap:"&",snapAnimation:"=?"},controller:["$scope",function(a){this.setSnapHeight=function(b){a.snapHeight=b}}],link:function(o,p,q){function r(){return p.children()}function s(a){return a.offsetHeight}function t(a){return s(r()[a])}function u(){return s(p[0])}function v(){return p[0].scrollHeight}function w(a){var b=v()-u();return a>b?b:a}function x(a,b){for(var c=a[0],d=a[1],e=0,f=r(),g=0;g<c;g++)e+=s(f[g]);if(0===d)return w(e);var h,i=u(),j=s(f[c]);if(k(b)&&d<b[1]){h=j;for(var l=d;l>=0;l--)h-=i}else{h=0;for(var m=0;m<d;m++)h+=i;var n=h+i-j;n>0&&(h-=n)}return w(e+h)}function y(a,b){var c=a[0],d=l(b)||c!==b[0];if(d){var e=o.beforeSnap({snapIndex:c,$event:o.sourceEvent});if(e===!1)return void(k(b)&&(o.ignoreCompositeIndexChange=!0,o.compositeIndex=b));if(j(e))return void(o.snapIndex=e)}return A(x(a,b)).then(function(){d&&o.afterSnap({snapIndex:c,$event:o.sourceEvent}),o.sourceEvent=void 0})}function z(){return p[0].scrollTop}function A(a){var b;b=o.snapAnimation?l(o.snapEasing)?[p,a,o.snapDuration]:[p,a,o.snapDuration,o.snapEasing]:[p,a];var c=z();return o.snapDirection=a>c?"down":a<c?"up":"same",Z(),d.to.apply(d,b).then(function(){o.snapDirection=void 0,$(),B()})}function B(){function b(){o.preventUp=!1,o.preventDown=!1}(o.preventUp||o.preventDown)&&(o.preventDoubleSnapDelay===!1?b():a(b,o.preventDoubleSnapDelay))}function C(){var a=u();if(!a)return!1;var b=r();if(!b.length)return!1;var c=0;return n(b,function(a){c+=s(a)}),!(c<a)}function D(a){return a>=0&&a<=r().length-1}function E(a,b){if(C())return l(a)?void(o.snapIndex=0):j(a)?a%1!=0?void(o.snapIndex=Math.round(a)):o.ignoreSnapIndexChange===!0?void(o.ignoreSnapIndexChange=void 0):D(a)?void(o.compositeIndex=[a,0]):(D(b)||(b=0),o.ignoreSnapIndexChange=!0,void(o.snapIndex=b)):(j(b)||(b=0),void(o.snapIndex=b))}function F(){o.unwatchSnapIndex=o.$watch("snapIndex",E)}function G(){m(o.unwatchSnapIndex)&&(o.unwatchSnapIndex(),o.unwatchSnapIndex=void 0)}function H(a,b){if(!l(a)){var c=a[0];if(o.snapIndex!==c&&(o.ignoreSnapIndexChange=!0,o.snapIndex=c),o.ignoreCompositeIndexChange===!0)return void(o.ignoreCompositeIndexChange=void 0);y(a,b)}}function I(){o.unwatchCompositeIndex=o.$watchCollection("compositeIndex",H)}function J(){m(o.unwatchCompositeIndex)&&(o.unwatchCompositeIndex(),o.unwatchCompositeIndex=void 0)}function K(a){var b=u(),c=t(a);if(c<=b)return 0;var d=parseInt(c/b,10);return c%b==0&&(d-=1),d}function L(a){var b=a[0],c=a[1];return c<0?D(b-1):!(c>K(b))||D(b+1)}function M(a){var b=a[0],c=a[1];return c<0?[b-1,K(b-1)]:c>K(b)?[b+1,0]:a}function N(a,b){if(C()){if("up"===a&&(o.preventDown=!1),"down"===a&&(o.preventUp=!1),o.snapDirection===a)return!0;if(o.preventUp||o.preventDown)return!0;var c,d=o.compositeIndex[0],e=o.compositeIndex[1];"up"===a&&(c=e-1),"down"===a&&(c=e+1);var f=[d,c];if(L(f))return"wheel"===b.type&&("up"===a&&(o.preventUp=!0),"down"===a&&(o.preventDown=!0)),o.$apply(function(){o.sourceEvent=b,o.compositeIndex=M(f)}),!0}}function O(a){return N("up",a)}function P(a){return N("down",a)}function Q(){o.disableWheelBinding||o.wheelBound||(c.bind(p,{up:function(a){a.preventDefault(),O(a)&&a.stopPropagation()},down:function(a){a.preventDefault(),P(a)&&a.stopPropagation()}},o.ignoreWheelClass),o.wheelBound=!0)}function R(){o.wheelBound&&(c.unbind(p),o.wheelBound=!1)}function S(a,b){a.css("height",b+"px")}function T(a,b){if(!l(a)){if(!j(a))return void(j(b)&&(o.snapHeight=b));S(p,a),n(r(),function(b){S(angular.element(b),a)}),k(o.snapIndex)&&(l(o.compositeIndex)&&(o.compositeIndex=[o.snapIndex,0]),y(o.compositeIndex))}}function U(){o.unwatchSnapHeight=o.$watch("snapHeight",T)}function V(){m(o.unwatchSnapHeight)&&(o.unwatchSnapHeight(),o.unwatchSnapHeight=void 0)}function W(a){var b=0,c=0;if(a>0){b=-1;for(var d,e=r();a>0;)d=s(e[++b]),a-=d;var f=u();if(d>f){for(a+=d-f,a>=f&&c++;a>0;)c++,a-=f;f/2>=-a&&(c+=1)}else d/2>=-a&&(b+=1)}return M([b,c])}function X(){function b(){var a=W(z());o.compositeIndex[0]===a[0]&&o.compositeIndex[1]===a[1]?y(o.compositeIndex):o.$apply(function(){o.compositeIndex=a})}d.stop(p),o.scrollDelay===!1?b():(a.cancel(o.scrollPromise),o.scrollPromise=a(function(){b(),o.scrollPromise=void 0},o.scrollDelay))}function Y(){if(!o.preventSnappingAfterManualScroll&&!o.scrollBound){if(k(o.snapDirection))return void $();p.on("scroll",X),o.scrollBound=!0}}function Z(){o.scrollBound&&(p.off("scroll",X),o.scrollBound=!1)}function $(){o.preventSnappingAfterManualScroll||(o.bindScrollPromise&&a.cancel(o.bindScrollPromise),o.bindScrollPromise=a(function(){Y(),o.bindScrollPromise=void 0},h))}function _(a){a.originalEvent&&(a=a.originalEvent);var b,c=a.keyCode;38===c&&(b=O),40===c&&(b=P),b&&(a.preventDefault(),b(a))}function aa(){o.enableArrowKeys&&!o.arrowKeysBound&&(b.on("keydown",_),o.arrowKeysBound=!0)}function ba(){o.arrowKeysBound&&(b.off("keydown",_),o.arrowKeysBound=!1)}function ca(){var a=q.scrollDelay;"false"===a?o.scrollDelay=!1:(a=parseInt(a,10),isNaN(a)&&(a=f),o.scrollDelay=a);var b=q.preventDoubleSnapDelay;"false"===b?o.preventDoubleSnapDelay=!1:(b=parseInt(b,10),isNaN(b)&&(b=i),o.preventDoubleSnapDelay=b);var c=q.snapEasing;k(c)?o.snapEasing=o.$parent.$eval(c):m(e)&&(o.snapEasing=e);var d=parseInt(q.snapDuration,10);isNaN(d)&&(d=g),o.snapDuration=d,l(o.snapAnimation)&&(o.snapAnimation=!0),o.disableWheelBinding=k(q.disableWheelBinding),o.enableArrowKeys=k(q.enableArrowKeys),o.preventSnappingAfterManualScroll=k(q.preventSnappingAfterManualScroll),o.ignoreWheelClass=q.ignoreWheelClass,"scroll"!==p.css("overflowY")&&p.css("overflowY","auto"),o.$watch("enabled",function(a,b){function c(){o.preventSnappingAfterManualScroll||(o.compositeIndex=W(z()))}a!==!1?(b===!1&&c(),I(),F(),U(),Y(),Q(),aa()):(J(),G(),V(),Z(),R(),ba())}),o.$on("$destroy",function(){o.enabled!==!1&&(Z(),R(),ba())})}ca()}}}]);
The MIT License
Copyright (c) 2014 - 2016, Joel Mukuthu.
Copyright (c) 2014 - 2017, Joel Mukuthu.

@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

{
"name": "angular-snapscroll",
"version": "1.2.0",
"version": "1.3.0",
"description": "Vertical scroll-and-snap functionality in angular",

@@ -39,4 +39,4 @@ "main": "dist/angular-snapscroll.js",

"angular": "^1.2.24",
"angular-scrollie": "^1.0.0",
"angular-wheelie": "^2.1.0"
"angular-scrollie": "^1.1.1",
"angular-wheelie": "^3.0.1"
},

@@ -43,0 +43,0 @@ "repository": {

@@ -1,57 +0,54 @@

(function () {
angular.module('snapscroll')
.directive('fitWindowHeight', [
'$window',
'$timeout',
'defaultSnapscrollResizeDelay',
function (
$window,
$timeout,
defaultSnapscrollResizeDelay
) {
return {
restrict: 'A',
require: 'snapscroll',
link: function (scope, element, attributes, snapscroll) {
var windowElement,
resizePromise,
resizeDelay = attributes.resizeDelay;
angular.module('snapscroll').directive('fitWindowHeight', [
'$window',
'$timeout',
'defaultSnapscrollResizeDelay',
function (
$window,
$timeout,
defaultSnapscrollResizeDelay
) {
return {
restrict: 'A',
require: 'snapscroll',
link: function (scope, element, attributes, snapscroll) {
var windowElement,
resizePromise,
resizeDelay = attributes.resizeDelay;
function onWindowResize() {
if (resizeDelay === false) {
function onWindowResize() {
if (resizeDelay === false) {
snapscroll.setSnapHeight($window.innerHeight);
} else {
$timeout.cancel(resizePromise);
resizePromise = $timeout(function () {
snapscroll.setSnapHeight($window.innerHeight);
} else {
$timeout.cancel(resizePromise);
resizePromise = $timeout(function () {
snapscroll.setSnapHeight($window.innerHeight);
}, resizeDelay);
}
}, resizeDelay);
}
}
function init() {
if (resizeDelay === 'false') {
resizeDelay = false;
} else {
resizeDelay = parseInt(resizeDelay, 10);
if (isNaN(resizeDelay)) {
resizeDelay = defaultSnapscrollResizeDelay;
}
function init() {
if (resizeDelay === 'false') {
resizeDelay = false;
} else {
resizeDelay = parseInt(resizeDelay, 10);
if (isNaN(resizeDelay)) {
resizeDelay = defaultSnapscrollResizeDelay;
}
}
// set initial snapHeight
snapscroll.setSnapHeight($window.innerHeight);
// set initial snapHeight
snapscroll.setSnapHeight($window.innerHeight);
// update snapHeight on window resize
windowElement = angular.element($window);
windowElement.on('resize', onWindowResize);
scope.$on('$destroy', function () {
windowElement.off('resize');
});
}
init();
// update snapHeight on window resize
windowElement = angular.element($window);
windowElement.on('resize', onWindowResize);
scope.$on('$destroy', function () {
windowElement.off('resize');
});
}
};
}]);
})();
init();
}
};
}
]);

@@ -1,733 +0,724 @@

(function () {
function isNumber(value) {
return angular.isNumber(value) && !isNaN(value);
}
angular.module('snapscroll').directive('snapscroll', [
'$timeout',
'$document',
'wheelie',
'scrollie',
'defaultSnapscrollScrollEasing',
'defaultSnapscrollScrollDelay',
'defaultSnapscrollSnapDuration',
'defaultSnapscrollBindScrollTimeout',
'defaultSnapscrollPreventDoubleSnapDelay',
function (
$timeout,
$document,
wheelie,
scrollie,
defaultSnapscrollScrollEasing,
defaultSnapscrollScrollDelay,
defaultSnapscrollSnapDuration,
defaultSnapscrollBindScrollTimeout,
defaultSnapscrollPreventDoubleSnapDelay
) {
function isNumber(value) {
return angular.isNumber(value) && !isNaN(value);
}
var isDefined = angular.isDefined;
var isUndefined = angular.isUndefined;
var isFunction = angular.isFunction;
var forEach = angular.forEach;
var isDefined = angular.isDefined;
var isUndefined = angular.isUndefined;
var isFunction = angular.isFunction;
var forEach = angular.forEach;
var scopeObject = {
enabled: '=snapscroll',
snapIndex: '=?',
snapHeight: '=?',
beforeSnap: '&',
afterSnap: '&',
snapAnimation: '=?'
};
return {
restrict: 'A',
scope: {
enabled: '=snapscroll',
snapIndex: '=?',
snapHeight: '=?',
beforeSnap: '&',
afterSnap: '&',
snapAnimation: '=?'
},
controller: ['$scope', function ($scope) {
this.setSnapHeight = function (height) {
$scope.snapHeight = height;
};
}],
link: function (scope, element, attributes) {
function getChildren() {
return element.children();
}
var controller = ['$scope', function ($scope) {
this.setSnapHeight = function (height) {
$scope.snapHeight = height;
};
}];
function getHeight(domElement) {
return domElement.offsetHeight;
}
var snapscrollAsAnAttribute = [
'$timeout',
'$document',
'wheelie',
'scrollie',
'defaultSnapscrollScrollEasing',
'defaultSnapscrollScrollDelay',
'defaultSnapscrollSnapDuration',
'defaultSnapscrollBindScrollTimeout',
'defaultSnapscrollPreventDoubleSnapDelay',
function (
$timeout,
$document,
wheelie,
scrollie,
defaultSnapscrollScrollEasing,
defaultSnapscrollScrollDelay,
defaultSnapscrollSnapDuration,
defaultSnapscrollBindScrollTimeout,
defaultSnapscrollPreventDoubleSnapDelay
) {
return {
restrict: 'A',
scope: scopeObject,
controller: controller,
link: function (scope, element, attributes) {
function getChildren() {
return element.children();
}
function getChildHeight(snapIndex) {
return getHeight(getChildren()[snapIndex]);
}
function getHeight(domElement) {
return domElement.offsetHeight;
}
function getSnapHeight() {
return getHeight(element[0]);
}
function getChildHeight(snapIndex) {
return getHeight(getChildren()[snapIndex]);
function getScrollHeight() {
return element[0].scrollHeight;
}
function rectifyScrollTop(scrollTop) {
var maxScrollTop = getScrollHeight() - getSnapHeight();
if (scrollTop > maxScrollTop) {
return maxScrollTop;
}
return scrollTop;
}
function getSnapHeight() {
return getHeight(element[0]);
function getScrollTop(compositeIndex, previousCompositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
var scrollTop = 0;
var children = getChildren();
for (var i = 0; i < snapIndex; i++) {
scrollTop += getHeight(children[i]);
}
function getScrollHeight() {
return element[0].scrollHeight;
if (innerSnapIndex === 0) {
return rectifyScrollTop(scrollTop);
}
function rectifyScrollTop(scrollTop) {
var maxScrollTop = getScrollHeight() - getSnapHeight();
if (scrollTop > maxScrollTop) {
return maxScrollTop;
var snapHeight = getSnapHeight();
var childHeight = getHeight(children[snapIndex]);
var innerScrollTop;
if (isDefined(previousCompositeIndex) &&
innerSnapIndex < previousCompositeIndex[1]) {
innerScrollTop = childHeight;
for (var j = innerSnapIndex; j >= 0; j--) {
innerScrollTop -= snapHeight;
}
return scrollTop;
} else {
innerScrollTop = 0;
for (var k = 0; k < innerSnapIndex; k++) {
innerScrollTop += snapHeight;
}
var overflow = innerScrollTop + snapHeight - childHeight;
if (overflow > 0) {
innerScrollTop -= overflow;
}
}
function getScrollTop(compositeIndex, previousCompositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
return rectifyScrollTop(scrollTop + innerScrollTop);
}
var scrollTop = 0;
var children = getChildren();
for (var i = 0; i < snapIndex; i++) {
scrollTop += getHeight(children[i]);
function snapTo(compositeIndex, previousCompositeIndex) {
var snapIndex = compositeIndex[0];
var isSnapIndexChanged = isUndefined(previousCompositeIndex) ||
snapIndex !== previousCompositeIndex[0];
if (isSnapIndexChanged) {
var returnValue = scope.beforeSnap({
snapIndex: snapIndex,
$event: scope.sourceEvent
});
if (returnValue === false) {
if (isDefined(previousCompositeIndex)) {
scope.ignoreCompositeIndexChange = true;
scope.compositeIndex = previousCompositeIndex;
}
return;
}
if (innerSnapIndex === 0) {
return rectifyScrollTop(scrollTop);
if (isNumber(returnValue)) {
scope.snapIndex = returnValue;
return;
}
var snapHeight = getSnapHeight();
var childHeight = getHeight(children[snapIndex]);
var innerScrollTop;
if (isDefined(previousCompositeIndex) &&
innerSnapIndex < previousCompositeIndex[1]) {
innerScrollTop = childHeight;
for (var j = innerSnapIndex; j >= 0; j--) {
innerScrollTop -= snapHeight;
}
} else {
innerScrollTop = 0;
for (var k = 0; k < innerSnapIndex; k++) {
innerScrollTop += snapHeight;
}
var overflow = innerScrollTop + snapHeight - childHeight;
if (overflow > 0) {
innerScrollTop -= overflow;
}
}
return rectifyScrollTop(scrollTop + innerScrollTop);
}
function snapTo(compositeIndex, previousCompositeIndex) {
var snapIndex = compositeIndex[0];
var isSnapIndexChanged = isUndefined(previousCompositeIndex) ||
snapIndex !== previousCompositeIndex[0];
return scrollTo(getScrollTop(
compositeIndex,
previousCompositeIndex
)).then(function () {
if (isSnapIndexChanged) {
var returnValue = scope.beforeSnap({
scope.afterSnap({
snapIndex: snapIndex,
$event: scope.sourceEvent
});
if (returnValue === false) {
if (isDefined(previousCompositeIndex)) {
scope.ignoreCompositeIndexChange = true;
scope.compositeIndex = previousCompositeIndex;
}
return;
}
if (isNumber(returnValue)) {
scope.snapIndex = returnValue;
return;
}
}
scope.sourceEvent = undefined;
});
}
return scrollTo(getScrollTop(
compositeIndex,
previousCompositeIndex
)).then(function () {
if (isSnapIndexChanged) {
scope.afterSnap({
snapIndex: snapIndex,
$event: scope.sourceEvent
});
}
scope.sourceEvent = undefined;
});
function getCurrentScrollTop() {
return element[0].scrollTop;
}
function scrollTo(scrollTop) {
var args;
if (!scope.snapAnimation) {
args = [
element,
scrollTop
];
} else if (isUndefined(scope.snapEasing)) {
// TODO: add tests for this. Will require refactoring
// the default values into an object, which is a good
// change anyway
args = [
element,
scrollTop,
scope.snapDuration
];
} else {
args = [
element,
scrollTop,
scope.snapDuration,
scope.snapEasing
];
}
function getCurrentScrollTop() {
return element[0].scrollTop;
var currentScrollTop = getCurrentScrollTop();
if (scrollTop > currentScrollTop) {
scope.snapDirection = 'down';
} else if (scrollTop < currentScrollTop) {
scope.snapDirection = 'up';
} else {
scope.snapDirection = 'same';
}
function scrollTo(scrollTop) {
var args;
if (!scope.snapAnimation) {
args = [
element,
scrollTop
];
} else if (isUndefined(scope.snapEasing)) {
// TODO: add tests for this. Will require refactoring
// the default values into an object, which is a good
// change anyway
args = [
element,
scrollTop,
scope.snapDuration
];
} else {
args = [
element,
scrollTop,
scope.snapDuration,
scope.snapEasing
];
}
unbindScroll();
return scrollie.to.apply(scrollie, args).then(function () {
scope.snapDirection = undefined;
bindScrollAfterDelay();
allowNextSnapAfterDelay();
});
}
var currentScrollTop = getCurrentScrollTop();
if (scrollTop > currentScrollTop) {
scope.snapDirection = 'down';
} else if (scrollTop < currentScrollTop) {
scope.snapDirection = 'up';
function allowNextSnapAfterDelay() {
function allowNextSnap() {
scope.preventUp = false;
scope.preventDown = false;
}
if (scope.preventUp || scope.preventDown) {
if (scope.preventDoubleSnapDelay === false) {
allowNextSnap();
} else {
scope.snapDirection = 'same';
$timeout(
allowNextSnap,
scope.preventDoubleSnapDelay
);
}
}
}
unbindScroll();
return scrollie.to.apply(scrollie, args).then(function () {
scope.snapDirection = undefined;
bindScrollAfterDelay();
allowNextSnapAfterDelay();
});
function isScrollable() {
var snapHeight = getSnapHeight();
if (!snapHeight) {
return false;
}
var children = getChildren();
if (!children.length) {
return false;
}
var totalHeight = 0;
forEach(children, function (child) {
totalHeight += getHeight(child);
});
if (totalHeight < snapHeight) {
return false;
}
return true;
}
function allowNextSnapAfterDelay() {
function allowNextSnap() {
scope.preventUp = false;
scope.preventDown = false;
function isSnapIndexValid(snapIndex) {
return snapIndex >= 0 &&
snapIndex <= getChildren().length - 1;
}
function snapIndexChanged(current, previous) {
if (!isScrollable()) {
return;
}
if (isUndefined(current)) {
scope.snapIndex = 0;
return;
}
if (!isNumber(current)) {
if (!isNumber(previous)) {
previous = 0;
}
if (scope.preventUp || scope.preventDown) {
if (scope.preventDoubleSnapDelay === false) {
allowNextSnap();
} else {
$timeout(
allowNextSnap,
scope.preventDoubleSnapDelay
);
}
}
scope.snapIndex = previous;
return;
}
function isScrollable() {
var snapHeight = getSnapHeight();
if (!snapHeight) {
return false;
if (current % 1 !== 0) {
scope.snapIndex = Math.round(current);
return;
}
if (scope.ignoreSnapIndexChange === true) {
scope.ignoreSnapIndexChange = undefined;
return;
}
if (!isSnapIndexValid(current)) {
if (!isSnapIndexValid(previous)) {
previous = 0;
}
var children = getChildren();
if (!children.length) {
return false;
}
var totalHeight = 0;
forEach(children, function (child) {
totalHeight += getHeight(child);
});
if (totalHeight < snapHeight) {
return false;
}
return true;
scope.ignoreSnapIndexChange = true;
scope.snapIndex = previous;
return;
}
scope.compositeIndex = [current, 0];
}
function isSnapIndexValid(snapIndex) {
return snapIndex >= 0 &&
snapIndex <= getChildren().length - 1;
function watchSnapIndex() {
scope.unwatchSnapIndex = scope.$watch(
'snapIndex',
snapIndexChanged
);
}
function unwatchSnapIndex() {
if (!isFunction(scope.unwatchSnapIndex)) {
return;
}
scope.unwatchSnapIndex();
scope.unwatchSnapIndex = undefined;
}
function snapIndexChanged(current, previous) {
if (!isScrollable()) {
return;
}
if (isUndefined(current)) {
scope.snapIndex = 0;
return;
}
if (!isNumber(current)) {
if (!isNumber(previous)) {
previous = 0;
}
scope.snapIndex = previous;
return;
}
if (current % 1 !== 0) {
scope.snapIndex = Math.round(current);
return;
}
if (scope.ignoreSnapIndexChange === true) {
scope.ignoreSnapIndexChange = undefined;
return;
}
if (!isSnapIndexValid(current)) {
if (!isSnapIndexValid(previous)) {
previous = 0;
}
scope.ignoreSnapIndexChange = true;
scope.snapIndex = previous;
return;
}
scope.compositeIndex = [current, 0];
function compositeIndexChanged(current, previous) {
if (isUndefined(current)) {
return;
}
var snapIndex = current[0];
if (scope.snapIndex !== snapIndex) {
scope.ignoreSnapIndexChange = true;
scope.snapIndex = snapIndex;
}
if (scope.ignoreCompositeIndexChange === true) {
scope.ignoreCompositeIndexChange = undefined;
return;
}
snapTo(current, previous);
}
function watchSnapIndex() {
scope.unwatchSnapIndex = scope.$watch(
'snapIndex',
snapIndexChanged
);
function watchCompositeIndex() {
scope.unwatchCompositeIndex = scope.$watchCollection(
'compositeIndex',
compositeIndexChanged
);
}
function unwatchCompositeIndex() {
if (!isFunction(scope.unwatchCompositeIndex)) {
return;
}
scope.unwatchCompositeIndex();
scope.unwatchCompositeIndex = undefined;
}
function unwatchSnapIndex() {
if (!isFunction(scope.unwatchSnapIndex)) {
return;
}
scope.unwatchSnapIndex();
scope.unwatchSnapIndex = undefined;
function getMaxInnerSnapIndex(snapIndex) {
var snapHeight = getSnapHeight();
var childHeight = getChildHeight(snapIndex);
if (childHeight <= snapHeight) {
return 0;
}
var max = parseInt((childHeight / snapHeight), 10);
if (childHeight % snapHeight === 0) {
max -= 1;
}
return max;
}
function compositeIndexChanged(current, previous) {
if (isUndefined(current)) {
return;
}
var snapIndex = current[0];
if (scope.snapIndex !== snapIndex) {
scope.ignoreSnapIndexChange = true;
scope.snapIndex = snapIndex;
}
if (scope.ignoreCompositeIndexChange === true) {
scope.ignoreCompositeIndexChange = undefined;
return;
}
snapTo(current, previous);
function isCompositeIndexValid(compositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
if (innerSnapIndex < 0) {
return isSnapIndexValid(snapIndex - 1);
}
if (innerSnapIndex > getMaxInnerSnapIndex(snapIndex)) {
return isSnapIndexValid(snapIndex + 1);
}
return true;
}
function watchCompositeIndex() {
scope.unwatchCompositeIndex = scope.$watchCollection(
'compositeIndex',
compositeIndexChanged
);
function rectifyCompositeIndex(compositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
if (innerSnapIndex < 0) {
return [
snapIndex - 1,
getMaxInnerSnapIndex(snapIndex - 1)
];
}
if (innerSnapIndex > getMaxInnerSnapIndex(snapIndex)) {
return [snapIndex + 1, 0];
}
return compositeIndex;
}
function unwatchCompositeIndex() {
if (!isFunction(scope.unwatchCompositeIndex)) {
return;
}
scope.unwatchCompositeIndex();
scope.unwatchCompositeIndex = undefined;
function snap(direction, event) {
if (!isScrollable()) {
return;
}
function getMaxInnerSnapIndex(snapIndex) {
var snapHeight = getSnapHeight();
var childHeight = getChildHeight(snapIndex);
if (childHeight <= snapHeight) {
return 0;
}
var max = parseInt((childHeight / snapHeight), 10);
if (childHeight % snapHeight === 0) {
max -= 1;
}
return max;
direction === 'up' && (scope.preventDown = false);
direction === 'down' && (scope.preventUp = false);
if (scope.snapDirection === direction) {
return true;
}
function isCompositeIndexValid(compositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
if (innerSnapIndex < 0) {
return isSnapIndexValid(snapIndex - 1);
}
if (innerSnapIndex > getMaxInnerSnapIndex(snapIndex)) {
return isSnapIndexValid(snapIndex + 1);
}
if (scope.preventUp || scope.preventDown) {
return true;
}
function rectifyCompositeIndex(compositeIndex) {
var snapIndex = compositeIndex[0];
var innerSnapIndex = compositeIndex[1];
if (innerSnapIndex < 0) {
return [
snapIndex - 1,
getMaxInnerSnapIndex(snapIndex - 1)
];
}
if (innerSnapIndex > getMaxInnerSnapIndex(snapIndex)) {
return [snapIndex + 1, 0];
}
return compositeIndex;
var snapIndex = scope.compositeIndex[0];
var innerSnapIndex = scope.compositeIndex[1];
var newInnerSnapIndex;
if (direction === 'up') {
newInnerSnapIndex = innerSnapIndex - 1;
}
if (direction === 'down') {
newInnerSnapIndex = innerSnapIndex + 1;
}
function snap(direction, event) {
if (!isScrollable()) {
return;
}
var newCompositeIndex = [snapIndex, newInnerSnapIndex];
if (!isCompositeIndexValid(newCompositeIndex)) {
return;
}
direction === 'up' && (scope.preventDown = false);
direction === 'down' && (scope.preventUp = false);
if (event.type === 'wheel') {
direction === 'up' && (scope.preventUp = true);
direction === 'down' && (scope.preventDown = true);
}
if (scope.snapDirection === direction) {
return true;
}
scope.$apply(function () {
scope.sourceEvent = event;
scope.compositeIndex = rectifyCompositeIndex(
newCompositeIndex
);
});
if (scope.preventUp || scope.preventDown) {
return true;
}
return true;
}
var snapIndex = scope.compositeIndex[0];
var innerSnapIndex = scope.compositeIndex[1];
var newInnerSnapIndex;
if (direction === 'up') {
newInnerSnapIndex = innerSnapIndex - 1;
}
if (direction === 'down') {
newInnerSnapIndex = innerSnapIndex + 1;
}
function snapUp(event) {
return snap('up', event);
}
var newCompositeIndex = [snapIndex, newInnerSnapIndex];
if (!isCompositeIndexValid(newCompositeIndex)) {
return;
}
function snapDown(event) {
return snap('down', event);
}
if (event.type === 'wheel') {
direction === 'up' && (scope.preventUp = true);
direction === 'down' && (scope.preventDown = true);
function bindWheel() {
if (scope.disableWheelBinding || scope.wheelBound) {
return;
}
wheelie.bind(element, {
up: function (e) {
e.preventDefault();
if (snapUp(e)) {
e.stopPropagation();
}
},
down: function (e) {
e.preventDefault();
if (snapDown(e)) {
e.stopPropagation();
}
}
}, scope.ignoreWheelClass);
scope.wheelBound = true;
}
scope.$apply(function () {
scope.sourceEvent = event;
scope.compositeIndex = rectifyCompositeIndex(
newCompositeIndex
);
});
return true;
function unbindWheel() {
if (!scope.wheelBound) {
return;
}
wheelie.unbind(element);
scope.wheelBound = false;
}
function snapUp(event) {
return snap('up', event);
}
function setHeight(angularElement, height) {
angularElement.css('height', height + 'px');
}
function snapDown(event) {
return snap('down', event);
function snapHeightChanged(current, previous) {
if (isUndefined(current)) {
return;
}
function bindWheel() {
if (scope.disableWheelBinding || scope.wheelBound) {
return;
if (!isNumber(current)) {
if (isNumber(previous)) {
scope.snapHeight = previous;
}
wheelie.bind(element, {
up: function (e) {
e.preventDefault();
if (snapUp(e)) {
e.stopPropagation();
}
},
down: function (e) {
e.preventDefault();
if (snapDown(e)) {
e.stopPropagation();
}
}
}, scope.ignoreWheelClass);
scope.wheelBound = true;
return;
}
function unbindWheel() {
if (!scope.wheelBound) {
return;
setHeight(element, current);
forEach(getChildren(), function (child) {
setHeight(angular.element(child), current);
});
if (isDefined(scope.snapIndex)) {
if (isUndefined(scope.compositeIndex)) {
scope.compositeIndex = [scope.snapIndex, 0];
}
wheelie.unbind(element);
scope.wheelBound = false;
snapTo(scope.compositeIndex);
}
}
function setHeight(angularElement, height) {
angularElement.css('height', height + 'px');
function watchSnapHeight() {
scope.unwatchSnapHeight = scope.$watch(
'snapHeight',
snapHeightChanged
);
}
function unwatchSnapHeight() {
if (!isFunction(scope.unwatchSnapHeight)) {
return;
}
scope.unwatchSnapHeight();
scope.unwatchSnapHeight = undefined;
}
function snapHeightChanged(current, previous) {
if (isUndefined(current)) {
return;
function getCompositeIndex(scrollTop) {
var snapIndex = 0;
var innerSnapIndex = 0;
if (scrollTop > 0) {
snapIndex = -1;
var children = getChildren();
var childHeight;
while (scrollTop > 0) {
childHeight = getHeight(children[++snapIndex]);
scrollTop -= childHeight;
}
if (!isNumber(current)) {
if (isNumber(previous)) {
scope.snapHeight = previous;
var snapHeight = getSnapHeight();
if (childHeight > snapHeight) {
scrollTop += childHeight - snapHeight;
if (scrollTop >= snapHeight) {
innerSnapIndex++;
}
return;
while (scrollTop > 0) {
innerSnapIndex++;
scrollTop -= snapHeight;
}
if ((snapHeight / 2) >= -scrollTop) {
innerSnapIndex += 1;
}
} else if ((childHeight / 2) >= -scrollTop) {
snapIndex += 1;
}
}
setHeight(element, current);
forEach(getChildren(), function (child) {
setHeight(angular.element(child), current);
});
return rectifyCompositeIndex([snapIndex, innerSnapIndex]);
}
if (isDefined(scope.snapIndex)) {
if (isUndefined(scope.compositeIndex)) {
scope.compositeIndex = [scope.snapIndex, 0];
}
function onScroll() {
function snapFromSrollTop() {
var compositeIndex = getCompositeIndex(
getCurrentScrollTop()
);
if (scope.compositeIndex[0] === compositeIndex[0] &&
scope.compositeIndex[1] === compositeIndex[1]) {
snapTo(scope.compositeIndex);
} else {
scope.$apply(function () {
scope.compositeIndex = compositeIndex;
});
}
}
function watchSnapHeight() {
scope.unwatchSnapHeight = scope.$watch(
'snapHeight',
snapHeightChanged
scrollie.stop(element);
if (scope.scrollDelay === false) {
snapFromSrollTop();
} else {
$timeout.cancel(scope.scrollPromise);
scope.scrollPromise = $timeout(
function () {
snapFromSrollTop();
scope.scrollPromise = undefined;
},
scope.scrollDelay
);
}
}
function unwatchSnapHeight() {
if (!isFunction(scope.unwatchSnapHeight)) {
return;
}
scope.unwatchSnapHeight();
scope.unwatchSnapHeight = undefined;
function bindScroll() {
if (scope.preventSnappingAfterManualScroll ||
scope.scrollBound) {
return;
}
function getCompositeIndex(scrollTop) {
var snapIndex = 0;
var innerSnapIndex = 0;
if (scrollTop > 0) {
snapIndex = -1;
var children = getChildren();
var childHeight;
while (scrollTop > 0) {
childHeight = getHeight(children[++snapIndex]);
scrollTop -= childHeight;
}
var snapHeight = getSnapHeight();
if (childHeight > snapHeight) {
scrollTop += childHeight - snapHeight;
if (scrollTop >= snapHeight) {
innerSnapIndex++;
}
while (scrollTop > 0) {
innerSnapIndex++;
scrollTop -= snapHeight;
}
if ((snapHeight / 2) >= -scrollTop) {
innerSnapIndex += 1;
}
} else if ((childHeight / 2) >= -scrollTop) {
snapIndex += 1;
}
}
return rectifyCompositeIndex([snapIndex, innerSnapIndex]);
if (isDefined(scope.snapDirection)) { // still snapping
// TODO: add tests for this
bindScrollAfterDelay();
return;
}
element.on('scroll', onScroll);
scope.scrollBound = true;
}
function onScroll() {
function snapFromSrollTop() {
var compositeIndex = getCompositeIndex(
getCurrentScrollTop()
);
if (scope.compositeIndex[0] === compositeIndex[0] &&
scope.compositeIndex[1] === compositeIndex[1]) {
snapTo(scope.compositeIndex);
} else {
scope.$apply(function () {
scope.compositeIndex = compositeIndex;
});
}
}
scrollie.stop(element);
if (scope.scrollDelay === false) {
snapFromSrollTop();
} else {
$timeout.cancel(scope.scrollPromise);
scope.scrollPromise = $timeout(
function () {
snapFromSrollTop();
scope.scrollPromise = undefined;
},
scope.scrollDelay
);
}
function unbindScroll() {
if (!scope.scrollBound) {
return;
}
element.off('scroll', onScroll);
scope.scrollBound = false;
}
function bindScroll() {
if (scope.preventSnappingAfterManualScroll ||
scope.scrollBound) {
return;
}
if (isDefined(scope.snapDirection)) { // still snapping
// TODO: add tests for this
bindScrollAfterDelay();
return;
}
element.on('scroll', onScroll);
scope.scrollBound = true;
function bindScrollAfterDelay() {
if (scope.preventSnappingAfterManualScroll) {
return;
}
function unbindScroll() {
if (!scope.scrollBound) {
return;
}
element.off('scroll', onScroll);
scope.scrollBound = false;
if (scope.bindScrollPromise) {
$timeout.cancel(scope.bindScrollPromise);
}
scope.bindScrollPromise = $timeout(
function () {
bindScroll();
scope.bindScrollPromise = undefined;
},
defaultSnapscrollBindScrollTimeout
);
}
function bindScrollAfterDelay() {
if (scope.preventSnappingAfterManualScroll) {
return;
}
if (scope.bindScrollPromise) {
$timeout.cancel(scope.bindScrollPromise);
}
scope.bindScrollPromise = $timeout(
function () {
bindScroll();
scope.bindScrollPromise = undefined;
},
defaultSnapscrollBindScrollTimeout
);
function onKeyDown(e) {
if (e.originalEvent) {
e = e.originalEvent;
}
var handler;
var keyCode = e.keyCode;
if (keyCode === 38) {
handler = snapUp;
}
if (keyCode === 40) {
handler = snapDown;
}
if (handler) {
e.preventDefault();
handler(e);
}
}
function onKeyDown(e) {
if (e.originalEvent) {
e = e.originalEvent;
}
var handler;
var keyCode = e.keyCode;
if (keyCode === 38) {
handler = snapUp;
}
if (keyCode === 40) {
handler = snapDown;
}
if (handler) {
e.preventDefault();
handler(e);
}
function bindArrowKeys() {
if (!scope.enableArrowKeys || scope.arrowKeysBound) {
return;
}
$document.on('keydown', onKeyDown);
scope.arrowKeysBound = true;
}
function bindArrowKeys() {
if (!scope.enableArrowKeys || scope.arrowKeysBound) {
return;
}
$document.on('keydown', onKeyDown);
scope.arrowKeysBound = true;
function unbindArrowKeys() {
if (!scope.arrowKeysBound) {
return;
}
$document.off('keydown', onKeyDown);
scope.arrowKeysBound = false;
}
function unbindArrowKeys() {
if (!scope.arrowKeysBound) {
return;
function init() {
var scrollDelay = attributes.scrollDelay;
if (scrollDelay === 'false') {
scope.scrollDelay = false;
} else {
scrollDelay = parseInt(scrollDelay, 10);
if (isNaN(scrollDelay)) {
scrollDelay = defaultSnapscrollScrollDelay;
}
$document.off('keydown', onKeyDown);
scope.arrowKeysBound = false;
scope.scrollDelay = scrollDelay;
}
function init() {
var scrollDelay = attributes.scrollDelay;
if (scrollDelay === 'false') {
scope.scrollDelay = false;
} else {
scrollDelay = parseInt(scrollDelay, 10);
if (isNaN(scrollDelay)) {
scrollDelay = defaultSnapscrollScrollDelay;
}
scope.scrollDelay = scrollDelay;
}
var preventDoubleSnapDelay = (
attributes.preventDoubleSnapDelay
var preventDoubleSnapDelay = (
attributes.preventDoubleSnapDelay
);
if (preventDoubleSnapDelay === 'false') {
scope.preventDoubleSnapDelay = false;
} else {
preventDoubleSnapDelay = parseInt(
preventDoubleSnapDelay,
10
);
if (preventDoubleSnapDelay === 'false') {
scope.preventDoubleSnapDelay = false;
} else {
preventDoubleSnapDelay = parseInt(
preventDoubleSnapDelay,
10
if (isNaN(preventDoubleSnapDelay)) {
preventDoubleSnapDelay = (
defaultSnapscrollPreventDoubleSnapDelay
);
if (isNaN(preventDoubleSnapDelay)) {
preventDoubleSnapDelay = (
defaultSnapscrollPreventDoubleSnapDelay
);
}
scope.preventDoubleSnapDelay = preventDoubleSnapDelay;
}
scope.preventDoubleSnapDelay = preventDoubleSnapDelay;
}
var snapEasing = attributes.snapEasing;
if (isDefined(snapEasing)) {
scope.snapEasing = scope.$parent.$eval(snapEasing);
} else if (isFunction(defaultSnapscrollScrollEasing)) {
scope.snapEasing = defaultSnapscrollScrollEasing;
}
var snapEasing = attributes.snapEasing;
if (isDefined(snapEasing)) {
scope.snapEasing = scope.$parent.$eval(snapEasing);
} else if (isFunction(defaultSnapscrollScrollEasing)) {
scope.snapEasing = defaultSnapscrollScrollEasing;
}
var snapDuration = parseInt(attributes.snapDuration, 10);
if (isNaN(snapDuration)) {
snapDuration = defaultSnapscrollSnapDuration;
}
scope.snapDuration = snapDuration;
var snapDuration = parseInt(attributes.snapDuration, 10);
if (isNaN(snapDuration)) {
snapDuration = defaultSnapscrollSnapDuration;
}
scope.snapDuration = snapDuration;
// TODO: perform initial snap without animation
if (isUndefined(scope.snapAnimation)) {
scope.snapAnimation = true;
}
// TODO: perform initial snap without animation
if (isUndefined(scope.snapAnimation)) {
scope.snapAnimation = true;
}
scope.disableWheelBinding = isDefined(
attributes.disableWheelBinding
);
scope.disableWheelBinding = isDefined(
attributes.disableWheelBinding
);
scope.enableArrowKeys = isDefined(
attributes.enableArrowKeys
);
scope.enableArrowKeys = isDefined(
attributes.enableArrowKeys
);
scope.preventSnappingAfterManualScroll = isDefined(
attributes.preventSnappingAfterManualScroll
);
scope.preventSnappingAfterManualScroll = isDefined(
attributes.preventSnappingAfterManualScroll
);
scope.ignoreWheelClass = attributes.ignoreWheelClass;
scope.ignoreWheelClass = attributes.ignoreWheelClass;
if (element.css('overflowY') !== 'scroll') {
element.css('overflowY', 'auto');
}
if (element.css('overflowY') !== 'scroll') {
element.css('overflowY', 'auto');
}
scope.$watch('enabled', function (current, previous) {
function updateCompositeIndexFromScrollTop() {
if (scope.preventSnappingAfterManualScroll) {
return;
}
scope.compositeIndex = getCompositeIndex(
getCurrentScrollTop()
);
scope.$watch('enabled', function (current, previous) {
function updateCompositeIndexFromScrollTop() {
if (scope.preventSnappingAfterManualScroll) {
return;
}
if (current !== false) {
if (previous === false) {
updateCompositeIndexFromScrollTop();
}
watchCompositeIndex();
watchSnapIndex();
watchSnapHeight();
bindScroll();
bindWheel();
bindArrowKeys();
} else {
unwatchCompositeIndex();
unwatchSnapIndex();
unwatchSnapHeight();
unbindScroll();
unbindWheel();
unbindArrowKeys();
scope.compositeIndex = getCompositeIndex(
getCurrentScrollTop()
);
}
if (current !== false) {
if (previous === false) {
updateCompositeIndexFromScrollTop();
}
});
watchCompositeIndex();
watchSnapIndex();
watchSnapHeight();
bindScroll();
bindWheel();
bindArrowKeys();
} else {
unwatchCompositeIndex();
unwatchSnapIndex();
unwatchSnapHeight();
unbindScroll();
unbindWheel();
unbindArrowKeys();
}
});
scope.$on('$destroy', function () {
if (scope.enabled !== false) {
unbindScroll();
unbindWheel();
unbindArrowKeys();
}
});
}
init();
scope.$on('$destroy', function () {
if (scope.enabled !== false) {
unbindScroll();
unbindWheel();
unbindArrowKeys();
}
});
}
};
}
];
angular.module('snapscroll')
.directive('snapscroll', snapscrollAsAnAttribute);
})();
init();
}
};
}
]);

@@ -1,10 +0,12 @@

(function () {
angular
.module('snapscroll', ['wheelie', 'scrollie'])
.value('defaultSnapscrollScrollEasing', undefined)
.value('defaultSnapscrollScrollDelay', 250)
.value('defaultSnapscrollSnapDuration', 800)
.value('defaultSnapscrollResizeDelay', 400)
.value('defaultSnapscrollBindScrollTimeout', 400)
.value('defaultSnapscrollPreventDoubleSnapDelay', 1000);
})();
if (typeof exports === 'object') {
module.exports = 'snapscroll';
}
angular
.module('snapscroll', ['wheelie', 'scrollie'])
.value('defaultSnapscrollScrollEasing', undefined)
.value('defaultSnapscrollScrollDelay', 250)
.value('defaultSnapscrollSnapDuration', 800)
.value('defaultSnapscrollResizeDelay', 400)
.value('defaultSnapscrollBindScrollTimeout', 400)
.value('defaultSnapscrollPreventDoubleSnapDelay', 1000);
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc