summaryrefslogtreecommitdiffstats
path: root/ecomp-portal-FE/client/bower_components/jqTree/src/scroll_handler.coffee
blob: 3456dec5197ea9cfda6c678cbc68e1775da2b167 (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
$ = jQuery


class ScrollHandler
    constructor: (tree_widget) ->
        @tree_widget = tree_widget
        @previous_top = -1
        @is_initialized = false

    _initScrollParent: ->
        getParentWithOverflow = =>
            css_values = ['overflow', 'overflow-y']

            hasOverFlow = (el) ->
                for css_value in css_values
                    if $.css(el, css_value) in ['auto', 'scroll']
                        return true

                return false

            if hasOverFlow(@tree_widget.$el[0])
                return @tree_widget.$el

            for el in @tree_widget.$el.parents()
                if hasOverFlow(el)
                    return $(el)

            return null

        setDocumentAsScrollParent = =>
            @scroll_parent_top = 0
            @$scroll_parent = null

        if @tree_widget.$el.css('position') == 'fixed'
            setDocumentAsScrollParent()

        $scroll_parent = getParentWithOverflow()

        if $scroll_parent and $scroll_parent.length and $scroll_parent[0].tagName != 'HTML'
            @$scroll_parent = $scroll_parent
            @scroll_parent_top = @$scroll_parent.offset().top
        else
            setDocumentAsScrollParent()

        @is_initialized = true

    _ensureInit: ->
        if not @is_initialized
            @_initScrollParent()

    checkScrolling: ->
        @_ensureInit()

        hovered_area = @tree_widget.dnd_handler.hovered_area

        if hovered_area and hovered_area.top != @previous_top
            @previous_top = hovered_area.top

            if @$scroll_parent
                @_handleScrollingWithScrollParent(hovered_area)
            else
                @_handleScrollingWithDocument(hovered_area)

    _handleScrollingWithScrollParent: (area) ->
        distance_bottom = @scroll_parent_top + @$scroll_parent[0].offsetHeight - area.bottom

        if distance_bottom < 20
            @$scroll_parent[0].scrollTop += 20
            @tree_widget.refreshHitAreas()
            @previous_top = -1
        else if (area.top - @scroll_parent_top) < 20
            @$scroll_parent[0].scrollTop -= 20
            @tree_widget.refreshHitAreas()
            @previous_top = -1

    _handleScrollingWithDocument: (area) ->
        distance_top = area.top - $(document).scrollTop()

        if distance_top < 20
            $(document).scrollTop($(document).scrollTop() - 20)
        else if $(window).height() - (area.bottom - $(document).scrollTop()) < 20
            $(document).scrollTop($(document).scrollTop() + 20)

    scrollTo: (top) ->
        @_ensureInit()

        if @$scroll_parent
            @$scroll_parent[0].scrollTop = top
        else
            tree_top = @tree_widget.$el.offset().top
            $(document).scrollTop(top + tree_top)

    isScrolledIntoView: (element) ->
        @_ensureInit()

        $element = $(element)

        if @$scroll_parent
            view_top = 0
            view_bottom = @$scroll_parent.height()

            element_top = $element.offset().top - @scroll_parent_top
            element_bottom = element_top + $element.height()
        else
            view_top = $(window).scrollTop()
            view_bottom = view_top + $(window).height()

            element_top = $element.offset().top
            element_bottom = element_top + $element.height()

        return (element_bottom <= view_bottom) and (element_top >= view_top)


module.exports = ScrollHandler