1 | // Helper methods for automated testing |
---|
2 | |
---|
3 | define([ |
---|
4 | "dojo/_base/array", "dojo/Deferred", "dojo/promise/all", |
---|
5 | "dojo/dom-attr", "dojo/dom-class", "dojo/dom-geometry", "dojo/dom-style", |
---|
6 | "dojo/_base/kernel", "dojo/_base/lang", "dojo/on", "dojo/query", "dojo/ready", "dojo/sniff", |
---|
7 | "dijit/a11y" // isTabNavigable, dijit._isElementShown |
---|
8 | ], function(array, Deferred, all, |
---|
9 | domAttr, domClass, domGeometry, domStyle, |
---|
10 | kernel, lang, on, query, ready, has, a11y){ |
---|
11 | |
---|
12 | |
---|
13 | // Globals used by onFocus() |
---|
14 | var curFocusNode, focusListener, focusCallback, focusCallbackDelay; |
---|
15 | |
---|
16 | var exports = { |
---|
17 | |
---|
18 | isVisible: function isVisible(/*dijit/_WidgetBase|DomNode*/ node){ |
---|
19 | // summary: |
---|
20 | // Return true if node/widget is visible |
---|
21 | var p; |
---|
22 | if(node.domNode){ node = node.domNode; } |
---|
23 | return (domStyle.get(node, "display") != "none") && |
---|
24 | (domStyle.get(node, "visibility") != "hidden") && |
---|
25 | (p = domGeometry.position(node, true), p.y + p.h >= 0 && p.x + p.w >= 0 && p.h && p.w); |
---|
26 | }, |
---|
27 | |
---|
28 | isHidden: function isHidden(/*dijit/_WidgetBase|DomNode*/ node){ |
---|
29 | // summary: |
---|
30 | // Return true if node/widget is hidden |
---|
31 | var p; |
---|
32 | if(node.domNode){ node = node.domNode; } |
---|
33 | return (domStyle.get(node, "display") == "none") || |
---|
34 | (domStyle.get(node, "visibility") == "hidden") || |
---|
35 | (p = domGeometry.position(node, true), p.y + p.h < 0 || p.x + p.w < 0 || p.h <= 0 || p.w <= 0); |
---|
36 | }, |
---|
37 | |
---|
38 | innerText: function innerText(/*DomNode*/ node){ |
---|
39 | // summary: |
---|
40 | // Browser portable function to get the innerText of specified DOMNode |
---|
41 | return lang.trim(node.textContent || node.innerText || ""); |
---|
42 | }, |
---|
43 | |
---|
44 | tabOrder: function tabOrder(/*DomNode?*/ root){ |
---|
45 | // summary: |
---|
46 | // Return all tab-navigable elements under specified node in the order that |
---|
47 | // they will be visited (by repeated presses of the tab key) |
---|
48 | |
---|
49 | var elems = []; |
---|
50 | |
---|
51 | function walkTree(/*DOMNode*/ parent){ |
---|
52 | query("> *", parent).forEach(function(child){ |
---|
53 | // Skip hidden elements, and also non-HTML elements (those in custom namespaces) in IE, |
---|
54 | // since show() invokes getAttribute("type"), which crashes on VML nodes in IE. |
---|
55 | if((has("ie") <= 8 && child.scopeName !== "HTML") || !a11y._isElementShown(child)){ |
---|
56 | return; |
---|
57 | } |
---|
58 | |
---|
59 | if(a11y.isTabNavigable(child)){ |
---|
60 | elems.push({ |
---|
61 | elem: child, |
---|
62 | tabIndex: domClass.contains(child, "tabIndex") ? domAttr.get(child, "tabIndex") : 0, |
---|
63 | pos: elems.length |
---|
64 | }); |
---|
65 | } |
---|
66 | if(child.nodeName.toUpperCase() != 'SELECT'){ |
---|
67 | walkTree(child); |
---|
68 | } |
---|
69 | }); |
---|
70 | } |
---|
71 | |
---|
72 | walkTree(root || dojo.body()); |
---|
73 | |
---|
74 | elems.sort(function(a, b){ |
---|
75 | return a.tabIndex != b.tabIndex ? a.tabIndex - b.tabIndex : a.pos - b.pos; |
---|
76 | }); |
---|
77 | return array.map(elems, function(elem){ return elem.elem; }); |
---|
78 | }, |
---|
79 | |
---|
80 | |
---|
81 | onFocus: function onFocus(func, delay){ |
---|
82 | // summary: |
---|
83 | // Wait for the next change of focus, and then delay ms (so widget has time to react to focus event), |
---|
84 | // then call func(node) with the currently focused node. Note that if focus changes again during delay, |
---|
85 | // newest focused node is passed to func. |
---|
86 | |
---|
87 | if(!focusListener){ |
---|
88 | focusListener = on(dojo.doc, "focusin", function(evt){ |
---|
89 | // Track most recently focused node; note it may change again before delay completes |
---|
90 | curFocusNode = evt.target; |
---|
91 | |
---|
92 | // If a handler was specified to fire after the next focus event (plus delay), set timeout to run it. |
---|
93 | if(focusCallback){ |
---|
94 | var callback = focusCallback; |
---|
95 | focusCallback = null; |
---|
96 | setTimeout(function(){ |
---|
97 | callback(curFocusNode); // return current focus, may be different than 10ms earlier |
---|
98 | }, focusCallbackDelay); // allow time for focus to change again, see #8285 |
---|
99 | } |
---|
100 | }); |
---|
101 | } |
---|
102 | |
---|
103 | focusCallback = func; |
---|
104 | focusCallbackDelay = delay || 10; |
---|
105 | }, |
---|
106 | |
---|
107 | waitForLoad: function(){ |
---|
108 | // summary: |
---|
109 | // Returns Promise that fires when all widgets have finished initializing |
---|
110 | |
---|
111 | var d = new Deferred(); |
---|
112 | |
---|
113 | dojo.global.require(["dojo/ready", "dijit/registry"], function(ready, registry){ |
---|
114 | ready(function(){ |
---|
115 | // Deferred fires when all widgets with an onLoadDeferred have fired |
---|
116 | var widgets = array.filter(registry.toArray(), function(w){ return w.onLoadDeferred; }), |
---|
117 | deferreds = array.map(widgets, function(w){ return w.onLoadDeferred; }); |
---|
118 | console.log("Waiting for " + widgets.length + " widgets: " + |
---|
119 | array.map(widgets, function(w){ return w.id; }).join(", ")); |
---|
120 | new all(deferreds).then(function(){ |
---|
121 | console.log("All widgets loaded."); |
---|
122 | d.resolve(widgets); |
---|
123 | }); |
---|
124 | }); |
---|
125 | }); |
---|
126 | |
---|
127 | return d.promise; |
---|
128 | } |
---|
129 | |
---|
130 | }; |
---|
131 | |
---|
132 | // All the old tests expect these symbols to be global |
---|
133 | lang.mixin(kernel.global, exports); |
---|
134 | |
---|
135 | return exports; |
---|
136 | |
---|
137 | }); |
---|