mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 481562: Don't create time container for an <svg> element until after it's been bound to a smil-enabled document. r+sr=roc
This commit is contained in:
parent
a5b835b377
commit
3f4092e862
@ -1321,15 +1321,26 @@ nsSVGSVGElement::BindToTree(nsIDocument* aDocument,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
PRBool outermost = WillBeOutermostSVG(aParent, aBindingParent);
|
||||
nsSMILAnimationController* smilController = nsnull;
|
||||
|
||||
if (!mTimedDocumentRoot && outermost) {
|
||||
// We will now be the outermost SVG element
|
||||
mTimedDocumentRoot = new nsSMILTimeContainer();
|
||||
NS_ENSURE_TRUE(mTimedDocumentRoot, NS_ERROR_OUT_OF_MEMORY);
|
||||
} else if (!outermost) {
|
||||
mTimedDocumentRoot = nsnull;
|
||||
mStartAnimationOnBindToTree = PR_TRUE;
|
||||
if (aDocument) {
|
||||
smilController = aDocument->GetAnimationController();
|
||||
if (smilController) {
|
||||
// SMIL is enabled in this document
|
||||
if (WillBeOutermostSVG(aParent, aBindingParent)) {
|
||||
// We'll be the outermost <svg> element. We'll need a time container.
|
||||
if (!mTimedDocumentRoot) {
|
||||
mTimedDocumentRoot = new nsSMILTimeContainer();
|
||||
NS_ENSURE_TRUE(mTimedDocumentRoot, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
} else {
|
||||
// We're a child of some other <svg> element, so we don't need our own
|
||||
// time container. However, we need to make sure that we'll get a
|
||||
// kick-start if we get promoted to be outermost later on.
|
||||
mTimedDocumentRoot = nsnull;
|
||||
mStartAnimationOnBindToTree = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = nsSVGSVGElementBase::BindToTree(aDocument, aParent,
|
||||
@ -1337,14 +1348,8 @@ nsSVGSVGElement::BindToTree(nsIDocument* aDocument,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (mTimedDocumentRoot) {
|
||||
if (aDocument) {
|
||||
nsSMILAnimationController* smilController =
|
||||
aDocument->GetAnimationController();
|
||||
if (smilController) {
|
||||
rv = mTimedDocumentRoot->SetParent(smilController);
|
||||
}
|
||||
}
|
||||
if (mTimedDocumentRoot && smilController) {
|
||||
rv = mTimedDocumentRoot->SetParent(smilController);
|
||||
if (mStartAnimationOnBindToTree) {
|
||||
mTimedDocumentRoot->Begin();
|
||||
}
|
||||
@ -1362,7 +1367,6 @@ nsSVGSVGElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
|
||||
nsSVGSVGElementBase::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
17
layout/reftests/svg/smil/container/deferred-tree-2-ref.xhtml
Normal file
17
layout/reftests/svg/smil/container/deferred-tree-2-ref.xhtml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Deferred tree</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="tree-container"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="200px"
|
||||
id="created-svg">
|
||||
<rect x="0" y="0" width="199" height="199"
|
||||
style="fill: none; stroke: black"/>
|
||||
<ellipse stroke-width="1" stroke="black" fill="yellow" cx="100"
|
||||
cy="20" rx="40" ry="20"/>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
44
layout/reftests/svg/smil/container/deferred-tree-2a.xhtml
Normal file
44
layout/reftests/svg/smil/container/deferred-tree-2a.xhtml
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>Deferred tree</title>
|
||||
<!--
|
||||
PURPOSE: If a SVG subdocument is created dynamically, any timing-related
|
||||
animation API calls on the subdocument should silently fail until it's
|
||||
been attached to a document.
|
||||
|
||||
OPERATION: We start with a plain XHTML document, but later a div and an SVG
|
||||
subdocument are created. We attempt an animation API call on the SVG
|
||||
element before attaching it to the XHTML document.
|
||||
|
||||
EXPECTED RESULTS: The animation API call should have no effect.
|
||||
-->
|
||||
<script src="deferred-tree-util.js" type="text/javascript"/>
|
||||
<script>
|
||||
function animate()
|
||||
{
|
||||
// Set up
|
||||
var div = makeDiv();
|
||||
var svg = makeSvg();
|
||||
var target = document.getElementById('tree-container');
|
||||
|
||||
// Make an animation api call (should have no effect, if we're sane)
|
||||
svg.setCurrentTime(1.0);
|
||||
|
||||
// Trigger a "BindToTree" call on the SVG element
|
||||
div.appendChild(svg);
|
||||
|
||||
// Finally, we attach to the document and pause animations.
|
||||
target.appendChild(div);
|
||||
|
||||
// Reftest Snapshot
|
||||
svg.pauseAnimations();
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="animate()">
|
||||
<p id="tree-container"/>
|
||||
</body>
|
||||
</html>
|
44
layout/reftests/svg/smil/container/deferred-tree-2b.xhtml
Normal file
44
layout/reftests/svg/smil/container/deferred-tree-2b.xhtml
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>Deferred tree</title>
|
||||
<!--
|
||||
PURPOSE: If a SVG subdocument is created dynamically, any timing-related
|
||||
animation API calls on the subdocument should silently fail until it's
|
||||
been attached to a document.
|
||||
|
||||
OPERATION: We start with a plain XHTML document, but later a div and an SVG
|
||||
subdocument are created. We attempt an animation API call on the SVG
|
||||
element before attaching it to the XHTML document.
|
||||
|
||||
EXPECTED RESULTS: The animation API call should have no effect.
|
||||
-->
|
||||
<script src="deferred-tree-util.js" type="text/javascript"/>
|
||||
<script>
|
||||
function animate()
|
||||
{
|
||||
// Set up
|
||||
var div = makeDiv();
|
||||
var svg = makeSvg();
|
||||
var target = document.getElementById('tree-container');
|
||||
|
||||
// Trigger a "BindToTree" call on the SVG element
|
||||
div.appendChild(svg);
|
||||
|
||||
// Make an animation api call (should have no effect, if we're sane)
|
||||
svg.setCurrentTime(1.0);
|
||||
|
||||
// Finally, we attach to the document and pause animations.
|
||||
target.appendChild(div);
|
||||
|
||||
// Reftest Snapshot
|
||||
svg.pauseAnimations();
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="animate()">
|
||||
<p id="tree-container"/>
|
||||
</body>
|
||||
</html>
|
17
layout/reftests/svg/smil/container/deferred-tree-3-ref.xhtml
Normal file
17
layout/reftests/svg/smil/container/deferred-tree-3-ref.xhtml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Deferred tree</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="tree-container"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="200px"
|
||||
id="created-svg">
|
||||
<rect x="0" y="0" width="199" height="199"
|
||||
style="fill: none; stroke: black"/>
|
||||
<ellipse stroke-width="1" stroke="black" fill="yellow" cx="100"
|
||||
cy="95" rx="40" ry="20"/>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
35
layout/reftests/svg/smil/container/deferred-tree-3a.xhtml
Normal file
35
layout/reftests/svg/smil/container/deferred-tree-3a.xhtml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>Deferred tree</title>
|
||||
<script src="deferred-tree-util.js" type="text/javascript"/>
|
||||
<script>
|
||||
function animate()
|
||||
{
|
||||
// Set up
|
||||
var div = makeDiv();
|
||||
var svg = makeSvg();
|
||||
var target = document.getElementById('tree-container');
|
||||
|
||||
div.appendChild(svg);
|
||||
target.appendChild(div);
|
||||
|
||||
// These calls *should* have an effect, since they happen
|
||||
// after 'svg' has been attached to the XHTML document.
|
||||
svg.setCurrentTime(1.0);
|
||||
svg.pauseAnimations();
|
||||
|
||||
// Reattach the SVG element to its parent div.
|
||||
// (If we're sane, this shouldn't reset its time container.)
|
||||
div.appendChild(svg);
|
||||
|
||||
// Reftest Snapshot
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="animate()">
|
||||
<p id="tree-container"/>
|
||||
</body>
|
||||
</html>
|
35
layout/reftests/svg/smil/container/deferred-tree-3b.xhtml
Normal file
35
layout/reftests/svg/smil/container/deferred-tree-3b.xhtml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>Deferred tree</title>
|
||||
<script src="deferred-tree-util.js" type="text/javascript"/>
|
||||
<script>
|
||||
function animate()
|
||||
{
|
||||
// Set up
|
||||
var div = makeDiv();
|
||||
var svg = makeSvg();
|
||||
var target = document.getElementById('tree-container');
|
||||
|
||||
div.appendChild(svg);
|
||||
target.appendChild(div);
|
||||
|
||||
// These calls *should* have an effect, since they happen
|
||||
// after 'svg' has been attached to the XHTML document.
|
||||
svg.setCurrentTime(1.0);
|
||||
svg.pauseAnimations();
|
||||
|
||||
// Shift the SVG element to its parent's parent.
|
||||
// (If we're sane, this shouldn't reset its time container.)
|
||||
target.appendChild(svg);
|
||||
|
||||
// Reftest Snapshot
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="animate()">
|
||||
<p id="tree-container"/>
|
||||
</body>
|
||||
</html>
|
40
layout/reftests/svg/smil/container/deferred-tree-3c.xhtml
Normal file
40
layout/reftests/svg/smil/container/deferred-tree-3c.xhtml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>Deferred tree</title>
|
||||
<script src="deferred-tree-util.js" type="text/javascript"/>
|
||||
<script>
|
||||
function animate()
|
||||
{
|
||||
// Set up
|
||||
var div = makeDiv();
|
||||
var svg = makeSvg();
|
||||
var target = document.getElementById('tree-container');
|
||||
|
||||
div.appendChild(svg);
|
||||
target.appendChild(div);
|
||||
|
||||
// These calls *should* have an effect, since they happen
|
||||
// after 'svg' has been attached to the XHTML document.
|
||||
svg.setCurrentTime(1.0);
|
||||
svg.pauseAnimations();
|
||||
|
||||
// Create another div container, and move svg element there
|
||||
// (temporarily detaching it from the document), before attaching
|
||||
// this new subtree back onto the document. Our current behavior
|
||||
// (which matches Opera 9.64) is to preserve svg's time container
|
||||
// through this manipulation.
|
||||
div2 = makeDiv();
|
||||
div2.appendChild(svg);
|
||||
div.appendChild(div2);
|
||||
|
||||
// Reftest Snapshot
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="animate()">
|
||||
<p id="tree-container"/>
|
||||
</body>
|
||||
</html>
|
42
layout/reftests/svg/smil/container/deferred-tree-3d.xhtml
Normal file
42
layout/reftests/svg/smil/container/deferred-tree-3d.xhtml
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>Deferred tree</title>
|
||||
<script src="deferred-tree-util.js" type="text/javascript"/>
|
||||
<script>
|
||||
function animate()
|
||||
{
|
||||
// Set up
|
||||
var div = makeDiv();
|
||||
var svg = makeSvg();
|
||||
var target = document.getElementById('tree-container');
|
||||
|
||||
div.appendChild(svg);
|
||||
target.appendChild(div);
|
||||
|
||||
// Create another div container, and move svg element there
|
||||
// (temporarily detaching it from the document).
|
||||
div2 = makeDiv();
|
||||
div2.appendChild(svg);
|
||||
|
||||
// These calls *should* have an effect, since they happen
|
||||
// after 'svg' has been attached to the XHTML document (even though
|
||||
// it's not currently attached)
|
||||
svg.setCurrentTime(1.0);
|
||||
svg.pauseAnimations();
|
||||
|
||||
// Attach the div2+svg subtree onto the document. Our current
|
||||
// behavior (which matches Opera 9.64) is to preserve svg's time
|
||||
// container through this manipulation.
|
||||
div.appendChild(div2);
|
||||
|
||||
// Reftest Snapshot
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="animate()">
|
||||
<p id="tree-container"/>
|
||||
</body>
|
||||
</html>
|
39
layout/reftests/svg/smil/container/deferred-tree-util.js
Normal file
39
layout/reftests/svg/smil/container/deferred-tree-util.js
Normal file
@ -0,0 +1,39 @@
|
||||
function makeDiv()
|
||||
{
|
||||
const xhtmlns="http://www.w3.org/1999/xhtml";
|
||||
return document.createElementNS(xhtmlns, 'div');
|
||||
}
|
||||
|
||||
function makeSvg()
|
||||
{
|
||||
const svgns="http://www.w3.org/2000/svg";
|
||||
var svg = document.createElementNS(svgns, 'svg');
|
||||
svg.setAttribute('xmlns', svgns);
|
||||
svg.setAttribute('width', '200px');
|
||||
svg.setAttribute('height', '200px');
|
||||
var rect = document.createElementNS(svgns, 'rect');
|
||||
rect.setAttribute('x', '0');
|
||||
rect.setAttribute('y', '0');
|
||||
rect.setAttribute('width', '199');
|
||||
rect.setAttribute('height', '199');
|
||||
rect.setAttribute('style', 'fill: none; stroke: black');
|
||||
var ellipse = document.createElementNS(svgns, 'ellipse');
|
||||
ellipse.setAttribute('stroke-width', '1');
|
||||
ellipse.setAttribute('stroke', 'black');
|
||||
ellipse.setAttribute('fill', 'yellow');
|
||||
ellipse.setAttribute('cx', '100');
|
||||
ellipse.setAttribute('cy', '20');
|
||||
ellipse.setAttribute('rx', '40');
|
||||
ellipse.setAttribute('ry', '20');
|
||||
var anim = document.createElementNS(svgns, 'animate');
|
||||
anim.setAttribute('attributeName', 'cy');
|
||||
anim.setAttribute('attributeType', 'XML');
|
||||
anim.setAttribute('begin', '0s');
|
||||
anim.setAttribute('from', '20');
|
||||
anim.setAttribute('to', '170');
|
||||
anim.setAttribute('dur', '2s');
|
||||
ellipse.appendChild(anim);
|
||||
svg.appendChild(rect);
|
||||
svg.appendChild(ellipse);
|
||||
return svg;
|
||||
}
|
@ -7,6 +7,12 @@ random == enveloped-tree-1.xhtml enveloped-tree-1-ref.xhtml # bug 470868
|
||||
== moved-tree-1.xhtml moved-tree-1-ref.xhtml
|
||||
== deferred-anim-1.xhtml deferred-anim-1-ref.xhtml
|
||||
== deferred-tree-1.xhtml deferred-tree-1-ref.xhtml
|
||||
== deferred-tree-2a.xhtml deferred-tree-2-ref.xhtml
|
||||
== deferred-tree-2b.xhtml deferred-tree-2-ref.xhtml
|
||||
== deferred-tree-3a.xhtml deferred-tree-3-ref.xhtml
|
||||
== deferred-tree-3b.xhtml deferred-tree-3-ref.xhtml
|
||||
== deferred-tree-3c.xhtml deferred-tree-3-ref.xhtml
|
||||
== deferred-tree-3d.xhtml deferred-tree-3-ref.xhtml
|
||||
# this will occasionally fail until we correctly clear animation effects from
|
||||
# no-longer-targeted elements
|
||||
random == invalid-elem-1.xhtml invalid-elem-1-ref.xhtml
|
||||
|
Loading…
Reference in New Issue
Block a user