diff options
Diffstat (limited to 'Source/WebCore/html/HTMLTextFormControlElement.cpp')
-rw-r--r-- | Source/WebCore/html/HTMLTextFormControlElement.cpp | 360 |
1 files changed, 141 insertions, 219 deletions
diff --git a/Source/WebCore/html/HTMLTextFormControlElement.cpp b/Source/WebCore/html/HTMLTextFormControlElement.cpp index 149f9dbf9..af222e4ac 100644 --- a/Source/WebCore/html/HTMLTextFormControlElement.cpp +++ b/Source/WebCore/html/HTMLTextFormControlElement.cpp @@ -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, 2014 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. * (C) 2006 Alexey Proskuryakov (ap@nypop.com) * * This library is free software; you can redistribute it and/or @@ -26,10 +26,12 @@ #include "HTMLTextFormControlElement.h" #include "AXObjectCache.h" +#include "Attribute.h" #include "ChromeClient.h" #include "Document.h" #include "Event.h" #include "EventNames.h" +#include "FeatureObserver.h" #include "Frame.h" #include "FrameSelection.h" #include "HTMLBRElement.h" @@ -37,7 +39,6 @@ #include "HTMLInputElement.h" #include "HTMLNames.h" #include "NodeTraversal.h" -#include "Page.h" #include "RenderBlockFlow.h" #include "RenderTextControlSingleLine.h" #include "RenderTheme.h" @@ -51,15 +52,12 @@ namespace WebCore { using namespace HTMLNames; -static Position positionForIndex(TextControlInnerTextElement*, unsigned); - HTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form) : HTMLFormControlElementWithState(tagName, document, form) + , m_lastChangeWasUserEdit(false) , m_cachedSelectionStart(-1) , m_cachedSelectionEnd(-1) , m_cachedSelectionDirection(SelectionHasNoDirection) - , m_lastChangeWasUserEdit(false) - , m_isPlaceholderVisible(false) { } @@ -78,37 +76,39 @@ bool HTMLTextFormControlElement::childShouldCreateRenderer(const Node& child) co Node::InsertionNotificationRequest HTMLTextFormControlElement::insertedInto(ContainerNode& insertionPoint) { - InsertionNotificationRequest insertionNotificationRequest = HTMLFormControlElementWithState::insertedInto(insertionPoint); + HTMLFormControlElementWithState::insertedInto(insertionPoint); if (!insertionPoint.inDocument()) - return insertionNotificationRequest; + return InsertionDone; String initialValue = value(); setTextAsOfLastFormControlChangeEvent(initialValue.isNull() ? emptyString() : initialValue); - return insertionNotificationRequest; + return InsertionDone; } -void HTMLTextFormControlElement::dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection direction) +void HTMLTextFormControlElement::dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection direction) { if (supportsPlaceholder()) - updatePlaceholderVisibility(); + updatePlaceholderVisibility(false); handleFocusEvent(oldFocusedElement.get(), direction); - HTMLFormControlElementWithState::dispatchFocusEvent(WTFMove(oldFocusedElement), direction); + HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, direction); } -void HTMLTextFormControlElement::dispatchBlurEvent(RefPtr<Element>&& newFocusedElement) +void HTMLTextFormControlElement::dispatchBlurEvent(PassRefPtr<Element> newFocusedElement) { if (supportsPlaceholder()) - updatePlaceholderVisibility(); + updatePlaceholderVisibility(false); handleBlurEvent(); - HTMLFormControlElementWithState::dispatchBlurEvent(WTFMove(newFocusedElement)); + HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement); } -void HTMLTextFormControlElement::didEditInnerTextValue() +void HTMLTextFormControlElement::defaultEventHandler(Event* event) { - if (!isTextFormControl()) + if (event->type() == eventNames().webkitEditableContentChangedEvent && renderer() && renderer()->isTextControl()) { + m_lastChangeWasUserEdit = true; + subtreeHasChanged(); return; + } - m_lastChangeWasUserEdit = true; - subtreeHasChanged(); + HTMLFormControlElementWithState::defaultEventHandler(event); } void HTMLTextFormControlElement::forwardEvent(Event* event) @@ -148,23 +148,24 @@ bool HTMLTextFormControlElement::isPlaceholderEmpty() const bool HTMLTextFormControlElement::placeholderShouldBeVisible() const { - // This function is used by the style resolver to match the :placeholder-shown pseudo class. - // Since it is used for styling, it must not use any value depending on the style. - return supportsPlaceholder() && isEmptyValue() && !isPlaceholderEmpty(); + return supportsPlaceholder() + && isEmptyValue() + && isEmptySuggestedValue() + && !isPlaceholderEmpty() + && (document().focusedElement() != this || (renderer() && renderer()->theme().shouldShowPlaceholderWhenFocused())) + && (!renderer() || renderer()->style().visibility() == VISIBLE); } -void HTMLTextFormControlElement::updatePlaceholderVisibility() +void HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderValueChanged) { - bool placeHolderWasVisible = m_isPlaceholderVisible; - m_isPlaceholderVisible = placeholderShouldBeVisible(); - - if (placeHolderWasVisible == m_isPlaceholderVisible) + if (!supportsPlaceholder()) return; - - setNeedsStyleRecalc(); - - if (HTMLElement* placeholder = placeholderElement()) - placeholder->setInlineStyleProperty(CSSPropertyDisplay, m_isPlaceholderVisible ? CSSValueBlock : CSSValueNone, true); + if (!placeholderElement() || placeholderValueChanged) + updatePlaceholderText(); + HTMLElement* placeholder = placeholderElement(); + if (!placeholder) + return; + placeholder->setInlineStyleProperty(CSSPropertyVisibility, placeholderShouldBeVisible() ? CSSValueVisible : CSSValueHidden); } void HTMLTextFormControlElement::setSelectionStart(int start) @@ -182,15 +183,15 @@ void HTMLTextFormControlElement::setSelectionDirection(const String& direction) setSelectionRange(selectionStart(), selectionEnd(), direction); } -void HTMLTextFormControlElement::select(const AXTextStateChangeIntent& intent) +void HTMLTextFormControlElement::select() { // FIXME: We should abstract the selection behavior into an EditingBehavior function instead // of hardcoding the behavior using a macro define. #if PLATFORM(IOS) // We don't want to select all the text on iOS. Instead use the standard textfield behavior of going to the end of the line. - setSelectionRange(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), SelectionHasForwardDirection, intent); + setSelectionRange(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), SelectionHasForwardDirection); #else - setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirection, intent); + setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirection); #endif } @@ -210,6 +211,11 @@ void HTMLTextFormControlElement::dispatchFormControlChangeEvent() setChangedSinceLastFormControlChangeEvent(false); } +static inline bool hasVisibleTextArea(RenderElement& textControl, TextControlInnerTextElement* innerText) +{ + return textControl.style().visibility() != HIDDEN && innerText && innerText->renderer() && innerText->renderBox()->height(); +} + void HTMLTextFormControlElement::setRangeText(const String& replacement, ExceptionCode& ec) { setRangeText(replacement, selectionStart(), selectionEnd(), String(), ec); @@ -244,12 +250,12 @@ void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigne subtreeHasChanged(); - if (equalLettersIgnoringASCIICase(selectionMode, "select")) { + if (equalIgnoringCase(selectionMode, "select")) { newSelectionStart = start; newSelectionEnd = start + replacementLength; - } else if (equalLettersIgnoringASCIICase(selectionMode, "start")) + } else if (equalIgnoringCase(selectionMode, "start")) newSelectionStart = newSelectionEnd = start; - else if (equalLettersIgnoringASCIICase(selectionMode, "end")) + else if (equalIgnoringCase(selectionMode, "end")) newSelectionStart = newSelectionEnd = start + replacementLength; else { // Default is "preserve". @@ -269,7 +275,7 @@ void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigne setSelectionRange(newSelectionStart, newSelectionEnd, SelectionHasNoDirection); } -void HTMLTextFormControlElement::setSelectionRange(int start, int end, const String& directionString, const AXTextStateChangeIntent& intent) +void HTMLTextFormControlElement::setSelectionRange(int start, int end, const String& directionString) { TextFieldSelectionDirection direction = SelectionHasNoDirection; if (directionString == "forward") @@ -277,61 +283,60 @@ void HTMLTextFormControlElement::setSelectionRange(int start, int end, const Str else if (directionString == "backward") direction = SelectionHasBackwardDirection; - return setSelectionRange(start, end, direction, intent); + return setSelectionRange(start, end, direction); } -void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextFieldSelectionDirection direction, const AXTextStateChangeIntent& intent) +void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextFieldSelectionDirection direction) { - if (!isTextFormControl()) + document().updateLayoutIgnorePendingStylesheets(); + + if (!renderer() || !renderer()->isTextControl()) return; end = std::max(end, 0); start = std::min(std::max(start, 0), end); - TextControlInnerTextElement* innerText = innerTextElement(); - bool hasFocus = document().focusedElement() == this; - if (!hasFocus && innerText) { - // FIXME: Removing this synchronous layout requires fixing <https://webkit.org/b/128797> - document().updateLayoutIgnorePendingStylesheets(); - if (RenderElement* rendererTextControl = renderer()) { - if (rendererTextControl->style().visibility() == HIDDEN || !innerText->renderBox()->height()) { - cacheSelection(start, end, direction); - return; - } - } + if (!hasVisibleTextArea(*renderer(), innerTextElement())) { + cacheSelection(start, end, direction); + return; } - - Position startPosition = positionForIndex(innerText, start); - Position endPosition; + VisiblePosition startPosition = visiblePositionForIndex(start); + VisiblePosition endPosition; if (start == end) endPosition = startPosition; - else { - if (direction == SelectionHasBackwardDirection) { - endPosition = startPosition; - startPosition = positionForIndex(innerText, end); - } else - endPosition = positionForIndex(innerText, end); + else + endPosition = visiblePositionForIndex(end); + +#if !PLATFORM(IOS) + // startPosition and endPosition can be null position for example when + // "-webkit-user-select: none" style attribute is specified. + if (startPosition.isNotNull() && endPosition.isNotNull()) { + ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowHost() == this + && endPosition.deepEquivalent().deprecatedNode()->shadowHost() == this); } +#endif + VisibleSelection newSelection; + if (direction == SelectionHasBackwardDirection) + newSelection = VisibleSelection(endPosition, startPosition); + else + newSelection = VisibleSelection(startPosition, endPosition); + newSelection.setIsDirectional(direction != SelectionHasNoDirection); if (Frame* frame = document().frame()) - frame->selection().moveWithoutValidationTo(startPosition, endPosition, direction != SelectionHasNoDirection, !hasFocus, intent); + frame->selection().setSelection(newSelection); } -int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& position) const +int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& pos) const { - TextControlInnerTextElement* innerText = innerTextElement(); - if (!innerText || !innerText->contains(position.deepEquivalent().anchorNode())) + if (enclosingTextFormControl(pos.deepEquivalent()) != this) return 0; - unsigned index = indexForPosition(position.deepEquivalent()); - ASSERT(VisiblePosition(positionForIndex(innerTextElement(), index)) == position); - return index; + bool forSelectionPreservation = false; + return WebCore::indexForVisiblePosition(innerTextElement(), pos, forSelectionPreservation); } VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) const { - VisiblePosition position = positionForIndex(innerTextElement(), index); - ASSERT(indexForVisiblePosition(position) == index); - return position; + return visiblePositionForIndexUsingCharacterIterator(innerTextElement(), index); } int HTMLTextFormControlElement::selectionStart() const @@ -351,7 +356,7 @@ int HTMLTextFormControlElement::computeSelectionStart() const if (!frame) return 0; - return indexForPosition(frame->selection().selection().start()); + return indexForVisiblePosition(frame->selection().start()); } int HTMLTextFormControlElement::selectionEnd() const @@ -370,14 +375,14 @@ int HTMLTextFormControlElement::computeSelectionEnd() const if (!frame) return 0; - return indexForPosition(frame->selection().selection().end()); + return indexForVisiblePosition(frame->selection().end()); } static const AtomicString& directionString(TextFieldSelectionDirection direction) { - static NeverDestroyed<const AtomicString> none("none", AtomicString::ConstructFromLiteral); - static NeverDestroyed<const AtomicString> forward("forward", AtomicString::ConstructFromLiteral); - static NeverDestroyed<const AtomicString> backward("backward", AtomicString::ConstructFromLiteral); + DEFINE_STATIC_LOCAL(const AtomicString, none, ("none", AtomicString::ConstructFromLiteral)); + DEFINE_STATIC_LOCAL(const AtomicString, forward, ("forward", AtomicString::ConstructFromLiteral)); + DEFINE_STATIC_LOCAL(const AtomicString, backward, ("backward", AtomicString::ConstructFromLiteral)); switch (direction) { case SelectionHasNoDirection: @@ -397,7 +402,7 @@ const AtomicString& HTMLTextFormControlElement::selectionDirection() const if (!isTextFormControl()) return directionString(SelectionHasNoDirection); if (document().focusedElement() != this && hasCachedSelection()) - return directionString(cachedSelectionDirection()); + return directionString(m_cachedSelectionDirection); return directionString(computeSelectionDirection()); } @@ -420,14 +425,14 @@ static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*& offsetInContainer = offset; } else { containerNode = node->parentNode(); - offsetInContainer = node->computeNodeIndex() + offset; + offsetInContainer = node->nodeIndex() + offset; } } PassRefPtr<Range> HTMLTextFormControlElement::selection() const { if (!renderer() || !isTextFormControl() || !hasCachedSelection()) - return nullptr; + return 0; int start = m_cachedSelectionStart; int end = m_cachedSelectionEnd; @@ -435,15 +440,15 @@ PassRefPtr<Range> HTMLTextFormControlElement::selection() const ASSERT(start <= end); TextControlInnerTextElement* innerText = innerTextElement(); if (!innerText) - return nullptr; + return 0; if (!innerText->firstChild()) return Range::create(document(), innerText, 0, innerText, 0); int offset = 0; - Node* startNode = nullptr; - Node* endNode = nullptr; - for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) { + Node* startNode = 0; + Node* endNode = 0; + for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(node, innerText)) { ASSERT(!node->firstChild()); ASSERT(node->isTextNode() || node->hasTagName(brTag)); int length = node->isTextNode() ? lastOffsetInNode(node) : 1; @@ -460,17 +465,17 @@ PassRefPtr<Range> HTMLTextFormControlElement::selection() const } if (!startNode || !endNode) - return nullptr; + return 0; return Range::create(document(), startNode, start, endNode, end); } -void HTMLTextFormControlElement::restoreCachedSelection(const AXTextStateChangeIntent& intent) +void HTMLTextFormControlElement::restoreCachedSelection() { - setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, cachedSelectionDirection(), intent); + setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSelectionDirection); } -void HTMLTextFormControlElement::selectionChanged(bool shouldFireSelectEvent) +void HTMLTextFormControlElement::selectionChanged(bool userTriggered) { if (!isTextFormControl()) return; @@ -478,38 +483,22 @@ void HTMLTextFormControlElement::selectionChanged(bool shouldFireSelectEvent) // FIXME: Don't re-compute selection start and end if this function was called inside setSelectionRange. // selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelectionDirection()); - - if (shouldFireSelectEvent && m_cachedSelectionStart != m_cachedSelectionEnd) - dispatchEvent(Event::create(eventNames().selectEvent, true, false)); + + if (Frame* frame = document().frame()) { + if (frame->selection().isRange() && userTriggered) + dispatchEvent(Event::create(eventNames().selectEvent, true, false)); + } } void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { if (name == placeholderAttr) { - updatePlaceholderText(); - updatePlaceholderVisibility(); + updatePlaceholderVisibility(true); + FeatureObserver::observe(&document(), FeatureObserver::PlaceholderAttribute); } else HTMLFormControlElementWithState::parseAttribute(name, value); } -void HTMLTextFormControlElement::disabledStateChanged() -{ - HTMLFormControlElementWithState::disabledStateChanged(); - updateInnerTextElementEditability(); -} - -void HTMLTextFormControlElement::readOnlyAttributeChanged() -{ - HTMLFormControlElementWithState::disabledAttributeChanged(); - updateInnerTextElementEditability(); -} - -void HTMLTextFormControlElement::updateInnerTextElementEditability() -{ - if (TextControlInnerTextElement* innerText = innerTextElement()) - innerText->setAttribute(contenteditableAttr, isDisabledOrReadOnly() ? "false" : "plaintext-only"); -} - bool HTMLTextFormControlElement::lastChangeWasUserEdit() const { if (!isTextFormControl()) @@ -517,136 +506,70 @@ bool HTMLTextFormControlElement::lastChangeWasUserEdit() const return m_lastChangeWasUserEdit; } -static void stripTrailingNewline(StringBuilder& result) -{ - // Remove one trailing newline; there's always one that's collapsed out by rendering. - size_t size = result.length(); - if (size && result[size - 1] == newlineCharacter) - result.resize(size - 1); -} - -static String innerTextValueFrom(TextControlInnerTextElement& innerText) -{ - StringBuilder result; - for (Node* node = innerText.firstChild(); node; node = NodeTraversal::next(*node, &innerText)) { - if (is<HTMLBRElement>(*node)) - result.append(newlineCharacter); - else if (is<Text>(*node)) - result.append(downcast<Text>(*node).data()); - } - stripTrailingNewline(result); - return result.toString(); -} - void HTMLTextFormControlElement::setInnerTextValue(const String& value) { - TextControlInnerTextElement* innerText = innerTextElement(); - if (!innerText) + if (!isTextFormControl()) return; - ASSERT(isTextFormControl()); - String previousValue = innerTextValueFrom(*innerText); - bool textIsChanged = value != previousValue; - if (textIsChanged || !innerText->hasChildNodes()) { -#if HAVE(ACCESSIBILITY) && !PLATFORM(COCOA) + bool textIsChanged = value != innerTextValue(); + if (textIsChanged || !innerTextElement()->hasChildNodes()) { if (textIsChanged && renderer()) { if (AXObjectCache* cache = document().existingAXObjectCache()) cache->postNotification(this, AXObjectCache::AXValueChanged, TargetObservableParent); } -#endif - innerText->setInnerText(value, ASSERT_NO_EXCEPTION); + innerTextElement()->setInnerText(value, ASSERT_NO_EXCEPTION); if (value.endsWith('\n') || value.endsWith('\r')) - innerText->appendChild(HTMLBRElement::create(document()), ASSERT_NO_EXCEPTION); - -#if HAVE(ACCESSIBILITY) && PLATFORM(COCOA) - if (textIsChanged && renderer()) { - if (AXObjectCache* cache = document().existingAXObjectCache()) - cache->postTextReplacementNotification(this, AXTextEditTypeDelete, previousValue, AXTextEditTypeInsert, value, VisiblePosition(Position(this, Position::PositionIsBeforeAnchor))); - } -#endif + innerTextElement()->appendChild(HTMLBRElement::create(document()), ASSERT_NO_EXCEPTION); } setFormControlValueMatchesRenderer(true); } -String HTMLTextFormControlElement::innerTextValue() const +static String finishText(StringBuilder& result) { - TextControlInnerTextElement* innerText = innerTextElement(); - return innerText ? innerTextValueFrom(*innerText) : emptyString(); -} - -static Position positionForIndex(TextControlInnerTextElement* innerText, unsigned index) -{ - unsigned remainingCharactersToMoveForward = index; - Node* lastBrOrText = innerText; - for (Node* node = innerText; node; node = NodeTraversal::next(*node, innerText)) { - if (node->hasTagName(brTag)) { - if (!remainingCharactersToMoveForward) - return positionBeforeNode(node); - remainingCharactersToMoveForward--; - lastBrOrText = node; - } else if (is<Text>(*node)) { - Text& text = downcast<Text>(*node); - if (remainingCharactersToMoveForward < text.length()) - return Position(&text, remainingCharactersToMoveForward); - remainingCharactersToMoveForward -= text.length(); - lastBrOrText = node; - } - } - return lastPositionInOrAfterNode(lastBrOrText); + // Remove one trailing newline; there's always one that's collapsed out by rendering. + size_t size = result.length(); + if (size && result[size - 1] == '\n') + result.resize(--size); + return result.toString(); } -unsigned HTMLTextFormControlElement::indexForPosition(const Position& passedPosition) const +String HTMLTextFormControlElement::innerTextValue() const { - TextControlInnerTextElement* innerText = innerTextElement(); - if (!innerText || !innerText->contains(passedPosition.anchorNode()) || passedPosition.isNull()) - return 0; + if (!isTextFormControl()) + return emptyString(); - if (positionBeforeNode(innerText) == passedPosition) - return 0; + TextControlInnerTextElement* innerText = innerTextElement(); + if (!innerText) + return emptyString(); - unsigned index = 0; - Node* startNode = passedPosition.computeNodeBeforePosition(); - if (!startNode) - startNode = passedPosition.containerNode(); - ASSERT(startNode); - ASSERT(innerText->contains(startNode)); - - for (Node* node = startNode; node; node = NodeTraversal::previous(*node, innerText)) { - if (is<Text>(*node)) { - unsigned length = downcast<Text>(*node).length(); - if (node == passedPosition.containerNode()) - index += std::min<unsigned>(length, passedPosition.offsetInContainerNode()); - else - index += length; - } else if (is<HTMLBRElement>(*node)) - ++index; + StringBuilder result; + for (Node* node = innerText; node; node = NodeTraversal::next(node, innerText)) { + if (node->hasTagName(brTag)) + result.append(newlineCharacter); + else if (node->isTextNode()) + result.append(toText(node)->data()); } - - unsigned length = innerTextValue().length(); - index = std::min(index, length); // FIXME: We shouldn't have to call innerTextValue() just to ignore the last LF. See finishText. -#ifndef ASSERT_DISABLED - VisiblePosition visiblePosition = passedPosition; - unsigned indexComputedByVisiblePosition = 0; - if (visiblePosition.isNotNull()) - indexComputedByVisiblePosition = WebCore::indexForVisiblePosition(innerText, visiblePosition, false /* forSelectionPreservation */); - ASSERT(index == indexComputedByVisiblePosition); -#endif - return index; + return finishText(result); } #if PLATFORM(IOS) void HTMLTextFormControlElement::hidePlaceholder() { - if (HTMLElement* placeholder = placeholderElement()) - placeholder->setInlineStyleProperty(CSSPropertyVisibility, CSSValueHidden, true); + if (!supportsPlaceholder()) + return; + HTMLElement* placeholder = placeholderElement(); + if (!placeholder) { + updatePlaceholderText(); + return; + } + placeholder->setInlineStyleProperty(CSSPropertyVisibility, ASCIILiteral("hidden")); } void HTMLTextFormControlElement::showPlaceholderIfNecessary() { - if (HTMLElement* placeholder = placeholderElement()) - placeholder->setInlineStyleProperty(CSSPropertyVisibility, CSSValueVisible, true); + updatePlaceholderVisibility(false); } #endif @@ -691,11 +614,11 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const getNextSoftBreak(line, breakNode, breakOffset); StringBuilder result; - for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) { - if (is<HTMLBRElement>(*node)) + for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(node, innerText)) { + if (node->hasTagName(brTag)) result.append(newlineCharacter); - else if (is<Text>(*node)) { - String data = downcast<Text>(*node).data(); + else if (node->isTextNode()) { + String data = toText(node)->data(); unsigned length = data.length(); unsigned position = 0; while (breakNode == node && breakOffset <= length) { @@ -711,8 +634,7 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const while (breakNode == node) getNextSoftBreak(line, breakNode, breakOffset); } - stripTrailingNewline(result); - return result.toString(); + return finishText(result); } HTMLTextFormControlElement* enclosingTextFormControl(const Position& position) @@ -725,7 +647,7 @@ HTMLTextFormControlElement* enclosingTextFormControl(const Position& position) if (!container) return nullptr; Element* ancestor = container->shadowHost(); - return ancestor && is<HTMLTextFormControlElement>(*ancestor) ? downcast<HTMLTextFormControlElement>(ancestor) : nullptr; + return ancestor && isHTMLTextFormControlElement(*ancestor) ? toHTMLTextFormControlElement(ancestor) : nullptr; } static const Element* parentHTMLElement(const Element* element) @@ -745,10 +667,10 @@ String HTMLTextFormControlElement::directionForFormData() const if (dirAttributeValue.isNull()) continue; - if (equalLettersIgnoringASCIICase(dirAttributeValue, "rtl") || equalLettersIgnoringASCIICase(dirAttributeValue, "ltr")) + if (equalIgnoringCase(dirAttributeValue, "rtl") || equalIgnoringCase(dirAttributeValue, "ltr")) return dirAttributeValue; - if (equalLettersIgnoringASCIICase(dirAttributeValue, "auto")) { + if (equalIgnoringCase(dirAttributeValue, "auto")) { bool isAuto; TextDirection textDirection = static_cast<const HTMLElement*>(element)->directionalityIfhasDirAutoAttribute(isAuto); return textDirection == RTL ? "rtl" : "ltr"; |