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