--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -12,16 +12,17 @@
#include <algorithm>
#include "mozilla/ArrayUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/dom/AnimationEffectReadOnlyBinding.h" // for PlaybackDirection
#include "mozilla/Likely.h"
#include "mozilla/LookAndFeel.h"
+#include "mozilla/unused.h"
#include "mozilla/css/Declaration.h"
#include "nsAlgorithm.h" // for clamped()
#include "nsRuleNode.h"
#include "nscore.h"
#include "nsIWidget.h"
#include "nsIPresShell.h"
@@ -1275,120 +1276,187 @@ static void SetStyleImage(nsStyleContext
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unexpected Unit type.");
break;
}
}
+struct SetEnumValueHelper
+{
+ template<typename FieldT>
+ static void SetIntegerValue(FieldT&, const nsCSSValue&)
+ {
+ // FIXME Is it possible to turn this assertion into a compilation error?
+ MOZ_ASSERT_UNREACHABLE("inappropriate unit");
+ }
+
+#define DEFINE_ENUM_CLASS_SETTER(type_, min_, max_) \
+ static void SetEnumeratedValue(type_& aField, const nsCSSValue& aValue) \
+ { \
+ auto value = aValue.GetIntValue(); \
+ MOZ_ASSERT(value >= static_cast<decltype(value)>(type_::min_) && \
+ value <= static_cast<decltype(value)>(type_::max_), \
+ "inappropriate value"); \
+ aField = static_cast<type_>(value); \
+ }
+
+ DEFINE_ENUM_CLASS_SETTER(StyleBoxSizing, Content, Border)
+
+#undef DEF_SET_ENUMERATED_VALUE
+};
+
+template<typename FieldT>
+struct SetIntegerValueHelper
+{
+ static void SetIntegerValue(FieldT& aField, const nsCSSValue& aValue)
+ {
+ aField = aValue.GetIntValue();
+ }
+ static void SetEnumeratedValue(FieldT& aField, const nsCSSValue& aValue)
+ {
+ aField = aValue.GetIntValue();
+ }
+};
+
+template<typename FieldT>
+struct SetValueHelper : Conditional<IsEnum<FieldT>::value,
+ SetEnumValueHelper,
+ SetIntegerValueHelper<FieldT>>::Type
+{
+ template<typename ValueT>
+ static void SetValue(FieldT& aField, const ValueT& aValue)
+ {
+ aField = aValue;
+ }
+ static void SetValue(FieldT&, unused_t)
+ {
+ // FIXME Is it possible to turn this assertion into a compilation error?
+ MOZ_ASSERT_UNREACHABLE("inappropriate unit");
+ }
+};
+
+
// flags for SetValue - align values with SETCOORD_* constants
// where possible
#define SETVAL_NORMAL 0x01 // N
#define SETVAL_AUTO 0x02 // A
#define SETVAL_INTEGER 0x40 // I
#define SETVAL_ENUMERATED 0x80 // E
#define SETVAL_NONE 0x100 // O
#define SETVAL_SYSTEM_FONT 0x2000
#define SETVAL_UNSET_INHERIT 0x00400000
#define SETVAL_UNSET_INITIAL 0x00800000
// no caller cares whether aField was changed or not
-template <typename FieldT,
- typename T1, typename T2, typename T3, typename T4, typename T5>
+template<typename FieldT, typename InitialT,
+ typename AutoT, typename NoneT, typename NormalT, typename SysFontT>
static void
-SetValue(const nsCSSValue& aValue, FieldT & aField,
+SetValue(const nsCSSValue& aValue, FieldT& aField,
RuleNodeCacheConditions& aConditions, uint32_t aMask,
FieldT aParentValue,
- T1 aInitialValue,
- T2 aAutoValue,
- T3 aNoneValue,
- T4 aNormalValue,
- T5 aSystemFontValue)
-{
+ InitialT aInitialValue,
+ AutoT aAutoValue,
+ NoneT aNoneValue,
+ NormalT aNormalValue,
+ SysFontT aSystemFontValue)
+{
+ typedef SetValueHelper<FieldT> Helper;
+
switch (aValue.GetUnit()) {
case eCSSUnit_Null:
return;
// every caller of SetValue provides inherit and initial
// alternatives, so we don't require them to say so in the mask
case eCSSUnit_Inherit:
aConditions.SetUncacheable();
aField = aParentValue;
return;
case eCSSUnit_Initial:
- aField = aInitialValue;
+ Helper::SetValue(aField, aInitialValue);
return;
// every caller provides one or other of these alternatives,
// but they have to say which
case eCSSUnit_Enumerated:
if (aMask & SETVAL_ENUMERATED) {
- aField = FieldT(aValue.GetIntValue());
+ Helper::SetEnumeratedValue(aField, aValue);
return;
}
break;
case eCSSUnit_Integer:
if (aMask & SETVAL_INTEGER) {
- aField = FieldT(aValue.GetIntValue());
+ Helper::SetIntegerValue(aField, aValue);
return;
}
break;
// remaining possibilities in descending order of frequency of use
case eCSSUnit_Auto:
if (aMask & SETVAL_AUTO) {
- aField = aAutoValue;
+ Helper::SetValue(aField, aAutoValue);
return;
}
break;
case eCSSUnit_None:
if (aMask & SETVAL_NONE) {
- aField = aNoneValue;
+ Helper::SetValue(aField, aNoneValue);
return;
}
break;
case eCSSUnit_Normal:
if (aMask & SETVAL_NORMAL) {
- aField = aNormalValue;
+ Helper::SetValue(aField, aNormalValue);
return;
}
break;
case eCSSUnit_System_Font:
if (aMask & SETVAL_SYSTEM_FONT) {
- aField = aSystemFontValue;
+ Helper::SetValue(aField, aSystemFontValue);
return;
}
break;
case eCSSUnit_Unset:
if (aMask & SETVAL_UNSET_INHERIT) {
aConditions.SetUncacheable();
aField = aParentValue;
return;
}
if (aMask & SETVAL_UNSET_INITIAL) {
- aField = aInitialValue;
+ Helper::SetValue(aField, aInitialValue);
return;
}
break;
default:
break;
}
NS_NOTREACHED("SetValue: inappropriate unit");
}
+template <typename FieldT, typename T1>
+static void
+SetValue(const nsCSSValue& aValue, FieldT& aField,
+ RuleNodeCacheConditions& aConditions, uint32_t aMask,
+ FieldT aParentValue, T1 aInitialValue)
+{
+ SetValue(aValue, aField, aConditions, aMask, aParentValue,
+ aInitialValue, Unused, Unused, Unused, Unused);
+}
+
// flags for SetFactor
#define SETFCT_POSITIVE 0x01 // assert value is >= 0.0f
#define SETFCT_OPACITY 0x02 // clamp value to [0.0f .. 1.0f]
#define SETFCT_NONE 0x04 // allow _None (uses aInitialValue).
#define SETFCT_UNSET_INHERIT 0x00400000
#define SETFCT_UNSET_INITIAL 0x00800000
static void
@@ -8367,21 +8435,17 @@ nsRuleNode::ComputePositionData(void* aS
SETCOORD_UNSET_INITIAL,
aContext, mPresContext, conditions);
// box-sizing: enum, inherit, initial
SetValue(*aRuleData->ValueForBoxSizing(),
pos->mBoxSizing, conditions,
SETVAL_ENUMERATED | SETVAL_UNSET_INITIAL,
parentPos->mBoxSizing,
- StyleBoxSizing::Content,
- StyleBoxSizing::Content /* ignored */,
- StyleBoxSizing::Content /* ignored */,
- StyleBoxSizing::Content /* ignored */,
- StyleBoxSizing::Content /* ignored */);
+ StyleBoxSizing::Content);
// align-content: enum, inherit, initial
SetValue(*aRuleData->ValueForAlignContent(),
pos->mAlignContent, conditions,
SETVAL_ENUMERATED | SETVAL_UNSET_INITIAL,
parentPos->mAlignContent,
NS_STYLE_ALIGN_NORMAL, 0, 0, 0, 0);