Changeset 27982 in webkit


Ignore:
Timestamp:
Nov 22, 2007 10:04:36 PM (16 years ago)
Author:
mitz@apple.com
Message:

WebCore:

Reviewed by Antti Koivisto.

Defer plug-in loading until after attach and recalcStyle using the
post-attach callback mechanism. Netscape plug-ins are still loaded only
after layout.

  • dom/ContainerNode.cpp: Made NodeCallbackQueue elements retain the Node because callbacks might delete nodes that are in the callback queue. (WebCore::ContainerNode::suspendPostAttachCallbacks): Added. Needed to prevent post-attach callbacks from being dispatched under recalcStyle(). (WebCore::ContainerNode::resumePostAttachCallbacks): Ditto. (WebCore::ContainerNode::dispatchPostAttachCallbacks): Factored out from attach(). (WebCore::ContainerNode::attach):
  • dom/ContainerNode.h:
  • dom/Document.cpp: (WebCore::Document::recalcStyle): Added calls to suspendPostAttachCallbacks() and resumePostAttachCallbacks().
  • html/HTMLEmbedElement.cpp: (WebCore::HTMLEmbedElement::HTMLEmbedElement): (WebCore::HTMLEmbedElement::attach): Changed to queue the widget update for post-attach. (WebCore::HTMLEmbedElement::updateWidget): Added. Called by the post-attach callback.
  • html/HTMLEmbedElement.h: Added an m_needWidgetUpdate member needed to prevent a double update if another plug-in's post-attach updateWidget() triggers a layout which updates the widget before this plug-in's post-attach callback is invoked. (WebCore::HTMLEmbedElement::setNeedWidgetUpdate): Added a setter for m_needWidgetUpdate.
  • html/HTMLObjectElement.cpp: (WebCore::HTMLObjectElement::attach): Changed to queue the widget update for post-attach. (WebCore::HTMLObjectElement::updateWidget): Added. Called by the post-attach callback.
  • html/HTMLObjectElement.h: (WebCore::HTMLObjectElement::setNeedWidgetUpdate): Added a setter for m_needWidgetUpdate.
  • html/HTMLPlugInElement.cpp: (WebCore::HTMLPlugInElement::updateWidgetCallback): Added.
  • html/HTMLPlugInElement.h: (WebCore::HTMLPlugInElement::updateWidget):
  • rendering/RenderPartObject.cpp: (WebCore::RenderPartObject::updateWidget): Added calls to setNeedWidgetUpdate(false) so that if this method is called from FrameView::layout() during post-attach dispatch of another plug-in, it will not be called again when this plug-in's post-attach callback is dispatched.
  • rendering/RenderPartObject.h: (WebCore::RenderPartObject::updateWidget) Renamed argument to match the method definition.

WebKit/mac:

Reviewed by Antti Koivisto.

Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r27981 r27982  
     12007-11-22  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Antti Koivisto.
     4
     5        - fix http://bugs.webkit.org/show_bug.cgi?id=15811
     6          WebKit plug-ins can re-enter WebKit under attach()
     7          <rdar://problem/5577978>
     8
     9        Defer plug-in loading until after attach and recalcStyle using the
     10        post-attach callback mechanism. Netscape plug-ins are still loaded only
     11        after layout.
     12
     13        * dom/ContainerNode.cpp:
     14        Made NodeCallbackQueue elements retain the Node because callbacks might
     15        delete nodes that are in the callback queue.
     16        (WebCore::ContainerNode::suspendPostAttachCallbacks): Added. Needed to
     17        prevent post-attach callbacks from being dispatched under recalcStyle().
     18        (WebCore::ContainerNode::resumePostAttachCallbacks): Ditto.
     19        (WebCore::ContainerNode::dispatchPostAttachCallbacks): Factored out from
     20        attach().
     21        (WebCore::ContainerNode::attach):
     22        * dom/ContainerNode.h:
     23        * dom/Document.cpp:
     24        (WebCore::Document::recalcStyle): Added calls to
     25        suspendPostAttachCallbacks() and resumePostAttachCallbacks().
     26        * html/HTMLEmbedElement.cpp:
     27        (WebCore::HTMLEmbedElement::HTMLEmbedElement):
     28        (WebCore::HTMLEmbedElement::attach): Changed to queue the widget update
     29        for post-attach.
     30        (WebCore::HTMLEmbedElement::updateWidget): Added. Called by the
     31        post-attach callback.
     32        * html/HTMLEmbedElement.h: Added an m_needWidgetUpdate member needed to
     33        prevent a double update if another plug-in's post-attach updateWidget()
     34        triggers a layout which updates the widget before this plug-in's
     35        post-attach callback is invoked.
     36        (WebCore::HTMLEmbedElement::setNeedWidgetUpdate): Added a setter for
     37        m_needWidgetUpdate.
     38        * html/HTMLObjectElement.cpp:
     39        (WebCore::HTMLObjectElement::attach): Changed to queue the widget update
     40        for post-attach.
     41        (WebCore::HTMLObjectElement::updateWidget): Added. Called by the
     42        post-attach callback.
     43        * html/HTMLObjectElement.h:
     44        (WebCore::HTMLObjectElement::setNeedWidgetUpdate): Added a setter for
     45        m_needWidgetUpdate.
     46        * html/HTMLPlugInElement.cpp:
     47        (WebCore::HTMLPlugInElement::updateWidgetCallback): Added.
     48        * html/HTMLPlugInElement.h:
     49        (WebCore::HTMLPlugInElement::updateWidget):
     50        * rendering/RenderPartObject.cpp:
     51        (WebCore::RenderPartObject::updateWidget): Added calls to
     52        setNeedWidgetUpdate(false) so that if this method is called from
     53        FrameView::layout() during post-attach dispatch of another plug-in,
     54        it will not be called again when this plug-in's post-attach callback
     55        is dispatched.
     56        * rendering/RenderPartObject.h:
     57        (WebCore::RenderPartObject::updateWidget) Renamed argument to match
     58        the method definition.
     59
    1602007-11-22  Timothy Hatcher  <timothy@apple.com>
    261
  • trunk/WebCore/dom/ContainerNode.cpp

    r26494 r27982  
    4646static void dispatchChildRemovalEvents(Node*, ExceptionCode&);
    4747
    48 typedef Vector<std::pair<NodeCallback, Node*> > NodeCallbackQueue;
     48typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue;
    4949static NodeCallbackQueue* s_postAttachCallbackQueue = 0;
    5050
     
    585585}
    586586
     587void ContainerNode::suspendPostAttachCallbacks()
     588{
     589    ++s_attachDepth;
     590}
     591
     592void ContainerNode::resumePostAttachCallbacks()
     593{
     594    if (s_attachDepth == 1 && s_postAttachCallbackQueue)
     595        dispatchPostAttachCallbacks();
     596    --s_attachDepth;
     597}
     598
    587599void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node)
    588600{
     
    590602        s_postAttachCallbackQueue = new NodeCallbackQueue;
    591603   
    592     s_postAttachCallbackQueue->append(std::pair<NodeCallback, Node*>(callback, node));
     604    s_postAttachCallbackQueue->append(std::pair<NodeCallback, RefPtr<Node> >(callback, node));
     605}
     606
     607void ContainerNode::dispatchPostAttachCallbacks()
     608{
     609    // We recalculate size() each time through the loop because a callback
     610    // can add more callbacks to the end of the queue.
     611    for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {
     612        std::pair<NodeCallback, RefPtr<Node> >& pair = (*s_postAttachCallbackQueue)[i];
     613        NodeCallback callback = pair.first;
     614        Node* node = pair.second.get();
     615
     616        callback(node);
     617    }
     618    s_postAttachCallbackQueue->clear();
    593619}
    594620
     
    601627    EventTargetNode::attach();
    602628
    603     if (s_attachDepth == 1) {
    604         if (s_postAttachCallbackQueue) {
    605             // We recalculate size() each time through the loop because a callback
    606             // can add more callbacks to the end of the queue.
    607             for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {
    608                 std::pair<NodeCallback, Node*>& pair = (*s_postAttachCallbackQueue)[i];
    609                 NodeCallback callback = pair.first;
    610                 Node* node = pair.second;
    611                
    612                 callback(node);
    613             }
    614             s_postAttachCallbackQueue->clear();
    615         }
    616     }   
     629    if (s_attachDepth == 1 && s_postAttachCallbackQueue)
     630        dispatchPostAttachCallbacks();
    617631    --s_attachDepth;
    618632}
  • trunk/WebCore/dom/ContainerNode.h

    r26494 r27982  
    6969protected:
    7070    static void queuePostAttachCallback(NodeCallback, Node*);
     71    static void suspendPostAttachCallbacks();
     72    static void resumePostAttachCallbacks();
    7173
    7274    void setFirstChild(Node* child) { m_firstChild = child; }
     
    7476   
    7577private:
     78    static void dispatchPostAttachCallbacks();
     79
    7680    virtual Node* virtualFirstChild() const;
    7781    virtual Node* virtualLastChild() const;
  • trunk/WebCore/dom/Document.cpp

    r27701 r27982  
    10461046       
    10471047    m_inStyleRecalc = true;
     1048    suspendPostAttachCallbacks();
    10481049   
    10491050    ASSERT(!renderer() || renderArena());
     
    11061107    setDocumentChanged(false);
    11071108   
     1109    resumePostAttachCallbacks();
    11081110    m_inStyleRecalc = false;
    11091111   
  • trunk/WebCore/html/HTMLEmbedElement.cpp

    r26946 r27982  
    4646HTMLEmbedElement::HTMLEmbedElement(Document* doc)
    4747    : HTMLPlugInElement(embedTag, doc)
     48    , m_needWidgetUpdate(false)
    4849{
    4950}
     
    154155void HTMLEmbedElement::attach()
    155156{
     157    m_needWidgetUpdate = true;
     158    queuePostAttachCallback(&HTMLPlugInElement::updateWidgetCallback, this);
    156159    HTMLPlugInElement::attach();
    157 
    158     if (renderer())
    159         static_cast<RenderPartObject*>(renderer())->updateWidget(true);
    160160}
    161161
     
    166166#endif
    167167    HTMLPlugInElement::detach();
     168}
     169
     170void HTMLEmbedElement::updateWidget()
     171{
     172    if (m_needWidgetUpdate && renderer())
     173        static_cast<RenderPartObject*>(renderer())->updateWidget(true);
    168174}
    169175
  • trunk/WebCore/html/HTMLEmbedElement.h

    r25754 r27982  
    5757    virtual bool isURLAttribute(Attribute*) const;
    5858
     59    virtual void updateWidget();
     60    void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
     61
    5962#if USE(JAVASCRIPTCORE_BINDINGS)
    6063    virtual KJS::Bindings::Instance* getInstance() const;
     
    7477    String m_pluginPage;
    7578    String m_serviceType;
     79    bool m_needWidgetUpdate;
    7680};
    7781
  • trunk/WebCore/html/HTMLObjectElement.cpp

    r27485 r27982  
    166166void HTMLObjectElement::attach()
    167167{
     168    bool isImage = isImageType();
     169
     170    if (!isImage)
     171        queuePostAttachCallback(&HTMLPlugInElement::updateWidgetCallback, this);
     172
    168173    HTMLPlugInElement::attach();
    169174
    170     if (renderer() && !m_useFallbackContent) {
    171         if (isImageType()) {
    172             if (!m_imageLoader)
    173                 m_imageLoader.set(new HTMLImageLoader(this));
    174             m_imageLoader->updateFromElement();
    175             if (renderer()) {
    176                 RenderImage* imageObj = static_cast<RenderImage*>(renderer());
    177                 imageObj->setCachedImage(m_imageLoader->image());
    178             }
    179         } else {
    180             if (m_needWidgetUpdate) {
    181                 // Set m_needWidgetUpdate to false before calling updateWidget because updateWidget may cause
    182                 // this method or recalcStyle (which also calls updateWidget) to be called.
    183                 m_needWidgetUpdate = false;
    184                 static_cast<RenderPartObject*>(renderer())->updateWidget(true);
    185             } else {
    186                 m_needWidgetUpdate = true;
    187                 setChanged();
    188             }
    189         }
    190     }
     175    if (isImage && renderer() && !m_useFallbackContent) {
     176        if (!m_imageLoader)
     177            m_imageLoader.set(new HTMLImageLoader(this));
     178        m_imageLoader->updateFromElement();
     179        if (renderer()) {
     180            RenderImage* imageObj = static_cast<RenderImage*>(renderer());
     181            imageObj->setCachedImage(m_imageLoader->image());
     182        }
     183    }
     184}
     185
     186void HTMLObjectElement::updateWidget()
     187{
     188    if (m_needWidgetUpdate && renderer() && !m_useFallbackContent && !isImageType())
     189        static_cast<RenderPartObject*>(renderer())->updateWidget(true);
    191190}
    192191
  • trunk/WebCore/html/HTMLObjectElement.h

    r27485 r27982  
    5757    virtual bool isURLAttribute(Attribute*) const;
    5858    virtual const QualifiedName& imageSourceAttributeName() const;
     59
     60    virtual void updateWidget();
     61    void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
    5962
    6063    bool isImageType();
  • trunk/WebCore/html/HTMLPlugInElement.cpp

    r27125 r27982  
    205205#endif /* USE(NPOBJECT) */
    206206
    207 }
     207void HTMLPlugInElement::updateWidgetCallback(Node* n)
     208{
     209    static_cast<HTMLPlugInElement*>(n)->updateWidget();
     210}
     211
     212}
  • trunk/WebCore/html/HTMLPlugInElement.h

    r27125 r27982  
    4949    virtual bool checkDTD(const Node* newChild);
    5050
     51    virtual void updateWidget() { }
     52
    5153    String align() const;
    5254    void setAlign(const String&);
     
    7577
    7678protected:
     79    static void updateWidgetCallback(Node*);
     80
    7781    String oldNameAttr;
    7882#if USE(JAVASCRIPTCORE_BINDINGS)
  • trunk/WebCore/rendering/RenderPartObject.cpp

    r27378 r27982  
    121121      HTMLObjectElement* o = static_cast<HTMLObjectElement*>(element());
    122122
     123      o->setNeedWidgetUpdate(false);
    123124      if (!o->isComplete())
    124125        return;
     
    230231  } else if (element()->hasTagName(embedTag)) {
    231232      HTMLEmbedElement *o = static_cast<HTMLEmbedElement*>(element());
     233      o->setNeedWidgetUpdate(false);
    232234      url = o->url;
    233235      serviceType = o->m_serviceType;
  • trunk/WebCore/rendering/RenderPartObject.h

    r26946 r27982  
    3838
    3939    virtual void layout();
    40     void updateWidget(bool onlyCreateNonPlugins);
     40    void updateWidget(bool onlyCreateNonNetscapePlugins);
    4141
    4242    virtual void viewCleared();
  • trunk/WebKit/mac/ChangeLog

    r27951 r27982  
     12007-11-22  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Antti Koivisto.
     4
     5        - http://bugs.webkit.org/show_bug.cgi?id=15811
     6          WebKit plug-ins can re-enter WebKit under attach()
     7          <rdar://problem/5577978>
     8
     9        * Plugins/WebNullPluginView.mm:
     10        (-[WebNullPluginView viewDidMoveToWindow]): Removed workaround for the
     11        above bug that added as part of fixing
     12        <http://bugs.webkit.org/show_bug.cgi?id=15804>.
     13
    1142007-11-21  Mark Rowe  <mrowe@apple.com>
    215
  • trunk/WebKit/mac/Plugins/WebNullPluginView.mm

    r27378 r27982  
    9191        return;
    9292
    93     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(reportFailure) object:nil];
    9493    if ([self window])
    95         [self performSelector:@selector(reportFailure) withObject:nil afterDelay:0.0];
     94        [self reportFailure];
    9695}
    9796
Note: See TracChangeset for help on using the changeset viewer.