source: Dev/trunk/src/client/dojo/dnd/autoscroll.js @ 529

Last change on this file since 529 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 4.5 KB
Line 
1define(["../_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
7var 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};
12lang.setObject("dojo.dnd.autoscroll", exports);
13
14exports.getViewport = winUtils.getBox;
15
16exports.V_TRIGGER_AUTOSCROLL = 32;
17exports.H_TRIGGER_AUTOSCROLL = 32;
18
19exports.V_AUTOSCROLL_VALUE = 16;
20exports.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)
24var viewport,
25        doc = win.doc,
26        maxScrollTop = Infinity,
27        maxScrollLeft = Infinity;
28
29exports.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
45exports.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
69exports._validNodes = {"div": 1, "p": 1, "td": 1};
70exports._validOverflow = {"auto": 1, "scroll": 1};
71
72exports.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
147return exports;
148
149});
Note: See TracBrowser for help on using the repository browser.