Bug 1345767 - Part 6: Factor IsRangeOverflow/Underflow() and HasStepMismatch() out of HTMLInputElement. r=smaug

MozReview-Commit-ID: 4jmjPK1Wxhz
This commit is contained in:
Jessica Jong
2017-05-04 15:33:38 +08:00
parent 8a807e1a27
commit f7b53a9295
7 changed files with 221 additions and 95 deletions

View File

@@ -127,14 +127,6 @@ NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Input)
static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
// This must come outside of any namespace, or else it won't overload with the
// double based version in nsMathUtils.h
inline mozilla::Decimal
NS_floorModulo(mozilla::Decimal x, mozilla::Decimal y)
{
return (x - y * (x / y).floor());
}
namespace mozilla {
namespace dom {
@@ -1473,26 +1465,10 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
UpdateTypeMismatchValidityState();
} else if (aName == nsGkAtoms::max) {
UpdateHasRange();
if (mType == NS_FORM_INPUT_RANGE) {
// The value may need to change when @max changes since the value may
// have been invalid and can now change to a valid value, or vice
// versa. For example, consider:
// <input type=range value=-1 max=1 step=3>. The valid range is 0 to 1
// while the nearest valid steps are -1 and 2 (the max value having
// prevented there being a valid step in range). Changing @max to/from
// 1 and a number greater than on equal to 3 should change whether we
// have a step mismatch or not.
// The value may also need to change between a value that results in
// a step mismatch and a value that results in overflow. For example,
// if @max in the example above were to change from 1 to -1.
nsAutoString value;
GetNonFileValueInternal(value);
nsresult rv =
SetValueInternal(value, nsTextEditorState::eSetValue_Internal);
NS_ENSURE_SUCCESS(rv, rv);
}
// Validity state must be updated *after* the SetValueInternal call above
// or else the following assert will not be valid.
nsresult rv = mInputType->MinMaxStepAttrChanged();
NS_ENSURE_SUCCESS(rv, rv);
// Validity state must be updated *after* the UpdateValueDueToAttrChange
// call above or else the following assert will not be valid.
// We don't assert the state of underflow during creation since
// DoneCreatingElement sanitizes.
UpdateRangeOverflowValidityState();
@@ -1502,14 +1478,8 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
"HTML5 spec does not allow underflow for type=range");
} else if (aName == nsGkAtoms::min) {
UpdateHasRange();
if (mType == NS_FORM_INPUT_RANGE) {
// See @max comment
nsAutoString value;
GetNonFileValueInternal(value);
nsresult rv =
SetValueInternal(value, nsTextEditorState::eSetValue_Internal);
NS_ENSURE_SUCCESS(rv, rv);
}
nsresult rv = mInputType->MinMaxStepAttrChanged();
NS_ENSURE_SUCCESS(rv, rv);
// See corresponding @max comment
UpdateRangeUnderflowValidityState();
UpdateStepMismatchValidityState();
@@ -1518,14 +1488,8 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
!GetValidityState(VALIDITY_STATE_RANGE_UNDERFLOW),
"HTML5 spec does not allow underflow for type=range");
} else if (aName == nsGkAtoms::step) {
if (mType == NS_FORM_INPUT_RANGE) {
// See @max comment
nsAutoString value;
GetNonFileValueInternal(value);
nsresult rv =
SetValueInternal(value, nsTextEditorState::eSetValue_Internal);
NS_ENSURE_SUCCESS(rv, rv);
}
nsresult rv = mInputType->MinMaxStepAttrChanged();
NS_ENSURE_SUCCESS(rv, rv);
// See corresponding @max comment
UpdateStepMismatchValidityState();
MOZ_ASSERT(!mDoneCreating ||
@@ -7548,67 +7512,19 @@ HTMLInputElement::HasPatternMismatch() const
bool
HTMLInputElement::IsRangeOverflow() const
{
if (!DoesMinMaxApply()) {
return false;
}
Decimal maximum = GetMaximum();
if (maximum.isNaN()) {
return false;
}
Decimal value = GetValueAsDecimal();
if (value.isNaN()) {
return false;
}
return value > maximum;
return mInputType->IsRangeOverflow();
}
bool
HTMLInputElement::IsRangeUnderflow() const
{
if (!DoesMinMaxApply()) {
return false;
}
Decimal minimum = GetMinimum();
if (minimum.isNaN()) {
return false;
}
Decimal value = GetValueAsDecimal();
if (value.isNaN()) {
return false;
}
return value < minimum;
return mInputType->IsRangeUnderflow();
}
bool
HTMLInputElement::HasStepMismatch(bool aUseZeroIfValueNaN) const
{
if (!DoesStepApply()) {
return false;
}
Decimal value = GetValueAsDecimal();
if (value.isNaN()) {
if (aUseZeroIfValueNaN) {
value = Decimal(0);
} else {
// The element can't suffer from step mismatch if it's value isn't a number.
return false;
}
}
Decimal step = GetStep();
if (step == kStepAny) {
return false;
}
// Value has to be an integral multiple of step.
return NS_floorModulo(value - GetStepBase(), step) != Decimal(0);
return mInputType->HasStepMismatch(aUseZeroIfValueNaN);
}
/**