Remove the Timer parameters from timer callbacks
[WebKit-https.git] / Source / WebCore / html / SearchInputType.cpp
index abddb01..fa68b24 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
 #include "SearchInputType.h"
 
 #include "HTMLInputElement.h"
-#include "RenderTextControlSingleLine.h"
+#include "HTMLNames.h"
+#include "InputTypeNames.h"
+#include "KeyboardEvent.h"
+#include "RenderSearchField.h"
 #include "ShadowRoot.h"
 #include "TextControlInnerElements.h"
-#include <wtf/PassOwnPtr.h>
 
 namespace WebCore {
 
-inline SearchInputType::SearchInputType(HTMLInputElement* element)
+using namespace HTMLNames;
+
+SearchInputType::SearchInputType(HTMLInputElement& element)
     : BaseTextInputType(element)
-    , m_searchEventTimer(this, &SearchInputType::searchEventTimerFired)
+    , m_resultsButton(nullptr)
+    , m_cancelButton(nullptr)
+    , m_searchEventTimer(*this, &SearchInputType::searchEventTimerFired)
 {
 }
 
-PassOwnPtr<InputType> SearchInputType::create(HTMLInputElement* element)
+void SearchInputType::addSearchResult()
 {
-    return adoptPtr(new SearchInputType(element));
+#if !PLATFORM(IOS)
+    if (auto* renderer = element().renderer())
+        downcast<RenderSearchField>(*renderer).addSearchResult();
+#endif
 }
 
-const AtomicString& SearchInputType::formControlType() const
+static void updateResultButtonPseudoType(SearchFieldResultsButtonElement& resultButton, int maxResults)
 {
-    return InputTypeNames::search();
+    if (!maxResults)
+        resultButton.setPseudo(AtomicString("-webkit-search-results-decoration", AtomicString::ConstructFromLiteral));
+    else if (maxResults < 0)
+        resultButton.setPseudo(AtomicString("-webkit-search-decoration", AtomicString::ConstructFromLiteral));
+    else if (maxResults > 0)
+        resultButton.setPseudo(AtomicString("-webkit-search-results-button", AtomicString::ConstructFromLiteral));
 }
 
-bool SearchInputType::shouldRespectSpeechAttribute()
+void SearchInputType::maxResultsAttributeChanged()
 {
-    return true;
+    if (m_resultsButton)
+        updateResultButtonPseudoType(*m_resultsButton, element().maxResults());
+}
+
+RenderPtr<RenderElement> SearchInputType::createInputRenderer(PassRef<RenderStyle> style)
+{
+    return createRenderer<RenderSearchField>(element(), WTF::move(style));
+}
+
+const AtomicString& SearchInputType::formControlType() const
+{
+    return InputTypeNames::search();
 }
 
 bool SearchInputType::isSearchField() const
@@ -81,45 +107,65 @@ void SearchInputType::createShadowSubtree()
     ASSERT(container);
     ASSERT(textWrapper);
 
-    ExceptionCode ec = 0;
-    m_resultsButton = SearchFieldResultsButtonElement::create(element()->document());
-    container->insertBefore(m_resultsButton, textWrapper, ec);
+    RefPtr<SearchFieldResultsButtonElement> resultsButton = SearchFieldResultsButtonElement::create(element().document());
+    m_resultsButton = resultsButton.get();
+    updateResultButtonPseudoType(*m_resultsButton, element().maxResults());
+    container->insertBefore(m_resultsButton, textWrapper, IGNORE_EXCEPTION);
 
-    m_cancelButton = SearchFieldCancelButtonElement::create(element()->document());
-    container->insertBefore(m_cancelButton, textWrapper->nextSibling(), ec);
+    RefPtr<SearchFieldCancelButtonElement> cancelButton = SearchFieldCancelButtonElement::create(element().document());
+    m_cancelButton = cancelButton.get();
+    container->insertBefore(m_cancelButton, textWrapper->nextSibling(), IGNORE_EXCEPTION);
 }
 
 HTMLElement* SearchInputType::resultsButtonElement() const
 {
-    return m_resultsButton.get();
+    return m_resultsButton;
 }
 
 HTMLElement* SearchInputType::cancelButtonElement() const
 {
-    return m_cancelButton.get();
+    return m_cancelButton;
+}
+
+void SearchInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+    if (element().isDisabledOrReadOnly()) {
+        TextFieldInputType::handleKeydownEvent(event);
+        return;
+    }
+
+    const String& key = event->keyIdentifier();
+    if (key == "U+001B") {
+        Ref<HTMLInputElement> input(this->element());
+        input->setValueForUser("");
+        input->onSearch();
+        event->setDefaultHandled();
+        return;
+    }
+    TextFieldInputType::handleKeydownEvent(event);
 }
 
 void SearchInputType::destroyShadowSubtree()
 {
     TextFieldInputType::destroyShadowSubtree();
-    m_resultsButton.clear();
-    m_cancelButton.clear();
+    m_resultsButton = nullptr;
+    m_cancelButton = nullptr;
 }
 
 void SearchInputType::startSearchEventTimer()
 {
-    ASSERT(element()->renderer());
-    unsigned length = toRenderTextControlSingleLine(element()->renderer())->text().length();
+    ASSERT(element().renderer());
+    unsigned length = element().innerTextValue().length();
 
     if (!length) {
         stopSearchEventTimer();
-        element()->onSearch();
+        element().onSearch();
         return;
     }
 
     // After typing the first key, we wait 0.5 seconds.
     // After the second key, 0.4 seconds, then 0.3, then 0.2 from then on.
-    m_searchEventTimer.startOneShot(max(0.2, 0.6 - 0.1 * length));
+    m_searchEventTimer.startOneShot(std::max(0.2, 0.6 - 0.1 * length));
 }
 
 void SearchInputType::stopSearchEventTimer()
@@ -127,10 +173,42 @@ void SearchInputType::stopSearchEventTimer()
     m_searchEventTimer.stop();
 }
 
-void SearchInputType::searchEventTimerFired(Timer<SearchInputType>*)
+void SearchInputType::searchEventTimerFired()
 {
-    element()->onSearch();
+    element().onSearch();
 }
 
+bool SearchInputType::searchEventsShouldBeDispatched() const
+{
+    return element().fastHasAttribute(incrementalAttr);
+}
+
+void SearchInputType::didSetValueByUserEdit(ValueChangeState state)
+{
+    if (m_cancelButton && element().renderer())
+        downcast<RenderSearchField>(*element().renderer()).updateCancelButtonVisibility();
+
+    // If the incremental attribute is set, then dispatch the search event
+    if (searchEventsShouldBeDispatched())
+        startSearchEventTimer();
+
+    TextFieldInputType::didSetValueByUserEdit(state);
+}
+
+bool SearchInputType::sizeShouldIncludeDecoration(int, int& preferredSize) const
+{
+    preferredSize = element().size();
+    return true;
+}
+
+float SearchInputType::decorationWidth() const
+{
+    float width = 0;
+    if (m_resultsButton)
+        width += m_resultsButton->computedStyle()->logicalWidth().value();
+    if (m_cancelButton)
+        width += m_cancelButton->computedStyle()->logicalWidth().value();
+    return width;
+}
 
 } // namespace WebCore