diff options
Diffstat (limited to 'toolkit/components/prompts/test/chromeScript.js')
-rw-r--r-- | toolkit/components/prompts/test/chromeScript.js | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/toolkit/components/prompts/test/chromeScript.js b/toolkit/components/prompts/test/chromeScript.js new file mode 100644 index 000000000..7b2d37100 --- /dev/null +++ b/toolkit/components/prompts/test/chromeScript.js @@ -0,0 +1,241 @@ +const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; +Components.utils.import("resource://gre/modules/Services.jsm"); +Components.utils.import("resource://gre/modules/Timer.jsm"); + +// Define these to make EventUtils happy. +let window = this; +let parent = {}; + +let EventUtils = {}; +Services.scriptloader.loadSubScript( + "chrome://mochikit/content/tests/SimpleTest/EventUtils.js", + EventUtils +); + +addMessageListener("handlePrompt", msg => { + handlePromptWhenItAppears(msg.action, msg.isTabModal, msg.isSelect); +}); + +function handlePromptWhenItAppears(action, isTabModal, isSelect) { + let interval = setInterval(() => { + if (handlePrompt(action, isTabModal, isSelect)) { + clearInterval(interval); + } + }, 100); +} + +function handlePrompt(action, isTabModal, isSelect) { + let ui; + + if (isTabModal) { + let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); + let gBrowser = browserWin.gBrowser; + let promptManager = gBrowser.getTabModalPromptBox(gBrowser.selectedBrowser); + let prompts = promptManager.listPrompts(); + if (!prompts.length) { + return false; // try again in a bit + } + + ui = prompts[0].Dialog.ui; + } else { + let doc = getDialogDoc(); + if (!doc) { + return false; // try again in a bit + } + + if (isSelect) + ui = doc; + else + ui = doc.defaultView.Dialog.ui; + + } + + let promptState; + if (isSelect) { + promptState = getSelectState(ui); + dismissSelect(ui, action); + } else { + promptState = getPromptState(ui); + dismissPrompt(ui, action); + } + sendAsyncMessage("promptHandled", { promptState: promptState }); + return true; +} + +function getSelectState(ui) { + let listbox = ui.getElementById("list"); + + let state = {}; + state.msg = ui.getElementById("info.txt").value; + state.selectedIndex = listbox.selectedIndex; + state.items = []; + + for (let i = 0; i < listbox.itemCount; i++) { + let item = listbox.getItemAtIndex(i).label; + state.items.push(item); + } + + return state; +} + +function getPromptState(ui) { + let state = {}; + state.msg = ui.infoBody.textContent; + state.titleHidden = ui.infoTitle.getAttribute("hidden") == "true"; + state.textHidden = ui.loginContainer.hidden; + state.passHidden = ui.password1Container.hidden; + state.checkHidden = ui.checkboxContainer.hidden; + state.checkMsg = ui.checkbox.label; + state.checked = ui.checkbox.checked; + // tab-modal prompts don't have an infoIcon + state.iconClass = ui.infoIcon ? ui.infoIcon.className : null; + state.textValue = ui.loginTextbox.getAttribute("value"); + state.passValue = ui.password1Textbox.getAttribute("value"); + + state.butt0Label = ui.button0.label; + state.butt1Label = ui.button1.label; + state.butt2Label = ui.button2.label; + + state.butt0Disabled = ui.button0.disabled; + state.butt1Disabled = ui.button1.disabled; + state.butt2Disabled = ui.button2.disabled; + + function isDefaultButton(b) { + return (b.hasAttribute("default") && + b.getAttribute("default") == "true"); + } + state.defButton0 = isDefaultButton(ui.button0); + state.defButton1 = isDefaultButton(ui.button1); + state.defButton2 = isDefaultButton(ui.button2); + + let fm = Cc["@mozilla.org/focus-manager;1"]. + getService(Ci.nsIFocusManager); + let e = fm.focusedElement; + + if (e == null) { + state.focused = null; + } else if (ui.button0.isSameNode(e)) { + state.focused = "button0"; + } else if (ui.button1.isSameNode(e)) { + state.focused = "button1"; + } else if (ui.button2.isSameNode(e)) { + state.focused = "button2"; + } else if (ui.loginTextbox.inputField.isSameNode(e)) { + state.focused = "textField"; + } else if (ui.password1Textbox.inputField.isSameNode(e)) { + state.focused = "passField"; + } else if (ui.infoBody.isSameNode(e)) { + state.focused = "infoBody"; + } else { + state.focused = "ERROR: unexpected element focused: " + (e ? e.localName : "<null>"); + } + + return state; +} + +function dismissSelect(ui, action) { + let dialog = ui.getElementsByTagName("dialog")[0]; + let listbox = ui.getElementById("list"); + + if (action.selectItem) { + listbox.selectedIndex = 1; + } + + if (action.buttonClick == "ok") { + dialog.acceptDialog(); + } else if (action.buttonClick == "cancel") { + dialog.cancelDialog(); + } +} + +function dismissPrompt(ui, action) { + if (action.setCheckbox) { + // Annoyingly, the prompt code is driven by oncommand. + ui.checkbox.setChecked(true); + ui.checkbox.doCommand(); + } + + if ("textField" in action) { + ui.loginTextbox.setAttribute("value", action.textField); + } + + if ("passField" in action) { + ui.password1Textbox.setAttribute("value", action.passField); + } + + switch (action.buttonClick) { + case "ok": + case 0: + ui.button0.click(); + break; + case "cancel": + case 1: + ui.button1.click(); + break; + case 2: + ui.button2.click(); + break; + case "ESC": + // XXX This is assuming tab-modal. + let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); + EventUtils.synthesizeKey("KEY_Escape", { code: "Escape" }, browserWin); + break; + case "pollOK": + // Buttons are disabled at the moment, poll until they're reenabled. + // Can't use setInterval here, because the window's in a modal state + // and thus DOM events are suppressed. + let interval = setInterval(() => { + if (ui.button0.disabled) + return; + ui.button0.click(); + clearInterval(interval); + }, 100); + break; + + default: + throw "dismissPrompt action listed unknown button."; + } +} + +function getDialogDoc() { + // Trudge through all the open windows, until we find the one + // that has either commonDialog.xul or selectDialog.xul loaded. + var wm = Cc["@mozilla.org/appshell/window-mediator;1"]. + getService(Ci.nsIWindowMediator); + // var enumerator = wm.getEnumerator("navigator:browser"); + var enumerator = wm.getXULWindowEnumerator(null); + + while (enumerator.hasMoreElements()) { + var win = enumerator.getNext(); + var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell; + + var containedDocShells = windowDocShell.getDocShellEnumerator( + Ci.nsIDocShellTreeItem.typeChrome, + Ci.nsIDocShell.ENUMERATE_FORWARDS); + while (containedDocShells.hasMoreElements()) { + // Get the corresponding document for this docshell + var childDocShell = containedDocShells.getNext(); + // We don't want it if it's not done loading. + if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE) + continue; + var childDoc = childDocShell.QueryInterface(Ci.nsIDocShell) + .contentViewer + .DOMDocument; + + if (childDoc.location.href != "chrome://global/content/commonDialog.xul" && + childDoc.location.href != "chrome://global/content/selectDialog.xul") + continue; + + // We're expecting the dialog to be focused. If it's not yet, try later. + // (In particular, this is needed on Linux to reliably check focused elements.) + let fm = Cc["@mozilla.org/focus-manager;1"]. + getService(Ci.nsIFocusManager); + if (fm.focusedWindow != childDoc.defaultView) + continue; + + return childDoc; + } + } + + return null; +} |