⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 197637 in webkit


Ignore:
Timestamp:
Mar 6, 2016, 2:17:52 AM (11 years ago)
Author:
Antti Koivisto
Message:

RenderTextControlSingleLine shouldn't mutate placeholder element inline style
​https://bugs.webkit.org/show_bug.cgi?id=155086

Reviewed by Andreas Kling.

Text field placeholder element is currently managed by changing its inline style
from the host renderer based on the host style and state. Rendering poking
into DOM is wrong.

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::setRangeText):
(WebCore::HTMLInputElement::shouldTruncateText):

Add a helper.

(WebCore::HTMLInputElement::createInnerTextStyle):

  • html/HTMLInputElement.h:
  • html/HTMLTextAreaElement.cpp:

(WebCore::HTMLTextAreaElement::HTMLTextAreaElement):
(WebCore::HTMLTextAreaElement::placeholderElement):
(WebCore::HTMLTextAreaElement::matchesReadWritePseudoClass):
(WebCore::HTMLTextAreaElement::updatePlaceholderText):

Use the new shadow element.

  • html/HTMLTextAreaElement.h:
  • html/HTMLTextFormControlElement.cpp:

(WebCore::HTMLTextFormControlElement::updatePlaceholderVisibility):

No more poking to inline style.

(WebCore::HTMLTextFormControlElement::setSelectionStart):

  • html/TextFieldInputType.cpp:

(WebCore::TextFieldInputType::updatePlaceholderText):

Use the new shadow element.

  • html/shadow/TextControlInnerElements.cpp:

(WebCore::TextControlPlaceholderElement::TextControlPlaceholderElement):

Add a subclass for the placeholder element instead of just using div.

(WebCore::TextControlPlaceholderElement::customStyleForRenderer):

Compute style base on the host state and style.

(WebCore::SearchFieldResultsButtonElement::SearchFieldResultsButtonElement):

  • html/shadow/TextControlInnerElements.h:
  • rendering/RenderTextControlSingleLine.cpp:

(WebCore::RenderTextControlSingleLine::styleDidChange):

No more setInlineStyleProperty.
This now needs to trigger layout like it does with other inner elements.

(WebCore::RenderTextControlSingleLine::computeControlLogicalHeight):
(WebCore::RenderTextControlSingleLine::autoscroll):
(WebCore::RenderTextControlSingleLine::textShouldBeTruncated): Deleted.

  • rendering/RenderTextControlSingleLine.h:
Location:
trunk/Source/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r197634 r197637  
     12016-03-06  Antti Koivisto  <antti@apple.com>
     2
     3        RenderTextControlSingleLine shouldn't mutate placeholder element inline style
     4        https://bugs.webkit.org/show_bug.cgi?id=155086
     5
     6        Reviewed by Andreas Kling.
     7
     8        Text field placeholder element is currently managed by changing its inline style
     9        from the host renderer based on the host style and state. Rendering poking
     10        into DOM is wrong.
     11
     12        * html/HTMLInputElement.cpp:
     13        (WebCore::HTMLInputElement::setRangeText):
     14        (WebCore::HTMLInputElement::shouldTruncateText):
     15
     16            Add a helper.
     17
     18        (WebCore::HTMLInputElement::createInnerTextStyle):
     19        * html/HTMLInputElement.h:
     20        * html/HTMLTextAreaElement.cpp:
     21        (WebCore::HTMLTextAreaElement::HTMLTextAreaElement):
     22        (WebCore::HTMLTextAreaElement::placeholderElement):
     23        (WebCore::HTMLTextAreaElement::matchesReadWritePseudoClass):
     24        (WebCore::HTMLTextAreaElement::updatePlaceholderText):
     25
     26            Use the new shadow element.
     27
     28        * html/HTMLTextAreaElement.h:
     29        * html/HTMLTextFormControlElement.cpp:
     30        (WebCore::HTMLTextFormControlElement::updatePlaceholderVisibility):
     31
     32            No more poking to inline style.
     33
     34        (WebCore::HTMLTextFormControlElement::setSelectionStart):
     35        * html/TextFieldInputType.cpp:
     36        (WebCore::TextFieldInputType::updatePlaceholderText):
     37
     38            Use the new shadow element.
     39
     40        * html/shadow/TextControlInnerElements.cpp:
     41        (WebCore::TextControlPlaceholderElement::TextControlPlaceholderElement):
     42
     43            Add a subclass for the placeholder element instead of just using div.
     44
     45        (WebCore::TextControlPlaceholderElement::customStyleForRenderer):
     46
     47            Compute style base on the host state and style.
     48
     49        (WebCore::SearchFieldResultsButtonElement::SearchFieldResultsButtonElement):
     50        * html/shadow/TextControlInnerElements.h:
     51        * rendering/RenderTextControlSingleLine.cpp:
     52        (WebCore::RenderTextControlSingleLine::styleDidChange):
     53
     54            No more setInlineStyleProperty.
     55            This now needs to trigger layout like it does with other inner elements.
     56
     57        (WebCore::RenderTextControlSingleLine::computeControlLogicalHeight):
     58        (WebCore::RenderTextControlSingleLine::autoscroll):
     59        (WebCore::RenderTextControlSingleLine::textShouldBeTruncated): Deleted.
     60        * rendering/RenderTextControlSingleLine.h:
     61
    1622016-03-05  Ryosuke Niwa  <rniwa@webkit.org>
    263
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r197563 r197637  
    18601860}
    18611861
     1862bool HTMLInputElement::shouldTruncateText(const RenderStyle& style) const
     1863{
     1864    if (!isTextField())
     1865        return false;
     1866    return document().focusedElement() != this && style.textOverflow() == TextOverflowEllipsis;
     1867}
     1868
    18621869Ref<RenderStyle> HTMLInputElement::createInnerTextStyle(const RenderStyle& style) const
    18631870{
    … …  
    18701877    textBlockStyle.get().setOverflowX(OHIDDEN);
    18711878    textBlockStyle.get().setOverflowY(OHIDDEN);
    1872 
    1873     bool textShouldBeTruncated = document().focusedElement() != this && style.textOverflow() == TextOverflowEllipsis;
    1874     textBlockStyle.get().setTextOverflow(textShouldBeTruncated ? TextOverflowEllipsis : TextOverflowClip);
     1879    textBlockStyle.get().setTextOverflow(shouldTruncateText(style) ? TextOverflowEllipsis : TextOverflowClip);
    18751880
    18761881    // Do not allow line-height to be smaller than our default.
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r197566 r197637  
    322322    void capsLockStateMayHaveChanged();
    323323
     324    bool shouldTruncateText(const RenderStyle&) const;
     325
    324326protected:
    325327    HTMLInputElement(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
  • trunk/Source/WebCore/html/HTMLTextAreaElement.cpp

    r197458 r197637  
    9393    , m_rows(defaultRows)
    9494    , m_cols(defaultCols)
    95     , m_wrap(SoftWrap)
    96     , m_placeholder(0)
    97     , m_isDirty(false)
    98     , m_wasModifiedByUser(false)
    9995{
    10096    ASSERT(hasTagName(textareaTag));
    … …  
    498494HTMLElement* HTMLTextAreaElement::placeholderElement() const
    499495{
    500     return m_placeholder;
     496    return m_placeholder.get();
    501497}
    502498
    … …  
    517513    }
    518514    if (!m_placeholder) {
    519         RefPtr<HTMLDivElement> placeholder = HTMLDivElement::create(document());
    520         m_placeholder = placeholder.get();
    521         m_placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
    522         m_placeholder->setInlineStyleProperty(CSSPropertyDisplay, isPlaceholderVisible() ? CSSValueBlock : CSSValueNone, true);
     515        m_placeholder = TextControlPlaceholderElement::create(document());
    523516        userAgentShadowRoot()->insertBefore(*m_placeholder, innerTextElement()->nextSibling());
    524517    }
  • trunk/Source/WebCore/html/HTMLTextAreaElement.h

    r197566 r197637  
    125125    unsigned m_cols;
    126126    int m_maxLength { -1 };
    127     WrapMethod m_wrap;
    128     HTMLElement* m_placeholder;
     127    WrapMethod m_wrap { SoftWrap };
     128    RefPtr<HTMLElement> m_placeholder;
    129129    mutable String m_value;
    130     mutable bool m_isDirty;
    131     mutable bool m_wasModifiedByUser;
     130    mutable bool m_isDirty { false };
     131    mutable bool m_wasModifiedByUser { false };
    132132};
    133133
  • trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp

    r197458 r197637  
    165165
    166166    setNeedsStyleRecalc();
    167 
    168     if (HTMLElement* placeholder = placeholderElement())
    169         placeholder->setInlineStyleProperty(CSSPropertyDisplay, m_isPlaceholderVisible ? CSSValueBlock : CSSValueNone, true);
    170167}
    171168
  • trunk/Source/WebCore/html/TextFieldInputType.cpp

    r197458 r197637  
    495495    }
    496496    if (!m_placeholder) {
    497         m_placeholder = HTMLDivElement::create(element().document());
    498         m_placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
    499         m_placeholder->setInlineStyleProperty(CSSPropertyDisplay, element().isPlaceholderVisible() ? CSSValueBlock : CSSValueNone, true);
    500         element().userAgentShadowRoot()->insertBefore(*m_placeholder, m_container ? m_container.get() : innerTextElement(), ASSERT_NO_EXCEPTION);
    501        
     497        m_placeholder = TextControlPlaceholderElement::create(element().document());
     498        element().userAgentShadowRoot()->insertBefore(*m_placeholder, m_container ? m_container.get() : innerTextElement(), ASSERT_NO_EXCEPTION);       
    502499    }
    503500    m_placeholder->setInnerText(placeholderText, ASSERT_NO_EXCEPTION);
  • trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp

    r197401 r197637  
    4040#include "RenderView.h"
    4141#include "ScriptController.h"
     42#include "ShadowRoot.h"
    4243#include "TextEvent.h"
    4344#include "TextEventInputType.h"
    … …  
    140141// ----------------------------
    141142
     143TextControlPlaceholderElement::TextControlPlaceholderElement(Document& document)
     144    : HTMLDivElement(divTag, document)
     145{
     146    setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
     147    setHasCustomStyleResolveCallbacks();
     148}
     149
     150RefPtr<RenderStyle> TextControlPlaceholderElement::customStyleForRenderer(RenderStyle& parentStyle, RenderStyle* shadowHostStyle)
     151{
     152    auto style = resolveStyle(&parentStyle);
     153
     154    auto& controlElement = downcast<HTMLTextFormControlElement>(*containingShadowRoot()->host());
     155    style->setDisplay(controlElement.isPlaceholderVisible() ? BLOCK : NONE);
     156
     157    if (is<HTMLInputElement>(controlElement)) {
     158        auto& inputElement = downcast<HTMLInputElement>(controlElement);
     159        style->setTextOverflow(inputElement.shouldTruncateText(*shadowHostStyle) ? TextOverflowEllipsis : TextOverflowClip);
     160    }
     161
     162    return WTFMove(style);
     163}
     164
     165// ----------------------------
     166
    142167inline SearchFieldResultsButtonElement::SearchFieldResultsButtonElement(Document& document)
    143168    : HTMLDivElement(divTag, document)
  • trunk/Source/WebCore/html/shadow/TextControlInnerElements.h

    r197563 r197637  
    7171};
    7272
     73class TextControlPlaceholderElement final : public HTMLDivElement {
     74public:
     75    static Ref<TextControlPlaceholderElement> create(Document& document) { return adoptRef(*new TextControlPlaceholderElement(document)); }
     76
     77private:
     78    TextControlPlaceholderElement(Document&);
     79   
     80    RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle, RenderStyle* shadowHostStyle) override;
     81};
     82
    7383class SearchFieldResultsButtonElement final : public HTMLDivElement {
    7484public:
  • trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp

    r197401 r197637  
    246246        containerRenderer->style().setWidth(Length());
    247247    }
    248     RenderTextControlInnerBlock* innerTextRenderer = innerTextElement()->renderer();
    249     if (innerTextRenderer && diff == StyleDifferenceLayout)
    250         innerTextRenderer->setNeedsLayout(MarkContainingBlockChain);
    251     if (HTMLElement* placeholder = inputElement().placeholderElement())
    252         placeholder->setInlineStyleProperty(CSSPropertyTextOverflow, textShouldBeTruncated() ? CSSValueEllipsis : CSSValueClip);
     248    if (diff == StyleDifferenceLayout) {
     249        if (auto* innerTextRenderer = innerTextElement()->renderer())
     250            innerTextRenderer->setNeedsLayout(MarkContainingBlockChain);
     251        if (auto* placeholder = inputElement().placeholderElement()) {
     252            if (placeholder->renderer())
     253                placeholder->renderer()->setNeedsLayout(MarkContainingBlockChain);
     254        }
     255    }
    253256    setHasOverflowClip(false);
    254257}
    … …  
    322325}
    323326
    324 bool RenderTextControlSingleLine::textShouldBeTruncated() const
    325 {
    326     return document().focusedElement() != &inputElement() && style().textOverflow() == TextOverflowEllipsis;
    327 }
    328 
    329327void RenderTextControlSingleLine::autoscroll(const IntPoint& position)
    330328{
  • trunk/Source/WebCore/rendering/RenderTextControlSingleLine.h

    r197566 r197637  
    7474    void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
    7575
    76     bool textShouldBeTruncated() const;
    77 
    7876    HTMLElement* innerSpinButtonElement() const;
    7977};
Note: See TracChangeset for help on using the changeset viewer.