mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1648550 - Fix getBoundingClientRect for use element position r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D83256
This commit is contained in:
parent
27932d4e6e
commit
61fc7b177e
@ -14,6 +14,10 @@ text { font: 20px monospace; }
|
||||
<svg id="svg3" width="1" height="1" overflow="hidden">
|
||||
<rect width="2" height="2" fill="yellow"/>
|
||||
</svg>
|
||||
<symbol>
|
||||
<rect id="use-test" width="50" height="10"/>
|
||||
</symbol>
|
||||
<use id="use1" href="#use-test" x="100" y="50" fill="yellow"/>
|
||||
<text id="text1" x="25" y="25">abc</text>
|
||||
<text id="text1a" x="85" y="25" stroke="black" stroke-width="4">abc</text>
|
||||
<rect id="rect1" x="50" y="50" width="50" height="50" fill="green"/>
|
||||
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.8 KiB |
@ -52,10 +52,6 @@ Rect.prototype.roundOut = function() {
|
||||
this.top = Math.floor(this.top);
|
||||
};
|
||||
|
||||
function isWithAbsTolerance(a, b, tolerance, message) {
|
||||
ok(tolerance >= Math.abs(a - b), message + " - got " + a + ", expected " + b + " ± " + tolerance);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
var bounds;
|
||||
|
||||
@ -99,15 +95,21 @@ function runTest() {
|
||||
is(svg3Bounds.width, 1, "svg3.getBoundingClientRect().width");
|
||||
is(svg3Bounds.height, 1, "svg3.getBoundingClientRect().height");
|
||||
|
||||
var use1Bounds = doc.getElementById("use1").getBoundingClientRect();
|
||||
is(use1Bounds.left, 100, "use1.getBoundingClientRect().left");
|
||||
is(use1Bounds.top, 50, "use1.getBoundingClientRect().top");
|
||||
is(use1Bounds.width, 50, "use1.getBoundingClientRect().width");
|
||||
is(use1Bounds.height, 10, "use1.getBoundingClientRect().height");
|
||||
|
||||
var text1 = doc.getElementById("text1");
|
||||
|
||||
var text1Bounds = text1.getBoundingClientRect();
|
||||
var text2Bounds = doc.getElementById("text2").getBoundingClientRect();
|
||||
var text3Bounds = doc.getElementById("text3").getBoundingClientRect();
|
||||
|
||||
var sin45 = Math.sin(Math.PI / 4);
|
||||
const sin45 = Math.sin(Math.PI / 4);
|
||||
|
||||
isWithAbsTolerance(text1Bounds.left, 24, 1, "text1.getBoundingClientRect().left");
|
||||
isfuzzy(text1Bounds.left, 24, 1, "text1.getBoundingClientRect().left");
|
||||
|
||||
is(text2Bounds.left, text1Bounds.left + 100, "text2.getBoundingClientRect().left");
|
||||
is(text2Bounds.top, text1Bounds.top, "text2.getBoundingClientRect().top");
|
||||
@ -115,8 +117,8 @@ function runTest() {
|
||||
is(text2Bounds.height, text1Bounds.height, "text2.getBoundingClientRect().height");
|
||||
|
||||
var r = (text1Bounds.width + text1Bounds.height) * sin45;
|
||||
isWithAbsTolerance(text3Bounds.width, Math.ceil(r), 1, "text3.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(text3Bounds.height, Math.ceil(r), 1, "text3.getBoundingClientRect().height");
|
||||
isfuzzy(text3Bounds.width, Math.ceil(r), 1, "text3.getBoundingClientRect().width");
|
||||
isfuzzy(text3Bounds.height, Math.ceil(r), 1, "text3.getBoundingClientRect().height");
|
||||
|
||||
var rect1Bounds = doc.getElementById("rect1").getBoundingClientRect();
|
||||
var rect2Bounds = doc.getElementById("rect2").getBoundingClientRect();
|
||||
@ -129,10 +131,10 @@ function runTest() {
|
||||
is(rect1Bounds.height, 50, "rect1.getBoundingClientRect().height");
|
||||
|
||||
var rect = new Rect(175 - 50 * sin45, 75 - 50 * sin45, 50 * sin45 * 2, 50 * sin45 * 2);
|
||||
isWithAbsTolerance(rect2Bounds.left, rect.left, 0.1, "rect2.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(rect2Bounds.top, rect.top, 0.1, "rect2.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(rect2Bounds.width, rect.width, 0.1, "rect2.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(rect2Bounds.height, rect.height, 0.1, "rect2.getBoundingClientRect().height");
|
||||
isfuzzy(rect2Bounds.left, rect.left, 0.1, "rect2.getBoundingClientRect().left");
|
||||
isfuzzy(rect2Bounds.top, rect.top, 0.1, "rect2.getBoundingClientRect().top");
|
||||
isfuzzy(rect2Bounds.width, rect.width, 0.1, "rect2.getBoundingClientRect().width");
|
||||
isfuzzy(rect2Bounds.height, rect.height, 0.1, "rect2.getBoundingClientRect().height");
|
||||
|
||||
is(rect3Bounds.left, 50, "rect3.getBoundingClientRect().left");
|
||||
is(rect3Bounds.top, 160, "rect3.getBoundingClientRect().top");
|
||||
@ -140,10 +142,10 @@ function runTest() {
|
||||
is(rect3Bounds.height, 100, "rect3.getBoundingClientRect().height");
|
||||
|
||||
rect = new Rect(350 - 100 * sin45, 150 - 100 * sin45, 100 * sin45 * 2, 100 * sin45 * 2);
|
||||
isWithAbsTolerance(rect4Bounds.left, rect.left, 0.1, "rect4.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(rect4Bounds.top, rect.top, 0.1, "rect4.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(rect4Bounds.width, rect.width, 0.1, "rect4.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(rect4Bounds.height, rect.height, 0.1, "rect4.getBoundingClientRect().height");
|
||||
isfuzzy(rect4Bounds.left, rect.left, 0.1, "rect4.getBoundingClientRect().left");
|
||||
isfuzzy(rect4Bounds.top, rect.top, 0.1, "rect4.getBoundingClientRect().top");
|
||||
isfuzzy(rect4Bounds.width, rect.width, 0.1, "rect4.getBoundingClientRect().width");
|
||||
isfuzzy(rect4Bounds.height, rect.height, 0.1, "rect4.getBoundingClientRect().height");
|
||||
|
||||
var rect1aBounds = doc.getElementById("rect1a").getBoundingClientRect();
|
||||
var rect2aBounds = doc.getElementById("rect2a").getBoundingClientRect();
|
||||
@ -157,40 +159,39 @@ function runTest() {
|
||||
is(rect1aBounds.height, 54, "rect1a.getBoundingClientRect().height");
|
||||
|
||||
rect = new Rect(175 - 54 * sin45, 75 - 54 * sin45, 54 * sin45 * 2, 54 * sin45 * 2);
|
||||
isWithAbsTolerance(rect2aBounds.left, rect.left, 0.1, "rect2a.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(rect2aBounds.top, rect.top, 0.1, "rect2a.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(rect2aBounds.width, rect.width, 0.1, "rect2a.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(rect2aBounds.height, rect.height, 0.1, "rect2a.getBoundingClientRect().height");
|
||||
isfuzzy(rect2aBounds.left, rect.left, 0.1, "rect2a.getBoundingClientRect().left");
|
||||
isfuzzy(rect2aBounds.top, rect.top, 0.1, "rect2a.getBoundingClientRect().top");
|
||||
isfuzzy(rect2aBounds.width, rect.width, 0.1, "rect2a.getBoundingClientRect().width");
|
||||
isfuzzy(rect2aBounds.height, rect.height, 0.1, "rect2a.getBoundingClientRect().height");
|
||||
|
||||
is(rect3aBounds.left, 46, "rect3a.getBoundingClientRect().left");
|
||||
is(rect3aBounds.top, 156, "rect3a.getBoundingClientRect().top");
|
||||
is(rect3aBounds.width, 108, "rect3a.getBoundingClientRect().width");
|
||||
is(rect3aBounds.height, 108, "rect3a.getBoundingClientRect().height");
|
||||
|
||||
isWithAbsTolerance(rect3bBounds.left, 198, 0.1, "rect3b.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(rect3bBounds.top, 198, 0.1, "rect3b.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(rect3bBounds.width, 54, 0.1, "rect3b.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(rect3bBounds.height, 54, 0.1, "rect3b.getBoundingClientRect().height");
|
||||
isfuzzy(rect3bBounds.left, 198, 0.1, "rect3b.getBoundingClientRect().left");
|
||||
isfuzzy(rect3bBounds.top, 198, 0.1, "rect3b.getBoundingClientRect().top");
|
||||
isfuzzy(rect3bBounds.width, 54, 0.1, "rect3b.getBoundingClientRect().width");
|
||||
isfuzzy(rect3bBounds.height, 54, 0.1, "rect3b.getBoundingClientRect().height");
|
||||
|
||||
rect = new Rect(350 - 108 * sin45, 150 - 108 * sin45, 108 * sin45 * 2, 108 * sin45 * 2);
|
||||
isWithAbsTolerance(rect4aBounds.left, rect.left, 0.1, "rect4a.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(rect4aBounds.top, rect.top, 0.1, "rect4a.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(rect4aBounds.width, rect.width, 0.1, "rect4a.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(rect4aBounds.height, rect.height, 0.1, "rect4a.getBoundingClientRect().height");
|
||||
isfuzzy(rect4aBounds.left, rect.left, 0.1, "rect4a.getBoundingClientRect().left");
|
||||
isfuzzy(rect4aBounds.top, rect.top, 0.1, "rect4a.getBoundingClientRect().top");
|
||||
isfuzzy(rect4aBounds.width, rect.width, 0.1, "rect4a.getBoundingClientRect().width");
|
||||
isfuzzy(rect4aBounds.height, rect.height, 0.1, "rect4a.getBoundingClientRect().height");
|
||||
|
||||
var text1a = doc.getElementById("text1a");
|
||||
|
||||
var text1aBounds = text1a.getBoundingClientRect();
|
||||
var text2aBounds = doc.getElementById("text2a").getBoundingClientRect();
|
||||
|
||||
isWithAbsTolerance(text1aBounds.left, 82, 1, "text1a.getBoundingClientRect().left");
|
||||
isfuzzy(text1aBounds.left, 82, 1, "text1a.getBoundingClientRect().left");
|
||||
is(text1aBounds.width, text1Bounds.width + 4, "text1a.getBoundingClientRect().width");
|
||||
|
||||
is(text2aBounds.left, text1aBounds.left + 100 - 3, "text2a.getBoundingClientRect().left");
|
||||
is(text2aBounds.width, text1aBounds.width + 6, "text2a.getBoundingClientRect().width");
|
||||
|
||||
var i = doc.getElementById("i");
|
||||
var iBounds = i.getBoundingClientRect();
|
||||
var iBounds = doc.getElementById("i").getBoundingClientRect();
|
||||
is(iBounds.left, 20, "i.getBoundingClientRect().left");
|
||||
is(iBounds.top, 20, "i.getBoundingClientRect().top");
|
||||
is(iBounds.width, 200, "i.getBoundingClientRect().width");
|
||||
@ -210,35 +211,35 @@ function runTest() {
|
||||
|
||||
var nonScalingStrokedCircle1Bounds =
|
||||
doc.getElementById("nonScalingStrokedCircle1").getBoundingClientRect();
|
||||
isWithAbsTolerance(nonScalingStrokedCircle1Bounds.left, 10, 0.15,
|
||||
isfuzzy(nonScalingStrokedCircle1Bounds.left, 10, 0.15,
|
||||
"nonScalingStrokedCircle1.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(nonScalingStrokedCircle1Bounds.top, 105, 0.15,
|
||||
isfuzzy(nonScalingStrokedCircle1Bounds.top, 105, 0.15,
|
||||
"nonScalingStrokedCircle1.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(nonScalingStrokedCircle1Bounds.width, 70, 0.15,
|
||||
isfuzzy(nonScalingStrokedCircle1Bounds.width, 70, 0.15,
|
||||
"nonScalingStrokedCircle1.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(nonScalingStrokedCircle1Bounds.height, 50, 0.15,
|
||||
isfuzzy(nonScalingStrokedCircle1Bounds.height, 50, 0.15,
|
||||
"nonScalingStrokedCircle1.getBoundingClientRect().height");
|
||||
|
||||
var nonScalingStrokedEllipse1Bounds =
|
||||
doc.getElementById("nonScalingStrokedEllipse1").getBoundingClientRect();
|
||||
isWithAbsTolerance(nonScalingStrokedEllipse1Bounds.left, 5, 0.15,
|
||||
isfuzzy(nonScalingStrokedEllipse1Bounds.left, 5, 0.15,
|
||||
"nonScalingStrokedEllipse1.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(nonScalingStrokedEllipse1Bounds.top, 40, 0.15,
|
||||
isfuzzy(nonScalingStrokedEllipse1Bounds.top, 40, 0.15,
|
||||
"nonScalingStrokedEllipse1.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(nonScalingStrokedEllipse1Bounds.width, 30, 0.15,
|
||||
isfuzzy(nonScalingStrokedEllipse1Bounds.width, 30, 0.15,
|
||||
"nonScalingStrokedEllipse1.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(nonScalingStrokedEllipse1Bounds.height, 40, 0.15,
|
||||
isfuzzy(nonScalingStrokedEllipse1Bounds.height, 40, 0.15,
|
||||
"nonScalingStrokedEllipse1.getBoundingClientRect().height");
|
||||
|
||||
var nonScalingStrokedLine1Bounds =
|
||||
doc.getElementById("nonScalingStrokedLine1").getBoundingClientRect();
|
||||
isWithAbsTolerance(nonScalingStrokedLine1Bounds.left, 235, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine1Bounds.left, 235, 0.1,
|
||||
"nonScalingStrokedLine1.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(nonScalingStrokedLine1Bounds.top, 10, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine1Bounds.top, 10, 0.1,
|
||||
"nonScalingStrokedLine1.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(nonScalingStrokedLine1Bounds.width, 10, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine1Bounds.width, 10, 0.1,
|
||||
"nonScalingStrokedLine1.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(nonScalingStrokedLine1Bounds.height, 25, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine1Bounds.height, 25, 0.1,
|
||||
"nonScalingStrokedLine1.getBoundingClientRect().height");
|
||||
|
||||
var nonScalingStrokedLine2Bounds =
|
||||
@ -246,13 +247,13 @@ function runTest() {
|
||||
var capDelta = 5 / Math.SQRT2 + 5 / Math.SQRT2;
|
||||
rect = new Rect(260 - capDelta, 15 - capDelta, 20 / Math.SQRT2 + 2 * capDelta,
|
||||
20 / Math.SQRT2 + 2 * capDelta);
|
||||
isWithAbsTolerance(nonScalingStrokedLine2Bounds.left, rect.left, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine2Bounds.left, rect.left, 0.1,
|
||||
"nonScalingStrokedLine2.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(nonScalingStrokedLine2Bounds.top, rect.top, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine2Bounds.top, rect.top, 0.1,
|
||||
"nonScalingStrokedLine2.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(nonScalingStrokedLine2Bounds.width, rect.width, 0.15,
|
||||
isfuzzy(nonScalingStrokedLine2Bounds.width, rect.width, 0.15,
|
||||
"nonScalingStrokedLine2.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(nonScalingStrokedLine2Bounds.height, rect.height, 0.15,
|
||||
isfuzzy(nonScalingStrokedLine2Bounds.height, rect.height, 0.15,
|
||||
"nonScalingStrokedLine2.getBoundingClientRect().height");
|
||||
|
||||
var nonScalingStrokedLine3Bounds =
|
||||
@ -260,36 +261,33 @@ function runTest() {
|
||||
capDelta = 5 / Math.SQRT2;
|
||||
rect = new Rect(280 - capDelta, 15 - capDelta, 20 / Math.SQRT2 + 2 * capDelta,
|
||||
20 / Math.SQRT2 + 2 * capDelta);
|
||||
isWithAbsTolerance(nonScalingStrokedLine3Bounds.left, rect.left, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine3Bounds.left, rect.left, 0.1,
|
||||
"nonScalingStrokedLine3.getBoundingClientRect().left");
|
||||
isWithAbsTolerance(nonScalingStrokedLine3Bounds.top, rect.top, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine3Bounds.top, rect.top, 0.1,
|
||||
"nonScalingStrokedLine3.getBoundingClientRect().top");
|
||||
isWithAbsTolerance(nonScalingStrokedLine3Bounds.width, rect.width, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine3Bounds.width, rect.width, 0.1,
|
||||
"nonScalingStrokedLine3.getBoundingClientRect().width");
|
||||
isWithAbsTolerance(nonScalingStrokedLine3Bounds.height, rect.height, 0.1,
|
||||
isfuzzy(nonScalingStrokedLine3Bounds.height, rect.height, 0.1,
|
||||
"nonScalingStrokedLine3.getBoundingClientRect().height");
|
||||
|
||||
var shapeWithMarker1Bounds =
|
||||
doc.getElementById("shapeWithMarker1").getBoundingClientRect();
|
||||
isWithAbsTolerance(shapeWithMarker1Bounds.left, 160, 0.1,
|
||||
isfuzzy(shapeWithMarker1Bounds.left, 160, 0.1,
|
||||
"shapeWithMarker1Bounds.left");
|
||||
isWithAbsTolerance(shapeWithMarker1Bounds.top, 120, 0.1,
|
||||
isfuzzy(shapeWithMarker1Bounds.top, 120, 0.1,
|
||||
"shapeWithMarker1Bounds.top");
|
||||
isWithAbsTolerance(shapeWithMarker1Bounds.width, 10 + Math.SQRT2 * 50, 0.1,
|
||||
isfuzzy(shapeWithMarker1Bounds.width, 10 + Math.SQRT2 * 50, 0.1,
|
||||
"shapeWithMarker1Bounds.width");
|
||||
isWithAbsTolerance(shapeWithMarker1Bounds.height, 20, 0.1,
|
||||
isfuzzy(shapeWithMarker1Bounds.height, 20, 0.1,
|
||||
"shapeWithMarker1Bounds.height");
|
||||
|
||||
var rotatedLine1Bounds =
|
||||
doc.getElementById("rotatedLine1").getBoundingClientRect();
|
||||
isWithAbsTolerance(rotatedLine1Bounds.left, 160, 0.1,
|
||||
"rotatedLine1Bounds.left");
|
||||
isWithAbsTolerance(rotatedLine1Bounds.top, 145, 0.1,
|
||||
"rotatedLine1Bounds.top");
|
||||
isWithAbsTolerance(rotatedLine1Bounds.width, Math.SQRT2 * 20, 0.1,
|
||||
isfuzzy(rotatedLine1Bounds.left, 160, 0.1, "rotatedLine1Bounds.left");
|
||||
isfuzzy(rotatedLine1Bounds.top, 145, 0.1, "rotatedLine1Bounds.top");
|
||||
isfuzzy(rotatedLine1Bounds.width, Math.SQRT2 * 20, 0.1,
|
||||
"rotatedLine1Bounds.width");
|
||||
isWithAbsTolerance(rotatedLine1Bounds.height, 10, 0.1,
|
||||
"rotatedLine1Bounds.height");
|
||||
isfuzzy(rotatedLine1Bounds.height, 10, 0.1, "rotatedLine1Bounds.height");
|
||||
|
||||
var cssTransRect2Bounds =
|
||||
doc.getElementById("css-trans-rect-2").getBoundingClientRect();
|
||||
|
@ -132,4 +132,18 @@ void SVGUseFrame::NotifySVGChanged(uint32_t aFlags) {
|
||||
SVGGFrame::NotifySVGChanged(aFlags);
|
||||
}
|
||||
|
||||
SVGBBox SVGUseFrame::GetBBoxContribution(const Matrix& aToBBoxUserspace,
|
||||
uint32_t aFlags) {
|
||||
SVGBBox bbox =
|
||||
SVGDisplayContainerFrame::GetBBoxContribution(aToBBoxUserspace, aFlags);
|
||||
|
||||
if (aFlags & SVGUtils::eForGetClientRects) {
|
||||
float x, y;
|
||||
static_cast<SVGUseElement*>(GetContent())
|
||||
->GetAnimatedLengthValues(&x, &y, nullptr);
|
||||
bbox.MoveBy(x, y);
|
||||
}
|
||||
return bbox;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -56,6 +56,8 @@ class SVGUseFrame final : public SVGGFrame {
|
||||
// ISVGDisplayableFrame interface:
|
||||
void ReflowSVG() override;
|
||||
void NotifySVGChanged(uint32_t aFlags) override;
|
||||
SVGBBox GetBBoxContribution(const Matrix& aToBBoxUserspace,
|
||||
uint32_t aFlags) override;
|
||||
|
||||
private:
|
||||
bool mHasValidDimensions;
|
||||
|
@ -97,6 +97,7 @@ class SVGBBox final {
|
||||
bool IsFinite() const { return mBBox.IsFinite(); }
|
||||
|
||||
void Scale(float aScale) { mBBox.Scale(aScale); }
|
||||
void MoveBy(float x, float y) { mBBox.MoveBy(x, y); }
|
||||
|
||||
void UnionEdges(const SVGBBox& aSVGBBox) {
|
||||
if (aSVGBBox.mIsEmpty) {
|
||||
|
Loading…
Reference in New Issue
Block a user