Bug 1345767 - Part 3: Factor IsValueMissing() out of HTMLInputElement. r?smaug
MozReview-Commit-ID: AE6SSA43Vx5
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -7518,41 +7518,17 @@ HTMLInputElement::IsTooShort()
}
bool
HTMLInputElement::IsValueMissing() const
{
// Should use UpdateValueMissingValidityStateForRadio() for type radio.
MOZ_ASSERT(mType != NS_FORM_INPUT_RADIO);
- if (!HasAttr(kNameSpaceID_None, nsGkAtoms::required) ||
- !DoesRequiredApply()) {
- return false;
- }
-
- if (!IsMutable()) {
- return false;
- }
-
- switch (GetValueMode()) {
- case VALUE_MODE_VALUE:
- return IsValueEmpty();
-
- case VALUE_MODE_FILENAME:
- return GetFilesOrDirectoriesInternal().IsEmpty();
-
- case VALUE_MODE_DEFAULT_ON:
- // This should not be used for type radio.
- // See the MOZ_ASSERT at the beginning of the method.
- return !mChecked;
-
- case VALUE_MODE_DEFAULT:
- default:
- return false;
- }
+ return mInputType->IsValueMissing();
}
bool
HTMLInputElement::HasTypeMismatch() const
{
if (mType != NS_FORM_INPUT_EMAIL && mType != NS_FORM_INPUT_URL) {
return false;
}
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -129,16 +129,17 @@ class HTMLInputElement final : public ns
public nsIDOMHTMLInputElement,
public nsITextControlElement,
public nsIPhonetic,
public nsIDOMNSEditableElement,
public nsIConstraintValidation
{
friend class AfterSetFilesOrDirectoriesCallback;
friend class DispatchChangeEventCallback;
+ friend class ::InputType;
public:
using nsIConstraintValidation::GetValidationMessage;
using nsIConstraintValidation::CheckValidity;
using nsIConstraintValidation::ReportValidity;
using nsIConstraintValidation::WillValidate;
using nsIConstraintValidation::Validity;
using nsGenericHTMLFormElementWithState::GetForm;
new file mode 100644
--- /dev/null
+++ b/dom/html/input/CheckableInputTypes.cpp
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "CheckableInputTypes.h"
+
+#include "mozilla/dom/HTMLInputElement.h"
+
+bool
+CheckboxInputType::IsValueMissing() const
+{
+ if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+ return false;
+ }
+
+ if (!IsMutable()) {
+ return false;
+ }
+
+ return !mInputElement->Checked();
+}
--- a/dom/html/input/CheckableInputTypes.h
+++ b/dom/html/input/CheckableInputTypes.h
@@ -25,16 +25,18 @@ class CheckboxInputType : public Checkab
{
public:
static InputType*
Create(mozilla::dom::HTMLInputElement* aInputElement, void* aMemory)
{
return new (aMemory) CheckboxInputType(aInputElement);
}
+ bool IsValueMissing() const override;
+
private:
explicit CheckboxInputType(mozilla::dom::HTMLInputElement* aInputElement)
: CheckableInputTypeBase(aInputElement)
{}
};
// input type=radio
class RadioInputType : public CheckableInputTypeBase
new file mode 100644
--- /dev/null
+++ b/dom/html/input/DateTimeInputTypes.cpp
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DateTimeInputTypes.h"
+
+#include "mozilla/dom/HTMLInputElement.h"
+
+bool
+DateTimeInputTypeBase::IsMutable() const
+{
+ return !mInputElement->IsDisabled() &&
+ !mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
+}
+
+bool
+DateTimeInputTypeBase::IsValueMissing() const
+{
+ if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+ return false;
+ }
+
+ if (!IsMutable()) {
+ return false;
+ }
+
+ return IsValueEmpty();
+}
--- a/dom/html/input/DateTimeInputTypes.h
+++ b/dom/html/input/DateTimeInputTypes.h
@@ -9,20 +9,24 @@
#include "InputType.h"
class DateTimeInputTypeBase : public ::InputType
{
public:
~DateTimeInputTypeBase() override {}
+ bool IsValueMissing() const override;
+
protected:
explicit DateTimeInputTypeBase(mozilla::dom::HTMLInputElement* aInputElement)
: InputType(aInputElement)
{}
+
+ bool IsMutable() const override;
};
// input type=date
class DateInputType : public DateTimeInputTypeBase
{
public:
static InputType*
Create(mozilla::dom::HTMLInputElement* aInputElement, void* aMemory)
new file mode 100644
--- /dev/null
+++ b/dom/html/input/FileInputType.cpp
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "FileInputType.h"
+
+#include "mozilla/dom/HTMLInputElement.h"
+
+bool
+FileInputType::IsValueMissing() const
+{
+ if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+ return false;
+ }
+
+ if (!IsMutable()) {
+ return false;
+ }
+
+ return mInputElement->GetFilesOrDirectoriesInternal().IsEmpty();
+}
--- a/dom/html/input/FileInputType.h
+++ b/dom/html/input/FileInputType.h
@@ -14,15 +14,17 @@ class FileInputType : public ::InputType
{
public:
static InputType*
Create(mozilla::dom::HTMLInputElement* aInputElement, void* aMemory)
{
return new (aMemory) FileInputType(aInputElement);
}
+ bool IsValueMissing() const override;
+
private:
explicit FileInputType(mozilla::dom::HTMLInputElement* aInputElement)
: InputType(aInputElement)
{}
};
#endif /* FileInputType_h__ */
--- a/dom/html/input/InputType.cpp
+++ b/dom/html/input/InputType.cpp
@@ -97,16 +97,28 @@ InputType::Create(mozilla::dom::HTMLInpu
break;
default:
inputType.reset(TextInputType::Create(aInputElement, aMemory));
}
return inputType;
}
+bool
+InputType::IsMutable() const
+{
+ return !mInputElement->IsDisabled();
+}
+
+bool
+InputType::IsValueEmpty() const
+{
+ return mInputElement->IsValueEmpty();
+}
+
void
InputType::DropReference()
{
// Drop our (non ref-counted) reference.
mInputElement = nullptr;
}
bool
@@ -115,8 +127,14 @@ InputType::IsTooLong() const
return false;
}
bool
InputType::IsTooShort() const
{
return false;
}
+
+bool
+InputType::IsValueMissing() const
+{
+ return false;
+}
--- a/dom/html/input/InputType.h
+++ b/dom/html/input/InputType.h
@@ -32,22 +32,41 @@ public:
/**
* Drop the reference to the input element.
*/
void DropReference();
virtual bool IsTooLong() const;
virtual bool IsTooShort() const;
+ virtual bool IsValueMissing() const;
protected:
explicit InputType(mozilla::dom::HTMLInputElement* aInputElement)
: mInputElement(aInputElement)
{}
+ /**
+ * Get the mutable state of the element.
+ * When the element isn't mutable (immutable), the value or checkedness
+ * should not be changed by the user.
+ *
+ * See: https://html.spec.whatwg.org/multipage/forms.html#the-input-element:concept-fe-mutable
+ */
+ virtual bool IsMutable() const;
+
+ /**
+ * Returns whether the input element's current value is the empty string.
+ * This only makes sense for some input types; does NOT make sense for file
+ * inputs.
+ *
+ * @return whether the input element's current value is the empty string.
+ */
+ bool IsValueEmpty() const;
+
mozilla::dom::HTMLInputElement* mInputElement;
};
// Custom deleter for UniquePtr<InputType> to avoid freeing memory pre-allocated
// for InputType, but we still need to call the destructor explictly.
struct DoNotDelete { void operator()(::InputType* p) { p->~InputType(); } };
#endif /* InputType_h__ */
new file mode 100644
--- /dev/null
+++ b/dom/html/input/NumericInputTypes.cpp
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "NumericInputTypes.h"
+
+#include "mozilla/dom/HTMLInputElement.h"
+
+bool
+NumberInputType::IsMutable() const
+{
+ return !mInputElement->IsDisabled() &&
+ !mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
+}
+
+bool
+NumberInputType::IsValueMissing() const
+{
+ if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+ return false;
+ }
+
+ if (!IsMutable()) {
+ return false;
+ }
+
+ return IsValueEmpty();
+}
--- a/dom/html/input/NumericInputTypes.h
+++ b/dom/html/input/NumericInputTypes.h
@@ -25,20 +25,24 @@ class NumberInputType : public NumericIn
{
public:
static InputType*
Create(mozilla::dom::HTMLInputElement* aInputElement, void* aMemory)
{
return new (aMemory) NumberInputType(aInputElement);
}
+ bool IsValueMissing() const override;
+
private:
explicit NumberInputType(mozilla::dom::HTMLInputElement* aInputElement)
: NumericInputTypeBase(aInputElement)
{}
+
+ bool IsMutable() const override;
};
// input type=range
class RangeInputType : public NumericInputTypeBase
{
public:
static InputType*
Create(mozilla::dom::HTMLInputElement* aInputElement, void* aMemory)
--- a/dom/html/input/SingleLineTextInputTypes.cpp
+++ b/dom/html/input/SingleLineTextInputTypes.cpp
@@ -5,16 +5,23 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SingleLineTextInputTypes.h"
#include "mozilla/dom/HTMLInputElement.h"
#include "mozilla/dom/BindingDeclarations.h"
bool
+SingleLineTextInputTypeBase::IsMutable() const
+{
+ return !mInputElement->IsDisabled() &&
+ !mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
+}
+
+bool
SingleLineTextInputTypeBase::IsTooLong() const
{
int32_t maxLength = mInputElement->MaxLength();
// Maxlength of -1 means attribute isn't set or parsing error.
if (maxLength == -1) {
return false;
}
@@ -35,8 +42,22 @@ SingleLineTextInputTypeBase::IsTooShort(
return false;
}
int32_t textLength =
mInputElement->InputTextLength(mozilla::dom::CallerType::System);
return textLength && textLength < minLength;
}
+
+bool
+SingleLineTextInputTypeBase::IsValueMissing() const
+{
+ if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+ return false;
+ }
+
+ if (!IsMutable()) {
+ return false;
+ }
+
+ return IsValueEmpty();
+}
--- a/dom/html/input/SingleLineTextInputTypes.h
+++ b/dom/html/input/SingleLineTextInputTypes.h
@@ -11,22 +11,25 @@
class SingleLineTextInputTypeBase : public ::InputType
{
public:
~SingleLineTextInputTypeBase() override {}
bool IsTooLong() const override;
bool IsTooShort() const override;
+ bool IsValueMissing() const override;
protected:
explicit SingleLineTextInputTypeBase(
mozilla::dom::HTMLInputElement* aInputElement)
: InputType(aInputElement)
{}
+
+ bool IsMutable() const override;
};
// input type=text
class TextInputType : public SingleLineTextInputTypeBase
{
public:
static InputType*
Create(mozilla::dom::HTMLInputElement* aInputElement, void* aMemory)
--- a/dom/html/input/moz.build
+++ b/dom/html/input/moz.build
@@ -12,17 +12,21 @@ EXPORTS += [
'FileInputType.h',
'HiddenInputType.h',
'InputType.h',
'NumericInputTypes.h',
'SingleLineTextInputTypes.h',
]
UNIFIED_SOURCES += [
+ 'CheckableInputTypes.cpp',
+ 'DateTimeInputTypes.cpp',
+ 'FileInputType.cpp',
'InputType.cpp',
+ 'NumericInputTypes.cpp',
'SingleLineTextInputTypes.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
LOCAL_INCLUDES += [
'/dom/base',
'/dom/html',