-
Notifications
You must be signed in to change notification settings - Fork 54
/
ReftestFissionChild.jsm
140 lines (121 loc) · 5.19 KB
/
ReftestFissionChild.jsm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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":
{
let errorStrings = [];
try {
if (this.manager.isProcessRoot) {
this.contentWindow.windowUtils.updateLayerTree();
}
} catch (e) {
errorStrings.push("updateLayerTree failed: " + e);
}
return Promise.resolve({errorStrings});
}
case "FlushRendering":
{
let errorStrings = [];
let warningStrings = [];
let infoStrings = [];
try {
let ignoreThrottledAnimations = msg.data.ignoreThrottledAnimations;
if (this.manager.isProcessRoot) {
var anyPendingPaintsGeneratedInDescendants = false;
function flushWindow(win) {
var utils = win.windowUtils;
var afterPaintWasPending = utils.isMozAfterPaintPending;
var root = win.document.documentElement;
if (root && !root.classList.contains("reftest-no-flush")) {
try {
if (ignoreThrottledAnimations) {
utils.flushLayoutWithoutThrottledAnimations();
} else {
root.getBoundingClientRect();
}
} catch (e) {
warningStrings.push("flushWindow failed: " + e + "\n");
}
}
if (!afterPaintWasPending && utils.isMozAfterPaintPending) {
infoStrings.push("FlushRendering generated paint for window " + win.location.href);
anyPendingPaintsGeneratedInDescendants = true;
}
for (let i = 0; i < win.frames.length; ++i) {
try {
if (!Cu.isRemoteProxy(win.frames[i])) {
flushWindow(win.frames[i]);
}
} catch (e) {
Cu.reportError(e);
}
}
}
flushWindow(this.contentWindow);
if (anyPendingPaintsGeneratedInDescendants &&
!this.contentWindow.windowUtils.isMozAfterPaintPending) {
warningStrings.push("Internal error: descendant frame generated a MozAfterPaint event, but the root document doesn't have one!");
}
}
} catch (e) {
errorStrings.push("flushWindow failed: " + e);
}
return Promise.resolve({errorStrings, warningStrings, infoStrings});
}
}
}
}