зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1615505. Forward MozAfterPaint events from child processes to the reftest harness. r=kmag,mattwoodrow
Differential Revision: https://phabricator.services.mozilla.com/D62859 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
310400ad9a
Коммит
5c0874aab0
|
@ -2,8 +2,67 @@ var EXPORTED_SYMBOLS = ["ReftestFissionChild"];
|
|||
|
||||
class ReftestFissionChild extends JSWindowActorChild {
|
||||
|
||||
forwardAfterPaintEventToParent(rects, originalTargetUri, dispatchToSelfAsWell) {
|
||||
if (dispatchToSelfAsWell) {
|
||||
let event = new this.contentWindow.CustomEvent("Reftest:MozAfterPaintFromChild",
|
||||
{bubbles: true, detail: {rects, originalTargetUri}});
|
||||
this.contentWindow.dispatchEvent(event);
|
||||
}
|
||||
|
||||
let parentContext = this.browsingContext.parent;
|
||||
if (parentContext) {
|
||||
this.sendAsyncMessage("ForwardAfterPaintEvent",
|
||||
{toBrowsingContext: parentContext, fromBrowsingContext: this.browsingContext,
|
||||
rects, originalTargetUri});
|
||||
}
|
||||
}
|
||||
|
||||
handleEvent(evt) {
|
||||
switch (evt.type) {
|
||||
case "MozAfterPaint":
|
||||
// We want to forward any after paint events to our parent document so that
|
||||
// that it reaches the root content document where the main reftest harness
|
||||
// code (reftest-content.js) will process it and update the canvas.
|
||||
var rects = [];
|
||||
for (let r of evt.clientRects) {
|
||||
rects.push({ left: r.left, top: r.top, right: r.right, bottom: r.bottom });
|
||||
}
|
||||
this.forwardAfterPaintEventToParent(rects, this.document.documentURI, /* dispatchToSelfAsWell */ false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
transformRect(transform, rect) {
|
||||
let p1 = transform.transformPoint({x: rect.left, y: rect.top});
|
||||
let p2 = transform.transformPoint({x: rect.right, y: rect.top});
|
||||
let p3 = transform.transformPoint({x: rect.left, y: rect.bottom});
|
||||
let p4 = transform.transformPoint({x: rect.right, y: rect.bottom});
|
||||
let quad = new DOMQuad(p1, p2, p3, p4);
|
||||
return quad.getBounds();
|
||||
}
|
||||
|
||||
receiveMessage(msg) {
|
||||
switch (msg.name) {
|
||||
case "ForwardAfterPaintEventToSelfAndParent":
|
||||
{
|
||||
// Transform the rects from fromBrowsingContext to us.
|
||||
// We first translate from the content rect to the border rect of the iframe.
|
||||
let style = this.contentWindow.getComputedStyle(msg.data.fromBrowsingContext.embedderElement);
|
||||
let translate = new DOMMatrixReadOnly().translate(
|
||||
parseFloat(style.paddingLeft) + parseFloat(style.borderLeftWidth),
|
||||
parseFloat(style.paddingTop) + parseFloat(style.borderTopWidth));
|
||||
|
||||
// Then we transform from the iframe to our root frame.
|
||||
// We are guaranteed to be the process with the embedderElement for fromBrowsingContext.
|
||||
let transform = msg.data.fromBrowsingContext.embedderElement.getTransformToViewport();
|
||||
let combined = translate.multiply(transform);
|
||||
|
||||
let newrects = msg.data.rects.map(r => this.transformRect(combined, r))
|
||||
|
||||
this.forwardAfterPaintEventToParent(newrects, msg.data.originalTargetUri, /* dispatchToSelfAsWell */ true);
|
||||
break;
|
||||
}
|
||||
|
||||
case "EmptyMessage":
|
||||
return undefined;
|
||||
case "UpdateLayerTree":
|
||||
|
|
|
@ -112,6 +112,17 @@ class ReftestFissionParent extends JSWindowActorParent {
|
|||
|
||||
receiveMessage(msg) {
|
||||
switch (msg.name) {
|
||||
case "ForwardAfterPaintEvent":
|
||||
{
|
||||
let cwg = msg.data.toBrowsingContext.currentWindowGlobal;
|
||||
if (cwg) {
|
||||
let a = cwg.getActor("ReftestFission");
|
||||
if (a) {
|
||||
a.sendAsyncMessage("ForwardAfterPaintEventToSelfAndParent", msg.data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "FlushRendering":
|
||||
{
|
||||
let promise = this.tellChildrenToFlushRendering(msg.data.browsingContext, msg.data.ignoreThrottledAnimations);
|
||||
|
|
|
@ -652,6 +652,20 @@ function WaitForTestEnd(contentRootElement, inPrintMode, spellCheckedElements, f
|
|||
}
|
||||
}
|
||||
|
||||
// true if rectA contains rectB
|
||||
function Contains(rectA, rectB) {
|
||||
return (rectA.left <= rectB.left && rectB.right <= rectA.right && rectA.top <= rectB.top && rectB.bottom <= rectA.bottom);
|
||||
}
|
||||
// true if some rect in rectList contains rect
|
||||
function ContainedIn(rectList, rect) {
|
||||
for (let i = 0; i < rectList.length; ++i) {
|
||||
if (Contains(rectList[i], rect)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function AfterPaintListener(event) {
|
||||
LogInfo("AfterPaintListener in " + event.target.document.location.href);
|
||||
if (event.target.document != currentDoc) {
|
||||
|
@ -660,23 +674,8 @@ function WaitForTestEnd(contentRootElement, inPrintMode, spellCheckedElements, f
|
|||
return;
|
||||
}
|
||||
|
||||
// true if rectA contains rectB
|
||||
function Contains(rectA, rectB) {
|
||||
return (rectA.left <= rectB.left && rectB.right <= rectA.right && rectA.top <= rectB.top && rectB.bottom <= rectA.bottom);
|
||||
}
|
||||
// true if some rect in rectList contains rect
|
||||
function ContainedIn(rectList, rect) {
|
||||
for (let i = 0; i < rectList.length; ++i) {
|
||||
if (Contains(rectList[i], rect)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
updateCanvasPending = true;
|
||||
for (let i = 0; i < event.clientRects.length; ++i) {
|
||||
let r = event.clientRects[i];
|
||||
for (let r of event.clientRects) {
|
||||
if (ContainedIn(updateCanvasRects, r)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -700,6 +699,29 @@ function WaitForTestEnd(contentRootElement, inPrintMode, spellCheckedElements, f
|
|||
// call, so we don't need to do anything.
|
||||
}
|
||||
|
||||
function FromChildAfterPaintListener(event) {
|
||||
LogInfo("FromChildAfterPaintListener from " + event.detail.originalTargetUri);
|
||||
|
||||
updateCanvasPending = true;
|
||||
for (let r of event.detail.rects) {
|
||||
if (ContainedIn(updateCanvasRects, r)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Copy the rect; it's content and we are chrome, which means if the
|
||||
// document goes away (and it can in some crashtests) our reference
|
||||
// to it will be turned into a dead wrapper that we can't acccess.
|
||||
updateCanvasRects.push({ left: r.left, top: r.top, right: r.right, bottom: r.bottom });
|
||||
}
|
||||
|
||||
if (!operationInProgress) {
|
||||
HandlePendingTasksAfterMakeProgress();
|
||||
}
|
||||
// Otherwise we know that eventually after the operation finishes we
|
||||
// will get a MakeProgress and/or HandlePendingTasksAfterMakeProgress
|
||||
// call, so we don't need to do anything.
|
||||
}
|
||||
|
||||
function AttrModifiedListener() {
|
||||
LogInfo("AttrModifiedListener fired");
|
||||
// Wait for the next return-to-event-loop before continuing --- for
|
||||
|
@ -719,6 +741,7 @@ function WaitForTestEnd(contentRootElement, inPrintMode, spellCheckedElements, f
|
|||
function RemoveListeners() {
|
||||
// OK, we can end the test now.
|
||||
removeEventListener("MozAfterPaint", AfterPaintListener, false);
|
||||
removeEventListener("Reftest:MozAfterPaintFromChild", FromChildAfterPaintListener, false);
|
||||
CheckForLivenessOfContentRootElement();
|
||||
if (contentRootElement) {
|
||||
contentRootElement.removeEventListener("DOMAttrModified", AttrModifiedListener);
|
||||
|
@ -968,6 +991,8 @@ function WaitForTestEnd(contentRootElement, inPrintMode, spellCheckedElements, f
|
|||
|
||||
LogInfo("WaitForTestEnd: Adding listeners");
|
||||
addEventListener("MozAfterPaint", AfterPaintListener, false);
|
||||
addEventListener("Reftest:MozAfterPaintFromChild", FromChildAfterPaintListener, false);
|
||||
|
||||
// If contentRootElement is null then shouldWaitForReftestWaitRemoval will
|
||||
// always return false so we don't need a listener anyway
|
||||
CheckForLivenessOfContentRootElement();
|
||||
|
|
|
@ -1576,6 +1576,9 @@ function RegisterMessageListenersAndLoadContentScript(aReload)
|
|||
},
|
||||
child: {
|
||||
moduleURI: "resource://reftest/ReftestFissionChild.jsm",
|
||||
events: {
|
||||
MozAfterPaint: {},
|
||||
},
|
||||
},
|
||||
allFrames: true,
|
||||
includeChrome: true,
|
||||
|
|
Загрузка…
Ссылка в новой задаче