mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Merge mozilla-inbound to mozilla-central. a=merge
This commit is contained in:
commit
de7676288a
@ -58,15 +58,13 @@ var CaptivePortalWatcher = {
|
||||
this._captivePortalDetected();
|
||||
|
||||
// Automatically open a captive portal tab if there's no other browser window.
|
||||
let windows = Services.wm.getEnumerator("navigator:browser");
|
||||
if (windows.getNext() == window && !windows.hasMoreElements()) {
|
||||
if (BrowserWindowTracker.windowCount == 1) {
|
||||
this.ensureCaptivePortalTab();
|
||||
}
|
||||
} else if (cps.state == cps.UNKNOWN) {
|
||||
// We trigger a portal check after delayed startup to avoid doing a network
|
||||
// request before first paint.
|
||||
this._delayedRecheckPending = true;
|
||||
Services.obs.addObserver(this, "browser-delayed-startup-finished");
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "PORTAL_RECHECK_DELAY_MS",
|
||||
@ -78,22 +76,18 @@ var CaptivePortalWatcher = {
|
||||
Services.obs.removeObserver(this, "captive-portal-login-abort");
|
||||
Services.obs.removeObserver(this, "captive-portal-login-success");
|
||||
|
||||
if (this._delayedRecheckPending) {
|
||||
Services.obs.removeObserver(this, "browser-delayed-startup-finished");
|
||||
}
|
||||
this._cancelDelayedCaptivePortal();
|
||||
},
|
||||
|
||||
if (this._delayedCaptivePortalDetectedInProgress) {
|
||||
Services.obs.removeObserver(this, "xul-window-visible");
|
||||
delayedStartup() {
|
||||
if (this._delayedRecheckPending) {
|
||||
delete this._delayedRecheckPending;
|
||||
cps.recheckCaptivePortal();
|
||||
}
|
||||
},
|
||||
|
||||
observe(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "browser-delayed-startup-finished":
|
||||
Services.obs.removeObserver(this, "browser-delayed-startup-finished");
|
||||
delete this._delayedRecheckPending;
|
||||
cps.recheckCaptivePortal();
|
||||
break;
|
||||
case "captive-portal-login":
|
||||
this._captivePortalDetected();
|
||||
break;
|
||||
@ -101,8 +95,8 @@ var CaptivePortalWatcher = {
|
||||
case "captive-portal-login-success":
|
||||
this._captivePortalGone();
|
||||
break;
|
||||
case "xul-window-visible":
|
||||
this._delayedCaptivePortalDetected();
|
||||
case "delayed-captive-portal-handled":
|
||||
this._cancelDelayedCaptivePortal();
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -113,9 +107,10 @@ var CaptivePortalWatcher = {
|
||||
}
|
||||
|
||||
let win = BrowserWindowTracker.getTopWindow();
|
||||
|
||||
// Used by tests: ignore the main test window in order to enable testing of
|
||||
// the case where we have no open windows.
|
||||
if (win && win.document.documentElement.getAttribute("ignorecaptiveportal")) {
|
||||
if (win.document.documentElement.getAttribute("ignorecaptiveportal")) {
|
||||
win = null;
|
||||
}
|
||||
|
||||
@ -123,9 +118,10 @@ var CaptivePortalWatcher = {
|
||||
// This is so that if a different application was focused, when the user
|
||||
// (re-)focuses a browser window, we open the tab immediately in that window
|
||||
// so they can log in before continuing to browse.
|
||||
if (win != Services.ww.activeWindow) {
|
||||
if (win != Services.focus.activeWindow) {
|
||||
this._delayedCaptivePortalDetectedInProgress = true;
|
||||
Services.obs.addObserver(this, "xul-window-visible");
|
||||
window.addEventListener("activate", this, { once: true });
|
||||
Services.obs.addObserver(this, "delayed-captive-portal-handled");
|
||||
}
|
||||
|
||||
this._showNotification();
|
||||
@ -141,24 +137,14 @@ var CaptivePortalWatcher = {
|
||||
return;
|
||||
}
|
||||
|
||||
let win = BrowserWindowTracker.getTopWindow();
|
||||
// Used by tests: ignore the main test window in order to enable testing of
|
||||
// the case where we have no open windows.
|
||||
if (win && win.document.documentElement.getAttribute("ignorecaptiveportal")) {
|
||||
win = null;
|
||||
}
|
||||
|
||||
if (win != Services.ww.activeWindow) {
|
||||
// The window that got focused was not a browser window.
|
||||
if (window.document.documentElement.getAttribute("ignorecaptiveportal")) {
|
||||
return;
|
||||
}
|
||||
Services.obs.removeObserver(this, "xul-window-visible");
|
||||
this._delayedCaptivePortalDetectedInProgress = false;
|
||||
|
||||
if (win != window) {
|
||||
// Some other browser window got focus, we don't have to do anything.
|
||||
return;
|
||||
}
|
||||
Services.obs.notifyObservers(null, "delayed-captive-portal-handled");
|
||||
|
||||
// Trigger a portal recheck. The user may have logged into the portal via
|
||||
// another client, or changed networks.
|
||||
cps.recheckCaptivePortal();
|
||||
@ -185,31 +171,42 @@ var CaptivePortalWatcher = {
|
||||
},
|
||||
|
||||
_captivePortalGone() {
|
||||
if (this._delayedCaptivePortalDetectedInProgress) {
|
||||
Services.obs.removeObserver(this, "xul-window-visible");
|
||||
this._delayedCaptivePortalDetectedInProgress = false;
|
||||
}
|
||||
|
||||
this._cancelDelayedCaptivePortal();
|
||||
this._removeNotification();
|
||||
},
|
||||
|
||||
_cancelDelayedCaptivePortal() {
|
||||
if (this._delayedCaptivePortalDetectedInProgress) {
|
||||
this._delayedCaptivePortalDetectedInProgress = false;
|
||||
Services.obs.removeObserver(this, "delayed-captive-portal-handled");
|
||||
window.removeEventListener("activate", this);
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent(aEvent) {
|
||||
if (aEvent.type != "TabSelect" || !this._captivePortalTab || !this._captivePortalNotification) {
|
||||
return;
|
||||
}
|
||||
switch (aEvent.type) {
|
||||
case "activate":
|
||||
this._delayedCaptivePortalDetected();
|
||||
break;
|
||||
case "TabSelect":
|
||||
if (!this._captivePortalTab || !this._captivePortalNotification) {
|
||||
break;
|
||||
}
|
||||
|
||||
let tab = this._captivePortalTab.get();
|
||||
let n = this._captivePortalNotification;
|
||||
if (!tab || !n) {
|
||||
return;
|
||||
}
|
||||
let tab = this._captivePortalTab.get();
|
||||
let n = this._captivePortalNotification;
|
||||
if (!tab || !n) {
|
||||
break;
|
||||
}
|
||||
|
||||
let doc = tab.ownerDocument;
|
||||
let button = n.querySelector("button.notification-button");
|
||||
if (doc.defaultView.gBrowser.selectedTab == tab) {
|
||||
button.style.visibility = "hidden";
|
||||
} else {
|
||||
button.style.visibility = "visible";
|
||||
let doc = tab.ownerDocument;
|
||||
let button = n.querySelector("button.notification-button");
|
||||
if (doc.defaultView.gBrowser.selectedTab == tab) {
|
||||
button.style.visibility = "hidden";
|
||||
} else {
|
||||
button.style.visibility = "visible";
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1559,6 +1559,8 @@ var gBrowserInit = {
|
||||
}
|
||||
});
|
||||
|
||||
CaptivePortalWatcher.delayedStartup();
|
||||
|
||||
this.delayedStartupFinished = true;
|
||||
|
||||
_resolveDelayedStartup();
|
||||
|
@ -24,7 +24,7 @@ let testCasesForBothSuccessAndAbort = [
|
||||
await freePortal(aSuccess);
|
||||
ensureNoPortalTab(win);
|
||||
ensureNoPortalNotification(win);
|
||||
await closeWindowAndWaitForXulWindowVisible(win);
|
||||
await closeWindowAndWaitForWindowActivate(win);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -57,7 +57,7 @@ let testCasesForBothSuccessAndAbort = [
|
||||
ensureNoPortalTab(win2);
|
||||
ensureNoPortalNotification(win2);
|
||||
|
||||
await closeWindowAndWaitForXulWindowVisible(win2);
|
||||
await closeWindowAndWaitForWindowActivate(win2);
|
||||
// No need to wait for xul-window-visible: after win2 is closed, focus
|
||||
// is restored to the default window and win1 remains in the background.
|
||||
await BrowserTestUtils.closeWindow(win1);
|
||||
@ -77,7 +77,7 @@ let testCasesForBothSuccessAndAbort = [
|
||||
await freePortal(aSuccess);
|
||||
ensureNoPortalTab(win);
|
||||
ensureNoPortalNotification(win);
|
||||
await closeWindowAndWaitForXulWindowVisible(win);
|
||||
await closeWindowAndWaitForWindowActivate(win);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -95,7 +95,7 @@ let testCasesForBothSuccessAndAbort = [
|
||||
});
|
||||
ensureNoPortalTab(win);
|
||||
ensureNoPortalNotification(win);
|
||||
await closeWindowAndWaitForXulWindowVisible(win);
|
||||
await closeWindowAndWaitForWindowActivate(win);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -113,8 +113,8 @@ let testCasesForBothSuccessAndAbort = [
|
||||
await freePortal(aSuccess);
|
||||
ensureNoPortalNotification(win1);
|
||||
ensureNoPortalNotification(win2);
|
||||
await closeWindowAndWaitForXulWindowVisible(win2);
|
||||
await closeWindowAndWaitForXulWindowVisible(win1);
|
||||
await closeWindowAndWaitForWindowActivate(win2);
|
||||
await closeWindowAndWaitForWindowActivate(win1);
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -21,7 +21,7 @@ let testcases = [
|
||||
await freePortal(true);
|
||||
ensurePortalTab(win);
|
||||
ensureNoPortalNotification(win);
|
||||
await closeWindowAndWaitForXulWindowVisible(win);
|
||||
await closeWindowAndWaitForWindowActivate(win);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -82,7 +82,7 @@ let testcases = [
|
||||
await freePortal(true);
|
||||
ensureNoPortalTab(win);
|
||||
ensureNoPortalNotification(win);
|
||||
await closeWindowAndWaitForXulWindowVisible(win);
|
||||
await closeWindowAndWaitForWindowActivate(win);
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -60,7 +60,9 @@ async function focusWindowAndWaitForPortalUI(aLongRecheck, win) {
|
||||
if (!win) {
|
||||
win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
}
|
||||
await SimpleTest.promiseFocus(win);
|
||||
let windowActivePromise = waitForBrowserWindowActive(win);
|
||||
win.focus();
|
||||
await windowActivePromise;
|
||||
|
||||
// After a new window is opened, CaptivePortalWatcher asks for a recheck, and
|
||||
// waits for it to complete. We need to manually tell it a recheck completed.
|
||||
@ -128,26 +130,35 @@ function ensureNoPortalNotification(win) {
|
||||
|
||||
/**
|
||||
* Some tests open a new window and close it later. When the window is closed,
|
||||
* the original window opened by mochitest gains focus, generating a
|
||||
* xul-window-visible notification. If the next test also opens a new window
|
||||
* before this notification has a chance to fire, CaptivePortalWatcher picks
|
||||
* the original window opened by mochitest gains focus, generating an
|
||||
* activate event. If the next test also opens a new window
|
||||
* before this event has a chance to fire, CaptivePortalWatcher picks
|
||||
* up the first one instead of the one from the new window. To avoid this
|
||||
* unfortunate intermittent timing issue, we wait for the notification from
|
||||
* unfortunate intermittent timing issue, we wait for the event from
|
||||
* the original window every time we close a window that we opened.
|
||||
*/
|
||||
function waitForXulWindowVisible() {
|
||||
function waitForBrowserWindowActive(win) {
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function observe() {
|
||||
Services.obs.removeObserver(observe, "xul-window-visible");
|
||||
if (Services.focus.activeWindow == win) {
|
||||
resolve();
|
||||
}, "xul-window-visible");
|
||||
} else {
|
||||
win.addEventListener("activate", () => {
|
||||
resolve();
|
||||
}, { once: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function closeWindowAndWaitForXulWindowVisible(win) {
|
||||
let p = waitForXulWindowVisible();
|
||||
async function closeWindowAndWaitForWindowActivate(win) {
|
||||
let activationPromises = [];
|
||||
for (let w of BrowserWindowTracker.orderedWindows) {
|
||||
if (w != win &&
|
||||
!win.document.documentElement.getAttribute("ignorecaptiveportal")) {
|
||||
activationPromises.push(waitForBrowserWindowActive(win));
|
||||
}
|
||||
}
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
await p;
|
||||
await Promise.race(activationPromises);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,6 +168,6 @@ async function closeWindowAndWaitForXulWindowVisible(win) {
|
||||
*/
|
||||
async function openWindowAndWaitForFocus() {
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await SimpleTest.promiseFocus(win);
|
||||
await waitForBrowserWindowActive(win);
|
||||
return win;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ skip-if = os != "win" # Windows-specific handler application selection dialog
|
||||
[browser_connection_bug1445991.js]
|
||||
skip-if = (verify && debug && (os == 'linux' || os == 'mac'))
|
||||
[browser_connection_dnsoverhttps.js]
|
||||
skip-if = ccov # Skipping test on all ccov platforms
|
||||
[browser_contentblocking.js]
|
||||
[browser_cookies_exceptions.js]
|
||||
[browser_defaultbrowser_alwayscheck.js]
|
||||
|
@ -66,7 +66,7 @@ add_task(async function test_windows_are_restored_in_reversed_z_order() {
|
||||
await promiseBrowserState(gBrowserState);
|
||||
|
||||
let indexedTabLabels = [...gTestURLsMap.values()];
|
||||
let tabsRestoredLabels = [...BrowserWindowTracker.orderedWindows].map(window => window.gBrowser.selectedTab.label);
|
||||
let tabsRestoredLabels = BrowserWindowTracker.orderedWindows.map(window => window.gBrowser.selectedTab.label);
|
||||
|
||||
Assert.equal(tabsRestoredLabels[0], indexedTabLabels[2], "First restored tab should be last used tab");
|
||||
Assert.equal(tabsRestoredLabels[1], indexedTabLabels[1], "Second restored tab is correct");
|
||||
|
@ -1,5 +1,5 @@
|
||||
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 2.0.815
|
||||
Current extension version is: 2.0.843
|
||||
|
||||
Taken from upstream commit: d6927376
|
||||
Taken from upstream commit: bf368f3a
|
||||
|
@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '2.0.815';
|
||||
var pdfjsBuild = 'd6927376';
|
||||
var pdfjsVersion = '2.0.843';
|
||||
var pdfjsBuild = 'bf368f3a';
|
||||
var pdfjsSharedUtil = __w_pdfjs_require__(1);
|
||||
var pdfjsDisplayAPI = __w_pdfjs_require__(7);
|
||||
var pdfjsDisplayTextLayer = __w_pdfjs_require__(19);
|
||||
@ -4226,7 +4226,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
||||
}
|
||||
return worker.messageHandler.sendWithPromise('GetDocRequest', {
|
||||
docId,
|
||||
apiVersion: '2.0.815',
|
||||
apiVersion: '2.0.843',
|
||||
source: {
|
||||
data: source.data,
|
||||
url: source.url,
|
||||
@ -5553,8 +5553,8 @@ var InternalRenderTask = function InternalRenderTaskClosure() {
|
||||
}();
|
||||
var version, build;
|
||||
{
|
||||
exports.version = version = '2.0.815';
|
||||
exports.build = build = 'd6927376';
|
||||
exports.version = version = '2.0.843';
|
||||
exports.build = build = 'bf368f3a';
|
||||
}
|
||||
exports.getDocument = getDocument;
|
||||
exports.LoopbackPort = LoopbackPort;
|
||||
@ -6354,7 +6354,7 @@ var CanvasGraphics = function CanvasGraphicsClosure() {
|
||||
if (canvasCtx) {
|
||||
addContextCurrentTransform(canvasCtx);
|
||||
}
|
||||
this.cachedGetSinglePixelWidth = null;
|
||||
this._cachedGetSinglePixelWidth = null;
|
||||
}
|
||||
function putBinaryImageData(ctx, imgData) {
|
||||
if (typeof ImageData !== 'undefined' && imgData instanceof ImageData) {
|
||||
@ -6829,12 +6829,12 @@ var CanvasGraphics = function CanvasGraphicsClosure() {
|
||||
this.current = this.stateStack.pop();
|
||||
this.ctx.restore();
|
||||
this.pendingClip = null;
|
||||
this.cachedGetSinglePixelWidth = null;
|
||||
this._cachedGetSinglePixelWidth = null;
|
||||
}
|
||||
},
|
||||
transform: function CanvasGraphics_transform(a, b, c, d, e, f) {
|
||||
this.ctx.transform(a, b, c, d, e, f);
|
||||
this.cachedGetSinglePixelWidth = null;
|
||||
this._cachedGetSinglePixelWidth = null;
|
||||
},
|
||||
constructPath: function CanvasGraphics_constructPath(ops, args) {
|
||||
var ctx = this.ctx;
|
||||
@ -7177,7 +7177,7 @@ var CanvasGraphics = function CanvasGraphicsClosure() {
|
||||
if (scale === 0 || lineWidth === 0) {
|
||||
var fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK;
|
||||
if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {
|
||||
this.cachedGetSinglePixelWidth = null;
|
||||
this._cachedGetSinglePixelWidth = null;
|
||||
lineWidth = this.getSinglePixelWidth() * MIN_WIDTH_FACTOR;
|
||||
}
|
||||
} else {
|
||||
@ -7269,7 +7269,7 @@ var CanvasGraphics = function CanvasGraphicsClosure() {
|
||||
if (isTextInvisible || fontSize === 0) {
|
||||
return;
|
||||
}
|
||||
this.cachedGetSinglePixelWidth = null;
|
||||
this._cachedGetSinglePixelWidth = null;
|
||||
ctx.save();
|
||||
ctx.transform.apply(ctx, current.textMatrix);
|
||||
ctx.translate(current.x, current.y);
|
||||
@ -7737,14 +7737,12 @@ var CanvasGraphics = function CanvasGraphicsClosure() {
|
||||
}
|
||||
ctx.beginPath();
|
||||
},
|
||||
getSinglePixelWidth: function CanvasGraphics_getSinglePixelWidth(scale) {
|
||||
if (this.cachedGetSinglePixelWidth === null) {
|
||||
this.ctx.save();
|
||||
var inverse = this.ctx.mozCurrentTransformInverse;
|
||||
this.ctx.restore();
|
||||
this.cachedGetSinglePixelWidth = Math.sqrt(Math.max(inverse[0] * inverse[0] + inverse[1] * inverse[1], inverse[2] * inverse[2] + inverse[3] * inverse[3]));
|
||||
getSinglePixelWidth(scale) {
|
||||
if (this._cachedGetSinglePixelWidth === null) {
|
||||
const inverse = this.ctx.mozCurrentTransformInverse;
|
||||
this._cachedGetSinglePixelWidth = Math.sqrt(Math.max(inverse[0] * inverse[0] + inverse[1] * inverse[1], inverse[2] * inverse[2] + inverse[3] * inverse[3]));
|
||||
}
|
||||
return this.cachedGetSinglePixelWidth;
|
||||
return this._cachedGetSinglePixelWidth;
|
||||
},
|
||||
getCanvasPosition: function CanvasGraphics_getCanvasPosition(x, y) {
|
||||
var transform = this.ctx.mozCurrentTransform;
|
||||
@ -10015,8 +10013,8 @@ var renderTextLayer = function renderTextLayerClosure() {
|
||||
let fontFamily = textDiv.style.fontFamily;
|
||||
if (fontSize !== this._layoutTextLastFontSize || fontFamily !== this._layoutTextLastFontFamily) {
|
||||
this._layoutTextCtx.font = fontSize + ' ' + fontFamily;
|
||||
this._lastFontSize = fontSize;
|
||||
this._lastFontFamily = fontFamily;
|
||||
this._layoutTextLastFontSize = fontSize;
|
||||
this._layoutTextLastFontFamily = fontFamily;
|
||||
}
|
||||
let width = this._layoutTextCtx.measureText(textDiv.textContent).width;
|
||||
let transform = '';
|
||||
|
284
browser/extensions/pdfjs/content/build/pdf.worker.js
vendored
284
browser/extensions/pdfjs/content/build/pdf.worker.js
vendored
@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '2.0.815';
|
||||
var pdfjsBuild = 'd6927376';
|
||||
var pdfjsVersion = '2.0.843';
|
||||
var pdfjsBuild = 'bf368f3a';
|
||||
var pdfjsCoreWorker = __w_pdfjs_require__(1);
|
||||
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||
|
||||
@ -327,7 +327,7 @@ var WorkerMessageHandler = {
|
||||
var cancelXHRs = null;
|
||||
var WorkerTasks = [];
|
||||
let apiVersion = docParams.apiVersion;
|
||||
let workerVersion = '2.0.815';
|
||||
let workerVersion = '2.0.843';
|
||||
if (apiVersion !== workerVersion) {
|
||||
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
|
||||
}
|
||||
@ -22285,7 +22285,7 @@ exports.CMapFactory = CMapFactory;
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.getFontType = exports.ProblematicCharRanges = exports.IdentityToUnicodeMap = exports.ToUnicodeMap = exports.FontFlags = exports.Font = exports.ErrorFont = exports.PRIVATE_USE_OFFSET_END = exports.PRIVATE_USE_OFFSET_START = exports.SEAC_ANALYSIS_ENABLED = undefined;
|
||||
exports.getFontType = exports.IdentityToUnicodeMap = exports.ToUnicodeMap = exports.FontFlags = exports.Font = exports.ErrorFont = exports.SEAC_ANALYSIS_ENABLED = undefined;
|
||||
|
||||
var _util = __w_pdfjs_require__(2);
|
||||
|
||||
@ -22307,11 +22307,9 @@ var _stream = __w_pdfjs_require__(14);
|
||||
|
||||
var _type1_parser = __w_pdfjs_require__(38);
|
||||
|
||||
var PRIVATE_USE_OFFSET_START = 0xE000;
|
||||
var PRIVATE_USE_OFFSET_END = 0xF8FF;
|
||||
var SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = false;
|
||||
const PRIVATE_USE_AREAS = [[0xE000, 0xF8FF], [0x100000, 0x10FFFD]];
|
||||
var PDF_GLYPH_SPACE_UNITS = 1000;
|
||||
var SEAC_ANALYSIS_ENABLED = false;
|
||||
var SEAC_ANALYSIS_ENABLED = true;
|
||||
var FontFlags = {
|
||||
FixedPitch: 1,
|
||||
Serif: 2,
|
||||
@ -22590,7 +22588,6 @@ var OpenTypeFileBuilder = function OpenTypeFileBuilderClosure() {
|
||||
};
|
||||
return OpenTypeFileBuilder;
|
||||
}();
|
||||
var ProblematicCharRanges = new Int32Array([0x0000, 0x0020, 0x007F, 0x00A1, 0x00AD, 0x00AE, 0x0600, 0x0780, 0x08A0, 0x10A0, 0x1780, 0x1800, 0x1C00, 0x1C50, 0x2000, 0x2010, 0x2011, 0x2012, 0x2028, 0x2030, 0x205F, 0x2070, 0x25CC, 0x25CD, 0x3000, 0x3001, 0x3164, 0x3165, 0xAA60, 0xAA80, 0xD800, 0xE000, 0xFFF0, 0x10000]);
|
||||
var Font = function FontClosure() {
|
||||
function Font(name, file, properties) {
|
||||
var charCode;
|
||||
@ -22794,58 +22791,33 @@ var Font = function FontClosure() {
|
||||
}
|
||||
return toFontChar;
|
||||
}
|
||||
function isProblematicUnicodeLocation(code) {
|
||||
var i = 0,
|
||||
j = ProblematicCharRanges.length - 1;
|
||||
while (i < j) {
|
||||
var c = i + j + 1 >> 1;
|
||||
if (code < ProblematicCharRanges[c]) {
|
||||
j = c - 1;
|
||||
} else {
|
||||
i = c;
|
||||
}
|
||||
}
|
||||
return !(i & 1);
|
||||
}
|
||||
function adjustMapping(charCodeToGlyphId, properties, missingGlyphs) {
|
||||
var toUnicode = properties.toUnicode;
|
||||
var isSymbolic = !!(properties.flags & FontFlags.Symbolic);
|
||||
var isIdentityUnicode = properties.toUnicode instanceof IdentityToUnicodeMap;
|
||||
function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId) {
|
||||
var newMap = Object.create(null);
|
||||
var toFontChar = [];
|
||||
var usedFontCharCodes = [];
|
||||
var nextAvailableFontCharCode = PRIVATE_USE_OFFSET_START;
|
||||
var privateUseAreaIndex = 0;
|
||||
var nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0];
|
||||
var privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];
|
||||
for (var originalCharCode in charCodeToGlyphId) {
|
||||
originalCharCode |= 0;
|
||||
var glyphId = charCodeToGlyphId[originalCharCode];
|
||||
if (missingGlyphs[glyphId]) {
|
||||
if (!hasGlyph(glyphId)) {
|
||||
continue;
|
||||
}
|
||||
var fontCharCode = originalCharCode;
|
||||
var hasUnicodeValue = false;
|
||||
if (!isIdentityUnicode && toUnicode.has(originalCharCode)) {
|
||||
hasUnicodeValue = true;
|
||||
var unicode = toUnicode.get(fontCharCode);
|
||||
if (unicode.length === 1) {
|
||||
fontCharCode = unicode.charCodeAt(0);
|
||||
if (nextAvailableFontCharCode > privateUseOffetEnd) {
|
||||
privateUseAreaIndex++;
|
||||
if (privateUseAreaIndex >= PRIVATE_USE_AREAS.length) {
|
||||
(0, _util.warn)('Ran out of space in font private use area.');
|
||||
break;
|
||||
}
|
||||
nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0];
|
||||
privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];
|
||||
}
|
||||
if (usedFontCharCodes[fontCharCode] !== undefined || isProblematicUnicodeLocation(fontCharCode) || isSymbolic && !hasUnicodeValue) {
|
||||
do {
|
||||
if (nextAvailableFontCharCode > PRIVATE_USE_OFFSET_END) {
|
||||
(0, _util.warn)('Ran out of space in font private use area.');
|
||||
break;
|
||||
}
|
||||
fontCharCode = nextAvailableFontCharCode++;
|
||||
if (SKIP_PRIVATE_USE_RANGE_F000_TO_F01F && fontCharCode === 0xF000) {
|
||||
fontCharCode = 0xF020;
|
||||
nextAvailableFontCharCode = fontCharCode + 1;
|
||||
}
|
||||
} while (usedFontCharCodes[fontCharCode] !== undefined);
|
||||
var fontCharCode = nextAvailableFontCharCode++;
|
||||
if (glyphId === 0) {
|
||||
glyphId = newGlyphZeroId;
|
||||
}
|
||||
newMap[fontCharCode] = glyphId;
|
||||
toFontChar[originalCharCode] = fontCharCode;
|
||||
usedFontCharCodes[fontCharCode] = true;
|
||||
}
|
||||
return {
|
||||
toFontChar,
|
||||
@ -23032,6 +23004,9 @@ var Font = function FontClosure() {
|
||||
throw new _util.FormatError('Unicode ranges Bits > 123 are reserved for internal usage');
|
||||
}
|
||||
}
|
||||
if (lastCharIndex > 0xFFFF) {
|
||||
lastCharIndex = 0xFFFF;
|
||||
}
|
||||
} else {
|
||||
firstCharIndex = 0;
|
||||
lastCharIndex = 255;
|
||||
@ -23585,13 +23560,12 @@ var Font = function FontClosure() {
|
||||
data[offset + 1] = value >> 1 & 0xFF;
|
||||
};
|
||||
}
|
||||
var numGlyphsOut = dupFirstEntry ? numGlyphs + 1 : numGlyphs;
|
||||
var locaData = loca.data;
|
||||
var locaDataSize = itemSize * (1 + numGlyphs);
|
||||
if (locaData.length !== locaDataSize) {
|
||||
locaData = new Uint8Array(locaDataSize);
|
||||
locaData.set(loca.data.subarray(0, locaDataSize));
|
||||
loca.data = locaData;
|
||||
}
|
||||
var locaDataSize = itemSize * (1 + numGlyphsOut);
|
||||
locaData = new Uint8Array(locaDataSize);
|
||||
locaData.set(loca.data.subarray(0, locaDataSize));
|
||||
loca.data = locaData;
|
||||
var oldGlyfData = glyf.data;
|
||||
var oldGlyfDataLength = oldGlyfData.length;
|
||||
var newGlyfData = new Uint8Array(oldGlyfDataLength);
|
||||
@ -23600,8 +23574,7 @@ var Font = function FontClosure() {
|
||||
var missingGlyphs = Object.create(null);
|
||||
itemEncode(locaData, 0, writeOffset);
|
||||
var i, j;
|
||||
var locaCount = dupFirstEntry ? numGlyphs - 1 : numGlyphs;
|
||||
for (i = 0, j = itemSize; i < locaCount; i++, j += itemSize) {
|
||||
for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
|
||||
var endOffset = itemDecode(locaData, j);
|
||||
if (endOffset === 0) {
|
||||
endOffset = startOffset;
|
||||
@ -23626,7 +23599,7 @@ var Font = function FontClosure() {
|
||||
}
|
||||
if (writeOffset === 0) {
|
||||
var simpleGlyph = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]);
|
||||
for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
|
||||
for (i = 0, j = itemSize; i < numGlyphsOut; i++, j += itemSize) {
|
||||
itemEncode(locaData, j, simpleGlyph.length);
|
||||
}
|
||||
glyf.data = simpleGlyph;
|
||||
@ -24045,7 +24018,14 @@ var Font = function FontClosure() {
|
||||
}
|
||||
font.pos = (font.start || 0) + tables['maxp'].offset;
|
||||
var version = font.getInt32();
|
||||
var numGlyphs = font.getUint16();
|
||||
const numGlyphs = font.getUint16();
|
||||
let numGlyphsOut = numGlyphs + 1;
|
||||
let dupFirstEntry = true;
|
||||
if (numGlyphsOut > 0xFFFF) {
|
||||
dupFirstEntry = false;
|
||||
numGlyphsOut = numGlyphs;
|
||||
(0, _util.warn)('Not enough space in glyfs to duplicate first glyph.');
|
||||
}
|
||||
var maxFunctionDefs = 0;
|
||||
var maxSizeOfInstructions = 0;
|
||||
if (version >= 0x00010000 && tables['maxp'].length >= 22) {
|
||||
@ -24060,20 +24040,15 @@ var Font = function FontClosure() {
|
||||
font.pos += 4;
|
||||
maxSizeOfInstructions = font.getUint16();
|
||||
}
|
||||
var dupFirstEntry = false;
|
||||
if (properties.type === 'CIDFontType2' && properties.toUnicode && properties.toUnicode.get(0) > '\u0000') {
|
||||
dupFirstEntry = true;
|
||||
numGlyphs++;
|
||||
tables['maxp'].data[4] = numGlyphs >> 8;
|
||||
tables['maxp'].data[5] = numGlyphs & 255;
|
||||
}
|
||||
tables['maxp'].data[4] = numGlyphsOut >> 8;
|
||||
tables['maxp'].data[5] = numGlyphsOut & 255;
|
||||
var hintsValid = sanitizeTTPrograms(tables['fpgm'], tables['prep'], tables['cvt '], maxFunctionDefs);
|
||||
if (!hintsValid) {
|
||||
delete tables['fpgm'];
|
||||
delete tables['prep'];
|
||||
delete tables['cvt '];
|
||||
}
|
||||
sanitizeMetrics(font, tables['hhea'], tables['hmtx'], numGlyphs);
|
||||
sanitizeMetrics(font, tables['hhea'], tables['hmtx'], numGlyphsOut);
|
||||
if (!tables['head']) {
|
||||
throw new _util.FormatError('Required "head" table is not found');
|
||||
}
|
||||
@ -24105,11 +24080,12 @@ var Font = function FontClosure() {
|
||||
this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm;
|
||||
this.descent = metricsOverride.descent / metricsOverride.unitsPerEm;
|
||||
if (tables['post']) {
|
||||
var valid = readPostScriptTable(tables['post'], properties, numGlyphs);
|
||||
if (!valid) {
|
||||
tables['post'] = null;
|
||||
}
|
||||
readPostScriptTable(tables['post'], properties, numGlyphs);
|
||||
}
|
||||
tables['post'] = {
|
||||
tag: 'post',
|
||||
data: createPostTable(properties)
|
||||
};
|
||||
var charCodeToGlyphId = [],
|
||||
charCode;
|
||||
function hasGlyph(glyphId) {
|
||||
@ -24132,9 +24108,6 @@ var Font = function FontClosure() {
|
||||
charCodeToGlyphId[charCode] = glyphId;
|
||||
}
|
||||
});
|
||||
if (dupFirstEntry && (isCidToGidMapEmpty || !charCodeToGlyphId[0])) {
|
||||
charCodeToGlyphId[0] = numGlyphs - 1;
|
||||
}
|
||||
} else {
|
||||
var cmapTable = readCmapTable(tables['cmap'], font, this.isSymbolicFont, properties.hasEncoding);
|
||||
var cmapPlatformId = cmapTable.platformId;
|
||||
@ -24202,11 +24175,15 @@ var Font = function FontClosure() {
|
||||
if (charCodeToGlyphId.length === 0) {
|
||||
charCodeToGlyphId[0] = 0;
|
||||
}
|
||||
var newMapping = adjustMapping(charCodeToGlyphId, properties, missingGlyphs);
|
||||
let glyphZeroId = numGlyphsOut - 1;
|
||||
if (!dupFirstEntry) {
|
||||
glyphZeroId = 0;
|
||||
}
|
||||
var newMapping = adjustMapping(charCodeToGlyphId, hasGlyph, glyphZeroId);
|
||||
this.toFontChar = newMapping.toFontChar;
|
||||
tables['cmap'] = {
|
||||
tag: 'cmap',
|
||||
data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphs)
|
||||
data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphsOut)
|
||||
};
|
||||
if (!tables['OS/2'] || !validateOS2Table(tables['OS/2'])) {
|
||||
tables['OS/2'] = {
|
||||
@ -24214,17 +24191,12 @@ var Font = function FontClosure() {
|
||||
data: createOS2Table(properties, newMapping.charCodeToGlyphId, metricsOverride)
|
||||
};
|
||||
}
|
||||
if (!tables['post']) {
|
||||
tables['post'] = {
|
||||
tag: 'post',
|
||||
data: createPostTable(properties)
|
||||
};
|
||||
}
|
||||
if (!isTrueType) {
|
||||
try {
|
||||
cffFile = new _stream.Stream(tables['CFF '].data);
|
||||
var parser = new _cff_parser.CFFParser(cffFile, properties, SEAC_ANALYSIS_ENABLED);
|
||||
cff = parser.parse();
|
||||
cff.duplicateFirstGlyph();
|
||||
var compiler = new _cff_parser.CFFCompiler(cff);
|
||||
tables['CFF '].data = compiler.compile();
|
||||
} catch (e) {
|
||||
@ -24251,8 +24223,12 @@ var Font = function FontClosure() {
|
||||
if (properties.builtInEncoding) {
|
||||
adjustToUnicode(properties, properties.builtInEncoding);
|
||||
}
|
||||
let glyphZeroId = 1;
|
||||
if (font instanceof CFFFont) {
|
||||
glyphZeroId = font.numGlyphs - 1;
|
||||
}
|
||||
var mapping = font.getGlyphMapping(properties);
|
||||
var newMapping = adjustMapping(mapping, properties, Object.create(null));
|
||||
var newMapping = adjustMapping(mapping, font.hasGlyphId.bind(font), glyphZeroId);
|
||||
this.toFontChar = newMapping.toFontChar;
|
||||
var numGlyphs = font.numGlyphs;
|
||||
function getCharCodes(charCodeToGlyphId, glyphId) {
|
||||
@ -24403,11 +24379,11 @@ var Font = function FontClosure() {
|
||||
var seac = this.seacMap[charcode];
|
||||
fontCharCode = seac.baseFontCharCode;
|
||||
accent = {
|
||||
fontChar: String.fromCharCode(seac.accentFontCharCode),
|
||||
fontChar: String.fromCodePoint(seac.accentFontCharCode),
|
||||
offset: seac.accentOffset
|
||||
};
|
||||
}
|
||||
var fontChar = String.fromCharCode(fontCharCode);
|
||||
var fontChar = typeof fontCharCode === 'number' ? String.fromCodePoint(fontCharCode) : '';
|
||||
var glyph = this.glyphCache[charcode];
|
||||
if (!glyph || !glyph.matchesForCache(fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont)) {
|
||||
glyph = new Glyph(fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont);
|
||||
@ -24669,6 +24645,16 @@ var Type1Font = function Type1FontClosure() {
|
||||
}
|
||||
return type1FontGlyphMapping(properties, builtInEncoding, glyphNames);
|
||||
},
|
||||
hasGlyphId: function Type1Font_hasGlyphID(id) {
|
||||
if (id < 0 || id >= this.numGlyphs) {
|
||||
return false;
|
||||
}
|
||||
if (id === 0) {
|
||||
return true;
|
||||
}
|
||||
var glyph = this.charstrings[id - 1];
|
||||
return glyph.charstring.length > 0;
|
||||
},
|
||||
getSeacs: function Type1Font_getSeacs(charstrings) {
|
||||
var i, ii;
|
||||
var seacMap = [];
|
||||
@ -24746,12 +24732,7 @@ var Type1Font = function Type1FontClosure() {
|
||||
var charStringsIndex = new _cff_parser.CFFIndex();
|
||||
charStringsIndex.add([0x8B, 0x0E]);
|
||||
for (i = 0; i < count; i++) {
|
||||
var glyph = glyphs[i];
|
||||
if (glyph.length === 0) {
|
||||
charStringsIndex.add([0x8B, 0x0E]);
|
||||
continue;
|
||||
}
|
||||
charStringsIndex.add(glyph);
|
||||
charStringsIndex.add(glyphs[i]);
|
||||
}
|
||||
cff.charStrings = charStringsIndex;
|
||||
var privateDict = new _cff_parser.CFFPrivateDict();
|
||||
@ -24787,6 +24768,7 @@ var CFFFont = function CFFFontClosure() {
|
||||
this.properties = properties;
|
||||
var parser = new _cff_parser.CFFParser(file, properties, SEAC_ANALYSIS_ENABLED);
|
||||
this.cff = parser.parse();
|
||||
this.cff.duplicateFirstGlyph();
|
||||
var compiler = new _cff_parser.CFFCompiler(this.cff);
|
||||
this.seacs = this.cff.seacs;
|
||||
try {
|
||||
@ -24827,29 +24809,19 @@ var CFFFont = function CFFFontClosure() {
|
||||
var encoding = cff.encoding ? cff.encoding.encoding : null;
|
||||
charCodeToGlyphId = type1FontGlyphMapping(properties, encoding, charsets);
|
||||
return charCodeToGlyphId;
|
||||
},
|
||||
hasGlyphId: function CFFFont_hasGlyphID(id) {
|
||||
return this.cff.hasGlyphId(id);
|
||||
}
|
||||
};
|
||||
return CFFFont;
|
||||
}();
|
||||
(function checkSeacSupport() {
|
||||
if (typeof navigator !== 'undefined' && /Windows/.test(navigator.userAgent)) {
|
||||
exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED = true;
|
||||
}
|
||||
})();
|
||||
(function checkChromeWindows() {
|
||||
if (typeof navigator !== 'undefined' && /Windows.*Chrome/.test(navigator.userAgent)) {
|
||||
SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = true;
|
||||
}
|
||||
})();
|
||||
exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED;
|
||||
exports.PRIVATE_USE_OFFSET_START = PRIVATE_USE_OFFSET_START;
|
||||
exports.PRIVATE_USE_OFFSET_END = PRIVATE_USE_OFFSET_END;
|
||||
exports.ErrorFont = ErrorFont;
|
||||
exports.Font = Font;
|
||||
exports.FontFlags = FontFlags;
|
||||
exports.ToUnicodeMap = ToUnicodeMap;
|
||||
exports.IdentityToUnicodeMap = IdentityToUnicodeMap;
|
||||
exports.ProblematicCharRanges = ProblematicCharRanges;
|
||||
exports.getFontType = getFontType;
|
||||
|
||||
/***/ }),
|
||||
@ -24862,7 +24834,7 @@ exports.getFontType = getFontType;
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.CFFCompiler = exports.CFFPrivateDict = exports.CFFTopDict = exports.CFFCharset = exports.CFFIndex = exports.CFFStrings = exports.CFFHeader = exports.CFF = exports.CFFParser = exports.CFFStandardStrings = undefined;
|
||||
exports.CFFFDSelect = exports.CFFCompiler = exports.CFFPrivateDict = exports.CFFTopDict = exports.CFFCharset = exports.CFFIndex = exports.CFFStrings = exports.CFFHeader = exports.CFF = exports.CFFParser = exports.CFFStandardStrings = undefined;
|
||||
|
||||
var _util = __w_pdfjs_require__(2);
|
||||
|
||||
@ -25626,20 +25598,16 @@ var CFFParser = function CFFParserClosure() {
|
||||
return new CFFEncoding(predefined, format, encoding, raw);
|
||||
},
|
||||
parseFDSelect: function CFFParser_parseFDSelect(pos, length) {
|
||||
var start = pos;
|
||||
var bytes = this.bytes;
|
||||
var format = bytes[pos++];
|
||||
var fdSelect = [],
|
||||
rawBytes;
|
||||
var i,
|
||||
invalidFirstGID = false;
|
||||
var fdSelect = [];
|
||||
var i;
|
||||
switch (format) {
|
||||
case 0:
|
||||
for (i = 0; i < length; ++i) {
|
||||
var id = bytes[pos++];
|
||||
fdSelect.push(id);
|
||||
}
|
||||
rawBytes = bytes.subarray(start, pos);
|
||||
break;
|
||||
case 3:
|
||||
var rangesCount = bytes[pos++] << 8 | bytes[pos++];
|
||||
@ -25647,7 +25615,6 @@ var CFFParser = function CFFParserClosure() {
|
||||
var first = bytes[pos++] << 8 | bytes[pos++];
|
||||
if (i === 0 && first !== 0) {
|
||||
(0, _util.warn)('parseFDSelect: The first range must have a first GID of 0' + ' -- trying to recover.');
|
||||
invalidFirstGID = true;
|
||||
first = 0;
|
||||
}
|
||||
var fdIndex = bytes[pos++];
|
||||
@ -25657,10 +25624,6 @@ var CFFParser = function CFFParserClosure() {
|
||||
}
|
||||
}
|
||||
pos += 2;
|
||||
rawBytes = bytes.subarray(start, pos);
|
||||
if (invalidFirstGID) {
|
||||
rawBytes[3] = rawBytes[4] = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new _util.FormatError(`parseFDSelect: Unknown format "${format}".`);
|
||||
@ -25668,7 +25631,7 @@ var CFFParser = function CFFParserClosure() {
|
||||
if (fdSelect.length !== length) {
|
||||
throw new _util.FormatError('parseFDSelect: Invalid font data.');
|
||||
}
|
||||
return new CFFFDSelect(fdSelect, rawBytes);
|
||||
return new CFFFDSelect(format, fdSelect);
|
||||
}
|
||||
};
|
||||
return CFFParser;
|
||||
@ -25687,6 +25650,26 @@ var CFF = function CFFClosure() {
|
||||
this.fdSelect = null;
|
||||
this.isCIDFont = false;
|
||||
}
|
||||
CFF.prototype = {
|
||||
duplicateFirstGlyph: function CFF_duplicateFirstGlyph() {
|
||||
if (this.charStrings.count >= 65535) {
|
||||
(0, _util.warn)('Not enough space in charstrings to duplicate first glyph.');
|
||||
return;
|
||||
}
|
||||
var glyphZero = this.charStrings.get(0);
|
||||
this.charStrings.add(glyphZero);
|
||||
if (this.isCIDFont) {
|
||||
this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0]);
|
||||
}
|
||||
},
|
||||
hasGlyphId: function CFF_hasGlyphID(id) {
|
||||
if (id < 0 || id >= this.charStrings.count) {
|
||||
return false;
|
||||
}
|
||||
var glyph = this.charStrings.get(id);
|
||||
return glyph.length > 0;
|
||||
}
|
||||
};
|
||||
return CFF;
|
||||
}();
|
||||
var CFFHeader = function CFFHeaderClosure() {
|
||||
@ -25873,9 +25856,9 @@ var CFFEncoding = function CFFEncodingClosure() {
|
||||
return CFFEncoding;
|
||||
}();
|
||||
var CFFFDSelect = function CFFFDSelectClosure() {
|
||||
function CFFFDSelect(fdSelect, raw) {
|
||||
function CFFFDSelect(format, fdSelect) {
|
||||
this.format = format;
|
||||
this.fdSelect = fdSelect;
|
||||
this.raw = raw;
|
||||
}
|
||||
CFFFDSelect.prototype = {
|
||||
getFDIndex: function CFFFDSelect_get(glyphIndex) {
|
||||
@ -25966,6 +25949,7 @@ var CFFCompiler = function CFFCompilerClosure() {
|
||||
}
|
||||
}
|
||||
}
|
||||
cff.topDict.setByName('charset', 0);
|
||||
var compiled = this.compileTopDicts([cff.topDict], output.length, cff.isCIDFont);
|
||||
output.add(compiled.output);
|
||||
var topDictTracker = compiled.trackers[0];
|
||||
@ -25982,21 +25966,15 @@ var CFFCompiler = function CFFCompilerClosure() {
|
||||
output.add(encoding);
|
||||
}
|
||||
}
|
||||
if (cff.charset && cff.topDict.hasName('charset')) {
|
||||
if (cff.charset.predefined) {
|
||||
topDictTracker.setEntryLocation('charset', [cff.charset.format], output);
|
||||
} else {
|
||||
var charset = this.compileCharset(cff.charset);
|
||||
topDictTracker.setEntryLocation('charset', [output.length], output);
|
||||
output.add(charset);
|
||||
}
|
||||
}
|
||||
var charset = this.compileCharset(cff.charset);
|
||||
topDictTracker.setEntryLocation('charset', [output.length], output);
|
||||
output.add(charset);
|
||||
var charStrings = this.compileCharStrings(cff.charStrings);
|
||||
topDictTracker.setEntryLocation('CharStrings', [output.length], output);
|
||||
output.add(charStrings);
|
||||
if (cff.isCIDFont) {
|
||||
topDictTracker.setEntryLocation('FDSelect', [output.length], output);
|
||||
var fdSelect = this.compileFDSelect(cff.fdSelect.raw);
|
||||
var fdSelect = this.compileFDSelect(cff.fdSelect);
|
||||
output.add(fdSelect);
|
||||
compiled = this.compileTopDicts(cff.fdArray, output.length, true);
|
||||
topDictTracker.setEntryLocation('FDArray', [output.length], output);
|
||||
@ -26191,16 +26169,55 @@ var CFFCompiler = function CFFCompilerClosure() {
|
||||
this.out.writeByteArray(this.compileIndex(globalSubrIndex));
|
||||
},
|
||||
compileCharStrings: function CFFCompiler_compileCharStrings(charStrings) {
|
||||
return this.compileIndex(charStrings);
|
||||
var charStringsIndex = new CFFIndex();
|
||||
for (var i = 0; i < charStrings.count; i++) {
|
||||
var glyph = charStrings.get(i);
|
||||
if (glyph.length === 0) {
|
||||
charStringsIndex.add(new Uint8Array([0x8B, 0x0E]));
|
||||
continue;
|
||||
}
|
||||
charStringsIndex.add(glyph);
|
||||
}
|
||||
return this.compileIndex(charStringsIndex);
|
||||
},
|
||||
compileCharset: function CFFCompiler_compileCharset(charset) {
|
||||
return this.compileTypedArray(charset.raw);
|
||||
let length = 1 + (this.cff.charStrings.count - 1) * 2;
|
||||
let out = new Uint8Array(length);
|
||||
return this.compileTypedArray(out);
|
||||
},
|
||||
compileEncoding: function CFFCompiler_compileEncoding(encoding) {
|
||||
return this.compileTypedArray(encoding.raw);
|
||||
},
|
||||
compileFDSelect: function CFFCompiler_compileFDSelect(fdSelect) {
|
||||
return this.compileTypedArray(fdSelect);
|
||||
let format = fdSelect.format;
|
||||
let out, i;
|
||||
switch (format) {
|
||||
case 0:
|
||||
out = new Uint8Array(1 + fdSelect.fdSelect.length);
|
||||
out[0] = format;
|
||||
for (i = 0; i < fdSelect.fdSelect.length; i++) {
|
||||
out[i + 1] = fdSelect.fdSelect[i];
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
let start = 0;
|
||||
let lastFD = fdSelect.fdSelect[0];
|
||||
let ranges = [format, 0, 0, start >> 8 & 0xFF, start & 0xFF, lastFD];
|
||||
for (i = 1; i < fdSelect.fdSelect.length; i++) {
|
||||
let currentFD = fdSelect.fdSelect[i];
|
||||
if (currentFD !== lastFD) {
|
||||
ranges.push(i >> 8 & 0xFF, i & 0xFF, currentFD);
|
||||
lastFD = currentFD;
|
||||
}
|
||||
}
|
||||
let numRanges = (ranges.length - 3) / 3;
|
||||
ranges[1] = numRanges >> 8 & 0xFF;
|
||||
ranges[2] = numRanges & 0xFF;
|
||||
ranges.push(i >> 8 & 0xFF, i & 0xFF);
|
||||
out = new Uint8Array(ranges);
|
||||
break;
|
||||
}
|
||||
return this.compileTypedArray(out);
|
||||
},
|
||||
compileTypedArray: function CFFCompiler_compileTypedArray(data) {
|
||||
var out = [];
|
||||
@ -26271,6 +26288,7 @@ exports.CFFCharset = CFFCharset;
|
||||
exports.CFFTopDict = CFFTopDict;
|
||||
exports.CFFPrivateDict = CFFPrivateDict;
|
||||
exports.CFFCompiler = CFFCompiler;
|
||||
exports.CFFFDSelect = CFFFDSelect;
|
||||
|
||||
/***/ }),
|
||||
/* 32 */
|
||||
@ -33703,7 +33721,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
|
||||
return glyphs;
|
||||
}
|
||||
function lookupCmap(ranges, unicode) {
|
||||
var code = unicode.charCodeAt(0),
|
||||
var code = unicode.codePointAt(0),
|
||||
gid = 0;
|
||||
var l = 0,
|
||||
r = ranges.length - 1;
|
||||
|
@ -82,11 +82,15 @@ See https://github.com/adobe-type-tools/cmap-resources
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="findbarOptionsContainer">
|
||||
<div id="findbarOptionsOneContainer">
|
||||
<input type="checkbox" id="findHighlightAll" class="toolbarField" tabindex="94">
|
||||
<label for="findHighlightAll" class="toolbarLabel" data-l10n-id="find_highlight">Highlight all</label>
|
||||
<input type="checkbox" id="findMatchCase" class="toolbarField" tabindex="95">
|
||||
<label for="findMatchCase" class="toolbarLabel" data-l10n-id="find_match_case_label">Match case</label>
|
||||
</div>
|
||||
<div id="findbarOptionsTwoContainer">
|
||||
<input type="checkbox" id="findEntireWord" class="toolbarField" tabindex="96">
|
||||
<label for="findEntireWord" class="toolbarLabel" data-l10n-id="find_entire_word_label">Whole words</label>
|
||||
<span id="findResultsCount" class="toolbarLabel hidden"></span>
|
||||
</div>
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@ origin:
|
||||
|
||||
# Human-readable identifier for this version/release
|
||||
# Generally "version NNN", "tag SSS", "bookmark SSS"
|
||||
release: version 2.0.815
|
||||
release: version 2.0.843
|
||||
|
||||
# The package's license, where possible using the mnemonic from
|
||||
# https://spdx.org/licenses/
|
||||
|
@ -165,8 +165,16 @@ find_next.title=Find the next occurrence of the phrase
|
||||
find_next_label=Next
|
||||
find_highlight=Highlight all
|
||||
find_match_case_label=Match case
|
||||
find_entire_word_label=Whole words
|
||||
find_reached_top=Reached top of document, continued from bottom
|
||||
find_reached_bottom=Reached end of document, continued from top
|
||||
# LOCALIZATION NOTE (find_matches_count): "{{current}}" and "{{total}}" will be
|
||||
# replaced by a number representing the index of the currently active find result,
|
||||
# respectively a number representing the total number of matches in the document.
|
||||
find_matches_count={{current}} of {{total}} matches
|
||||
# LOCALIZATION NOTE (find_matches_count_limit): "{{limit}}" will be replaced by
|
||||
# a numerical value.
|
||||
find_matches_count_limit=More than {{limit}} matches
|
||||
find_not_found=Phrase not found
|
||||
|
||||
# Error panel labels
|
||||
|
@ -13,13 +13,10 @@ var EXPORTED_SYMBOLS = [
|
||||
];
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
|
||||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["URLSearchParams"]);
|
||||
|
||||
// The upper bound for the count of the visited unique domain names.
|
||||
const MAX_UNIQUE_VISITED_DOMAINS = 100;
|
||||
|
||||
@ -202,29 +199,7 @@ let URICountListener = {
|
||||
return;
|
||||
}
|
||||
|
||||
let parseURLResult = Services.search.parseSubmissionURL(uriSpec);
|
||||
if (parseURLResult.engine) {
|
||||
this._recordSearchTelemetry(uriSpec, parseURLResult);
|
||||
} else if (this._urlsQueuedForParsing) {
|
||||
if (Services.search.isInitialized) {
|
||||
this._urlsQueuedForParsing = null;
|
||||
} else {
|
||||
this._urlsQueuedForParsing.push(uriSpec);
|
||||
if (this._urlsQueuedForParsing.length == 1) {
|
||||
Services.search.init(rv => {
|
||||
if (Components.isSuccessCode(rv)) {
|
||||
for (let url of this._urlsQueuedForParsing) {
|
||||
let innerParseURLResult = Services.search.parseSubmissionURL(url);
|
||||
if (innerParseURLResult.engine) {
|
||||
this._recordSearchTelemetry(url, innerParseURLResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
this._urlsQueuedForParsing = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Services.search.recordSearchURLTelemetry(uriSpec);
|
||||
|
||||
if (!shouldCountURI) {
|
||||
return;
|
||||
@ -262,31 +237,6 @@ let URICountListener = {
|
||||
this._domainSet.clear();
|
||||
},
|
||||
|
||||
_urlsQueuedForParsing: [],
|
||||
|
||||
_recordSearchTelemetry(url, parseURLResult) {
|
||||
switch (parseURLResult.engine.identifier) {
|
||||
case "google":
|
||||
case "google-2018":
|
||||
let type;
|
||||
let queries = new URLSearchParams(url.split("#")[0].split("?")[1]);
|
||||
let code = queries.get("client");
|
||||
if (code) {
|
||||
// Detecting follow-on searches for sap is a little tricky.
|
||||
// There are a few parameters that only show up
|
||||
// with follow-ons, so we look for those. (oq/ved/ei)
|
||||
type = queries.has("oq") || queries.has("ved") || queries.has("ei") ? "sap-follow-on" : "sap";
|
||||
} else {
|
||||
type = "organic";
|
||||
}
|
||||
let payload = `google.in-content:${type}:${code || "none"}`;
|
||||
|
||||
let histogram = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
|
||||
histogram.add(payload);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
};
|
||||
|
@ -14,7 +14,6 @@ ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Lazy getters
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
|
||||
});
|
||||
|
||||
@ -145,44 +144,6 @@ var WindowHelper = {
|
||||
_trackedWindows.push(window);
|
||||
}
|
||||
},
|
||||
|
||||
getTopWindow(options) {
|
||||
let checkPrivacy = typeof options == "object" &&
|
||||
"private" in options;
|
||||
|
||||
let allowPopups = typeof options == "object" && !!options.allowPopups;
|
||||
|
||||
function isSuitableBrowserWindow(win) {
|
||||
return (!win.closed &&
|
||||
(allowPopups || win.toolbar.visible) &&
|
||||
(!checkPrivacy ||
|
||||
PrivateBrowsingUtils.permanentPrivateBrowsing ||
|
||||
PrivateBrowsingUtils.isWindowPrivate(win) == options.private));
|
||||
}
|
||||
|
||||
let broken_wm_z_order =
|
||||
AppConstants.platform != "macosx" && AppConstants.platform != "win";
|
||||
|
||||
if (broken_wm_z_order) {
|
||||
let win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
|
||||
// if we're lucky, this isn't a popup, and we can just return this
|
||||
if (win && !isSuitableBrowserWindow(win)) {
|
||||
win = null;
|
||||
// this is oldest to newest, so this gets a bit ugly
|
||||
for (let nextWin of Services.wm.getEnumerator("navigator:browser")) {
|
||||
if (isSuitableBrowserWindow(nextWin))
|
||||
win = nextWin;
|
||||
}
|
||||
}
|
||||
return win;
|
||||
}
|
||||
for (let win of Services.wm.getZOrderDOMWindowEnumerator("navigator:browser", true)) {
|
||||
if (isSuitableBrowserWindow(win))
|
||||
return win;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
||||
this.BrowserWindowTracker = {
|
||||
@ -195,23 +156,34 @@ this.BrowserWindowTracker = {
|
||||
* Omit the property to search in both groups.
|
||||
* * allowPopups: true if popup windows are permissable.
|
||||
*/
|
||||
getTopWindow(options) {
|
||||
return WindowHelper.getTopWindow(options);
|
||||
getTopWindow(options = {}) {
|
||||
for (let win of _trackedWindows) {
|
||||
if (!win.closed &&
|
||||
(options.allowPopups || win.toolbar.visible) &&
|
||||
(!("private" in options) ||
|
||||
PrivateBrowsingUtils.permanentPrivateBrowsing ||
|
||||
PrivateBrowsingUtils.isWindowPrivate(win) == options.private)) {
|
||||
return win;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Iterator property that yields window objects by z-index, in reverse order.
|
||||
* This means that the lastly focused window will the first item that is yielded.
|
||||
* Note: we only know the order of windows we're actively tracking, which
|
||||
* basically means _only_ browser windows.
|
||||
* Number of currently open browser windows.
|
||||
*/
|
||||
orderedWindows: {
|
||||
* [Symbol.iterator]() {
|
||||
// Clone the windows array immediately as it may change during iteration,
|
||||
// we'd rather have an outdated order than skip/revisit windows.
|
||||
for (let window of [..._trackedWindows])
|
||||
yield window;
|
||||
},
|
||||
get windowCount() {
|
||||
return _trackedWindows.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Array of browser windows ordered by z-index, in reverse order.
|
||||
* This means that the top-most browser window will be the first item.
|
||||
*/
|
||||
get orderedWindows() {
|
||||
// Clone the windows array immediately as it may change during iteration,
|
||||
// we'd rather have an outdated order than skip/revisit windows.
|
||||
return [..._trackedWindows];
|
||||
},
|
||||
|
||||
track(window) {
|
||||
|
@ -79,7 +79,9 @@ add_task(async function test_getTopWindow() {
|
||||
|
||||
add_task(async function test_orderedWindows() {
|
||||
await withOpenWindows(10, async function(windows) {
|
||||
let ordered = [...BrowserWindowTracker.orderedWindows].filter(w => w != TEST_WINDOW);
|
||||
Assert.equal(BrowserWindowTracker.windowCount, 11,
|
||||
"Number of tracked windows, including the test window");
|
||||
let ordered = BrowserWindowTracker.orderedWindows.filter(w => w != TEST_WINDOW);
|
||||
Assert.deepEqual([9, 8, 7, 6, 5, 4, 3, 2, 1, 0], ordered.map(w => windows.indexOf(w)),
|
||||
"Order of opened windows should be as opened.");
|
||||
|
||||
@ -90,7 +92,7 @@ add_task(async function test_orderedWindows() {
|
||||
await promise;
|
||||
}
|
||||
|
||||
let ordered2 = [...BrowserWindowTracker.orderedWindows].filter(w => w != TEST_WINDOW);
|
||||
let ordered2 = BrowserWindowTracker.orderedWindows.filter(w => w != TEST_WINDOW);
|
||||
// After the shuffle, we expect window '1' to be the top-most window, because
|
||||
// it was the last one we called focus on. Then '6', the window we focused
|
||||
// before-last, followed by '4'. The order of the other windows remains
|
||||
@ -104,7 +106,7 @@ add_task(async function test_orderedWindows() {
|
||||
windows[9].minimize();
|
||||
await promise;
|
||||
|
||||
let ordered3 = [...BrowserWindowTracker.orderedWindows].filter(w => w != TEST_WINDOW);
|
||||
let ordered3 = BrowserWindowTracker.orderedWindows.filter(w => w != TEST_WINDOW);
|
||||
// Test the end of the array of window indices, because Windows Debug builds
|
||||
// mysteriously swap the order of the first two windows.
|
||||
Assert.deepEqual([8, 7, 5, 3, 2, 0, 9], ordered3.map(w => windows.indexOf(w)).slice(3),
|
||||
|
@ -483,3 +483,7 @@ def alter_path(sdk_bin_path):
|
||||
set_config('PATH', alter_path)
|
||||
|
||||
check_prog('MAKECAB', ('makecab.exe',))
|
||||
|
||||
# Make sure that the build system can handle non-ASCII characters in
|
||||
# environment variables to prevent silent breakage on non-English systems.
|
||||
set_config('NONASCII', b'\241\241')
|
||||
|
@ -5,7 +5,6 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIPaymentActionRequest.idl',
|
||||
'nsIPaymentActionResponse.idl',
|
||||
'nsIPaymentAddress.idl',
|
||||
'nsIPaymentRequest.idl',
|
||||
|
@ -1,161 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIVariant.idl"
|
||||
#include "nsIPaymentRequest.idl"
|
||||
#include "nsIPaymentActionResponse.idl"
|
||||
#include "nsIPaymentAddress.idl"
|
||||
|
||||
interface nsIArray;
|
||||
|
||||
[builtinclass, uuid(3fef5459-b0ea-469b-be9f-b99e8ca75d3d)]
|
||||
interface nsIPaymentActionCallback : nsISupports
|
||||
{
|
||||
void respondPayment(in nsIPaymentActionResponse aResponse);
|
||||
void changeShippingAddress(in AString aRequestId, in nsIPaymentAddress aAddress);
|
||||
void changeShippingOption(in AString aRequestId, in AString aOption);
|
||||
};
|
||||
|
||||
[builtinclass, uuid(7ddbe8be-beac-4952-96f6-619981dff7a6)]
|
||||
interface nsIPaymentActionRequest : nsISupports
|
||||
{
|
||||
const uint32_t UNKNOWN_ACTION = 0;
|
||||
const uint32_t CREATE_ACTION = 1;
|
||||
const uint32_t CANMAKE_ACTION = 2;
|
||||
const uint32_t SHOW_ACTION = 3;
|
||||
const uint32_t ABORT_ACTION = 4;
|
||||
const uint32_t COMPLETE_ACTION = 5;
|
||||
const uint32_t UPDATE_ACTION = 6;
|
||||
const uint32_t CLOSE_ACTION = 7;
|
||||
|
||||
/*
|
||||
* The payment request identifier.
|
||||
*/
|
||||
readonly attribute AString requestId;
|
||||
|
||||
/*
|
||||
* The type of the requested task.
|
||||
*/
|
||||
readonly attribute uint32_t type;
|
||||
|
||||
/*
|
||||
* The callback for the response from UI module
|
||||
*/
|
||||
readonly attribute nsIPaymentActionCallback callback;
|
||||
|
||||
/*
|
||||
* Initialize function for this request.
|
||||
*/
|
||||
void init(in AString aRequestId,
|
||||
in uint32_t aType,
|
||||
in nsIPaymentActionCallback aCallback);
|
||||
};
|
||||
|
||||
[builtinclass, uuid(1d38dce6-8bcd-441b-aa94-68e300b6e175)]
|
||||
interface nsIPaymentCreateActionRequest : nsIPaymentActionRequest
|
||||
{
|
||||
/*
|
||||
* The tab identifier
|
||||
*/
|
||||
readonly attribute uint64_t tabId;
|
||||
|
||||
/*
|
||||
* The top level document's principal
|
||||
*/
|
||||
readonly attribute nsIPrincipal topLevelPrincipal;
|
||||
|
||||
/*
|
||||
* The methodData information of the payment request.
|
||||
*/
|
||||
readonly attribute nsIArray methodData;
|
||||
|
||||
/*
|
||||
* The Details information of the payment request.
|
||||
*/
|
||||
readonly attribute nsIPaymentDetails details;
|
||||
|
||||
/*
|
||||
* The Options information of the payment request.
|
||||
*/
|
||||
readonly attribute nsIPaymentOptions options;
|
||||
|
||||
/*
|
||||
* The selected shipping option of the payment request;
|
||||
*/
|
||||
readonly attribute AString shippingOption;
|
||||
|
||||
/*
|
||||
* Initialize function the this request.
|
||||
*/
|
||||
void initRequest(in AString aRequestId,
|
||||
in nsIPaymentActionCallback aCallback,
|
||||
in uint64_t aTabId,
|
||||
in nsIPrincipal aPrincipal,
|
||||
in nsIArray aMethodData,
|
||||
in nsIPaymentDetails aDetails,
|
||||
in nsIPaymentOptions aOptions,
|
||||
in AString aShippingOption);
|
||||
};
|
||||
|
||||
[builtinclass, uuid(4429697d-1135-47de-a46e-5196d399ec55)]
|
||||
interface nsIPaymentCompleteActionRequest : nsIPaymentActionRequest
|
||||
{
|
||||
/*
|
||||
* The complete status from merchant side.
|
||||
*/
|
||||
readonly attribute AString completeStatus;
|
||||
|
||||
/*
|
||||
* Initialize function for this request.
|
||||
*/
|
||||
void initRequest(in AString aRequestId,
|
||||
in nsIPaymentActionCallback aCallback,
|
||||
in AString aCompleteStatus);
|
||||
};
|
||||
|
||||
[builtinclass, uuid(21f631e8-c047-4fd8-b3c6-68e26c62639a)]
|
||||
interface nsIPaymentUpdateActionRequest : nsIPaymentActionRequest
|
||||
{
|
||||
/*
|
||||
* The details information for updating the specified payment request.
|
||||
*/
|
||||
readonly attribute nsIPaymentDetails details;
|
||||
|
||||
/*
|
||||
* The selected shipping option information
|
||||
*/
|
||||
readonly attribute AString shippingOption;
|
||||
|
||||
/*
|
||||
* Initialize function for this request.
|
||||
*/
|
||||
void initRequest(in AString aRequestId,
|
||||
in nsIPaymentActionCallback aCallback,
|
||||
in nsIPaymentDetails aDetails,
|
||||
in AString aShippingOption);
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_PAYMENT_ACTION_REQUEST_CID \
|
||||
{ 0x7ddbe8be, 0xbeac, 0x4952, { 0x96, 0xf6, 0x61, 0x99, 0x81, 0xdf, 0xf7, 0xa6 } }
|
||||
#define NS_PAYMENT_ACTION_REQUEST_CONTRACT_ID \
|
||||
"@mozilla.org/dom/payments/payment-action-request;1"
|
||||
|
||||
#define NS_PAYMENT_CREATE_ACTION_REQUEST_CID \
|
||||
{ 0x1d38dce6, 0x8bcd, 0x441b, { 0xaa, 0x94, 0x68, 0xe3, 0x00, 0xb6, 0xe1, 0x75 } }
|
||||
#define NS_PAYMENT_CREATE_ACTION_REQUEST_CONTRACT_ID \
|
||||
"@mozilla.org/dom/payments/payment-create-action-request;1"
|
||||
|
||||
#define NS_PAYMENT_COMPLETE_ACTION_REQUEST_CID \
|
||||
{ 0x4429697d, 0x1135, 0x47de, { 0xa4, 0x6e, 0x51, 0x96, 0xd3, 0x99, 0xec, 0x55 } }
|
||||
#define NS_PAYMENT_COMPLETE_ACTION_REQUEST_CONTRACT_ID \
|
||||
"@mozilla.org/dom/payments/payment-complete-action-request;1"
|
||||
|
||||
#define NS_PAYMENT_UPDATE_ACTION_REQUEST_CID \
|
||||
{ 0x21f631e8, 0xc047, 0x4fd8, { 0xb3, 0xc6, 0x68, 0xe2, 0x6c, 0x62, 0x63, 0x9a } }
|
||||
#define NS_PAYMENT_UPDATE_ACTION_REQUEST_CONTRACT_ID \
|
||||
"@mozilla.org/dom/payments/payment-update-action-request;1"
|
||||
%}
|
@ -63,9 +63,10 @@ interface nsIPaymentDetails : nsISupports
|
||||
readonly attribute AString error;
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval shippingAddressErrors;
|
||||
|
||||
void update(in nsIPaymentDetails aDetails, in boolean aRequestShipping);
|
||||
AString shippingAddressErrorsJSON();
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval payer;
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval paymentMethod;
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(d53f9f20-138e-47cc-9fd5-db16a3f6d301)]
|
||||
@ -89,8 +90,4 @@ interface nsIPaymentRequest : nsISupports
|
||||
readonly attribute nsIPaymentDetails paymentDetails;
|
||||
readonly attribute nsIPaymentOptions paymentOptions;
|
||||
readonly attribute AString shippingOption;
|
||||
|
||||
[noscript] void setCompleteStatus(in AString aCompleteStatus);
|
||||
void updatePaymentDetails(in nsIPaymentDetails aDetails,
|
||||
in AString aShippingOption);
|
||||
};
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIVariant.idl"
|
||||
#include "nsIPaymentRequest.idl"
|
||||
#include "nsIPaymentActionRequest.idl"
|
||||
#include "nsIPaymentActionResponse.idl"
|
||||
#include "nsIPaymentAddress.idl"
|
||||
#include "nsISimpleEnumerator.idl"
|
||||
@ -70,22 +69,6 @@ interface nsIPaymentRequestService : nsISupports
|
||||
* This API is for testing only.
|
||||
*/
|
||||
void setTestingUIService(in nsIPaymentUIService aUIService);
|
||||
|
||||
/**
|
||||
* Request a specified action on the specified PaymentRequest.
|
||||
* @param aRequest - the requested action.
|
||||
*/
|
||||
void requestPayment(in nsIPaymentActionRequest aRequest);
|
||||
|
||||
/**
|
||||
* This is a cleanup function to break the association between
|
||||
* nsIPaymentRequestService and nsIPaymentActionCallback.
|
||||
* nsIPaymentActionCallback is an interface that registered to
|
||||
* nsIPaymentRequestService when the merchant asks to perform actions, and it
|
||||
* will be called when user's response send back to nsIPaymentRequestService.
|
||||
* @param aCallback - the specified nsIPaymentActionCallback.
|
||||
*/
|
||||
void removeActionCallback(in nsIPaymentActionCallback aCallback);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
@ -753,7 +753,7 @@ SpeechRecognition::Start(const Optional<NonNull<DOMMediaStream>>& aStream,
|
||||
if (aStream.WasPassed()) {
|
||||
StartRecording(&aStream.Value());
|
||||
} else {
|
||||
AutoNoJSAPI();
|
||||
AutoNoJSAPI nojsapi;
|
||||
MediaManager* manager = MediaManager::Get();
|
||||
MediaManager::GetUserMediaSuccessCallback onsuccess(
|
||||
new GetUserMediaSuccessCallback(this));
|
||||
|
@ -1,230 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "PaymentActionRequest.h"
|
||||
#include "PaymentRequestData.h"
|
||||
|
||||
using namespace mozilla::dom::payments;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/* PaymentActionRequest */
|
||||
|
||||
NS_IMPL_ISUPPORTS(PaymentActionRequest,
|
||||
nsIPaymentActionRequest)
|
||||
|
||||
PaymentActionRequest::PaymentActionRequest()
|
||||
: mRequestId(EmptyString())
|
||||
, mType(nsIPaymentActionRequest::UNKNOWN_ACTION)
|
||||
, mCallback(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentActionRequest::Init(const nsAString& aRequestId,
|
||||
const uint32_t aType,
|
||||
nsIPaymentActionCallback* aCallback)
|
||||
{
|
||||
mRequestId = aRequestId;
|
||||
mType = aType;
|
||||
mCallback = aCallback;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentActionRequest::GetRequestId(nsAString& aRequestId)
|
||||
{
|
||||
aRequestId = mRequestId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentActionRequest::GetType(uint32_t* aType)
|
||||
{
|
||||
*aType = mType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentActionRequest::GetCallback(nsIPaymentActionCallback** aCallback)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
nsCOMPtr<nsIPaymentActionCallback> callback = mCallback;
|
||||
callback.forget(aCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* PaymentCreateActionRequest */
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(PaymentCreateActionRequest,
|
||||
PaymentActionRequest,
|
||||
nsIPaymentCreateActionRequest)
|
||||
|
||||
PaymentCreateActionRequest::PaymentCreateActionRequest()
|
||||
: mTabId(0)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentCreateActionRequest::InitRequest(const nsAString& aRequestId,
|
||||
nsIPaymentActionCallback* aCallback,
|
||||
const uint64_t aTabId,
|
||||
nsIPrincipal* aTopLevelPrincipal,
|
||||
nsIArray* aMethodData,
|
||||
nsIPaymentDetails* aDetails,
|
||||
nsIPaymentOptions* aOptions,
|
||||
const nsAString& aShippingOption)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
NS_ENSURE_ARG_POINTER(aTopLevelPrincipal);
|
||||
NS_ENSURE_ARG_POINTER(aMethodData);
|
||||
NS_ENSURE_ARG_POINTER(aDetails);
|
||||
NS_ENSURE_ARG_POINTER(aOptions);
|
||||
nsresult rv = Init(aRequestId, nsIPaymentActionRequest::CREATE_ACTION, aCallback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
mTabId = aTabId;
|
||||
mTopLevelPrincipal = aTopLevelPrincipal;
|
||||
mMethodData = aMethodData;
|
||||
mDetails = aDetails;
|
||||
mOptions = aOptions;
|
||||
mShippingOption = aShippingOption;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentCreateActionRequest::GetTabId(uint64_t* aTabId)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTabId);
|
||||
*aTabId = mTabId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentCreateActionRequest::GetTopLevelPrincipal(nsIPrincipal** aTopLevelPrincipal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTopLevelPrincipal);
|
||||
MOZ_ASSERT(mTopLevelPrincipal);
|
||||
nsCOMPtr<nsIPrincipal> principal = mTopLevelPrincipal;
|
||||
principal.forget(aTopLevelPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentCreateActionRequest::GetMethodData(nsIArray** aMethodData)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMethodData);
|
||||
MOZ_ASSERT(mMethodData);
|
||||
nsCOMPtr<nsIArray> methodData = mMethodData;
|
||||
methodData.forget(aMethodData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentCreateActionRequest::GetDetails(nsIPaymentDetails** aDetails)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDetails);
|
||||
MOZ_ASSERT(mDetails);
|
||||
nsCOMPtr<nsIPaymentDetails> details = mDetails;
|
||||
details.forget(aDetails);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentCreateActionRequest::GetOptions(nsIPaymentOptions** aOptions)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOptions);
|
||||
MOZ_ASSERT(mOptions);
|
||||
nsCOMPtr<nsIPaymentOptions> options = mOptions;
|
||||
options.forget(aOptions);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentCreateActionRequest::GetShippingOption(nsAString& aShippingOption)
|
||||
{
|
||||
aShippingOption = mShippingOption;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* PaymentCompleteActionRequest */
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(PaymentCompleteActionRequest,
|
||||
PaymentActionRequest,
|
||||
nsIPaymentCompleteActionRequest)
|
||||
|
||||
PaymentCompleteActionRequest::PaymentCompleteActionRequest()
|
||||
: mCompleteStatus(EmptyString())
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentCompleteActionRequest::GetCompleteStatus(nsAString& aCompleteStatus)
|
||||
{
|
||||
aCompleteStatus = mCompleteStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentCompleteActionRequest::InitRequest(const nsAString& aRequestId,
|
||||
nsIPaymentActionCallback* aCallback,
|
||||
const nsAString& aCompleteStatus)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
nsresult rv = Init(aRequestId, nsIPaymentActionRequest::COMPLETE_ACTION, aCallback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
mCompleteStatus = aCompleteStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* PaymentUpdateActionRequest */
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(PaymentUpdateActionRequest,
|
||||
PaymentActionRequest,
|
||||
nsIPaymentUpdateActionRequest)
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentUpdateActionRequest::GetDetails(nsIPaymentDetails** aDetails)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDetails);
|
||||
MOZ_ASSERT(mDetails);
|
||||
nsCOMPtr<nsIPaymentDetails> details = mDetails;
|
||||
details.forget(aDetails);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentUpdateActionRequest::GetShippingOption(nsAString& aShippingOption)
|
||||
{
|
||||
aShippingOption = mShippingOption;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentUpdateActionRequest::InitRequest(const nsAString& aRequestId,
|
||||
nsIPaymentActionCallback* aCallback,
|
||||
nsIPaymentDetails* aDetails,
|
||||
const nsAString& aShippingOption)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
NS_ENSURE_ARG_POINTER(aDetails);
|
||||
nsresult rv = Init(aRequestId, nsIPaymentActionRequest::UPDATE_ACTION, aCallback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
mDetails = aDetails;
|
||||
mShippingOption = aShippingOption;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // end of namespace dom
|
||||
} // end of namespace mozilla
|
@ -1,90 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_PaymentActionRequest_h
|
||||
#define mozilla_dom_PaymentActionRequest_h
|
||||
|
||||
#include "nsIPaymentActionRequest.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIArray.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class PaymentActionRequest : public nsIPaymentActionRequest
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPAYMENTACTIONREQUEST
|
||||
|
||||
PaymentActionRequest();
|
||||
|
||||
protected:
|
||||
virtual ~PaymentActionRequest() = default;
|
||||
|
||||
nsString mRequestId;
|
||||
uint32_t mType;
|
||||
nsCOMPtr<nsIPaymentActionCallback> mCallback;
|
||||
};
|
||||
|
||||
class PaymentCreateActionRequest final : public nsIPaymentCreateActionRequest
|
||||
, public PaymentActionRequest
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_NSIPAYMENTACTIONREQUEST(PaymentActionRequest::)
|
||||
NS_DECL_NSIPAYMENTCREATEACTIONREQUEST
|
||||
|
||||
PaymentCreateActionRequest();
|
||||
|
||||
private:
|
||||
~PaymentCreateActionRequest() = default;
|
||||
|
||||
uint64_t mTabId;
|
||||
nsCOMPtr<nsIPrincipal> mTopLevelPrincipal;
|
||||
nsCOMPtr<nsIArray> mMethodData;
|
||||
nsCOMPtr<nsIPaymentDetails> mDetails;
|
||||
nsCOMPtr<nsIPaymentOptions> mOptions;
|
||||
nsString mShippingOption;
|
||||
};
|
||||
|
||||
class PaymentCompleteActionRequest final : public nsIPaymentCompleteActionRequest
|
||||
, public PaymentActionRequest
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_NSIPAYMENTACTIONREQUEST(PaymentActionRequest::)
|
||||
NS_DECL_NSIPAYMENTCOMPLETEACTIONREQUEST
|
||||
|
||||
PaymentCompleteActionRequest();
|
||||
|
||||
private:
|
||||
~PaymentCompleteActionRequest() = default;
|
||||
|
||||
nsString mCompleteStatus;
|
||||
};
|
||||
|
||||
class PaymentUpdateActionRequest final : public nsIPaymentUpdateActionRequest
|
||||
, public PaymentActionRequest
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_NSIPAYMENTACTIONREQUEST(PaymentActionRequest::)
|
||||
NS_DECL_NSIPAYMENTUPDATEACTIONREQUEST
|
||||
|
||||
PaymentUpdateActionRequest() = default;
|
||||
private:
|
||||
~PaymentUpdateActionRequest() = default;
|
||||
|
||||
nsCOMPtr<nsIPaymentDetails> mDetails;
|
||||
nsString mShippingOption;
|
||||
};
|
||||
|
||||
} // end of namespace dom
|
||||
} // end of namespace mozilla
|
||||
|
||||
#endif
|
@ -745,10 +745,14 @@ PaymentRequest::Show(const Optional<OwningNonNull<Promise>>& aDetailsPromise,
|
||||
void
|
||||
PaymentRequest::RejectShowPayment(nsresult aRejectReason)
|
||||
{
|
||||
MOZ_ASSERT(mAcceptPromise);
|
||||
MOZ_ASSERT(mAcceptPromise || mResponse);
|
||||
MOZ_ASSERT(mState == eInteractive);
|
||||
|
||||
mAcceptPromise->MaybeReject(aRejectReason);
|
||||
if (mResponse) {
|
||||
mResponse->RejectRetry(aRejectReason);
|
||||
} else {
|
||||
mAcceptPromise->MaybeReject(aRejectReason);
|
||||
}
|
||||
mState = eClosed;
|
||||
mAcceptPromise = nullptr;
|
||||
}
|
||||
@ -761,7 +765,7 @@ PaymentRequest::RespondShowPayment(const nsAString& aMethodName,
|
||||
const nsAString& aPayerPhone,
|
||||
nsresult aRv)
|
||||
{
|
||||
MOZ_ASSERT(mAcceptPromise);
|
||||
MOZ_ASSERT(mAcceptPromise || mResponse);
|
||||
MOZ_ASSERT(mState == eInteractive);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
@ -773,12 +777,17 @@ PaymentRequest::RespondShowPayment(const nsAString& aMethodName,
|
||||
mShippingAddress.swap(mFullShippingAddress);
|
||||
mFullShippingAddress = nullptr;
|
||||
|
||||
RefPtr<PaymentResponse> paymentResponse =
|
||||
new PaymentResponse(GetOwner(), this, mId, aMethodName,
|
||||
mShippingOption, mShippingAddress, aDetails,
|
||||
aPayerName, aPayerEmail, aPayerPhone);
|
||||
mResponse = paymentResponse;
|
||||
mAcceptPromise->MaybeResolve(paymentResponse);
|
||||
if (mResponse) {
|
||||
mResponse->RespondRetry(aMethodName, mShippingOption, mShippingAddress,
|
||||
aDetails, aPayerName, aPayerEmail, aPayerPhone);
|
||||
} else {
|
||||
RefPtr<PaymentResponse> paymentResponse =
|
||||
new PaymentResponse(GetOwner(), this, mId, aMethodName,
|
||||
mShippingOption, mShippingAddress, aDetails,
|
||||
aPayerName, aPayerEmail, aPayerPhone);
|
||||
mResponse = paymentResponse;
|
||||
mAcceptPromise->MaybeResolve(paymentResponse);
|
||||
}
|
||||
|
||||
mState = eClosed;
|
||||
mAcceptPromise = nullptr;
|
||||
@ -903,6 +912,22 @@ PaymentRequest::AbortUpdate(nsresult aRv, bool aDeferredShow)
|
||||
mUpdateError = aRv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequest::RetryPayment(JSContext* aCx, const PaymentValidationErrors& aErrors)
|
||||
{
|
||||
if (mState == eInteractive) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
|
||||
MOZ_ASSERT(manager);
|
||||
nsresult rv = manager->RetryPayment(aCx, this, aErrors);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
mState = eInteractive;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PaymentRequest::GetId(nsAString& aRetVal) const
|
||||
{
|
||||
|
@ -109,6 +109,8 @@ public:
|
||||
already_AddRefed<Promise> Abort(ErrorResult& aRv);
|
||||
void RespondAbortPayment(bool aResult);
|
||||
|
||||
nsresult RetryPayment(JSContext* aCx, const PaymentValidationErrors& aErrors);
|
||||
|
||||
void GetId(nsAString& aRetVal) const;
|
||||
void GetInternalId(nsAString& aRetVal);
|
||||
void SetId(const nsAString& aId);
|
||||
|
@ -341,7 +341,9 @@ PaymentDetails::PaymentDetails(const nsAString& aId,
|
||||
nsIArray* aShippingOptions,
|
||||
nsIArray* aModifiers,
|
||||
const nsAString& aError,
|
||||
const nsAString& aShippingAddressErrors)
|
||||
const nsAString& aShippingAddressErrors,
|
||||
const nsAString& aPayerErrors,
|
||||
const nsAString& aPaymentMethodErrors)
|
||||
: mId(aId)
|
||||
, mTotalItem(aTotalItem)
|
||||
, mDisplayItems(aDisplayItems)
|
||||
@ -349,6 +351,8 @@ PaymentDetails::PaymentDetails(const nsAString& aId,
|
||||
, mModifiers(aModifiers)
|
||||
, mError(aError)
|
||||
, mShippingAddressErrors(aShippingAddressErrors)
|
||||
, mPayerErrors(aPayerErrors)
|
||||
, mPaymentMethodErrors(aPaymentMethodErrors)
|
||||
{
|
||||
}
|
||||
|
||||
@ -415,7 +419,9 @@ PaymentDetails::Create(const IPCPaymentDetails& aIPCDetails,
|
||||
nsCOMPtr<nsIPaymentDetails> details =
|
||||
new PaymentDetails(aIPCDetails.id(), total, displayItems, shippingOptions,
|
||||
modifiers, aIPCDetails.error(),
|
||||
aIPCDetails.shippingAddressErrors());
|
||||
aIPCDetails.shippingAddressErrors(),
|
||||
aIPCDetails.payerErrors(),
|
||||
aIPCDetails.paymentMethodErrors());
|
||||
|
||||
details.forget(aDetails);
|
||||
return NS_OK;
|
||||
@ -484,6 +490,31 @@ PaymentDetails::GetShippingAddressErrors(JSContext* aCx, JS::MutableHandleValue
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentDetails::GetPayer(JSContext* aCx, JS::MutableHandleValue aErrors)
|
||||
{
|
||||
PayerErrorFields errors;
|
||||
errors.Init(mPayerErrors);
|
||||
if (!ToJSValue(aCx, errors, aErrors)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentDetails::GetPaymentMethod(JSContext* aCx, JS::MutableHandleValue aErrors)
|
||||
{
|
||||
if (mPaymentMethodErrors.IsEmpty()) {
|
||||
aErrors.set(JS::NullValue());
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult rv = DeserializeToJSValue(mPaymentMethodErrors, aCx ,aErrors);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentDetails::Update(nsIPaymentDetails* aDetails, const bool aRequestShipping)
|
||||
{
|
||||
MOZ_ASSERT(aDetails);
|
||||
@ -533,14 +564,44 @@ PaymentDetails::Update(nsIPaymentDetails* aDetails, const bool aRequestShipping)
|
||||
return rv;
|
||||
}
|
||||
|
||||
aDetails->ShippingAddressErrorsJSON(mShippingAddressErrors);
|
||||
PaymentDetails* rowDetails = static_cast<PaymentDetails*>(aDetails);
|
||||
MOZ_ASSERT(rowDetails);
|
||||
mShippingAddressErrors = rowDetails->GetShippingAddressErrors();
|
||||
mPayerErrors = rowDetails->GetPayer();
|
||||
mPaymentMethodErrors = rowDetails->GetPaymentMethod();
|
||||
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
PaymentDetails::ShippingAddressErrorsJSON(nsAString& aErrors)
|
||||
|
||||
const nsString&
|
||||
PaymentDetails::GetShippingAddressErrors() const
|
||||
{
|
||||
aErrors = mShippingAddressErrors;
|
||||
return mShippingAddressErrors;
|
||||
}
|
||||
|
||||
const nsString&
|
||||
PaymentDetails::GetPayer() const
|
||||
{
|
||||
return mPayerErrors;
|
||||
}
|
||||
|
||||
const nsString&
|
||||
PaymentDetails::GetPaymentMethod() const
|
||||
{
|
||||
return mPaymentMethodErrors;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentDetails::UpdateErrors(const nsAString& aError,
|
||||
const nsAString& aPayerErrors,
|
||||
const nsAString& aPaymentMethodErrors,
|
||||
const nsAString& aShippingAddressErrors)
|
||||
{
|
||||
mError = aError;
|
||||
mPayerErrors = aPayerErrors;
|
||||
mPaymentMethodErrors = aPaymentMethodErrors;
|
||||
mShippingAddressErrors = aShippingAddressErrors;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -701,7 +762,7 @@ PaymentRequest::GetShippingOption(nsAString& aShippingOption)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
PaymentRequest::UpdatePaymentDetails(nsIPaymentDetails* aPaymentDetails,
|
||||
const nsAString& aShippingOption)
|
||||
{
|
||||
@ -712,14 +773,30 @@ PaymentRequest::UpdatePaymentDetails(nsIPaymentDetails* aPaymentDetails,
|
||||
return rv;
|
||||
}
|
||||
mShippingOption = aShippingOption;
|
||||
return mPaymentDetails->Update(aPaymentDetails, requestShipping);
|
||||
|
||||
PaymentDetails* rowDetails = static_cast<PaymentDetails*>(mPaymentDetails.get());
|
||||
MOZ_ASSERT(rowDetails);
|
||||
return rowDetails->Update(aPaymentDetails, requestShipping);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
void
|
||||
PaymentRequest::SetCompleteStatus(const nsAString& aCompleteStatus)
|
||||
{
|
||||
mCompleteStatus = aCompleteStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequest::UpdateErrors(const nsAString& aError,
|
||||
const nsAString& aPayerErrors,
|
||||
const nsAString& aPaymentMethodErrors,
|
||||
const nsAString& aShippingAddressErrors)
|
||||
{
|
||||
PaymentDetails* rowDetails = static_cast<PaymentDetails*>(mPaymentDetails.get());
|
||||
MOZ_ASSERT(rowDetails);
|
||||
return rowDetails->UpdateErrors(aError,
|
||||
aPayerErrors,
|
||||
aPaymentMethodErrors,
|
||||
aShippingAddressErrors);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "nsIPaymentAddress.h"
|
||||
#include "nsIPaymentRequest.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/dom/PPaymentRequest.h"
|
||||
#include "mozilla/dom/PaymentRequestParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -131,6 +131,15 @@ public:
|
||||
|
||||
static nsresult Create(const IPCPaymentDetails& aIPCDetails,
|
||||
nsIPaymentDetails** aDetails);
|
||||
nsresult Update(nsIPaymentDetails* aDetails, const bool aRequestShipping);
|
||||
const nsString& GetShippingAddressErrors() const;
|
||||
const nsString& GetPayer() const;
|
||||
const nsString& GetPaymentMethod() const;
|
||||
nsresult UpdateErrors(const nsAString& aError,
|
||||
const nsAString& aPayerErrors,
|
||||
const nsAString& aPaymentMethodErrors,
|
||||
const nsAString& aShippingAddressErrors);
|
||||
|
||||
private:
|
||||
PaymentDetails(const nsAString& aId,
|
||||
nsIPaymentItem* aTotalItem,
|
||||
@ -138,7 +147,9 @@ private:
|
||||
nsIArray* aShippingOptions,
|
||||
nsIArray* aModifiers,
|
||||
const nsAString& aError,
|
||||
const nsAString& aShippingAddressError);
|
||||
const nsAString& aShippingAddressError,
|
||||
const nsAString& aPayerError,
|
||||
const nsAString& aPaymentMethodError);
|
||||
|
||||
~PaymentDetails() = default;
|
||||
|
||||
@ -149,6 +160,8 @@ private:
|
||||
nsCOMPtr<nsIArray> mModifiers;
|
||||
nsString mError;
|
||||
nsString mShippingAddressErrors;
|
||||
nsString mPayerErrors;
|
||||
nsString mPaymentMethodErrors;
|
||||
};
|
||||
|
||||
class PaymentOptions final : public nsIPaymentOptions
|
||||
@ -189,6 +202,29 @@ public:
|
||||
nsIPaymentOptions* aPaymentOptions,
|
||||
const nsAString& aShippingOption);
|
||||
|
||||
void SetIPC(PaymentRequestParent* aIPC)
|
||||
{
|
||||
mIPC = aIPC;
|
||||
}
|
||||
|
||||
PaymentRequestParent* GetIPC() const
|
||||
{
|
||||
return mIPC;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UpdatePaymentDetails(nsIPaymentDetails* aPaymentDetails,
|
||||
const nsAString& aShippingOption);
|
||||
|
||||
void
|
||||
SetCompleteStatus(const nsAString& aCompleteStatus);
|
||||
|
||||
nsresult
|
||||
UpdateErrors(const nsAString& aError,
|
||||
const nsAString& aPayerErrors,
|
||||
const nsAString& aPaymentMethodErrors,
|
||||
const nsAString& aShippingAddressErrors);
|
||||
|
||||
private:
|
||||
~PaymentRequest() = default;
|
||||
|
||||
@ -200,6 +236,10 @@ private:
|
||||
nsCOMPtr<nsIPaymentDetails> mPaymentDetails;
|
||||
nsCOMPtr<nsIPaymentOptions> mPaymentOptions;
|
||||
nsString mShippingOption;
|
||||
|
||||
// IPC's life cycle should be controlled by IPC mechanism.
|
||||
// PaymentRequest should not own the reference of it.
|
||||
PaymentRequestParent* mIPC;
|
||||
};
|
||||
|
||||
class PaymentAddress final : public nsIPaymentAddress
|
||||
|
@ -163,7 +163,7 @@ ConvertDetailsInit(JSContext* aCx,
|
||||
}
|
||||
|
||||
// Convert |id|
|
||||
nsString id(EmptyString());
|
||||
nsAutoString id;
|
||||
if (aDetails.mId.WasPassed()) {
|
||||
id = aDetails.mId.Value();
|
||||
}
|
||||
@ -178,7 +178,9 @@ ConvertDetailsInit(JSContext* aCx,
|
||||
shippingOptions,
|
||||
modifiers,
|
||||
EmptyString(), // error message
|
||||
EmptyString()); // shippingAddressErrors
|
||||
EmptyString(), // shippingAddressErrors
|
||||
EmptyString(), // payerErrors
|
||||
EmptyString()); // paymentMethodErrors
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -204,23 +206,39 @@ ConvertDetailsUpdate(JSContext* aCx,
|
||||
ConvertItem(aDetails.mTotal, total);
|
||||
|
||||
// Convert |error|
|
||||
nsString error(EmptyString());
|
||||
nsAutoString error;
|
||||
if (aDetails.mError.WasPassed()) {
|
||||
error = aDetails.mError.Value();
|
||||
}
|
||||
|
||||
nsString shippingAddressErrors(EmptyString());
|
||||
nsAutoString shippingAddressErrors;
|
||||
if (!aDetails.mShippingAddressErrors.ToJSON(shippingAddressErrors)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoString payerErrors;
|
||||
if (!aDetails.mPayerErrors.ToJSON(payerErrors)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoString paymentMethodErrors;
|
||||
if (aDetails.mPaymentMethodErrors.WasPassed()) {
|
||||
JS::RootedObject object(aCx, aDetails.mPaymentMethodErrors.Value());
|
||||
nsresult rv = SerializeFromJSObject(aCx, object, paymentMethodErrors);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
aIPCDetails = IPCPaymentDetails(EmptyString(), // id
|
||||
total,
|
||||
displayItems,
|
||||
shippingOptions,
|
||||
modifiers,
|
||||
error,
|
||||
shippingAddressErrors);
|
||||
shippingAddressErrors,
|
||||
payerErrors,
|
||||
paymentMethodErrors);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -539,6 +557,44 @@ PaymentRequestManager::ClosePayment(PaymentRequest* aRequest)
|
||||
return SendRequestPayment(aRequest, action, false);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestManager::RetryPayment(JSContext* aCx,
|
||||
PaymentRequest* aRequest,
|
||||
const PaymentValidationErrors& aErrors)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCx);
|
||||
NS_ENSURE_ARG_POINTER(aRequest);
|
||||
|
||||
nsAutoString requestId;
|
||||
aRequest->GetInternalId(requestId);
|
||||
|
||||
nsAutoString error;
|
||||
if (aErrors.mError.WasPassed()) {
|
||||
error = aErrors.mError.Value();
|
||||
}
|
||||
|
||||
nsAutoString shippingAddressErrors;
|
||||
aErrors.mShippingAddress.ToJSON(shippingAddressErrors);
|
||||
|
||||
nsAutoString payerErrors;
|
||||
aErrors.mPayer.ToJSON(payerErrors);
|
||||
|
||||
nsAutoString paymentMethodErrors;
|
||||
if (aErrors.mPaymentMethod.WasPassed()) {
|
||||
JS::RootedObject object(aCx, aErrors.mPaymentMethod.Value());
|
||||
nsresult rv = SerializeFromJSObject(aCx, object, paymentMethodErrors);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
IPCPaymentRetryActionRequest action(requestId,
|
||||
error,
|
||||
payerErrors,
|
||||
paymentMethodErrors,
|
||||
shippingAddressErrors);
|
||||
return SendRequestPayment(aRequest, action);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestManager::RespondPayment(PaymentRequest* aRequest,
|
||||
const IPCPaymentActionResponse& aResponse)
|
||||
|
@ -58,6 +58,9 @@ public:
|
||||
bool aRequestShipping,
|
||||
bool aDeferredShow);
|
||||
nsresult ClosePayment(PaymentRequest* aRequest);
|
||||
nsresult RetryPayment(JSContext* aCx,
|
||||
PaymentRequest* aRequest,
|
||||
const PaymentValidationErrors& aErrors);
|
||||
|
||||
nsresult RespondPayment(PaymentRequest* aRequest,
|
||||
const IPCPaymentActionResponse& aResponse);
|
||||
|
@ -5,17 +5,12 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "PaymentActionRequest.h"
|
||||
#include "PaymentActionResponse.h"
|
||||
#include "PaymentRequestData.h"
|
||||
#include "PaymentRequestService.h"
|
||||
|
||||
using mozilla::dom::GeneralResponseData;
|
||||
using mozilla::dom::BasicCardResponseData;
|
||||
using mozilla::dom::PaymentActionRequest;
|
||||
using mozilla::dom::PaymentCreateActionRequest;
|
||||
using mozilla::dom::PaymentCompleteActionRequest;
|
||||
using mozilla::dom::PaymentUpdateActionRequest;
|
||||
using mozilla::dom::PaymentCanMakeActionResponse;
|
||||
using mozilla::dom::PaymentAbortActionResponse;
|
||||
using mozilla::dom::PaymentShowActionResponse;
|
||||
@ -25,10 +20,6 @@ using mozilla::dom::PaymentRequestService;
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(GeneralResponseData)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(BasicCardResponseData)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentActionRequest)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentCreateActionRequest)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentCompleteActionRequest)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentUpdateActionRequest)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentCanMakeActionResponse)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentAbortActionResponse)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentShowActionResponse)
|
||||
@ -39,10 +30,6 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(PaymentRequestService,
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_GENERAL_RESPONSE_DATA_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_BASICCARD_RESPONSE_DATA_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PAYMENT_ACTION_REQUEST_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PAYMENT_CREATE_ACTION_REQUEST_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PAYMENT_COMPLETE_ACTION_REQUEST_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PAYMENT_UPDATE_ACTION_REQUEST_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PAYMENT_ABORT_ACTION_RESPONSE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PAYMENT_SHOW_ACTION_RESPONSE_CID);
|
||||
@ -53,10 +40,6 @@ NS_DEFINE_NAMED_CID(NS_PAYMENT_REQUEST_SERVICE_CID);
|
||||
static const mozilla::Module::CIDEntry kPaymentRequestCIDs[] = {
|
||||
{ &kNS_GENERAL_RESPONSE_DATA_CID, false, nullptr, GeneralResponseDataConstructor},
|
||||
{ &kNS_BASICCARD_RESPONSE_DATA_CID, false, nullptr, BasicCardResponseDataConstructor},
|
||||
{ &kNS_PAYMENT_ACTION_REQUEST_CID, false, nullptr, PaymentActionRequestConstructor},
|
||||
{ &kNS_PAYMENT_CREATE_ACTION_REQUEST_CID, false, nullptr, PaymentCreateActionRequestConstructor},
|
||||
{ &kNS_PAYMENT_COMPLETE_ACTION_REQUEST_CID, false, nullptr, PaymentCompleteActionRequestConstructor},
|
||||
{ &kNS_PAYMENT_UPDATE_ACTION_REQUEST_CID, false, nullptr, PaymentUpdateActionRequestConstructor},
|
||||
{ &kNS_PAYMENT_CANMAKE_ACTION_RESPONSE_CID, false, nullptr, PaymentCanMakeActionResponseConstructor},
|
||||
{ &kNS_PAYMENT_ABORT_ACTION_RESPONSE_CID, false, nullptr, PaymentAbortActionResponseConstructor},
|
||||
{ &kNS_PAYMENT_SHOW_ACTION_RESPONSE_CID, false, nullptr, PaymentShowActionResponseConstructor},
|
||||
@ -69,10 +52,6 @@ static const mozilla::Module::CIDEntry kPaymentRequestCIDs[] = {
|
||||
static const mozilla::Module::ContractIDEntry kPaymentRequestContracts[] = {
|
||||
{ NS_GENERAL_RESPONSE_DATA_CONTRACT_ID, &kNS_GENERAL_RESPONSE_DATA_CID },
|
||||
{ NS_BASICCARD_RESPONSE_DATA_CONTRACT_ID, &kNS_BASICCARD_RESPONSE_DATA_CID },
|
||||
{ NS_PAYMENT_ACTION_REQUEST_CONTRACT_ID, &kNS_PAYMENT_ACTION_REQUEST_CID },
|
||||
{ NS_PAYMENT_CREATE_ACTION_REQUEST_CONTRACT_ID, &kNS_PAYMENT_CREATE_ACTION_REQUEST_CID },
|
||||
{ NS_PAYMENT_COMPLETE_ACTION_REQUEST_CONTRACT_ID, &kNS_PAYMENT_COMPLETE_ACTION_REQUEST_CID },
|
||||
{ NS_PAYMENT_UPDATE_ACTION_REQUEST_CONTRACT_ID, &kNS_PAYMENT_UPDATE_ACTION_REQUEST_CID },
|
||||
{ NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CONTRACT_ID, &kNS_PAYMENT_CANMAKE_ACTION_RESPONSE_CID },
|
||||
{ NS_PAYMENT_ABORT_ACTION_RESPONSE_CONTRACT_ID, &kNS_PAYMENT_ABORT_ACTION_RESPONSE_CID },
|
||||
{ NS_PAYMENT_SHOW_ACTION_RESPONSE_CONTRACT_ID, &kNS_PAYMENT_SHOW_ACTION_RESPONSE_CID },
|
||||
@ -85,10 +64,6 @@ static const mozilla::Module::ContractIDEntry kPaymentRequestContracts[] = {
|
||||
static const mozilla::Module::CategoryEntry kPaymentRequestCategories[] = {
|
||||
{ "payment-request", "GeneralResponseData", NS_GENERAL_RESPONSE_DATA_CONTRACT_ID },
|
||||
{ "payment-request", "BasicCardResponseData", NS_BASICCARD_RESPONSE_DATA_CONTRACT_ID },
|
||||
{ "payment-request", "PaymentActionRequest", NS_PAYMENT_ACTION_REQUEST_CONTRACT_ID },
|
||||
{ "payment-request", "PaymentCreateActionRequest", NS_PAYMENT_CREATE_ACTION_REQUEST_CONTRACT_ID },
|
||||
{ "payment-request", "PaymentCompleteActionRequest", NS_PAYMENT_COMPLETE_ACTION_REQUEST_CONTRACT_ID },
|
||||
{ "payment-request", "PaymentUpdateActionRequest", NS_PAYMENT_UPDATE_ACTION_REQUEST_CONTRACT_ID },
|
||||
{ "payment-request", "PaymentCanMakeActionResponse", NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CONTRACT_ID },
|
||||
{ "payment-request", "PaymentAbortActionResponse", NS_PAYMENT_ABORT_ACTION_RESPONSE_CONTRACT_ID },
|
||||
{ "payment-request", "PaymentShowActionResponse", NS_PAYMENT_SHOW_ACTION_RESPONSE_CONTRACT_ID },
|
||||
|
@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/PaymentRequestParent.h"
|
||||
#include "PaymentRequestData.h"
|
||||
#include "PaymentRequestService.h"
|
||||
#include "BasicCardPayment.h"
|
||||
@ -161,23 +162,23 @@ PaymentRequestService::LaunchUIAction(const nsAString& aRequestId, uint32_t aAct
|
||||
}
|
||||
}
|
||||
switch (aActionType) {
|
||||
case nsIPaymentActionRequest::SHOW_ACTION: {
|
||||
case IPCPaymentActionRequest::TIPCPaymentShowActionRequest:{
|
||||
rv = uiService->ShowPayment(aRequestId);
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::ABORT_ACTION: {
|
||||
case IPCPaymentActionRequest::TIPCPaymentAbortActionRequest: {
|
||||
rv = uiService->AbortPayment(aRequestId);
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::COMPLETE_ACTION: {
|
||||
case IPCPaymentActionRequest::TIPCPaymentCompleteActionRequest: {
|
||||
rv = uiService->CompletePayment(aRequestId);
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::UPDATE_ACTION: {
|
||||
case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
|
||||
rv = uiService->UpdatePayment(aRequestId);
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::CLOSE_ACTION: {
|
||||
case IPCPaymentActionRequest::TIPCPaymentCloseActionRequest: {
|
||||
rv = uiService->ClosePayment(aRequestId);
|
||||
break;
|
||||
}
|
||||
@ -191,103 +192,85 @@ PaymentRequestService::LaunchUIAction(const nsAString& aRequestId, uint32_t aAct
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentRequestService::RemoveActionCallback(nsIPaymentActionCallback* aCallback)
|
||||
nsresult
|
||||
PaymentRequestService::RequestPayment(const nsAString& aRequestId,
|
||||
const IPCPaymentActionRequest& aAction,
|
||||
PaymentRequestParent* aIPC)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
for (auto iter = mCallbackHashtable.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsCOMPtr<nsIPaymentActionCallback> callback = iter.Data();
|
||||
MOZ_ASSERT(callback);
|
||||
if (callback == aCallback) {
|
||||
iter.Remove();
|
||||
return NS_OK;
|
||||
NS_ENSURE_ARG_POINTER(aIPC);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
uint32_t type = aAction.type();
|
||||
|
||||
if (type != IPCPaymentActionRequest::TIPCPaymentCreateActionRequest) {
|
||||
nsCOMPtr<nsIPaymentRequest> request;
|
||||
rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (!request && type != IPCPaymentActionRequest::TIPCPaymentCloseActionRequest) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (request) {
|
||||
payments::PaymentRequest* rowRequest =
|
||||
static_cast<payments::PaymentRequest*>(request.get());
|
||||
if (!rowRequest) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rowRequest->SetIPC(aIPC);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentRequestService::RequestPayment(nsIPaymentActionRequest* aRequest)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRequest);
|
||||
|
||||
nsAutoString requestId;
|
||||
nsresult rv = aRequest->GetRequestId(requestId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
nsCOMPtr<nsIPaymentActionCallback> callback;
|
||||
rv = aRequest->GetCallback(getter_AddRefs(callback));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
rv = SetActionCallback(requestId, callback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t type;
|
||||
rv = aRequest->GetType(&type);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case nsIPaymentActionRequest::CREATE_ACTION: {
|
||||
nsCOMPtr<nsIPaymentCreateActionRequest> request =
|
||||
do_QueryInterface(aRequest);
|
||||
MOZ_ASSERT(request);
|
||||
uint64_t tabId;
|
||||
rv = request->GetTabId(&tabId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> topLevelPrincipal;
|
||||
rv = request->GetTopLevelPrincipal(getter_AddRefs(topLevelPrincipal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIArray> methodData;
|
||||
rv = request->GetMethodData(getter_AddRefs(methodData));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
case IPCPaymentActionRequest::TIPCPaymentCreateActionRequest: {
|
||||
const IPCPaymentCreateActionRequest& action = aAction;
|
||||
uint64_t tabId = aIPC->GetTabId();
|
||||
nsCOMPtr<nsIMutableArray> methodData = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
MOZ_ASSERT(methodData);
|
||||
for (IPCPaymentMethodData data : action.methodData()) {
|
||||
nsCOMPtr<nsIPaymentMethodData> method;
|
||||
rv = payments::PaymentMethodData::Create(data, getter_AddRefs(method));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = methodData->AppendElement(method);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
nsCOMPtr<nsIPaymentDetails> details;
|
||||
rv = request->GetDetails(getter_AddRefs(details));
|
||||
rv = payments::PaymentDetails::Create(action.details(), getter_AddRefs(details));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPaymentOptions> options;
|
||||
rv = request->GetOptions(getter_AddRefs(options));
|
||||
rv = payments::PaymentOptions::Create(action.options(), getter_AddRefs(options));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString shippingOption;
|
||||
rv = request->GetShippingOption(shippingOption);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPaymentRequest> payment =
|
||||
new payments::PaymentRequest(tabId, requestId, topLevelPrincipal,
|
||||
methodData, details, options, shippingOption);
|
||||
new payments::PaymentRequest(tabId,
|
||||
aRequestId,
|
||||
action.topLevelPrincipal(),
|
||||
methodData,
|
||||
details,
|
||||
options,
|
||||
action.shippingOption());
|
||||
|
||||
if (!mRequestQueue.AppendElement(payment, mozilla::fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::CANMAKE_ACTION: {
|
||||
case IPCPaymentActionRequest::TIPCPaymentCanMakeActionRequest: {
|
||||
nsCOMPtr<nsIPaymentCanMakeActionResponse> canMakeResponse =
|
||||
do_CreateInstance(NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CONTRACT_ID);
|
||||
MOZ_ASSERT(canMakeResponse);
|
||||
|
||||
rv = canMakeResponse->Init(requestId, CanMakePayment(requestId));
|
||||
rv = canMakeResponse->Init(aRequestId,
|
||||
CanMakePayment(aRequestId));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = RespondPayment(canMakeResponse.get());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::SHOW_ACTION: {
|
||||
if (mShowingRequest || !CanMakePayment(requestId)) {
|
||||
case IPCPaymentActionRequest::TIPCPaymentShowActionRequest: {
|
||||
if (mShowingRequest || !CanMakePayment(aRequestId)) {
|
||||
uint32_t responseStatus;
|
||||
if (mShowingRequest) {
|
||||
responseStatus = nsIPaymentActionResponse::PAYMENT_REJECTED;
|
||||
@ -297,7 +280,7 @@ PaymentRequestService::RequestPayment(nsIPaymentActionRequest* aRequest)
|
||||
nsCOMPtr<nsIPaymentShowActionResponse> showResponse =
|
||||
do_CreateInstance(NS_PAYMENT_SHOW_ACTION_RESPONSE_CONTRACT_ID);
|
||||
MOZ_ASSERT(showResponse);
|
||||
rv = showResponse->Init(requestId,
|
||||
rv = showResponse->Init(aRequestId,
|
||||
responseStatus,
|
||||
EmptyString(),
|
||||
nullptr,
|
||||
@ -309,90 +292,83 @@ PaymentRequestService::RequestPayment(nsIPaymentActionRequest* aRequest)
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
rv = GetPaymentRequestById(requestId, getter_AddRefs(mShowingRequest));
|
||||
rv = GetPaymentRequestById(aRequestId,
|
||||
getter_AddRefs(mShowingRequest));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
rv = LaunchUIAction(requestId, type);
|
||||
rv = LaunchUIAction(aRequestId, type);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::ABORT_ACTION: {
|
||||
rv = LaunchUIAction(requestId, type);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::COMPLETE_ACTION: {
|
||||
nsCOMPtr<nsIPaymentCompleteActionRequest> request =
|
||||
do_QueryInterface(aRequest);
|
||||
MOZ_ASSERT(request);
|
||||
nsAutoString completeStatus;
|
||||
rv = request->GetCompleteStatus(completeStatus);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIPaymentRequest> payment;
|
||||
rv = GetPaymentRequestById(requestId, getter_AddRefs(payment));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = payment->SetCompleteStatus(completeStatus);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = LaunchUIAction(requestId, type);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::UPDATE_ACTION: {
|
||||
nsCOMPtr<nsIPaymentUpdateActionRequest> request = do_QueryInterface(aRequest);
|
||||
MOZ_ASSERT(request);
|
||||
|
||||
nsCOMPtr<nsIPaymentDetails> details;
|
||||
rv = request->GetDetails(getter_AddRefs(details));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString shippingOption;
|
||||
rv = request->GetShippingOption(shippingOption);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = request->GetRequestId(requestId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIPaymentRequest> payment;
|
||||
rv = GetPaymentRequestById(requestId, getter_AddRefs(payment));
|
||||
case IPCPaymentActionRequest::TIPCPaymentAbortActionRequest: {
|
||||
rv = LaunchUIAction(aRequestId, type);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
rv = payment->UpdatePaymentDetails(details, shippingOption);
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentCompleteActionRequest: {
|
||||
const IPCPaymentCompleteActionRequest& action = aAction;
|
||||
nsCOMPtr<nsIPaymentRequest> payment;
|
||||
rv = GetPaymentRequestById(aRequestId, getter_AddRefs(payment));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
MOZ_ASSERT(payment);
|
||||
payments::PaymentRequest* rowPayment =
|
||||
static_cast<payments::PaymentRequest*>(payment.get());
|
||||
MOZ_ASSERT(rowPayment);
|
||||
rowPayment->SetCompleteStatus(action.completeStatus());
|
||||
rv = LaunchUIAction(aRequestId, type);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
|
||||
const IPCPaymentUpdateActionRequest& action = aAction;
|
||||
nsCOMPtr<nsIPaymentDetails> details;
|
||||
rv = payments::PaymentDetails::Create(action.details(), getter_AddRefs(details));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
nsCOMPtr<nsIPaymentRequest> payment;
|
||||
rv = GetPaymentRequestById(aRequestId, getter_AddRefs(payment));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
MOZ_ASSERT(payment);
|
||||
payments::PaymentRequest* rowPayment =
|
||||
static_cast<payments::PaymentRequest*>(payment.get());
|
||||
MOZ_ASSERT(rowPayment);
|
||||
rv = rowPayment->UpdatePaymentDetails(details, action.shippingOption());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (mShowingRequest) {
|
||||
MOZ_ASSERT(mShowingRequest == payment);
|
||||
rv = LaunchUIAction(requestId, type);
|
||||
rv = LaunchUIAction(aRequestId, type);
|
||||
} else {
|
||||
mShowingRequest = payment;
|
||||
rv = LaunchUIAction(requestId, nsIPaymentActionRequest::SHOW_ACTION);
|
||||
rv = LaunchUIAction(aRequestId,
|
||||
IPCPaymentActionRequest::TIPCPaymentShowActionRequest);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIPaymentActionRequest::CLOSE_ACTION: {
|
||||
nsCOMPtr<nsIPaymentRequest> payment;
|
||||
rv = GetPaymentRequestById(requestId, getter_AddRefs(payment));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
rv = LaunchUIAction(requestId, type);
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentCloseActionRequest: {
|
||||
nsCOMPtr<nsIPaymentRequest> payment;
|
||||
rv = GetPaymentRequestById(aRequestId, getter_AddRefs(payment));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
rv = LaunchUIAction(aRequestId, type);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -402,6 +378,26 @@ PaymentRequestService::RequestPayment(nsIPaymentActionRequest* aRequest)
|
||||
mRequestQueue.RemoveElement(payment);
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentRetryActionRequest: {
|
||||
const IPCPaymentRetryActionRequest& action = aAction;
|
||||
nsCOMPtr<nsIPaymentRequest> payment;
|
||||
rv = GetPaymentRequestById(aRequestId, getter_AddRefs(payment));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
MOZ_ASSERT(payment);
|
||||
payments::PaymentRequest* rowPayment =
|
||||
static_cast<payments::PaymentRequest*>(payment.get());
|
||||
MOZ_ASSERT(rowPayment);
|
||||
rowPayment->UpdateErrors(action.error(),
|
||||
action.payerErrors(),
|
||||
action.paymentMethodErrors(),
|
||||
action.shippingAddressErrors());
|
||||
MOZ_ASSERT(mShowingRequest == payment);
|
||||
rv = LaunchUIAction(aRequestId,
|
||||
IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -422,19 +418,18 @@ PaymentRequestService::RespondPayment(nsIPaymentActionResponse* aResponse)
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!request) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPaymentActionCallback> callback;
|
||||
if (!mCallbackHashtable.Get(requestId, getter_AddRefs(callback))) {
|
||||
payments::PaymentRequest* rowRequest =
|
||||
static_cast<payments::PaymentRequest*>(request.get());
|
||||
if (!rowRequest) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (NS_WARN_IF(!callback)) {
|
||||
if (!rowRequest->GetIPC()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = callback->RespondPayment(aResponse);
|
||||
rv = rowRequest->GetIPC()->RespondPayment(aResponse);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -487,15 +482,23 @@ NS_IMETHODIMP
|
||||
PaymentRequestService::ChangeShippingAddress(const nsAString& aRequestId,
|
||||
nsIPaymentAddress* aAddress)
|
||||
{
|
||||
nsCOMPtr<nsIPaymentActionCallback> callback;
|
||||
if (!mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
|
||||
nsCOMPtr<nsIPaymentRequest> request;
|
||||
nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (!request) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (NS_WARN_IF(!callback)) {
|
||||
payments::PaymentRequest* rowRequest =
|
||||
static_cast<payments::PaymentRequest*>(request.get());
|
||||
if (!rowRequest) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = callback->ChangeShippingAddress(aRequestId, aAddress);
|
||||
if (!rowRequest->GetIPC()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = rowRequest->GetIPC()->ChangeShippingAddress(aRequestId, aAddress);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -506,15 +509,23 @@ NS_IMETHODIMP
|
||||
PaymentRequestService::ChangeShippingOption(const nsAString& aRequestId,
|
||||
const nsAString& aOption)
|
||||
{
|
||||
nsCOMPtr<nsIPaymentActionCallback> callback;
|
||||
if (!mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
|
||||
nsCOMPtr<nsIPaymentRequest> request;
|
||||
nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (!request) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (NS_WARN_IF(!callback)) {
|
||||
payments::PaymentRequest* rowRequest =
|
||||
static_cast<payments::PaymentRequest*>(request.get());
|
||||
if (!rowRequest) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = callback->ChangeShippingOption(aRequestId, aOption);
|
||||
if (!rowRequest->GetIPC()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = rowRequest->GetIPC()->ChangeShippingOption(aRequestId, aOption);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -522,30 +533,6 @@ PaymentRequestService::ChangeShippingOption(const nsAString& aRequestId,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestService::SetActionCallback(const nsAString& aRequestId,
|
||||
nsIPaymentActionCallback* aCallback)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
nsCOMPtr<nsIPaymentActionCallback> callback;
|
||||
if (mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
|
||||
mCallbackHashtable.Remove(aRequestId);
|
||||
}
|
||||
mCallbackHashtable.Put(aRequestId, aCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestService::RemoveActionCallback(const nsAString& aRequestId)
|
||||
{
|
||||
nsCOMPtr<nsIPaymentActionCallback> callback;
|
||||
if (!mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mCallbackHashtable.Remove(aRequestId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
PaymentRequestService::CanMakePayment(const nsAString& aRequestId)
|
||||
{
|
||||
|
@ -34,16 +34,12 @@ public:
|
||||
|
||||
uint32_t NumPayments() const;
|
||||
|
||||
nsresult RequestPayment(const nsAString& aRequestId,
|
||||
const IPCPaymentActionRequest& aAction,
|
||||
PaymentRequestParent* aCallback);
|
||||
private:
|
||||
~PaymentRequestService() = default;
|
||||
|
||||
nsresult
|
||||
SetActionCallback(const nsAString& aRequestId,
|
||||
nsIPaymentActionCallback* aCallback);
|
||||
nsresult
|
||||
RemoveActionCallback(const nsAString& aRequestId);
|
||||
|
||||
// this method is only used for testing
|
||||
nsresult
|
||||
LaunchUIAction(const nsAString& aRequestId, uint32_t aActionType);
|
||||
|
||||
@ -55,8 +51,6 @@ private:
|
||||
|
||||
FallibleTArray<nsCOMPtr<nsIPaymentRequest>> mRequestQueue;
|
||||
|
||||
nsInterfaceHashtable<nsStringHashKey, nsIPaymentActionCallback> mCallbackHashtable;
|
||||
|
||||
nsCOMPtr<nsIPaymentUIService> mTestingUIService;
|
||||
|
||||
nsCOMPtr<nsIPaymentRequest> mShowingRequest;
|
||||
|
@ -31,7 +31,7 @@ PaymentResponse::PaymentResponse(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aRequestId,
|
||||
const nsAString& aMethodName,
|
||||
const nsAString& aShippingOption,
|
||||
RefPtr<PaymentAddress> aShippingAddress,
|
||||
PaymentAddress* aShippingAddress,
|
||||
const nsAString& aDetails,
|
||||
const nsAString& aPayerName,
|
||||
const nsAString& aPayerEmail,
|
||||
@ -183,6 +183,156 @@ PaymentResponse::RespondComplete()
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
PaymentResponse::Retry(JSContext* aCx,
|
||||
const PaymentValidationErrors& aErrors,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsIGlobalObject* global = mOwner->AsGlobal();
|
||||
ErrorResult errResult;
|
||||
RefPtr<Promise> promise = Promise::Create(global, errResult);
|
||||
if (errResult.Failed()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nullptr;
|
||||
}
|
||||
|
||||
nsIDocument* doc = mOwner->GetExtantDoc();
|
||||
if (!doc || !doc->IsCurrentActiveDocument()) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (mCompleteCalled || mRetryPromise) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsresult rv = ValidatePaymentValidationErrors(aErrors);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
promise->MaybeReject(rv);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mRequest);
|
||||
rv = mRequest->RetryPayment(aCx, aErrors);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
promise->MaybeReject(rv);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
mRetryPromise = promise;
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void
|
||||
PaymentResponse::RespondRetry(const nsAString& aMethodName,
|
||||
const nsAString& aShippingOption,
|
||||
PaymentAddress* aShippingAddress,
|
||||
const nsAString& aDetails,
|
||||
const nsAString& aPayerName,
|
||||
const nsAString& aPayerEmail,
|
||||
const nsAString& aPayerPhone)
|
||||
{
|
||||
mMethodName = aMethodName;
|
||||
mShippingOption = aShippingOption;
|
||||
mShippingAddress = aShippingAddress;
|
||||
mDetails = aDetails;
|
||||
mPayerName = aPayerName;
|
||||
mPayerEmail = aPayerEmail;
|
||||
mPayerPhone = aPayerPhone;
|
||||
|
||||
NS_NewTimerWithCallback(getter_AddRefs(mTimer),
|
||||
this,
|
||||
StaticPrefs::dom_payments_response_timeout(),
|
||||
nsITimer::TYPE_ONE_SHOT,
|
||||
mOwner->EventTargetFor(TaskCategory::Other));
|
||||
MOZ_ASSERT(mRetryPromise);
|
||||
mRetryPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
mRetryPromise = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
PaymentResponse::RejectRetry(nsresult aRejectReason)
|
||||
{
|
||||
MOZ_ASSERT(mRetryPromise);
|
||||
mRetryPromise->MaybeReject(aRejectReason);
|
||||
mRetryPromise = nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentResponse::ValidatePaymentValidationErrors(const PaymentValidationErrors& aErrors)
|
||||
{
|
||||
// Should not be empty errors
|
||||
// check PaymentValidationErrors.error
|
||||
if (aErrors.mError.WasPassed() && !aErrors.mError.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
// check PaymentValidationErrors.payer
|
||||
PayerErrorFields payerErrors(aErrors.mPayer);
|
||||
if (payerErrors.mName.WasPassed() && !payerErrors.mName.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (payerErrors.mEmail.WasPassed() && !payerErrors.mEmail.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (payerErrors.mPhone.WasPassed() && !payerErrors.mPhone.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
// check PaymentValidationErrors.paymentMethod
|
||||
if (aErrors.mPaymentMethod.WasPassed()) {
|
||||
return NS_OK;
|
||||
}
|
||||
// check PaymentValidationErrors.shippingAddress
|
||||
AddressErrors addErrors(aErrors.mShippingAddress);
|
||||
if (addErrors.mAddressLine.WasPassed() &&
|
||||
!addErrors.mAddressLine.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mCity.WasPassed() && !addErrors.mCity.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mCountry.WasPassed() && !addErrors.mCountry.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mDependentLocality.WasPassed() &&
|
||||
!addErrors.mDependentLocality.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mOrganization.WasPassed() &&
|
||||
!addErrors.mOrganization.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mPhone.WasPassed() && !addErrors.mPhone.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mPostalCode.WasPassed() &&
|
||||
!addErrors.mPostalCode.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mRecipient.WasPassed() &&
|
||||
!addErrors.mRecipient.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mRegion.WasPassed() &&
|
||||
!addErrors.mRegion.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mRegionCode.WasPassed() &&
|
||||
!addErrors.mRegionCode.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (addErrors.mSortingCode.WasPassed() &&
|
||||
!addErrors.mSortingCode.Value().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_DOM_ABORT_ERR;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PaymentResponse::Notify(nsITimer *timer)
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
const nsAString& aRequestId,
|
||||
const nsAString& aMethodName,
|
||||
const nsAString& aShippingOption,
|
||||
RefPtr<PaymentAddress> aShippingAddress,
|
||||
PaymentAddress* aShippingAddress,
|
||||
const nsAString& aDetails,
|
||||
const nsAString& aPayerName,
|
||||
const nsAString& aPayerEmail,
|
||||
@ -69,9 +69,24 @@ public:
|
||||
|
||||
void RespondComplete();
|
||||
|
||||
already_AddRefed<Promise> Retry(JSContext* aCx,
|
||||
const PaymentValidationErrors& errorField,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void RespondRetry(const nsAString& aMethodName,
|
||||
const nsAString& aShippingOption,
|
||||
PaymentAddress* aShippingAddress,
|
||||
const nsAString& aDetails,
|
||||
const nsAString& aPayerName,
|
||||
const nsAString& aPayerEmail,
|
||||
const nsAString& aPayerPhone);
|
||||
void RejectRetry(nsresult aRejectReason);
|
||||
|
||||
protected:
|
||||
~PaymentResponse();
|
||||
|
||||
nsresult ValidatePaymentValidationErrors(const PaymentValidationErrors& aErrors);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsPIDOMWindowInner> mOwner;
|
||||
bool mCompleteCalled;
|
||||
@ -89,6 +104,8 @@ private:
|
||||
// Timer for timing out if the page doesn't call
|
||||
// complete()
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
// Promise for "PaymentResponse::Retry"
|
||||
RefPtr<Promise> mRetryPromise;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -56,6 +56,8 @@ struct IPCPaymentDetails
|
||||
IPCPaymentDetailsModifier[] modifiers;
|
||||
nsString error;
|
||||
nsString shippingAddressErrors;
|
||||
nsString payerErrors;
|
||||
nsString paymentMethodErrors;
|
||||
};
|
||||
|
||||
struct IPCPaymentOptions
|
||||
@ -110,6 +112,15 @@ struct IPCPaymentCloseActionRequest
|
||||
nsString requestId;
|
||||
};
|
||||
|
||||
struct IPCPaymentRetryActionRequest
|
||||
{
|
||||
nsString requestId;
|
||||
nsString error;
|
||||
nsString payerErrors;
|
||||
nsString paymentMethodErrors;
|
||||
nsString shippingAddressErrors;
|
||||
};
|
||||
|
||||
union IPCPaymentActionRequest
|
||||
{
|
||||
IPCPaymentCreateActionRequest;
|
||||
@ -119,6 +130,7 @@ union IPCPaymentActionRequest
|
||||
IPCPaymentCompleteActionRequest;
|
||||
IPCPaymentUpdateActionRequest;
|
||||
IPCPaymentCloseActionRequest;
|
||||
IPCPaymentRetryActionRequest;
|
||||
};
|
||||
|
||||
struct IPCPaymentCanMakeActionResponse
|
||||
|
@ -7,21 +7,20 @@
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsIPaymentRequestService.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "PaymentRequestData.h"
|
||||
#include "PaymentRequestParent.h"
|
||||
#include "PaymentRequestService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(PaymentRequestParent, nsIPaymentActionCallback)
|
||||
|
||||
PaymentRequestParent::PaymentRequestParent(uint64_t aTabId)
|
||||
: mActorAlive(true)
|
||||
, mTabId(aTabId)
|
||||
, mRequestId(EmptyString())
|
||||
{
|
||||
}
|
||||
|
||||
@ -31,151 +30,75 @@ PaymentRequestParent::RecvRequestPayment(const IPCPaymentActionRequest& aRequest
|
||||
if (!mActorAlive) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
nsCOMPtr<nsIPaymentActionRequest> action;
|
||||
nsresult rv;
|
||||
switch (aRequest.type()) {
|
||||
case IPCPaymentActionRequest::TIPCPaymentCreateActionRequest: {
|
||||
case IPCPaymentActionRequest::TIPCPaymentCreateActionRequest:{
|
||||
const IPCPaymentCreateActionRequest& request = aRequest;
|
||||
|
||||
nsCOMPtr<nsIMutableArray> methodData = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
MOZ_ASSERT(methodData);
|
||||
for (IPCPaymentMethodData data : request.methodData()) {
|
||||
nsCOMPtr<nsIPaymentMethodData> method;
|
||||
rv = payments::PaymentMethodData::Create(data, getter_AddRefs(method));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
rv = methodData->AppendElement(method);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPaymentDetails> details;
|
||||
rv = payments::PaymentDetails::Create(request.details(), getter_AddRefs(details));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPaymentOptions> options;
|
||||
rv = payments::PaymentOptions::Create(request.options(), getter_AddRefs(options));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPaymentCreateActionRequest> createAction =
|
||||
do_CreateInstance(NS_PAYMENT_CREATE_ACTION_REQUEST_CONTRACT_ID);
|
||||
if (NS_WARN_IF(!createAction)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
rv = createAction->InitRequest(request.requestId(),
|
||||
this,
|
||||
mTabId,
|
||||
request.topLevelPrincipal(),
|
||||
methodData,
|
||||
details,
|
||||
options,
|
||||
request.shippingOption());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
action = do_QueryInterface(createAction);
|
||||
MOZ_ASSERT(action);
|
||||
mRequestId = request.requestId();
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentCanMakeActionRequest: {
|
||||
case IPCPaymentActionRequest::TIPCPaymentCanMakeActionRequest:{
|
||||
const IPCPaymentCanMakeActionRequest& request = aRequest;
|
||||
rv = CreateActionRequest(request.requestId(),
|
||||
nsIPaymentActionRequest::CANMAKE_ACTION,
|
||||
getter_AddRefs(action));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
mRequestId = request.requestId();
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentShowActionRequest: {
|
||||
case IPCPaymentActionRequest::TIPCPaymentShowActionRequest:{
|
||||
const IPCPaymentShowActionRequest& request = aRequest;
|
||||
rv = CreateActionRequest(request.requestId(),
|
||||
nsIPaymentActionRequest::SHOW_ACTION,
|
||||
getter_AddRefs(action));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
mRequestId = request.requestId();
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentAbortActionRequest: {
|
||||
const IPCPaymentAbortActionRequest& request = aRequest;
|
||||
rv = CreateActionRequest(request.requestId(),
|
||||
nsIPaymentActionRequest::ABORT_ACTION,
|
||||
getter_AddRefs(action));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
mRequestId = request.requestId();
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentCompleteActionRequest: {
|
||||
const IPCPaymentCompleteActionRequest& request = aRequest;
|
||||
nsCOMPtr<nsIPaymentCompleteActionRequest> completeAction =
|
||||
do_CreateInstance(NS_PAYMENT_COMPLETE_ACTION_REQUEST_CONTRACT_ID);
|
||||
rv = completeAction->InitRequest(request.requestId(),
|
||||
this,
|
||||
request.completeStatus());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
action = do_QueryInterface(completeAction);
|
||||
MOZ_ASSERT(action);
|
||||
mRequestId = request.requestId();
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
|
||||
const IPCPaymentUpdateActionRequest& request = aRequest;
|
||||
|
||||
nsCOMPtr<nsIPaymentDetails> details;
|
||||
rv = payments::PaymentDetails::Create(request.details(), getter_AddRefs(details));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPaymentUpdateActionRequest> updateAction =
|
||||
do_CreateInstance(NS_PAYMENT_UPDATE_ACTION_REQUEST_CONTRACT_ID);
|
||||
rv = updateAction->InitRequest(request.requestId(),
|
||||
this,
|
||||
details,
|
||||
request.shippingOption());
|
||||
action = do_QueryInterface(updateAction);
|
||||
MOZ_ASSERT(action);
|
||||
mRequestId = request.requestId();
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionRequest::TIPCPaymentCloseActionRequest: {
|
||||
const IPCPaymentCloseActionRequest& request = aRequest;
|
||||
rv = CreateActionRequest(request.requestId(),
|
||||
nsIPaymentActionRequest::CLOSE_ACTION,
|
||||
getter_AddRefs(action));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
mRequestId = request.requestId();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return IPC_FAIL(this, "Unexpected request type");
|
||||
case IPCPaymentActionRequest::TIPCPaymentRetryActionRequest: {
|
||||
const IPCPaymentRetryActionRequest& request = aRequest;
|
||||
mRequestId = request.requestId();
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
return IPC_FAIL(this, "Unknown PaymentRequest action type");
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIPaymentRequestService> service =
|
||||
do_GetService(NS_PAYMENT_REQUEST_SERVICE_CONTRACT_ID);
|
||||
MOZ_ASSERT(service);
|
||||
rv = service->RequestPayment(action);
|
||||
PaymentRequestService* rowService =
|
||||
static_cast<PaymentRequestService*>(service.get());
|
||||
MOZ_ASSERT(rowService);
|
||||
nsresult rv = rowService->RequestPayment(mRequestId, aRequest, this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL(this, "nsIPaymentRequestService::RequestPayment failed");
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
uint64_t
|
||||
PaymentRequestParent::GetTabId()
|
||||
{
|
||||
return mTabId;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestParent::RespondPayment(nsIPaymentActionResponse* aResponse)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIPaymentActionCallback> self = this;
|
||||
RefPtr<PaymentRequestParent> self = this;
|
||||
nsCOMPtr<nsIPaymentActionResponse> response = aResponse;
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("PaymentRequestParent::RespondPayment",
|
||||
[self, response] ()
|
||||
@ -268,12 +191,12 @@ PaymentRequestParent::RespondPayment(nsIPaymentActionResponse* aResponse)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
PaymentRequestParent::ChangeShippingAddress(const nsAString& aRequestId,
|
||||
nsIPaymentAddress* aAddress)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIPaymentActionCallback> self = this;
|
||||
RefPtr<PaymentRequestParent> self = this;
|
||||
nsCOMPtr<nsIPaymentAddress> address = aAddress;
|
||||
nsAutoString requestId(aRequestId);
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("dom::PaymentRequestParent::ChangeShippingAddress",
|
||||
@ -350,12 +273,12 @@ PaymentRequestParent::ChangeShippingAddress(const nsAString& aRequestId,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
PaymentRequestParent::ChangeShippingOption(const nsAString& aRequestId,
|
||||
const nsAString& aOption)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIPaymentActionCallback> self = this;
|
||||
RefPtr<PaymentRequestParent> self = this;
|
||||
nsAutoString requestId(aRequestId);
|
||||
nsAutoString option(aOption);
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("dom::PaymentRequestParent::ChangeShippingOption",
|
||||
@ -390,28 +313,20 @@ PaymentRequestParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
nsCOMPtr<nsIPaymentRequestService> service =
|
||||
do_GetService(NS_PAYMENT_REQUEST_SERVICE_CONTRACT_ID);
|
||||
MOZ_ASSERT(service);
|
||||
nsresult rv = service->RemoveActionCallback(this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_ASSERT(false);
|
||||
if (!mRequestId.Equals(EmptyString())) {
|
||||
nsCOMPtr<nsIPaymentRequest> request;
|
||||
nsresult rv = service->GetPaymentRequestById(mRequestId, getter_AddRefs(request));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
payments::PaymentRequest* rowRequest =
|
||||
static_cast<payments::PaymentRequest*>(request.get());
|
||||
MOZ_ASSERT(rowRequest);
|
||||
rowRequest->SetIPC(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestParent::CreateActionRequest(const nsAString& aRequestId,
|
||||
uint32_t aActionType,
|
||||
nsIPaymentActionRequest** aAction)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAction);
|
||||
nsCOMPtr<nsIPaymentActionRequest> action =
|
||||
do_CreateInstance(NS_PAYMENT_ACTION_REQUEST_CONTRACT_ID);
|
||||
MOZ_ASSERT(action);
|
||||
nsresult rv = action->Init(aRequestId, aActionType, this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
action.forget(aAction);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // end of namespace dom
|
||||
} // end of namespace mozilla
|
||||
|
@ -8,19 +8,25 @@
|
||||
#define mozilla_dom_PaymentRequestParent_h
|
||||
|
||||
#include "mozilla/dom/PPaymentRequestParent.h"
|
||||
#include "nsIPaymentActionRequest.h"
|
||||
#include "nsIPaymentAddress.h"
|
||||
#include "nsIPaymentActionResponse.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class PaymentRequestParent final : public nsIPaymentActionCallback
|
||||
, public PPaymentRequestParent
|
||||
class PaymentRequestParent final : public PPaymentRequestParent
|
||||
{
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIPAYMENTACTIONCALLBACK
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(PaymentRequestParent)
|
||||
public:
|
||||
explicit PaymentRequestParent(uint64_t aTabId);
|
||||
|
||||
uint64_t GetTabId();
|
||||
nsresult RespondPayment(nsIPaymentActionResponse* aResponse);
|
||||
nsresult ChangeShippingAddress(const nsAString& aRequestId,
|
||||
nsIPaymentAddress* aAddress);
|
||||
nsresult ChangeShippingOption(const nsAString& aRequestId,
|
||||
const nsAString& aOption);
|
||||
|
||||
protected:
|
||||
mozilla::ipc::IPCResult
|
||||
RecvRequestPayment(const IPCPaymentActionRequest& aRequest) override;
|
||||
@ -31,12 +37,9 @@ protected:
|
||||
private:
|
||||
~PaymentRequestParent() = default;
|
||||
|
||||
nsresult CreateActionRequest(const nsAString& aRequestId,
|
||||
uint32_t aActionType,
|
||||
nsIPaymentActionRequest** aAction);
|
||||
|
||||
bool mActorAlive;
|
||||
uint64_t mTabId;
|
||||
nsString mRequestId;
|
||||
};
|
||||
|
||||
} // end of namespace dom
|
||||
|
@ -24,7 +24,6 @@ EXPORTS.mozilla.dom += [
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'BasicCardPayment.cpp',
|
||||
'PaymentActionRequest.cpp',
|
||||
'PaymentActionResponse.cpp',
|
||||
'PaymentAddress.cpp',
|
||||
'PaymentMethodChangeEvent.cpp',
|
||||
|
182
dom/payments/test/RetryPaymentChromeScript.js
Normal file
182
dom/payments/test/RetryPaymentChromeScript.js
Normal file
@ -0,0 +1,182 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"].getService(Ci.nsIPaymentRequestService);
|
||||
|
||||
function emitTestFail(message) {
|
||||
sendAsyncMessage("test-fail", message);
|
||||
}
|
||||
function emitTestPass(message) {
|
||||
sendAsyncMessage("test-pass", message);
|
||||
}
|
||||
|
||||
const billingAddress = Cc["@mozilla.org/dom/payments/payment-address;1"].
|
||||
createInstance(Ci.nsIPaymentAddress);
|
||||
const addressLine = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
|
||||
const address = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
||||
address.data = "Easton Ave";
|
||||
addressLine.appendElement(address);
|
||||
billingAddress.init("USA", // country
|
||||
addressLine, // address line
|
||||
"CA", // region
|
||||
"San Bruno", // city
|
||||
"", // dependent locality
|
||||
"94066", // postal code
|
||||
"123456", // sorting code
|
||||
"", // organization
|
||||
"Bill A. Pacheco", // recipient
|
||||
"+14344413879"); // phone
|
||||
|
||||
function acceptPayment(requestId, mode) {
|
||||
const basiccardResponseData = Cc["@mozilla.org/dom/payments/basiccard-response-data;1"].
|
||||
createInstance(Ci.nsIBasicCardResponseData);
|
||||
const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
|
||||
createInstance(Ci.nsIPaymentShowActionResponse);
|
||||
basiccardResponseData.initData("Bill A. Pacheco", // cardholderName
|
||||
"4916855166538720", // cardNumber
|
||||
"01", // expiryMonth
|
||||
"2024", // expiryYear
|
||||
"180", // cardSecurityCode
|
||||
billingAddress); // billingAddress
|
||||
if (mode === "show") {
|
||||
showResponse.init(requestId,
|
||||
Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
|
||||
"basic-card", // payment method
|
||||
basiccardResponseData,// payment method data
|
||||
"Bill A. Pacheco", // payer name
|
||||
"", // payer email
|
||||
""); // payer phone
|
||||
}
|
||||
if (mode == "retry") {
|
||||
showResponse.init(requestId,
|
||||
Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
|
||||
"basic-card", // payment method
|
||||
basiccardResponseData,// payment method data
|
||||
"Bill A. Pacheco", // payer name
|
||||
"bpacheco@test.org", // payer email
|
||||
"+123456789"); // payer phone
|
||||
}
|
||||
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
|
||||
}
|
||||
|
||||
function rejectPayment(requestId) {
|
||||
const responseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
|
||||
createInstance(Ci.nsIGeneralResponseData);
|
||||
responseData.initData({});
|
||||
const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
|
||||
createInstance(Ci.nsIPaymentShowActionResponse);
|
||||
showResponse.init(requestId,
|
||||
Ci.nsIPaymentActionResponse.PAYMENT_REJECTED,
|
||||
"", // payment method
|
||||
responseData, // payment method data
|
||||
"", // payer name
|
||||
"", // payer email
|
||||
""); // payer phone
|
||||
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
|
||||
}
|
||||
|
||||
function checkAddressErrors(testName, errors) {
|
||||
if (!errors) {
|
||||
emitTestFail(`${testName}: Expect non-null shippingAddressErrors, but got null.`);
|
||||
return;
|
||||
}
|
||||
for (const [key, msg] of Object.entries(errors)) {
|
||||
const expected = `${key} error`;
|
||||
if (msg !== expected) {
|
||||
emitTestFail(
|
||||
`${testName}: Expected '${expected}' on shippingAddressErrors.${key}, but got '${msg}'.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkPayerErrors(testName, errors) {
|
||||
if (!errors) {
|
||||
emitTestFail(`${testName}: Expect non-null payerErrors, but got null.`);
|
||||
return;
|
||||
}
|
||||
for (const [key, msg] of Object.entries(errors)) {
|
||||
const expected = `${key} error`;
|
||||
if (msg !== expected) {
|
||||
emitTestFail(`${testName}: Expected '${expected}' on payerErrors.${key}, but got '${msg}'.`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkPaymentMethodErrors(testName, errors) {
|
||||
if (!errors) {
|
||||
emitTestFail(`${testName} :Expect non-null payerMethodErrors, but got null.`);
|
||||
return;
|
||||
}
|
||||
for (const [key, msg] of Object.entries(errors)) {
|
||||
const expected = `method ${key} error`;
|
||||
if (msg !== expected) {
|
||||
emitTestFail(
|
||||
`${testName}: Expected '${expected}' on paymentMethodErrors.${key}, but got '${msg}'.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DummyUIService = {
|
||||
testName: "",
|
||||
rejectRetry: false,
|
||||
showPayment(requestId) {
|
||||
acceptPayment(requestId, "show");
|
||||
},
|
||||
abortPaymen(requestId) {
|
||||
respondRequestId = requestId
|
||||
},
|
||||
completePayment(requestId) {
|
||||
let completeResponse = Cc["@mozilla.org/dom/payments/payment-complete-action-response;1"].
|
||||
createInstance(Ci.nsIPaymentCompleteActionResponse);
|
||||
completeResponse.init(requestId, Ci.nsIPaymentActionResponse.COMPLETE_SUCCEEDED);
|
||||
paymentSrv.respondPayment(completeResponse.QueryInterface(Ci.nsIPaymentActionResponse));
|
||||
},
|
||||
updatePayment(requestId) {
|
||||
const payment = paymentSrv.getPaymentRequestById(requestId);
|
||||
if (payment.paymentDetails.error !== "error") {
|
||||
emitTestFail("Expect 'error' on details.error, but got '" +
|
||||
payment.paymentDetails.error + "'");
|
||||
}
|
||||
checkAddressErrors(this.testName, payment.paymentDetails.shippingAddressErrors)
|
||||
checkPayerErrors(this.testName, payment.paymentDetails.payer);
|
||||
checkPaymentMethodErrors(this.testName, payment.paymentDetails.paymentMethod);
|
||||
if (this.rejectRetry) {
|
||||
rejectPayment(requestId);
|
||||
} else {
|
||||
acceptPayment(requestId, "retry");
|
||||
}
|
||||
},
|
||||
closePayment: (requestId) => {respondRequestId = requestId},
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
|
||||
};
|
||||
|
||||
paymentSrv.setTestingUIService(DummyUIService.QueryInterface(Ci.nsIPaymentUIService));
|
||||
|
||||
addMessageListener("start-test", function(testName) {
|
||||
DummyUIService.testName = testName;
|
||||
sendAsyncMessage("start-test-complete");
|
||||
});
|
||||
|
||||
addMessageListener("finish-test", function() {
|
||||
DummyUIService.testName = "";
|
||||
sendAsyncMessage("finish-test-complete");
|
||||
});
|
||||
|
||||
addMessageListener("reject-retry", function() {
|
||||
DummyUIService.rejectRetry = true;
|
||||
sendAsyncMessage("reject-retry-complete");
|
||||
});
|
||||
|
||||
addMessageListener("teardown", function() {
|
||||
paymentSrv.setTestingUIService(null);
|
||||
sendAsyncMessage('teardown-complete');
|
||||
});
|
@ -14,6 +14,7 @@ support-files =
|
||||
GeneralChromeScript.js
|
||||
PMIValidationChromeScript.js
|
||||
RequestShippingChromeScript.js
|
||||
RetryPaymentChromeScript.js
|
||||
ShippingOptionsChromeScript.js
|
||||
ShowPaymentChromeScript.js
|
||||
UpdateErrorsChromeScript.js
|
||||
@ -33,6 +34,7 @@ skip-if = (verify && debug)
|
||||
[test_pmi_validation.html]
|
||||
skip-if = (verify && debug)
|
||||
[test_requestShipping.html]
|
||||
[test_retryPayment.html]
|
||||
[test_shippingOptions.html]
|
||||
[test_showPayment.html]
|
||||
[test_update_errors.html]
|
||||
|
354
dom/payments/test/test_retryPayment.html
Normal file
354
dom/payments/test/test_retryPayment.html
Normal file
@ -0,0 +1,354 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1435161
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for retry PaymentRequest</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="DefaultData.js"></script>
|
||||
<script type="application/javascript">
|
||||
|
||||
"use strict";
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const gUrl = SimpleTest.getTestFileURL('RetryPaymentChromeScript.js');
|
||||
const gScript = SpecialPowers.loadChromeScript(gUrl);
|
||||
|
||||
function testFailHandler(message) {
|
||||
ok(false, message);
|
||||
}
|
||||
function testPassHandler(message) {
|
||||
ok(true, message);
|
||||
}
|
||||
gScript.addMessageListener("test-fail", testFailHandler);
|
||||
gScript.addMessageListener("test-pass", testPassHandler);
|
||||
|
||||
async function requestChromeAction(action, params) {
|
||||
gScript.sendAsyncMessage(action, params);
|
||||
await new Promise(resolve => {
|
||||
gScript.addMessageListener(`${action}-complete`, function completeListener() {
|
||||
gScript.removeMessageListener(`${action}-complete`, completeListener);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const validationErrors = {
|
||||
error: "error",
|
||||
shippingAddress: {
|
||||
addressLine: "addressLine error",
|
||||
city: "city error",
|
||||
country: "country error",
|
||||
dependentLocality: "dependentLocality error",
|
||||
organization: "organization error",
|
||||
phone: "phone error",
|
||||
postalCode: "postalCode error",
|
||||
recipient: "recipient error",
|
||||
region: "region error",
|
||||
regionCode: "regionCode error",
|
||||
sortingCode: "sortingCode error",
|
||||
},
|
||||
payer: {
|
||||
name: "name error",
|
||||
email: "email error",
|
||||
phone: "phone error",
|
||||
},
|
||||
paymentMethod: {
|
||||
account: "method account error",
|
||||
password: "method password error",
|
||||
},
|
||||
};
|
||||
|
||||
const options = {
|
||||
requestPayerName: true,
|
||||
requestPayerEmail: true,
|
||||
reqeustPayerPhone: true,
|
||||
requestShipping: true,
|
||||
shippingType: "shipping"
|
||||
};
|
||||
|
||||
function checkShowResponse(testName, payResponse) {
|
||||
const { payerName, payerEmail, payerPhone } = payResponse.toJSON();
|
||||
is(
|
||||
payerName,
|
||||
"Bill A. Pacheco",
|
||||
`${testName}: Expected 'Bill A. Pacheco' on payerName, but got '${payerName}' after show PaymentRequest`
|
||||
);
|
||||
is(
|
||||
payerEmail,
|
||||
"",
|
||||
`${testName}: Expected '' on payerEmail, but got '${payerEmail}' after show PaymentRequest`
|
||||
);
|
||||
is(
|
||||
payerPhone,
|
||||
"",
|
||||
`${testName}: Expected '' on payerPhone, but got '${payerPhone}' after show PaymentRequest`
|
||||
);
|
||||
}
|
||||
|
||||
function checkRetryResponse(testName, payResponse) {
|
||||
const { payerName, payerEmail, payerPhone } = payResponse.toJSON();
|
||||
is(
|
||||
payerName,
|
||||
"Bill A. Pacheco",
|
||||
`${testName}: Expected 'Bill A. Pacheco' on payerName, but got '${payerName}' after retry PaymentRequest`
|
||||
);
|
||||
is(
|
||||
payerEmail,
|
||||
"bpacheco@test.org",
|
||||
`${testName} : Expected 'bpacheco@test.org' on payerEmail, but got '${payerEmail}' after retry PaymentRequest`
|
||||
);
|
||||
is(
|
||||
payerPhone,
|
||||
"+123456789",
|
||||
`${testName} : Expected '+123456789' on payerPhone, but got '${payerPhone}' after retry PaymentRequest`
|
||||
);
|
||||
}
|
||||
|
||||
function unexpectedErrMsg(testName, errName, timing) {
|
||||
return `${testName}: Unexpected error(${errName}) when ${timing} the PaymentRequest.`;
|
||||
}
|
||||
|
||||
function expectedErrMsg(testName, expectedErr, errName, timing) {
|
||||
return `${testName}: Expected '${expectedErr}' when ${timing} PaymentResponse, but got '${errName}'.`;
|
||||
}
|
||||
|
||||
async function testRetryAfterComplete() {
|
||||
const testName = "testRetryAfterComplete";
|
||||
await requestChromeAction("start-test", testName);
|
||||
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, options);
|
||||
ok(payRequest, testName + ": failed to create PaymentRequest.");
|
||||
if (!payRequest) {
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
|
||||
let payResponse;
|
||||
try {
|
||||
payResponse = await payRequest.show();
|
||||
await checkShowResponse(testName, payResponse);
|
||||
handler.destruct();
|
||||
} catch(err) {
|
||||
ok(false, unexpectedErrMsg(testName, err.Name, "showing"));
|
||||
await requestChromeAction("finish-test");
|
||||
handler.destruct();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await payResponse.complete("success");
|
||||
} catch(err) {
|
||||
let errName = err.Name;
|
||||
ok(false, unexpectedErrMsg(testName, err.Name, "completing"));
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await payResponse.retry(validationErrors);
|
||||
ok(false, `${testName}: Unexpected success when retry the PaymentResponse.`);
|
||||
return;
|
||||
} catch(err) {
|
||||
is(err.name,
|
||||
"InvalidStateError",
|
||||
expectedErrMsg(testName, "InvalidStateError", err.name, "retrying"));
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
await requestChromeAction("finish-test");
|
||||
}
|
||||
|
||||
async function testRetryAfterRetry() {
|
||||
const testName = "testRetryAfterRetry";
|
||||
await requestChromeAction("start-test", testName);
|
||||
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, options);
|
||||
ok(payRequest, testName + ": failed to create PaymentRequest.");
|
||||
if (!payRequest) {
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
|
||||
let payResponse;
|
||||
try {
|
||||
payResponse = await payRequest.show();
|
||||
await checkShowResponse(testName, payResponse);
|
||||
handler.destruct();
|
||||
} catch(err) {
|
||||
ok(false, unexpectedErrMsg(testName, err.name, "showing"));
|
||||
await requestChromeAction("finish-test");
|
||||
handler.destruct();
|
||||
return;
|
||||
}
|
||||
let retryPromise;
|
||||
try {
|
||||
retryPromise = payResponse.retry(validationErrors);
|
||||
await payResponse.retry(validationErrors);
|
||||
ok(false, `${testName}: Unexpected success when retry the PaymentResponse.`);
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
} catch(err) {
|
||||
is(err.name,
|
||||
"InvalidStateError",
|
||||
expectedErrMsg(testName, "InvalidStateError", err.name, "retrying"));
|
||||
}
|
||||
try {
|
||||
await retryPromise;
|
||||
await payResponse.complete("success");
|
||||
} catch(err) {
|
||||
ok(false, unexpectedErrMsg(testName, err.name, "completing"));
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
await requestChromeAction("finish-test");
|
||||
}
|
||||
|
||||
async function testRetryWithEmptyErrors() {
|
||||
const testName = "testRetryWithEmptyErrors";
|
||||
await requestChromeAction("start-test", testName);
|
||||
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, options);
|
||||
ok(payRequest, testName + ": failed to create PaymentRequest.");
|
||||
if (!payRequest) {
|
||||
requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
|
||||
let payResponse;
|
||||
try {
|
||||
payResponse = await payRequest.show();
|
||||
await checkShowResponse(testName, payResponse);
|
||||
handler.destruct();
|
||||
} catch(err) {
|
||||
ok(false, unexpectedErrMsg(testName, err.name, "showing"));
|
||||
await requestChromeAction("finish-test");
|
||||
handler.destruct();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await payResponse.retry();
|
||||
ok(false, `${testName}: Unexpected success when retry the PaymentResponse.`);
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
} catch(err) {
|
||||
is(err.name,
|
||||
"AbortError",
|
||||
expectedErrMsg(testName, "AbortError", err.name, "retrying"));
|
||||
}
|
||||
try {
|
||||
await payResponse.complete("success");
|
||||
} catch(err) {
|
||||
ok(false, unexpectedErrMsg(testName, err.name, "completing"));
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
await requestChromeAction("finish-test");
|
||||
}
|
||||
|
||||
async function testRetry() {
|
||||
const testName = "testRetry";
|
||||
await requestChromeAction("start-test", testName);
|
||||
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, options);
|
||||
ok(payRequest, testName + ": failed to create PaymentRequest.");
|
||||
if (!payRequest) {
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
|
||||
let payResponse;
|
||||
try {
|
||||
payResponse = await payRequest.show();
|
||||
await checkShowResponse(testName, payResponse);
|
||||
handler.destruct();
|
||||
} catch(err) {
|
||||
ok(false, unexpectedErrMsg(testName, err.name, "showing"));
|
||||
await requestChromeAction("finish-test");
|
||||
handler.destruct();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await payResponse.retry(validationErrors);
|
||||
await checkRetryResponse(testName, payResponse);
|
||||
await payResponse.complete("success");
|
||||
} catch(err) {
|
||||
ok(false, unexpectedErrMsg(testName, err.name, "retrying"));
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
await requestChromeAction("finish-test");
|
||||
}
|
||||
|
||||
async function testRetryAbortByUser() {
|
||||
const testName = "testRetryAbortByUser";
|
||||
await requestChromeAction("reject-retry");
|
||||
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, options);
|
||||
ok(payRequest, testName + ": failed to create PaymentRequest.");
|
||||
if (!payRequest) {
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
|
||||
let payResponse;
|
||||
try {
|
||||
payResponse = await payRequest.show();
|
||||
await checkShowResponse(testName, payResponse);
|
||||
handler.destruct();
|
||||
} catch(err) {
|
||||
ok(false, unexpectedErrMsg(testName, err.name, "showing"));
|
||||
handler.destruct();
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await payResponse.retry(validationErrors);
|
||||
ok(false, `${testName}: Unexpected success when retry the PaymentResponse.`);
|
||||
await requestChromeAction("finish-test");
|
||||
return;
|
||||
} catch(err) {
|
||||
is(err.name,
|
||||
"AbortError",
|
||||
expectedErrMsg(testName, "AbortError", err.name, "retrying"));
|
||||
}
|
||||
await requestChromeAction("finish-test");
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
return new Promise((resolve, reject) => {
|
||||
gScript.addMessageListener("teardown-complete", function teardownCompleteHandler() {
|
||||
gScript.removeMessageListener("teardown-complete", teardownCompleteHandler);
|
||||
gScript.removeMessageListener("test-fail", testFailHandler);
|
||||
gScript.removeMessageListener("test-pass", testPassHandler);
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
resolve();
|
||||
});
|
||||
gScript.sendAsyncMessage("teardown");
|
||||
});
|
||||
}
|
||||
|
||||
async function runTests() {
|
||||
try {
|
||||
await testRetryAfterComplete()
|
||||
await testRetryAfterRetry()
|
||||
await testRetryWithEmptyErrors()
|
||||
await testRetry()
|
||||
await testRetryAbortByUser()
|
||||
await teardown()
|
||||
} catch(e) {
|
||||
ok(false, "Unexpected error: " + e.name);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
['dom.payments.request.enabled', true],
|
||||
]
|
||||
}, runTests);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435161">Mozilla Bug 1435161</a>
|
||||
</body>
|
||||
</html>
|
@ -68,9 +68,24 @@ dictionary AddressErrors {
|
||||
DOMString sortingCode;
|
||||
};
|
||||
|
||||
dictionary PaymentValidationErrors {
|
||||
PayerErrorFields payer;
|
||||
AddressErrors shippingAddress;
|
||||
DOMString error;
|
||||
object paymentMethod;
|
||||
};
|
||||
|
||||
dictionary PayerErrorFields {
|
||||
DOMString email;
|
||||
DOMString name;
|
||||
DOMString phone;
|
||||
};
|
||||
|
||||
dictionary PaymentDetailsUpdate : PaymentDetailsBase {
|
||||
DOMString error;
|
||||
AddressErrors shippingAddressErrors;
|
||||
PayerErrorFields payerErrors;
|
||||
object paymentMethodErrors;
|
||||
PaymentItem total;
|
||||
};
|
||||
|
||||
|
@ -29,4 +29,8 @@ interface PaymentResponse {
|
||||
|
||||
[NewObject]
|
||||
Promise<void> complete(optional PaymentComplete result = "unknown");
|
||||
|
||||
// If the dictionary argument has no required members, it must be optional.
|
||||
[NewObject]
|
||||
Promise<void> retry(optional PaymentValidationErrors errorFields);
|
||||
};
|
||||
|
@ -7,8 +7,7 @@ function load()
|
||||
let textarea = document.getElementById("editor");
|
||||
textarea.focus();
|
||||
|
||||
SpecialPowers.Cu.import(
|
||||
"chrome://reftest/content/AsyncSpellCheckTestHelper.jsm")
|
||||
SpecialPowers.Cu.import("resource://reftest/AsyncSpellCheckTestHelper.jsm")
|
||||
.onSpellCheck(textarea, () => {
|
||||
let isc = SpecialPowers.wrap(textarea).editor.getInlineSpellChecker(false);
|
||||
let sc = isc.spellChecker;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://reftest/content/input.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://reftest/input.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
|
@ -130,15 +130,15 @@ impl GlyphCache {
|
||||
where
|
||||
for<'r> F: Fn(&'r &FontInstance) -> bool,
|
||||
{
|
||||
let caches_to_destroy = self.glyph_key_caches
|
||||
.keys()
|
||||
.filter(&key_fun)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
for key in caches_to_destroy {
|
||||
let mut cache = self.glyph_key_caches.remove(&key).unwrap();
|
||||
self.glyph_key_caches.retain(|k, cache| {
|
||||
let should_clear = key_fun(&k);
|
||||
if !should_clear {
|
||||
return true;
|
||||
}
|
||||
|
||||
cache.clear();
|
||||
}
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
// Clear out evicted entries from glyph key caches and, if possible,
|
||||
|
@ -97,12 +97,6 @@ struct Document {
|
||||
// A set of pipelines that the caller has requested be
|
||||
// made available as output textures.
|
||||
output_pipelines: FastHashSet<PipelineId>,
|
||||
// A helper switch to prevent any frames rendering triggered by scrolling
|
||||
// messages between `SetDisplayList` and `GenerateFrame`.
|
||||
// If we allow them, then a reftest that scrolls a few layers before generating
|
||||
// the first frame would produce inconsistent rendering results, because
|
||||
// scroll events are not necessarily received in deterministic order.
|
||||
render_on_scroll: Option<bool>,
|
||||
|
||||
/// A data structure to allow hit testing against rendered frames. This is updated
|
||||
/// every time we produce a fully rendered frame.
|
||||
@ -117,14 +111,8 @@ impl Document {
|
||||
pub fn new(
|
||||
window_size: DeviceUintSize,
|
||||
layer: DocumentLayer,
|
||||
enable_render_on_scroll: bool,
|
||||
default_device_pixel_ratio: f32,
|
||||
) -> Self {
|
||||
let render_on_scroll = if enable_render_on_scroll {
|
||||
Some(false)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Document {
|
||||
scene: Scene::new(),
|
||||
removed_pipelines: Vec::new(),
|
||||
@ -141,7 +129,6 @@ impl Document {
|
||||
frame_id: FrameId(0),
|
||||
frame_builder: None,
|
||||
output_pipelines: FastHashSet::default(),
|
||||
render_on_scroll,
|
||||
hit_tester: None,
|
||||
dynamic_properties: SceneProperties::new(),
|
||||
}
|
||||
@ -173,7 +160,6 @@ impl Document {
|
||||
FrameMsg::Scroll(delta, cursor) => {
|
||||
profile_scope!("Scroll");
|
||||
|
||||
let mut should_render = true;
|
||||
let node_index = match self.hit_tester {
|
||||
Some(ref hit_tester) => {
|
||||
// Ideally we would call self.scroll_nearest_scrolling_ancestor here, but
|
||||
@ -182,20 +168,18 @@ impl Document {
|
||||
hit_tester.find_node_under_point(test)
|
||||
}
|
||||
None => {
|
||||
should_render = false;
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let should_render =
|
||||
should_render &&
|
||||
self.scroll_nearest_scrolling_ancestor(delta, node_index) &&
|
||||
self.render_on_scroll == Some(true);
|
||||
if self.hit_tester.is_some() {
|
||||
let _scrolled = self.scroll_nearest_scrolling_ancestor(delta, node_index);
|
||||
}
|
||||
|
||||
return DocumentOps {
|
||||
// TODO: Does it make sense to track this as a scrolling even if we
|
||||
// ended up not scrolling anything?
|
||||
scroll: true,
|
||||
build_frame: should_render,
|
||||
render_frame: should_render,
|
||||
..DocumentOps::nop()
|
||||
};
|
||||
}
|
||||
@ -216,13 +200,10 @@ impl Document {
|
||||
FrameMsg::ScrollNodeWithId(origin, id, clamp) => {
|
||||
profile_scope!("ScrollNodeWithScrollId");
|
||||
|
||||
let should_render = self.scroll_node(origin, id, clamp)
|
||||
&& self.render_on_scroll == Some(true);
|
||||
let _scrolled = self.scroll_node(origin, id, clamp);
|
||||
|
||||
return DocumentOps {
|
||||
scroll: true,
|
||||
build_frame: should_render,
|
||||
render_frame: should_render,
|
||||
..DocumentOps::nop()
|
||||
};
|
||||
}
|
||||
@ -350,7 +331,6 @@ static NEXT_NAMESPACE_ID: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
struct PlainRenderBackend {
|
||||
default_device_pixel_ratio: f32,
|
||||
enable_render_on_scroll: bool,
|
||||
frame_config: FrameBuilderConfig,
|
||||
documents: FastHashMap<DocumentId, DocumentView>,
|
||||
resources: PlainResources,
|
||||
@ -384,7 +364,6 @@ pub struct RenderBackend {
|
||||
sampler: Option<Box<AsyncPropertySampler + Send>>,
|
||||
|
||||
last_scene_id: u64,
|
||||
enable_render_on_scroll: bool,
|
||||
}
|
||||
|
||||
impl RenderBackend {
|
||||
@ -401,7 +380,6 @@ impl RenderBackend {
|
||||
frame_config: FrameBuilderConfig,
|
||||
recorder: Option<Box<ApiRecordingReceiver>>,
|
||||
sampler: Option<Box<AsyncPropertySampler + Send>>,
|
||||
enable_render_on_scroll: bool,
|
||||
) -> RenderBackend {
|
||||
// The namespace_id should start from 1.
|
||||
NEXT_NAMESPACE_ID.fetch_add(1, Ordering::Relaxed);
|
||||
@ -423,7 +401,6 @@ impl RenderBackend {
|
||||
recorder,
|
||||
sampler,
|
||||
last_scene_id: 0,
|
||||
enable_render_on_scroll,
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,10 +484,6 @@ impl RenderBackend {
|
||||
content_size,
|
||||
});
|
||||
|
||||
if let Some(ref mut ros) = doc.render_on_scroll {
|
||||
*ros = false; //wait for `GenerateFrame`
|
||||
}
|
||||
|
||||
// Note: this isn't quite right as auxiliary values will be
|
||||
// pulled out somewhere in the prim_store, but aux values are
|
||||
// really simple and cheap to access, so it's not a big deal.
|
||||
@ -597,18 +570,16 @@ impl RenderBackend {
|
||||
self.resource_cache.set_blob_rasterizer(rasterizer);
|
||||
}
|
||||
|
||||
if txn.build_frame || !txn.resource_updates.is_empty() || !txn.frame_ops.is_empty() {
|
||||
self.update_document(
|
||||
self.update_document(
|
||||
txn.document_id,
|
||||
replace(&mut txn.resource_updates, Vec::new()),
|
||||
replace(&mut txn.frame_ops, Vec::new()),
|
||||
txn.build_frame,
|
||||
txn.render_frame,
|
||||
&mut frame_counter,
|
||||
&mut profile_counters,
|
||||
has_built_scene,
|
||||
);
|
||||
}
|
||||
replace(&mut txn.resource_updates, Vec::new()),
|
||||
replace(&mut txn.frame_ops, Vec::new()),
|
||||
txn.build_frame,
|
||||
txn.render_frame,
|
||||
&mut frame_counter,
|
||||
&mut profile_counters,
|
||||
has_built_scene,
|
||||
);
|
||||
},
|
||||
SceneBuilderResult::FlushComplete(tx) => {
|
||||
tx.send(()).ok();
|
||||
@ -704,7 +675,6 @@ impl RenderBackend {
|
||||
let document = Document::new(
|
||||
initial_size,
|
||||
layer,
|
||||
self.enable_render_on_scroll,
|
||||
self.default_device_pixel_ratio,
|
||||
);
|
||||
self.documents.insert(document_id, document);
|
||||
@ -720,14 +690,7 @@ impl RenderBackend {
|
||||
}
|
||||
ApiMsg::ClearNamespace(namespace_id) => {
|
||||
self.resource_cache.clear_namespace(namespace_id);
|
||||
let document_ids = self.documents
|
||||
.keys()
|
||||
.filter(|did| did.0 == namespace_id)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
for document in document_ids {
|
||||
self.documents.remove(&document);
|
||||
}
|
||||
self.documents.retain(|did, _doc| did.0 != namespace_id);
|
||||
}
|
||||
ApiMsg::MemoryPressure => {
|
||||
// This is drastic. It will basically flush everything out of the cache,
|
||||
@ -956,12 +919,6 @@ impl RenderBackend {
|
||||
build_frame = true;
|
||||
}
|
||||
|
||||
if render_frame {
|
||||
if let Some(ref mut ros) = doc.render_on_scroll {
|
||||
*ros = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !doc.can_render() {
|
||||
// TODO: this happens if we are building the first scene asynchronously and
|
||||
// scroll at the same time. we should keep track of the fact that we skipped
|
||||
@ -1225,7 +1182,6 @@ impl RenderBackend {
|
||||
info!("\tbackend");
|
||||
let backend = PlainRenderBackend {
|
||||
default_device_pixel_ratio: self.default_device_pixel_ratio,
|
||||
enable_render_on_scroll: self.enable_render_on_scroll,
|
||||
frame_config: self.frame_config.clone(),
|
||||
documents: self.documents
|
||||
.iter()
|
||||
@ -1290,7 +1246,6 @@ impl RenderBackend {
|
||||
self.documents.clear();
|
||||
self.default_device_pixel_ratio = backend.default_device_pixel_ratio;
|
||||
self.frame_config = backend.frame_config;
|
||||
self.enable_render_on_scroll = backend.enable_render_on_scroll;
|
||||
|
||||
let mut scenes_to_build = Vec::new();
|
||||
|
||||
@ -1309,7 +1264,6 @@ impl RenderBackend {
|
||||
frame_id: FrameId(0),
|
||||
frame_builder: Some(FrameBuilder::empty()),
|
||||
output_pipelines: FastHashSet::default(),
|
||||
render_on_scroll: None,
|
||||
dynamic_properties: SceneProperties::new(),
|
||||
hit_tester: None,
|
||||
};
|
||||
|
@ -458,48 +458,6 @@ pub(crate) mod desc {
|
||||
],
|
||||
};
|
||||
|
||||
pub const BORDER_CORNER_DASH_AND_DOT: VertexDescriptor = VertexDescriptor {
|
||||
vertex_attributes: &[
|
||||
VertexAttribute {
|
||||
name: "aPosition",
|
||||
count: 2,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
],
|
||||
instance_attributes: &[
|
||||
VertexAttribute {
|
||||
name: "aClipRenderTaskAddress",
|
||||
count: 1,
|
||||
kind: VertexAttributeKind::I32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aScrollNodeId",
|
||||
count: 1,
|
||||
kind: VertexAttributeKind::I32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aClipSegment",
|
||||
count: 1,
|
||||
kind: VertexAttributeKind::I32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aClipDataResourceAddress",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::U16,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aDashOrDot0",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aDashOrDot1",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
pub const GPU_CACHE_UPDATE: VertexDescriptor = VertexDescriptor {
|
||||
vertex_attributes: &[
|
||||
VertexAttribute {
|
||||
@ -1349,7 +1307,6 @@ pub struct RendererVAOs {
|
||||
prim_vao: VAO,
|
||||
blur_vao: VAO,
|
||||
clip_vao: VAO,
|
||||
dash_and_dot_vao: VAO,
|
||||
border_vao: VAO,
|
||||
}
|
||||
|
||||
@ -1646,8 +1603,6 @@ impl Renderer {
|
||||
let clip_vao = device.create_vao_with_new_instances(&desc::CLIP, &prim_vao);
|
||||
let border_vao =
|
||||
device.create_vao_with_new_instances(&desc::BORDER, &prim_vao);
|
||||
let dash_and_dot_vao =
|
||||
device.create_vao_with_new_instances(&desc::BORDER_CORNER_DASH_AND_DOT, &prim_vao);
|
||||
let texture_cache_upload_pbo = device.create_pbo();
|
||||
|
||||
let texture_resolver = SourceTextureResolver::new(&mut device);
|
||||
@ -1710,7 +1665,6 @@ impl Renderer {
|
||||
Arc::new(worker.unwrap())
|
||||
});
|
||||
let sampler = options.sampler;
|
||||
let enable_render_on_scroll = options.enable_render_on_scroll;
|
||||
|
||||
let blob_image_handler = options.blob_image_handler.take();
|
||||
let thread_listener_for_render_backend = thread_listener.clone();
|
||||
@ -1792,7 +1746,6 @@ impl Renderer {
|
||||
config,
|
||||
recorder,
|
||||
sampler,
|
||||
enable_render_on_scroll,
|
||||
);
|
||||
backend.run(backend_profile_counters);
|
||||
if let Some(ref thread_listener) = *thread_listener_for_render_backend {
|
||||
@ -1836,7 +1789,6 @@ impl Renderer {
|
||||
prim_vao,
|
||||
blur_vao,
|
||||
clip_vao,
|
||||
dash_and_dot_vao,
|
||||
border_vao,
|
||||
},
|
||||
transforms_texture,
|
||||
@ -4060,7 +4012,6 @@ impl Renderer {
|
||||
self.device.delete_vao(self.vaos.prim_vao);
|
||||
self.device.delete_vao(self.vaos.clip_vao);
|
||||
self.device.delete_vao(self.vaos.blur_vao);
|
||||
self.device.delete_vao(self.vaos.dash_and_dot_vao);
|
||||
self.device.delete_vao(self.vaos.border_vao);
|
||||
|
||||
#[cfg(feature = "debug_renderer")]
|
||||
@ -4240,7 +4191,6 @@ pub struct RendererOptions {
|
||||
pub blob_image_handler: Option<Box<BlobImageHandler>>,
|
||||
pub recorder: Option<Box<ApiRecordingReceiver>>,
|
||||
pub thread_listener: Option<Box<ThreadListener + Send + Sync>>,
|
||||
pub enable_render_on_scroll: bool,
|
||||
pub cached_programs: Option<Rc<ProgramCache>>,
|
||||
pub debug_flags: DebugFlags,
|
||||
pub renderer_id: Option<u64>,
|
||||
@ -4276,7 +4226,6 @@ impl Default for RendererOptions {
|
||||
blob_image_handler: None,
|
||||
recorder: None,
|
||||
thread_listener: None,
|
||||
enable_render_on_scroll: true,
|
||||
renderer_id: None,
|
||||
cached_programs: None,
|
||||
disable_dual_source_blending: false,
|
||||
|
@ -395,12 +395,11 @@ impl SegmentBuilder {
|
||||
None => return,
|
||||
};
|
||||
|
||||
let mut items = self.items;
|
||||
|
||||
// First, filter out any items that don't intersect
|
||||
// with the visible bounding rect.
|
||||
let mut items: Vec<Item> = self.items
|
||||
.into_iter()
|
||||
.filter(|item| item.rect.intersects(&bounding_rect))
|
||||
.collect();
|
||||
items.retain(|item| item.rect.intersects(&bounding_rect));
|
||||
|
||||
// Create events for each item
|
||||
let mut x_events = Vec::new();
|
||||
|
@ -400,6 +400,14 @@ static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
|
||||
return IntRectAbsolute(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
layers::BlobFont ReadBlobFont() {
|
||||
MOZ_RELEASE_ASSERT(pos + sizeof(layers::BlobFont) <= len);
|
||||
layers::BlobFont ret;
|
||||
memcpy(&ret, buf + pos, sizeof(ret));
|
||||
pos += sizeof(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MOZ_RELEASE_ASSERT(aBlob.length() > sizeof(size_t));
|
||||
@ -421,10 +429,12 @@ static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
|
||||
|
||||
layers::WebRenderTranslator translator(dt);
|
||||
|
||||
size_t count = *(size_t*)(aBlob.begin().get() + end);
|
||||
MOZ_RELEASE_ASSERT(extra_end >= end);
|
||||
MOZ_RELEASE_ASSERT(extra_end < aBlob.length());
|
||||
Reader fontReader(aBlob.begin().get() + end, extra_end - end);
|
||||
size_t count = fontReader.ReadSize();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
layers::BlobFont blobFont =
|
||||
*(layers::BlobFont*)(aBlob.begin() + end + sizeof(count) + sizeof(layers::BlobFont)*i).get();
|
||||
layers::BlobFont blobFont = fontReader.ReadBlobFont();
|
||||
RefPtr<ScaledFont> scaledFont = GetScaledFont(&translator, blobFont.mFontInstanceKey);
|
||||
translator.AddScaledFont(blobFont.mScaledFontPtr, scaledFont);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
ced27184ede63268f78ab56453e7ee39007826d7
|
||||
27e3bc4293d4a5057346739bfe8b7a163cf068f3
|
||||
|
@ -938,7 +938,6 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
|
||||
blob_image_handler: Some(Box::new(Moz2dBlobImageHandler::new(workers.clone()))),
|
||||
workers: Some(workers.clone()),
|
||||
thread_listener: Some(Box::new(GeckoProfilerThreadListener::new())),
|
||||
enable_render_on_scroll: false,
|
||||
resource_override_path: unsafe {
|
||||
let override_charptr = gfx_wr_resource_path_override();
|
||||
if override_charptr.is_null() {
|
||||
|
@ -40,6 +40,7 @@ from __future__ import with_statement
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
import mozpack.path as mozpath
|
||||
import subprocess
|
||||
import shlex
|
||||
import which
|
||||
@ -86,8 +87,11 @@ namespace %(namespace)s {
|
||||
|
||||
|
||||
def embed(cxx, preprocessorOption, cppflags, msgs, sources, c_out, js_out, namespace, env):
|
||||
objdir = os.getcwd()
|
||||
# Use relative pathnames to avoid path translation issues in WSL.
|
||||
combinedSources = '\n'.join([msgs] + ['#include "%(s)s"' %
|
||||
{'s': source} for source in sources])
|
||||
{'s': mozpath.relpath(source, objdir)}
|
||||
for source in sources])
|
||||
args = cppflags + ['-D%(k)s=%(v)s' % {'k': k, 'v': env[k]} for k in env]
|
||||
preprocessed = preprocess(cxx, preprocessorOption, combinedSources, args)
|
||||
processed = '\n'.join([line for line in preprocessed.splitlines() if
|
||||
|
5
js/src/jit-test/tests/baseline/bug1463375.js
Normal file
5
js/src/jit-test/tests/baseline/bug1463375.js
Normal file
@ -0,0 +1,5 @@
|
||||
// |jit-test| allow-overrecursed
|
||||
function f() {
|
||||
f.apply(null, new Array(20000));
|
||||
}
|
||||
f()
|
@ -2572,7 +2572,7 @@ class Simulator : public DecoderVisitor {
|
||||
|
||||
// Stack
|
||||
byte* stack_;
|
||||
static const int stack_protection_size_ = 128 * KBytes;
|
||||
static const int stack_protection_size_ = 512 * KBytes;
|
||||
static const int stack_size_ = (2 * MBytes) + (2 * stack_protection_size_);
|
||||
byte* stack_limit_;
|
||||
|
||||
|
@ -188,6 +188,7 @@ EXPORTS.js += [
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'builtin/Array.cpp',
|
||||
'builtin/AtomicsObject.cpp',
|
||||
'builtin/Boolean.cpp',
|
||||
'builtin/DataViewObject.cpp',
|
||||
@ -382,6 +383,7 @@ UNIFIED_SOURCES += [
|
||||
'vm/Id.cpp',
|
||||
'vm/Initialization.cpp',
|
||||
'vm/Iteration.cpp',
|
||||
'vm/JSAtom.cpp',
|
||||
'vm/JSContext.cpp',
|
||||
'vm/JSFunction.cpp',
|
||||
'vm/JSObject.cpp',
|
||||
@ -443,8 +445,6 @@ UNIFIED_SOURCES += [
|
||||
'wasm/WasmValidate.cpp'
|
||||
]
|
||||
|
||||
# builtin/Array.cpp and vm/JSAtom.cpp cannot be built in unified mode because
|
||||
# xpcshell is broken during packaging when compiled with gcc-4.8.2
|
||||
# builtin/RegExp.cpp cannot be built in unified mode because it causes huge
|
||||
# win32 test slowdowns
|
||||
# frontend/Parser.cpp cannot be built in unified mode because of explicit
|
||||
@ -464,7 +464,6 @@ UNIFIED_SOURCES += [
|
||||
# vm/Interpreter.cpp is gigantic and destroys incremental build times for any
|
||||
# files unlucky enough to be unified with it.
|
||||
SOURCES += [
|
||||
'builtin/Array.cpp',
|
||||
'builtin/RegExp.cpp',
|
||||
'frontend/Parser.cpp',
|
||||
'gc/StoreBuffer.cpp',
|
||||
@ -472,7 +471,6 @@ SOURCES += [
|
||||
'jsutil.cpp',
|
||||
'util/DoubleToString.cpp',
|
||||
'vm/Interpreter.cpp',
|
||||
'vm/JSAtom.cpp',
|
||||
'vm/ProfilingStack.cpp',
|
||||
]
|
||||
|
||||
|
@ -1662,12 +1662,6 @@ else
|
||||
fi
|
||||
AC_SUBST(CL_INCLUDES_PREFIX)
|
||||
rm -f dummy-hello.c
|
||||
|
||||
dnl Make sure that the build system can handle non-ASCII characters
|
||||
dnl in environment variables to prevent it from breaking silently on
|
||||
dnl non-English systems.
|
||||
NONASCII=$'\241\241'
|
||||
AC_SUBST(NONASCII)
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -428,12 +428,14 @@ ParseTask::ParseTask(ParseTaskKind kind, JSContext* cx,
|
||||
JS::OffThreadCompileCallback callback, void* callbackData)
|
||||
: kind(kind),
|
||||
options(cx),
|
||||
alloc(JSContext::TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
||||
parseGlobal(nullptr),
|
||||
callback(callback), callbackData(callbackData),
|
||||
scripts(cx), sourceObjects(cx),
|
||||
overRecursed(false), outOfMemory(false)
|
||||
{
|
||||
// Note that |cx| is the main thread context here but the parse task will
|
||||
// run with a different, helper thread, context.
|
||||
MOZ_ASSERT(!cx->helperThread());
|
||||
|
||||
MOZ_ALWAYS_TRUE(scripts.reserve(scripts.capacity()));
|
||||
MOZ_ALWAYS_TRUE(sourceObjects.reserve(sourceObjects.capacity()));
|
||||
}
|
||||
@ -441,6 +443,8 @@ ParseTask::ParseTask(ParseTaskKind kind, JSContext* cx,
|
||||
bool
|
||||
ParseTask::init(JSContext* cx, const ReadOnlyCompileOptions& options, JSObject* global)
|
||||
{
|
||||
MOZ_ASSERT(!cx->helperThread());
|
||||
|
||||
if (!this->options.copy(cx, options))
|
||||
return false;
|
||||
|
||||
@ -454,20 +458,6 @@ ParseTask::activate(JSRuntime* rt)
|
||||
rt->setUsedByHelperThread(parseGlobal->zone());
|
||||
}
|
||||
|
||||
bool
|
||||
ParseTask::finish(JSContext* cx)
|
||||
{
|
||||
for (auto& sourceObject : sourceObjects) {
|
||||
RootedScriptSourceObject sso(cx, sourceObject);
|
||||
if (!ScriptSourceObject::initFromOptions(cx, sso, options))
|
||||
return false;
|
||||
if (!sso->source()->tryCompressOffThread(cx))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ParseTask::~ParseTask() = default;
|
||||
|
||||
void
|
||||
@ -491,7 +481,6 @@ size_t
|
||||
ParseTask::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
|
||||
{
|
||||
return options.sizeOfExcludingThis(mallocSizeOf) +
|
||||
alloc.sizeOfExcludingThis(mallocSizeOf) +
|
||||
errors.sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
@ -504,11 +493,13 @@ ScriptParseTask::ScriptParseTask(JSContext* cx, JS::SourceBufferHolder& srcBuf,
|
||||
void
|
||||
ScriptParseTask::parse(JSContext* cx)
|
||||
{
|
||||
MOZ_ASSERT(cx->helperThread());
|
||||
|
||||
Rooted<ScriptSourceObject*> sourceObject(cx);
|
||||
|
||||
ScopeKind scopeKind = options.nonSyntacticScope ? ScopeKind::NonSyntactic : ScopeKind::Global;
|
||||
|
||||
JSScript* script = frontend::CompileGlobalScript(cx, alloc, scopeKind,
|
||||
JSScript* script = frontend::CompileGlobalScript(cx, cx->tempLifoAlloc(), scopeKind,
|
||||
options, data,
|
||||
/* sourceObjectOut = */ &sourceObject.get());
|
||||
if (script)
|
||||
@ -526,9 +517,11 @@ ModuleParseTask::ModuleParseTask(JSContext* cx, JS::SourceBufferHolder& srcBuf,
|
||||
void
|
||||
ModuleParseTask::parse(JSContext* cx)
|
||||
{
|
||||
MOZ_ASSERT(cx->helperThread());
|
||||
|
||||
Rooted<ScriptSourceObject*> sourceObject(cx);
|
||||
|
||||
JSScript* script = frontend::CompileModule(cx, options, data, alloc, &sourceObject.get());
|
||||
JSScript* script = frontend::CompileModule(cx, options, data, cx->tempLifoAlloc(), &sourceObject.get());
|
||||
if (script) {
|
||||
scripts.infallibleAppend(script);
|
||||
if (sourceObject)
|
||||
@ -545,11 +538,13 @@ ScriptDecodeTask::ScriptDecodeTask(JSContext* cx, const JS::TranscodeRange& rang
|
||||
void
|
||||
ScriptDecodeTask::parse(JSContext* cx)
|
||||
{
|
||||
MOZ_ASSERT(cx->helperThread());
|
||||
|
||||
RootedScript resultScript(cx);
|
||||
Rooted<ScriptSourceObject*> sourceObject(cx);
|
||||
|
||||
XDROffThreadDecoder decoder(cx, alloc, &options, /* sourceObjectOut = */ &sourceObject.get(),
|
||||
range);
|
||||
XDROffThreadDecoder decoder(cx, cx->tempLifoAlloc(), &options,
|
||||
/* sourceObjectOut = */ &sourceObject.get(), range);
|
||||
XDRResult res = decoder.codeScript(&resultScript);
|
||||
MOZ_ASSERT(bool(resultScript) == res.isOk());
|
||||
if (res.isOk()) {
|
||||
@ -570,9 +565,11 @@ BinASTDecodeTask::BinASTDecodeTask(JSContext* cx, const uint8_t* buf, size_t len
|
||||
void
|
||||
BinASTDecodeTask::parse(JSContext* cx)
|
||||
{
|
||||
MOZ_ASSERT(cx->helperThread());
|
||||
|
||||
RootedScriptSourceObject sourceObject(cx);
|
||||
|
||||
JSScript* script = frontend::CompileGlobalBinASTScript(cx, alloc, options,
|
||||
JSScript* script = frontend::CompileGlobalBinASTScript(cx, cx->tempLifoAlloc(), options,
|
||||
data.begin().get(), data.length(),
|
||||
&sourceObject.get());
|
||||
if (script) {
|
||||
@ -594,9 +591,12 @@ MultiScriptsDecodeTask::MultiScriptsDecodeTask(JSContext* cx, JS::TranscodeSourc
|
||||
void
|
||||
MultiScriptsDecodeTask::parse(JSContext* cx)
|
||||
{
|
||||
MOZ_ASSERT(cx->helperThread());
|
||||
|
||||
if (!scripts.reserve(sources->length()) ||
|
||||
!sourceObjects.reserve(sources->length()))
|
||||
{
|
||||
ReportOutOfMemory(cx); // This sets |outOfMemory|.
|
||||
return;
|
||||
}
|
||||
|
||||
@ -607,7 +607,8 @@ MultiScriptsDecodeTask::parse(JSContext* cx)
|
||||
RootedScript resultScript(cx);
|
||||
Rooted<ScriptSourceObject*> sourceObject(cx);
|
||||
|
||||
XDROffThreadDecoder decoder(cx, alloc, &opts, &sourceObject.get(), source.range);
|
||||
XDROffThreadDecoder decoder(cx, cx->tempLifoAlloc(), &opts, &sourceObject.get(),
|
||||
source.range);
|
||||
XDRResult res = decoder.codeScript(&resultScript);
|
||||
MOZ_ASSERT(bool(resultScript) == res.isOk());
|
||||
|
||||
@ -1647,11 +1648,11 @@ GlobalHelperThreadState::removeFinishedParseTask(ParseTaskKind kind, JS::OffThre
|
||||
return task;
|
||||
}
|
||||
|
||||
template <typename F, typename>
|
||||
bool
|
||||
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token, F&& finishCallback)
|
||||
UniquePtr<ParseTask>
|
||||
GlobalHelperThreadState::finishParseTaskCommon(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token)
|
||||
{
|
||||
MOZ_ASSERT(!cx->helperThread());
|
||||
MOZ_ASSERT(cx->realm());
|
||||
|
||||
Rooted<UniquePtr<ParseTask>> parseTask(cx, removeFinishedParseTask(kind, token));
|
||||
@ -1660,23 +1661,26 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
// remapping below, since we can't GC while that's happening.
|
||||
if (!EnsureParserCreatedClasses(cx, kind)) {
|
||||
LeaveParseTaskZone(cx->runtime(), parseTask.get().get());
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mergeParseTaskRealm(cx, parseTask.get().get(), cx->realm());
|
||||
|
||||
bool ok = finishCallback(parseTask.get().get());
|
||||
|
||||
for (auto& script : parseTask->scripts)
|
||||
cx->releaseCheck(script);
|
||||
|
||||
if (!parseTask->finish(cx) || !ok)
|
||||
return false;
|
||||
for (auto& sourceObject : parseTask->sourceObjects) {
|
||||
RootedScriptSourceObject sso(cx, sourceObject);
|
||||
if (!ScriptSourceObject::initFromOptions(cx, sso, parseTask->options))
|
||||
return nullptr;
|
||||
if (!sso->source()->tryCompressOffThread(cx))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Report out of memory errors eagerly, or errors could be malformed.
|
||||
if (parseTask->outOfMemory) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Report any error or warnings generated during the parse.
|
||||
@ -1685,28 +1689,27 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
if (parseTask->overRecursed)
|
||||
ReportOverRecursed(cx);
|
||||
if (cx->isExceptionPending())
|
||||
return false;
|
||||
return nullptr;
|
||||
|
||||
return true;
|
||||
return std::move(parseTask.get());
|
||||
}
|
||||
|
||||
JSScript*
|
||||
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token)
|
||||
GlobalHelperThreadState::finishSingleParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token)
|
||||
{
|
||||
JS::RootedScript script(cx);
|
||||
|
||||
bool ok = finishParseTask(cx, kind, token, [&script] (ParseTask* parseTask) {
|
||||
MOZ_RELEASE_ASSERT(parseTask->scripts.length() <= 1);
|
||||
|
||||
if (parseTask->scripts.length() > 0)
|
||||
script = parseTask->scripts[0];
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!ok)
|
||||
Rooted<UniquePtr<ParseTask>> parseTask(cx, finishParseTaskCommon(cx, kind, token));
|
||||
if (!parseTask) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(parseTask->scripts.length() <= 1);
|
||||
|
||||
if (parseTask->scripts.length() > 0) {
|
||||
script = parseTask->scripts[0];
|
||||
}
|
||||
|
||||
if (!script) {
|
||||
// No error was reported, but no script produced. Assume we hit out of
|
||||
@ -1723,29 +1726,26 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token,
|
||||
MutableHandle<ScriptVector> scripts)
|
||||
GlobalHelperThreadState::finishMultiParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token,
|
||||
MutableHandle<ScriptVector> scripts)
|
||||
{
|
||||
size_t expectedLength = 0;
|
||||
|
||||
bool ok = finishParseTask(cx, kind, token, [&scripts, &expectedLength] (ParseTask* parseTask) {
|
||||
MOZ_ASSERT(parseTask->kind == ParseTaskKind::MultiScriptsDecode);
|
||||
auto task = static_cast<MultiScriptsDecodeTask*>(parseTask);
|
||||
|
||||
expectedLength = task->sources->length();
|
||||
|
||||
if (!scripts.reserve(task->scripts.length()))
|
||||
return false;
|
||||
|
||||
for (auto& script : task->scripts)
|
||||
scripts.infallibleAppend(script);
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!ok)
|
||||
Rooted<UniquePtr<ParseTask>> parseTask(cx, finishParseTaskCommon(cx, kind, token));
|
||||
if (!parseTask)
|
||||
return false;
|
||||
|
||||
MOZ_ASSERT(parseTask->kind == ParseTaskKind::MultiScriptsDecode);
|
||||
auto task = static_cast<MultiScriptsDecodeTask*>(parseTask.get().get());
|
||||
size_t expectedLength = task->sources->length();
|
||||
|
||||
if (!scripts.reserve(parseTask->scripts.length())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& script : parseTask->scripts)
|
||||
scripts.infallibleAppend(script);
|
||||
|
||||
if (scripts.length() != expectedLength) {
|
||||
// No error was reported, but fewer scripts produced than expected.
|
||||
// Assume we hit out of memory.
|
||||
@ -1769,7 +1769,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
|
||||
JSScript*
|
||||
GlobalHelperThreadState::finishScriptParseTask(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
JSScript* script = finishParseTask(cx, ParseTaskKind::Script, token);
|
||||
JSScript* script = finishSingleParseTask(cx, ParseTaskKind::Script, token);
|
||||
MOZ_ASSERT_IF(script, script->isGlobalCode());
|
||||
return script;
|
||||
}
|
||||
@ -1777,7 +1777,7 @@ GlobalHelperThreadState::finishScriptParseTask(JSContext* cx, JS::OffThreadToken
|
||||
JSScript*
|
||||
GlobalHelperThreadState::finishScriptDecodeTask(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
JSScript* script = finishParseTask(cx, ParseTaskKind::ScriptDecode, token);
|
||||
JSScript* script = finishSingleParseTask(cx, ParseTaskKind::ScriptDecode, token);
|
||||
MOZ_ASSERT_IF(script, script->isGlobalCode());
|
||||
return script;
|
||||
}
|
||||
@ -1787,7 +1787,7 @@ GlobalHelperThreadState::finishScriptDecodeTask(JSContext* cx, JS::OffThreadToke
|
||||
JSScript*
|
||||
GlobalHelperThreadState::finishBinASTDecodeTask(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
JSScript* script = finishParseTask(cx, ParseTaskKind::BinAST, token);
|
||||
JSScript* script = finishSingleParseTask(cx, ParseTaskKind::BinAST, token);
|
||||
MOZ_ASSERT_IF(script, script->isGlobalCode());
|
||||
return script;
|
||||
}
|
||||
@ -1798,13 +1798,13 @@ bool
|
||||
GlobalHelperThreadState::finishMultiScriptsDecodeTask(JSContext* cx, JS::OffThreadToken* token,
|
||||
MutableHandle<ScriptVector> scripts)
|
||||
{
|
||||
return finishParseTask(cx, ParseTaskKind::MultiScriptsDecode, token, scripts);
|
||||
return finishMultiParseTask(cx, ParseTaskKind::MultiScriptsDecode, token, scripts);
|
||||
}
|
||||
|
||||
JSScript*
|
||||
GlobalHelperThreadState::finishModuleParseTask(JSContext* cx, JS::OffThreadToken* token)
|
||||
{
|
||||
RootedScript script(cx, finishParseTask(cx, ParseTaskKind::Module, token));
|
||||
RootedScript script(cx, finishSingleParseTask(cx, ParseTaskKind::Module, token));
|
||||
if (!script)
|
||||
return nullptr;
|
||||
|
||||
|
@ -279,30 +279,23 @@ class GlobalHelperThreadState
|
||||
// Used by a major GC to signal processing enqueued compression tasks.
|
||||
void startHandlingCompressionTasks(const AutoLockHelperThreadState&);
|
||||
|
||||
jit::IonBuilder* highestPriorityPendingIonCompile(const AutoLockHelperThreadState& lock);
|
||||
private:
|
||||
void scheduleCompressionTasks(const AutoLockHelperThreadState&);
|
||||
|
||||
public:
|
||||
jit::IonBuilder* highestPriorityPendingIonCompile(const AutoLockHelperThreadState& lock);
|
||||
UniquePtr<ParseTask> finishParseTaskCommon(JSContext* cx, ParseTaskKind kind,
|
||||
JS::OffThreadToken* token);
|
||||
|
||||
template <
|
||||
typename F,
|
||||
typename = typename mozilla::EnableIf<
|
||||
// Matches when the type is a function or lambda with the signature `bool(ParseTask*)`
|
||||
mozilla::IsSame<bool, decltype((*(F*)nullptr)((ParseTask*)nullptr))>::value
|
||||
>::Type
|
||||
>
|
||||
bool finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, F&& finishCallback);
|
||||
|
||||
JSScript* finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token);
|
||||
|
||||
bool finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, MutableHandle<ScriptVector> scripts);
|
||||
|
||||
void cancelParseTask(JSRuntime* rt, ParseTaskKind kind, JS::OffThreadToken* token);
|
||||
void destroyParseTask(JSRuntime* rt, ParseTask* parseTask);
|
||||
JSScript* finishSingleParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token);
|
||||
bool finishMultiParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token,
|
||||
MutableHandle<ScriptVector> scripts);
|
||||
|
||||
void mergeParseTaskRealm(JSContext* cx, ParseTask* parseTask, JS::Realm* dest);
|
||||
|
||||
public:
|
||||
void cancelParseTask(JSRuntime* rt, ParseTaskKind kind, JS::OffThreadToken* token);
|
||||
void destroyParseTask(JSRuntime* rt, ParseTask* parseTask);
|
||||
|
||||
void trace(JSTracer* trc);
|
||||
|
||||
JSScript* finishScriptParseTask(JSContext* cx, JS::OffThreadToken* token);
|
||||
@ -690,8 +683,6 @@ struct ParseTask : public mozilla::LinkedListElement<ParseTask>, public JS::OffT
|
||||
ParseTaskKind kind;
|
||||
JS::OwningCompileOptions options;
|
||||
|
||||
LifoAlloc alloc;
|
||||
|
||||
// The global object to use while parsing.
|
||||
JSObject* parseGlobal;
|
||||
|
||||
@ -702,10 +693,10 @@ struct ParseTask : public mozilla::LinkedListElement<ParseTask>, public JS::OffT
|
||||
// Holds the final scripts between the invocation of the callback and the
|
||||
// point where FinishOffThreadScript is called, which will destroy the
|
||||
// ParseTask.
|
||||
GCVector<JSScript*, 1> scripts;
|
||||
GCVector<JSScript*, 1, SystemAllocPolicy> scripts;
|
||||
|
||||
// Holds the ScriptSourceObjects generated for the script compilation.
|
||||
GCVector<ScriptSourceObject*, 1> sourceObjects;
|
||||
GCVector<ScriptSourceObject*, 1, SystemAllocPolicy> sourceObjects;
|
||||
|
||||
// Any errors or warnings produced during compilation. These are reported
|
||||
// when finishing the script.
|
||||
@ -721,7 +712,6 @@ struct ParseTask : public mozilla::LinkedListElement<ParseTask>, public JS::OffT
|
||||
|
||||
void activate(JSRuntime* rt);
|
||||
virtual void parse(JSContext* cx) = 0;
|
||||
bool finish(JSContext* cx);
|
||||
|
||||
bool runtimeMatches(JSRuntime* rt) {
|
||||
return parseGlobal->runtimeFromAnyThread() == rt;
|
||||
|
@ -204,6 +204,7 @@ XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE , "The JAR's signature is wr
|
||||
XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_ENTRY_TOO_LARGE , "An entry in the JAR is too large.")
|
||||
XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_ENTRY_INVALID , "An entry in the JAR is invalid.")
|
||||
XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_MANIFEST_INVALID , "The JAR's manifest or signature file is invalid.")
|
||||
XPC_MSG_DEF(NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO , "The PKCS#7 signature is malformed or invalid.")
|
||||
XPC_MSG_DEF(NS_ERROR_CMS_VERIFY_NOT_SIGNED , "The PKCS#7 information is not signed.")
|
||||
|
||||
/* Codes related to signed manifests */
|
||||
@ -236,4 +237,4 @@ XPC_MSG_DEF(NS_ERROR_PHISHING_URI , "The URI is phishing")
|
||||
XPC_MSG_DEF(NS_ERROR_TRACKING_URI , "The URI is tracking")
|
||||
XPC_MSG_DEF(NS_ERROR_UNWANTED_URI , "The URI is unwanted")
|
||||
XPC_MSG_DEF(NS_ERROR_BLOCKED_URI , "The URI is blocked")
|
||||
XPC_MSG_DEF(NS_ERROR_HARMFUL_URI , "The URI is harmful")
|
||||
XPC_MSG_DEF(NS_ERROR_HARMFUL_URI , "The URI is harmful")
|
||||
|
@ -370,7 +370,7 @@ TextOverflow::TextOverflow(nsDisplayListBuilder* aBuilder,
|
||||
// has overflow on that side.
|
||||
}
|
||||
|
||||
/* static */ UniquePtr<TextOverflow>
|
||||
/* static */ Maybe<TextOverflow>
|
||||
TextOverflow::WillProcessLines(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aBlockFrame)
|
||||
{
|
||||
@ -378,14 +378,14 @@ TextOverflow::WillProcessLines(nsDisplayListBuilder* aBuilder,
|
||||
if (aBuilder->IsForEventDelivery() ||
|
||||
aBuilder->IsForFrameVisibility() ||
|
||||
!CanHaveTextOverflow(aBlockFrame)) {
|
||||
return nullptr;
|
||||
return Nothing();
|
||||
}
|
||||
nsIScrollableFrame* scrollableFrame = nsLayoutUtils::GetScrollableFrameFor(aBlockFrame);
|
||||
if (scrollableFrame && scrollableFrame->IsTransformingByAPZ()) {
|
||||
// If the APZ is actively scrolling this, don't bother with markers.
|
||||
return nullptr;
|
||||
return Nothing();
|
||||
}
|
||||
return MakeUnique<TextOverflow>(aBuilder, aBlockFrame);
|
||||
return Some(TextOverflow(aBuilder, aBlockFrame));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -27,13 +27,13 @@ namespace css {
|
||||
* 1. allocate an object using WillProcessLines
|
||||
* 2. then call ProcessLine for each line you are building display lists for
|
||||
*/
|
||||
class MOZ_HEAP_CLASS TextOverflow final {
|
||||
class TextOverflow final {
|
||||
public:
|
||||
/**
|
||||
* Allocate an object for text-overflow processing.
|
||||
* @return nullptr if no processing is necessary. The caller owns the object.
|
||||
*/
|
||||
static UniquePtr<TextOverflow>
|
||||
static Maybe<TextOverflow>
|
||||
WillProcessLines(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aBlockFrame);
|
||||
|
||||
@ -45,6 +45,13 @@ class MOZ_HEAP_CLASS TextOverflow final {
|
||||
TextOverflow(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aBlockFrame);
|
||||
|
||||
TextOverflow() = default;
|
||||
~TextOverflow() = default;
|
||||
TextOverflow(TextOverflow&&) = default;
|
||||
TextOverflow(const TextOverflow&) = delete;
|
||||
TextOverflow& operator=(TextOverflow&&) = default;
|
||||
TextOverflow& operator=(const TextOverflow&) = delete;
|
||||
|
||||
/**
|
||||
* Analyze the display lists for text overflow and what kind of item is at
|
||||
* the content edges. Add display items for text-overflow markers as needed
|
||||
|
@ -6812,8 +6812,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
aBuilder->MarkFramesForDisplayList(this, mFloats);
|
||||
|
||||
// Prepare for text-overflow processing.
|
||||
UniquePtr<TextOverflow> textOverflow =
|
||||
TextOverflow::WillProcessLines(aBuilder, this);
|
||||
Maybe<TextOverflow> textOverflow = TextOverflow::WillProcessLines(aBuilder, this);
|
||||
|
||||
// We'll collect our lines' display items here, & then append this to aLists.
|
||||
nsDisplayListCollection linesDisplayListCollection(aBuilder);
|
||||
@ -6828,7 +6827,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
// Also skip the cursor if we're creating text overflow markers,
|
||||
// since we need to know what line number we're up to in order
|
||||
// to generate unique display item keys.
|
||||
nsLineBox* cursor = (aBuilder->ShouldDescendIntoFrame(this, true) || textOverflow) ?
|
||||
nsLineBox* cursor = (aBuilder->ShouldDescendIntoFrame(this, true) || textOverflow.isSome()) ?
|
||||
nullptr : GetFirstLineContaining(aBuilder->GetDirtyRect().y);
|
||||
LineIterator line_end = LinesEnd();
|
||||
|
||||
@ -6843,7 +6842,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
if (lineArea.y >= aBuilder->GetDirtyRect().YMost()) {
|
||||
break;
|
||||
}
|
||||
MOZ_ASSERT(!textOverflow);
|
||||
MOZ_ASSERT(textOverflow.isNothing());
|
||||
DisplayLine(aBuilder, lineArea, line, depth, drawnLines,
|
||||
linesDisplayListCollection, this, nullptr, 0);
|
||||
}
|
||||
@ -6858,7 +6857,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
++line) {
|
||||
nsRect lineArea = line->GetVisualOverflowArea();
|
||||
DisplayLine(aBuilder, lineArea, line, depth, drawnLines,
|
||||
linesDisplayListCollection, this, textOverflow.get(), lineCount);
|
||||
linesDisplayListCollection, this, textOverflow.ptrOr(nullptr), lineCount);
|
||||
if (!lineArea.IsEmpty()) {
|
||||
if (lineArea.y < lastY
|
||||
|| lineArea.YMost() < lastYMost) {
|
||||
@ -6879,7 +6878,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
// PositionedDescendants just before we append the lines' display items,
|
||||
// so that our text-overflow markers will appear on top of this block's
|
||||
// normal content but below any of its its' positioned children.
|
||||
if (textOverflow) {
|
||||
if (textOverflow.isSome()) {
|
||||
aLists.PositionedDescendants()->AppendToTop(&textOverflow->GetMarkers());
|
||||
}
|
||||
linesDisplayListCollection.MoveTo(aLists);
|
||||
|
@ -159,8 +159,7 @@ public:
|
||||
|
||||
/**
|
||||
* Return the containing block for aChild which MUST be an abs.pos. child
|
||||
* of a grid container. This is just a helper method for
|
||||
* nsAbsoluteContainingBlock::Reflow - it's not meant to be used elsewhere.
|
||||
* of a grid container and that container must have been reflowed.
|
||||
*/
|
||||
static const nsRect& GridItemCB(nsIFrame* aChild);
|
||||
|
||||
|
@ -3254,6 +3254,40 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
nsDisplayList(nsDisplayList&& aOther)
|
||||
{
|
||||
mIsOpaque = aOther.mIsOpaque;
|
||||
mForceTransparentSurface = aOther.mForceTransparentSurface;
|
||||
|
||||
if (aOther.mSentinel.mAbove) {
|
||||
AppendToTop(&aOther);
|
||||
} else {
|
||||
mTop = &mSentinel;
|
||||
mLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nsDisplayList& operator=(nsDisplayList&& aOther)
|
||||
{
|
||||
if (this != &aOther) {
|
||||
if (aOther.mSentinel.mAbove) {
|
||||
nsDisplayList tmp;
|
||||
tmp.AppendToTop(&aOther);
|
||||
aOther.AppendToTop(this);
|
||||
AppendToTop(&tmp);
|
||||
} else {
|
||||
mTop = &mSentinel;
|
||||
mLength = 0;
|
||||
}
|
||||
mIsOpaque = aOther.mIsOpaque;
|
||||
mForceTransparentSurface = aOther.mForceTransparentSurface;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsDisplayList(const nsDisplayList&) = delete;
|
||||
nsDisplayList& operator=(const nsDisplayList& aOther) = delete;
|
||||
|
||||
/**
|
||||
* Append an item to the top of the list. The item must not currently
|
||||
* be in a list and cannot be null.
|
||||
|
@ -867,7 +867,7 @@ fuzzy-if(skiaContent,0-2,0-5) == 402629-3.html 402629-3-ref.html
|
||||
== 403129-3.html 403129-3-ref.html
|
||||
== 403129-4.html 403129-4-ref.html
|
||||
random == 403134-1.html 403134-1-ref.html # bug 405377
|
||||
fuzzy-if(webrender,130-131,177-177) == 403181-1.xml 403181-1-ref.xml
|
||||
fuzzy-if(webrender,130-131,177-177) skip-if(winWidget&&!isDebugBuild&&webrender) == 403181-1.xml 403181-1-ref.xml
|
||||
== 403249-1a.html 403249-1-ref.html
|
||||
== 403249-1b.html 403249-1-ref.html
|
||||
== 403249-2a.html 403249-2-ref.html
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
body > div:nth-child(1) > .progress-bar { margin: 10px; padding: 0px; }
|
||||
body > div:nth-child(2) > .progress-bar { margin: 0px; padding: 10px; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
body > div:nth-child(1) > .progress-bar { margin: 0px 10px 0px 0px; padding: 0px; }
|
||||
body > div:nth-child(2) > .progress-bar { margin: 0px 0px 0px 10px; padding: 0px; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
.progress-element { margin: 10px; }
|
||||
body > div:nth-child(1) > .progress-bar { position: relative; top: 4px; left: 4px;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
.progress-element { margin: 10px; }
|
||||
body > div:nth-child(1) > .progress-bar { position: relative; top: 4px; left: 4px;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
progress { display: block; }
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
progress { width: 10em; height: 1em; }
|
||||
progress.vertical { -moz-orient: vertical; width: 1em; height: 10em; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
div.progress-element {
|
||||
height: 12em;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
div.progress-bar {
|
||||
width:100%;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
body > div:nth-child(1) { margin: 10px; padding: 0px; }
|
||||
body > div:nth-child(2) { margin: 0px; padding: 10px; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
body > div:nth-child(1) { margin: 10px; padding: 0px; }
|
||||
body > div:nth-child(2) { margin: 0px; padding: 10px; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
body > div:nth-child(1) { margin: 10px; padding: 0px; }
|
||||
body > div:nth-child(2) { margin: 0px; padding: 10px; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
body > div:nth-child(1) { margin: 10px; padding: 0px; }
|
||||
body > div:nth-child(2) { margin: 0px; padding: 10px; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
body > div:nth-child(1) { -moz-transform: matrix(1, -0.2, 0, 1, 0, 0); }
|
||||
body > div:nth-child(2) { -moz-transform: translateX(15em) matrix(1, 0, 0.6, 1, 0, 0); }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
div:nth-child(1) > .progress-bar { width: 100%; }
|
||||
div:nth-child(2) > .progress-bar { width: 0%; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
div:nth-child(1) > .progress-bar { width: 100%; }
|
||||
div:nth-child(2) > .progress-bar { width: 0%; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
div:nth-child(1) > .progress-bar { position: relative; top: 0%; height: 100%; }
|
||||
div:nth-child(2) > .progress-bar { position: relative; top: 100%; height: 0%; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' href='chrome://reftest/content/progress.css'>
|
||||
<link rel='stylesheet' href='resource://reftest/progress.css'>
|
||||
<style>
|
||||
div:nth-child(1) > .progress-bar { position: relative; top: 0%; height: 100%; }
|
||||
div:nth-child(2) > .progress-bar { position: relative; top: 100%; height: 0%; }
|
||||
|
@ -6,7 +6,7 @@
|
||||
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<link rel="help" href="http://www.w3.org/TR/css-containment-1/#containment-layout">
|
||||
<link rel="match" href="contain-paint-formatting-context-margin-001-ref.html">
|
||||
<link rel="match" href="contain-layout-formatting-context-margin-001-ref.html">
|
||||
<style>
|
||||
#a {
|
||||
contain:layout;
|
||||
|
@ -4162,6 +4162,10 @@ nsComputedDOMStyle::GetAbsoluteOffset(mozilla::Side aSide)
|
||||
if (scrollFrame) {
|
||||
scrollbarSizes = scrollFrame->GetActualScrollbarSizes();
|
||||
}
|
||||
} else if (container->IsGridContainerFrame() &&
|
||||
(mOuterFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW))) {
|
||||
containerRect = nsGridContainerFrame::GridItemCB(mOuterFrame);
|
||||
rect.MoveBy(-containerRect.x, -containerRect.y);
|
||||
}
|
||||
|
||||
nscoord offset = 0;
|
||||
|
114
layout/tools/reftest/api.js
Normal file
114
layout/tools/reftest/api.js
Normal file
@ -0,0 +1,114 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const Cm = Components.manager;
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "resProto",
|
||||
"@mozilla.org/network/protocol;1?name=resource",
|
||||
"nsISubstitutingProtocolHandler");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "aomStartup",
|
||||
"@mozilla.org/addons/addon-manager-startup;1",
|
||||
"amIAddonManagerStartup");
|
||||
|
||||
function processTerminated() {
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function observe(subject, topic) {
|
||||
if (topic == "ipc:content-shutdown") {
|
||||
Services.obs.removeObserver(observe, topic);
|
||||
resolve();
|
||||
}
|
||||
}, "ipc:content-shutdown");
|
||||
});
|
||||
}
|
||||
|
||||
function startAndroid(win) {
|
||||
// Add setTimeout here because windows.innerWidth/Height are not set yet.
|
||||
win.setTimeout(function() {OnRefTestLoad(win);}, 0);
|
||||
}
|
||||
|
||||
var WindowListener = {
|
||||
onOpenWindow: function(xulWin) {
|
||||
Services.wm.removeListener(WindowListener);
|
||||
|
||||
let win = xulWin.docShell.domWindow;
|
||||
win.addEventListener("load", function listener() {
|
||||
// Load into any existing windows.
|
||||
for (win of Services.wm.getEnumerator("navigator:browser")) {
|
||||
break;
|
||||
}
|
||||
|
||||
win.addEventListener("pageshow", function() {
|
||||
startAndroid(win);
|
||||
}, {once: true});
|
||||
}, {once: true});
|
||||
}
|
||||
};
|
||||
|
||||
this.reftest = class extends ExtensionAPI {
|
||||
onStartup() {
|
||||
let uri = Services.io.newURI("chrome/reftest/res/", null, this.extension.rootURI);
|
||||
resProto.setSubstitutionWithFlags("reftest", uri, resProto.ALLOW_CONTENT_ACCESS);
|
||||
|
||||
const manifestURI = Services.io.newURI("manifest.json", null, this.extension.rootURI);
|
||||
this.chromeHandle = aomStartup.registerChrome(manifestURI, [
|
||||
["content", "reftest", "chrome/reftest/content/", "contentaccessible=yes"],
|
||||
]);
|
||||
|
||||
// Starting tests is handled quite differently on android and desktop.
|
||||
// On Android, OnRefTestLoad() takes over the main browser window so
|
||||
// we just need to call it as soon as the browser window is available.
|
||||
// On desktop, a separate window (dummy) is created and explicitly given
|
||||
// focus (see bug 859339 for details), then tests are launched in a new
|
||||
// top-level window.
|
||||
let win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
|
||||
if (Services.appinfo.OS == "Android") {
|
||||
ChromeUtils.import("resource://reftest/reftest.jsm");
|
||||
if (win) {
|
||||
startAndroid(win);
|
||||
} else {
|
||||
Services.wm.addListener(WindowListener);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Services.io.manageOfflineStatus = false;
|
||||
Services.io.offline = false;
|
||||
|
||||
let dummy = Services.ww.openWindow(null, "about:blank", "dummy",
|
||||
"chrome,dialog=no,left=800,height=200,width=200,all",null);
|
||||
dummy.onload = async function() {
|
||||
// Close pre-existing window
|
||||
win.close();
|
||||
|
||||
ChromeUtils.import("resource://reftest/PerTestCoverageUtils.jsm");
|
||||
if (PerTestCoverageUtils.enabled) {
|
||||
// In PerTestCoverage mode, wait for the process belonging to the window we just closed
|
||||
// to be terminated, to avoid its shutdown interfering when we reset the counters.
|
||||
await processTerminated();
|
||||
}
|
||||
|
||||
dummy.focus();
|
||||
Services.ww.openWindow(null, "chrome://reftest/content/reftest.xul",
|
||||
"_blank", "chrome,dialog=no,all", {});
|
||||
};
|
||||
}
|
||||
|
||||
onShutdown() {
|
||||
resProto.setSubstitution("reftest", null);
|
||||
|
||||
this.chromeHandle.destruct();
|
||||
this.chromeHandle = null;
|
||||
|
||||
if (Services.appinfo.OS == "Android") {
|
||||
Services.wm.removeListener(WindowListener);
|
||||
OnRefTestUnload();
|
||||
Cu.unload("resource://reftest/reftest.jsm");
|
||||
}
|
||||
}
|
||||
};
|
86
layout/tools/reftest/bootstrap.js
vendored
86
layout/tools/reftest/bootstrap.js
vendored
@ -1,86 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const Cm = Components.manager;
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function processTerminated() {
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function observe(subject, topic) {
|
||||
if (topic == "ipc:content-shutdown") {
|
||||
Services.obs.removeObserver(observe, topic);
|
||||
resolve();
|
||||
}
|
||||
}, "ipc:content-shutdown");
|
||||
});
|
||||
}
|
||||
|
||||
var WindowListener = {
|
||||
onOpenWindow: function(xulWin) {
|
||||
Services.wm.removeListener(WindowListener);
|
||||
|
||||
let win = xulWin.docShell.domWindow;
|
||||
win.addEventListener("load", function listener() {
|
||||
// Load into any existing windows.
|
||||
for (win of Services.wm.getEnumerator("navigator:browser")) {
|
||||
break;
|
||||
}
|
||||
|
||||
ChromeUtils.import("chrome://reftest/content/reftest.jsm");
|
||||
win.addEventListener("pageshow", function() {
|
||||
// Add setTimeout here because windows.innerWidth/Height are not set yet.
|
||||
win.setTimeout(function() {OnRefTestLoad(win);}, 0);
|
||||
}, {once: true});
|
||||
}, {once: true});
|
||||
}
|
||||
};
|
||||
|
||||
function startup(data, reason) {
|
||||
if (Services.appinfo.OS == "Android") {
|
||||
Cm.addBootstrappedManifestLocation(data.installPath);
|
||||
Services.wm.addListener(WindowListener);
|
||||
return;
|
||||
}
|
||||
|
||||
let orig = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
|
||||
let ios = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
ios.manageOfflineStatus = false;
|
||||
ios.offline = false;
|
||||
|
||||
let wwatch = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Ci.nsIWindowWatcher);
|
||||
let dummy = wwatch.openWindow(null, "about:blank", "dummy",
|
||||
"chrome,dialog=no,left=800,height=200,width=200,all",null);
|
||||
dummy.onload = async function() {
|
||||
// Close pre-existing window
|
||||
orig.close();
|
||||
|
||||
ChromeUtils.import("chrome://reftest/content/PerTestCoverageUtils.jsm");
|
||||
if (PerTestCoverageUtils.enabled) {
|
||||
// In PerTestCoverage mode, wait for the process belonging to the window we just closed
|
||||
// to be terminated, to avoid its shutdown interfering when we reset the counters.
|
||||
await processTerminated();
|
||||
}
|
||||
|
||||
dummy.focus();
|
||||
wwatch.openWindow(null, "chrome://reftest/content/reftest.xul", "_blank",
|
||||
"chrome,dialog=no,all", {});
|
||||
};
|
||||
}
|
||||
|
||||
function shutdown(data, reason) {
|
||||
if (Services.appinfo.OS == "Android") {
|
||||
Services.wm.removeListener(WindowListener);
|
||||
Cm.removedBootstrappedManifestLocation(data.installPath);
|
||||
OnRefTestUnload();
|
||||
Cu.unload("chrome://reftest/content/reftest.jsm");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function install(data, reason) {}
|
||||
function uninstall(data, reason) {}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user