Changeset 180062 in webkit


Ignore:
Timestamp:
Feb 13, 2015, 11:04:09 AM (10 years ago)
Author:
Simon Fraser
Message:

determinePrimarySnapshottedPlugIn() should only traverse visible Frames
https://bugs.webkit.org/show_bug.cgi?id=141547
Part of rdar://problem/18445733.

Reviewed by Anders Carlsson.
Source/WebCore:

There's an expectation from clients that FrameView::updateLayoutAndStyleIfNeededRecursive()
updates layout in all frames, but it uses the widget tree, so only hits frames
that are parented via renderers (i.e. not display:none frames or their descendants).

Moving towards a future where we remove Widgets, fix by adding a FrameTree
traversal function that only finds rendered frames (those with an ownerRenderer).

Not testable.

  • page/FrameTree.cpp:

(WebCore::FrameTree::firstRenderedChild):
(WebCore::FrameTree::nextRenderedSibling):
(WebCore::FrameTree::traverseNextRendered):
(printFrames):

  • page/FrameTree.h:
  • page/FrameView.cpp:

(WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):

Source/WebKit2:

Use FrameTree::traverseNextRendered() to avoid doing things in unrendered frames
which are not guaranteed to have been laid out.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::determinePrimarySnapshottedPlugIn):

Location:
trunk/Source
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r180058 r180062  
     12015-02-12  Simon Fraser  <simon.fraser@apple.com>
     2
     3        determinePrimarySnapshottedPlugIn() should only traverse visible Frames
     4        https://bugs.webkit.org/show_bug.cgi?id=141547
     5        Part of rdar://problem/18445733.
     6
     7        Reviewed by Anders Carlsson.
     8
     9        There's an expectation from clients that FrameView::updateLayoutAndStyleIfNeededRecursive()
     10        updates layout in all frames, but it uses the widget tree, so only hits frames
     11        that are parented via renderers (i.e. not display:none frames or their descendants).
     12       
     13        Moving towards a future where we remove Widgets, fix by adding a FrameTree
     14        traversal function that only finds rendered frames (those with an ownerRenderer).
     15       
     16        Not testable.
     17
     18        * page/FrameTree.cpp:
     19        (WebCore::FrameTree::firstRenderedChild):
     20        (WebCore::FrameTree::nextRenderedSibling):
     21        (WebCore::FrameTree::traverseNextRendered):
     22        (printFrames):
     23        * page/FrameTree.h:
     24        * page/FrameView.cpp:
     25        (WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):
     26
    1272015-02-13  Alexey Proskuryakov  <ap@apple.com>
    228
  • trunk/Source/WebCore/WebCore.exp.in

    r180007 r180062  
    21462146__ZNK7WebCore9FrameTree12traverseNextEPKNS_5FrameE
    21472147__ZNK7WebCore9FrameTree14isDescendantOfEPKNS_5FrameE
     2148__ZNK7WebCore9FrameTree20traverseNextRenderedEPKNS_5FrameE
    21482149__ZNK7WebCore9FrameTree20traverseNextWithWrapEb
    21492150__ZNK7WebCore9FrameTree24traversePreviousWithWrapEb
  • trunk/Source/WebCore/page/FrameTree.cpp

    r179947 r180062  
    357357}
    358358
     359Frame* FrameTree::firstRenderedChild() const
     360{
     361    Frame* child = firstChild();
     362    if (!child)
     363        return nullptr;
     364   
     365    if (child->ownerRenderer())
     366        return child;
     367
     368    while ((child = child->tree().nextSibling())) {
     369        if (child->ownerRenderer())
     370            return child;
     371    }
     372   
     373    return nullptr;
     374}
     375
     376Frame* FrameTree::nextRenderedSibling() const
     377{
     378    Frame* sibling = &m_thisFrame;
     379
     380    while ((sibling = sibling->tree().nextSibling())) {
     381        if (sibling->ownerRenderer())
     382            return sibling;
     383    }
     384   
     385    return nullptr;
     386}
     387
     388Frame* FrameTree::traverseNextRendered(const Frame* stayWithin) const
     389{
     390    Frame* child = firstRenderedChild();
     391    if (child) {
     392        ASSERT(!stayWithin || child->tree().isDescendantOf(stayWithin));
     393        return child;
     394    }
     395
     396    if (&m_thisFrame == stayWithin)
     397        return nullptr;
     398
     399    Frame* sibling = nextRenderedSibling();
     400    if (sibling) {
     401        ASSERT(!stayWithin || sibling->tree().isDescendantOf(stayWithin));
     402        return sibling;
     403    }
     404
     405    Frame* frame = &m_thisFrame;
     406    while (!sibling && (!stayWithin || frame->tree().parent() != stayWithin)) {
     407        frame = frame->tree().parent();
     408        if (!frame)
     409            return nullptr;
     410        sibling = frame->tree().nextRenderedSibling();
     411    }
     412
     413    if (frame) {
     414        ASSERT(!stayWithin || !sibling || sibling->tree().isDescendantOf(stayWithin));
     415        return sibling;
     416    }
     417
     418    return nullptr;
     419}
     420
    359421Frame* FrameTree::traverseNextWithWrap(bool wrap) const
    360422{
     
    429491    printf("  renderView=%p\n", view ? view->renderView() : nullptr);
    430492    printIndent(indent);
    431     printf("  document=%p (needs style recalc %d)\n", frame.document(), frame.document() ? frame.document()->needsStyleRecalc() : false);
     493    printf("  ownerRenderer=%p\n", frame.ownerRenderer());
     494    printIndent(indent);
     495    printf("  document=%p (needs style recalc %d)\n", frame.document(), frame.document() ? frame.document()->childNeedsStyleRecalc() : false);
    432496    printIndent(indent);
    433497    printf("  uri=%s\n", frame.document()->documentURI().utf8().data());
  • trunk/Source/WebCore/page/FrameTree.h

    r172862 r180062  
    5757
    5858        WEBCORE_EXPORT bool isDescendantOf(const Frame* ancestor) const;
    59         WEBCORE_EXPORT Frame* traverseNext(const Frame* stayWithin = 0) const;
     59       
     60        WEBCORE_EXPORT Frame* traverseNext(const Frame* stayWithin = nullptr) const;
     61        // Rendered means being the main frame or having an ownerRenderer. It may not have been parented in the Widget tree yet (see WidgetHierarchyUpdatesSuspensionScope).
     62        WEBCORE_EXPORT Frame* traverseNextRendered(const Frame* stayWithin = nullptr) const;
    6063        WEBCORE_EXPORT Frame* traverseNextWithWrap(bool) const;
    6164        WEBCORE_EXPORT Frame* traversePreviousWithWrap(bool) const;
     
    8891        unsigned scopedChildCount(TreeScope*) const;
    8992
     93        Frame* firstRenderedChild() const;
     94        Frame* nextRenderedSibling() const;
     95
    9096        Frame& m_thisFrame;
    9197
     
    105111#ifndef NDEBUG
    106112// Outside the WebCore namespace for ease of invocation from gdb.
    107 void showFrameTree(const WebCore::Frame*);
     113WEBCORE_EXPORT void showFrameTree(const WebCore::Frame*);
    108114#endif
    109115
  • trunk/Source/WebCore/page/FrameView.cpp

    r179982 r180062  
    39703970    // and thus mutates the children() set.
    39713971    // We use the Widget children because walking the Frame tree would include display:none frames.
     3972    // FIXME: use FrameTree::traverseNextRendered().
    39723973    Vector<Ref<FrameView>, 16> childViews;
    39733974    childViews.reserveInitialCapacity(children().size());
  • trunk/Source/WebKit2/ChangeLog

    r180054 r180062  
     12015-02-12  Simon Fraser  <simon.fraser@apple.com>
     2
     3        determinePrimarySnapshottedPlugIn() should only traverse visible Frames
     4        https://bugs.webkit.org/show_bug.cgi?id=141547
     5        Part of rdar://problem/18445733.
     6
     7        Reviewed by Anders Carlsson.
     8       
     9        Use FrameTree::traverseNextRendered() to avoid doing things in unrendered frames
     10        which are not guaranteed to have been laid out.
     11
     12        * WebProcess/WebPage/WebPage.cpp:
     13        (WebKit::WebPage::determinePrimarySnapshottedPlugIn):
     14
    1152015-02-13  Antti Koivisto  <antti@apple.com>
    216
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r180031 r180062  
    46494649    unsigned candidatePlugInArea = 0;
    46504650
    4651     for (Frame* frame = &mainFrame; frame; frame = frame->tree().traverseNext()) {
     4651    for (Frame* frame = &mainFrame; frame; frame = frame->tree().traverseNextRendered()) {
    46524652        if (!frame->loader().subframeLoader().containsPlugins())
    46534653            continue;
Note: See TracChangeset for help on using the changeset viewer.