]> git.wh0rd.org Git - tt-rss.git/blob - lib/dojo/dnd/autoscroll.js.uncompressed.js
29fd413f5dd1667c7d648dc33027ffa451cde68b
[tt-rss.git] / lib / dojo / dnd / autoscroll.js.uncompressed.js
1 define("dojo/dnd/autoscroll", ["../_base/lang", "../sniff", "../_base/window", "../dom-geometry", "../dom-style", "../window"],
2         function(lang, has, win, domGeom, domStyle, winUtils){
3
4 // module:
5 //              dojo/dnd/autoscroll
6
7 var exports = {
8         // summary:
9         //              Used by dojo/dnd/Manager to scroll document or internal node when the user
10         //              drags near the edge of the viewport or a scrollable node
11 };
12 lang.setObject("dojo.dnd.autoscroll", exports);
13
14 exports.getViewport = winUtils.getBox;
15
16 exports.V_TRIGGER_AUTOSCROLL = 32;
17 exports.H_TRIGGER_AUTOSCROLL = 32;
18
19 exports.V_AUTOSCROLL_VALUE = 16;
20 exports.H_AUTOSCROLL_VALUE = 16;
21
22 // These are set by autoScrollStart().
23 // Set to default values in case autoScrollStart() isn't called. (back-compat, remove for 2.0)
24 var viewport,
25         doc = win.doc,
26         maxScrollTop = Infinity,
27         maxScrollLeft = Infinity;
28
29 exports.autoScrollStart = function(d){
30         // summary:
31         //              Called at the start of a drag.
32         // d: Document
33         //              The document of the node being dragged.
34
35         doc = d;
36         viewport = winUtils.getBox(doc);
37
38         // Save height/width of document at start of drag, before it gets distorted by a user dragging an avatar past
39         // the document's edge
40         var html = win.body(doc).parentNode;
41         maxScrollTop = Math.max(html.scrollHeight - viewport.h, 0);
42         maxScrollLeft = Math.max(html.scrollWidth - viewport.w, 0);     // usually 0
43 };
44
45 exports.autoScroll = function(e){
46         // summary:
47         //              a handler for mousemove and touchmove events, which scrolls the window, if
48         //              necessary
49         // e: Event
50         //              mousemove/touchmove event
51
52         // FIXME: needs more docs!
53         var v = viewport || winUtils.getBox(doc), // getBox() call for back-compat, in case autoScrollStart() wasn't called
54                 html = win.body(doc).parentNode,
55                 dx = 0, dy = 0;
56         if(e.clientX < exports.H_TRIGGER_AUTOSCROLL){
57                 dx = -exports.H_AUTOSCROLL_VALUE;
58         }else if(e.clientX > v.w - exports.H_TRIGGER_AUTOSCROLL){
59                 dx = Math.min(exports.H_AUTOSCROLL_VALUE, maxScrollLeft - html.scrollLeft);     // don't scroll past edge of doc
60         }
61         if(e.clientY < exports.V_TRIGGER_AUTOSCROLL){
62                 dy = -exports.V_AUTOSCROLL_VALUE;
63         }else if(e.clientY > v.h - exports.V_TRIGGER_AUTOSCROLL){
64                 dy = Math.min(exports.V_AUTOSCROLL_VALUE, maxScrollTop - html.scrollTop);       // don't scroll past edge of doc
65         }
66         window.scrollBy(dx, dy);
67 };
68
69 exports._validNodes = {"div": 1, "p": 1, "td": 1};
70 exports._validOverflow = {"auto": 1, "scroll": 1};
71
72 exports.autoScrollNodes = function(e){
73         // summary:
74         //              a handler for mousemove and touchmove events, which scrolls the first available
75         //              Dom element, it falls back to exports.autoScroll()
76         // e: Event
77         //              mousemove/touchmove event
78
79         // FIXME: needs more docs!
80
81         var b, t, w, h, rx, ry, dx = 0, dy = 0, oldLeft, oldTop;
82
83         for(var n = e.target; n;){
84                 if(n.nodeType == 1 && (n.tagName.toLowerCase() in exports._validNodes)){
85                         var s = domStyle.getComputedStyle(n),
86                                 overflow = (s.overflow.toLowerCase() in exports._validOverflow),
87                                 overflowX = (s.overflowX.toLowerCase() in exports._validOverflow),
88                                 overflowY = (s.overflowY.toLowerCase() in exports._validOverflow);
89                         if(overflow || overflowX || overflowY){
90                                 b = domGeom.getContentBox(n, s);
91                                 t = domGeom.position(n, true);
92                         }
93                         // overflow-x
94                         if(overflow || overflowX){
95                                 w = Math.min(exports.H_TRIGGER_AUTOSCROLL, b.w / 2);
96                                 rx = e.pageX - t.x;
97                                 if(has("webkit") || has("opera")){
98                                         // FIXME: this code should not be here, it should be taken into account
99                                         // either by the event fixing code, or the domGeom.position()
100                                         // FIXME: this code doesn't work on Opera 9.5 Beta
101                                         rx += win.body().scrollLeft;
102                                 }
103                                 dx = 0;
104                                 if(rx > 0 && rx < b.w){
105                                         if(rx < w){
106                                                 dx = -w;
107                                         }else if(rx > b.w - w){
108                                                 dx = w;
109                                         }
110                                         oldLeft = n.scrollLeft;
111                                         n.scrollLeft = n.scrollLeft + dx;
112                                 }
113                         }
114                         // overflow-y
115                         if(overflow || overflowY){
116                                 //console.log(b.l, b.t, t.x, t.y, n.scrollLeft, n.scrollTop);
117                                 h = Math.min(exports.V_TRIGGER_AUTOSCROLL, b.h / 2);
118                                 ry = e.pageY - t.y;
119                                 if(has("webkit") || has("opera")){
120                                         // FIXME: this code should not be here, it should be taken into account
121                                         // either by the event fixing code, or the domGeom.position()
122                                         // FIXME: this code doesn't work on Opera 9.5 Beta
123                                         ry += win.body().scrollTop;
124                                 }
125                                 dy = 0;
126                                 if(ry > 0 && ry < b.h){
127                                         if(ry < h){
128                                                 dy = -h;
129                                         }else if(ry > b.h - h){
130                                                 dy = h;
131                                         }
132                                         oldTop = n.scrollTop;
133                                         n.scrollTop  = n.scrollTop  + dy;
134                                 }
135                         }
136                         if(dx || dy){ return; }
137                 }
138                 try{
139                         n = n.parentNode;
140                 }catch(x){
141                         n = null;
142                 }
143         }
144         exports.autoScroll(e);
145 };
146
147 return exports;
148
149 });