michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /////////////////////////////////////////////////////////////////////////// michael@0: // michael@0: // Utilities for navigation tests michael@0: // michael@0: /////////////////////////////////////////////////////////////////////////// michael@0: michael@0: var body = "This frame was navigated."; michael@0: var target_url = "data:text/html," + body + ""; michael@0: michael@0: var popup_body = "This is a popup"; michael@0: var target_popup_url = "data:text/html," + popup_body + ""; michael@0: michael@0: /////////////////////////////////////////////////////////////////////////// michael@0: // Functions that navigate frames michael@0: /////////////////////////////////////////////////////////////////////////// michael@0: michael@0: function navigateByLocation(wnd) { michael@0: try { michael@0: wnd.location = target_url; michael@0: } catch(ex) { michael@0: // We need to keep our finished frames count consistent. michael@0: // Oddly, this ends up simulating the behavior of IE7. michael@0: window.open(target_url, "_blank", "width=10,height=10"); michael@0: } michael@0: } michael@0: michael@0: function navigateByOpen(name) { michael@0: window.open(target_url, name, "width=10,height=10"); michael@0: } michael@0: michael@0: function navigateByForm(name) { michael@0: var form = document.createElement("form"); michael@0: form.action = target_url; michael@0: form.method = "POST"; michael@0: form.target = name; document.body.appendChild(form); michael@0: form.submit(); michael@0: } michael@0: michael@0: var hyperlink_count = 0; michael@0: michael@0: function navigateByHyperlink(name) { michael@0: var link = document.createElement("a"); michael@0: link.href = target_url; michael@0: link.target = name; michael@0: link.id = "navigation_hyperlink_" + hyperlink_count++; michael@0: document.body.appendChild(link); michael@0: sendMouseEvent({type:"click"}, link.id); michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////// michael@0: // Functions that call into Mochitest framework michael@0: /////////////////////////////////////////////////////////////////////////// michael@0: michael@0: function isNavigated(wnd, message) { michael@0: var result = null; michael@0: try { michael@0: result = SpecialPowers.wrap(wnd).document.body.innerHTML; michael@0: } catch(ex) { michael@0: result = ex; michael@0: } michael@0: is(result, body, message); michael@0: } michael@0: michael@0: function isBlank(wnd, message) { michael@0: var result = null; michael@0: try { michael@0: result = wnd.document.body.innerHTML; michael@0: } catch(ex) { michael@0: result = ex; michael@0: } michael@0: is(result, "This is a blank document.", message); michael@0: } michael@0: michael@0: function isAccessible(wnd, message) { michael@0: try { michael@0: wnd.document.body.innerHTML; michael@0: ok(true, message); michael@0: } catch(ex) { michael@0: ok(false, message); michael@0: } michael@0: } michael@0: michael@0: function isInaccessible(wnd, message) { michael@0: try { michael@0: wnd.document.body.innerHTML; michael@0: ok(false, message); michael@0: } catch(ex) { michael@0: ok(true, message); michael@0: } michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////// michael@0: // Functions that require UniversalXPConnect privilege michael@0: /////////////////////////////////////////////////////////////////////////// michael@0: michael@0: function xpcEnumerateContentWindows(callback) { michael@0: michael@0: var Ci = SpecialPowers.Ci; michael@0: var ww = SpecialPowers.Cc["@mozilla.org/embedcomp/window-watcher;1"] michael@0: .getService(Ci.nsIWindowWatcher); michael@0: var enumerator = ww.getWindowEnumerator(); michael@0: michael@0: var contentWindows = []; michael@0: michael@0: while (enumerator.hasMoreElements()) { michael@0: var win = enumerator.getNext(); michael@0: if (/ChromeWindow/.exec(win)) { michael@0: var docshellTreeNode = win.QueryInterface(Ci.nsIInterfaceRequestor) michael@0: .getInterface(Ci.nsIWebNavigation) michael@0: .QueryInterface(Ci.nsIDocShellTreeItem); michael@0: var childCount = docshellTreeNode.childCount; michael@0: for (var i = 0; i < childCount; ++i) { michael@0: var childTreeNode = docshellTreeNode.getChildAt(i); michael@0: michael@0: // we're only interested in content docshells michael@0: if (SpecialPowers.unwrap(childTreeNode.itemType) != Ci.nsIDocShellTreeItem.typeContent) michael@0: continue; michael@0: michael@0: var webNav = childTreeNode.QueryInterface(Ci.nsIWebNavigation); michael@0: contentWindows.push(webNav.document.defaultView); michael@0: } michael@0: } else { michael@0: contentWindows.push(win); michael@0: } michael@0: } michael@0: michael@0: while (contentWindows.length > 0) michael@0: callback(contentWindows.pop()); michael@0: } michael@0: michael@0: // Note: This only searches for top-level frames with this name. michael@0: function xpcGetFramesByName(name) { michael@0: var results = []; michael@0: michael@0: xpcEnumerateContentWindows(function(win) { michael@0: if (win.name == name) michael@0: results.push(win); michael@0: }); michael@0: michael@0: return results; michael@0: } michael@0: michael@0: function xpcCleanupWindows() { michael@0: xpcEnumerateContentWindows(function(win) { michael@0: if (win.location && win.location.protocol == "data:") michael@0: win.close(); michael@0: }); michael@0: } michael@0: michael@0: function xpcWaitForFinishedFrames(callback, numFrames) { michael@0: var finishedFrameCount = 0; michael@0: function frameFinished() { michael@0: finishedFrameCount++; michael@0: michael@0: if (finishedFrameCount == numFrames) { michael@0: clearInterval(frameWaitInterval); michael@0: setTimeout(callback, 0); michael@0: return; michael@0: } michael@0: michael@0: if (finishedFrameCount > numFrames) michael@0: throw "Too many frames loaded."; michael@0: } michael@0: michael@0: var finishedWindows = []; michael@0: michael@0: function contains(obj, arr) { michael@0: for (var i = 0; i < arr.length; i++) { michael@0: if (obj === arr[i]) michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: function searchForFinishedFrames(win) { michael@0: if ((escape(unescape(win.location)) == escape(target_url) || michael@0: escape(unescape(win.location)) == escape(target_popup_url)) && michael@0: win.document && michael@0: win.document.body && michael@0: (win.document.body.textContent == body || michael@0: win.document.body.textContent == popup_body) && michael@0: win.document.readyState == "complete") { michael@0: michael@0: var util = win.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) michael@0: .getInterface(SpecialPowers.Ci.nsIDOMWindowUtils); michael@0: var windowId = util.outerWindowID; michael@0: if (!contains(windowId, finishedWindows)) { michael@0: finishedWindows.push(windowId); michael@0: frameFinished(); michael@0: } michael@0: } michael@0: for (var i = 0; i < win.frames.length; i++) michael@0: searchForFinishedFrames(win.frames[i]); michael@0: } michael@0: michael@0: function poll() { michael@0: try { michael@0: // This only gives us UniversalXPConnect for the current stack frame michael@0: // We're using setInterval, so the main page's privileges are still normal michael@0: xpcEnumerateContentWindows(searchForFinishedFrames); michael@0: } catch(ex) { michael@0: // We might be accessing windows before they are fully constructed, michael@0: // which can throw. We'll find those frames on our next poll(). michael@0: } michael@0: } michael@0: michael@0: var frameWaitInterval = setInterval(poll, 500); michael@0: } michael@0: