summaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/directives/perfect-scrollbar/angular-perfect-scrollbar.ts
blob: 914a7049bb4b129a1bb3346a89ffb284e1be325e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
'use strict';

export interface IPerfectScrollerScope extends ng.IScope {
    //update(event:string): void;
}

export class PerfectScrollerDirective implements ng.IDirective {

    constructor(private $parse:any) {

    }

    replace = true;
    restrict = 'EA';
    transclude = true;

    template = ():string => {
        return '<div><div ng-transclude=""></div></div>';
    };

    link = ($scope:IPerfectScrollerScope, $elem, $attr) => {
        let self = this;
        let options = {};

        let psOptions = [
            'wheelSpeed', 'wheelPropagation', 'minScrollbarLength', 'useBothWheelAxes',
            'useKeyboard', 'suppressScrollX', 'suppressScrollY', 'scrollXMarginOffset',
            'scrollYMarginOffset', 'includePadding'//, 'onScroll', 'scrollDown'
        ];

        for (let i = 0, l = psOptions.length; i < l; i++) {
            let opt = psOptions[i];
            if ($attr[opt] !== undefined) {
                options[opt] = self.$parse($attr[opt])();
            }
        }

        $scope.$evalAsync(function () {
            $elem.perfectScrollbar(options);
            let onScrollHandler = self.$parse($attr.onScroll)
            $elem.scroll(function () {
                let scrollTop = $elem.scrollTop()
                let scrollHeight = $elem.prop('scrollHeight') - $elem.height()
                $scope.$apply(function () {
                    onScrollHandler($scope, {
                        scrollTop: scrollTop,
                        scrollHeight: scrollHeight
                    })
                })
            });
        });

        /*
         $scope.update = (event:string): void => {
         $scope.$evalAsync(function() {
         //if ($attr.scrollDown == 'true' && event != 'mouseenter') {
         if (event != 'mouseenter') {
         setTimeout(function () {
         $($elem).scrollTop($($elem).prop("scrollHeight"));
         }, 100);
         }
         $elem.perfectScrollbar('update');
         });
         };
         */

        // This is necessary when you don't watch anything with the scrollbar
        $elem.bind('mouseenter', function () {
            //console.log("mouseenter");
            $elem.perfectScrollbar('update');
        });

        $elem.bind('mouseleave', function () {
            //console.log("mouseleave");
            setTimeout(function () {
                $(window).trigger('mouseup');
                $elem.perfectScrollbar('update');
            }, 10);
        });

        $elem.bind('click', function () {
            //console.log("click");
            // Wait 500 milliseconds until the collapse finish closing and update.
            setTimeout(function () {
                $elem.perfectScrollbar('update');
            }, 500);
        });

        /**
         * Check if the content of the scroller was changed, and if changed update the scroller.
         * Because DOMSubtreeModified event is fire many time (while filling the content), I'm checking that
         * there is at least 100 milliseconds between DOMSubtreeModified events to update the scrollbar.
         * @type {boolean}
         */
        let insideDOMSubtreeModified = false;
        $elem.bind('DOMSubtreeModified', function () {
            if (insideDOMSubtreeModified == false) {
                insideDOMSubtreeModified = true;
                setTimeout(function () {
                    insideDOMSubtreeModified = false;
                    $elem.perfectScrollbar('update');
                }, 100);
            }
        });

        // Possible future improvement - check the type here and use the appropriate watch for non-arrays
        if ($attr.refreshOnChange) {
            $scope.$watchCollection($attr.refreshOnChange, function () {
                $elem.perfectScrollbar('update');
            });
        }

        $elem.bind('$destroy', function () {
            $elem.perfectScrollbar('destroy');
        });

    };

    public static factory = ($parse:any)=> {
        return new PerfectScrollerDirective($parse);
    };

}

PerfectScrollerDirective.factory.$inject = ['$parse'];