]> git.wh0rd.org - tt-rss.git/blame - lib/dojo/robot.js
remove call-by-reference to comply with php 5.4
[tt-rss.git] / lib / dojo / robot.js
CommitLineData
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
8if(!dojo._hasResource["dojo.robot"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
9dojo._hasResource["dojo.robot"] = true;
2f01fe57 10dojo.provide("dojo.robot");
2f01fe57
AD
11dojo.require("doh.robot");
12dojo.require("dojo.window");
a089699c 13
81bea17a
AD
14
15dojo.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
20dojo.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}