Title: [293546] trunk/Source/WebCore/html
Revision
293546
Author
cdu...@apple.com
Date
2022-04-27 16:42:59 -0700 (Wed, 27 Apr 2022)

Log Message

Devirtualize InputType validation
https://bugs.webkit.org/show_bug.cgi?id=239809

Reviewed by Geoff Garen and Cameron McCormack.

HTMLInputElement::isValidValue() used to call 4 virtual functions on InputType
and is hot code on Speedometer. To optimize this, HTMLInputElement::isValidValue()
now calls a non-virtual HTMLInputElement::isValidValue() which switches on the
input type and then calls the 4 functions on the actual InputType subclass, so
that the compiler can optimize out the virtual calls out thanks to final
optimization.

This is a 0.5-0.75% progression on Speedometer on Intel. This might be a very
small (~0.2%) progression on Apple Silicon.

* Source/WebCore/html/BaseButtonInputType.h:
(WebCore::BaseButtonInputType::BaseButtonInputType):
* Source/WebCore/html/BaseCheckableInputType.h:
(WebCore::BaseCheckableInputType::BaseCheckableInputType):
* Source/WebCore/html/BaseClickableWithKeyInputType.h:
(WebCore::BaseClickableWithKeyInputType::BaseClickableWithKeyInputType):
* Source/WebCore/html/BaseDateAndTimeInputType.h:
* Source/WebCore/html/BaseTextInputType.h:
(WebCore::BaseTextInputType::BaseTextInputType):
* Source/WebCore/html/ButtonInputType.h:
* Source/WebCore/html/CheckboxInputType.h:
* Source/WebCore/html/ColorInputType.h:
* Source/WebCore/html/DateInputType.h:
* Source/WebCore/html/DateTimeLocalInputType.h:
* Source/WebCore/html/EmailInputType.h:
* Source/WebCore/html/FileInputType.h:
* Source/WebCore/html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::isValidValue const):
* Source/WebCore/html/HiddenInputType.h:
* Source/WebCore/html/ImageInputType.h:
* Source/WebCore/html/InputType.cpp:
(WebCore::validateInputType):
(WebCore::InputType::isValidValue const):
* Source/WebCore/html/InputType.h:
(WebCore::InputType::type const):
* Source/WebCore/html/MonthInputType.h:
* Source/WebCore/html/NumberInputType.h:
* Source/WebCore/html/PasswordInputType.h:
* Source/WebCore/html/RadioInputType.h:
* Source/WebCore/html/RangeInputType.h:
* Source/WebCore/html/ResetInputType.h:
* Source/WebCore/html/SearchInputType.h:
* Source/WebCore/html/SubmitInputType.h:
* Source/WebCore/html/TelephoneInputType.h:
* Source/WebCore/html/TextFieldInputType.h:
* Source/WebCore/html/TextInputType.h:
* Source/WebCore/html/TimeInputType.h:
* Source/WebCore/html/URLInputType.h:
* Source/WebCore/html/WeekInputType.h:

Canonical link: https://commits.webkit.org/250065@main

Modified Paths

Diff

Modified: trunk/Source/WebCore/html/BaseButtonInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/BaseButtonInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/BaseButtonInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,14 +37,17 @@
 // Base of button, file, image, reset, and submit types.
 class BaseButtonInputType : public BaseClickableWithKeyInputType {
 protected:
-    explicit BaseButtonInputType(Type type, HTMLInputElement& element) : BaseClickableWithKeyInputType(type, element) { }
+    explicit BaseButtonInputType(Type type, HTMLInputElement& element)
+        : BaseClickableWithKeyInputType(type, element)
+    {
+    }
 
 private:
-    bool shouldSaveAndRestoreFormControlState() const override;
+    bool shouldSaveAndRestoreFormControlState() const final;
     bool appendFormData(DOMFormData&) const override;
     RenderPtr<RenderElement> createInputRenderer(RenderStyle&&) override;
-    bool storesValueSeparateFromAttribute() override;
-    void setValue(const String&, bool, TextFieldEventBehavior, TextControlSetValueSelection) override;
+    bool storesValueSeparateFromAttribute() final;
+    void setValue(const String&, bool, TextFieldEventBehavior, TextControlSetValueSelection) final;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/BaseCheckableInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/BaseCheckableInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/BaseCheckableInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -36,21 +36,27 @@
 
 // Base of checkbox and radio types.
 class BaseCheckableInputType : public InputType {
+public:
+    bool canSetStringValue() const final;
+
 protected:
-    explicit BaseCheckableInputType(Type type, HTMLInputElement& element) : InputType(type, element) { }
+    explicit BaseCheckableInputType(Type type, HTMLInputElement& element)
+        : InputType(type, element)
+    {
+    }
+
     ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) override;
     void fireInputAndChangeEvents();
 
 private:
-    FormControlState saveFormControlState() const override;
-    void restoreFormControlState(const FormControlState&) override;
-    bool appendFormData(DOMFormData&) const override;
-    void handleKeypressEvent(KeyboardEvent&) override;
-    bool canSetStringValue() const override;
-    bool accessKeyAction(bool sendMouseEvents) override;
-    String fallbackValue() const override;
-    bool storesValueSeparateFromAttribute() override;
-    void setValue(const String&, bool, TextFieldEventBehavior, TextControlSetValueSelection) override;
+    FormControlState saveFormControlState() const final;
+    void restoreFormControlState(const FormControlState&) final;
+    bool appendFormData(DOMFormData&) const final;
+    void handleKeypressEvent(KeyboardEvent&) final;
+    bool accessKeyAction(bool sendMouseEvents) final;
+    String fallbackValue() const final;
+    bool storesValueSeparateFromAttribute() final;
+    void setValue(const String&, bool, TextFieldEventBehavior, TextControlSetValueSelection) final;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/BaseClickableWithKeyInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/BaseClickableWithKeyInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/BaseClickableWithKeyInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -43,13 +43,16 @@
     static bool accessKeyAction(HTMLInputElement&, bool sendMouseEvents);
     
 protected:
-    explicit BaseClickableWithKeyInputType(Type type, HTMLInputElement& element) : InputType(type, element) { }
+    explicit BaseClickableWithKeyInputType(Type type, HTMLInputElement& element)
+        : InputType(type, element)
+    {
+    }
 
 private:
-    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) override;
-    void handleKeypressEvent(KeyboardEvent&) override;
-    void handleKeyupEvent(KeyboardEvent&) override;
-    bool accessKeyAction(bool sendMouseEvents) override;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) final;
+    void handleKeypressEvent(KeyboardEvent&) final;
+    void handleKeyupEvent(KeyboardEvent&) final;
+    bool accessKeyAction(bool sendMouseEvents) final;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/BaseDateAndTimeInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/BaseDateAndTimeInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/BaseDateAndTimeInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -48,6 +48,10 @@
 
 // A super class of date, datetime, datetime-local, month, time, and week types.
 class BaseDateAndTimeInputType : public InputType, private DateTimeChooserClient, private DateTimeEditElement::EditControlOwner {
+public:
+    bool typeMismatchFor(const String&) const final;
+    bool valueMissing(const String&) const final;
+
 protected:
     enum class DateTimeFormatValidationResults : uint8_t {
         HasYear = 1 << 0,
@@ -69,14 +73,13 @@
     ~BaseDateAndTimeInputType();
 
     Decimal parseToNumber(const String&, const Decimal&) const override;
-    String serialize(const Decimal&) const override;
+    String serialize(const Decimal&) const final;
     String serializeWithComponents(const DateComponents&) const;
 
     bool shouldHaveSecondField(const DateComponents&) const;
     bool shouldHaveMillisecondField(const DateComponents&) const;
-    bool typeMismatchFor(const String&) const final;
+
     bool typeMismatch() const final;
-    bool valueMissing(const String&) const final;
 
 private:
     class DateTimeFormatValidator final : public DateTimeFormat::TokenHandler {
@@ -123,11 +126,11 @@
     void elementDidBlur() final;
     void detach() final;
 
-    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) override;
-    void handleKeypressEvent(KeyboardEvent&) override;
-    void handleKeyupEvent(KeyboardEvent&) override;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) final;
+    void handleKeypressEvent(KeyboardEvent&) final;
+    void handleKeyupEvent(KeyboardEvent&) final;
     void handleFocusEvent(Node* oldFocusedNode, FocusDirection) final;
-    bool accessKeyAction(bool sendMouseEvents) override;
+    bool accessKeyAction(bool sendMouseEvents) final;
 
     // DateTimeEditElement::EditControlOwner functions:
     void didBlurFromControl() final;

Modified: trunk/Source/WebCore/html/BaseTextInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/BaseTextInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/BaseTextInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,11 +37,16 @@
 // Base of email, password, search, tel, text, and URL types.
 // They support maxlength, selection functions, and so on.
 class BaseTextInputType : public TextFieldInputType {
+public:
+    bool patternMismatch(const String&) const final;
+
 protected:
-    explicit BaseTextInputType(Type type, HTMLInputElement& element) : TextFieldInputType(type, element) { }
+    explicit BaseTextInputType(Type type, HTMLInputElement& element)
+        : TextFieldInputType(type, element)
+    {
+    }
 
-    bool patternMismatch(const String&) const override;
-    bool supportsPlaceholder() const override;
+    bool supportsPlaceholder() const final;
     bool supportsSelectionAPI() const override;
 };
 

Modified: trunk/Source/WebCore/html/ButtonInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/ButtonInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/ButtonInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,10 +37,15 @@
 class ButtonInputType final : public BaseButtonInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit ButtonInputType(HTMLInputElement& element) : BaseButtonInputType(Type::Button, element) { }
+    explicit ButtonInputType(HTMLInputElement& element)
+        : BaseButtonInputType(Type::Button, element)
+    {
+    }
 
 private:
-    const AtomString& formControlType() const override;
+    const AtomString& formControlType() const final;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(ButtonInputType, Type::Button)

Modified: trunk/Source/WebCore/html/CheckboxInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/CheckboxInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/CheckboxInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,11 +37,15 @@
 class CheckboxInputType final : public BaseCheckableInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit CheckboxInputType(HTMLInputElement& element) : BaseCheckableInputType(Type::Checkbox, element) { }
+    explicit CheckboxInputType(HTMLInputElement& element)
+        : BaseCheckableInputType(Type::Checkbox, element)
+    {
+    }
 
+    bool valueMissing(const String&) const final;
+
 private:
     const AtomString& formControlType() const final;
-    bool valueMissing(const String&) const final;
     String valueMissingText() const final;
     void handleKeyupEvent(KeyboardEvent&) final;
     void willDispatchClick(InputElementClickState&) final;
@@ -51,3 +55,5 @@
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(CheckboxInputType, Type::Checkbox)

Modified: trunk/Source/WebCore/html/ColorInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/ColorInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/ColorInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -49,6 +49,7 @@
     }
 
     virtual ~ColorInputType();
+    bool typeMismatchFor(const String&) const final;
 
 private:
     void didChooseColor(const Color&) final;
@@ -71,7 +72,6 @@
     void detach() final;
     void elementDidBlur() final;
     bool shouldRespectListAttribute() final;
-    bool typeMismatchFor(const String&) const final;
     bool shouldResetOnDocumentActivation() final;
     Color valueAsColor() const final;
     void selectColor(StringView) final;
@@ -85,4 +85,6 @@
 
 } // namespace WebCore
 
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(ColorInputType, Type::Color)
+
 #endif // ENABLE(INPUT_TYPE_COLOR)

Modified: trunk/Source/WebCore/html/DateInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/DateInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/DateInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -42,11 +42,11 @@
     explicit DateInputType(HTMLInputElement&);
 
 private:
-    const AtomString& formControlType() const override;
-    DateComponentsType dateType() const override;
-    StepRange createStepRange(AnyStepHandling) const override;
-    std::optional<DateComponents> parseToDateComponents(StringView) const override;
-    std::optional<DateComponents> setMillisecondToDateComponents(double) const override;
+    const AtomString& formControlType() const final;
+    DateComponentsType dateType() const final;
+    StepRange createStepRange(AnyStepHandling) const final;
+    std::optional<DateComponents> parseToDateComponents(StringView) const final;
+    std::optional<DateComponents> setMillisecondToDateComponents(double) const final;
 
     bool isValidFormat(OptionSet<DateTimeFormatValidationResults>) const final;
     String formatDateTimeFieldsState(const DateTimeFieldsState&) const final;
@@ -55,4 +55,6 @@
 
 } // namespace WebCore
 
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(DateInputType, Type::Date)
+
 #endif

Modified: trunk/Source/WebCore/html/DateTimeLocalInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/DateTimeLocalInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/DateTimeLocalInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -61,4 +61,6 @@
 
 } // namespace WebCore
 
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(DateTimeLocalInputType, Type::DateTimeLocal)
+
 #endif

Modified: trunk/Source/WebCore/html/EmailInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/EmailInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/EmailInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,15 +37,21 @@
 class EmailInputType final : public BaseTextInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit EmailInputType(HTMLInputElement& element) : BaseTextInputType(Type::Email, element) { }
+    explicit EmailInputType(HTMLInputElement& element)
+        : BaseTextInputType(Type::Email, element)
+    {
+    }
 
+    bool typeMismatchFor(const String&) const final;
+
 private:
-    const AtomString& formControlType() const override;
-    bool typeMismatchFor(const String&) const override;
-    bool typeMismatch() const override;
-    String typeMismatchText() const override;
-    bool supportsSelectionAPI() const override;
-    String sanitizeValue(const String&) const override;
+    const AtomString& formControlType() const final;
+    bool typeMismatch() const final;
+    String typeMismatchText() const final;
+    bool supportsSelectionAPI() const final;
+    String sanitizeValue(const String&) const final;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(EmailInputType, Type::Email)

Modified: trunk/Source/WebCore/html/FileInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/FileInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/FileInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -51,6 +51,8 @@
     virtual ~FileInputType();
 
     static Vector<FileChooserFileInfo> filesFromFormControlState(const FormControlState&);
+    bool canSetStringValue() const final;
+    bool valueMissing(const String&) const final;
 
 private:
     const AtomString& formControlType() const final;
@@ -57,11 +59,9 @@
     FormControlState saveFormControlState() const final;
     void restoreFormControlState(const FormControlState&) final;
     bool appendFormData(DOMFormData&) const final;
-    bool valueMissing(const String&) const final;
     String valueMissingText() const final;
     void handleDOMActivateEvent(Event&) final;
     RenderPtr<RenderElement> createInputRenderer(RenderStyle&&) final;
-    bool canSetStringValue() const final;
     FileList* files() final;
     void setFiles(RefPtr<FileList>&&, WasSetByJavaScript) final;
     enum class RequestIcon { Yes, No };
@@ -107,3 +107,5 @@
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(FileInputType, Type::File)

Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (293545 => 293546)


--- trunk/Source/WebCore/html/HTMLInputElement.cpp	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp	2022-04-27 23:42:59 UTC (rev 293546)
@@ -267,18 +267,10 @@
 
 bool HTMLInputElement::isValidValue(const String& value) const
 {
-    if (!m_inputType->canSetStringValue()) {
-        ASSERT_NOT_REACHED();
+    if (!m_inputType->isValidValue(value))
         return false;
-    }
-    return !m_inputType->typeMismatchFor(value)
-        && !m_inputType->stepMismatch(value)
-        && !m_inputType->rangeUnderflow(value)
-        && !m_inputType->rangeOverflow(value)
-        && !tooShort(value, IgnoreDirtyFlag)
-        && !tooLong(value, IgnoreDirtyFlag)
-        && !m_inputType->patternMismatch(value)
-        && !m_inputType->valueMissing(value);
+
+    return !tooShort(value, IgnoreDirtyFlag) && !tooLong(value, IgnoreDirtyFlag);
 }
 
 bool HTMLInputElement::tooShort() const

Modified: trunk/Source/WebCore/html/HiddenInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/HiddenInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/HiddenInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,19 +37,24 @@
 class HiddenInputType final : public InputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit HiddenInputType(HTMLInputElement& element) : InputType(Type::Hidden, element) { }
+    explicit HiddenInputType(HTMLInputElement& element)
+        : InputType(Type::Hidden, element)
+    {
+    }
 
 private:
-    const AtomString& formControlType() const override;
-    FormControlState saveFormControlState() const override;
-    void restoreFormControlState(const FormControlState&) override;
-    RenderPtr<RenderElement> createInputRenderer(RenderStyle&&) override;
-    bool accessKeyAction(bool sendMouseEvents) override;
-    bool rendererIsNeeded() override;
-    bool storesValueSeparateFromAttribute() override;
-    bool shouldRespectHeightAndWidthAttributes() override;
-    void setValue(const String&, bool, TextFieldEventBehavior, TextControlSetValueSelection) override;
-    bool appendFormData(DOMFormData&) const override;
+    const AtomString& formControlType() const final;
+    FormControlState saveFormControlState() const final;
+    void restoreFormControlState(const FormControlState&) final;
+    RenderPtr<RenderElement> createInputRenderer(RenderStyle&&) final;
+    bool accessKeyAction(bool sendMouseEvents) final;
+    bool rendererIsNeeded() final;
+    bool storesValueSeparateFromAttribute() final;
+    bool shouldRespectHeightAndWidthAttributes() final;
+    void setValue(const String&, bool, TextFieldEventBehavior, TextControlSetValueSelection) final;
+    bool appendFormData(DOMFormData&) const final;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(HiddenInputType, Type::Hidden)

Modified: trunk/Source/WebCore/html/ImageInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/ImageInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/ImageInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -61,3 +61,5 @@
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(ImageInputType, Type::Image)

Modified: trunk/Source/WebCore/html/InputType.cpp (293545 => 293546)


--- trunk/Source/WebCore/html/InputType.cpp	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/InputType.cpp	2022-04-27 23:42:59 UTC (rev 293546)
@@ -169,6 +169,81 @@
     return RenderTheme::singleton().supportsDataListUI(type->formControlType());
 }
 
+template<typename T> static bool validateInputType(const T& inputType, const String& value)
+{
+    ASSERT(inputType.canSetStringValue());
+    return !inputType.typeMismatchFor(value)
+        && !inputType.stepMismatch(value)
+        && !inputType.rangeUnderflow(value)
+        && !inputType.rangeOverflow(value)
+        && !inputType.patternMismatch(value)
+        && !inputType.valueMissing(value);
+}
+
+bool InputType::isValidValue(const String& value) const
+{
+    switch (m_type) {
+    case Type::Button:
+        return validateInputType(downcast<ButtonInputType>(*this), value);
+    case Type::Checkbox:
+        return validateInputType(downcast<CheckboxInputType>(*this), value);
+#if ENABLE(INPUT_TYPE_COLOR)
+    case Type::Color:
+        return validateInputType(downcast<ColorInputType>(*this), value);
+#endif
+#if ENABLE(INPUT_TYPE_DATE)
+    case Type::Date:
+        return validateInputType(downcast<DateInputType>(*this), value);
+#endif
+#if ENABLE(INPUT_TYPE_DATETIMELOCAL)
+    case Type::DateTimeLocal:
+        return validateInputType(downcast<DateTimeLocalInputType>(*this), value);
+#endif
+    case Type::Email:
+        return validateInputType(downcast<EmailInputType>(*this), value);
+    case Type::File:
+        return validateInputType(downcast<FileInputType>(*this), value);
+    case Type::Hidden:
+        return validateInputType(downcast<HiddenInputType>(*this), value);
+    case Type::Image:
+        return validateInputType(downcast<ImageInputType>(*this), value);
+#if ENABLE(INPUT_TYPE_MONTH)
+    case Type::Month:
+        return validateInputType(downcast<MonthInputType>(*this), value);
+#endif
+    case Type::Number:
+        return validateInputType(downcast<NumberInputType>(*this), value);
+    case Type::Password:
+        return validateInputType(downcast<PasswordInputType>(*this), value);
+    case Type::Radio:
+        return validateInputType(downcast<RadioInputType>(*this), value);
+    case Type::Range:
+        return validateInputType(downcast<RangeInputType>(*this), value);
+    case Type::Reset:
+        return validateInputType(downcast<ResetInputType>(*this), value);
+    case Type::Search:
+        return validateInputType(downcast<SearchInputType>(*this), value);
+    case Type::Submit:
+        return validateInputType(downcast<SubmitInputType>(*this), value);
+    case Type::Telephone:
+        return validateInputType(downcast<TelephoneInputType>(*this), value);
+#if ENABLE(INPUT_TYPE_TIME)
+    case Type::Time:
+        return validateInputType(downcast<TimeInputType>(*this), value);
+#endif
+    case Type::URL:
+        return validateInputType(downcast<URLInputType>(*this), value);
+#if ENABLE(INPUT_TYPE_WEEK)
+    case Type::Week:
+        return validateInputType(downcast<WeekInputType>(*this), value);
+#endif
+    case Type::Text:
+        return validateInputType(downcast<TextInputType>(*this), value);
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
 bool InputType::shouldSaveAndRestoreFormControlState() const
 {
     return true;

Modified: trunk/Source/WebCore/html/InputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/InputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/InputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -164,6 +164,8 @@
 
     virtual const AtomString& formControlType() const = 0;
 
+    bool isValidValue(const String&) const;
+
     // Type query functions.
 
     // Any time we are using one of these functions it's best to refactor
@@ -202,6 +204,8 @@
     bool supportsValidation() const { return !nonValidatingTypes.contains(m_type); }
     bool canHaveTypeSpecificValue() const { return isFileUpload(); }
 
+    Type type() const { return m_type; }
+
     bool isInteractiveContent() const;
     bool supportLabels() const;
     bool isEnumeratable() const;
@@ -433,7 +437,7 @@
 
 } // namespace WebCore
 
-#define SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(ToValueTypeName, predicate) \
+#define SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(ToValueTypeName, TypeEnumValue) \
 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
-static bool isType(const WebCore::InputType& input) { return input.predicate; } \
+static bool isType(const WebCore::InputType& input) { return input.type() == WebCore::InputType::TypeEnumValue; } \
 SPECIALIZE_TYPE_TRAITS_END()

Modified: trunk/Source/WebCore/html/MonthInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/MonthInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/MonthInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -45,16 +45,16 @@
     }
 
 private:
-    const AtomString& formControlType() const override;
-    DateComponentsType dateType() const override;
-    WallTime valueAsDate() const override;
-    String serializeWithMilliseconds(double) const override;
-    Decimal parseToNumber(const String&, const Decimal&) const override;
-    Decimal defaultValueForStepUp() const override;
-    StepRange createStepRange(AnyStepHandling) const override;
-    std::optional<DateComponents> parseToDateComponents(StringView) const override;
-    std::optional<DateComponents> setMillisecondToDateComponents(double) const override;
-    void handleDOMActivateEvent(Event&) override;
+    const AtomString& formControlType() const final;
+    DateComponentsType dateType() const final;
+    WallTime valueAsDate() const final;
+    String serializeWithMilliseconds(double) const final;
+    Decimal parseToNumber(const String&, const Decimal&) const final;
+    Decimal defaultValueForStepUp() const final;
+    StepRange createStepRange(AnyStepHandling) const final;
+    std::optional<DateComponents> parseToDateComponents(StringView) const final;
+    std::optional<DateComponents> setMillisecondToDateComponents(double) const final;
+    void handleDOMActivateEvent(Event&) final;
 
     bool isValidFormat(OptionSet<DateTimeFormatValidationResults>) const final;
     String formatDateTimeFieldsState(const DateTimeFieldsState&) const final;
@@ -63,4 +63,6 @@
 
 } // namespace WebCore
 
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(MonthInputType, Type::Month)
+
 #endif // ENABLE(INPUT_TYPE_MONTH)

Modified: trunk/Source/WebCore/html/NumberInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/NumberInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/NumberInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -38,7 +38,11 @@
 class NumberInputType final : public TextFieldInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit NumberInputType(HTMLInputElement& element) : TextFieldInputType(Type::Number, element) { }
+    explicit NumberInputType(HTMLInputElement& element)
+        : TextFieldInputType(Type::Number, element)
+    {
+    }
+    bool typeMismatchFor(const String&) const final;
 
 private:
     const AtomString& formControlType() const final;
@@ -46,7 +50,6 @@
     double valueAsDouble() const final;
     ExceptionOr<void> setValueAsDouble(double, TextFieldEventBehavior) const final;
     ExceptionOr<void> setValueAsDecimal(const Decimal&, TextFieldEventBehavior) const final;
-    bool typeMismatchFor(const String&) const final;
     bool typeMismatch() const final;
     bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const final;
     float decorationWidth() const final;
@@ -65,3 +68,5 @@
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(NumberInputType, Type::Number)

Modified: trunk/Source/WebCore/html/PasswordInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/PasswordInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/PasswordInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,16 +37,21 @@
 class PasswordInputType final : public BaseTextInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit PasswordInputType(HTMLInputElement& element) : BaseTextInputType(Type::Password, element) { }
+    explicit PasswordInputType(HTMLInputElement& element)
+        : BaseTextInputType(Type::Password, element)
+    {
+    }
 
 private:
-    const AtomString& formControlType() const override;
-    bool shouldSaveAndRestoreFormControlState() const override;
-    FormControlState saveFormControlState() const override;
-    void restoreFormControlState(const FormControlState&) override;
-    bool shouldUseInputMethod() const override;
-    bool shouldResetOnDocumentActivation() override;
-    bool shouldRespectListAttribute() override;
+    const AtomString& formControlType() const final;
+    bool shouldSaveAndRestoreFormControlState() const final;
+    FormControlState saveFormControlState() const final;
+    void restoreFormControlState(const FormControlState&) final;
+    bool shouldUseInputMethod() const final;
+    bool shouldResetOnDocumentActivation() final;
+    bool shouldRespectListAttribute() final;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(PasswordInputType, Type::Password)

Modified: trunk/Source/WebCore/html/RadioInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/RadioInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/RadioInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -38,13 +38,17 @@
 class RadioInputType final : public BaseCheckableInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit RadioInputType(HTMLInputElement& element) : BaseCheckableInputType(Type::Radio, element) { }
+    explicit RadioInputType(HTMLInputElement& element)
+        : BaseCheckableInputType(Type::Radio, element)
+    {
+    }
 
     static void forEachButtonInDetachedGroup(ContainerNode& rootName, const String& groupName, const Function<bool(HTMLInputElement&)>&);
 
+    bool valueMissing(const String&) const final;
+
 private:
     const AtomString& formControlType() const final;
-    bool valueMissing(const String&) const final;
     String valueMissingText() const final;
     void handleClickEvent(MouseEvent&) final;
     ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) final;
@@ -58,3 +62,5 @@
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(RadioInputType, Type::Radio)

Modified: trunk/Source/WebCore/html/RangeInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/RangeInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/RangeInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -41,12 +41,12 @@
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
     explicit RangeInputType(HTMLInputElement&);
+    bool typeMismatchFor(const String&) const final;
 
 private:
     const AtomString& formControlType() const final;
     double valueAsDouble() const final;
     ExceptionOr<void> setValueAsDecimal(const Decimal&, TextFieldEventBehavior) const final;
-    bool typeMismatchFor(const String&) const final;
     bool supportsRequired() const final;
     StepRange createStepRange(AnyStepHandling) const final;
     void handleMouseDownEvent(MouseEvent&) final;
@@ -87,3 +87,5 @@
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(RangeInputType, Type::Range)

Modified: trunk/Source/WebCore/html/ResetInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/ResetInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/ResetInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,12 +37,17 @@
 class ResetInputType final : public BaseButtonInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit ResetInputType(HTMLInputElement& element) : BaseButtonInputType(Type::Reset, element) { }
+    explicit ResetInputType(HTMLInputElement& element)
+        : BaseButtonInputType(Type::Reset, element)
+    {
+    }
 
 private:
-    const AtomString& formControlType() const override;
-    void handleDOMActivateEvent(Event&) override;
-    String defaultValue() const override;
+    const AtomString& formControlType() const final;
+    void handleDOMActivateEvent(Event&) final;
+    String defaultValue() const final;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(ResetInputType, Type::Reset)

Modified: trunk/Source/WebCore/html/SearchInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/SearchInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/SearchInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -71,4 +71,4 @@
 
 } // namespace WebCore
 
-SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(SearchInputType, isSearchField())
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(SearchInputType, Type::Search)

Modified: trunk/Source/WebCore/html/SubmitInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/SubmitInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/SubmitInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,15 +37,20 @@
 class SubmitInputType final : public BaseButtonInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit SubmitInputType(HTMLInputElement& element) : BaseButtonInputType(Type::Submit, element) { }
+    explicit SubmitInputType(HTMLInputElement& element)
+        : BaseButtonInputType(Type::Submit, element)
+    {
+    }
 
 private:
-    const AtomString& formControlType() const override;
-    bool appendFormData(DOMFormData&) const override;
-    bool supportsRequired() const override;
-    void handleDOMActivateEvent(Event&) override;
-    bool canBeSuccessfulSubmitButton() override;
-    String defaultValue() const override;
+    const AtomString& formControlType() const final;
+    bool appendFormData(DOMFormData&) const final;
+    bool supportsRequired() const final;
+    void handleDOMActivateEvent(Event&) final;
+    bool canBeSuccessfulSubmitButton() final;
+    String defaultValue() const final;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(SubmitInputType, Type::Submit)

Modified: trunk/Source/WebCore/html/TelephoneInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/TelephoneInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/TelephoneInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,10 +37,15 @@
 class TelephoneInputType final : public BaseTextInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit TelephoneInputType(HTMLInputElement& element) : BaseTextInputType(Type::Telephone, element) { }
+    explicit TelephoneInputType(HTMLInputElement& element)
+        : BaseTextInputType(Type::Telephone, element)
+    {
+    }
 
 private:
-    const AtomString& formControlType() const override;
+    const AtomString& formControlType() const final;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(TelephoneInputType, Type::Telephone)

Modified: trunk/Source/WebCore/html/TextFieldInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/TextFieldInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/TextFieldInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -50,6 +50,9 @@
     , private DataListSuggestionsClient, protected DataListButtonElement::DataListButtonOwner
 #endif
 {
+public:
+    bool valueMissing(const String&) const final;
+
 protected:
     explicit TextFieldInputType(Type, HTMLInputElement&);
     virtual ~TextFieldInputType();
@@ -81,7 +84,6 @@
     void setValue(const String&, bool valueChanged, TextFieldEventBehavior, TextControlSetValueSelection) override;
     void updateInnerTextValue() final;
     String sanitizeValue(const String&) const override;
-    bool valueMissing(const String&) const final;
 
     virtual String convertFromVisibleValue(const String&) const;
     virtual void didSetValueByUserEdit();

Modified: trunk/Source/WebCore/html/TextInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/TextInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/TextInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,10 +37,15 @@
 class TextInputType final : public BaseTextInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit TextInputType(HTMLInputElement& element) : BaseTextInputType(Type::Text, element) { }
+    explicit TextInputType(HTMLInputElement& element)
+        : BaseTextInputType(Type::Text, element)
+    {
+    }
 
 private:
-    const AtomString& formControlType() const override;
+    const AtomString& formControlType() const final;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(TextInputType, Type::Text)

Modified: trunk/Source/WebCore/html/TimeInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/TimeInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/TimeInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -42,13 +42,13 @@
     explicit TimeInputType(HTMLInputElement&);
 
 private:
-    const AtomString& formControlType() const override;
-    DateComponentsType dateType() const override;
-    Decimal defaultValueForStepUp() const override;
-    StepRange createStepRange(AnyStepHandling) const override;
-    std::optional<DateComponents> parseToDateComponents(StringView) const override;
-    std::optional<DateComponents> setMillisecondToDateComponents(double) const override;
-    void handleDOMActivateEvent(Event&) override;
+    const AtomString& formControlType() const final;
+    DateComponentsType dateType() const final;
+    Decimal defaultValueForStepUp() const final;
+    StepRange createStepRange(AnyStepHandling) const final;
+    std::optional<DateComponents> parseToDateComponents(StringView) const final;
+    std::optional<DateComponents> setMillisecondToDateComponents(double) const final;
+    void handleDOMActivateEvent(Event&) final;
 
     bool isValidFormat(OptionSet<DateTimeFormatValidationResults>) const final;
     String formatDateTimeFieldsState(const DateTimeFieldsState&) const final;
@@ -57,4 +57,6 @@
 
 } // namespace WebCore
 
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(TimeInputType, Type::Time)
+
 #endif // ENABLE(INPUT_TYPE_TIME)

Modified: trunk/Source/WebCore/html/URLInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/URLInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/URLInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -37,14 +37,20 @@
 class URLInputType final : public BaseTextInputType {
     template<typename DowncastedType> friend bool isInvalidInputType(const InputType&, const String&);
 public:
-    explicit URLInputType(HTMLInputElement& element) : BaseTextInputType(Type::URL, element) { }
+    explicit URLInputType(HTMLInputElement& element)
+        : BaseTextInputType(Type::URL, element)
+    {
+    }
 
+    bool typeMismatchFor(const String&) const final;
+
 private:
-    const AtomString& formControlType() const override;
-    bool typeMismatchFor(const String&) const override;
-    bool typeMismatch() const override;
-    String typeMismatchText() const override;
-    String sanitizeValue(const String&) const override;
+    const AtomString& formControlType() const final;
+    bool typeMismatch() const final;
+    String typeMismatchText() const final;
+    String sanitizeValue(const String&) const final;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(URLInputType, Type::URL)

Modified: trunk/Source/WebCore/html/WeekInputType.h (293545 => 293546)


--- trunk/Source/WebCore/html/WeekInputType.h	2022-04-27 23:42:12 UTC (rev 293545)
+++ trunk/Source/WebCore/html/WeekInputType.h	2022-04-27 23:42:59 UTC (rev 293546)
@@ -45,12 +45,12 @@
     }
 
 private:
-    const AtomString& formControlType() const override;
-    DateComponentsType dateType() const override;
-    StepRange createStepRange(AnyStepHandling) const override;
-    std::optional<DateComponents> parseToDateComponents(StringView) const override;
-    std::optional<DateComponents> setMillisecondToDateComponents(double) const override;
-    void handleDOMActivateEvent(Event&) override;
+    const AtomString& formControlType() const final;
+    DateComponentsType dateType() const final;
+    StepRange createStepRange(AnyStepHandling) const final;
+    std::optional<DateComponents> parseToDateComponents(StringView) const final;
+    std::optional<DateComponents> setMillisecondToDateComponents(double) const final;
+    void handleDOMActivateEvent(Event&) final;
 
     bool isValidFormat(OptionSet<DateTimeFormatValidationResults>) const final;
     String formatDateTimeFieldsState(const DateTimeFieldsState&) const final;
@@ -59,4 +59,6 @@
 
 } // namespace WebCore
 
+SPECIALIZE_TYPE_TRAITS_INPUT_TYPE(WeekInputType, Type::Week)
+
 #endif // ENABLE(INPUT_TYPE_WEEK)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to