Changeset 172826 in webkit


Ignore:
Timestamp:
Aug 20, 2014 8:33:18 PM (10 years ago)
Author:
benjamin@webkit.org
Message:

CSS: Implement the :placeholder-shown pseudo-class from Selectors Level 4
https://bugs.webkit.org/show_bug.cgi?id=118162

Reviewed by Antti Koivisto.

Source/WebCore:

Previously, HTMLTextFormControlElement was using some mix of its own state
and style to change the visibility of the placeholder. That approach was a little
bit too fragile, and we do not want the style to depends on the renderer() since
that creates circular dependencies.

The biggest change here is refactoring HTMLTextFormControlElement to have
1) An explicit "visible placeholder" state.
2) Separate the textUpdate() from the visibilityUpdate().
3) Remove the dependencies between the Element's style and the placeholder's style.

This is done by simply using display:none; on the placeholder so that its parent's visibility
is irrelevant.

When matching the selector, the style is set as unique since style sharing does not deal with
the changes of HTMLTextFormControlElement.

Tests: fast/css/placeholder-shown-basics.html

fast/selectors/placeholder-shown-long-adjacent-backtracking.html
fast/selectors/placeholder-shown-sibling-style-update.html
fast/selectors/placeholder-shown-style-update.html
fast/selectors/placeholder-shown-with-input-basics.html
fast/selectors/placeholder-shown-with-textarea-basics.html

  • css/CSSSelector.cpp:

(WebCore::CSSSelector::selectorText):
Add the CSS Selector description for CSSOM.

  • css/CSSSelector.h:
  • css/SelectorChecker.cpp:

(WebCore::SelectorChecker::checkOne):

  • css/SelectorCheckerTestFunctions.h:

(WebCore::isPlaceholderShown):

  • css/SelectorPseudoClassAndCompatibilityElementMap.in:
  • css/html.css:

(::-webkit-input-placeholder):
Previously, the display was forced through the UA stylesheet. Since the display is now part
of the placeholder visibility, it is explicitly handled by HTMLTextFormControlElement and
its subclasses.

  • cssjit/SelectorCompiler.cpp:

(WebCore::SelectorCompiler::addPseudoClassType):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
(WebCore::SelectorCompiler::makeUniqueIfNecessaryAndTestIsPlaceholderShown):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementHasPlaceholderShown):

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::parseAttribute):

  • html/HTMLTextAreaElement.cpp:

(WebCore::HTMLTextAreaElement::updateValue):
(WebCore::HTMLTextAreaElement::setValueCommon):
(WebCore::HTMLTextAreaElement::updatePlaceholderText):

  • html/HTMLTextFormControlElement.cpp:

(WebCore::HTMLTextFormControlElement::HTMLTextFormControlElement):
(WebCore::HTMLTextFormControlElement::dispatchFocusEvent):
(WebCore::HTMLTextFormControlElement::dispatchBlurEvent):
(WebCore::HTMLTextFormControlElement::placeholderShouldBeVisible):
(WebCore::HTMLTextFormControlElement::updatePlaceholderVisibility):
(WebCore::HTMLTextFormControlElement::selectionDirection):
(WebCore::HTMLTextFormControlElement::restoreCachedSelection):
(WebCore::HTMLTextFormControlElement::parseAttribute):
(WebCore::HTMLTextFormControlElement::hidePlaceholder):
(WebCore::HTMLTextFormControlElement::showPlaceholderIfNecessary):

  • html/HTMLTextFormControlElement.h:

(WebCore::HTMLTextFormControlElement::isPlaceholderVisible):
(WebCore::HTMLTextFormControlElement::cachedSelectionDirection):

  • html/TextFieldInputType.cpp:

(WebCore::TextFieldInputType::updatePlaceholderText):
(WebCore::TextFieldInputType::subtreeHasChanged):
(WebCore::TextFieldInputType::updateInnerTextValue):

  • rendering/RenderTextControl.cpp:

(WebCore::RenderTextControl::styleDidChange):

  • testing/Internals.cpp:

(WebCore::Internals::visiblePlaceholder):

LayoutTests:

Add basic test coverage for common operations: styling, querySelector, CSSOM.

The layout test failure of placeholder-shown-sibling-style-update.html seems unrelated
to this patch, it fails in many more cases. This will be investigated separately, the failure
are used as expected values for now.

  • fast/css/css-selector-text-expected.txt:
  • fast/css/css-selector-text.html:
  • fast/css/css-set-selector-text-expected.txt:
  • fast/css/css-set-selector-text.html:
  • fast/css/placeholder-shown-basics-expected.html: Added.
  • fast/css/placeholder-shown-basics.html: Added.
  • fast/selectors/placeholder-shown-long-adjacent-backtracking-expected.txt: Added.
  • fast/selectors/placeholder-shown-long-adjacent-backtracking.html: Added.
  • fast/selectors/placeholder-shown-sibling-style-update-expected.txt: Added.
  • fast/selectors/placeholder-shown-sibling-style-update.html: Added.
  • fast/selectors/placeholder-shown-style-update-expected.txt: Added.
  • fast/selectors/placeholder-shown-style-update.html: Added.
  • fast/selectors/placeholder-shown-with-input-basics-expected.txt: Added.
  • fast/selectors/placeholder-shown-with-input-basics.html: Added.
  • fast/selectors/placeholder-shown-with-textarea-basics-expected.txt: Added.
  • fast/selectors/placeholder-shown-with-textarea-basics.html: Added.
Location:
trunk
Files:
12 added
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r172817 r172826  
     12014-08-20  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        CSS: Implement the :placeholder-shown pseudo-class from Selectors Level 4
     4        https://bugs.webkit.org/show_bug.cgi?id=118162
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Add basic test coverage for common operations: styling, querySelector, CSSOM.
     9
     10        The layout test failure of placeholder-shown-sibling-style-update.html seems unrelated
     11        to this patch, it fails in many more cases. This will be investigated separately, the failure
     12        are used as expected values for now.
     13
     14        * fast/css/css-selector-text-expected.txt:
     15        * fast/css/css-selector-text.html:
     16        * fast/css/css-set-selector-text-expected.txt:
     17        * fast/css/css-set-selector-text.html:
     18        * fast/css/placeholder-shown-basics-expected.html: Added.
     19        * fast/css/placeholder-shown-basics.html: Added.
     20        * fast/selectors/placeholder-shown-long-adjacent-backtracking-expected.txt: Added.
     21        * fast/selectors/placeholder-shown-long-adjacent-backtracking.html: Added.
     22        * fast/selectors/placeholder-shown-sibling-style-update-expected.txt: Added.
     23        * fast/selectors/placeholder-shown-sibling-style-update.html: Added.
     24        * fast/selectors/placeholder-shown-style-update-expected.txt: Added.
     25        * fast/selectors/placeholder-shown-style-update.html: Added.
     26        * fast/selectors/placeholder-shown-with-input-basics-expected.txt: Added.
     27        * fast/selectors/placeholder-shown-with-input-basics.html: Added.
     28        * fast/selectors/placeholder-shown-with-textarea-basics-expected.txt: Added.
     29        * fast/selectors/placeholder-shown-with-textarea-basics.html: Added.
     30
    1312014-08-20  Benjamin Poulain  <bpoulain@apple.com>
    232
  • trunk/LayoutTests/fast/css/css-selector-text-expected.txt

    r101998 r172826  
    4141PASS parseThenSerializeRule(':indeterminate { }') is ':indeterminate { }'
    4242PASS parseThenSerializeRule(':link { }') is ':link { }'
     43PASS parseThenSerializeRule(':not(:placeholder-shown) { }') is ':not(:placeholder-shown) { }'
     44PASS parseThenSerializeRule(':placeholder-shown { }') is ':placeholder-shown { }'
    4345PASS parseThenSerializeRule(':root { }') is ':root { }'
    4446PASS parseThenSerializeRule(':target { }') is ':target { }'
  • trunk/LayoutTests/fast/css/css-selector-text.html

    r155263 r172826  
    7272testSelectorRoundTrip(":indeterminate");
    7373testSelectorRoundTrip(":link");
     74testSelectorRoundTrip(":not(:placeholder-shown)");
     75testSelectorRoundTrip(":placeholder-shown");
    7476testSelectorRoundTrip(":root");
    7577testSelectorRoundTrip(":target");
  • trunk/LayoutTests/fast/css/css-set-selector-text-expected.txt

    r101998 r172826  
    5151PASS setThenReadSelectorText(':indeterminate') is ':indeterminate'
    5252PASS setThenReadSelectorText(':link') is ':link'
     53PASS setThenReadSelectorText(':not(:placeholder-shown)') is ':not(:placeholder-shown)'
     54PASS setThenReadSelectorText(':placeholder-shown') is ':placeholder-shown'
    5355PASS setThenReadSelectorText(':root') is ':root'
    5456PASS setThenReadSelectorText(':target') is ':target'
  • trunk/LayoutTests/fast/css/css-set-selector-text.html

    r155263 r172826  
    8989testSelectorRoundTrip(":indeterminate");
    9090testSelectorRoundTrip(":link");
     91testSelectorRoundTrip(":not(:placeholder-shown)");
     92testSelectorRoundTrip(":placeholder-shown");
    9193testSelectorRoundTrip(":root");
    9294testSelectorRoundTrip(":target");
  • trunk/Source/WebCore/ChangeLog

    r172818 r172826  
     12014-08-20  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        CSS: Implement the :placeholder-shown pseudo-class from Selectors Level 4
     4        https://bugs.webkit.org/show_bug.cgi?id=118162
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Previously, HTMLTextFormControlElement was using some mix of its own state
     9        and style to change the visibility of the placeholder. That approach was a little
     10        bit too fragile, and we do not want the style to depends on the renderer() since
     11        that creates circular dependencies.
     12
     13        The biggest change here is refactoring HTMLTextFormControlElement to have
     14        1) An explicit "visible placeholder" state.
     15        2) Separate the textUpdate() from the visibilityUpdate().
     16        3) Remove the dependencies between the Element's style and the placeholder's style.
     17           This is done by simply using display:none; on the placeholder so that its parent's visibility
     18           is irrelevant.
     19
     20        When matching the selector, the style is set as unique since style sharing does not deal with
     21        the changes of HTMLTextFormControlElement.
     22
     23        Tests: fast/css/placeholder-shown-basics.html
     24               fast/selectors/placeholder-shown-long-adjacent-backtracking.html
     25               fast/selectors/placeholder-shown-sibling-style-update.html
     26               fast/selectors/placeholder-shown-style-update.html
     27               fast/selectors/placeholder-shown-with-input-basics.html
     28               fast/selectors/placeholder-shown-with-textarea-basics.html
     29
     30        * css/CSSSelector.cpp:
     31        (WebCore::CSSSelector::selectorText):
     32        Add the CSS Selector description for CSSOM.
     33
     34        * css/CSSSelector.h:
     35        * css/SelectorChecker.cpp:
     36        (WebCore::SelectorChecker::checkOne):
     37        * css/SelectorCheckerTestFunctions.h:
     38        (WebCore::isPlaceholderShown):
     39        * css/SelectorPseudoClassAndCompatibilityElementMap.in:
     40        * css/html.css:
     41        (::-webkit-input-placeholder):
     42        Previously, the display was forced through the UA stylesheet. Since the display is now part
     43        of the placeholder visibility, it is explicitly handled by HTMLTextFormControlElement and
     44        its subclasses.
     45
     46        * cssjit/SelectorCompiler.cpp:
     47        (WebCore::SelectorCompiler::addPseudoClassType):
     48        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
     49        (WebCore::SelectorCompiler::makeUniqueIfNecessaryAndTestIsPlaceholderShown):
     50        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementHasPlaceholderShown):
     51        * html/HTMLInputElement.cpp:
     52        (WebCore::HTMLInputElement::parseAttribute):
     53        * html/HTMLTextAreaElement.cpp:
     54        (WebCore::HTMLTextAreaElement::updateValue):
     55        (WebCore::HTMLTextAreaElement::setValueCommon):
     56        (WebCore::HTMLTextAreaElement::updatePlaceholderText):
     57        * html/HTMLTextFormControlElement.cpp:
     58        (WebCore::HTMLTextFormControlElement::HTMLTextFormControlElement):
     59        (WebCore::HTMLTextFormControlElement::dispatchFocusEvent):
     60        (WebCore::HTMLTextFormControlElement::dispatchBlurEvent):
     61        (WebCore::HTMLTextFormControlElement::placeholderShouldBeVisible):
     62        (WebCore::HTMLTextFormControlElement::updatePlaceholderVisibility):
     63        (WebCore::HTMLTextFormControlElement::selectionDirection):
     64        (WebCore::HTMLTextFormControlElement::restoreCachedSelection):
     65        (WebCore::HTMLTextFormControlElement::parseAttribute):
     66        (WebCore::HTMLTextFormControlElement::hidePlaceholder):
     67        (WebCore::HTMLTextFormControlElement::showPlaceholderIfNecessary):
     68        * html/HTMLTextFormControlElement.h:
     69        (WebCore::HTMLTextFormControlElement::isPlaceholderVisible):
     70        (WebCore::HTMLTextFormControlElement::cachedSelectionDirection):
     71        * html/TextFieldInputType.cpp:
     72        (WebCore::TextFieldInputType::updatePlaceholderText):
     73        (WebCore::TextFieldInputType::subtreeHasChanged):
     74        (WebCore::TextFieldInputType::updateInnerTextValue):
     75        * rendering/RenderTextControl.cpp:
     76        (WebCore::RenderTextControl::styleDidChange):
     77        * testing/Internals.cpp:
     78        (WebCore::Internals::visiblePlaceholder):
     79
    1802014-08-20  Mark Rowe  <mrowe@apple.com>
    281
  • trunk/Source/WebCore/WebCore.exp.in

    r172817 r172826  
    18531853__ZNK7WebCore23FrameLoaderStateMachine23committingFirstRealLoadEv
    18541854__ZNK7WebCore26HTMLTextFormControlElement21lastChangeWasUserEditEv
    1855 __ZNK7WebCore26HTMLTextFormControlElement26placeholderShouldBeVisibleEv
    18561855__ZNK7WebCore26NetscapePlugInStreamLoader6isDoneEv
    18571856__ZNK7WebCore27AuthenticationChallengeBase15failureResponseEv
  • trunk/Source/WebCore/css/CSSSelector.cpp

    r170774 r172826  
    418418                str.appendLiteral(":optional");
    419419                break;
     420#if ENABLE(CSS_SELECTORS_LEVEL4)
     421            case CSSSelector::PseudoClassPlaceholderShown:
     422                str.appendLiteral(":placeholder-shown");
     423                break;
     424#endif
    420425            case CSSSelector::PseudoClassOutOfRange:
    421426                str.appendLiteral(":out-of-range");
     
    462467                str.appendLiteral(":window-inactive");
    463468                break;
    464             default:
     469            case CSSSelector::PseudoClassUnknown:
    465470                ASSERT_NOT_REACHED();
    466471            }
  • trunk/Source/WebCore/css/CSSSelector.h

    r167571 r172826  
    22 * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
    33 *               1999 Waldo Bastian (bastian@kde.org)
    4  * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
     4 * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2013, 2014 Apple Inc. All rights reserved.
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    107107            PseudoClassDisabled,
    108108            PseudoClassOptional,
     109#if ENABLE(CSS_SELECTORS_LEVEL4)
     110            PseudoClassPlaceholderShown,
     111#endif
    109112            PseudoClassRequired,
    110113            PseudoClassReadOnly,
  • trunk/Source/WebCore/css/SelectorChecker.cpp

    r172721 r172826  
    605605            }
    606606            break;
     607#if ENABLE(CSS_SELECTORS_LEVEL4)
     608        case CSSSelector::PseudoClassPlaceholderShown:
     609            if (m_mode == Mode::ResolvingStyle) {
     610                if (RenderStyle* style = context.elementStyle ? context.elementStyle : element->renderStyle())
     611                    style->setUnique();
     612            }
     613            return isPlaceholderShown(element);
     614#endif
    607615        case CSSSelector::PseudoClassNthChild:
    608616            if (!selector->parseNth())
  • trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h

    r172663 r172826  
    115115}
    116116
     117#if ENABLE(CSS_SELECTORS_LEVEL4)
     118ALWAYS_INLINE bool isPlaceholderShown(Element* element)
     119{
     120    if (isHTMLTextFormControlElement(*element))
     121        return toHTMLTextFormControlElement(*element).isPlaceholderVisible();
     122    return false;
     123}
     124#endif
     125
    117126ALWAYS_INLINE bool isRequiredFormControl(const Element* element)
    118127{
  • trunk/Source/WebCore/css/SelectorPseudoClassAndCompatibilityElementMap.in

    r167571 r172826  
    4242optional
    4343out-of-range
     44#if ENABLE(CSS_SELECTORS_LEVEL4)
     45placeholder-shown
     46#endif
    4447read-only
    4548read-write
  • trunk/Source/WebCore/css/html.css

    r172259 r172826  
    612612    -webkit-text-security: none;
    613613    color: darkGray;
    614     display: block !important;
    615614    pointer-events: none !important;
    616615}
  • trunk/Source/WebCore/cssjit/SelectorCompiler.cpp

    r172721 r172826  
    245245    void generateElementIsLastChild(Assembler::JumpList& failureCases, const SelectorFragment&);
    246246    void generateElementIsOnlyChild(Assembler::JumpList& failureCases, const SelectorFragment&);
     247#if ENABLE(CSS_SELECTORS_LEVEL4)
     248    void generateElementHasPlaceholderShown(Assembler::JumpList& failureCases, const SelectorFragment&);
     249#endif
    247250    void generateSynchronizeStyleAttribute(Assembler::RegisterID elementDataArraySizeAndFlags);
    248251    void generateSynchronizeAllAnimatedSVGAttribute(Assembler::RegisterID elementDataArraySizeAndFlags);
     
    537540    case CSSSelector::PseudoClassLastChild:
    538541    case CSSSelector::PseudoClassOnlyChild:
     542#if ENABLE(CSS_SELECTORS_LEVEL4)
     543    case CSSSelector::PseudoClassPlaceholderShown:
     544#endif
    539545        fragment.pseudoClasses.add(type);
    540546        if (selectorContext == SelectorContext::QuerySelector)
     
    19731979    if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassOnlyChild))
    19741980        generateElementIsOnlyChild(matchingPostTagNameFailureCases, fragment);
     1981#if ENABLE(CSS_SELECTORS_LEVEL4)
     1982    if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassPlaceholderShown))
     1983        generateElementHasPlaceholderShown(matchingPostTagNameFailureCases, fragment);
     1984#endif
    19751985    if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassFirstChild))
    19761986        generateElementIsFirstChild(matchingPostTagNameFailureCases, fragment);
     
    27992809}
    28002810
     2811#if ENABLE(CSS_SELECTORS_LEVEL4)
     2812static bool makeUniqueIfNecessaryAndTestIsPlaceholderShown(Element* element, const CheckingContext* checkingContext)
     2813{
     2814    if (checkingContext->resolvingMode == SelectorChecker::Mode::ResolvingStyle) {
     2815        if (RenderStyle* style = element->renderStyle())
     2816            style->setUnique();
     2817    }
     2818    return isPlaceholderShown(element);
     2819}
     2820
     2821void SelectorCodeGenerator::generateElementHasPlaceholderShown(Assembler::JumpList& failureCases, const SelectorFragment& fragment)
     2822{
     2823    if (m_selectorContext == SelectorContext::QuerySelector) {
     2824        FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
     2825        functionCall.setFunctionAddress(isPlaceholderShown);
     2826        functionCall.setOneArgument(elementAddressRegister);
     2827        failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
     2828        return;
     2829    }
     2830
     2831    if (fragmentMatchesTheRightmostElement(m_selectorContext, fragment)) {
     2832        {
     2833            LocalRegister checkingContext(m_registerAllocator);
     2834            Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext);
     2835            addFlagsToElementStyleFromContext(checkingContext, RenderStyle::NonInheritedFlags::flagIsUnique());
     2836            notResolvingStyle.link(&m_assembler);
     2837        }
     2838
     2839        FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
     2840        functionCall.setFunctionAddress(isPlaceholderShown);
     2841        functionCall.setOneArgument(elementAddressRegister);
     2842        failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
     2843    } else {
     2844        Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegisterWithPreference(JSC::GPRInfo::argumentGPR1);
     2845        loadCheckingContext(checkingContext);
     2846        m_registerAllocator.deallocateRegister(checkingContext);
     2847
     2848        FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
     2849        functionCall.setFunctionAddress(makeUniqueIfNecessaryAndTestIsPlaceholderShown);
     2850        functionCall.setTwoArguments(elementAddressRegister, checkingContext);
     2851        failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
     2852    }
     2853}
     2854#endif
     2855
    28012856inline void SelectorCodeGenerator::generateElementHasTagName(Assembler::JumpList& failureCases, const QualifiedName& nameToMatch)
    28022857{
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r172817 r172826  
    637637        // We only need to setChanged if the form is looking at the default value right now.
    638638        if (!hasDirtyValue()) {
    639             updatePlaceholderVisibility(false);
     639            updatePlaceholderVisibility();
    640640            setNeedsStyleRecalc();
    641641        }
  • trunk/Source/WebCore/html/HTMLTextAreaElement.cpp

    r170774 r172826  
    33 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2001 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
     5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2014 Apple Inc. All rights reserved.
    66 *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    77 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
     
    346346    m_isDirty = true;
    347347    m_wasModifiedByUser = true;
    348     const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility(false);
     348    const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility();
    349349}
    350350
     
    386386    setInnerTextValue(m_value);
    387387    setLastChangeWasNotUserEdit();
    388     updatePlaceholderVisibility(false);
     388    updatePlaceholderVisibility();
    389389    setNeedsStyleRecalc();
    390390    setFormControlValueMatchesRenderer(true);
     
    540540        m_placeholder = placeholder.get();
    541541        m_placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
     542        m_placeholder->setInlineStyleProperty(CSSPropertyDisplay, isPlaceholderVisible() ? CSSValueBlock : CSSValueNone, true);
    542543        userAgentShadowRoot()->insertBefore(m_placeholder, innerTextElement()->nextSibling());
    543544    }
  • trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp

    r172817 r172826  
    33 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2001 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     5 * Copyright (C) 2004, 2005, 2006, 2007, 2014 Apple Inc. All rights reserved.
    66 *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    77 *
     
    3939#include "HTMLNames.h"
    4040#include "NodeTraversal.h"
     41#include "Page.h"
    4142#include "RenderBlockFlow.h"
    4243#include "RenderTextControlSingleLine.h"
     
    5657HTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
    5758    : HTMLFormControlElementWithState(tagName, document, form)
    58     , m_lastChangeWasUserEdit(false)
    5959    , m_cachedSelectionStart(-1)
    6060    , m_cachedSelectionEnd(-1)
    6161    , m_cachedSelectionDirection(SelectionHasNoDirection)
     62    , m_lastChangeWasUserEdit(false)
     63    , m_isPlaceholderVisible(false)
    6264{
    6365}
     
    8991{
    9092    if (supportsPlaceholder())
    91         updatePlaceholderVisibility(false);
     93        updatePlaceholderVisibility();
    9294    handleFocusEvent(oldFocusedElement.get(), direction);
    9395    HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, direction);
     
    9799{
    98100    if (supportsPlaceholder())
    99         updatePlaceholderVisibility(false);
     101        updatePlaceholderVisibility();
    100102    handleBlurEvent();
    101103    HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement);
     
    148150bool HTMLTextFormControlElement::placeholderShouldBeVisible() const
    149151{
     152    // This function is used by the style resolver to match the :placeholder-shown pseudo class.
     153    // Since it is used for styling, it must not use any value depending on the style.
    150154    return supportsPlaceholder()
    151155        && isEmptyValue()
    152156        && !isPlaceholderEmpty()
    153         && (document().focusedElement() != this || (renderer() && renderer()->theme().shouldShowPlaceholderWhenFocused()))
    154         && (!renderer() || renderer()->style().visibility() == VISIBLE);
    155 }
    156 
    157 void HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderValueChanged)
    158 {
    159     if (!supportsPlaceholder())
     157        && (document().focusedElement() != this || (document().page()->theme().shouldShowPlaceholderWhenFocused()));
     158}
     159
     160void HTMLTextFormControlElement::updatePlaceholderVisibility()
     161{
     162    bool placeHolderWasVisible = m_isPlaceholderVisible;
     163    m_isPlaceholderVisible = placeholderShouldBeVisible();
     164
     165    if (placeHolderWasVisible == m_isPlaceholderVisible)
    160166        return;
    161     if (!placeholderElement() || placeholderValueChanged)
    162         updatePlaceholderText();
    163     HTMLElement* placeholder = placeholderElement();
    164     if (!placeholder)
    165         return;
    166     placeholder->setInlineStyleProperty(CSSPropertyVisibility, placeholderShouldBeVisible() ? CSSValueVisible : CSSValueHidden);
     167
     168    setNeedsStyleRecalc();
     169
     170    if (HTMLElement* placeholder = placeholderElement())
     171        placeholder->setInlineStyleProperty(CSSPropertyDisplay, m_isPlaceholderVisible ? CSSValueBlock : CSSValueNone, true);
    167172}
    168173
     
    397402        return directionString(SelectionHasNoDirection);
    398403    if (document().focusedElement() != this && hasCachedSelection())
    399         return directionString(m_cachedSelectionDirection);
     404        return directionString(cachedSelectionDirection());
    400405
    401406    return directionString(computeSelectionDirection());
     
    467472void HTMLTextFormControlElement::restoreCachedSelection()
    468473{
    469     setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSelectionDirection);
     474    setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, cachedSelectionDirection());
    470475}
    471476
     
    485490void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
    486491{
    487     if (name == placeholderAttr)
    488         updatePlaceholderVisibility(true);
    489     else
     492    if (name == placeholderAttr) {
     493        updatePlaceholderText();
     494        updatePlaceholderVisibility();
     495    } else
    490496        HTMLFormControlElementWithState::parseAttribute(name, value);
    491497}
     
    627633void HTMLTextFormControlElement::hidePlaceholder()
    628634{
    629     if (!supportsPlaceholder())
    630         return;
    631     HTMLElement* placeholder = placeholderElement();
    632     if (!placeholder) {
    633         updatePlaceholderText();
    634         return;
    635     }
    636     placeholder->setInlineStyleProperty(CSSPropertyVisibility, ASCIILiteral("hidden"));
     635    if (HTMLElement* placeholder = placeholderElement())
     636        placeholder->setInlineStyleProperty(CSSPropertyVisibility, CSSValueHidden, true);
    637637}
    638638
    639639void HTMLTextFormControlElement::showPlaceholderIfNecessary()
    640640{
    641     updatePlaceholderVisibility(false);
     641    if (HTMLElement* placeholder = placeholderElement())
     642        placeholder->setInlineStyleProperty(CSSPropertyVisibility, CSSValueVisible, true);
    642643}
    643644#endif
  • trunk/Source/WebCore/html/HTMLTextFormControlElement.h

    r172817 r172826  
    33 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2000 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
    66 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved.
    77 *
     
    5151
    5252    // The derived class should return true if placeholder processing is needed.
     53    bool isPlaceholderVisible() const { return m_isPlaceholderVisible; }
    5354    virtual bool supportsPlaceholder() const = 0;
    5455    String strippedPlaceholder() const;
    55     bool placeholderShouldBeVisible() const;
    5656    virtual HTMLElement* placeholderElement() const = 0;
    57     void updatePlaceholderVisibility(bool);
     57    void updatePlaceholderVisibility();
    5858
    5959    int indexForVisiblePosition(const VisiblePosition&) const;
     
    121121
    122122private:
     123    TextFieldSelectionDirection cachedSelectionDirection() const { return static_cast<TextFieldSelectionDirection>(m_cachedSelectionDirection); }
     124
    123125    int computeSelectionStart() const;
    124126    int computeSelectionEnd() const;
     
    138140    virtual void handleBlurEvent() { }
    139141
     142    bool placeholderShouldBeVisible() const;
     143
    140144    String m_textAsOfLastFormControlChangeEvent;
    141     bool m_lastChangeWasUserEdit;
    142    
     145
    143146    int m_cachedSelectionStart;
    144147    int m_cachedSelectionEnd;
    145     TextFieldSelectionDirection m_cachedSelectionDirection;
     148
     149    unsigned char m_cachedSelectionDirection : 2;
     150    unsigned char m_lastChangeWasUserEdit : 1;
     151    unsigned char m_isPlaceholderVisible : 1;
    146152};
    147153
  • trunk/Source/WebCore/html/TextFieldInputType.cpp

    r172817 r172826  
    11/*
    22 * Copyright (C) 2010 Google Inc. All rights reserved.
    3  * Copyright (C) 2011 Apple Inc. All rights reserved.
     3 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    410410        m_placeholder = HTMLDivElement::create(element().document());
    411411        m_placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
     412        m_placeholder->setInlineStyleProperty(CSSPropertyDisplay, element().isPlaceholderVisible() ? CSSValueBlock : CSSValueNone, true);
    412413        element().userAgentShadowRoot()->insertBefore(m_placeholder, m_container ? m_container.get() : innerTextElement(), ASSERT_NO_EXCEPTION);
    413414    }
     
    439440    // sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent.
    440441    element().setValueFromRenderer(sanitizeValue(convertFromVisibleValue(element().innerTextValue())));
    441     element().updatePlaceholderVisibility(false);
     442    element().updatePlaceholderVisibility();
    442443    // Recalc for :invalid change.
    443444    element().setNeedsStyleRecalc();
     
    473474        // It protects an unacceptable renderer value from being overwritten with the DOM value.
    474475        element().setInnerTextValue(visibleValue());
    475         element().updatePlaceholderVisibility(false);
     476        element().updatePlaceholderVisibility();
    476477    }
    477478}
  • trunk/Source/WebCore/rendering/RenderTextControl.cpp

    r170774 r172826  
    11/**
    2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2014 Apple Inc. All rights reserved.
    33 *           (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 
    44 *
     
    7171        innerTextRenderer->setStyle(createInnerTextStyle(&style()));
    7272    }
    73     textFormControlElement().updatePlaceholderVisibility(false);
     73    textFormControlElement().updatePlaceholderVisibility();
    7474}
    7575
  • trunk/Source/WebCore/testing/Internals.cpp

    r172817 r172826  
    11/*
    22 * Copyright (C) 2012 Google Inc. All rights reserved.
    3  * Copyright (C) 2013 Apple Inc. All rights reserved.
     3 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    618618{
    619619    if (element && isHTMLTextFormControlElement(*element)) {
    620         if (toHTMLTextFormControlElement(*element).placeholderShouldBeVisible())
    621             return toHTMLTextFormControlElement(*element).placeholderElement()->textContent();
     620        const HTMLTextFormControlElement& textFormControlElement = toHTMLTextFormControlElement(*element);
     621        if (!textFormControlElement.isPlaceholderVisible())
     622            return String();
     623        if (HTMLElement* placeholderElement = textFormControlElement.placeholderElement())
     624            return placeholderElement->textContent();
    622625    }
    623626
  • trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in

    r172817 r172826  
    263263        symbolWithPointer(?pageNumberForElement@PrintContext@WebCore@@SAHPAVElement@2@ABVFloatSize@2@@Z, ?pageNumberForElement@PrintContext@WebCore@@SAHPEAVElement@2@AEBVFloatSize@2@@Z)
    264264        symbolWithPointer(?paintControlTints@FrameView@WebCore@@AAEXXZ, ?paintControlTints@FrameView@WebCore@@AEAAXXZ)
    265         symbolWithPointer(?placeholderShouldBeVisible@HTMLTextFormControlElement@WebCore@@QBE_NXZ, ?placeholderShouldBeVisible@HTMLTextFormControlElement@WebCore@@QEBA_NXZ)
    266265        symbolWithPointer(?rangeFromLocationAndLength@TextIterator@WebCore@@SA?AV?$PassRefPtr@VRange@WebCore@@@WTF@@PAVContainerNode@2@HH_N@Z, ?rangeFromLocationAndLength@TextIterator@WebCore@@SA?AV?$PassRefPtr@VRange@WebCore@@@WTF@@PEAVContainerNode@2@HH_N@Z)
    267266        symbolWithPointer(?rectBasedTestResult@HitTestResult@WebCore@@QBEABV?$ListHashSet@V?$RefPtr@VNode@WebCore@@@WTF@@$0BAA@U?$PtrHash@V?$RefPtr@VNode@WebCore@@@WTF@@@2@@WTF@@XZ, ?rectBasedTestResult@HitTestResult@WebCore@@QEBAAEBV?$ListHashSet@V?$RefPtr@VNode@WebCore@@@WTF@@$0BAA@U?$PtrHash@V?$RefPtr@VNode@WebCore@@@WTF@@@2@@WTF@@XZ)
Note: See TracChangeset for help on using the changeset viewer.