Bug 503720: Implement vw/vh/vmin/vmax. r=dbaron

This commit is contained in:
Seth Fowler 2012-10-19 16:21:06 -07:00
Родитель 77d39ba769
Коммит ed0c222ddd
13 изменённых файлов: 163 добавлений и 4 удалений

Просмотреть файл

@ -1660,6 +1660,7 @@ nsPresContext::RebuildAllStyleData(nsChangeHint aExtraHint)
return;
}
mUsesViewportUnits = false;
RebuildUserFontSet();
AnimationManager()->KeyframesListIsDirty();
@ -1680,12 +1681,18 @@ void
nsPresContext::MediaFeatureValuesChanged(bool aCallerWillRebuildStyleData)
{
mPendingMediaFeatureValuesChanged = false;
if (mShell &&
mShell->StyleSet()->MediumFeaturesChanged(this) &&
!aCallerWillRebuildStyleData) {
// MediumFeaturesChanged updates the applied rules, so it always gets called.
bool mediaFeaturesDidChange = mShell ? mShell->StyleSet()->MediumFeaturesChanged(this)
: false;
if (!aCallerWillRebuildStyleData &&
(mediaFeaturesDidChange || (mUsesViewportUnits && mPendingViewportChange))) {
RebuildAllStyleData(nsChangeHint(0));
}
mPendingViewportChange = false;
if (!nsContentUtils::IsSafeToRunScript()) {
NS_ABORT_IF_FALSE(mDocument->IsBeingUsedAsImage(),
"How did we get here? Are we failing to notify "

Просмотреть файл

@ -414,8 +414,10 @@ public:
if (!r.IsEqualEdges(mVisibleArea)) {
mVisibleArea = r;
// Visible area does not affect media queries when paginated.
if (!IsPaginated() && HasCachedStyleData())
if (!IsPaginated() && HasCachedStyleData()) {
mPendingViewportChange = true;
PostMediaFeatureValuesChangedEvent();
}
}
}
@ -943,6 +945,14 @@ public:
mIsGlyph = aValue;
}
bool UsesViewportUnits() const {
return mUsesViewportUnits;
}
void SetUsesViewportUnits(bool aValue) {
mUsesViewportUnits = aValue;
}
protected:
friend class nsRunnableMethod<nsPresContext>;
NS_HIDDEN_(void) ThemeChangedInternal();
@ -1195,6 +1205,12 @@ protected:
// Are we currently drawing an SVG glyph?
unsigned mIsGlyph : 1;
// Does the associated document use viewport units?
unsigned mUsesViewportUnits : 1;
// Has there been a change to the viewport's dimensions?
unsigned mPendingViewportChange : 1;
// Is the current mUserFontSet valid?
unsigned mUserFontSetDirty : 1;
// Has GetUserFontSet() been called?

Просмотреть файл

@ -6,3 +6,5 @@
== unit-rem-root-fontsize.html unit-rem-ref2-root-fontsize.html
== unit-rem-root-width.html unit-rem-ref-root-width.html
== unit-rem.svg unit-rem-ref.svg
== unit-vh-vw.html unit-vh-vw-ref.html
== unit-vh-vw-zoom.html unit-vh-vw-zoom-ref.html

Просмотреть файл

@ -0,0 +1,14 @@
<style>
div {
width: 10px;
height: 10px;
background-color: #d64203;
}
</style>
<body>
<div style="width: 50vw"></div>
<div style="height: 25vh"></div>
<div style="width: 35vmin"></div>
<div style="height: 25vmax"></div>
</body>

Просмотреть файл

@ -0,0 +1,15 @@
<style>
div {
width: 10px;
height: 10px;
background-color: #d64203;
}
</style>
<body>
<div style="width: 50px"></div>
<div style="height: 50px"></div>
<div style="width: 35px"></div>
<div style="height: 50px"></div>
</body>

Просмотреть файл

@ -0,0 +1,14 @@
<style>
body { background-color: black }
iframe {
width: 100px;
height: 200px;
margin: 0px;
border: 0px;
}
</style>
<body>
<iframe src="unit-vh-vw-ref-iframe.html"></iframe>
<iframe src="unit-vh-vw-ref-iframe.html"></iframe>
</body>

Просмотреть файл

@ -0,0 +1,18 @@
<html reftest-zoom="2">
<style>
body { background-color: black }
iframe {
width: 100px;
height: 200px;
margin: 0px;
border: 0px;
}
</style>
<body>
<iframe src="unit-vh-vw-ref-iframe.html"></iframe>
<iframe src="unit-vh-vw-ref-iframe.html"></iframe>
</body>
</html>

Просмотреть файл

@ -0,0 +1,18 @@
<html reftest-zoom="2">
<style>
body { background-color: black }
iframe {
width: 100px;
height: 200px;
margin: 0px;
border: 0px;
}
</style>
<body>
<iframe src="unit-vh-vw-iframe.html"></iframe>
<iframe src="unit-vh-vw-iframe.html"></iframe>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<style>
body { background-color: black }
iframe {
width: 100px;
height: 200px;
margin: 0px;
border: 0px;
}
</style>
<body>
<iframe src="unit-vh-vw-iframe.html"></iframe>
<iframe src="unit-vh-vw-iframe.html"></iframe>
</body>

Просмотреть файл

@ -4510,6 +4510,10 @@ const UnitInfo UnitData[] = {
{ STR_WITH_LEN("rem"), eCSSUnit_RootEM, VARIANT_LENGTH },
{ STR_WITH_LEN("mm"), eCSSUnit_Millimeter, VARIANT_LENGTH },
{ STR_WITH_LEN("mozmm"), eCSSUnit_PhysicalMillimeter, VARIANT_LENGTH },
{ STR_WITH_LEN("vw"), eCSSUnit_ViewportWidth, VARIANT_LENGTH },
{ STR_WITH_LEN("vh"), eCSSUnit_ViewportHeight, VARIANT_LENGTH },
{ STR_WITH_LEN("vmin"), eCSSUnit_ViewportMin, VARIANT_LENGTH },
{ STR_WITH_LEN("vmax"), eCSSUnit_ViewportMax, VARIANT_LENGTH },
{ STR_WITH_LEN("pc"), eCSSUnit_Pica, VARIANT_LENGTH },
{ STR_WITH_LEN("deg"), eCSSUnit_Degree, VARIANT_ANGLE },
{ STR_WITH_LEN("grad"), eCSSUnit_Grad, VARIANT_ANGLE },

Просмотреть файл

@ -1120,6 +1120,11 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
case eCSSUnit_Point: aResult.AppendLiteral("pt"); break;
case eCSSUnit_Pica: aResult.AppendLiteral("pc"); break;
case eCSSUnit_ViewportWidth: aResult.AppendLiteral("vw"); break;
case eCSSUnit_ViewportHeight: aResult.AppendLiteral("vh"); break;
case eCSSUnit_ViewportMin: aResult.AppendLiteral("vmin"); break;
case eCSSUnit_ViewportMax: aResult.AppendLiteral("vmax"); break;
case eCSSUnit_EM: aResult.AppendLiteral("em"); break;
case eCSSUnit_XHeight: aResult.AppendLiteral("ex"); break;
case eCSSUnit_Char: aResult.AppendLiteral("ch"); break;
@ -1248,6 +1253,10 @@ nsCSSValue::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
case eCSSUnit_Percent:
case eCSSUnit_Number:
case eCSSUnit_PhysicalMillimeter:
case eCSSUnit_ViewportWidth:
case eCSSUnit_ViewportHeight:
case eCSSUnit_ViewportMin:
case eCSSUnit_ViewportMax:
case eCSSUnit_EM:
case eCSSUnit_XHeight:
case eCSSUnit_Char:

Просмотреть файл

@ -209,6 +209,12 @@ enum nsCSSUnit {
eCSSUnit_PhysicalMillimeter = 200, // (float) 1/25.4 inch
// Length units - relative
// Viewport relative measure
eCSSUnit_ViewportWidth = 700, // (float) 1% of the width of the initial containing block
eCSSUnit_ViewportHeight = 701, // (float) 1% of the height of the initial containing block
eCSSUnit_ViewportMin = 702, // (float) smaller of ViewportWidth and ViewportHeight
eCSSUnit_ViewportMax = 703, // (float) larger of ViewportWidth and ViewportHeight
// Font relative measure
eCSSUnit_EM = 800, // (float) == current font size
eCSSUnit_XHeight = 801, // (float) distance from top of lower case x to baseline

Просмотреть файл

@ -9,6 +9,8 @@
* responsible for converting the rules' information into computed style
*/
#include <algorithm>
#include "nsRuleNode.h"
#include "nscore.h"
#include "nsIServiceManager.h"
@ -53,6 +55,8 @@
#include <alloca.h>
#endif
using std::max;
using std::min;
using namespace mozilla;
using namespace mozilla::dom;
@ -264,6 +268,24 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
aFontSize = styleFont->mFont.size;
}
switch (aValue.GetUnit()) {
case eCSSUnit_ViewportWidth: {
aPresContext->SetUsesViewportUnits(true);
return ScaleCoord(aValue, 0.01f * aPresContext->GetVisibleArea().width);
}
case eCSSUnit_ViewportHeight: {
aPresContext->SetUsesViewportUnits(true);
return ScaleCoord(aValue, 0.01f * aPresContext->GetVisibleArea().height);
}
case eCSSUnit_ViewportMin: {
aPresContext->SetUsesViewportUnits(true);
nsSize viewportSize = aPresContext->GetVisibleArea().Size();
return ScaleCoord(aValue, 0.01f * min(viewportSize.width, viewportSize.height));
}
case eCSSUnit_ViewportMax: {
aPresContext->SetUsesViewportUnits(true);
nsSize viewportSize = aPresContext->GetVisibleArea().Size();
return ScaleCoord(aValue, 0.01f * max(viewportSize.width, viewportSize.height));
}
case eCSSUnit_RootEM: {
nscoord rootFontSize;