mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1902675 - animations should not run in inactive switch children or if they are children of elements that have failed conditional processing tests r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D213848
This commit is contained in:
parent
266c474a97
commit
0d068a2c72
@ -6,6 +6,7 @@
|
||||
|
||||
#include "mozilla/dom/SVGAnimationElement.h"
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "mozilla/dom/SVGSwitchElement.h"
|
||||
#include "mozilla/dom/BindContext.h"
|
||||
#include "mozilla/dom/ElementInlines.h"
|
||||
#include "mozilla/SMILAnimationController.h"
|
||||
@ -152,6 +153,7 @@ nsresult SVGAnimationElement::BindToTree(BindContext& aContext,
|
||||
mTimedElement.BindToTree(*this);
|
||||
}
|
||||
|
||||
mTimedElement.SetIsDisabled(IsDisabled());
|
||||
AnimationNeedsResample();
|
||||
|
||||
return NS_OK;
|
||||
@ -228,8 +230,7 @@ void SVGAnimationElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
||||
aSubjectPrincipal, aNotify);
|
||||
|
||||
if (SVGTests::IsConditionalProcessingAttribute(aName)) {
|
||||
bool isDisabled = !SVGTests::PassesConditionalProcessingTests();
|
||||
if (mTimedElement.SetIsDisabled(isDisabled)) {
|
||||
if (mTimedElement.SetIsDisabled(IsDisabled())) {
|
||||
AnimationNeedsResample();
|
||||
}
|
||||
}
|
||||
@ -272,6 +273,38 @@ void SVGAnimationElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
||||
// next BindToTree call.
|
||||
}
|
||||
|
||||
bool SVGAnimationElement::IsDisabled() {
|
||||
if (!SVGTests::PassesConditionalProcessingTests()) {
|
||||
return true;
|
||||
}
|
||||
nsIContent* child = this;
|
||||
while (nsIContent* parent = child->GetFlattenedTreeParent()) {
|
||||
if (!parent->IsSVGElement()) {
|
||||
return false;
|
||||
}
|
||||
if (auto* svgSwitch = SVGSwitchElement::FromNodeOrNull(parent)) {
|
||||
nsIFrame* frame = svgSwitch->GetPrimaryFrame();
|
||||
// If we've been reflowed then the active child has been determined,
|
||||
// otherwise we'll have to calculate whether this is the active child.
|
||||
if (frame && !frame->HasAnyStateBits(NS_FRAME_FIRST_REFLOW)) {
|
||||
if (child != svgSwitch->GetActiveChild()) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (child != SVGTests::FindActiveSwitchChild(svgSwitch)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (auto* svgGraphics = SVGGraphicsElement::FromNode(parent)) {
|
||||
if (!svgGraphics->PassesConditionalProcessingTests()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
child = parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// SVG utility methods
|
||||
|
||||
|
@ -64,6 +64,8 @@ class SVGAnimationElement : public SVGAnimationElementBase, public SVGTests {
|
||||
// Utility methods for within SVG
|
||||
void ActivateByHyperlink();
|
||||
|
||||
bool IsDisabled();
|
||||
|
||||
// WebIDL
|
||||
SVGElement* GetTargetElement();
|
||||
float GetStartTime(ErrorResult& rv);
|
||||
|
@ -61,7 +61,7 @@ bool SVGTests::IsConditionalProcessingAttribute(
|
||||
|
||||
// Find the best match from aAvailLangs for the users accept-languages,
|
||||
// returning the index in the aAvailLangs list, or -1 if no match.
|
||||
int32_t FindBestLanguage(const nsTArray<nsCString>& aAvailLangs) {
|
||||
static int32_t FindBestLanguage(const nsTArray<nsCString>& aAvailLangs) {
|
||||
AutoTArray<nsCString, 16> reqLangs;
|
||||
nsCString acceptLangs;
|
||||
Preferences::GetLocalizedCString("intl.accept_languages", acceptLangs);
|
||||
|
@ -257,16 +257,15 @@ static bool NodeCouldBeRendered(const nsINode& aNode) {
|
||||
if (const auto* symbol = SVGSymbolElement::FromNode(aNode)) {
|
||||
return symbol->CouldBeRendered();
|
||||
}
|
||||
if (const auto* svgGraphics = SVGGraphicsElement::FromNode(aNode)) {
|
||||
if (!svgGraphics->PassesConditionalProcessingTests()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (auto* svgSwitch =
|
||||
SVGSwitchElement::FromNodeOrNull(aNode.GetParentNode())) {
|
||||
if (&aNode != svgSwitch->GetActiveChild()) {
|
||||
return false;
|
||||
}
|
||||
} else if (const auto* svgGraphics = SVGGraphicsElement::FromNode(aNode)) {
|
||||
if (!svgGraphics->PassesConditionalProcessingTests()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -296,9 +295,8 @@ auto SVGUseElement::ScanAncestors(const Element& aTarget) const -> ScanResult {
|
||||
return ScanAncestorsInternal(aTarget, count);
|
||||
}
|
||||
|
||||
auto SVGUseElement::ScanAncestorsInternal(const Element& aTarget,
|
||||
uint32_t& aCount) const
|
||||
-> ScanResult {
|
||||
auto SVGUseElement::ScanAncestorsInternal(
|
||||
const Element& aTarget, uint32_t& aCount) const -> ScanResult {
|
||||
if (&aTarget == this) {
|
||||
return ScanResult::CyclicReference;
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html class="reftest-wait">
|
||||
<title>Test animation as children of failed conditional processing test elements</title>
|
||||
<link rel="match" href="../struct/reftests/reference/green-100x100.html">
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="/common/rendering-utils.js"></script>
|
||||
<script>
|
||||
function test() {
|
||||
document.getElementsByTagName('svg')[0].setCurrentTime(2);
|
||||
waitForAtLeastOneFrame().then(takeScreenshot);
|
||||
}
|
||||
</script>
|
||||
<svg onload="test()">
|
||||
<g systemLanguage="x-xl">
|
||||
<set xlink:href="#test" attributeName="width" begin="2s" to="0" />
|
||||
</g>
|
||||
<rect id="test" width="100" height="100" fill="green"/>
|
||||
</svg>
|
@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<html class="reftest-wait">
|
||||
<title>Test animation as children of switch elements</title>
|
||||
<link rel="match" href="../struct/reftests/reference/green-100x100.html">
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="/common/rendering-utils.js"></script>
|
||||
<script>
|
||||
function test() {
|
||||
document.getElementsByTagName('svg')[0].setCurrentTime(2);
|
||||
waitForAtLeastOneFrame().then(takeScreenshot);
|
||||
}
|
||||
</script>
|
||||
<svg onload="test()">
|
||||
<switch>
|
||||
<set systemLanguage="x-xl" xlink:href="#test" attributeName="width" begin="2s" to="0" />
|
||||
<set xlink:href="#test" attributeName="height" begin="2s" to="100" />
|
||||
</switch>
|
||||
<rect id="test" width="100" height="0" fill="green"/>
|
||||
</svg>
|
@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<html class="reftest-wait">
|
||||
<title>Test animation as children of switch elements</title>
|
||||
<link rel="match" href="../struct/reftests/reference/green-100x100.html">
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="/common/rendering-utils.js"></script>
|
||||
<script>
|
||||
function test() {
|
||||
document.getElementsByTagName('svg')[0].setCurrentTime(2);
|
||||
waitForAtLeastOneFrame().then(takeScreenshot);
|
||||
}
|
||||
</script>
|
||||
<svg onload="test()">
|
||||
<switch>
|
||||
<g systemLanguage="x-xl">
|
||||
<set xlink:href="#test" attributeName="width" begin="2s" to="0" />
|
||||
</g>
|
||||
<g>
|
||||
<set xlink:href="#test" attributeName="height" begin="2s" to="100" />
|
||||
</g>
|
||||
</switch>
|
||||
<rect id="test" width="100" height="0" fill="green"/>
|
||||
</svg>
|
Loading…
Reference in New Issue
Block a user