Backed out 3 changesets (bug 1435871) for mochitest crashes. CLOSED TREE

Backed out changeset 8eab3320b8c5 (bug 1435871)
Backed out changeset 29777ddd9def (bug 1435871)
Backed out changeset afdc3066f12c (bug 1435871)
This commit is contained in:
Dorel Luca 2018-10-17 23:06:14 +03:00
Родитель d56eb2a314
Коммит 001975a583
13 изменённых файлов: 136 добавлений и 245 удалений

Просмотреть файл

@ -1094,13 +1094,8 @@ window._gBrowser = {
if (newBrowser.hasAttribute("tabmodalPromptShowing")) {
let prompts = newBrowser.parentNode.getElementsByTagNameNS(this._XUL_NS, "tabmodalprompt");
let prompt = prompts[prompts.length - 1];
// @tabmodalPromptShowing is also set for other tab modal prompts
// (e.g. the Payment Request dialog) so there may not be a <tabmodalprompt>.
// Bug 1492814 will implement this for the Payment Request dialog.
if (prompt) {
prompt.Dialog.setDefaultFocus();
return;
}
prompt.Dialog.setDefaultFocus();
return;
}
// Focus the location bar if it was previously focused for that tab.

Просмотреть файл

@ -12,15 +12,10 @@
const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"]
.getService(Ci.nsIPaymentRequestService);
const paymentUISrv = Cc["@mozilla.org/dom/payments/payment-ui-service;1"]
.getService(Ci.nsIPaymentUIService);
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "BrowserWindowTracker",
"resource:///modules/BrowserWindowTracker.jsm");
ChromeUtils.defineModuleGetter(this, "OSKeyStore",
"resource://formautofill/OSKeyStore.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
@ -221,7 +216,7 @@ var paymentDialogWrapper = {
if (AppConstants.platform == "win") {
this.frame.setAttribute("selectmenulist", "ContentSelectDropdown-windows");
}
this.frame.setAttribute("src", "resource://payments/paymentRequest.xhtml");
this.frame.loadURI("resource://payments/paymentRequest.xhtml");
this.temporaryStore = {
addresses: new TempCollection("addresses"),
@ -457,7 +452,7 @@ var paymentDialogWrapper = {
Services.obs.addObserver(this, "formautofill-storage-changed", true);
let requestSerialized = this._serializeRequest(this.request);
let chromeWindow = window.frameElement.ownerGlobal;
let chromeWindow = Services.wm.getMostRecentWindow("navigator:browser");
let isPrivate = PrivateBrowsingUtils.isWindowPrivate(chromeWindow);
let [savedAddresses, savedBasicCards] =
@ -479,25 +474,28 @@ var paymentDialogWrapper = {
Cu.reportError("devtools.chrome.enabled must be enabled to debug the frame");
return;
}
let chromeWindow = Services.wm.getMostRecentWindow(null);
let {
gDevToolsBrowser,
} = ChromeUtils.import("resource://devtools/client/framework/gDevTools.jsm", {});
gDevToolsBrowser.openContentProcessToolbox({
selectedBrowser: document.getElementById("paymentRequestFrame").frameLoader,
selectedBrowser: chromeWindow.document.getElementById("paymentRequestFrame").frameLoader,
});
},
onOpenPreferences() {
BrowserWindowTracker.getTopWindow().openPreferences("privacy-form-autofill");
let prefsURL = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
prefsURL.data = "about:preferences#privacy-form-autofill";
Services.ww.openWindow(null, AppConstants.BROWSER_CHROME_URL, "_blank", "chrome,all,dialog=no",
prefsURL);
},
onPaymentCancel() {
const showResponse = this.createShowResponse({
acceptStatus: Ci.nsIPaymentActionResponse.PAYMENT_REJECTED,
});
paymentSrv.respondPayment(showResponse);
paymentUISrv.closePayment(this.request.requestId);
window.close();
},
async onPay({
@ -577,7 +575,7 @@ var paymentDialogWrapper = {
onCloseDialogMessage() {
// The PR is complete(), just close the dialog
paymentUISrv.closePayment(this.request.requestId);
window.close();
},
async onUpdateAutofillRecord(collectionName, record, guid, messageID) {
@ -687,12 +685,6 @@ var paymentDialogWrapper = {
this.onPaymentCancel();
break;
}
case "paymentDialogReady": {
window.dispatchEvent(new Event("tabmodaldialogready", {
bubbles: true,
}));
break;
}
case "pay": {
this.onPay(data);
break;
@ -701,9 +693,6 @@ var paymentDialogWrapper = {
this.onUpdateAutofillRecord(data.collectionName, data.record, data.guid, data.messageID);
break;
}
default: {
throw new Error(`paymentDialogWrapper: Unexpected messageType: ${messageType}`);
}
}
},
};

Просмотреть файл

@ -15,12 +15,8 @@
"use strict";
const XHTML_NS = "http://www.w3.org/1999/xhtml";
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "BrowserWindowTracker",
"resource:///modules/BrowserWindowTracker.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this,
"paymentSrv",
@ -36,6 +32,7 @@ function PaymentUIService() {
prefix: "Payment UI Service",
});
});
Services.wm.addListener(this);
this.log.debug("constructor");
}
@ -45,44 +42,27 @@ PaymentUIService.prototype = {
DIALOG_URL: "chrome://payments/content/paymentDialogWrapper.xul",
REQUEST_ID_PREFIX: "paymentRequest-",
// nsIWindowMediatorListener implementation:
onOpenWindow(aWindow) {},
onCloseWindow(aWindow) {
let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
let requestId = this.requestIdForWindow(domWindow);
if (!requestId || !paymentSrv.getPaymentRequestById(requestId)) {
return;
}
this.log.debug(`onCloseWindow, close of window for active requestId: ${requestId}`);
this.rejectPaymentForClosedDialog(requestId);
},
// nsIPaymentUIService implementation:
showPayment(requestId) {
this.log.debug("showPayment:", requestId);
let request = paymentSrv.getPaymentRequestById(requestId);
let merchantBrowser = this.findBrowserByTabId(request.tabId);
let chromeWindow = merchantBrowser.ownerGlobal;
let {gBrowser} = chromeWindow;
let browserContainer = gBrowser.getBrowserContainer(merchantBrowser);
let container = chromeWindow.document.createElementNS(XHTML_NS, "div");
container.dataset.requestId = requestId;
container.classList.add("paymentDialogContainer");
container.hidden = true;
let paymentsBrowser = chromeWindow.document.createElementNS(XHTML_NS, "iframe");
paymentsBrowser.classList.add("paymentDialogContainerFrame");
paymentsBrowser.setAttribute("type", "content");
paymentsBrowser.setAttribute("remote", "true");
paymentsBrowser.setAttribute("src", `${this.DIALOG_URL}?requestId=${requestId}`);
// append the frame to start the loading
container.appendChild(paymentsBrowser);
browserContainer.prepend(container);
// Only show the frame and change the UI when the dialog is ready to show.
paymentsBrowser.addEventListener("tabmodaldialogready", function readyToShow() {
container.hidden = false;
// Prevent focusing or interacting with the <browser>.
merchantBrowser.setAttribute("tabmodalPromptShowing", "true");
// Darken the merchant content area.
let tabModalBackground = chromeWindow.document.createElement("box");
tabModalBackground.classList.add("tab-modal-background", "payment-dialog-background");
// Insert the same way as <tabmodalprompt>.
merchantBrowser.parentNode.insertBefore(tabModalBackground,
merchantBrowser.nextElementSibling);
}, {
once: true,
});
let chromeWindow = Services.wm.getMostRecentWindow("navigator:browser");
chromeWindow.openDialog(`${this.DIALOG_URL}?requestId=${requestId}`,
`${this.REQUEST_ID_PREFIX}${requestId}`,
"modal,dialog,centerscreen,resizable=no");
},
abortPayment(requestId) {
@ -101,6 +81,20 @@ PaymentUIService.prototype = {
paymentSrv.respondPayment(abortResponse);
},
rejectPaymentForClosedDialog(requestId) {
this.log.debug("rejectPaymentForClosedDialog:", requestId);
const rejectResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"]
.createInstance(Ci.nsIPaymentShowActionResponse);
rejectResponse.init(requestId,
Ci.nsIPaymentActionResponse.PAYMENT_REJECTED,
"", // payment method
null, // payment method data
"", // payer name
"", // payer email
"");// payer phone
paymentSrv.respondPayment(rejectResponse);
},
completePayment(requestId) {
// completeStatus should be one of "timeout", "success", "fail", ""
let {completeStatus} = paymentSrv.getPaymentRequestById(requestId);
@ -115,18 +109,6 @@ PaymentUIService.prototype = {
closed = this.closeDialog(requestId);
break;
}
let dialogContainer;
if (!closed) {
// We need to call findDialog before we respond below as getPaymentRequestById
// may fail due to the request being removed upon completion.
dialogContainer = this.findDialog(requestId).dialogContainer;
if (!dialogContainer) {
this.log.error("completePayment: no dialog found");
return;
}
}
let responseCode = closed ?
Ci.nsIPaymentActionResponse.COMPLETE_SUCCEEDED :
Ci.nsIPaymentActionResponse.COMPLETE_FAILED;
@ -136,18 +118,23 @@ PaymentUIService.prototype = {
paymentSrv.respondPayment(completeResponse.QueryInterface(Ci.nsIPaymentActionResponse));
if (!closed) {
dialogContainer.querySelector("iframe").contentWindow.paymentDialogWrapper.updateRequest();
let dialog = this.findDialog(requestId);
if (!dialog) {
this.log.error("completePayment: no dialog found");
return;
}
dialog.paymentDialogWrapper.updateRequest();
}
},
updatePayment(requestId) {
let {dialogContainer} = this.findDialog(requestId);
let dialog = this.findDialog(requestId);
this.log.debug("updatePayment:", requestId);
if (!dialogContainer) {
if (!dialog) {
this.log.error("updatePayment: no dialog found");
return;
}
dialogContainer.querySelector("iframe").contentWindow.paymentDialogWrapper.updateRequest();
dialog.paymentDialogWrapper.updateRequest();
},
closePayment(requestId) {
@ -161,47 +148,31 @@ PaymentUIService.prototype = {
* @returns {boolean} whether the specified dialog was closed.
*/
closeDialog(requestId) {
let {
browser,
dialogContainer,
} = this.findDialog(requestId);
if (!dialogContainer) {
let win = this.findDialog(requestId);
if (!win) {
return false;
}
this.log.debug(`closing: ${requestId}`);
dialogContainer.remove();
browser.parentElement.querySelector(".payment-dialog-background").remove();
this.log.debug(`closing: ${win.name}`);
win.close();
return true;
},
findDialog(requestId) {
for (let win of BrowserWindowTracker.orderedWindows) {
for (let dialogContainer of win.document.querySelectorAll(".paymentDialogContainer")) {
if (dialogContainer.dataset.requestId == requestId) {
return {
dialogContainer,
browser: dialogContainer.parentElement.querySelector("browser"),
};
}
for (let win of Services.wm.getEnumerator(null)) {
if (win.name == `${this.REQUEST_ID_PREFIX}${requestId}`) {
return win;
}
}
return {};
return null;
},
findBrowserByTabId(tabId) {
for (let win of BrowserWindowTracker.orderedWindows) {
for (let browser of win.gBrowser.browsers) {
if (!browser.frameLoader || !browser.frameLoader.tabParent) {
continue;
}
if (browser.frameLoader.tabParent.tabId == tabId) {
return browser;
}
}
}
requestIdForWindow(window) {
let windowName = window.name;
this.log.error("findBrowserByTabId: No browser found for tabId:", tabId);
return null;
return windowName.startsWith(this.REQUEST_ID_PREFIX) ?
windowName.replace(this.REQUEST_ID_PREFIX, "") : // returns suffix, which is the requestId
null;
},
};

Просмотреть файл

@ -385,7 +385,7 @@ export default class PaymentDialog extends PaymentStateSubscriberMixin(HTMLEleme
let link = manageTextEl.querySelector("a");
// The href is only set to be exposed to accessibility tools so users know what will open.
// The actual opening happens from the click event listener.
link.href = "about:preferences#privacy-form-autofill";
link.href = "about:preferences#privacy-address-autofill";
}
this._renderPayButton(state);

Просмотреть файл

@ -109,6 +109,7 @@ var paymentRequest = {
onPaymentRequestLoad() {
log.debug("onPaymentRequestLoad");
window.addEventListener("unload", this, {once: true});
this.sendMessageToChrome("paymentDialogReady");
// Automatically show the debugging console if loaded with a truthy `debug` query parameter.
if (new URLSearchParams(location.search).get("debug")) {
@ -169,8 +170,6 @@ var paymentRequest = {
}
paymentDialog.setStateFromParent(state);
this.sendMessageToChrome("paymentDialogReady");
},
openPreferences() {

Просмотреть файл

@ -112,7 +112,6 @@ var PaymentTestUtils = {
* @param {PaymentMethodData[]} methodData
* @param {PaymentDetailsInit} details
* @param {PaymentOptions} options
* @returns {Object}
*/
createAndShowRequest: ({methodData, details, options}) => {
const rq = new content.PaymentRequest(Cu.cloneInto(methodData, content), details, options);
@ -122,9 +121,19 @@ var PaymentTestUtils = {
content.showPromise = rq.show();
handle.destruct();
return {
requestId: rq.id,
};
},
/**
* Add a rejection handler for the `showPromise` created by createAndShowRequest
* and stash details of any eventual exception or response in `rqResult`
*/
catchShowPromiseRejection: () => {
content.rqResult = {};
content.showPromise.then(res => content.rqResult.response = res)
.catch(ex => content.rqResult.showException = {
name: ex.name,
message: ex.message,
});
},
},

Просмотреть файл

@ -45,8 +45,6 @@ add_task(async function test_dropdown() {
}
is(event.target.parentElement.id, expectedPopupID, "Checked menulist of opened popup");
event.target.hidePopup(true);
info("clicking cancel");
spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);

Просмотреть файл

@ -20,8 +20,9 @@ add_task(async function test_openPreferences() {
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
});
let prefsTabPromise = BrowserTestUtils.waitForNewTab(gBrowser,
"about:preferences#privacy-form-autofill");
let prefsWindowPromise = BrowserTestUtils.waitForNewWindow({
url: "about:preferences#privacy",
});
let prefsLoadedPromise = TestUtils.topicObserved("sync-pane-loaded");
@ -48,11 +49,11 @@ add_task(async function test_openPreferences() {
isMac: AppConstants.platform == "macosx",
});
let prefsTab = await prefsTabPromise;
ok(prefsTab, "Ensure a tab was opened");
let browserWin = await prefsWindowPromise;
ok(browserWin, "Ensure a window was opened");
await prefsLoadedPromise;
await BrowserTestUtils.removeTab(prefsTab);
await BrowserTestUtils.closeWindow(browserWin);
spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");

Просмотреть файл

@ -143,6 +143,31 @@ add_task(async function test_show_completePayment2() {
});
});
add_task(async function test_show_closeReject_dialog() {
await BrowserTestUtils.withNewTab({
gBrowser,
url: BLANK_PAGE_URL,
}, async browser => {
let {win} =
await setupPaymentDialog(browser, {
methodData,
details,
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
}
);
await ContentTask.spawn(browser, null, PTU.ContentTasks.catchShowPromiseRejection);
info("Closing the dialog to reject the payment request");
BrowserTestUtils.closeWindow(win);
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
let result = await ContentTask.spawn(browser, null, async () => content.rqResult);
ok(result.showException, "Expected promise rejection from the rq.show() promise");
ok(!result.response,
"rq.show() shouldn't resolve to a response");
});
});
add_task(async function test_localized() {
await BrowserTestUtils.withNewTab({
gBrowser,
@ -251,68 +276,3 @@ add_task(async function test_supportedNetworks() {
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
});
});
add_task(async function test_tab_modal() {
await BrowserTestUtils.withNewTab({
gBrowser,
url: BLANK_PAGE_URL,
}, async browser => {
let {win, frame} = await setupPaymentDialog(browser, {
methodData,
details,
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
});
await TestUtils.waitForCondition(() => {
return !document.querySelector(".paymentDialogContainer").hidden;
}, "Waiting for container to be visible after the dialog's ready");
ok(!EventUtils.isHidden(win.frameElement), "Frame should be visible");
let {
bottom: toolboxBottom,
} = document.getElementById("navigator-toolbox").getBoundingClientRect();
let {x, y} = win.frameElement.getBoundingClientRect();
ok(y > 0, "Frame should have y > 0");
// Inset by 10px since the corner point doesn't return the frame due to the
// border-radius.
is(document.elementFromPoint(x + 10, y + 10), win.frameElement,
"Check .paymentDialogContainerFrame is visible");
info("Click to the left of the dialog over the content area");
isnot(document.elementFromPoint(x - 10, y + 50), browser,
"Check clicks on the merchant content area don't go to the browser");
is(document.elementFromPoint(x - 10, y + 50),
document.querySelector(".payment-dialog-background"),
"Check clicks on the merchant content area go to the payment dialog background");
ok(y < toolboxBottom - 2, "Dialog should overlap the toolbox by at least 2px");
await BrowserTestUtils.withNewTab({
gBrowser,
url: BLANK_PAGE_URL,
}, async newBrowser => {
let {
x: x2,
y: y2,
} = win.frameElement.getBoundingClientRect();
is(x2, x, "Check x-coordinate is the same");
is(y2, y, "Check y-coordinate is the same");
isnot(document.elementFromPoint(x + 10, y + 10), win.frameElement,
"Check .paymentDialogContainerFrame is hidden");
});
let {
x: x3,
y: y3,
} = win.frameElement.getBoundingClientRect();
is(x3, x, "Check x-coordinate is the same again");
is(y3, y, "Check y-coordinate is the same again");
is(document.elementFromPoint(x + 10, y + 10), win.frameElement,
"Check .paymentDialogContainerFrame is visible again");
spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
});
});

Просмотреть файл

@ -17,13 +17,12 @@ const SAVE_ADDRESS_DEFAULT_PREF = "dom.payments.defaults.saveAddress";
const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"]
.getService(Ci.nsIPaymentRequestService);
const paymentUISrv = Cc["@mozilla.org/dom/payments/payment-ui-service;1"]
.getService(Ci.nsIPaymentUIService).wrappedJSObject;
.getService().wrappedJSObject;
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {});
const {formAutofillStorage} = ChromeUtils.import(
"resource://formautofill/FormAutofillStorage.jsm", {});
const {PaymentTestUtils: PTU} = ChromeUtils.import(
"resource://testing-common/PaymentTestUtils.jsm", {});
ChromeUtils.import("resource:///modules/BrowserWindowTracker.jsm");
ChromeUtils.import("resource://gre/modules/CreditCard.jsm");
function getPaymentRequests() {
@ -32,23 +31,19 @@ function getPaymentRequests() {
/**
* Return the container (e.g. dialog or overlay) that the payment request contents are shown in.
* This abstracts away the details of the widget used so that this can more easily transition to
* another kind of dialog/overlay.
* @param {string} requestId
* This abstracts away the details of the widget used so that this can more earily transition from a
* dialog to another kind of overlay.
* Consumers shouldn't rely on a dialog window being returned.
* @returns {Promise}
*/
async function getPaymentWidget(requestId) {
return BrowserTestUtils.waitForCondition(() => {
let {dialogContainer} = paymentUISrv.findDialog(requestId);
if (!dialogContainer) {
return false;
}
let browserIFrame = dialogContainer.querySelector("iframe");
if (!browserIFrame) {
return false;
}
return browserIFrame.contentWindow;
}, "payment dialog should be opened");
async function getPaymentWidget() {
let win;
await BrowserTestUtils.waitForCondition(() => {
win = Services.wm.getMostRecentWindow(null);
return win.name.startsWith(paymentUISrv.REQUEST_ID_PREFIX);
}, "payment dialog should be the most recent");
return win;
}
async function getPaymentFrame(widget) {
@ -242,18 +237,19 @@ function checkPaymentMethodDetailsMatchesCard(methodDetails, card, msg) {
*/
async function setupPaymentDialog(browser, {methodData, details, options, merchantTaskFn}) {
let dialogReadyPromise = waitForWidgetReady();
let {requestId} = await ContentTask.spawn(browser,
{
methodData,
details,
options,
},
merchantTaskFn);
ok(requestId, "requestId should be defined");
await ContentTask.spawn(browser,
{
methodData,
details,
options,
},
merchantTaskFn);
// get a reference to the UI dialog and the requestId
let [win] = await Promise.all([getPaymentWidget(requestId), dialogReadyPromise]);
let [win] = await Promise.all([getPaymentWidget(), dialogReadyPromise]);
ok(win, "Got payment widget");
let requestId = paymentUISrv.requestIdForWindow(win);
ok(requestId, "requestId should be defined");
is(win.closed, false, "dialog should not be closed");
let frame = await getPaymentFrame(win);

Просмотреть файл

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Tab Modal Prompt boxes */
.tab-modal-background,
tabmodalprompt {
width: 100%;
height: 100%;
@ -34,19 +33,3 @@ tabmodalprompt {
tabmodalprompt label[value=""] {
visibility: collapse;
}
/* Tab-Modal Payment Request widget */
.paymentDialogContainer {
position: absolute;
}
.paymentDialogContainerFrame {
box-sizing: border-box;
height: 500px;
/* Center the dialog with 20% on the left/right and 60% width for content */
left: 20%;
position: absolute;
/* Overlap the chrome */
top: -6px;
width: 60%;
}

Просмотреть файл

@ -3,17 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Tab Modal Prompt boxes */
.tab-modal-background,
tabmodalprompt {
background-color: hsla(0,0%,10%,.5);
}
tabmodalprompt {
font-family: sans-serif; /* use content font not system UI font */
font-size: 110%;
}
.paymentDialogContainerFrame,
.tabmodalprompt-mainContainer {
color: black;
background-color: hsla(0,0%,100%,.95);

Просмотреть файл

@ -3,16 +3,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Tab Modal Prompt boxes */
.tab-modal-background,
tabmodalprompt {
background-color: hsla(0,0%,10%,.5);
}
tabmodalprompt {
font-family: sans-serif; /* use content font not system UI font */
}
.paymentDialogContainerFrame,
.tabmodalprompt-mainContainer {
color: -moz-fieldText;
background-color: -moz-field;