Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
1 const Ci = SpecialPowers.Ci;
2 const Cc = SpecialPowers.Cc;
3 ok(Ci != null, "Access Ci");
4 ok(Cc != null, "Access Cc");
6 var didDialog;
8 var isSelectDialog = false;
9 var isTabModal = false;
10 var usePromptService = true;
12 var timer; // keep in outer scope so it's not GC'd before firing
13 function startCallbackTimer() {
14 didDialog = false;
16 // Delay before the callback twiddles the prompt.
17 const dialogDelay = 10;
19 // Use a timer to invoke a callback to twiddle the authentication dialog
20 timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
21 timer.init(observer, dialogDelay, Ci.nsITimer.TYPE_ONE_SHOT);
22 }
25 var observer = {
26 QueryInterface : function (iid) {
27 const interfaces = [Ci.nsIObserver,
28 Ci.nsISupports, Ci.nsISupportsWeakReference];
30 if (!interfaces.some( function(v) { return iid.equals(v) } ))
31 throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
32 return this;
33 },
35 observe : SpecialPowers.wrapCallback(function (subject, topic, data) {
36 try {
37 if (isTabModal) {
38 var promptBox = getTabModalPromptBox(window);
39 ok(promptBox, "got tabmodal promptbox");
40 var prompts = SpecialPowers.wrap(promptBox).listPrompts();
41 if (prompts.length)
42 handleDialog(prompts[0].Dialog.ui, testNum);
43 else
44 startCallbackTimer(); // try again in a bit
45 } else {
46 var doc = getDialogDoc();
47 if (isSelectDialog && doc)
48 handleDialog(doc, testNum);
49 else if (doc)
50 handleDialog(doc.defaultView.Dialog.ui, testNum);
51 else
52 startCallbackTimer(); // try again in a bit
53 }
54 } catch (e) {
55 ok(false, "Exception thrown in the timer callback: " + e + " at " + (e.fileName || e.filename) + ":" + (e.lineNumber || e.linenumber));
56 }
57 })
58 };
60 function getTabModalPromptBox(domWin) {
61 var promptBox = null;
63 // Given a content DOM window, returns the chrome window it's in.
64 function getChromeWindow(aWindow) {
65 var chromeWin = SpecialPowers.wrap(aWindow).QueryInterface(Ci.nsIInterfaceRequestor)
66 .getInterface(Ci.nsIWebNavigation)
67 .QueryInterface(Ci.nsIDocShell)
68 .chromeEventHandler.ownerDocument.defaultView;
69 return chromeWin;
70 }
72 try {
73 // Get the topmost window, in case we're in a frame.
74 var promptWin = domWin.top;
76 // Get the chrome window for the content window we're using.
77 var chromeWin = getChromeWindow(promptWin);
79 if (chromeWin.getTabModalPromptBox)
80 promptBox = chromeWin.getTabModalPromptBox(promptWin);
81 } catch (e) {
82 // If any errors happen, just assume no tabmodal prompter.
83 }
85 // Callers get confused by a wrapped promptBox here.
86 return SpecialPowers.unwrap(promptBox);
87 }
89 function getDialogDoc() {
90 // Trudge through all the open windows, until we find the one
91 // that has either commonDialog.xul or selectDialog.xul loaded.
92 var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
93 getService(Ci.nsIWindowMediator);
94 //var enumerator = wm.getEnumerator("navigator:browser");
95 var enumerator = wm.getXULWindowEnumerator(null);
97 while (enumerator.hasMoreElements()) {
98 var win = enumerator.getNext();
99 var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
101 var containedDocShells = windowDocShell.getDocShellEnumerator(
102 Ci.nsIDocShellTreeItem.typeChrome,
103 Ci.nsIDocShell.ENUMERATE_FORWARDS);
104 while (containedDocShells.hasMoreElements()) {
105 // Get the corresponding document for this docshell
106 var childDocShell = containedDocShells.getNext();
107 // We don't want it if it's not done loading.
108 if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
109 continue;
110 var childDoc = childDocShell.QueryInterface(Ci.nsIDocShell)
111 .contentViewer
112 .DOMDocument;
114 //ok(true, "Got window: " + childDoc.location.href);
115 if (childDoc.location.href == "chrome://global/content/commonDialog.xul")
116 return childDoc;
117 if (childDoc.location.href == "chrome://global/content/selectDialog.xul")
118 return childDoc;
119 }
120 }
122 return null;
123 }