mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
Support CSS sizing math functions
This commit is contained in:
parent
7766f8f53d
commit
c47cea4ddf
12 changed files with 1234 additions and 28 deletions
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "mozilla/CSSStyleSheet.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "nsIAtom.h"
|
||||
#include "nsCSSRuleProcessor.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
|
@ -130,6 +132,153 @@ int32_t DoCompare(Numeric a, Numeric b)
|
|||
return 1;
|
||||
}
|
||||
|
||||
struct MediaQueryTypedCalcLengthResult
|
||||
{
|
||||
double mValue;
|
||||
int32_t mExponent;
|
||||
};
|
||||
|
||||
static bool
|
||||
EvaluateMediaQueryTypedCalcLength(nsPresContext* aPresContext,
|
||||
const nsCSSValue& aValue,
|
||||
MediaQueryTypedCalcLengthResult& aResult)
|
||||
{
|
||||
switch (aValue.GetUnit()) {
|
||||
case eCSSUnit_Calc: {
|
||||
nsCSSValue::Array* array = aValue.GetArrayValue();
|
||||
MOZ_ASSERT(array->Count() == 1, "unexpected length");
|
||||
return EvaluateMediaQueryTypedCalcLength(aPresContext, array->Item(0),
|
||||
aResult);
|
||||
}
|
||||
|
||||
case eCSSUnit_Calc_Plus:
|
||||
case eCSSUnit_Calc_Minus: {
|
||||
nsCSSValue::Array* array = aValue.GetArrayValue();
|
||||
MOZ_ASSERT(array->Count() == 2, "unexpected length");
|
||||
MediaQueryTypedCalcLengthResult lhs;
|
||||
MediaQueryTypedCalcLengthResult rhs;
|
||||
if (!EvaluateMediaQueryTypedCalcLength(aPresContext, array->Item(0), lhs) ||
|
||||
!EvaluateMediaQueryTypedCalcLength(aPresContext, array->Item(1), rhs) ||
|
||||
lhs.mExponent != rhs.mExponent) {
|
||||
return false;
|
||||
}
|
||||
aResult.mExponent = lhs.mExponent;
|
||||
aResult.mValue = aValue.GetUnit() == eCSSUnit_Calc_Plus
|
||||
? lhs.mValue + rhs.mValue
|
||||
: lhs.mValue - rhs.mValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
case eCSSUnit_Calc_Times_L:
|
||||
case eCSSUnit_Calc_Times_R:
|
||||
case eCSSUnit_Calc_Divided: {
|
||||
nsCSSValue::Array* array = aValue.GetArrayValue();
|
||||
MOZ_ASSERT(array->Count() == 2, "unexpected length");
|
||||
MediaQueryTypedCalcLengthResult lhs;
|
||||
MediaQueryTypedCalcLengthResult rhs;
|
||||
if (!EvaluateMediaQueryTypedCalcLength(aPresContext, array->Item(0), lhs) ||
|
||||
!EvaluateMediaQueryTypedCalcLength(aPresContext, array->Item(1), rhs)) {
|
||||
return false;
|
||||
}
|
||||
if (aValue.GetUnit() == eCSSUnit_Calc_Divided) {
|
||||
if (rhs.mValue == 0.0) {
|
||||
return false;
|
||||
}
|
||||
aResult.mValue = lhs.mValue / rhs.mValue;
|
||||
aResult.mExponent = lhs.mExponent - rhs.mExponent;
|
||||
} else {
|
||||
aResult.mValue = lhs.mValue * rhs.mValue;
|
||||
aResult.mExponent = lhs.mExponent + rhs.mExponent;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case eCSSUnit_Calc_Min:
|
||||
case eCSSUnit_Calc_Max:
|
||||
case eCSSUnit_Calc_Clamp: {
|
||||
nsCSSValue::Array* array = aValue.GetArrayValue();
|
||||
MOZ_ASSERT(aValue.GetUnit() != eCSSUnit_Calc_Clamp ||
|
||||
array->Count() == 3, "unexpected length");
|
||||
MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Calc_Clamp ||
|
||||
array->Count() >= 1, "unexpected length");
|
||||
|
||||
MediaQueryTypedCalcLengthResult result;
|
||||
if (!EvaluateMediaQueryTypedCalcLength(aPresContext, array->Item(0),
|
||||
result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aValue.GetUnit() == eCSSUnit_Calc_Clamp) {
|
||||
MediaQueryTypedCalcLengthResult center;
|
||||
MediaQueryTypedCalcLengthResult max;
|
||||
if (!EvaluateMediaQueryTypedCalcLength(aPresContext, array->Item(1),
|
||||
center) ||
|
||||
!EvaluateMediaQueryTypedCalcLength(aPresContext, array->Item(2),
|
||||
max) ||
|
||||
result.mExponent != center.mExponent ||
|
||||
result.mExponent != max.mExponent) {
|
||||
return false;
|
||||
}
|
||||
aResult.mExponent = result.mExponent;
|
||||
aResult.mValue = std::max(result.mValue,
|
||||
std::min(center.mValue, max.mValue));
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32_t i = 1; i < array->Count(); ++i) {
|
||||
MediaQueryTypedCalcLengthResult item;
|
||||
if (!EvaluateMediaQueryTypedCalcLength(aPresContext, array->Item(i),
|
||||
item) ||
|
||||
result.mExponent != item.mExponent) {
|
||||
return false;
|
||||
}
|
||||
result.mValue = aValue.GetUnit() == eCSSUnit_Calc_Min
|
||||
? std::min(result.mValue, item.mValue)
|
||||
: std::max(result.mValue, item.mValue);
|
||||
}
|
||||
aResult = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
case eCSSUnit_Number:
|
||||
aResult.mValue = aValue.GetFloatValue();
|
||||
aResult.mExponent = 0;
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!aValue.IsLengthUnit()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aResult.mValue = double(nsRuleNode::CalcLengthWithInitialFont(aPresContext,
|
||||
aValue));
|
||||
aResult.mExponent = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ComputeMediaQueryTypedCalcLength(nsPresContext* aPresContext,
|
||||
const nsCSSValue& aValue,
|
||||
nscoord& aResult)
|
||||
{
|
||||
if (aValue.IsLengthUnit()) {
|
||||
aResult = nsRuleNode::CalcLengthWithInitialFont(aPresContext, aValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
MediaQueryTypedCalcLengthResult result;
|
||||
if (!EvaluateMediaQueryTypedCalcLength(aPresContext, aValue, result) ||
|
||||
result.mExponent != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aResult = NSToCoordFloorClamped(result.mValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsMediaExpression::Matches(nsPresContext *aPresContext,
|
||||
const nsCSSValue& aActualValue) const
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue