Changeset 188298 in webkit
- Timestamp:
- Aug 11, 2015 2:50:32 PM (9 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r188291 r188298 1 2015-08-11 Zalan Bujtas <zalan@apple.com> 2 3 Invalid FrameView::m_viewportRenderer after layout is finished. 4 https://bugs.webkit.org/show_bug.cgi?id=147848 5 rdar://problem/22205197 6 7 Reviewed by Simon Fraser. 8 9 We cache the current viewport renderer (FrameView::m_viewportRenderer) right before layout. 10 It gets dereferenced later when layout is finished to update the overflow status. 11 If the viewport renderer gets destroyed during layout, we end up with a dangling pointer. 12 This patch replaces the pointer caching with type caching (none, body, document). 13 14 Unable to construct a test case. 15 1 16 2015-08-11 Brent Fulgham <bfulgham@apple.com> 2 17 -
trunk/Source/WebCore/page/FrameView.cpp
r188164 r188298 173 173 , m_mediaType("screen") 174 174 , m_overflowStatusDirty(true) 175 , m_viewportRenderer(nullptr)176 175 , m_wasScrolledByUser(false) 177 176 , m_inProgrammaticScroll(false) … … 622 621 { 623 622 RenderView* renderView = this->renderView(); 624 if (!renderView || !m_viewportRenderer || !is<RenderBox>(m_viewportRenderer) || !frame().isMainFrame()) 623 auto* viewportRenderer = this->viewportRenderer(); 624 if (!renderView || !is<RenderBox>(viewportRenderer) || !frame().isMainFrame()) 625 625 return contentsSize(); 626 626 … … 628 628 629 629 FloatRect contentRect = renderView->unscaledDocumentRect(); 630 RenderBox& viewportRendererBox = downcast<RenderBox>(* m_viewportRenderer);631 632 if ( m_viewportRenderer->style().overflowX() == OHIDDEN)630 RenderBox& viewportRendererBox = downcast<RenderBox>(*viewportRenderer); 631 632 if (viewportRendererBox.style().overflowX() == OHIDDEN) 633 633 contentRect.setWidth(std::min<float>(contentRect.width(), viewportRendererBox.frameRect().width())); 634 634 635 if ( m_viewportRenderer->style().overflowY() == OHIDDEN)635 if (viewportRendererBox.style().overflowY() == OHIDDEN) 636 636 contentRect.setHeight(std::min<float>(contentRect.height(), viewportRendererBox.frameRect().height())); 637 637 … … 642 642 } 643 643 644 void FrameView::applyOverflowToViewport( RenderElement*renderer, ScrollbarMode& hMode, ScrollbarMode& vMode)644 void FrameView::applyOverflowToViewport(const RenderElement& renderer, ScrollbarMode& hMode, ScrollbarMode& vMode) 645 645 { 646 646 // Handle the overflow:hidden/scroll case for the body/html elements. WinIE treats … … 655 655 bool overrideHidden = frame().isMainFrame() && ((frame().frameScaleFactor() > 1) || headerHeight() || footerHeight()); 656 656 657 EOverflow overflowX = renderer ->style().overflowX();658 EOverflow overflowY = renderer ->style().overflowY();659 660 if (is<RenderSVGRoot>( *renderer)) {657 EOverflow overflowX = renderer.style().overflowX(); 658 EOverflow overflowY = renderer.style().overflowY(); 659 660 if (is<RenderSVGRoot>(renderer)) { 661 661 // FIXME: evaluate if we can allow overflow for these cases too. 662 662 // Overflow is always hidden when stand-alone SVG documents are embedded. 663 if (downcast<RenderSVGRoot>( *renderer).isEmbeddedThroughFrameContainingSVGDocument()) {663 if (downcast<RenderSVGRoot>(renderer).isEmbeddedThroughFrameContainingSVGDocument()) { 664 664 overflowX = OHIDDEN; 665 665 overflowY = OHIDDEN; … … 702 702 ; 703 703 } 704 705 m_viewportRenderer = renderer;706 704 } 707 705 … … 734 732 void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy) 735 733 { 736 m_viewportRenderer = nullptr;734 m_viewportRendererType = ViewportRendererType::None; 737 735 738 736 const HTMLFrameOwnerElement* owner = frame().ownerElement(); … … 751 749 } 752 750 753 if (!m_layoutRoot) { 754 Document* document = frame().document(); 755 auto documentElement = document->documentElement(); 756 RenderElement* rootRenderer = documentElement ? documentElement->renderer() : nullptr; 757 auto* body = document->bodyOrFrameset(); 758 if (body && body->renderer()) { 759 if (is<HTMLFrameSetElement>(*body) && !frameFlatteningEnabled()) { 760 vMode = ScrollbarAlwaysOff; 761 hMode = ScrollbarAlwaysOff; 762 } else if (is<HTMLBodyElement>(*body)) { 763 // It's sufficient to just check the X overflow, 764 // since it's illegal to have visible in only one direction. 765 RenderElement* o = rootRenderer->style().overflowX() == OVISIBLE && is<HTMLHtmlElement>(*document->documentElement()) ? body->renderer() : rootRenderer; 766 applyOverflowToViewport(o, hMode, vMode); 751 if (m_layoutRoot) 752 return; 753 754 auto* document = frame().document(); 755 if (!document) 756 return; 757 758 auto documentElement = document->documentElement(); 759 if (!documentElement) 760 return; 761 762 auto* bodyOrFrameset = document->bodyOrFrameset(); 763 auto* rootRenderer = documentElement->renderer(); 764 if (!bodyOrFrameset || !bodyOrFrameset->renderer()) { 765 if (rootRenderer) { 766 applyOverflowToViewport(*rootRenderer, hMode, vMode); 767 m_viewportRendererType = ViewportRendererType::Document; 768 } 769 return; 770 } 771 772 if (is<HTMLFrameSetElement>(*bodyOrFrameset) && !frameFlatteningEnabled()) { 773 vMode = ScrollbarAlwaysOff; 774 hMode = ScrollbarAlwaysOff; 775 return; 776 } 777 778 if (is<HTMLBodyElement>(*bodyOrFrameset) && rootRenderer) { 779 // It's sufficient to just check the X overflow, 780 // since it's illegal to have visible in only one direction. 781 if (rootRenderer->style().overflowX() == OVISIBLE && is<HTMLHtmlElement>(documentElement)) { 782 auto* bodyRenderer = bodyOrFrameset->renderer(); 783 if (bodyRenderer) { 784 applyOverflowToViewport(*bodyRenderer, hMode, vMode); 785 m_viewportRendererType = ViewportRendererType::Body; 767 786 } 768 } else if (rootRenderer) 769 applyOverflowToViewport(rootRenderer, hMode, vMode); 770 } 787 } else { 788 applyOverflowToViewport(*rootRenderer, hMode, vMode); 789 m_viewportRendererType = ViewportRendererType::Document; 790 } 791 } 771 792 } 772 793 … … 3264 3285 } 3265 3286 3287 RenderElement* FrameView::viewportRenderer() const 3288 { 3289 if (m_viewportRendererType == ViewportRendererType::None) 3290 return nullptr; 3291 3292 auto* document = frame().document(); 3293 if (!document) 3294 return nullptr; 3295 3296 if (m_viewportRendererType == ViewportRendererType::Document) { 3297 auto* documentElement = document->documentElement(); 3298 if (!documentElement) 3299 return nullptr; 3300 return documentElement->renderer(); 3301 } 3302 3303 if (m_viewportRendererType == ViewportRendererType::Body) { 3304 auto* body = document->body(); 3305 if (!body) 3306 return nullptr; 3307 return body->renderer(); 3308 } 3309 3310 ASSERT_NOT_REACHED(); 3311 return nullptr; 3312 } 3313 3266 3314 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow) 3267 3315 { 3268 if (!m_viewportRenderer) 3316 auto* viewportRenderer = this->viewportRenderer(); 3317 if (!viewportRenderer) 3269 3318 return; 3270 3319 … … 3285 3334 RefPtr<OverflowEvent> overflowEvent = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, 3286 3335 verticalOverflowChanged, verticalOverflow); 3287 overflowEvent->setTarget( m_viewportRenderer->element());3336 overflowEvent->setTarget(viewportRenderer->element()); 3288 3337 3289 3338 frame().document()->enqueueOverflowEvent(overflowEvent.release()); -
trunk/Source/WebCore/page/FrameView.h
r188163 r188298 595 595 virtual void scrollPositionChangedViaPlatformWidgetImpl(const IntPoint& oldPosition, const IntPoint& newPosition) override; 596 596 597 void applyOverflowToViewport( RenderElement*, ScrollbarMode& hMode, ScrollbarMode& vMode);597 void applyOverflowToViewport(const RenderElement&, ScrollbarMode& hMode, ScrollbarMode& vMode); 598 598 void applyPaginationToViewport(); 599 599 … … 676 676 void notifyWidgets(WidgetNotification); 677 677 678 RenderElement* viewportRenderer() const; 679 678 680 HashSet<Widget*> m_widgetsInRenderTree; 679 681 … … 719 721 bool m_overflowStatusDirty; 720 722 bool m_horizontalOverflow; 721 bool m_verticalOverflow; 722 RenderElement* m_viewportRenderer; 723 bool m_verticalOverflow; 724 enum class ViewportRendererType { None, Document, Body }; 725 ViewportRendererType m_viewportRendererType { ViewportRendererType::None }; 723 726 724 727 Pagination m_pagination;
Note: See TracChangeset
for help on using the changeset viewer.