Commit 994e7d38 authored by tkent@chromium.org's avatar tkent@chromium.org

Introduce isValidValue(const String&) of HTMLInputElement and HTMLTextAreaElement

https://bugs.webkit.org/show_bug.cgi?id=43537

Reviewed by Darin Adler.

WebCore:

isValidValue() is useful for browser implementations to propose
form field values without breaking form validity.
No new tests because these functions are not exposed to JavaScript.

* html/HTMLFormControlElement.h:
(WebCore::HTMLTextFormControlElement::):
 Remove virtual valueMissing(), patternMismatch(), and tooLong().
* html/HTMLInputElement.cpp:
(WebCore::isValidColorString): Moved from ValidityState.
(WebCore::isValidEmailAddress): ditto.
(WebCore::HTMLInputElement::isValidValue): Added.
(WebCore::HTMLInputElement::typeMismatch): Add a String parameter.
(WebCore::HTMLInputElement::valueMissing): Add a String parameter.
(WebCore::HTMLInputElement::patternMismatch): Add a String parameter.
(WebCore::HTMLInputElement::tooLong): Add String and NeedsToCheckDirtyFlag parameters.
(WebCore::HTMLInputElement::rangeUnderflow): Add a String parameter.
(WebCore::HTMLInputElement::rangeOverflow): Add a String parameter.
(WebCore::HTMLInputElement::stepMismatch): Add a String parameter.
* html/HTMLInputElement.h:
* html/HTMLTextAreaElement.cpp:
(WebCore::HTMLTextAreaElement::tooLong): Add String and NeedsToCheckDirtyFlag parameters.
(WebCore::HTMLTextAreaElement::isValidValue): Added.
* html/HTMLTextAreaElement.h:
(WebCore::HTMLTextAreaElement::valueMissing):
* html/ValidityState.cpp:
(WebCore::ValidityState::valueMissing): Calls valueMissing() of HTMLInputElement or HTMLTextAreaElement.
(WebCore::ValidityState::typeMismatch): Passes value() to HTMLInputElement::typeMismatch().
(WebCore::ValidityState::patternMismatch): Calls patternMismatch() of HTMLInputElement.
(WebCore::ValidityState::tooLong): Calls valueMissing() of HTMLInputElement or HTMLTextAreaElement.
(WebCore::ValidityState::rangeUnderflow): Passes value() to HTMLInputElement::rangeUnderflow().
(WebCore::ValidityState::rangeOverflow): Passes value() to HTMLInputElement::rangeUnderflow().
(WebCore::ValidityState::stepMismatch): Passes value() to HTMLInputElement::stepMismatch().
* html/ValidityState.h:

WebKit/chromium:

* public/WebInputElement.h:
* src/WebInputElement.cpp:
(WebKit::WebInputElement::isValidValue):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66357 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 7829f9f4
2010-08-29 Kent Tamura <tkent@chromium.org>
Reviewed by Darin Adler.
Introduce isValidValue(const String&) of HTMLInputElement and HTMLTextAreaElement
https://bugs.webkit.org/show_bug.cgi?id=43537
isValidValue() is useful for browser implementations to propose
form field values without breaking form validity.
No new tests because these functions are not exposed to JavaScript.
* html/HTMLFormControlElement.h:
(WebCore::HTMLTextFormControlElement::):
Remove virtual valueMissing(), patternMismatch(), and tooLong().
* html/HTMLInputElement.cpp:
(WebCore::isValidColorString): Moved from ValidityState.
(WebCore::isValidEmailAddress): ditto.
(WebCore::HTMLInputElement::isValidValue): Added.
(WebCore::HTMLInputElement::typeMismatch): Add a String parameter.
(WebCore::HTMLInputElement::valueMissing): Add a String parameter.
(WebCore::HTMLInputElement::patternMismatch): Add a String parameter.
(WebCore::HTMLInputElement::tooLong): Add String and NeedsToCheckDirtyFlag parameters.
(WebCore::HTMLInputElement::rangeUnderflow): Add a String parameter.
(WebCore::HTMLInputElement::rangeOverflow): Add a String parameter.
(WebCore::HTMLInputElement::stepMismatch): Add a String parameter.
* html/HTMLInputElement.h:
* html/HTMLTextAreaElement.cpp:
(WebCore::HTMLTextAreaElement::tooLong): Add String and NeedsToCheckDirtyFlag parameters.
(WebCore::HTMLTextAreaElement::isValidValue): Added.
* html/HTMLTextAreaElement.h:
(WebCore::HTMLTextAreaElement::valueMissing):
* html/ValidityState.cpp:
(WebCore::ValidityState::valueMissing): Calls valueMissing() of HTMLInputElement or HTMLTextAreaElement.
(WebCore::ValidityState::typeMismatch): Passes value() to HTMLInputElement::typeMismatch().
(WebCore::ValidityState::patternMismatch): Calls patternMismatch() of HTMLInputElement.
(WebCore::ValidityState::tooLong): Calls valueMissing() of HTMLInputElement or HTMLTextAreaElement.
(WebCore::ValidityState::rangeUnderflow): Passes value() to HTMLInputElement::rangeUnderflow().
(WebCore::ValidityState::rangeOverflow): Passes value() to HTMLInputElement::rangeUnderflow().
(WebCore::ValidityState::stepMismatch): Passes value() to HTMLInputElement::stepMismatch().
* html/ValidityState.h:
2010-08-29 Kent Tamura <tkent@chromium.org>
Reviewed by Darin Adler.
......@@ -88,9 +88,6 @@ public:
// This must be called when a validation constraint or control value is changed.
void setNeedsValidityCheck();
void setCustomValidity(const String&);
virtual bool valueMissing() const { return false; }
virtual bool patternMismatch() const { return false; }
virtual bool tooLong() const { return false; }
void formDestroyed() { m_form = 0; }
......@@ -175,6 +172,9 @@ private:
// FIXME: Give this class its own header file.
class HTMLTextFormControlElement : public HTMLFormControlElementWithState {
public:
// Common flag for HTMLInputElement::tooLong() and HTMLTextAreaElement::tooLong().
enum NeedsToCheckDirtyFlag {CheckDirtyFlag, IgnoreDirtyFlag};
virtual ~HTMLTextFormControlElement();
String strippedPlaceholder() const;
......
......@@ -108,12 +108,44 @@ static const double weekDefaultStepBase = -259200000.0; // The first day of 1970
static const double msecPerMinute = 60 * 1000;
static const double msecPerSecond = 1000;
static const char emailPattern[] =
"[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part
"@"
"[a-z0-9-]+(\\.[a-z0-9-]+)+"; // domain part
static bool isNumberCharacter(UChar ch)
{
return ch == '+' || ch == '-' || ch == '.' || ch == 'e' || ch == 'E'
|| (ch >= '0' && ch <= '9');
}
static bool isValidColorString(const String& value)
{
if (value.isEmpty())
return false;
if (value[0] == '#') {
// We don't accept #rgb and #aarrggbb formats.
if (value.length() != 7)
return false;
}
Color color(value); // This accepts named colors such as "white".
return color.isValid() && !color.hasAlpha();
}
static bool isValidEmailAddress(const String& address)
{
int addressLength = address.length();
if (!addressLength)
return false;
DEFINE_STATIC_LOCAL(const RegularExpression, regExp, (emailPattern, TextCaseInsensitive));
int matchLength;
int matchOffset = regExp.match(address, 0, &matchLength);
return !matchOffset && matchLength == addressLength;
}
HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
: HTMLTextFormControlElement(tagName, document, form)
, m_xPos(0)
......@@ -205,7 +237,71 @@ void HTMLInputElement::updateCheckedRadioButtons()
renderer()->theme()->stateChanged(renderer(), CheckedState);
}
bool HTMLInputElement::valueMissing() const
bool HTMLInputElement::isValidValue(const String& value) const
{
// Should not call isValidValue() for the following types because
// we can't set string values for these types.
if (inputType() == CHECKBOX || inputType() == FILE || inputType() == RADIO) {
ASSERT_NOT_REACHED();
return false;
}
return !typeMismatch(value)
&& !stepMismatch(value)
&& !rangeUnderflow(value)
&& !rangeOverflow(value)
&& !tooLong(value, IgnoreDirtyFlag)
&& !patternMismatch(value)
&& !valueMissing(value);
}
bool HTMLInputElement::typeMismatch(const String& value) const
{
switch (inputType()) {
case COLOR:
return !isValidColorString(value);
case NUMBER:
return !parseToDoubleForNumberType(value, 0);
case URL:
return !KURL(KURL(), value).isValid();
case EMAIL: {
if (!multiple())
return !isValidEmailAddress(value);
Vector<String> addresses;
value.split(',', addresses);
for (unsigned i = 0; i < addresses.size(); ++i) {
if (!isValidEmailAddress(addresses[i]))
return true;
}
return false;
}
case DATE:
case DATETIME:
case DATETIMELOCAL:
case MONTH:
case TIME:
case WEEK:
return !parseToDateComponents(inputType(), value, 0);
case BUTTON:
case CHECKBOX:
case FILE:
case HIDDEN:
case IMAGE:
case ISINDEX:
case PASSWORD:
case RADIO:
case RANGE:
case RESET:
case SEARCH:
case SUBMIT:
case TELEPHONE:
case TEXT:
return false;
}
ASSERT_NOT_REACHED();
return false;
}
bool HTMLInputElement::valueMissing(const String& value) const
{
if (!isRequiredFormControl() || readOnly() || disabled())
return false;
......@@ -225,7 +321,7 @@ bool HTMLInputElement::valueMissing() const
case TIME:
case URL:
case WEEK:
return value().isEmpty();
return value.isEmpty();
case CHECKBOX:
return !checked();
case RADIO:
......@@ -246,12 +342,11 @@ bool HTMLInputElement::valueMissing() const
return false;
}
bool HTMLInputElement::patternMismatch() const
bool HTMLInputElement::patternMismatch(const String& value) const
{
if (!isTextType())
return false;
const AtomicString& pattern = getAttribute(patternAttr);
String value = this->value();
// Empty values can't be mismatched
if (pattern.isEmpty() || value.isEmpty())
return false;
......@@ -262,7 +357,7 @@ bool HTMLInputElement::patternMismatch() const
return matchOffset || matchLength != valueLength;
}
bool HTMLInputElement::tooLong() const
bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
{
// We use isTextType() instead of supportsMaxLength() because of the
// 'virtual' overhead.
......@@ -271,14 +366,16 @@ bool HTMLInputElement::tooLong() const
int max = maxLength();
if (max < 0)
return false;
// Return false for the default value even if it is longer than maxLength.
bool userEdited = !m_data.value().isNull();
if (!userEdited)
return false;
return numGraphemeClusters(value()) > static_cast<unsigned>(max);
if (check == CheckDirtyFlag) {
// Return false for the default value even if it is longer than maxLength.
bool userEdited = !m_data.value().isNull();
if (!userEdited)
return false;
}
return numGraphemeClusters(value) > static_cast<unsigned>(max);
}
bool HTMLInputElement::rangeUnderflow() const
bool HTMLInputElement::rangeUnderflow(const String& value) const
{
const double nan = numeric_limits<double>::quiet_NaN();
switch (inputType()) {
......@@ -289,11 +386,11 @@ bool HTMLInputElement::rangeUnderflow() const
case NUMBER:
case TIME:
case WEEK: {
double doubleValue = parseToDouble(value(), nan);
double doubleValue = parseToDouble(value, nan);
return isfinite(doubleValue) && doubleValue < minimum();
}
case RANGE: // Guaranteed by sanitization.
ASSERT(parseToDouble(value(), nan) >= minimum());
ASSERT(parseToDouble(value, nan) >= minimum());
case BUTTON:
case CHECKBOX:
case COLOR:
......@@ -315,7 +412,7 @@ bool HTMLInputElement::rangeUnderflow() const
return false;
}
bool HTMLInputElement::rangeOverflow() const
bool HTMLInputElement::rangeOverflow(const String& value) const
{
const double nan = numeric_limits<double>::quiet_NaN();
switch (inputType()) {
......@@ -326,11 +423,11 @@ bool HTMLInputElement::rangeOverflow() const
case NUMBER:
case TIME:
case WEEK: {
double doubleValue = parseToDouble(value(), nan);
double doubleValue = parseToDouble(value, nan);
return isfinite(doubleValue) && doubleValue > maximum();
}
case RANGE: // Guaranteed by sanitization.
ASSERT(parseToDouble(value(), nan) <= maximum());
ASSERT(parseToDouble(value, nan) <= maximum());
case BUTTON:
case CHECKBOX:
case COLOR:
......@@ -475,7 +572,7 @@ double HTMLInputElement::stepBase() const
return 0.0;
}
bool HTMLInputElement::stepMismatch() const
bool HTMLInputElement::stepMismatch(const String& value) const
{
double step;
if (!getAllowedValueStep(&step))
......@@ -488,7 +585,7 @@ bool HTMLInputElement::stepMismatch() const
return false;
case NUMBER: {
double doubleValue;
if (!parseToDoubleForNumberType(value(), &doubleValue))
if (!parseToDoubleForNumberType(value, &doubleValue))
return false;
doubleValue = fabs(doubleValue - stepBase());
if (isinf(doubleValue))
......@@ -510,7 +607,7 @@ bool HTMLInputElement::stepMismatch() const
case TIME:
case WEEK: {
const double nan = numeric_limits<double>::quiet_NaN();
double doubleValue = parseToDouble(value(), nan);
double doubleValue = parseToDouble(value, nan);
doubleValue = fabs(doubleValue - stepBase());
if (!isfinite(doubleValue))
return false;
......
......@@ -75,8 +75,13 @@ public:
bool autoComplete() const;
// For ValidityState
bool rangeUnderflow() const;
bool rangeOverflow() const;
bool typeMismatch(const String&) const;
// valueMissing() ignores the specified string value for CHECKBOX and RADIO.
bool valueMissing(const String&) const;
bool patternMismatch(const String&) const;
bool tooLong(const String&, NeedsToCheckDirtyFlag) const;
bool rangeUnderflow(const String&) const;
bool rangeOverflow(const String&) const;
// Returns the minimum value for type=date, number, or range. Don't call this for other types.
double minimum() const;
// Returns the maximum value for type=date, number, or range. Don't call this for other types.
......@@ -86,7 +91,8 @@ public:
// Returns false if there is no "allowed value step."
bool getAllowedValueStep(double*) const;
// For ValidityState.
bool stepMismatch() const;
bool stepMismatch(const String&) const;
// Implementations of HTMLInputElement::stepUp() and stepDown().
void stepUp(int, ExceptionCode&);
void stepDown(int, ExceptionCode&);
......@@ -124,6 +130,9 @@ public:
virtual String value() const;
virtual void setValue(const String&, bool sendChangeEvent = false);
virtual void setValueForUser(const String&);
// Checks if the specified string would be a valid value.
// We should not call this for types with no string value such as CHECKBOX and RADIO.
bool isValidValue(const String&) const;
virtual const String& suggestedValue() const;
void setSuggestedValue(const String&);
......@@ -233,10 +242,6 @@ private:
virtual bool isTextFormControl() const { return isTextField(); }
virtual bool valueMissing() const;
virtual bool patternMismatch() const;
virtual bool tooLong() const;
virtual bool hasSpinButton() const { return m_type == NUMBER || m_type == DATE || m_type == DATETIME || m_type == DATETIMELOCAL || m_type == MONTH || m_type == TIME || m_type == WEEK; }
virtual bool canTriggerImplicitSubmission() const { return isTextField(); }
......
......@@ -382,16 +382,21 @@ void HTMLTextAreaElement::setMaxLength(int newValue, ExceptionCode& ec)
setAttribute(maxlengthAttr, String::number(newValue));
}
bool HTMLTextAreaElement::tooLong() const
bool HTMLTextAreaElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
{
// Return false for the default value even if it is longer than maxLength.
if (!m_isDirty)
if (check == CheckDirtyFlag && !m_isDirty)
return false;
int max = maxLength();
if (max < 0)
return false;
return numGraphemeClusters(value()) > static_cast<unsigned>(max);
return numGraphemeClusters(value) > static_cast<unsigned>(max);
}
bool HTMLTextAreaElement::isValidValue(const String& candidate) const
{
return !valueMissing(candidate) && !tooLong(candidate, IgnoreDirtyFlag);
}
void HTMLTextAreaElement::accessKeyAction(bool)
......
......@@ -47,7 +47,9 @@ public:
int textLength() const { return value().length(); }
int maxLength() const;
void setMaxLength(int, ExceptionCode&);
virtual bool tooLong() const;
bool valueMissing(const String& value) const { return isRequiredFormControl() && !disabled() && !readOnly() && value.isEmpty(); }
bool tooLong(const String&, NeedsToCheckDirtyFlag) const;
bool isValidValue(const String&) const;
void rendererWillBeDestroyed();
......@@ -85,8 +87,6 @@ private:
virtual bool isTextFormControl() const { return true; }
virtual bool valueMissing() const { return isRequiredFormControl() && !disabled() && !readOnly() && value().isEmpty(); }
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual void parseMappedAttribute(Attribute*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
......
......@@ -26,21 +26,15 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "HTMLTextAreaElement.h"
#include "HTMLTreeBuilder.h"
#include "KURL.h"
#include "LocalizedStrings.h"
#include "RegularExpression.h"
#include <wtf/StdLibExtras.h>
namespace WebCore {
using namespace HTMLNames;
static const char emailPattern[] =
"[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part
"@"
"[a-z0-9-]+(\\.[a-z0-9-]+)+"; // domain part
String ValidityState::validationMessage() const
{
if (!m_control->willValidate())
......@@ -72,6 +66,19 @@ void ValidityState::setCustomErrorMessage(const String& message)
m_control->setNeedsValidityCheck();
}
bool ValidityState::valueMissing() const
{
if (m_control->hasTagName(inputTag)) {
HTMLInputElement* input = static_cast<HTMLInputElement*>(m_control);
return input->valueMissing(input->value());
}
if (m_control->hasTagName(textareaTag)) {
HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(m_control);
return textArea->valueMissing(textArea->value());
}
return false;
}
bool ValidityState::typeMismatch() const
{
if (!m_control->hasTagName(inputTag))
......@@ -79,53 +86,29 @@ bool ValidityState::typeMismatch() const
HTMLInputElement* input = static_cast<HTMLInputElement*>(m_control);
String value = input->value();
if (value.isEmpty())
return false;
return input->typeMismatch(value);
}
switch (input->inputType()) {
case HTMLInputElement::COLOR:
return !isValidColorString(value);
case HTMLInputElement::NUMBER:
return !parseToDoubleForNumberType(value, 0);
case HTMLInputElement::URL:
return !KURL(KURL(), value).isValid();
case HTMLInputElement::EMAIL: {
if (!input->multiple())
return !isValidEmailAddress(value);
Vector<String> addresses;
value.split(',', addresses);
for (unsigned i = 0; i < addresses.size(); ++i) {
if (!isValidEmailAddress(addresses[i]))
return true;
}
bool ValidityState::patternMismatch() const
{
if (!m_control->hasTagName(inputTag))
return false;
HTMLInputElement* input = static_cast<HTMLInputElement*>(m_control);
return input->patternMismatch(input->value());
}
bool ValidityState::tooLong() const
{
if (m_control->hasTagName(inputTag)) {
HTMLInputElement* input = static_cast<HTMLInputElement*>(m_control);
return input->tooLong(input->value(), HTMLTextFormControlElement::CheckDirtyFlag);
}
case HTMLInputElement::DATE:
case HTMLInputElement::DATETIME:
case HTMLInputElement::DATETIMELOCAL:
case HTMLInputElement::MONTH:
case HTMLInputElement::TIME:
case HTMLInputElement::WEEK:
return !HTMLInputElement::parseToDateComponents(input->inputType(), value, 0);
case HTMLInputElement::BUTTON:
case HTMLInputElement::CHECKBOX:
case HTMLInputElement::FILE:
case HTMLInputElement::HIDDEN:
case HTMLInputElement::IMAGE:
case HTMLInputElement::ISINDEX:
case HTMLInputElement::PASSWORD:
case HTMLInputElement::RADIO:
case HTMLInputElement::RANGE:
case HTMLInputElement::RESET:
case HTMLInputElement::SEARCH:
case HTMLInputElement::SUBMIT:
case HTMLInputElement::TELEPHONE: // FIXME: Is there validation for <input type=telephone>?
case HTMLInputElement::TEXT:
return false;
if (m_control->hasTagName(textareaTag)) {
HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(m_control);
return textArea->tooLong(textArea->value(), HTMLTextFormControlElement::CheckDirtyFlag);
}
ASSERT_NOT_REACHED();
return false;
}
......@@ -133,21 +116,24 @@ bool ValidityState::rangeUnderflow() const
{
if (!m_control->hasTagName(inputTag))
return false;
return static_cast<HTMLInputElement*>(m_control)->rangeUnderflow();
HTMLInputElement* input = static_cast<HTMLInputElement*>(m_control);
return input->rangeUnderflow(input->value());
}
bool ValidityState::rangeOverflow() const
{
if (!m_control->hasTagName(inputTag))
return false;
return static_cast<HTMLInputElement*>(m_control)->rangeOverflow();
HTMLInputElement* input = static_cast<HTMLInputElement*>(m_control);
return input->rangeOverflow(input->value());
}
bool ValidityState::stepMismatch() const
{
if (!m_control->hasTagName(inputTag))
return false;
return static_cast<HTMLInputElement*>(m_control)->stepMismatch();
HTMLInputElement* input = static_cast<HTMLInputElement*>(m_control);
return input->stepMismatch(input->value());
}
bool ValidityState::valid() const
......@@ -157,31 +143,4 @@ bool ValidityState::valid() const
return !someError;
}
bool ValidityState::isValidColorString(const String& value)
{
if (value.isEmpty())
return false;
if (value[0] == '#') {
// We don't accept #rgb and #aarrggbb formats.
if (value.length() != 7)
return false;
}
Color color(value); // This accepts named colors such as "white".
return color.isValid() && !color.hasAlpha();
}
bool ValidityState::isValidEmailAddress(const String& address)
{
int addressLength = address.length();
if (!addressLength)
return false;
DEFINE_STATIC_LOCAL(const RegularExpression, regExp, (emailPattern, TextCaseInsensitive));
int matchLength;
int matchOffset = regExp.match(address, 0, &matchLength);
return matchOffset == 0 && matchLength == addressLength;
}
} // namespace
......@@ -43,10 +43,10 @@ public:
void setCustomErrorMessage(const String&);
bool valueMissing() const { return m_control->valueMissing(); }
bool valueMissing() const;
bool typeMismatch() const;
bool patternMismatch() const { return m_control->patternMismatch(); }
bool tooLong() const { return m_control->tooLong(); }
bool patternMismatch() const;
bool tooLong() const;
bool rangeUnderflow() const;
bool rangeOverflow() const;
bool stepMismatch() const;
......
2010-08-29 Kent Tamura <tkent@chromium.org>
Reviewed by Darin Adler.
Introduce isValidValue(const String&) of HTMLInputElement and HTMLTextAreaElement
https://bugs.webkit.org/show_bug.cgi?id=43537
* public/WebInputElement.h:
* src/WebInputElement.cpp:
(WebKit::WebInputElement::isValidValue):
2010-08-29 Kent Tamura <tkent@chromium.org>
Reviewed by Dimitri Glazkov.
......
......@@ -99,6 +99,7 @@ namespace WebKit {
WEBKIT_API void setSelectionRange(int, int);
WEBKIT_API int selectionStart();
WEBKIT_API int selectionEnd();
WEBKIT_API bool isValidValue(const WebString&) const;
#if WEBKIT_IMPLEMENTATION
WebInputElement(const WTF::PassRefPtr<WebCore::HTMLInputElement>&);
......
......@@ -140,6 +140,11 @@ int WebInputElement::selectionEnd()
return unwrap<HTMLInputElement>()->selectionEnd();
}
bool WebInputElement::isValidValue(const WebString& value) const
{
return constUnwrap<HTMLInputElement>()->isValidValue(value);
}
WebInputElement::WebInputElement(const PassRefPtr<HTMLInputElement>& elem)
: WebFormControlElement(elem)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment