зеркало из https://github.com/mozilla/gecko-dev.git
Bug 507067: Fix GetAnimVal and GetBaseVal's handling of em/ex/etc. units inside display:none elements by using nsComputedDOMStyle's method for resolving style contexts for such elements. r=dbaron
This commit is contained in:
Родитель
36c0b9d09f
Коммит
4e96b6eb1b
|
@ -45,6 +45,7 @@ include $(DEPTH)/config/autoconf.mk
|
|||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
test_animLengthUnits.xhtml \
|
||||
test_bbox.xhtml \
|
||||
bbox-helper.svg \
|
||||
bounds-helper.svg \
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=507067
|
||||
-->
|
||||
<head>
|
||||
<title>Test for units of SVG animated lengths</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=507067">Mozilla Bug 507067</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
|
||||
<g font-size="10px">
|
||||
<circle cx="-100" cy="20" r="15" fill="blue" id="circle">
|
||||
<animate attributeName="cx" from="0em" to="10em" dur="8s" begin="1s"
|
||||
fill="freeze"/>
|
||||
</circle>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
<![CDATA[
|
||||
/** Test units of animated lengths **/
|
||||
|
||||
/* Global Variables */
|
||||
const svgns="http://www.w3.org/2000/svg";
|
||||
var svg = document.getElementById("svg");
|
||||
var circle = document.getElementById('circle');
|
||||
var animate = document.getElementById('animate');
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Interop comments are based on:
|
||||
//
|
||||
// Opera -- 10 beta 2
|
||||
// WebKit -- July 09 trunk build
|
||||
// Batik -- 1.7
|
||||
// Firefox -- July 09 trunk build
|
||||
//
|
||||
|
||||
function main() {
|
||||
// Sanity check: check initial values
|
||||
is(circle.cx.baseVal.valueInSpecifiedUnits, -100,
|
||||
"Unexpected initial baseVal");
|
||||
is(circle.cx.baseVal.unitType, SVGLength.SVG_LENGTHTYPE_NUMBER,
|
||||
"Unexpected initial baseVal units");
|
||||
is(circle.cx.animVal.valueInSpecifiedUnits, -100,
|
||||
"Unexpected initial animVal");
|
||||
is(circle.cx.animVal.unitType, SVGLength.SVG_LENGTHTYPE_NUMBER,
|
||||
"Unexpected initial animVal units");
|
||||
|
||||
// Sample mid-way through the animation
|
||||
svg.pauseAnimations();
|
||||
svg.setCurrentTime(5);
|
||||
|
||||
// (1) Check the absolute value is right
|
||||
//
|
||||
// We're not too worried about the units. Based on our testing we get:
|
||||
// Opera: Will use user units for the animVal
|
||||
// Safari: Doesn't work
|
||||
// Batik: Will use the units specified on the animation function provided they
|
||||
// are the same
|
||||
// FF: Will use the units of the baseVal for the animVal
|
||||
//
|
||||
is(circle.cx.baseVal.value, -100,
|
||||
"(1) Unexpected value for baseVal during animation");
|
||||
is(circle.cx.animVal.value, 50,
|
||||
"(1) Unexpected value for animVal during animation");
|
||||
|
||||
// Change font-size and check
|
||||
circle.parentNode.setAttribute('font-size', '5px');
|
||||
|
||||
// Currently, changing the font-size on a parent doesn't force a resample (see
|
||||
// bug 508206) so we have to give the animation a chance to run
|
||||
setTimeout("checkAfterChangeFontSize()",100);
|
||||
}
|
||||
|
||||
function checkAfterChangeFontSize() {
|
||||
// (2) Check that changing the font-size of the parent element is reflected in
|
||||
// the anim val
|
||||
is(circle.cx.baseVal.value, -100,
|
||||
"(2) Unexpected value for baseVal after changing font-size during " +
|
||||
"animation");
|
||||
is(circle.cx.animVal.value, 25,
|
||||
"(2) Unexpected value for animVal after changing font-size during " +
|
||||
"animation");
|
||||
|
||||
// Do the same again, when the animation is frozen
|
||||
svg.setCurrentTime(10);
|
||||
circle.parentNode.setAttribute('font-size', '7px');
|
||||
|
||||
// Again, due to bug 508206 we need to give the animation a chance to resample
|
||||
setTimeout("checkWhilstFrozen()",100);
|
||||
}
|
||||
|
||||
function checkWhilstFrozen() {
|
||||
// (3) Check that changing the font-size of the parent element is reflected in
|
||||
// the anim val
|
||||
is(circle.cx.baseVal.value, -100,
|
||||
"(3) Unexpected value for baseVal after changing font-size whilst " +
|
||||
"frozen");
|
||||
is(circle.cx.animVal.value, 70,
|
||||
"(3) Unexpected value for animVal after changing font-size whilst " +
|
||||
"frozen");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalPreferencesRead");
|
||||
if (navigator.preference('svg.smil.enabled')) {
|
||||
window.addEventListener("load", main, false);
|
||||
} else {
|
||||
ok(true); // Skip tests but don't report 'todo' either
|
||||
SimpleTest.finish();
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -354,7 +354,35 @@ nsComputedDOMStyle::GetStyleContextForContent(nsIContent* aContent,
|
|||
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eELEMENT),
|
||||
"aContent must be an element");
|
||||
if (!aPseudo) {
|
||||
// If there's no pres shell, get it from the content
|
||||
if (!aPresShell) {
|
||||
aPresShell = GetPresShellForContent(aContent);
|
||||
if (!aPresShell)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
aPresShell->FlushPendingNotifications(Flush_Style);
|
||||
}
|
||||
|
||||
return GetStyleContextForContentNoFlush(aContent, aPseudo, aPresShell);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsStyleContext>
|
||||
nsComputedDOMStyle::GetStyleContextForContentNoFlush(nsIContent* aContent,
|
||||
nsIAtom* aPseudo,
|
||||
nsIPresShell* aPresShell)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aContent, "NULL content node");
|
||||
|
||||
// If there's no pres shell, get it from the content
|
||||
if (!aPresShell) {
|
||||
aPresShell = GetPresShellForContent(aContent);
|
||||
if (!aPresShell)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!aPseudo) {
|
||||
nsIFrame* frame = aPresShell->GetPrimaryFrameFor(aContent);
|
||||
if (frame) {
|
||||
nsStyleContext* result = GetStyleContextForFrame(frame);
|
||||
|
@ -390,6 +418,17 @@ nsComputedDOMStyle::GetStyleContextForContent(nsIContent* aContent,
|
|||
return styleSet->ResolveStyleFor(aContent, parentContext);
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsIPresShell*
|
||||
nsComputedDOMStyle::GetPresShellForContent(nsIContent* aContent)
|
||||
{
|
||||
nsIDocument* currentDoc = aContent->GetCurrentDoc();
|
||||
if (!currentDoc)
|
||||
return nsnull;
|
||||
|
||||
return currentDoc->GetPrimaryShell();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName,
|
||||
nsIDOMCSSValue** aReturn)
|
||||
|
|
|
@ -86,6 +86,13 @@ public:
|
|||
GetStyleContextForContent(nsIContent* aContent, nsIAtom* aPseudo,
|
||||
nsIPresShell* aPresShell);
|
||||
|
||||
static already_AddRefed<nsStyleContext>
|
||||
GetStyleContextForContentNoFlush(nsIContent* aContent, nsIAtom* aPseudo,
|
||||
nsIPresShell* aPresShell);
|
||||
|
||||
static nsIPresShell*
|
||||
GetPresShellForContent(nsIContent* aContent);
|
||||
|
||||
private:
|
||||
void AssertFlushedPendingReflows() {
|
||||
NS_ASSERTION(mFlushedPendingReflows,
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#include "nsSVGIntegrationUtils.h"
|
||||
#include "nsSVGFilterPaintCallback.h"
|
||||
#include "nsSVGGeometryFrame.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
|
||||
gfxASurface *nsSVGUtils::mThebesComputationalSurface = nsnull;
|
||||
|
||||
|
@ -267,39 +268,69 @@ nsSVGUtils::GetParentElement(nsIContent *aContent)
|
|||
float
|
||||
nsSVGUtils::GetFontSize(nsIContent *aContent)
|
||||
{
|
||||
nsIFrame* frame = GetFrameForContent(aContent);
|
||||
if (!frame) {
|
||||
NS_WARNING("no frame in GetFontSize()");
|
||||
nsRefPtr<nsStyleContext> styleContext =
|
||||
nsComputedDOMStyle::GetStyleContextForContentNoFlush(aContent, nsnull,
|
||||
nsnull);
|
||||
if (!styleContext) {
|
||||
NS_WARNING("Couldn't get style context for content in GetFontStyle");
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
return GetFontSize(frame);
|
||||
return GetFontSize(styleContext);
|
||||
}
|
||||
|
||||
float
|
||||
nsSVGUtils::GetFontSize(nsIFrame *aFrame)
|
||||
{
|
||||
return nsPresContext::AppUnitsToFloatCSSPixels(aFrame->GetStyleFont()->mSize) /
|
||||
aFrame->PresContext()->TextZoom();
|
||||
NS_ABORT_IF_FALSE(aFrame, "NULL frame in GetFontSize");
|
||||
return GetFontSize(aFrame->GetStyleContext());
|
||||
}
|
||||
|
||||
float
|
||||
nsSVGUtils::GetFontSize(nsStyleContext *aStyleContext)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aStyleContext, "NULL style context in GetFontSize");
|
||||
|
||||
nsPresContext *presContext = aStyleContext->PresContext();
|
||||
NS_ABORT_IF_FALSE(presContext, "NULL pres context in GetFontSize");
|
||||
|
||||
nscoord fontSize = aStyleContext->GetStyleFont()->mSize;
|
||||
return nsPresContext::AppUnitsToFloatCSSPixels(fontSize) /
|
||||
presContext->TextZoom();
|
||||
}
|
||||
|
||||
float
|
||||
nsSVGUtils::GetFontXHeight(nsIContent *aContent)
|
||||
{
|
||||
nsIFrame* frame = GetFrameForContent(aContent);
|
||||
if (!frame) {
|
||||
NS_WARNING("no frame in GetFontXHeight()");
|
||||
nsRefPtr<nsStyleContext> styleContext =
|
||||
nsComputedDOMStyle::GetStyleContextForContentNoFlush(aContent, nsnull,
|
||||
nsnull);
|
||||
if (!styleContext) {
|
||||
NS_WARNING("Couldn't get style context for content in GetFontStyle");
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
return GetFontXHeight(frame);
|
||||
return GetFontXHeight(styleContext);
|
||||
}
|
||||
|
||||
float
|
||||
nsSVGUtils::GetFontXHeight(nsIFrame *aFrame)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aFrame, "NULL frame in GetFontXHeight");
|
||||
return GetFontXHeight(aFrame->GetStyleContext());
|
||||
}
|
||||
|
||||
float
|
||||
nsSVGUtils::GetFontXHeight(nsStyleContext *aStyleContext)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aStyleContext, "NULL style context in GetFontXHeight");
|
||||
|
||||
nsPresContext *presContext = aStyleContext->PresContext();
|
||||
NS_ABORT_IF_FALSE(presContext, "NULL pres context in GetFontXHeight");
|
||||
|
||||
nsCOMPtr<nsIFontMetrics> fontMetrics;
|
||||
nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fontMetrics));
|
||||
nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext,
|
||||
getter_AddRefs(fontMetrics));
|
||||
|
||||
if (!fontMetrics) {
|
||||
NS_WARNING("no FontMetrics in GetFontXHeight()");
|
||||
|
@ -309,7 +340,7 @@ nsSVGUtils::GetFontXHeight(nsIFrame *aFrame)
|
|||
nscoord xHeight;
|
||||
fontMetrics->GetXHeight(xHeight);
|
||||
return nsPresContext::AppUnitsToFloatCSSPixels(xHeight) /
|
||||
aFrame->PresContext()->TextZoom();
|
||||
presContext->TextZoom();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
class nsIDocument;
|
||||
class nsPresContext;
|
||||
class nsIContent;
|
||||
class nsStyleContext;
|
||||
class nsStyleCoord;
|
||||
class nsFrameList;
|
||||
class nsIFrame;
|
||||
|
@ -203,11 +204,13 @@ public:
|
|||
*/
|
||||
static float GetFontSize(nsIContent *aContent);
|
||||
static float GetFontSize(nsIFrame *aFrame);
|
||||
static float GetFontSize(nsStyleContext *aStyleContext);
|
||||
/*
|
||||
* Get an x-height of of an nsIContent
|
||||
*/
|
||||
static float GetFontXHeight(nsIContent *aContent);
|
||||
static float GetFontXHeight(nsIFrame *aFrame);
|
||||
static float GetFontXHeight(nsStyleContext *aStyleContext);
|
||||
|
||||
/*
|
||||
* Converts image data from premultipled to unpremultiplied alpha
|
||||
|
|
Загрузка…
Ссылка в новой задаче