Changeset 52778 in webkit


Ignore:
Timestamp:
Jan 4, 2010 5:35:59 PM (14 years ago)
Author:
Darin Adler
Message:

Selection-related code needs stricter rules about how it relates to layout
https://bugs.webkit.org/show_bug.cgi?id=32882

Reviewed by Maciej Stachowiak.

Covered by existing tests along with the new assertions.

  • dom/Document.cpp:

(WebCore::Document::recalcStyle): Make sure that m_inStyleRecalc is
already false by the time post-attach callbacks are done so that
layout triggered inside those callbacks can work properly.

  • editing/SelectionController.cpp:

(WebCore::SelectionController::layout): Added code to trigger a
layout when it's needed.
(WebCore::SelectionController::recomputeCaretRect): Removed unneeded
code to do nothing when FrameView is 0. Added an assertion that layout
is not needed at the time the function is called.
(WebCore::SelectionController::invalidateCaretRect): Added code to
trigger a layout when it's needed.
(WebCore::SelectionController::paintCaret): Added an assertion that
layout is not needed at the time the function is called.

  • html/HTMLFormControlElement.cpp:

(WebCore::shouldAutofocus): Added. Helper function that expresses
the rule for which form control elements should auto-focus.
(WebCore::focusPostAttach): Added. Called post-attach to focus an
element if we discover it should be focused during attach.
(WebCore::HTMLFormControlElement::attach): Refactored code for
which elements need auto-focus into a separate function. Instead
of focusing right away, use the focusPostAttach function to focus
after attach is done. Also added calls to suspendPostAttachCallbacks
and resumePostAttachCallbacks so post-attach callbacks happen late
enough. Before, they could run inside the base attach function.

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::attach): Added calls to
suspendPostAttachCallbacks and resumePostAttachCallbacks so
post-attach callbacks happen late enough

  • page/Frame.cpp:

(WebCore::Frame::revealSelection): Added code to trigger a layout
when it's needed.

Location:
trunk/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r52777 r52778  
     12010-01-04  Darin Adler  <darin@apple.com>
     2
     3        Reviewed by Maciej Stachowiak.
     4
     5        Selection-related code needs stricter rules about how it relates to layout
     6        https://bugs.webkit.org/show_bug.cgi?id=32882
     7
     8        Covered by existing tests along with the new assertions.
     9
     10        * dom/Document.cpp:
     11        (WebCore::Document::recalcStyle): Make sure that m_inStyleRecalc is
     12        already false by the time post-attach callbacks are done so that
     13        layout triggered inside those callbacks can work properly.
     14
     15        * editing/SelectionController.cpp:
     16        (WebCore::SelectionController::layout): Added code to trigger a
     17        layout when it's needed.
     18        (WebCore::SelectionController::recomputeCaretRect): Removed unneeded
     19        code to do nothing when FrameView is 0. Added an assertion that layout
     20        is not needed at the time the function is called.
     21        (WebCore::SelectionController::invalidateCaretRect): Added code to
     22        trigger a layout when it's needed.
     23        (WebCore::SelectionController::paintCaret): Added an assertion that
     24        layout is not needed at the time the function is called.
     25
     26        * html/HTMLFormControlElement.cpp:
     27        (WebCore::shouldAutofocus): Added. Helper function that expresses
     28        the rule for which form control elements should auto-focus.
     29        (WebCore::focusPostAttach): Added. Called post-attach to focus an
     30        element if we discover it should be focused during attach.
     31        (WebCore::HTMLFormControlElement::attach): Refactored code for
     32        which elements need auto-focus into a separate function. Instead
     33        of focusing right away, use the focusPostAttach function to focus
     34        after attach is done. Also added calls to suspendPostAttachCallbacks
     35        and resumePostAttachCallbacks so post-attach callbacks happen late
     36        enough. Before, they could run inside the base attach function.
     37
     38        * html/HTMLInputElement.cpp:
     39        (WebCore::HTMLInputElement::attach): Added calls to
     40        suspendPostAttachCallbacks and resumePostAttachCallbacks so
     41        post-attach callbacks happen late enough
     42
     43        * page/Frame.cpp:
     44        (WebCore::Frame::revealSelection): Added code to trigger a layout
     45        when it's needed.
     46
    1472010-01-04  Gavin Barraclough <barraclough@apple.com>
    248
  • trunk/WebCore/dom/Document.cpp

    r52756 r52778  
    12951295    unscheduleStyleRecalc();
    12961296
     1297    m_inStyleRecalc = false;
     1298
    12971299    if (view())
    12981300        view()->resumeScheduledEvents();
    12991301    RenderWidget::resumeWidgetHierarchyUpdates();
    13001302    resumePostAttachCallbacks();
    1301     m_inStyleRecalc = false;
    13021303
    13031304    // If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
  • trunk/WebCore/editing/SelectionController.cpp

    r52756 r52778  
    820820    }
    821821
    822     m_selection.start().node()->document()->updateStyleIfNeeded();
    823    
    824822    m_caretRect = IntRect();
    825823       
    826824    if (isCaret()) {
     825        Document* document = m_selection.start().node()->document();
     826
     827        document->updateStyleIfNeeded();
     828        if (FrameView* view = document->view()) {
     829            if (view->needsLayout())
     830                view->layout();
     831        }
     832
    827833        VisiblePosition pos(m_selection.start(), m_selection.affinity());
    828834        if (pos.isNotNull()) {
     
    921927        return false;
    922928       
    923     FrameView* v = m_frame->document()->view();
    924     if (!v)
    925         return false;
     929    ASSERT(!m_frame->view() || !m_frame->view()->needsLayout());
    926930
    927931    if (!m_needsLayout)
     
    959963        return;
    960964
    961     Document* d = m_selection.start().node()->document();
     965    Document* document = m_selection.start().node()->document();
     966
     967    if (FrameView* frameView = document->view()) {
     968        if (frameView->needsLayout())
     969            frameView->layout();
     970    }
    962971
    963972    // recomputeCaretRect will always return false for the drag caret,
     
    979988
    980989    if (!caretRectChanged) {
    981         if (RenderView* view = toRenderView(d->renderer()))
     990        if (RenderView* view = toRenderView(document->renderer()))
    982991            view->repaintRectangleInViewAndCompositedLayers(caretRepaintRect(), false);
    983992    }
     
    986995void SelectionController::paintCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect)
    987996{
    988     if (! m_selection.isCaret())
     997    ASSERT(!m_frame || !m_frame->view() || !m_frame->view()->needsLayout());
     998
     999    if (!isCaret())
    9891000        return;
    9901001
  • trunk/WebCore/html/HTMLFormControlElement.cpp

    r52314 r52778  
    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, 2008, 2009, 2010 Apple Inc. All rights reserved.
    66 *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    77 *
     
    117117}
    118118
     119static bool shouldAutofocus(HTMLFormControlElement* element)
     120{
     121    if (!element->autofocus())
     122        return false;
     123    if (!element->renderer())
     124        return false;
     125    if (element->document()->ignoreAutofocus())
     126        return false;
     127    if (element->isReadOnlyFormControl())
     128        return false;
     129
     130    // FIXME: Should this set of hasTagName checks be replaced by a
     131    // virtual member function?
     132    if (element->hasTagName(inputTag))
     133        return !static_cast<HTMLInputElement*>(element)->isInputTypeHidden();
     134    if (element->hasTagName(selectTag))
     135        return true;
     136    if (element->hasTagName(buttonTag))
     137        return true;
     138    if (element->hasTagName(textareaTag))
     139        return true;
     140
     141    return false;
     142}
     143
     144static void focusPostAttach(Node* element)
     145{
     146    static_cast<Element*>(element)->focus();
     147    element->deref();
     148}
     149
    119150void HTMLFormControlElement::attach()
    120151{
    121152    ASSERT(!attached());
     153
     154    suspendPostAttachCallbacks();
    122155
    123156    HTMLElement::attach();
     
    128161    if (renderer())
    129162        renderer()->updateFromElement();
    130        
    131     // Focus the element if it should honour its autofocus attribute.
    132     // We have to determine if the element is a TextArea/Input/Button/Select,
    133     // if input type hidden ignore autofocus. So if disabled or readonly.
    134     bool isInputTypeHidden = false;
    135     if (hasTagName(inputTag))
    136         isInputTypeHidden = static_cast<HTMLInputElement*>(this)->isInputTypeHidden();
    137 
    138     if (autofocus() && renderer() && !document()->ignoreAutofocus() && !isReadOnlyFormControl() &&
    139             ((hasTagName(inputTag) && !isInputTypeHidden) || hasTagName(selectTag) ||
    140               hasTagName(buttonTag) || hasTagName(textareaTag)))
    141          focus();
     163
     164    if (shouldAutofocus(this)) {
     165        ref();
     166        queuePostAttachCallback(focusPostAttach, this);
     167    }
     168
     169    resumePostAttachCallbacks();
    142170}
    143171
  • trunk/WebCore/html/HTMLInputElement.cpp

    r52524 r52778  
    33 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2001 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
     5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
    66 *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    77 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
     
    988988void HTMLInputElement::attach()
    989989{
     990    suspendPostAttachCallbacks();
     991
    990992    if (!m_inited) {
    991993        if (!m_haveType)
     
    10101012        }
    10111013    }
     1014
     1015    resumePostAttachCallbacks();
    10121016}
    10131017
  • trunk/WebCore/page/Frame.cpp

    r52756 r52778  
    13521352void Frame::revealSelection(const ScrollAlignment& alignment, bool revealExtent)
    13531353{
     1354    if (view()->needsLayout())
     1355        view()->layout();
     1356
    13541357    IntRect rect;
    13551358
Note: See TracChangeset for help on using the changeset viewer.