Simplify and streamline some Color-related code to prepare for some Color/ExtendedCol...
[WebKit-https.git] / Source / WebCore / html / InputType.cpp
index a730504..1a6db49 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
  *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
  * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
  * Copyright (C) 2009, 2010, 2011, 2012 Google Inc. All rights reserved.
 #include "ButtonInputType.h"
 #include "CheckboxInputType.h"
 #include "ColorInputType.h"
+#include "DOMFormData.h"
 #include "DateComponents.h"
 #include "DateInputType.h"
 #include "DateTimeInputType.h"
 #include "DateTimeLocalInputType.h"
 #include "EmailInputType.h"
 #include "EventNames.h"
-#include "ExceptionCode.h"
-#include "ExceptionCodePlaceholder.h"
 #include "FileInputType.h"
 #include "FileList.h"
 #include "FormController.h"
-#include "FormDataList.h"
 #include "HTMLFormElement.h"
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
@@ -70,7 +68,7 @@
 #include "ShadowRoot.h"
 #include "SubmitInputType.h"
 #include "TelephoneInputType.h"
-#include <wtf/text/TextBreakIterator.h>
+#include "TextControlInnerElements.h"
 #include "TextInputType.h"
 #include "TimeInputType.h"
 #include "URLInputType.h"
@@ -79,6 +77,7 @@
 #include <wtf/Assertions.h>
 #include <wtf/HashMap.h>
 #include <wtf/text/StringHash.h>
+#include <wtf/text/TextBreakIterator.h>
 
 namespace WebCore {
 
@@ -95,7 +94,7 @@ static std::unique_ptr<InputType> createInputType(HTMLInputElement& element)
     return std::make_unique<T>(element);
 }
 
-static void populateInputTypeFactoryMap(InputTypeFactoryMap& map)
+static InputTypeFactoryMap createInputTypeFactoryMap()
 {
     static const struct InputTypes {
         InputTypeConditionalFunction conditionalFunction;
@@ -141,20 +140,19 @@ static void populateInputTypeFactoryMap(InputTypeFactoryMap& map)
         // No need to register "text" because it is the default type.
     };
 
+    InputTypeFactoryMap map;
     for (auto& inputType : inputTypes) {
         auto conditionalFunction = inputType.conditionalFunction;
         if (!conditionalFunction || (RuntimeEnabledFeatures::sharedFeatures().*conditionalFunction)())
             map.add(inputType.nameFunction(), inputType.factoryFunction);
     }
+    return map;
 }
 
 std::unique_ptr<InputType> InputType::create(HTMLInputElement& element, const AtomicString& typeName)
 {
-    static NeverDestroyed<InputTypeFactoryMap> factoryMap;
-    if (factoryMap.get().isEmpty())
-        populateInputTypeFactoryMap(factoryMap);
-
     if (!typeName.isEmpty()) {
+        static const auto factoryMap = makeNeverDestroyed(createInputTypeFactoryMap());
         if (auto factory = factoryMap.get().get(typeName))
             return factory(element);
     }
@@ -166,14 +164,11 @@ std::unique_ptr<InputType> InputType::createText(HTMLInputElement& element)
     return std::make_unique<TextInputType>(element);
 }
 
-InputType::~InputType()
-{
-}
+InputType::~InputType() = default;
 
 bool InputType::themeSupportsDataListUI(InputType* type)
 {
-    Document& document = type->element().document();
-    return RenderTheme::themeForPage(document.page())->supportsDataListUI(type->formControlType());
+    return RenderTheme::singleton().supportsDataListUI(type->formControlType());
 }
 
 bool InputType::isTextField() const
@@ -198,10 +193,10 @@ bool InputType::shouldSaveAndRestoreFormControlState() const
 
 FormControlState InputType::saveFormControlState() const
 {
-    String currentValue = element().value();
+    auto currentValue = element().value();
     if (currentValue == element().defaultValue())
-        return FormControlState();
-    return FormControlState(currentValue);
+        return { };
+    return { { currentValue } };
 }
 
 void InputType::restoreFormControlState(const FormControlState& state)
@@ -215,10 +210,10 @@ bool InputType::isFormDataAppendable() const
     return !element().name().isEmpty();
 }
 
-bool InputType::appendFormData(FormDataList& encoding, bool) const
+bool InputType::appendFormData(DOMFormData& formData, bool) const
 {
     // Always successful.
-    encoding.appendData(element().name(), element().value());
+    formData.append(element().name(), element().value());
     return true;
 }
 
@@ -227,9 +222,9 @@ double InputType::valueAsDate() const
     return DateComponents::invalidMilliseconds();
 }
 
-void InputType::setValueAsDate(double, ExceptionCode& ec) const
+ExceptionOr<void> InputType::setValueAsDate(double) const
 {
-    ec = INVALID_STATE_ERR;
+    return Exception { InvalidStateError };
 }
 
 double InputType::valueAsDouble() const
@@ -237,14 +232,14 @@ double InputType::valueAsDouble() const
     return std::numeric_limits<double>::quiet_NaN();
 }
 
-void InputType::setValueAsDouble(double doubleValue, TextFieldEventBehavior eventBehavior, ExceptionCode& ec) const
+ExceptionOr<void> InputType::setValueAsDouble(double doubleValue, TextFieldEventBehavior eventBehavior) const
 {
-    setValueAsDecimal(Decimal::fromDouble(doubleValue), eventBehavior, ec);
+    return setValueAsDecimal(Decimal::fromDouble(doubleValue), eventBehavior);
 }
 
-void InputType::setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionCode& ec) const
+ExceptionOr<void> InputType::setValueAsDecimal(const Decimal&, TextFieldEventBehavior) const
 {
-    ec = INVALID_STATE_ERR;
+    return Exception { InvalidStateError };
 }
 
 bool InputType::supportsValidation() const
@@ -483,11 +478,6 @@ bool InputType::shouldSubmitImplicitly(Event& event)
     return is<KeyboardEvent>(event) && event.type() == eventNames().keypressEvent && downcast<KeyboardEvent>(event).charCode() == '\r';
 }
 
-PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
-{
-    return element().form();
-}
-
 RenderPtr<RenderElement> InputType::createInputRenderer(RenderStyle&& style)
 {
     return RenderPtr<RenderElement>(RenderElement::createFor(element(), WTFMove(style)));
@@ -504,7 +494,7 @@ void InputType::createShadowSubtree()
 
 void InputType::destroyShadowSubtree()
 {
-    ShadowRoot* root = element().userAgentShadowRoot();
+    RefPtr<ShadowRoot> root = element().userAgentShadowRoot();
     if (!root)
         return;
 
@@ -552,7 +542,7 @@ Chrome* InputType::chrome() const
 {
     if (Page* page = element().document().page())
         return &page->chrome();
-    return 0;
+    return nullptr;
 }
 
 bool InputType::canSetStringValue() const
@@ -637,7 +627,7 @@ bool InputType::canBeSuccessfulSubmitButton()
 
 HTMLElement* InputType::placeholderElement() const
 {
-    return 0;
+    return nullptr;
 }
 
 bool InputType::rendererIsNeeded()
@@ -647,10 +637,10 @@ bool InputType::rendererIsNeeded()
 
 FileList* InputType::files()
 {
-    return 0;
+    return nullptr;
 }
 
-void InputType::setFiles(PassRefPtr<FileList>)
+void InputType::setFiles(RefPtr<FileList>&&)
 {
 }
 
@@ -707,7 +697,7 @@ void InputType::willDispatchClick(InputElementClickState&)
 {
 }
 
-void InputType::didDispatchClick(Event*, const InputElementClickState&)
+void InputType::didDispatchClick(Event&, const InputElementClickState&)
 {
 }
 
@@ -732,26 +722,26 @@ String InputType::sanitizeValue(const String& proposedValue) const
 }
 
 #if ENABLE(DRAG_SUPPORT)
+
 bool InputType::receiveDroppedFiles(const DragData&)
 {
     ASSERT_NOT_REACHED();
     return false;
 }
+
 #endif
 
 Icon* InputType::icon() const
 {
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
-#if PLATFORM(IOS)
 String InputType::displayString() const
 {
     ASSERT_NOT_REACHED();
     return String();
 }
-#endif
 
 bool InputType::shouldResetOnDocumentActivation()
 {
@@ -906,7 +896,7 @@ void InputType::updatePlaceholderText()
 {
 }
 
-void InputType::attributeChanged()
+void InputType::attributeChanged(const QualifiedName&)
 {
 }
 
@@ -956,10 +946,10 @@ void InputType::listAttributeTargetChanged()
 {
 }
 
-Optional<Decimal> InputType::findClosestTickMarkValue(const Decimal&)
+std::optional<Decimal> InputType::findClosestTickMarkValue(const Decimal&)
 {
     ASSERT_NOT_REACHED();
-    return Nullopt;
+    return std::nullopt;
 }
 #endif
 
@@ -988,47 +978,41 @@ unsigned InputType::width() const
     return 0;
 }
 
-void InputType::applyStep(int count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionCode& ec)
+ExceptionOr<void> InputType::applyStep(int count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior)
 {
     StepRange stepRange(createStepRange(anyStepHandling));
-    if (!stepRange.hasStep()) {
-        ec = INVALID_STATE_ERR;
-        return;
-    }
+    if (!stepRange.hasStep())
+        return Exception { InvalidStateError };
 
     const Decimal current = parseToNumberOrNaN(element().value());
-    if (!current.isFinite()) {
-        ec = INVALID_STATE_ERR;
-        return;
-    }
+    if (!current.isFinite())
+        return Exception { InvalidStateError };
     Decimal newValue = current + stepRange.step() * count;
-    if (!newValue.isFinite()) {
-        ec = INVALID_STATE_ERR;
-        return;
-    }
+    if (!newValue.isFinite())
+        return Exception { InvalidStateError };
 
     const Decimal acceptableErrorValue = stepRange.acceptableError();
-    if (newValue - stepRange.minimum() < -acceptableErrorValue) {
-        ec = INVALID_STATE_ERR;
-        return;
-    }
+    if (newValue - stepRange.minimum() < -acceptableErrorValue)
+        return Exception { InvalidStateError };
     if (newValue < stepRange.minimum())
         newValue = stepRange.minimum();
 
     if (!equalLettersIgnoringASCIICase(element().attributeWithoutSynchronization(stepAttr), "any"))
         newValue = stepRange.alignValueForStep(current, newValue);
 
-    if (newValue - stepRange.maximum() > acceptableErrorValue) {
-        ec = INVALID_STATE_ERR;
-        return;
-    }
+    if (newValue - stepRange.maximum() > acceptableErrorValue)
+        return Exception { InvalidStateError };
     if (newValue > stepRange.maximum())
         newValue = stepRange.maximum();
 
-    setValueAsDecimal(newValue, eventBehavior, ec);
+    auto result = setValueAsDecimal(newValue, eventBehavior);
+    if (result.hasException())
+        return result;
 
     if (AXObjectCache* cache = element().document().existingAXObjectCache())
         cache->postNotification(&element(), AXObjectCache::AXValueChanged);
+
+    return result;
 }
 
 bool InputType::getAllowedValueStep(Decimal* step) const
@@ -1044,13 +1028,11 @@ StepRange InputType::createStepRange(AnyStepHandling) const
     return StepRange();
 }
 
-void InputType::stepUp(int n, ExceptionCode& ec)
+ExceptionOr<void> InputType::stepUp(int n)
 {
-    if (!isSteppable()) {
-        ec = INVALID_STATE_ERR;
-        return;
-    }
-    applyStep(n, RejectAny, DispatchNoEvent, ec);
+    if (!isSteppable())
+        return Exception { InvalidStateError };
+    return applyStep(n, RejectAny, DispatchNoEvent);
 }
 
 void InputType::stepUpFromRenderer(int n)
@@ -1124,10 +1106,10 @@ void InputType::stepUpFromRenderer(int n)
             current = stepRange.minimum() - nextDiff;
         if (current > stepRange.maximum() - nextDiff)
             current = stepRange.maximum() - nextDiff;
-        setValueAsDecimal(current, DispatchNoEvent, IGNORE_EXCEPTION);
+        setValueAsDecimal(current, DispatchNoEvent);
     }
     if ((sign > 0 && current < stepRange.minimum()) || (sign < 0 && current > stepRange.maximum()))
-        setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(), DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
+        setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(), DispatchInputAndChangeEvent);
     else {
         if (stepMismatch(element().value())) {
             ASSERT(!step.isZero());
@@ -1145,13 +1127,13 @@ void InputType::stepUpFromRenderer(int n)
             if (newValue > stepRange.maximum())
                 newValue = stepRange.maximum();
 
-            setValueAsDecimal(newValue, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent, IGNORE_EXCEPTION);
+            setValueAsDecimal(newValue, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent);
             if (n > 1)
-                applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
+                applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent);
             else if (n < -1)
-                applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
+                applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent);
         } else
-            applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
+            applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent);
     }
 }
 
@@ -1160,8 +1142,13 @@ Color InputType::valueAsColor() const
     return Color::transparent;
 }
 
-void InputType::selectColor(const Color&)
+void InputType::selectColor(StringView)
+{
+}
+
+RefPtr<TextControlInnerTextElement> InputType::innerTextElement() const
 {
+    return nullptr;
 }
 
 } // namespace WebCore