source: Dev/branches/rest-dojo-ui/client/dojo/robot.js @ 263

Last change on this file since 263 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 6.4 KB
Line 
1define(["dojo", "doh/_browserRunner", "doh/robot", "dojo/window"], function(dojo, doh) {
2
3dojo.experimental("dojo.robot");
4
5// users who use doh+dojo get the added convenience of dojo.mouseMoveAt,
6// instead of computing the absolute coordinates of their elements themselves
7dojo.mixin(doh.robot,{
8
9        _resolveNode: function(/*String||DOMNode||Function*/ n){
10                if(typeof n == "function"){
11                        // if the user passed a function returning a node, evaluate it
12                        n = n();
13                }
14                return n? dojo.byId(n) : null;
15        },
16
17        _scrollIntoView: function(/*Node*/ n){
18                // scrolls the passed node into view, scrolling all ancester frames/windows as well.
19                // Assumes parent iframes can be made fully visible given the current browser window size
20                var dr = doh.robot,
21                        p = null;
22                dojo.forEach(dr._getWindowChain(n), function(w){
23                        dojo.withGlobal(w, function(){
24                                // get the position of the node wrt its parent window
25                                // if it is a parent frame, its padding and border extents will get added in
26                                var p2 = dojo.position(n, false),
27                                        b = dojo._getPadBorderExtents(n),
28                                        oldp = null;
29                                // if p2 is the position of the original passed node, store the position away as p
30                                // otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
31                                if(!p){
32                                        p = p2;
33                                }else{
34                                        oldp = p;
35                                        p = {x: p.x+p2.x+b.l,
36                                                y: p.y+p2.y+b.t,
37                                                w: p.w,
38                                                h: p.h};
39
40                                }
41                                // scroll the parent window so that the node translated into the parent window's coordinate space is in view
42                                dojo.window.scrollIntoView(n,p);
43                                // adjust position for the new scroll offsets
44                                p2 = dojo.position(n, false);
45                                if(!oldp){
46                                        p = p2;
47                                }else{
48                                        p = {x: oldp.x+p2.x+b.l,
49                                                y: oldp.y+p2.y+b.t,
50                                                w: p.w,
51                                                h: p.h};
52                                }
53                                // get the parent iframe so it can be scrolled too
54                                n = w.frameElement;
55                        });
56                });
57        },
58
59        _position: function(/*Node*/ n){
60                // Returns the dojo.position of the passed node wrt the passed window's viewport,
61                // following any parent iframes containing the node and clipping the node to each iframe.
62                // precondition: _scrollIntoView already called
63                var p = null, M = Math.max, m = Math.min;
64                // p: the returned position of the node
65                dojo.forEach(doh.robot._getWindowChain(n), function(w){
66                        dojo.withGlobal(w, function(){
67                                // get the position of the node wrt its parent window
68                                // if it is a parent frame, its padding and border extents will get added in
69                                var p2 = dojo.position(n, false), b = dojo._getPadBorderExtents(n);
70                                // if p2 is the position of the original passed node, store the position away as p
71                                // otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
72                                if(!p){
73                                        p = p2;
74                                }else{
75                                        var view;
76                                        dojo.withGlobal(n.contentWindow,function(){
77                                                view=dojo.window.getBox();
78                                        });
79                                        p2.r = p2.x+view.w;
80                                        p2.b = p2.y+view.h;
81                                        p = {x: M(p.x+p2.x,p2.x)+b.l, // clip left edge of node wrt the iframe
82                                                y: M(p.y+p2.y,p2.y)+b.t,        // top edge
83                                                r: m(p.x+p2.x+p.w,p2.r)+b.l,    // right edge (to compute width)
84                                                b: m(p.y+p2.y+p.h,p2.b)+b.t}; // bottom edge (to compute height)
85                                        // save a few bytes by computing width and height from r and b
86                                        p.w = p.r-p.x;
87                                        p.h = p.b-p.y;
88                                }
89                                // the new node is now the old node's parent iframe
90                                n=w.frameElement;
91                        });
92                });
93                return p;
94        },
95
96        _getWindowChain : function(/*Node*/ n){
97                // Returns an array of windows starting from the passed node's parent window and ending at dojo's window
98                var cW = dojo.window.get(n.ownerDocument);
99                var arr=[cW];
100                var f = cW.frameElement;
101                return (cW == dojo.global || f == null)? arr : arr.concat(doh.robot._getWindowChain(f));
102        },
103
104        scrollIntoView : function(/*String||DOMNode||Function*/ node, /*Number, optional*/ delay){
105                // summary:
106                //              Scroll the passed node into view, if it is not.
107                //
108                // node:
109                //              The id of the node, or the node itself, to move the mouse to.
110                //              If you pass an id or a function that returns a node, the node will not be evaluated until the movement executes.
111                //              This is useful if you need to move the mouse to an node that is not yet present.
112                //
113                // delay:
114                //              Delay, in milliseconds, to wait before firing.
115                //              The delay is a delta with respect to the previous automation call.
116                //
117                doh.robot.sequence(function(){
118                        doh.robot._scrollIntoView(doh.robot._resolveNode(node));
119                }, delay);
120        },
121
122        mouseMoveAt : function(/*String||DOMNode||Function*/ node, /*Integer, optional*/ delay, /*Integer, optional*/ duration, /*Number, optional*/ offsetX, /*Number, optional*/ offsetY){
123                // summary:
124                //              Moves the mouse over the specified node at the specified relative x,y offset.
125                //
126                // description:
127                //              Moves the mouse over the specified node at the specified relative x,y offset.
128                //              If you do not specify an offset, mouseMove will default to move to the middle of the node.
129                //              Example: to move the mouse over a ComboBox's down arrow node, call doh.mouseMoveAt(dijit.byId('setvaluetest').downArrowNode);
130                //
131                // node:
132                //              The id of the node, or the node itself, to move the mouse to.
133                //              If you pass an id or a function that returns a node, the node will not be evaluated until the movement executes.
134                //              This is useful if you need to move the mouse to an node that is not yet present.
135                //
136                // delay:
137                //              Delay, in milliseconds, to wait before firing.
138                //              The delay is a delta with respect to the previous automation call.
139                //              For example, the following code ends after 600ms:
140                //                      doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
141                //                      doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
142                //
143                // duration:
144                //              Approximate time Robot will spend moving the mouse
145                //              The default is 100ms.
146                //
147                // offsetX:
148                //              x offset relative to the node, in pixels, to move the mouse. The default is half the node's width.
149                //
150                // offsetY:
151                //              y offset relative to the node, in pixels, to move the mouse. The default is half the node's height.
152                //
153
154                doh.robot._assertRobot();
155                duration = duration||100;
156                this.sequence(function(){
157                        node=doh.robot._resolveNode(node);
158                        doh.robot._scrollIntoView(node);
159                        var pos = doh.robot._position(node);
160                        if(offsetY === undefined){
161                                offsetX=pos.w/2;
162                                offsetY=pos.h/2;
163                        }
164                        var x = pos.x+offsetX;
165                        var y = pos.y+offsetY;
166                        doh.robot._mouseMove(x, y, false, duration);
167                }, delay, duration);
168        }
169});
170
171return doh.robot;
172});
Note: See TracBrowser for help on using the repository browser.