Show
Ignore:
Timestamp:
07/19/06 16:54:49 (2 years ago)
Author:
adele
Message:

Reviewed by Maciej.

<rdar://problem/4614181> REGRESSION: Crash in WebCore::RenderTextField::text() when quoting post at the Ars Technica forum (9707)
http://bugzilla.opendarwin.org/show_bug.cgi?id=9707

Needs an http test. (http://bugzilla.opendarwin.org/show_bug.cgi?id=10020)

These bugs were both cases where focus() was called on an element which didn't have a renderer yet because stylesheets hadn't finished loading yet.
Now, we detect this case and let setFocusNode be called. And when the stylesheet finishes loading, and the element attaches, a timer will fire,
which will cause the correct selection & scrolling behavior to occur.

This fix removes selection and scrolling behavior from the focus method. This code is now in a new method, updateFocusAppearance.
updateFocusAppearance can now be called directly from focus(), but it can also be called when a timer fires. This timer gets set
up when an element attaches, and its already been focused by the focus method. We have to use a timer, because updateFocusAppearance can cause
a layout to happen, and we don't want that to happen in the middle of attach().

  • bindings/objc/DOM.mm: (-[DOMElement isFocused]): Added SPI for autofill.
  • bindings/objc/DOMPrivate.h:
  • dom/Element.cpp: (WebCore::Element::Element): Initializes timer and needFocusAppearanceUpdate bool. (WebCore::Element::attach): Checks needsFocusAppearanceUpdate, and if the node is focused, then starts the timer. (WebCore::Element::focus): Updated to check supportsFocus before calling setFocusNode, and only requiring the element to be focusable now before updating focus appearance. (WebCore::Element::updateFocusAppearance): Added. Separates the selection, and the scrolling from focusing the node. (WebCore::Element::updateFocusAppearanceTimerFired): Stops the timer, and if the element is focusable, calls updateFocusAppearance. (WebCore::Element::stopUpdateFocusAppearanceTimer): Cancels timer, and setsNeedsFocusAppearanceUpdate(false). (WebCore::Element::detach): Calls stopUpdateFocusAppearanceTimer. (WebCore::Element::blur): ditto.
  • dom/Element.h: (WebCore::Element::needsFocusAppearanceUpdate): Added so the timer only fires when focus() methods have caused an element to be focused. (WebCore::Element::setNeedsFocusAppearanceUpdate): Added so focus methods can set this flag.
  • dom/Node.h: (WebCore::Node::supportsFocus): Added. Base class just calls isFocusable.
  • html/HTMLAnchorElement.h: Added supportsFocus.
  • html/HTMLAnchorElement.cpp: (WebCore::HTMLAnchorElement::supportsFocus): Added. Checks for the case where stylesheets haven't loaded yet, so we can still focus the node without a renderer, and when it gets a renderer, we'll update the focus appearance.
  • html/HTMLGenericFormElement.h: (WebCore::HTMLGenericFormElement::supportsFocus): ditto.
  • html/HTMLGenericFormElement.cpp: Removed include of Document.h since this is now in the header.
  • html/HTMLInputElement.cpp: (WebCore::HTMLInputElement::focus): Updated to check supportsFocus before calling setFocusNode, and only requiring the element to be focusable now before updating focus appearance. (WebCore::HTMLInputElement::updateFocusAppearance): Added. Separates the selection, and the scrolling from focusing the node.
  • html/HTMLInputElement.h:
  • html/HTMLTextAreaElement.cpp: (WebCore::HTMLTextAreaElement::focus): Updated to check supportsFocus before calling setFocusNode, and only requiring the element to be focusable now before updating focus appearance. (WebCore::HTMLTextAreaElement::updateFocusAppearance): Added. Separates the selection, and the scrolling from focusing the node.
  • html/HTMLTextAreaElement.h:
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/dom/Element.h

    r15258 r15532  
    3030#include "Attr.h" 
    3131#include "ScrollBar.h" 
     32#include "Timer.h" 
    3233 
    3334namespace WebCore { 
     
    135136 
    136137    virtual void attach(); 
     138    virtual void detach(); 
    137139    virtual RenderStyle *styleForRenderer(RenderObject *parent); 
    138140    virtual RenderObject *createRenderer(RenderArena *, RenderStyle *); 
     
    153155         
    154156    virtual void focus(); 
     157    virtual void updateFocusAppearance(); 
    155158    void blur(); 
     159    bool needsFocusAppearanceUpdate() const { return m_needsFocusAppearanceUpdate; } 
     160    void setNeedsFocusAppearanceUpdate(bool b) { m_needsFocusAppearanceUpdate = b; } 
    156161     
    157162#if !NDEBUG 
     
    171176 
    172177    virtual void updateStyleAttributeIfNeeded() const {} 
     178     
     179    void updateFocusAppearanceTimerFired(Timer<Element>*); 
     180    void stopUpdateFocusAppearanceTimer(); 
     181    Timer<Element> m_updateFocusAppearanceTimer; 
     182    bool m_needsFocusAppearanceUpdate; 
    173183 
    174184protected: // member variables