diff options
Diffstat (limited to 'Source/WebCore/html/ValidationMessage.cpp')
-rw-r--r-- | Source/WebCore/html/ValidationMessage.cpp | 87 |
1 files changed, 46 insertions, 41 deletions
diff --git a/Source/WebCore/html/ValidationMessage.cpp b/Source/WebCore/html/ValidationMessage.cpp index e00b19544..9d5dcacfb 100644 --- a/Source/WebCore/html/ValidationMessage.cpp +++ b/Source/WebCore/html/ValidationMessage.cpp @@ -33,7 +33,6 @@ #include "CSSPropertyNames.h" #include "CSSValueKeywords.h" -#include "ExceptionCodePlaceholder.h" #include "HTMLBRElement.h" #include "HTMLDivElement.h" #include "HTMLFormControlElement.h" @@ -46,13 +45,12 @@ #include "StyleResolver.h" #include "Text.h" #include "ValidationMessageClient.h" -#include <wtf/PassOwnPtr.h> namespace WebCore { using namespace HTMLNames; -ALWAYS_INLINE ValidationMessage::ValidationMessage(HTMLFormControlElement* element) +ValidationMessage::ValidationMessage(HTMLFormControlElement* element) : m_element(element) { ASSERT(m_element); @@ -68,11 +66,6 @@ ValidationMessage::~ValidationMessage() deleteBubbleTree(); } -OwnPtr<ValidationMessage> ValidationMessage::create(HTMLFormControlElement* element) -{ - return adoptPtr(new ValidationMessage(element)); -} - ValidationMessageClient* ValidationMessage::validationMessageClient() const { if (Page* page = m_element->document().page()) @@ -82,15 +75,23 @@ ValidationMessageClient* ValidationMessage::validationMessageClient() const void ValidationMessage::updateValidationMessage(const String& message) { + // We want to hide the validation message as soon as the user starts + // typing, even if a constraint is still violated. Thefore, we hide the message instead + // of updating it if it is already visible. + if (isVisible()) { + requestToHideMessage(); + return; + } + String updatedMessage = message; if (!validationMessageClient()) { // HTML5 specification doesn't ask UA to show the title attribute value // with the validationMessage. However, this behavior is same as Opera // and the specification describes such behavior as an example. - const AtomicString& title = m_element->fastGetAttribute(titleAttr); - if (!updatedMessage.isEmpty() && !title.isEmpty()) { - updatedMessage.append('\n'); - updatedMessage.append(title); + if (!updatedMessage.isEmpty()) { + const AtomicString& title = m_element->attributeWithoutSynchronization(titleAttr); + if (!title.isEmpty()) + updatedMessage = updatedMessage + '\n' + title; } } @@ -113,13 +114,13 @@ void ValidationMessage::setMessage(const String& message) ASSERT(!message.isEmpty()); m_message = message; if (!m_bubble) - m_timer = adoptPtr(new Timer<ValidationMessage>(this, &ValidationMessage::buildBubbleTree)); + m_timer = std::make_unique<Timer>(*this, &ValidationMessage::buildBubbleTree); else - m_timer = adoptPtr(new Timer<ValidationMessage>(this, &ValidationMessage::setMessageDOMAndStartTimer)); + m_timer = std::make_unique<Timer>(*this, &ValidationMessage::setMessageDOMAndStartTimer); m_timer->startOneShot(0); } -void ValidationMessage::setMessageDOMAndStartTimer(Timer<ValidationMessage>*) +void ValidationMessage::setMessageDOMAndStartTimer() { ASSERT(!validationMessageClient()); ASSERT(m_messageHeading); @@ -131,18 +132,18 @@ void ValidationMessage::setMessageDOMAndStartTimer(Timer<ValidationMessage>*) Document& document = m_messageHeading->document(); for (unsigned i = 0; i < lines.size(); ++i) { if (i) { - m_messageBody->appendChild(Text::create(document, lines[i]), ASSERT_NO_EXCEPTION); + m_messageBody->appendChild(Text::create(document, lines[i])); if (i < lines.size() - 1) - m_messageBody->appendChild(HTMLBRElement::create(document), ASSERT_NO_EXCEPTION); + m_messageBody->appendChild(HTMLBRElement::create(document)); } else - m_messageHeading->setInnerText(lines[i], ASSERT_NO_EXCEPTION); + m_messageHeading->setInnerText(lines[i]); } int magnification = document.page() ? document.page()->settings().validationMessageTimerMagnification() : -1; if (magnification <= 0) - m_timer.clear(); + m_timer = nullptr; else { - m_timer = adoptPtr(new Timer<ValidationMessage>(this, &ValidationMessage::deleteBubbleTree)); + m_timer = std::make_unique<Timer>(*this, &ValidationMessage::deleteBubbleTree); m_timer->startOneShot(std::max(5.0, static_cast<double>(m_message.length()) * magnification / 1000)); } } @@ -171,9 +172,13 @@ static void adjustBubblePosition(const LayoutRect& hostRect, HTMLElement* bubble bubble->setInlineStyleProperty(CSSPropertyLeft, bubbleX, CSSPrimitiveValue::CSS_PX); } -void ValidationMessage::buildBubbleTree(Timer<ValidationMessage>*) +void ValidationMessage::buildBubbleTree() { ASSERT(!validationMessageClient()); + + if (!m_element->renderer()) + return; + ShadowRoot& shadowRoot = m_element->ensureUserAgentShadowRoot(); Document& document = m_element->document(); @@ -182,32 +187,32 @@ void ValidationMessage::buildBubbleTree(Timer<ValidationMessage>*) // Need to force position:absolute because RenderMenuList doesn't assume it // contains non-absolute or non-fixed renderers as children. m_bubble->setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute); - shadowRoot.appendChild(m_bubble.get(), ASSERT_NO_EXCEPTION); + shadowRoot.appendChild(*m_bubble); document.updateLayout(); - adjustBubblePosition(m_element->boundingBox(), m_bubble.get()); + adjustBubblePosition(m_element->renderer()->absoluteBoundingBoxRect(), m_bubble.get()); - RefPtr<HTMLDivElement> clipper = HTMLDivElement::create(document); + auto clipper = HTMLDivElement::create(document); clipper->setPseudo(AtomicString("-webkit-validation-bubble-arrow-clipper", AtomicString::ConstructFromLiteral)); - RefPtr<HTMLDivElement> bubbleArrow = HTMLDivElement::create(document); + auto bubbleArrow = HTMLDivElement::create(document); bubbleArrow->setPseudo(AtomicString("-webkit-validation-bubble-arrow", AtomicString::ConstructFromLiteral)); - clipper->appendChild(bubbleArrow.release(), ASSERT_NO_EXCEPTION); - m_bubble->appendChild(clipper.release(), ASSERT_NO_EXCEPTION); + clipper->appendChild(bubbleArrow); + m_bubble->appendChild(clipper); - RefPtr<HTMLElement> message = HTMLDivElement::create(document); + auto message = HTMLDivElement::create(document); message->setPseudo(AtomicString("-webkit-validation-bubble-message", AtomicString::ConstructFromLiteral)); - RefPtr<HTMLElement> icon = HTMLDivElement::create(document); + auto icon = HTMLDivElement::create(document); icon->setPseudo(AtomicString("-webkit-validation-bubble-icon", AtomicString::ConstructFromLiteral)); - message->appendChild(icon.release(), ASSERT_NO_EXCEPTION); - RefPtr<HTMLElement> textBlock = HTMLDivElement::create(document); + message->appendChild(icon); + auto textBlock = HTMLDivElement::create(document); textBlock->setPseudo(AtomicString("-webkit-validation-bubble-text-block", AtomicString::ConstructFromLiteral)); m_messageHeading = HTMLDivElement::create(document); m_messageHeading->setPseudo(AtomicString("-webkit-validation-bubble-heading", AtomicString::ConstructFromLiteral)); - textBlock->appendChild(m_messageHeading, ASSERT_NO_EXCEPTION); + textBlock->appendChild(*m_messageHeading); m_messageBody = HTMLDivElement::create(document); m_messageBody->setPseudo(AtomicString("-webkit-validation-bubble-body", AtomicString::ConstructFromLiteral)); - textBlock->appendChild(m_messageBody, ASSERT_NO_EXCEPTION); - message->appendChild(textBlock.release(), ASSERT_NO_EXCEPTION); - m_bubble->appendChild(message.release(), ASSERT_NO_EXCEPTION); + textBlock->appendChild(*m_messageBody); + message->appendChild(textBlock); + m_bubble->appendChild(message); setMessageDOMAndStartTimer(); @@ -222,7 +227,7 @@ void ValidationMessage::requestToHideMessage() } // We must not modify the DOM tree in this context by the same reason as setMessage(). - m_timer = adoptPtr(new Timer<ValidationMessage>(this, &ValidationMessage::deleteBubbleTree)); + m_timer = std::make_unique<Timer>(*this, &ValidationMessage::deleteBubbleTree); m_timer->startOneShot(0); } @@ -233,14 +238,14 @@ bool ValidationMessage::shadowTreeContains(const Node& node) const return &m_bubble->treeScope() == &node.treeScope(); } -void ValidationMessage::deleteBubbleTree(Timer<ValidationMessage>*) +void ValidationMessage::deleteBubbleTree() { ASSERT(!validationMessageClient()); if (m_bubble) { - m_messageHeading = 0; - m_messageBody = 0; - m_element->userAgentShadowRoot()->removeChild(m_bubble.get(), ASSERT_NO_EXCEPTION); - m_bubble = 0; + m_messageHeading = nullptr; + m_messageBody = nullptr; + m_element->userAgentShadowRoot()->removeChild(*m_bubble); + m_bubble = nullptr; } m_message = String(); } |