5 ScrollHandler = (function() {
6 function ScrollHandler(tree_widget) {
7 this.tree_widget = tree_widget;
8 this.previous_top = -1;
9 this.is_initialized = false;
12 ScrollHandler.prototype._initScrollParent = function() {
13 var $scroll_parent, getParentWithOverflow, setDocumentAsScrollParent;
14 getParentWithOverflow = (function(_this) {
16 var css_values, el, hasOverFlow, i, len, ref;
17 css_values = ['overflow', 'overflow-y'];
18 hasOverFlow = function(el) {
19 var css_value, i, len, ref;
20 for (i = 0, len = css_values.length; i < len; i++) {
21 css_value = css_values[i];
22 if ((ref = $.css(el, css_value)) === 'auto' || ref === 'scroll') {
28 if (hasOverFlow(_this.tree_widget.$el[0])) {
29 return _this.tree_widget.$el;
31 ref = _this.tree_widget.$el.parents();
32 for (i = 0, len = ref.length; i < len; i++) {
34 if (hasOverFlow(el)) {
41 setDocumentAsScrollParent = (function(_this) {
43 _this.scroll_parent_top = 0;
44 return _this.$scroll_parent = null;
47 if (this.tree_widget.$el.css('position') === 'fixed') {
48 setDocumentAsScrollParent();
50 $scroll_parent = getParentWithOverflow();
51 if ($scroll_parent && $scroll_parent.length && $scroll_parent[0].tagName !== 'HTML') {
52 this.$scroll_parent = $scroll_parent;
53 this.scroll_parent_top = this.$scroll_parent.offset().top;
55 setDocumentAsScrollParent();
57 return this.is_initialized = true;
60 ScrollHandler.prototype._ensureInit = function() {
61 if (!this.is_initialized) {
62 return this._initScrollParent();
66 ScrollHandler.prototype.checkScrolling = function() {
69 hovered_area = this.tree_widget.dnd_handler.hovered_area;
70 if (hovered_area && hovered_area.top !== this.previous_top) {
71 this.previous_top = hovered_area.top;
72 if (this.$scroll_parent) {
73 return this._handleScrollingWithScrollParent(hovered_area);
75 return this._handleScrollingWithDocument(hovered_area);
80 ScrollHandler.prototype._handleScrollingWithScrollParent = function(area) {
82 distance_bottom = this.scroll_parent_top + this.$scroll_parent[0].offsetHeight - area.bottom;
83 if (distance_bottom < 20) {
84 this.$scroll_parent[0].scrollTop += 20;
85 this.tree_widget.refreshHitAreas();
86 return this.previous_top = -1;
87 } else if ((area.top - this.scroll_parent_top) < 20) {
88 this.$scroll_parent[0].scrollTop -= 20;
89 this.tree_widget.refreshHitAreas();
90 return this.previous_top = -1;
94 ScrollHandler.prototype._handleScrollingWithDocument = function(area) {
96 distance_top = area.top - $(document).scrollTop();
97 if (distance_top < 20) {
98 return $(document).scrollTop($(document).scrollTop() - 20);
99 } else if ($(window).height() - (area.bottom - $(document).scrollTop()) < 20) {
100 return $(document).scrollTop($(document).scrollTop() + 20);
104 ScrollHandler.prototype.scrollTo = function(top) {
107 if (this.$scroll_parent) {
108 return this.$scroll_parent[0].scrollTop = top;
110 tree_top = this.tree_widget.$el.offset().top;
111 return $(document).scrollTop(top + tree_top);
115 ScrollHandler.prototype.isScrolledIntoView = function(element) {
116 var $element, element_bottom, element_top, view_bottom, view_top;
118 $element = $(element);
119 if (this.$scroll_parent) {
121 view_bottom = this.$scroll_parent.height();
122 element_top = $element.offset().top - this.scroll_parent_top;
123 element_bottom = element_top + $element.height();
125 view_top = $(window).scrollTop();
126 view_bottom = view_top + $(window).height();
127 element_top = $element.offset().top;
128 element_bottom = element_top + $element.height();
130 return (element_bottom <= view_bottom) && (element_top >= view_top);
133 return ScrollHandler;
137 module.exports = ScrollHandler;