Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: Source/core/rendering/RenderLayerScrollableArea.cpp

Issue 22893055: Split computeScrollDimensions() out of RenderLayer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Updated after Ian's comment. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderLayerScrollableArea.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * 3 *
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5 * 5 *
6 * Other contributors: 6 * Other contributors:
7 * Robert O'Callahan <roc+@cs.cmu.edu> 7 * Robert O'Callahan <roc+@cs.cmu.edu>
8 * David Baron <dbaron@fas.harvard.edu> 8 * David Baron <dbaron@fas.harvard.edu>
9 * Christian Biesinger <cbiesinger@web.de> 9 * Christian Biesinger <cbiesinger@web.de>
10 * Randall Jesup <rjesup@wgate.com> 10 * Randall Jesup <rjesup@wgate.com>
(...skipping 26 matching lines...) Expand all
37 * version of this file under the LGPL, indicate your decision by 37 * version of this file under the LGPL, indicate your decision by
38 * deletingthe provisions above and replace them with the notice and 38 * deletingthe provisions above and replace them with the notice and
39 * other provisions required by the MPL or the GPL, as the case may be. 39 * other provisions required by the MPL or the GPL, as the case may be.
40 * If you do not delete the provisions above, a recipient may use your 40 * If you do not delete the provisions above, a recipient may use your
41 * version of this file under any of the LGPL, the MPL or the GPL. 41 * version of this file under any of the LGPL, the MPL or the GPL.
42 */ 42 */
43 43
44 #include "config.h" 44 #include "config.h"
45 #include "core/rendering/RenderLayer.h" 45 #include "core/rendering/RenderLayer.h"
46 46
47 #include "core/editing/FrameSelection.h"
48 #include "core/inspector/InspectorInstrumentation.h"
49 #include "core/page/EventHandler.h"
47 #include "core/page/Frame.h" 50 #include "core/page/Frame.h"
48 #include "core/page/FrameView.h" 51 #include "core/page/FrameView.h"
49 #include "core/page/Page.h" 52 #include "core/page/Page.h"
50 #include "core/page/scrolling/ScrollingCoordinator.h" 53 #include "core/page/scrolling/ScrollingCoordinator.h"
51 #include "core/platform/ScrollAnimator.h" 54 #include "core/platform/ScrollAnimator.h"
55 #include "core/rendering/RenderLayerCompositor.h"
56 #include "core/rendering/RenderView.h"
52 57
53 namespace WebCore { 58 namespace WebCore {
54 59
55 RenderLayerScrollableArea::RenderLayerScrollableArea(RenderLayer* layer) 60 RenderLayerScrollableArea::RenderLayerScrollableArea(RenderLayer* layer)
56 : m_layer(layer) 61 : m_layer(layer)
62 , m_scrollDimensionsDirty(true)
57 { 63 {
58 ScrollableArea::setConstrainsScrollingToContentEdge(false); 64 ScrollableArea::setConstrainsScrollingToContentEdge(false);
59 65
60 Node* node = renderer()->node(); 66 Node* node = renderer()->node();
61 if (node && node->isElementNode()) { 67 if (node && node->isElementNode()) {
62 // We save and restore only the scrollOffset as the other scroll values are recalculated. 68 // We save and restore only the scrollOffset as the other scroll values are recalculated.
63 Element* element = toElement(node); 69 Element* element = toElement(node);
64 m_scrollOffset = element->savedLayerScrollOffset(); 70 m_scrollOffset = element->savedLayerScrollOffset();
65 if (!m_scrollOffset.isZero()) 71 if (!m_scrollOffset.isZero())
66 scrollAnimator()->setCurrentPosition(FloatPoint(m_scrollOffset.width (), m_scrollOffset.height())); 72 scrollAnimator()->setCurrentPosition(FloatPoint(m_scrollOffset.width (), m_scrollOffset.height()));
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 IntPoint RenderLayerScrollableArea::convertFromContainingViewToScrollbar(const S crollbar* scrollbar, const IntPoint& point) const 184 IntPoint RenderLayerScrollableArea::convertFromContainingViewToScrollbar(const S crollbar* scrollbar, const IntPoint& point) const
179 { 185 {
180 return m_layer->convertFromContainingViewToScrollbar(scrollbar, point); 186 return m_layer->convertFromContainingViewToScrollbar(scrollbar, point);
181 } 187 }
182 188
183 int RenderLayerScrollableArea::scrollSize(ScrollbarOrientation orientation) cons t 189 int RenderLayerScrollableArea::scrollSize(ScrollbarOrientation orientation) cons t
184 { 190 {
185 return m_layer->scrollSize(orientation); 191 return m_layer->scrollSize(orientation);
186 } 192 }
187 193
188 void RenderLayerScrollableArea::setScrollOffset(const IntPoint& offset) 194 void RenderLayerScrollableArea::setScrollOffset(const IntPoint& newScrollOffset)
189 { 195 {
190 m_layer->setScrollOffset(offset); 196 if (!toRenderBox(renderer())->isMarquee()) {
197 // Ensure that the dimensions will be computed if they need to be (for o verflow:hidden blocks).
198 if (m_scrollDimensionsDirty)
199 computeScrollDimensions();
200 }
201
202 if (scrollOffset() == toIntSize(newScrollOffset))
203 return;
204
205 setScrollOffset(toIntSize(newScrollOffset));
206
207 Frame* frame = renderer()->frame();
208 InspectorInstrumentation::willScrollLayer(renderer());
209
210 RenderView* view = renderer()->view();
211
212 // We should have a RenderView if we're trying to scroll.
213 ASSERT(view);
214
215 // Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
216 // We don't update compositing layers, because we need to do a deep update f rom the compositing ancestor.
217 bool inLayout = view ? view->frameView()->isInLayout() : false;
218 if (!inLayout) {
219 // If we're in the middle of layout, we'll just update layers once layou t has finished.
220 m_layer->updateLayerPositionsAfterOverflowScroll();
221 if (view) {
222 // Update regions, scrolling may change the clip of a particular reg ion.
223 view->frameView()->updateAnnotatedRegions();
224 view->updateWidgetPositions();
225 }
226
227 m_layer->updateCompositingLayersAfterScroll();
228 }
229
230 RenderLayerModelObject* repaintContainer = renderer()->containerForRepaint() ;
231 if (frame) {
232 // The caret rect needs to be invalidated after scrolling
233 frame->selection().setCaretRectNeedsUpdate();
234
235 FloatQuad quadForFakeMouseMoveEvent = FloatQuad(m_layer->m_repaintRect);
236 if (repaintContainer)
237 quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(qu adForFakeMouseMoveEvent);
238 frame->eventHandler()->dispatchFakeMouseMoveEventSoonInQuad(quadForFakeM ouseMoveEvent);
239 }
240
241 bool requiresRepaint = true;
242
243 if (m_layer->compositor()->inCompositingMode() && m_layer->usesCompositedScr olling())
244 requiresRepaint = false;
245
246 // Just schedule a full repaint of our object.
247 if (view && requiresRepaint)
248 renderer()->repaintUsingContainer(repaintContainer, pixelSnappedIntRect( m_layer->m_repaintRect));
249
250 // Schedule the scroll DOM event.
251 if (renderer()->node())
252 renderer()->node()->document().eventQueue()->enqueueOrDispatchScrollEven t(renderer()->node(), DocumentEventQueue::ScrollEventElementTarget);
253
254 InspectorInstrumentation::didScrollLayer(renderer());
191 } 255 }
192 256
193 IntPoint RenderLayerScrollableArea::scrollPosition() const 257 IntPoint RenderLayerScrollableArea::scrollPosition() const
194 { 258 {
195 return IntPoint(m_scrollOffset); 259 return IntPoint(m_scrollOffset);
196 } 260 }
197 261
198 IntPoint RenderLayerScrollableArea::minimumScrollPosition() const 262 IntPoint RenderLayerScrollableArea::minimumScrollPosition() const
199 { 263 {
200 return m_layer->minimumScrollPosition(); 264 return -scrollOrigin();
201 } 265 }
202 266
203 IntPoint RenderLayerScrollableArea::maximumScrollPosition() const 267 IntPoint RenderLayerScrollableArea::maximumScrollPosition() const
204 { 268 {
205 return m_layer->maximumScrollPosition(); 269 RenderBox* box = toRenderBox(renderer());
270
271 if (!box->hasOverflowClip())
272 return -scrollOrigin();
273
274 return -scrollOrigin() + enclosingIntRect(m_overflowRect).size() - enclosing IntRect(box->clientBoxRect()).size();
206 } 275 }
207 276
208 IntRect RenderLayerScrollableArea::visibleContentRect(VisibleContentRectIncludes Scrollbars scrollbarInclusion) const 277 IntRect RenderLayerScrollableArea::visibleContentRect(VisibleContentRectIncludes Scrollbars scrollbarInclusion) const
209 { 278 {
210 int verticalScrollbarWidth = 0; 279 int verticalScrollbarWidth = 0;
211 int horizontalScrollbarHeight = 0; 280 int horizontalScrollbarHeight = 0;
212 if (scrollbarInclusion == IncludeScrollbars) { 281 if (scrollbarInclusion == IncludeScrollbars) {
213 verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->i sOverlayScrollbar()) ? verticalScrollbar()->width() : 0; 282 verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->i sOverlayScrollbar()) ? verticalScrollbar()->width() : 0;
214 horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollb ar()->isOverlayScrollbar()) ? horizontalScrollbar()->height() : 0; 283 horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollb ar()->isOverlayScrollbar()) ? horizontalScrollbar()->height() : 0;
215 } 284 }
216 285
217 return IntRect(IntPoint(scrollXOffset(), scrollYOffset()), 286 return IntRect(IntPoint(scrollXOffset(), scrollYOffset()),
218 IntSize(max(0, m_layer->size().width() - verticalScrollbarWidth), max(0, m_layer->size().height() - horizontalScrollbarHeight))); 287 IntSize(max(0, m_layer->size().width() - verticalScrollbarWidth), max(0, m_layer->size().height() - horizontalScrollbarHeight)));
219 } 288 }
220 289
221 int RenderLayerScrollableArea::visibleHeight() const 290 int RenderLayerScrollableArea::visibleHeight() const
222 { 291 {
223 return m_layer->visibleHeight(); 292 return m_layer->visibleHeight();
224 } 293 }
225 294
226 int RenderLayerScrollableArea::visibleWidth() const 295 int RenderLayerScrollableArea::visibleWidth() const
227 { 296 {
228 return m_layer->visibleWidth(); 297 return m_layer->visibleWidth();
229 } 298 }
230 299
231 IntSize RenderLayerScrollableArea::contentsSize() const 300 IntSize RenderLayerScrollableArea::contentsSize() const
232 { 301 {
233 return m_layer->contentsSize(); 302 return IntSize(scrollWidth(), scrollHeight());
234 } 303 }
235 304
236 IntSize RenderLayerScrollableArea::overhangAmount() const 305 IntSize RenderLayerScrollableArea::overhangAmount() const
237 { 306 {
238 return m_layer->overhangAmount(); 307 return m_layer->overhangAmount();
239 } 308 }
240 309
241 IntPoint RenderLayerScrollableArea::lastKnownMousePosition() const 310 IntPoint RenderLayerScrollableArea::lastKnownMousePosition() const
242 { 311 {
243 return m_layer->lastKnownMousePosition(); 312 return m_layer->lastKnownMousePosition();
(...skipping 24 matching lines...) Expand all
268 return m_layer->pageStep(orientation); 337 return m_layer->pageStep(orientation);
269 } 338 }
270 339
271 RenderLayerModelObject* RenderLayerScrollableArea::renderer() const 340 RenderLayerModelObject* RenderLayerScrollableArea::renderer() const
272 { 341 {
273 // Only RenderBoxes can have a scrollable area, however we allocate an 342 // Only RenderBoxes can have a scrollable area, however we allocate an
274 // RenderLayerScrollableArea for any renderers (FIXME). 343 // RenderLayerScrollableArea for any renderers (FIXME).
275 return m_layer->renderer(); 344 return m_layer->renderer();
276 } 345 }
277 346
347 int RenderLayerScrollableArea::scrollWidth() const
348 {
349 RenderBox* box = toRenderBox(renderer());
350 if (m_scrollDimensionsDirty)
351 const_cast<RenderLayerScrollableArea*>(this)->computeScrollDimensions();
352 return snapSizeToPixel(m_overflowRect.width(), box->clientLeft() + box->x()) ;
353 }
354
355 int RenderLayerScrollableArea::scrollHeight() const
356 {
357 RenderBox* box = toRenderBox(renderer());
358 if (m_scrollDimensionsDirty)
359 const_cast<RenderLayerScrollableArea*>(this)->computeScrollDimensions();
360 return snapSizeToPixel(m_overflowRect.height(), box->clientTop() + box->y()) ;
361 }
362
363 void RenderLayerScrollableArea::computeScrollDimensions()
364 {
365 RenderBox* box = toRenderBox(renderer());
366
367 m_scrollDimensionsDirty = false;
368
369 m_overflowRect = box->layoutOverflowRect();
370 box->flipForWritingMode(m_overflowRect);
371
372 int scrollableLeftOverflow = m_overflowRect.x() - box->borderLeft();
373 int scrollableTopOverflow = m_overflowRect.y() - box->borderTop();
374 setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
375 }
376
377 void RenderLayerScrollableArea::scrollToOffset(const IntSize& scrollOffset, Scro llOffsetClamping clamp)
378 {
379 IntSize newScrollOffset = clamp == ScrollOffsetClamped ? clampScrollOffset(s crollOffset) : scrollOffset;
380 if (newScrollOffset != adjustedScrollOffset())
381 scrollToOffsetWithoutAnimation(-scrollOrigin() + newScrollOffset);
382 }
383
384 void RenderLayerScrollableArea::updateAfterLayout()
385 {
386 m_scrollDimensionsDirty = true;
387 IntSize originalScrollOffset = adjustedScrollOffset();
388
389 computeScrollDimensions();
390
391 if (!toRenderBox(renderer())->isMarquee()) {
392 // Layout may cause us to be at an invalid scroll position. In this case we need
393 // to pull our scroll offsets back to the max (or push them up to the mi n).
394 IntSize clampedScrollOffset = clampScrollOffset(adjustedScrollOffset());
395 if (clampedScrollOffset != adjustedScrollOffset())
396 scrollToOffset(clampedScrollOffset);
397 }
398
399 if (originalScrollOffset != adjustedScrollOffset())
400 scrollToOffsetWithoutAnimation(-scrollOrigin() + adjustedScrollOffset()) ;
401 }
402
403 bool RenderLayerScrollableArea::hasHorizontalOverflow() const
404 {
405 ASSERT(!m_scrollDimensionsDirty);
406
407 return scrollWidth() > toRenderBox(renderer())->pixelSnappedClientWidth();
408 }
409
410 bool RenderLayerScrollableArea::hasVerticalOverflow() const
411 {
412 ASSERT(!m_scrollDimensionsDirty);
413
414 return scrollHeight() > toRenderBox(renderer())->pixelSnappedClientHeight();
415 }
416
417 bool RenderLayerScrollableArea::hasScrollableHorizontalOverflow() const
418 {
419 return hasHorizontalOverflow() && toRenderBox(renderer())->scrollsOverflowX( );
420 }
421
422 bool RenderLayerScrollableArea::hasScrollableVerticalOverflow() const
423 {
424 return hasVerticalOverflow() && toRenderBox(renderer())->scrollsOverflowY();
425 }
426
427 void RenderLayerScrollableArea::updateAfterStyleChange(const RenderStyle*)
428 {
429 if (!m_scrollDimensionsDirty)
430 m_layer->updateScrollableAreaSet(hasScrollableHorizontalOverflow() || ha sScrollableVerticalOverflow());
431 }
432
433 IntSize RenderLayerScrollableArea::clampScrollOffset(const IntSize& scrollOffset ) const
434 {
435 RenderBox* box = toRenderBox(renderer());
436
437 int maxX = scrollWidth() - box->pixelSnappedClientWidth();
438 int maxY = scrollHeight() - box->pixelSnappedClientHeight();
439
440 int x = std::max(std::min(scrollOffset.width(), maxX), 0);
441 int y = std::max(std::min(scrollOffset.height(), maxY), 0);
442 return IntSize(x, y);
443 }
444
278 } // Namespace WebCore 445 } // Namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderLayerScrollableArea.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698