Changeset 18877 in webkit


Ignore:
Timestamp:
Jan 15, 2007, 8:43:39 PM (18 years ago)
Author:
darin
Message:

LayoutTests:

  • fast/forms/placeholder-set-attribute-expected.checksum: Added.
  • fast/forms/placeholder-set-attribute-expected.png: Added.
  • fast/forms/placeholder-set-attribute-expected.txt: Added.
  • fast/forms/placeholder-set-attribute.html: Added.

WebCore:

Reviewed by Adam.

Test: fast/forms/placeholder-set-attribute.html

  • html/HTMLTextFieldInnerElement.cpp: (WebCore::HTMLSearchFieldCancelButtonElement::defaultEventHandler): Call onSearch on the element since I removed it from the renderer.
  • rendering/RenderTextControl.h: Added explicit virtual keywords for overrides of virtual functions. Removed the unneeded onSearch function. Made the inheritance from PopupMenuClient be private, and made the overrides all private. Replaced the showPlaceholderIfNeeded and hidePlaceholderIfNeeded functions with updatePlaceholder.
  • rendering/RenderTextControl.cpp: (WebCore::RenderTextControl::createResultsButtonStyle): Added an assertion. (WebCore::RenderTextControl::updatePlaceholder): Added. Replaces the two functions, showPlaceholderIfNeeded and hidePlaceholderIfNeeded. (WebCore::RenderTextControl::updateFromElement): Added call to updatePlaceholder before updating the value. Also improved the structure of the function and corrected incorrect use of copy and replace. (WebCore::RenderTextControl::updateCancelButtonVisibility): Added an assertion and removed an unneeded local variable. (WebCore::RenderTextControl::subtreeHasChanged): Removed an unneeded null check and virtual function calls. (WebCore::RenderTextControl::forwardEvent): Replaced calls to the old functions with calls to updatePlaceholder. (WebCore::RenderTextControl::selectionChanged): Changed code to dispatch the select event directly -- I plan to remove the onSelect function, which was only called here. (WebCore::RenderTextControl::autosaveName): Removed too-specific cast and local variable. (WebCore::RenderTextControl::addSearchResult): Added assertion and changed variable name for clarity. (WebCore::RenderTextControl::valueChanged): Changed code to check for empty autosave name instead of null for consistency with other call sites that manage the autosave name. Also changed the code that dispatches an event to call onSearch on the input element so we don't need our own function.
Location:
trunk
Files:
4 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r18875 r18877  
     12007-01-15  Darin Adler  <darin@apple.com>
     2
     3        - test for http://bugs.webkit.org/show_bug.cgi?id=12190
     4          REGRESSION: Placeholder text does not reflect dynamic updates
     5
     6        * fast/forms/placeholder-set-attribute-expected.checksum: Added.
     7        * fast/forms/placeholder-set-attribute-expected.png: Added.
     8        * fast/forms/placeholder-set-attribute-expected.txt: Added.
     9        * fast/forms/placeholder-set-attribute.html: Added.
     10
    1112007-01-15  Justin Garcia  <justin.garcia@apple.com>
    212
  • trunk/WebCore/ChangeLog

    r18876 r18877  
     12007-01-15  Darin Adler  <darin@apple.com>
     2
     3        Reviewed by Adam.
     4
     5        - fix http://bugs.webkit.org/show_bug.cgi?id=12190
     6          REGRESSION: Placeholder text does not reflect dynamic updates
     7
     8        Test: fast/forms/placeholder-set-attribute.html
     9
     10        * html/HTMLTextFieldInnerElement.cpp:
     11        (WebCore::HTMLSearchFieldCancelButtonElement::defaultEventHandler):
     12        Call onSearch on the element since I removed it from the renderer.
     13
     14        * rendering/RenderTextControl.h: Added explicit virtual keywords for overrides
     15        of virtual functions. Removed the unneeded onSearch function. Made the inheritance
     16        from PopupMenuClient be private, and made the overrides all private. Replaced the
     17        showPlaceholderIfNeeded and hidePlaceholderIfNeeded functions with updatePlaceholder.
     18        * rendering/RenderTextControl.cpp:
     19        (WebCore::RenderTextControl::createResultsButtonStyle): Added an assertion.
     20        (WebCore::RenderTextControl::updatePlaceholder): Added. Replaces the two
     21        functions, showPlaceholderIfNeeded and hidePlaceholderIfNeeded.
     22        (WebCore::RenderTextControl::updateFromElement): Added call to
     23        updatePlaceholder before updating the value. Also improved the structure
     24        of the function and corrected incorrect use of copy and replace.
     25        (WebCore::RenderTextControl::updateCancelButtonVisibility): Added an
     26        assertion and removed an unneeded local variable.
     27        (WebCore::RenderTextControl::subtreeHasChanged): Removed an unneeded
     28        null check and virtual function calls.
     29        (WebCore::RenderTextControl::forwardEvent): Replaced calls to the old
     30        functions with calls to updatePlaceholder.
     31        (WebCore::RenderTextControl::selectionChanged): Changed code to dispatch
     32        the select event directly -- I plan to remove the onSelect function, which
     33        was only called here.
     34        (WebCore::RenderTextControl::autosaveName): Removed too-specific cast and
     35        local variable.
     36        (WebCore::RenderTextControl::addSearchResult): Added assertion and changed
     37        variable name for clarity.
     38        (WebCore::RenderTextControl::valueChanged): Changed code to check for empty
     39        autosave name instead of null for consistency with other call sites that
     40        manage the autosave name. Also changed the code that dispatches an event
     41        to call onSearch on the input element so we don't need our own function.
     42
     432007-01-15  Lars Naesbye Christensen  <larsnaesbye@stud.ku.dk>
     44
     45        Reviewed by Darin.
     46
     47        - http://bugs.webkit.org/show_bug.cgi?id=11112
     48          add a drop shadow to the hand cursor used for links
     49
     50        * Resources/linkCursor.png: Added a drop shadow.
     51
    1522007-01-15  Eric Seidel  <eric@webkit.org>
    253
     
    10661117        (WebCore::RenderObject::setStyle):
    10671118
     1119>>>>>>> .r18876
    106811202007-01-13  Lars Knoll <lars@trolltech.com>
    10691121
  • trunk/WebCore/html/HTMLTextFieldInnerElement.cpp

    r18252 r18877  
    102102    } else if (evt->type() == mouseupEvent) {
    103103        if (renderer() && renderer()->style()->visibility() == VISIBLE) {
    104             input->setValue(String(""));
    105             static_cast<RenderTextControl*>(input->renderer())->onSearch();
     104            input->setValue("");
     105            input->onSearch();
    106106            evt->setDefaultHandled();
    107107        }
  • trunk/WebCore/rendering/RenderTextControl.cpp

    r18824 r18877  
    11/**
    2  * Copyright (C) 2006 Apple Computer, Inc.
     2 * Copyright (C) 2006, 2007 Apple Inc.
    33 *
    44 * This library is free software; you can redistribute it and/or
     
    174174RenderStyle* RenderTextControl::createResultsButtonStyle(RenderStyle* startStyle)
    175175{
     176    ASSERT(!m_multiLine);
    176177    HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    177178    RenderStyle* resultsBlockStyle;
     
    210211}
    211212
    212 void RenderTextControl::showPlaceholderIfNeeded()
    213 {
    214     if (m_multiLine)
    215         return;
    216 
    217     String value = static_cast<HTMLInputElement*>(node())->value().copy();
    218     String placeholder = static_cast<HTMLInputElement*>(node())->getAttribute(placeholderAttr);
    219 
    220     if (!value.isEmpty() || placeholder.isEmpty())
    221         return;
    222 
    223     if (document()->focusedNode() == node())
    224         return;
    225 
    226     m_placeholderVisible = true;
    227     ExceptionCode ec = 0;
    228     m_innerText->setInnerText(placeholder, ec);
    229     Color placeholderColor(128, 128, 128);
    230     m_innerText->renderer()->style()->setColor(placeholderColor);
    231     m_innerText->renderer()->repaint();
    232 }
    233 
    234 void RenderTextControl::hidePlaceholderIfNeeded()
    235 {
    236     if (!m_placeholderVisible)
    237         return;
    238 
    239     m_placeholderVisible = false;
    240     m_innerText->removeChildren();
    241     if (node()->isEnabled())
    242         m_innerText->renderer()->style()->setColor(style()->color());
     213void RenderTextControl::updatePlaceholder()
     214{
     215    String placeholder;
     216    if (!m_multiLine) {
     217        HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
     218        if (input->value().isEmpty() && document()->focusedNode() != node())
     219            placeholder = input->getAttribute(placeholderAttr);
     220    }
     221
     222    if (!placeholder.isEmpty() || m_placeholderVisible) {
     223        ExceptionCode ec = 0;
     224        m_innerText->setInnerText(placeholder, ec);
     225        m_placeholderVisible = !placeholder.isEmpty();
     226    }
     227
     228    Color color;
     229    if (!placeholder.isEmpty())
     230        color = Color::darkGray;
     231    else if (node()->isEnabled())
     232        color = style()->color();
    243233    else
    244         m_innerText->renderer()->style()->setColor(disabledTextColor(style()->color(), style()->backgroundColor()));
    245 
    246     m_innerText->renderer()->repaint();
    247 
     234        color = disabledTextColor(style()->color(), style()->backgroundColor());
     235
     236    RenderObject* renderer = m_innerText->renderer();
     237    RenderStyle* style = renderer->style();
     238    if (style->color() != color) {
     239        style->setColor(color);
     240        renderer->repaint();
     241    }
    248242}
    249243
     
    326320void RenderTextControl::updateFromElement()
    327321{
     322    HTMLGenericFormElement* element = static_cast<HTMLGenericFormElement*>(node());
     323
    328324    createSubtreeIfNeeded();
    329325
     
    331327        updateCancelButtonVisibility(m_cancelButton->renderer()->style());
    332328
    333     HTMLGenericFormElement* element = static_cast<HTMLGenericFormElement*>(node());
     329    updatePlaceholder();
     330
    334331    m_innerText->renderer()->style()->setUserModify(element->isReadOnlyControl() || element->disabled() ? READ_ONLY : READ_WRITE_PLAINTEXT_ONLY);
    335     String value;
    336     if (m_multiLine)
    337         value = static_cast<HTMLTextAreaElement*>(element)->value().copy();
    338     else
    339         value = static_cast<HTMLInputElement*>(element)->value().copy();
    340 
    341     if (!element->valueMatchesRenderer() || m_multiLine) {
    342         String oldText = text();
     332
     333    if ((!element->valueMatchesRenderer() || m_multiLine) && !m_placeholderVisible) {
     334        String value;
     335        if (m_multiLine)
     336            value = static_cast<HTMLTextAreaElement*>(element)->value();
     337        else
     338            value = static_cast<HTMLInputElement*>(element)->value();
    343339        if (value.isNull())
    344340            value = "";
    345         value.replace('\\', backslashAsCurrencySymbol());
    346         if (value != oldText || !m_innerText->hasChildNodes()) {
     341        else
     342            value = value.replace('\\', backslashAsCurrencySymbol());
     343        if (value != text() || !m_innerText->hasChildNodes()) {
    347344            ExceptionCode ec = 0;
    348345            m_innerText->setInnerText(value, ec);
    349346            if (value.endsWith("\n") || value.endsWith("\r"))
    350347                m_innerText->appendChild(new HTMLBRElement(document()), ec);
    351             if (document()->frame())
    352                 document()->frame()->editor()->clearUndoRedoOperations();
    353             setEdited(false);
     348            if (Frame* frame = document()->frame())
     349                frame->editor()->clearUndoRedoOperations();
     350            m_dirty = false;
    354351        }
    355352        element->setValueMatchesRenderer();
    356 
    357         showPlaceholderIfNeeded();
    358353    }
    359354
     
    364359int RenderTextControl::selectionStart()
    365360{
    366     return indexForVisiblePosition(document()->frame()->selectionController()->start());
     361    Frame* frame = document()->frame();
     362    if (!frame)
     363        return 0;
     364    return indexForVisiblePosition(frame->selectionController()->start());
    367365}
    368366
    369367int RenderTextControl::selectionEnd()
    370368{
    371     return indexForVisiblePosition(document()->frame()->selectionController()->end());
     369    Frame* frame = document()->frame();
     370    if (!frame)
     371        return 0;
     372    return indexForVisiblePosition(frame->selectionController()->end());
    372373}
    373374
     
    412413
    413414    Selection newSelection = Selection(startPosition, endPosition);
    414     document()->frame()->selectionController()->setSelection(newSelection);
     415
     416    if (Frame* frame = document()->frame())
     417        frame->selectionController()->setSelection(newSelection);
     418
    415419    // FIXME: Granularity is stored separately on the frame, but also in the selection controller.
    416420    // The granularity in the selection controller should be used, and then this line of code would not be needed.
    417     document()->frame()->setSelectionGranularity(CharacterGranularity);
     421    if (Frame* frame = document()->frame())
     422        frame->setSelectionGranularity(CharacterGranularity);
    418423}
    419424
     
    444449void RenderTextControl::updateCancelButtonVisibility(RenderStyle* style)
    445450{
     451    ASSERT(!m_multiLine);
    446452    HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    447     String val = input->value();
    448     if (val.isEmpty())
     453    if (input->value().isEmpty())
    449454        style->setVisibility(HIDDEN);
    450455    else
     
    454459void RenderTextControl::subtreeHasChanged()
    455460{
    456     bool wasPreviouslyEdited = isEdited();
    457     setEdited(true);
     461    bool wasDirty = m_dirty;
     462    m_dirty = true;
    458463    HTMLGenericFormElement* element = static_cast<HTMLGenericFormElement*>(node());
    459464    if (m_multiLine) {
    460465        element->setValueMatchesRenderer(false);
    461         document()->frame()->textDidChangeInTextArea(element);
     466        if (Frame* frame = document()->frame())
     467            frame->textDidChangeInTextArea(element);
    462468    } else {
    463469        HTMLInputElement* input = static_cast<HTMLInputElement*>(element);
    464         if (input) {
    465             input->setValueFromRenderer(text());
    466             if (m_cancelButton)
    467                 updateCancelButtonVisibility(m_cancelButton->renderer()->style());
    468 
    469             // If the incremental attribute is set, then dispatch the search event
    470             if (!input->getAttribute(incrementalAttr).isNull())
    471                 onSearch();
    472 
    473             if (!wasPreviouslyEdited)
    474                 document()->frame()->textFieldDidBeginEditing(input);
    475             document()->frame()->textDidChangeInTextField(input);
     470        input->setValueFromRenderer(text());
     471        if (m_cancelButton)
     472            updateCancelButtonVisibility(m_cancelButton->renderer()->style());
     473
     474        // If the incremental attribute is set, then dispatch the search event
     475        if (!input->getAttribute(incrementalAttr).isNull())
     476            input->onSearch();
     477
     478        if (!wasDirty) {
     479            if (Frame* frame = document()->frame())
     480                frame->textFieldDidBeginEditing(input);
    476481        }
     482        if (Frame* frame = document()->frame())
     483            frame->textDidChangeInTextField(input);
    477484    }
    478485}
     
    706713                innerLayer->scrollToOffset(style()->direction() == RTL ? innerLayer->scrollWidth() : 0, 0);
    707714        }
    708         showPlaceholderIfNeeded();
     715        updatePlaceholder();
    709716    } else if (evt->type() == focusEvent)
    710         hidePlaceholderIfNeeded();
     717        updatePlaceholder();
    711718    else {
    712719        EventTargetNode* leftNode;
     
    735742    else
    736743        static_cast<HTMLInputElement*>(element)->cacheSelection(selectionStart(), selectionEnd());
    737     if (document()->frame()->selectionController()->isRange() && userTriggered)
    738         element->onSelect();
     744    if (Frame* frame = document()->frame())
     745        if (frame->selectionController()->isRange() && userTriggered)
     746            element->dispatchHTMLEvent(selectEvent, true, false);
    739747}
    740748
     
    781789const AtomicString& RenderTextControl::autosaveName() const
    782790{
    783     HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    784     return input->getAttribute(autosaveAttr);
     791    return static_cast<Element*>(node())->getAttribute(autosaveAttr);
    785792}
    786793
    787794void RenderTextControl::addSearchResult()
    788795{
     796    ASSERT(!m_multiLine);
     797
    789798    HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    790799    if (input->maxResults() <= 0)
    791800        return;
    792801
    793     String v = input->value();
    794     if (v.isEmpty() || !document() || !document()->frame() || document()->frame()->settings()->privateBrowsingEnabled())
     802    String value = input->value();
     803    if (value.isEmpty())
     804        return;
     805
     806    Frame* frame = document()->frame();
     807    if (!frame || frame->settings()->privateBrowsingEnabled())
    795808        return;
    796809
    797810    int size = static_cast<int>(m_recentSearches.size());
    798811    for (int i = size - 1; i >= 0; --i)
    799         if (m_recentSearches[i] == v)
     812        if (m_recentSearches[i] == value)
    800813            m_recentSearches.remove(i);
    801814
    802     m_recentSearches.insert(0, v);
     815    m_recentSearches.insert(0, value);
    803816    while (static_cast<int>(m_recentSearches.size()) > input->maxResults())
    804817        m_recentSearches.removeLast();
     
    808821        m_searchPopup = SearchPopupMenu::create(this);
    809822    m_searchPopup->saveRecentSearches(name, m_recentSearches);
    810 }
    811 
    812 void RenderTextControl::onSearch() const
    813 {
    814     static_cast<HTMLInputElement*>(node())->onSearch();
    815823}
    816824
     
    846854}
    847855
    848 void RenderTextControl::valueChanged(unsigned listIndex, bool fireOnSearch)
     856void RenderTextControl::valueChanged(unsigned listIndex, bool fireEvents)
    849857{
    850858    ASSERT(listIndex < listSize());
    851859    HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    852860    if (listIndex == (listSize() - 1)) {
    853         if (fireOnSearch) {
     861        if (fireEvents) {
    854862            m_recentSearches.clear();
    855863            const AtomicString& name = autosaveName();
    856             if (!name.isNull()) {
     864            if (!name.isEmpty()) {
    857865                if (!m_searchPopup)
    858866                    m_searchPopup = SearchPopupMenu::create(this);
     
    862870    } else {
    863871        input->setValue(itemText(listIndex));
    864         if (fireOnSearch)
    865             onSearch();
     872        if (fireEvents)
     873            input->onSearch();
    866874        input->select();
    867875    }
  • trunk/WebCore/rendering/RenderTextControl.h

    r18264 r18877  
    11/*
    2  * Copyright (C) 2006 Apple Computer, Inc.
     2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.s
    33 *
    44 * This library is free software; you can redistribute it and/or
     
    3333class SearchPopupMenu;
    3434
    35 class RenderTextControl : public RenderBlock, public PopupMenuClient {
     35class RenderTextControl : public RenderBlock, private PopupMenuClient {
    3636public:
    3737    RenderTextControl(Node*, bool multiLine);
     
    5151    virtual bool avoidsFloats() const { return true; }
    5252
    53     bool isEdited() const { return m_dirty; };
    54     void setEdited(bool isEdited) { m_dirty = isEdited; };
    55     bool isTextField() const { return !m_multiLine; }
    56     bool isTextArea() const { return m_multiLine; }
     53    virtual bool isEdited() const { return m_dirty; }
     54    virtual void setEdited(bool isEdited) { m_dirty = isEdited; }
     55    virtual bool isTextField() const { return !m_multiLine; }
     56    virtual bool isTextArea() const { return m_multiLine; }
    5757
    5858    int selectionStart();
     
    8282
    8383    void addSearchResult();
    84     void onSearch() const;
    8584
    8685    bool popupIsVisible() const { return m_searchPopupIsVisible; }
     
    8887    void hidePopup();
    8988
     89private:
    9090    // PopupMenuClient methods
    91     void valueChanged(unsigned listIndex, bool fireOnSearch = true);
    92     String itemText(unsigned listIndex) const;
    93     bool itemIsEnabled(unsigned listIndex) const;
    94     RenderStyle* itemStyle(unsigned listIndex) const;
    95     RenderStyle* clientStyle() const;
    96     Document* clientDocument() const;
    97     int clientPaddingLeft() const;
    98     int clientPaddingRight() const;
    99     unsigned listSize() const;
    100     int selectedIndex() const;
    101     bool itemIsSeparator(unsigned listIndex) const;
    102     bool itemIsLabel(unsigned listIndex) const;
    103     bool itemIsSelected(unsigned listIndex) const;
    104     void setTextFromItem(unsigned listIndex);
    105     bool shouldPopOver() const { return false; }
    106     bool valueShouldChangeOnHotTrack() const { return false; }
     91    virtual void valueChanged(unsigned listIndex, bool fireEvents = true);
     92    virtual String itemText(unsigned listIndex) const;
     93    virtual bool itemIsEnabled(unsigned listIndex) const;
     94    virtual RenderStyle* itemStyle(unsigned listIndex) const;
     95    virtual RenderStyle* clientStyle() const;
     96    virtual Document* clientDocument() const;
     97    virtual int clientPaddingLeft() const;
     98    virtual int clientPaddingRight() const;
     99    virtual unsigned listSize() const;
     100    virtual int selectedIndex() const;
     101    virtual bool itemIsSeparator(unsigned listIndex) const;
     102    virtual bool itemIsLabel(unsigned listIndex) const;
     103    virtual bool itemIsSelected(unsigned listIndex) const;
     104    virtual void setTextFromItem(unsigned listIndex);
     105    virtual bool shouldPopOver() const { return false; }
     106    virtual bool valueShouldChangeOnHotTrack() const { return false; }
    107107
    108 private:
    109108    RenderStyle* createInnerBlockStyle(RenderStyle* startStyle);
    110109    RenderStyle* createInnerTextStyle(RenderStyle* startStyle);
     
    112111    RenderStyle* createResultsButtonStyle(RenderStyle* startStyle);
    113112
    114     void showPlaceholderIfNeeded();
    115     void hidePlaceholderIfNeeded();
     113    void updatePlaceholder();
    116114    void createSubtreeIfNeeded();
    117115    void updateCancelButtonVisibility(RenderStyle*);
Note: See TracChangeset for help on using the changeset viewer.