Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 ///////////////////////////////////////////////////////////////////////////
6 //
7 // Utilities for navigation tests
8 //
9 ///////////////////////////////////////////////////////////////////////////
11 var body = "This frame was navigated.";
12 var target_url = "data:text/html,<html><body>" + body + "</body></html>";
14 var popup_body = "This is a popup";
15 var target_popup_url = "data:text/html,<html><body>" + popup_body + "</body></html>";
17 ///////////////////////////////////////////////////////////////////////////
18 // Functions that navigate frames
19 ///////////////////////////////////////////////////////////////////////////
21 function navigateByLocation(wnd) {
22 try {
23 wnd.location = target_url;
24 } catch(ex) {
25 // We need to keep our finished frames count consistent.
26 // Oddly, this ends up simulating the behavior of IE7.
27 window.open(target_url, "_blank", "width=10,height=10");
28 }
29 }
31 function navigateByOpen(name) {
32 window.open(target_url, name, "width=10,height=10");
33 }
35 function navigateByForm(name) {
36 var form = document.createElement("form");
37 form.action = target_url;
38 form.method = "POST";
39 form.target = name; document.body.appendChild(form);
40 form.submit();
41 }
43 var hyperlink_count = 0;
45 function navigateByHyperlink(name) {
46 var link = document.createElement("a");
47 link.href = target_url;
48 link.target = name;
49 link.id = "navigation_hyperlink_" + hyperlink_count++;
50 document.body.appendChild(link);
51 sendMouseEvent({type:"click"}, link.id);
52 }
54 ///////////////////////////////////////////////////////////////////////////
55 // Functions that call into Mochitest framework
56 ///////////////////////////////////////////////////////////////////////////
58 function isNavigated(wnd, message) {
59 var result = null;
60 try {
61 result = SpecialPowers.wrap(wnd).document.body.innerHTML;
62 } catch(ex) {
63 result = ex;
64 }
65 is(result, body, message);
66 }
68 function isBlank(wnd, message) {
69 var result = null;
70 try {
71 result = wnd.document.body.innerHTML;
72 } catch(ex) {
73 result = ex;
74 }
75 is(result, "This is a blank document.", message);
76 }
78 function isAccessible(wnd, message) {
79 try {
80 wnd.document.body.innerHTML;
81 ok(true, message);
82 } catch(ex) {
83 ok(false, message);
84 }
85 }
87 function isInaccessible(wnd, message) {
88 try {
89 wnd.document.body.innerHTML;
90 ok(false, message);
91 } catch(ex) {
92 ok(true, message);
93 }
94 }
96 ///////////////////////////////////////////////////////////////////////////
97 // Functions that require UniversalXPConnect privilege
98 ///////////////////////////////////////////////////////////////////////////
100 function xpcEnumerateContentWindows(callback) {
102 var Ci = SpecialPowers.Ci;
103 var ww = SpecialPowers.Cc["@mozilla.org/embedcomp/window-watcher;1"]
104 .getService(Ci.nsIWindowWatcher);
105 var enumerator = ww.getWindowEnumerator();
107 var contentWindows = [];
109 while (enumerator.hasMoreElements()) {
110 var win = enumerator.getNext();
111 if (/ChromeWindow/.exec(win)) {
112 var docshellTreeNode = win.QueryInterface(Ci.nsIInterfaceRequestor)
113 .getInterface(Ci.nsIWebNavigation)
114 .QueryInterface(Ci.nsIDocShellTreeItem);
115 var childCount = docshellTreeNode.childCount;
116 for (var i = 0; i < childCount; ++i) {
117 var childTreeNode = docshellTreeNode.getChildAt(i);
119 // we're only interested in content docshells
120 if (SpecialPowers.unwrap(childTreeNode.itemType) != Ci.nsIDocShellTreeItem.typeContent)
121 continue;
123 var webNav = childTreeNode.QueryInterface(Ci.nsIWebNavigation);
124 contentWindows.push(webNav.document.defaultView);
125 }
126 } else {
127 contentWindows.push(win);
128 }
129 }
131 while (contentWindows.length > 0)
132 callback(contentWindows.pop());
133 }
135 // Note: This only searches for top-level frames with this name.
136 function xpcGetFramesByName(name) {
137 var results = [];
139 xpcEnumerateContentWindows(function(win) {
140 if (win.name == name)
141 results.push(win);
142 });
144 return results;
145 }
147 function xpcCleanupWindows() {
148 xpcEnumerateContentWindows(function(win) {
149 if (win.location && win.location.protocol == "data:")
150 win.close();
151 });
152 }
154 function xpcWaitForFinishedFrames(callback, numFrames) {
155 var finishedFrameCount = 0;
156 function frameFinished() {
157 finishedFrameCount++;
159 if (finishedFrameCount == numFrames) {
160 clearInterval(frameWaitInterval);
161 setTimeout(callback, 0);
162 return;
163 }
165 if (finishedFrameCount > numFrames)
166 throw "Too many frames loaded.";
167 }
169 var finishedWindows = [];
171 function contains(obj, arr) {
172 for (var i = 0; i < arr.length; i++) {
173 if (obj === arr[i])
174 return true;
175 }
176 return false;
177 }
179 function searchForFinishedFrames(win) {
180 if ((escape(unescape(win.location)) == escape(target_url) ||
181 escape(unescape(win.location)) == escape(target_popup_url)) &&
182 win.document &&
183 win.document.body &&
184 (win.document.body.textContent == body ||
185 win.document.body.textContent == popup_body) &&
186 win.document.readyState == "complete") {
188 var util = win.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
189 .getInterface(SpecialPowers.Ci.nsIDOMWindowUtils);
190 var windowId = util.outerWindowID;
191 if (!contains(windowId, finishedWindows)) {
192 finishedWindows.push(windowId);
193 frameFinished();
194 }
195 }
196 for (var i = 0; i < win.frames.length; i++)
197 searchForFinishedFrames(win.frames[i]);
198 }
200 function poll() {
201 try {
202 // This only gives us UniversalXPConnect for the current stack frame
203 // We're using setInterval, so the main page's privileges are still normal
204 xpcEnumerateContentWindows(searchForFinishedFrames);
205 } catch(ex) {
206 // We might be accessing windows before they are fully constructed,
207 // which can throw. We'll find those frames on our next poll().
208 }
209 }
211 var frameWaitInterval = setInterval(poll, 500);
212 }