Changeset 45710 in webkit
- Timestamp:
- Jul 10, 2009 9:54:14 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r45709 r45710 1 2009-07-10 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Simon Fraser. 4 5 - test for https://bugs.webkit.org/show_bug.cgi?id=27137 6 <rdar://problem/7043124> REGRESSION (r44311): Reproducible crash due 7 to infinite recursion into FrameLoader::gotoAnchor() -> 8 FrameView::layout() 9 10 * fast/loader/goto-anchor-infinite-layout-expected.txt: Added. 11 * fast/loader/goto-anchor-infinite-layout.html: Added. 12 1 13 2009-07-09 Simon Hausmann <hausmann@webkit.org> 2 14 -
trunk/WebCore/ChangeLog
r45707 r45710 1 2009-07-10 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Simon Fraser. 4 5 - fix https://bugs.webkit.org/show_bug.cgi?id=27137 6 <rdar://problem/7043124> REGRESSION (r44311): Reproducible crash due 7 to infinite recursion into FrameLoader::gotoAnchor() -> 8 FrameView::layout() 9 10 Test: fast/loader/goto-anchor-infinite-layout.html 11 12 * loader/FrameLoader.cpp: 13 (WebCore::FrameLoader::gotoAnchor): Moved the code to update layout, 14 find the renderer to scroll to, and scroll from here to methods on 15 FrameView, and replaced it with a call to 16 FrameView::maintainScrollPositionAtAnchor(). 17 (WebCore::FrameLoader::completed): Call maintainScrollPositionAtAnchor() 18 instead of setLockedToAnchor(). 19 20 * page/FrameView.cpp: 21 (WebCore::FrameView::FrameView): Removed initialization of 22 m_lockedToAnchor. 23 (WebCore::FrameView::reset): Reset m_maintainScrollPositionAnchor instead 24 of m_lockedToAnchor. 25 (WebCore::FrameView::layout): Removed the code related to scrolling to 26 the anchor from here, because scrolling can trigger events which 27 invalidate the layout, and as such, belongs with the post-layout tasks. 28 (WebCore::FrameView::maintainScrollPositionAtAnchor): Added. When called 29 with a node scrolls the view to the top of that node and maintains it 30 scrolled to the top of the node during subsequent layouts, until 31 this function is called with 0 or other things trigger scrolling. 32 (WebCore::FrameView::scrollRectIntoViewRecursively): Reset 33 m_maintainScrollPositionAnchor. 34 (WebCore::FrameView::setScrollPosition): Ditto. 35 (WebCore::FrameView::scrollToAnchor): Added. Scrolls to the top of 36 m_maintainScrollPositionAnchor, if it is set. 37 (WebCore::FrameView::performPostLayoutTasks): Call scrollToAnchor(). 38 (WebCore::FrameView::setWasScrolledByUser): Reset 39 m_maintainScrollPositionAnchor. 40 41 * page/FrameView.h: Removed lockedToAnchor(), setLockedToAnchor(), 42 and m_lockedToAnchor. Added maintainScrollPositionAtAnchor() and 43 m_maintainScrollPositionAnchor. 44 1 45 2009-07-04 Sriram Yadavalli <sriram.yadavalli@nokia.com> 2 46 -
trunk/WebCore/loader/FrameLoader.cpp
r45679 r45710 1590 1590 return false; 1591 1591 1592 // We need to update the layout before scrolling, otherwise we could 1593 // really mess things up if an anchor scroll comes at a bad moment. 1594 m_frame->document()->updateStyleIfNeeded(); 1595 // Only do a layout if changes have occurred that make it necessary. 1596 if (m_frame->view() && m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout()) 1597 m_frame->view()->layout(); 1598 1599 // Scroll nested layers and frames to reveal the anchor. 1600 // Align to the top and to the closest side (this matches other browsers). 1601 RenderObject* renderer; 1602 IntRect rect; 1603 if (!anchorNode) 1604 renderer = m_frame->document()->renderer(); // top of document 1605 else { 1606 renderer = anchorNode->renderer(); 1607 rect = anchorNode->getRect(); 1608 } 1609 if (renderer) { 1610 renderer->enclosingLayer()->scrollRectToVisible(rect, true, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways); 1611 if (m_frame->view()) 1612 m_frame->view()->setLockedToAnchor(true); 1613 } 1592 if (FrameView* view = m_frame->view()) 1593 view->maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document()); 1614 1594 1615 1595 return true; … … 2115 2095 parent->loader()->checkCompleted(); 2116 2096 if (m_frame->view()) 2117 m_frame->view()-> setLockedToAnchor(false);2097 m_frame->view()->maintainScrollPositionAtAnchor(0); 2118 2098 } 2119 2099 -
trunk/WebCore/page/FrameView.cpp
r45679 r45710 112 112 , m_deferSetNeedsLayouts(0) 113 113 , m_setNeedsLayoutWasDeferred(false) 114 , m_lockedToAnchor(false)115 114 { 116 115 init(); … … 186 185 m_isVisuallyNonEmpty = false; 187 186 m_firstVisuallyNonEmptyLayoutCallbackPending = true; 188 m_ lockedToAnchor = false;187 m_maintainScrollPositionAnchor = 0; 189 188 } 190 189 … … 667 666 } 668 667 669 if (lockedToAnchor())670 m_frame->loader()->gotoAnchor();671 672 668 m_nestedLayoutCount--; 673 669 } … … 752 748 } 753 749 750 void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode) 751 { 752 m_maintainScrollPositionAnchor = anchorNode; 753 if (!m_maintainScrollPositionAnchor) 754 return; 755 756 // We need to update the layout before scrolling, otherwise we could 757 // really mess things up if an anchor scroll comes at a bad moment. 758 m_frame->document()->updateStyleIfNeeded(); 759 // Only do a layout if changes have occurred that make it necessary. 760 if (m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout()) 761 layout(); 762 else 763 scrollToAnchor(); 764 } 765 754 766 void FrameView::scrollRectIntoViewRecursively(const IntRect& r) 755 767 { 756 768 bool wasInProgrammaticScroll = m_inProgrammaticScroll; 757 769 m_inProgrammaticScroll = true; 758 setLockedToAnchor(false);770 m_maintainScrollPositionAnchor = 0; 759 771 ScrollView::scrollRectIntoViewRecursively(r); 760 772 m_inProgrammaticScroll = wasInProgrammaticScroll; … … 765 777 bool wasInProgrammaticScroll = m_inProgrammaticScroll; 766 778 m_inProgrammaticScroll = true; 767 setLockedToAnchor(false);779 m_maintainScrollPositionAnchor = 0; 768 780 ScrollView::setScrollPosition(scrollPoint); 769 781 m_inProgrammaticScroll = wasInProgrammaticScroll; … … 1119 1131 } 1120 1132 1133 void FrameView::scrollToAnchor() 1134 { 1135 RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor; 1136 if (!anchorNode) 1137 return; 1138 1139 if (!anchorNode->renderer()) 1140 return; 1141 1142 IntRect rect; 1143 if (anchorNode != m_frame->document()) 1144 rect = anchorNode->getRect(); 1145 1146 // Scroll nested layers and frames to reveal the anchor. 1147 // Align to the top and to the closest side (this matches other browsers). 1148 anchorNode->renderer()->enclosingLayer()->scrollRectToVisible(rect, true, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways); 1149 1150 // scrollRectToVisible can call into scrollRectIntoViewRecursively(), which resets m_maintainScrollPositionAnchor. 1151 m_maintainScrollPositionAnchor = anchorNode; 1152 } 1153 1121 1154 bool FrameView::updateWidgets() 1122 1155 { … … 1162 1195 break; 1163 1196 } 1164 1197 1198 scrollToAnchor(); 1199 1165 1200 resumeScheduledEvents(); 1166 1201 … … 1352 1387 if (m_inProgrammaticScroll) 1353 1388 return; 1354 setLockedToAnchor(false);1389 m_maintainScrollPositionAnchor = 0; 1355 1390 m_wasScrolledByUser = wasScrolledByUser; 1356 1391 } -
trunk/WebCore/page/FrameView.h
r45679 r45710 180 180 void adjustPageHeight(float* newBottom, float oldTop, float oldBottom, float bottomLimit); 181 181 182 bool lockedToAnchor() { return m_lockedToAnchor; } 183 void setLockedToAnchor(bool lockedToAnchor) { m_lockedToAnchor = lockedToAnchor; } 182 void maintainScrollPositionAtAnchor(Node*); 184 183 185 184 // Methods to convert points and rects between the coordinate space of the renderer, and this view. … … 234 233 235 234 bool updateWidgets(); 235 void scrollToAnchor(); 236 236 237 237 static double sCurrentPaintTimeStamp; // used for detecting decoded resource thrash in the cache … … 303 303 bool m_firstVisuallyNonEmptyLayoutCallbackPending; 304 304 305 bool m_lockedToAnchor;305 RefPtr<Node> m_maintainScrollPositionAnchor; 306 306 }; 307 307
Note: See TracChangeset
for help on using the changeset viewer.