Changeset 190454 in webkit


Ignore:
Timestamp:
Oct 1, 2015 10:35:42 PM (9 years ago)
Author:
bshafiei@apple.com
Message:

Merged r188298. rdar://problem/22936040

Location:
branches/safari-601.1.46-branch/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-601.1.46-branch/Source/WebCore/ChangeLog

    r189902 r190454  
     12015-10-01  Babak Shafiei  <bshafiei@apple.com>
     2
     3        Merge r188298.
     4
     5    2015-08-11  Zalan Bujtas  <zalan@apple.com>
     6
     7            Invalid FrameView::m_viewportRenderer after layout is finished.
     8            https://bugs.webkit.org/show_bug.cgi?id=147848
     9            rdar://problem/22205197
     10
     11            Reviewed by Simon Fraser.
     12
     13            We cache the current viewport renderer (FrameView::m_viewportRenderer) right before layout.
     14            It gets dereferenced later when layout is finished to update the overflow status.
     15            If the viewport renderer gets destroyed during layout, we end up with a dangling pointer.
     16            This patch replaces the pointer caching with type caching (none, body, document).
     17
     18            Unable to construct a test case.
     19
    1202015-09-16  Babak Shafiei  <bshafiei@apple.com>
    221
  • branches/safari-601.1.46-branch/Source/WebCore/page/FrameView.cpp

    r188786 r190454  
    174174    , m_mediaType("screen")
    175175    , m_overflowStatusDirty(true)
    176     , m_viewportRenderer(nullptr)
    177176    , m_wasScrolledByUser(false)
    178177    , m_inProgrammaticScroll(false)
     
    621620{
    622621    RenderView* renderView = this->renderView();
    623     if (!renderView || !m_viewportRenderer || !is<RenderBox>(m_viewportRenderer) || !frame().isMainFrame())
     622    auto* viewportRenderer = this->viewportRenderer();
     623    if (!renderView || !is<RenderBox>(viewportRenderer) || !frame().isMainFrame())
    624624        return contentsSize();
    625625
     
    627627
    628628    FloatRect contentRect = renderView->unscaledDocumentRect();
    629     RenderBox& viewportRendererBox = downcast<RenderBox>(*m_viewportRenderer);
    630 
    631     if (m_viewportRenderer->style().overflowX() == OHIDDEN)
     629    RenderBox& viewportRendererBox = downcast<RenderBox>(*viewportRenderer);
     630
     631    if (viewportRendererBox.style().overflowX() == OHIDDEN)
    632632        contentRect.setWidth(std::min<float>(contentRect.width(), viewportRendererBox.frameRect().width()));
    633633
    634     if (m_viewportRenderer->style().overflowY() == OHIDDEN)
     634    if (viewportRendererBox.style().overflowY() == OHIDDEN)
    635635        contentRect.setHeight(std::min<float>(contentRect.height(), viewportRendererBox.frameRect().height()));
    636636
     
    641641}
    642642
    643 void FrameView::applyOverflowToViewport(RenderElement* renderer, ScrollbarMode& hMode, ScrollbarMode& vMode)
     643void FrameView::applyOverflowToViewport(const RenderElement& renderer, ScrollbarMode& hMode, ScrollbarMode& vMode)
    644644{
    645645    // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
     
    654654    bool overrideHidden = frame().isMainFrame() && ((frame().frameScaleFactor() > 1) || headerHeight() || footerHeight());
    655655
    656     EOverflow overflowX = renderer->style().overflowX();
    657     EOverflow overflowY = renderer->style().overflowY();
    658 
    659     if (is<RenderSVGRoot>(*renderer)) {
     656    EOverflow overflowX = renderer.style().overflowX();
     657    EOverflow overflowY = renderer.style().overflowY();
     658
     659    if (is<RenderSVGRoot>(renderer)) {
    660660        // FIXME: evaluate if we can allow overflow for these cases too.
    661661        // Overflow is always hidden when stand-alone SVG documents are embedded.
    662         if (downcast<RenderSVGRoot>(*renderer).isEmbeddedThroughFrameContainingSVGDocument()) {
     662        if (downcast<RenderSVGRoot>(renderer).isEmbeddedThroughFrameContainingSVGDocument()) {
    663663            overflowX = OHIDDEN;
    664664            overflowY = OHIDDEN;
     
    701701            ;
    702702    }
    703 
    704     m_viewportRenderer = renderer;
    705703}
    706704
     
    733731void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
    734732{
    735     m_viewportRenderer = nullptr;
     733    m_viewportRendererType = ViewportRendererType::None;
    736734
    737735    const HTMLFrameOwnerElement* owner = frame().ownerElement();
     
    750748    }
    751749   
    752     if (!m_layoutRoot) {
    753         Document* document = frame().document();
    754         auto documentElement = document->documentElement();
    755         RenderElement* rootRenderer = documentElement ? documentElement->renderer() : nullptr;
    756         auto* body = document->bodyOrFrameset();
    757         if (body && body->renderer()) {
    758             if (is<HTMLFrameSetElement>(*body) && !frameFlatteningEnabled()) {
    759                 vMode = ScrollbarAlwaysOff;
    760                 hMode = ScrollbarAlwaysOff;
    761             } else if (is<HTMLBodyElement>(*body)) {
    762                 // It's sufficient to just check the X overflow,
    763                 // since it's illegal to have visible in only one direction.
    764                 RenderElement* o = rootRenderer->style().overflowX() == OVISIBLE && is<HTMLHtmlElement>(*document->documentElement()) ? body->renderer() : rootRenderer;
    765                 applyOverflowToViewport(o, hMode, vMode);
     750    if (m_layoutRoot)
     751        return;
     752   
     753    auto* document = frame().document();
     754    if (!document)
     755        return;
     756
     757    auto documentElement = document->documentElement();
     758    if (!documentElement)
     759        return;
     760
     761    auto* bodyOrFrameset = document->bodyOrFrameset();
     762    auto* rootRenderer = documentElement->renderer();
     763    if (!bodyOrFrameset || !bodyOrFrameset->renderer()) {
     764        if (rootRenderer) {
     765            applyOverflowToViewport(*rootRenderer, hMode, vMode);
     766            m_viewportRendererType = ViewportRendererType::Document;
     767        }
     768        return;
     769    }
     770   
     771    if (is<HTMLFrameSetElement>(*bodyOrFrameset) && !frameFlatteningEnabled()) {
     772        vMode = ScrollbarAlwaysOff;
     773        hMode = ScrollbarAlwaysOff;
     774        return;
     775    }
     776
     777    if (is<HTMLBodyElement>(*bodyOrFrameset) && rootRenderer) {
     778        // It's sufficient to just check the X overflow,
     779        // since it's illegal to have visible in only one direction.
     780        if (rootRenderer->style().overflowX() == OVISIBLE && is<HTMLHtmlElement>(documentElement)) {
     781            auto* bodyRenderer = bodyOrFrameset->renderer();
     782            if (bodyRenderer) {
     783                applyOverflowToViewport(*bodyRenderer, hMode, vMode);
     784                m_viewportRendererType = ViewportRendererType::Body;
    766785            }
    767         } else if (rootRenderer)
    768             applyOverflowToViewport(rootRenderer, hMode, vMode);
    769     }   
     786        } else {
     787            applyOverflowToViewport(*rootRenderer, hMode, vMode);
     788            m_viewportRendererType = ViewportRendererType::Document;
     789        }
     790    }
    770791}
    771792
     
    32653286}
    32663287
     3288RenderElement* FrameView::viewportRenderer() const
     3289{
     3290    if (m_viewportRendererType == ViewportRendererType::None)
     3291        return nullptr;
     3292
     3293    auto* document = frame().document();
     3294    if (!document)
     3295        return nullptr;
     3296
     3297    if (m_viewportRendererType == ViewportRendererType::Document) {
     3298        auto* documentElement = document->documentElement();
     3299        if (!documentElement)
     3300            return nullptr;
     3301        return documentElement->renderer();
     3302    }
     3303
     3304    if (m_viewportRendererType == ViewportRendererType::Body) {
     3305        auto* body = document->body();
     3306        if (!body)
     3307            return nullptr;
     3308        return body->renderer();
     3309    }
     3310
     3311    ASSERT_NOT_REACHED();
     3312    return nullptr;
     3313}
     3314
    32673315void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
    32683316{
    3269     if (!m_viewportRenderer)
     3317    auto* viewportRenderer = this->viewportRenderer();
     3318    if (!viewportRenderer)
    32703319        return;
    32713320   
     
    32863335        RefPtr<OverflowEvent> overflowEvent = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
    32873336            verticalOverflowChanged, verticalOverflow);
    3288         overflowEvent->setTarget(m_viewportRenderer->element());
     3337        overflowEvent->setTarget(viewportRenderer->element());
    32893338
    32903339        frame().document()->enqueueOverflowEvent(overflowEvent.release());
  • branches/safari-601.1.46-branch/Source/WebCore/page/FrameView.h

    r188786 r190454  
    599599    virtual void scrollPositionChangedViaPlatformWidgetImpl(const IntPoint& oldPosition, const IntPoint& newPosition) override;
    600600
    601     void applyOverflowToViewport(RenderElement*, ScrollbarMode& hMode, ScrollbarMode& vMode);
     601    void applyOverflowToViewport(const RenderElement&, ScrollbarMode& hMode, ScrollbarMode& vMode);
    602602    void applyPaginationToViewport();
    603603
     
    680680    void notifyWidgets(WidgetNotification);
    681681
     682    RenderElement* viewportRenderer() const;
     683
    682684    HashSet<Widget*> m_widgetsInRenderTree;
    683685
     
    723725    bool m_overflowStatusDirty;
    724726    bool m_horizontalOverflow;
    725     bool m_verticalOverflow;   
    726     RenderElement* m_viewportRenderer;
     727    bool m_verticalOverflow;
     728    enum class ViewportRendererType { None, Document, Body };
     729    ViewportRendererType m_viewportRendererType { ViewportRendererType::None };
    727730
    728731    Pagination m_pagination;
Note: See TracChangeset for help on using the changeset viewer.