Project

General

Profile

1
/* angularjs Scroll Glue
2
 * version 2.0.6
3
 * https://github.com/Luegg/angularjs-scroll-glue
4
 * An AngularJs directive that automatically scrolls to the bottom of an element on changes in it's scope.
5
*/
6

    
7
(function(angular, undefined){
8
    'use strict';
9

    
10
    function createActivationState($parse, attr, scope){
11
        function unboundState(initValue){
12
            var activated = initValue;
13
            return {
14
                getValue: function(){
15
                    return activated;
16
                },
17
                setValue: function(value){
18
                    activated = value;
19
                }
20
            };
21
        }
22

    
23
        function oneWayBindingState(getter, scope){
24
            return {
25
                getValue: function(){
26
                    return getter(scope);
27
                },
28
                setValue: function(){}
29
            }
30
        }
31

    
32
        function twoWayBindingState(getter, setter, scope){
33
            return {
34
                getValue: function(){
35
                    return getter(scope);
36
                },
37
                setValue: function(value){
38
                    if(value !== getter(scope)){
39
                        scope.$apply(function(){
40
                            setter(scope, value);
41
                        });
42
                    }
43
                }
44
            };
45
        }
46

    
47
        if(attr !== ""){
48
            var getter = $parse(attr);
49
            if(getter.assign !== undefined){
50
                return twoWayBindingState(getter, getter.assign, scope);
51
            } else {
52
                return oneWayBindingState(getter, scope);
53
            }
54
        } else {
55
            return unboundState(true);
56
        }
57
    }
58

    
59
    function createDirective(module, attrName, direction){
60
        module.directive(attrName, ['$parse', '$window', '$timeout', function($parse, $window, $timeout){
61
            return {
62
                priority: 1,
63
                restrict: 'A',
64
                link: function(scope, $el, attrs){
65
                    var el = $el[0],
66
                        activationState = createActivationState($parse, attrs[attrName], scope);
67

    
68
                    function scrollIfGlued() {
69
                        if(activationState.getValue() && !direction.isAttached(el)){
70
                            direction.scroll(el);
71
                        }
72
                    }
73

    
74
                    scope.$watch(scrollIfGlued);
75
                    
76
                    $timeout(scrollIfGlued, 0, false);
77
                    
78
                    $window.addEventListener('resize', scrollIfGlued, false);
79

    
80
                    $el.bind('scroll', function(){
81
                        activationState.setValue(direction.isAttached(el));
82
                    });
83
                }
84
            };
85
        }]);
86
    }
87

    
88
    var bottom = {
89
        isAttached: function(el){
90
            // + 1 catches off by one errors in chrome
91
            return el.scrollTop + el.clientHeight + 1 >= el.scrollHeight;
92
        },
93
        scroll: function(el){
94
            el.scrollTop = el.scrollHeight;
95
        }
96
    };
97

    
98
    var top = {
99
        isAttached: function(el){
100
            return el.scrollTop <= 1;
101
        },
102
        scroll: function(el){
103
            el.scrollTop = 0;
104
        }
105
    };
106

    
107
    var right = {
108
        isAttached: function(el){
109
            return el.scrollLeft + el.clientWidth + 1 >= el.scrollWidth;
110
        },
111
        scroll: function(el){
112
            el.scrollLeft = el.scrollWidth;
113
        }
114
    };
115

    
116
    var left = {
117
        isAttached: function(el){
118
            return el.scrollLeft <= 1;
119
        },
120
        scroll: function(el){
121
            el.scrollLeft = 0;
122
        }
123
    };
124

    
125
    var module = angular.module('luegg.directives', []);
126

    
127
    createDirective(module, 'scrollGlue', bottom);
128
    createDirective(module, 'scrollGlueTop', top);
129
    createDirective(module, 'scrollGlueBottom', bottom);
130
    createDirective(module, 'scrollGlueLeft', left);
131
    createDirective(module, 'scrollGlueRight', right);
132
}(angular));
(32-32/39)