fune/toolkit/components/prompts/test/chromeScript.js
Kris Maglione 6adf9223ce Bug 1484496: Part 5b - Convert toolkit/ nsISimpleEnumerator users to use JS iteration. r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D3730

--HG--
extra : rebase_source : 935f166ec2c6581ba6f3fffe912404e81c8dc3d6
extra : histedit_source : ba701801de5205dcce6cfdccabe7b26aa7c7859c
2018-08-18 19:27:50 -07:00

228 lines
6.6 KiB
JavaScript

/* eslint-env mozilla/frame-script */
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.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 });
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 e = Services.focus.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", {}, 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 enumerator = Services.wm.getEnumerator("navigator:browser");
for (let {docShell} of Services.wm.getEnumerator(null)) {
var containedDocShells = docShell.getDocShellEnumerator(
docShell.typeChrome,
docShell.ENUMERATE_FORWARDS);
for (let childDocShell of containedDocShells) {
// Get the corresponding document for this docshell
// We don't want it if it's not done loading.
if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
continue;
var childDoc = childDocShell.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.)
if (Services.focus.focusedWindow != childDoc.defaultView)
continue;
return childDoc;
}
}
return null;
}