Bug 1615507. Support reftest-async-scroll--x/y attributes in fission iframes. r=mattwoodrow,kmag

Differential Revision: https://phabricator.services.mozilla.com/D62861
This commit is contained in:
Timothy Nikkel 2020-12-17 10:00:47 +00:00
parent 3a2f3b0a2e
commit 9af22902d0
3 changed files with 122 additions and 54 deletions

View File

@ -111,6 +111,44 @@ class ReftestFissionChild extends JSWindowActorChild {
}
}
setupAsyncScrollOffsetsForElement(element, winUtils, allowFailure, returnStrings) {
let sx = this.attrOrDefault(element, "reftest-async-scroll-x", 0);
let sy = this.attrOrDefault(element, "reftest-async-scroll-y", 0);
if (sx != 0 || sy != 0) {
try {
// This might fail when called from RecordResult since layers
// may not have been constructed yet
winUtils.setAsyncScrollOffset(element, sx, sy);
return true;
} catch (e) {
if (allowFailure) {
returnStrings.infoStrings.push("setupAsyncScrollOffsetsForElement error calling setAsyncScrollOffset: " + e);
} else {
returnStrings.errorStrings.push("setupAsyncScrollOffsetsForElement error calling setAsyncScrollOffset: " + e);
}
}
}
return false;
}
setupAsyncScrollOffsetsForElementSubtree(element, winUtils, allowFailure, returnStrings) {
let updatedAny = this.setupAsyncScrollOffsetsForElement(element, winUtils, returnStrings);
for (let c = element.firstElementChild; c; c = c.nextElementSibling) {
if (this.setupAsyncScrollOffsetsForElementSubtree(c, winUtils, allowFailure, returnStrings)) {
updatedAny = true;
}
}
if (typeof element.contentDocument !== "undefined" &&
element.contentDocument) {
returnStrings.infoStrings.push("setupAsyncScrollOffsetsForElementSubtree Descending into subdocument");
if (this.setupAsyncScrollOffsetsForElementSubtree(element.contentDocument.documentElement,
element.contentWindow.windowUtils, allowFailure, returnStrings)) {
updatedAny = true;
}
}
return updatedAny;
}
receiveMessage(msg) {
switch (msg.name) {
case "ForwardAfterPaintEventToSelfAndParent":
@ -231,6 +269,21 @@ class ReftestFissionChild extends JSWindowActorChild {
return Promise.resolve(returnStrings);
}
case "SetupAsyncScrollOffsets":
{
let returns = {infoStrings: [], errorStrings: [], updatedAny: false};
let contentRootElement = this.document.documentElement;
if (!contentRootElement) {
return returns;
}
let winUtils = this.contentWindow.windowUtils;
returns.updatedAny = this.setupAsyncScrollOffsetsForElementSubtree(contentRootElement, winUtils, msg.data.allowFailure, returns);
return returns;
}
}
}
}

View File

@ -125,6 +125,21 @@ class ReftestFissionParent extends JSWindowActorParent {
}
}
tellChildrenToSetupAsyncScrollOffsets(browsingContext, allowFailure, promises) {
let cwg = browsingContext.currentWindowGlobal;
if (cwg && cwg.isProcessRoot) {
let a = cwg.getActor("ReftestFission");
if (a) {
let responsePromise = a.sendQuery("SetupAsyncScrollOffsets", {allowFailure});
promises.push(responsePromise);
}
}
for (let context of browsingContext.children) {
this.tellChildrenToSetupAsyncScrollOffsets(context, allowFailure, promises);
}
}
receiveMessage(msg) {
switch (msg.name) {
@ -191,6 +206,32 @@ class ReftestFissionParent extends JSWindowActorParent {
});
}
case "SetupAsyncScrollOffsets":
{
let promises = [];
this.tellChildrenToSetupAsyncScrollOffsets(this.manager.browsingContext, msg.data.allowFailure, promises);
return Promise.allSettled(promises).then(function (results) {
let errorStrings = [];
let infoStrings = [];
let updatedAny = false;
for (let r of results) {
if (r.status != "fulfilled") {
// We expect actors to go away causing sendQuery's to fail, so
// just note it.
infoStrings.push("SetupAsyncScrollOffsets sendQuery to child promise rejected: " + r.reason);
continue;
}
errorStrings.push(...r.value.errorStrings);
infoStrings.push(...r.value.infoStrings);
if (r.value.updatedAny) {
updatedAny = true;
}
}
return {errorStrings, infoStrings, updatedAny};
});
}
}
}

View File

@ -326,53 +326,28 @@ function setupDisplayport(contentRootElement) {
// Returns whether any offsets were updated
function setupAsyncScrollOffsets(options) {
var currentDoc = content.document;
var contentRootElement = currentDoc ? currentDoc.documentElement : null;
let currentDoc = content.document;
let contentRootElement = currentDoc ? currentDoc.documentElement : null;
if (!contentRootElement) {
if (!contentRootElement || !contentRootElement.hasAttribute("reftest-async-scroll")) {
return Promise.resolve(false);
}
let allowFailure = options.allowFailure;
let promise = content.windowGlobalChild.getActor("ReftestFission").sendQuery("SetupAsyncScrollOffsets", {allowFailure});
return promise.then(function(result) {
for (let errorString of result.errorStrings) {
LogError(errorString);
}
for (let infoString of result.infoStrings) {
LogInfo(infoString);
}
return result.updatedAny;
},
function(reason) {
LogError("SetupAsyncScrollOffsets SendQuery to parent promise rejected: " + reason);
return false;
}
function setupAsyncScrollOffsetsForElement(element, winUtils) {
var sx = attrOrDefault(element, "reftest-async-scroll-x", 0);
var sy = attrOrDefault(element, "reftest-async-scroll-y", 0);
if (sx != 0 || sy != 0) {
try {
// This might fail when called from RecordResult since layers
// may not have been constructed yet
winUtils.setAsyncScrollOffset(element, sx, sy);
return true;
} catch (e) {
if (!options.allowFailure) {
throw e;
}
}
}
return false;
}
function setupAsyncScrollOffsetsForElementSubtree(element, winUtils) {
var updatedAny = setupAsyncScrollOffsetsForElement(element, winUtils);
for (var c = element.firstElementChild; c; c = c.nextElementSibling) {
if (setupAsyncScrollOffsetsForElementSubtree(c, winUtils)) {
updatedAny = true;
}
}
if (element.contentDocument) {
LogInfo("Descending into subdocument (async offsets)");
if (setupAsyncScrollOffsetsForElementSubtree(element.contentDocument.documentElement,
windowUtilsForWindow(element.contentWindow))) {
updatedAny = true;
}
}
return updatedAny;
}
var asyncScroll = contentRootElement.hasAttribute("reftest-async-scroll");
if (asyncScroll) {
return setupAsyncScrollOffsetsForElementSubtree(contentRootElement, windowUtils());
}
return false;
});
}
function setupAsyncZoom(options) {
@ -1207,7 +1182,7 @@ function CheckForProcessCrashExpectation(contentRootElement)
}
}
function RecordResult(forURL)
async function RecordResult(forURL)
{
if (forURL != gCurrentURL) {
LogInfo("RecordResult fired for previous document");
@ -1278,10 +1253,7 @@ function RecordResult(forURL)
// Setup async scroll offsets now in case SynchronizeForSnapshot is not
// called (due to reftest-no-sync-layers being supplied, or in the single
// process case).
var changedAsyncScrollZoom = false;
if (setupAsyncScrollOffsets({allowFailure:true})) {
changedAsyncScrollZoom = true;
}
let changedAsyncScrollZoom = await setupAsyncScrollOffsets({allowFailure:true});
if (setupAsyncZoom({allowFailure:true})) {
changedAsyncScrollZoom = true;
}
@ -1394,8 +1366,9 @@ function SynchronizeForSnapshot(flags)
// Setup async scroll offsets now, because any scrollable layers should
// have had their AsyncPanZoomControllers created.
setupAsyncScrollOffsets({allowFailure:false});
setupAsyncZoom({allowFailure:false});
return setupAsyncScrollOffsets({allowFailure:false}).then(function(result) {
setupAsyncZoom({allowFailure:false});
});
}, function(reason) {
// We expect actors to go away causing sendQuery's to fail, so
// just note it.
@ -1403,8 +1376,9 @@ function SynchronizeForSnapshot(flags)
// Setup async scroll offsets now, because any scrollable layers should
// have had their AsyncPanZoomControllers created.
setupAsyncScrollOffsets({allowFailure:false});
setupAsyncZoom({allowFailure:false});
return setupAsyncScrollOffsets({allowFailure:false}).then(function(result) {
setupAsyncZoom({allowFailure:false});
});
});
}