Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(957)

Unified Diff: Source/core/html/TextFieldInputType.cpp

Issue 24246011: Move form-related 78 files to core/html/forms/. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/html/TextFieldInputType.h ('k') | Source/core/html/TextInputType.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/html/TextFieldInputType.cpp
diff --git a/Source/core/html/TextFieldInputType.cpp b/Source/core/html/TextFieldInputType.cpp
deleted file mode 100644
index 65693bd25f7d9493f92aca42a9e097f91430facf..0000000000000000000000000000000000000000
--- a/Source/core/html/TextFieldInputType.cpp
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2011 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
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/TextFieldInputType.h"
-
-#include "HTMLNames.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/dom/BeforeTextInsertedEvent.h"
-#include "core/dom/KeyboardEvent.h"
-#include "core/dom/NodeRenderStyle.h"
-#include "core/dom/TextEvent.h"
-#include "core/dom/shadow/ShadowRoot.h"
-#include "core/editing/Editor.h"
-#include "core/editing/FrameSelection.h"
-#include "core/editing/TextIterator.h"
-#include "core/html/FormDataList.h"
-#include "core/html/HTMLInputElement.h"
-#include "core/html/shadow/ShadowElementNames.h"
-#include "core/html/shadow/TextControlInnerElements.h"
-#include "core/page/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/Settings.h"
-#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderTextControlSingleLine.h"
-#include "core/rendering/RenderTheme.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-TextFieldInputType::TextFieldInputType(HTMLInputElement* element)
- : InputType(element)
-{
-}
-
-TextFieldInputType::~TextFieldInputType()
-{
- if (SpinButtonElement* spinButton = spinButtonElement())
- spinButton->removeSpinButtonOwner();
-}
-
-SpinButtonElement* TextFieldInputType::spinButtonElement() const
-{
- return toSpinButtonElement(element()->userAgentShadowRoot()->getElementById(ShadowElementNames::spinButton()));
-}
-
-bool TextFieldInputType::shouldShowFocusRingOnMouseFocus() const
-{
- return true;
-}
-
-bool TextFieldInputType::isTextField() const
-{
- return true;
-}
-
-static inline bool shouldIgnoreRequiredAttribute(const HTMLInputElement& input)
-{
- if (!input.document().settings() || !input.document().settings()->needsSiteSpecificQuirks())
- return false;
- if (!equalIgnoringCase(input.document().url().host(), "egov.uscis.gov"))
- return false;
- return input.fastGetAttribute(requiredAttr) == "no";
-}
-
-bool TextFieldInputType::valueMissing(const String& value) const
-{
- return !shouldIgnoreRequiredAttribute(*element()) && element()->isRequired() && value.isEmpty();
-}
-
-bool TextFieldInputType::canSetSuggestedValue()
-{
- return true;
-}
-
-void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
-{
- // Grab this input element to keep reference even if JS event handler
- // changes input type.
- RefPtr<HTMLInputElement> input(element());
-
- // We don't ask InputType::setValue to dispatch events because
- // TextFieldInputType dispatches events different way from InputType.
- InputType::setValue(sanitizedValue, valueChanged, DispatchNoEvent);
-
- if (valueChanged)
- updateInnerTextValue();
-
- unsigned max = visibleValue().length();
- if (input->focused())
- input->setSelectionRange(max, max);
- else
- input->cacheSelectionInResponseToSetValue(max);
-
- if (!valueChanged)
- return;
-
- switch (eventBehavior) {
- case DispatchChangeEvent:
- // If the user is still editing this field, dispatch an input event rather than a change event.
- // The change event will be dispatched when editing finishes.
- if (input->focused())
- input->dispatchFormControlInputEvent();
- else
- input->dispatchFormControlChangeEvent();
- break;
-
- case DispatchInputAndChangeEvent: {
- input->dispatchFormControlInputEvent();
- input->dispatchFormControlChangeEvent();
- break;
- }
-
- case DispatchNoEvent:
- break;
- }
-
- if (!input->focused())
- input->setTextAsOfLastFormControlChangeEvent(sanitizedValue);
-}
-
-void TextFieldInputType::handleKeydownEvent(KeyboardEvent* event)
-{
- if (!element()->focused())
- return;
- Frame* frame = element()->document().frame();
- if (!frame || !frame->editor().doTextFieldCommandFromEvent(element(), event))
- return;
- event->setDefaultHandled();
-}
-
-void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent* event)
-{
- if (element()->isDisabledOrReadOnly())
- return;
- const String& key = event->keyIdentifier();
- if (key == "Up")
- spinButtonStepUp();
- else if (key == "Down")
- spinButtonStepDown();
- else
- return;
- event->setDefaultHandled();
-}
-
-void TextFieldInputType::forwardEvent(Event* event)
-{
- if (SpinButtonElement* spinButton = spinButtonElement()) {
- spinButton->forwardEvent(event);
- if (event->defaultHandled())
- return;
- }
-
- if (element()->renderer() && (event->isMouseEvent() || event->isDragEvent() || event->hasInterface(eventNames().interfaceForWheelEvent) || event->type() == eventNames().blurEvent || event->type() == eventNames().focusEvent)) {
- RenderTextControlSingleLine* renderTextControl = toRenderTextControlSingleLine(element()->renderer());
- if (event->type() == eventNames().blurEvent) {
- if (RenderBox* innerTextRenderer = innerTextElement()->renderBox()) {
- if (RenderLayer* innerLayer = innerTextRenderer->layer()) {
- IntSize scrollOffset(!renderTextControl->style()->isLeftToRightDirection() ? innerLayer->scrollWidth() : 0, 0);
- innerLayer->scrollToOffset(scrollOffset, ScrollOffsetClamped);
- }
- }
-
- renderTextControl->capsLockStateMayHaveChanged();
- } else if (event->type() == eventNames().focusEvent)
- renderTextControl->capsLockStateMayHaveChanged();
-
- element()->forwardEvent(event);
- }
-}
-
-void TextFieldInputType::handleFocusEvent(Element* oldFocusedNode, FocusDirection focusDirection)
-{
- InputType::handleFocusEvent(oldFocusedNode, focusDirection);
- element()->beginEditing();
-}
-
-void TextFieldInputType::handleBlurEvent()
-{
- InputType::handleBlurEvent();
- element()->endEditing();
-}
-
-bool TextFieldInputType::shouldSubmitImplicitly(Event* event)
-{
- return (event->type() == eventNames().textInputEvent && event->hasInterface(eventNames().interfaceForTextEvent) && static_cast<TextEvent*>(event)->data() == "\n") || InputType::shouldSubmitImplicitly(event);
-}
-
-RenderObject* TextFieldInputType::createRenderer(RenderStyle*) const
-{
- return new RenderTextControlSingleLine(element());
-}
-
-bool TextFieldInputType::needsContainer() const
-{
-#if ENABLE(INPUT_SPEECH)
- return element()->isSpeechEnabled();
-#else
- return false;
-#endif
-}
-
-bool TextFieldInputType::shouldHaveSpinButton() const
-{
- return RenderTheme::theme().shouldHaveSpinButton(element());
-}
-
-void TextFieldInputType::createShadowSubtree()
-{
- ASSERT(element()->shadow());
- ShadowRoot* shadowRoot = element()->userAgentShadowRoot();
- ASSERT(!shadowRoot->hasChildNodes());
-
- Document& document = element()->document();
- bool shouldHaveSpinButton = this->shouldHaveSpinButton();
- bool createsContainer = shouldHaveSpinButton || needsContainer();
-
- m_innerText = TextControlInnerTextElement::create(document);
- if (!createsContainer) {
- shadowRoot->appendChild(m_innerText);
- return;
- }
-
- m_container = TextControlInnerContainer::create(document);
- m_container->setPart(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
- shadowRoot->appendChild(m_container);
-
- RefPtr<EditingViewPortElement> editingViewPort = EditingViewPortElement::create(document);
- editingViewPort->appendChild(m_innerText);
- m_container->appendChild(editingViewPort.release());
-
-#if ENABLE(INPUT_SPEECH)
- if (element()->isSpeechEnabled())
- m_container->appendChild(InputFieldSpeechButtonElement::create(document));
-#endif
-
- if (shouldHaveSpinButton)
- m_container->appendChild(SpinButtonElement::create(document, *this));
-}
-
-HTMLElement* TextFieldInputType::containerElement() const
-{
- return m_container.get();
-}
-
-HTMLElement* TextFieldInputType::innerTextElement() const
-{
- ASSERT(m_innerText);
- return m_innerText.get();
-}
-
-void TextFieldInputType::destroyShadowSubtree()
-{
- InputType::destroyShadowSubtree();
- m_innerText.clear();
- if (SpinButtonElement* spinButton = spinButtonElement())
- spinButton->removeSpinButtonOwner();
- m_container.clear();
-}
-
-void TextFieldInputType::attributeChanged()
-{
- // FIXME: Updating the inner text on any attribute update should
- // be unnecessary. We should figure out what attributes affect.
- updateInnerTextValue();
-}
-
-void TextFieldInputType::disabledAttributeChanged()
-{
- if (SpinButtonElement* spinButton = spinButtonElement())
- spinButton->releaseCapture();
-}
-
-void TextFieldInputType::readonlyAttributeChanged()
-{
- if (SpinButtonElement* spinButton = spinButtonElement())
- spinButton->releaseCapture();
-}
-
-bool TextFieldInputType::supportsReadOnly() const
-{
- return true;
-}
-
-bool TextFieldInputType::shouldUseInputMethod() const
-{
- return true;
-}
-
-static bool isASCIILineBreak(UChar c)
-{
- return c == '\r' || c == '\n';
-}
-
-static String limitLength(const String& string, unsigned maxLength)
-{
- unsigned newLength = std::min(maxLength, string.length());
- // FIXME: We should not truncate the string at a control character. It's not
- // compatible with IE and Firefox.
- for (unsigned i = 0; i < newLength; ++i) {
- const UChar current = string[i];
- if (current < ' ' && current != '\t') {
- newLength = i;
- break;
- }
- }
- if (newLength == string.length())
- return string;
- if (newLength > 0 && U16_IS_LEAD(string[newLength - 1]))
- --newLength;
- return string.left(newLength);
-}
-
-String TextFieldInputType::sanitizeValue(const String& proposedValue) const
-{
- return limitLength(proposedValue.removeCharacters(isASCIILineBreak), HTMLInputElement::maximumLength);
-}
-
-void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event)
-{
- // Make sure that the text to be inserted will not violate the maxLength.
-
- // We use HTMLInputElement::innerTextValue() instead of
- // HTMLInputElement::value() because they can be mismatched by
- // sanitizeValue() in HTMLInputElement::subtreeHasChanged() in some cases.
- unsigned oldLength = element()->innerTextValue().length();
-
- // selectionLength represents the selection length of this text field to be
- // removed by this insertion.
- // If the text field has no focus, we don't need to take account of the
- // selection length. The selection is the source of text drag-and-drop in
- // that case, and nothing in the text field will be removed.
- unsigned selectionLength = element()->focused() ? plainText(element()->document().frame()->selection().selection().toNormalizedRange().get()).length() : 0;
- ASSERT(oldLength >= selectionLength);
-
- // Selected characters will be removed by the next text event.
- unsigned baseLength = oldLength - selectionLength;
- unsigned maxLength = static_cast<unsigned>(isTextType() ? element()->maxLength() : HTMLInputElement::maximumLength); // maxLength can never be negative.
- unsigned appendableLength = maxLength > baseLength ? maxLength - baseLength : 0;
-
- // Truncate the inserted text to avoid violating the maxLength and other constraints.
- String eventText = event->text();
- unsigned textLength = eventText.length();
- while (textLength > 0 && isASCIILineBreak(eventText[textLength - 1]))
- textLength--;
- eventText.truncate(textLength);
- eventText.replace("\r\n", " ");
- eventText.replace('\r', ' ');
- eventText.replace('\n', ' ');
-
- event->setText(limitLength(eventText, appendableLength));
-}
-
-bool TextFieldInputType::shouldRespectListAttribute()
-{
- return InputType::themeSupportsDataListUI(this);
-}
-
-void TextFieldInputType::updatePlaceholderText()
-{
- if (!supportsPlaceholder())
- return;
- HTMLElement* placeholder = element()->placeholderElement();
- String placeholderText = element()->strippedPlaceholder();
- if (placeholderText.isEmpty()) {
- if (placeholder)
- placeholder->remove(ASSERT_NO_EXCEPTION);
- return;
- }
- if (!placeholder) {
- RefPtr<HTMLElement> newElement = HTMLDivElement::create(element()->document());
- placeholder = newElement.get();
- placeholder->setPart(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
- placeholder->setAttribute(idAttr, ShadowElementNames::placeholder());
- element()->userAgentShadowRoot()->insertBefore(placeholder, m_container ? m_container->nextSibling() : innerTextElement()->nextSibling());
- }
- placeholder->setTextContent(placeholderText, ASSERT_NO_EXCEPTION);
-}
-
-bool TextFieldInputType::appendFormData(FormDataList& list, bool multipart) const
-{
- InputType::appendFormData(list, multipart);
- const AtomicString& dirnameAttrValue = element()->fastGetAttribute(dirnameAttr);
- if (!dirnameAttrValue.isNull())
- list.appendData(dirnameAttrValue, element()->directionForFormData());
- return true;
-}
-
-String TextFieldInputType::convertFromVisibleValue(const String& visibleValue) const
-{
- return visibleValue;
-}
-
-void TextFieldInputType::subtreeHasChanged()
-{
- ASSERT(element()->renderer());
-
- bool wasChanged = element()->wasChangedSinceLastFormControlChangeEvent();
- element()->setChangedSinceLastFormControlChangeEvent(true);
-
- // We don't need to call sanitizeUserInputValue() function here because
- // HTMLInputElement::handleBeforeTextInsertedEvent() has already called
- // sanitizeUserInputValue().
- // sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent.
- element()->setValueFromRenderer(sanitizeValue(convertFromVisibleValue(element()->innerTextValue())));
- element()->updatePlaceholderVisibility(false);
- // Recalc for :invalid change.
- element()->setNeedsStyleRecalc();
-
- didSetValueByUserEdit(wasChanged ? ValueChangeStateChanged : ValueChangeStateNone);
-}
-
-void TextFieldInputType::didSetValueByUserEdit(ValueChangeState state)
-{
- if (!element()->focused())
- return;
- if (Frame* frame = element()->document().frame())
- frame->editor().textDidChangeInTextField(element());
-}
-
-void TextFieldInputType::spinButtonStepDown()
-{
- stepUpFromRenderer(-1);
-}
-
-void TextFieldInputType::spinButtonStepUp()
-{
- stepUpFromRenderer(1);
-}
-
-void TextFieldInputType::updateInnerTextValue()
-{
- if (!element()->suggestedValue().isNull()) {
- element()->setInnerTextValue(element()->suggestedValue());
- element()->updatePlaceholderVisibility(false);
- } else if (!element()->formControlValueMatchesRenderer()) {
- // Update the renderer value if the formControlValueMatchesRenderer() flag is false.
- // It protects an unacceptable renderer value from being overwritten with the DOM value.
- element()->setInnerTextValue(visibleValue());
- element()->updatePlaceholderVisibility(false);
- }
-}
-
-void TextFieldInputType::focusAndSelectSpinButtonOwner()
-{
- RefPtr<HTMLInputElement> input(element());
- input->focus();
- input->select();
-}
-
-bool TextFieldInputType::shouldSpinButtonRespondToMouseEvents()
-{
- return !element()->isDisabledOrReadOnly();
-}
-
-bool TextFieldInputType::shouldSpinButtonRespondToWheelEvents()
-{
- return shouldSpinButtonRespondToMouseEvents() && element()->focused();
-}
-
-} // namespace WebCore
« no previous file with comments | « Source/core/html/TextFieldInputType.h ('k') | Source/core/html/TextInputType.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698