Bug 1937320 - Style of mapped attributes is not updated when changed r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D232157
This commit is contained in:
longsonr
2024-12-16 21:14:28 +00:00
parent 16ba2bd62e
commit 13716f4e33
3 changed files with 53 additions and 28 deletions

View File

@@ -173,8 +173,7 @@ static Point GetPointFrom(const DOMPointInit& aPoint) {
}
bool SVGGeometryElement::IsPointInFill(const DOMPointInit& aPoint) {
// d is a presentation attribute, so make sure style is up to date:
FlushStyleIfNeeded();
FlushIfNeeded();
RefPtr<Path> path = GetOrBuildPathForHitTest();
if (!path) {
@@ -188,9 +187,7 @@ bool SVGGeometryElement::IsPointInFill(const DOMPointInit& aPoint) {
bool SVGGeometryElement::IsPointInStroke(const DOMPointInit& aPoint) {
// stroke-* attributes and the d attribute are presentation attributes, so we
// flush the layout before building the path.
if (auto* doc = GetComposedDoc()) {
doc->FlushPendingNotifications(FlushType::Layout);
}
Unused << GetPrimaryFrame(FlushType::Layout);
RefPtr<Path> path = GetOrBuildPathForHitTest();
if (!path) {
@@ -222,15 +219,14 @@ bool SVGGeometryElement::IsPointInStroke(const DOMPointInit& aPoint) {
}
float SVGGeometryElement::GetTotalLengthForBinding() {
// d is a presentation attribute, so make sure style is up to date:
FlushStyleIfNeeded();
FlushIfNeeded();
return GetTotalLength();
}
already_AddRefed<DOMSVGPoint> SVGGeometryElement::GetPointAtLength(
float distance, ErrorResult& rv) {
// d is a presentation attribute, so make sure style is up to date:
FlushStyleIfNeeded();
FlushIfNeeded();
RefPtr<Path> path = GetOrBuildPathForMeasuring();
if (!path) {
rv.ThrowInvalidStateError("No path available for measuring");
@@ -297,20 +293,10 @@ float SVGGeometryElement::GetTotalLength() {
return flat ? flat->ComputeLength() : 0.f;
}
void SVGGeometryElement::FlushStyleIfNeeded() {
// Note: we still can set d property on other elements which don't have d
// attribute, but we don't look at the d property on them, so here we only
// care about the element with d attribute, i.e. SVG path element.
if (GetPathDataAttrName() != nsGkAtoms::d) {
return;
}
RefPtr<Document> doc = GetComposedDoc();
if (!doc) {
return;
}
doc->FlushPendingNotifications(FlushType::Style);
void SVGGeometryElement::FlushIfNeeded() {
FlushType flushType =
GeometryDependsOnCoordCtx() ? FlushType::Layout : FlushType::Style;
Unused << GetPrimaryFrame(flushType);
}
} // namespace mozilla::dom

View File

@@ -253,9 +253,7 @@ class SVGGeometryElement : public SVGGeometryElementBase {
// SVGElement method
NumberAttributesInfo GetNumberInfo() override;
// d is a presentation attribute, so we would like to make sure style is
// up-to-date. This function flushes the style if the path attribute is d.
MOZ_CAN_RUN_SCRIPT void FlushStyleIfNeeded();
MOZ_CAN_RUN_SCRIPT void FlushIfNeeded();
SVGAnimatedNumber mPathLength;
static NumberInfo sNumberInfo;

View File

@@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml">
<title>SVGGeometryElement.prototype.getTotalLength() query with 'pathLength'</title>
<title>SVGGeometryElement.prototype.getTotalLength()</title>
<h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getTotalLength"/>
<h:script src="/resources/testharness.js"/>
<h:script src="/resources/testharnessreport.js"/>
@@ -9,6 +9,47 @@ test(function() {
path.setAttribute('d', 'M0,0L100,0L100,100');
path.setAttribute('pathLength', '1000');
assert_approx_equals(path.getTotalLength(), 200, 1e-5);
}, document.title+', getTotalLength');
}, document.title+', getTotalLength - path with pathLength');
test(function() {
let rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('width', '100');
rect.setAttribute('height', '100');
assert_equals(rect.getTotalLength(), 400);
rect.setAttribute('width', '50');
rect.setAttribute('height', '50');
assert_equals(rect.getTotalLength(), 200);
}, document.title+', getTotalLength - rect');
test(function() {
let rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
document.documentElement.appendChild(rect);
try {
rect.setAttribute('width', '100');
rect.setAttribute('height', '100');
assert_equals(rect.getTotalLength(), 400);
rect.setAttribute('width', '50');
rect.setAttribute('height', '50');
assert_equals(rect.getTotalLength(), 200);
} finally {
document.documentElement.removeChild(rect);
}
}, document.title+', getTotalLength - rect in document');
test(function() {
let rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
document.documentElement.appendChild(rect);
try {
document.documentElement.setAttribute("height", "50");
rect.setAttribute('width', '50');
rect.setAttribute('height', '100%');
assert_equals(rect.getTotalLength(), 200);
} finally {
document.documentElement.removeAttribute("height");
document.documentElement.removeChild(rect);
}
}, document.title+', getTotalLength - rect in document with percent units');
</script>
</svg>

Before

Width:  |  Height:  |  Size: 698 B

After

Width:  |  Height:  |  Size: 2.1 KiB