2 Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 (C) 1998 Waldo Bastian (bastian@kde.org)
4 (C) 1998, 1999 Torben Weis (weis@kde.org)
5 (C) 1999 Lars Knoll (knoll@kde.org)
6 (C) 1999 Antti Koivisto (koivisto@kde.org)
7 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
19 You should have received a copy of the GNU Library General Public License
20 along with this library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.
28 #include "AdjustViewSizeOrNot.h"
31 #include "LayoutTypes.h"
32 #include "PaintPhase.h"
33 #include "ScrollView.h"
34 #include <wtf/Forward.h>
35 #include <wtf/OwnPtr.h>
36 #include <wtf/text/WTFString.h>
45 class FrameActionScheduler;
50 class RenderEmbeddedObject;
53 class RenderScrollbarPart;
55 typedef unsigned long long DOMTimeStamp;
57 class FrameView : public ScrollView {
59 friend class RenderView;
60 friend class Internals;
62 static PassRefPtr<FrameView> create(Frame*);
63 static PassRefPtr<FrameView> create(Frame*, const IntSize& initialSize);
67 virtual HostWindow* hostWindow() const;
69 virtual void invalidateRect(const IntRect&);
70 virtual void setFrameRect(const IntRect&);
72 #if ENABLE(REQUEST_ANIMATION_FRAME)
73 virtual bool scheduleAnimation();
76 Frame* frame() const { return m_frame.get(); }
78 #if ENABLE(TIZEN_ELEMENTS_NESTED_IN_FLATTENED_FRAME_FIX)
79 bool inFlattenFrame();
82 int mapFromLayoutToCSSUnits(LayoutUnit);
83 LayoutUnit mapFromCSSToLayoutUnits(int);
85 LayoutUnit marginWidth() const { return m_margins.width(); } // -1 means default
86 LayoutUnit marginHeight() const { return m_margins.height(); } // -1 means default
87 void setMarginWidth(LayoutUnit);
88 void setMarginHeight(LayoutUnit);
90 virtual void setCanHaveScrollbars(bool);
91 void updateCanHaveScrollbars();
93 virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
95 virtual bool avoidScrollbarCreation() const;
97 virtual void setContentsSize(const IntSize&);
99 void layout(bool allowSubtree = true);
100 bool didFirstLayout() const;
101 void layoutTimerFired(Timer<FrameView>*);
102 void scheduleRelayout();
103 void scheduleRelayoutOfSubtree(RenderObject*);
104 void unscheduleRelayout();
105 bool layoutPending() const;
106 bool isInLayout() const { return m_inLayout; }
108 RenderObject* layoutRoot(bool onlyDuringLayout = false) const;
109 void clearLayoutRoot() { m_layoutRoot = 0; }
110 int layoutCount() const { return m_layoutCount; }
112 bool needsLayout() const;
113 void setNeedsLayout();
115 bool needsFullRepaint() const { return m_doFullRepaint; }
117 #if ENABLE(REQUEST_ANIMATION_FRAME)
118 void serviceScriptedAnimations(DOMTimeStamp);
121 #if USE(ACCELERATED_COMPOSITING)
122 void updateCompositingLayersAfterStyleChange();
123 void updateCompositingLayersAfterLayout();
124 bool syncCompositingStateForThisFrame(Frame* rootFrameForSync);
126 void clearBackingStores();
127 void restoreBackingStores();
129 // Called when changes to the GraphicsLayer hierarchy have to be synchronized with
130 // content rendered via the normal painting path.
131 void setNeedsOneShotDrawingSynchronization();
133 virtual TiledBacking* tiledBacking() OVERRIDE;
136 bool hasCompositedContent() const;
137 bool hasCompositedContentIncludingDescendants() const;
138 bool hasCompositingAncestor() const;
139 void enterCompositingMode();
140 bool isEnclosedInCompositingLayer() const;
142 // Only used with accelerated compositing, but outside the #ifdef to make linkage easier.
143 // Returns true if the sync was completed.
144 bool syncCompositingStateIncludingSubframes();
146 // Returns true when a paint with the PaintBehaviorFlattenCompositingLayers flag set gives
147 // a faithful representation of the content.
148 bool isSoftwareRenderable() const;
150 void didMoveOnscreen();
151 void willMoveOffscreen();
153 void resetScrollbars();
154 void resetScrollbarsAndClearContentsSize();
155 void detachCustomScrollbars();
156 virtual void recalculateScrollbarOverlayStyle();
160 bool isTransparent() const;
161 void setTransparent(bool isTransparent);
163 Color baseBackgroundColor() const;
164 void setBaseBackgroundColor(const Color&);
165 void updateBackgroundRecursively(const Color&, bool);
167 bool shouldUpdateWhileOffscreen() const;
168 void setShouldUpdateWhileOffscreen(bool);
169 bool shouldUpdate(bool = false) const;
171 void adjustViewSize();
173 virtual IntRect windowClipRect(bool clipToContents = true) const;
174 IntRect windowClipRectForFrameOwner(const HTMLFrameOwnerElement*, bool clipToLayerContents) const;
176 virtual IntRect windowResizerRect() const;
178 virtual void setFixedVisibleContentRect(const IntRect&) OVERRIDE;
180 void setScrollPosition(const IntPoint&);
181 void scrollPositionChangedViaPlatformWidget();
182 virtual void repaintFixedElementsAfterScrolling();
183 virtual void updateFixedElementsAfterScrolling();
184 virtual bool shouldRubberBandInDirection(ScrollDirection) const;
185 virtual bool requestScrollPositionUpdate(const IntPoint&) OVERRIDE;
187 #if ENABLE(TIZEN_WEBKIT2_HISTORICAL_RESTORE_VISIBLE_CONTENT_RECT)
188 virtual void requestVisibleContentRectRestore(const IntPoint& position, float scale);
191 String mediaType() const;
192 void setMediaType(const String&);
193 void adjustMediaTypeForPrinting(bool printing);
195 void setCannotBlitToWindow();
196 void setIsOverlapped(bool);
197 bool isOverlapped() const { return m_isOverlapped; }
198 bool isOverlappedIncludingAncestors() const;
199 void setContentIsOpaque(bool);
201 void addSlowRepaintObject();
202 void removeSlowRepaintObject();
203 bool hasSlowRepaintObjects() const { return m_slowRepaintObjectCount; }
205 typedef HashSet<RenderObject*> FixedObjectSet;
206 void addFixedObject(RenderObject*);
207 void removeFixedObject(RenderObject*);
208 const FixedObjectSet* fixedObjects() const { return m_fixedObjects.get(); }
209 bool hasFixedObjects() const { return m_fixedObjects && m_fixedObjects->size() > 0; }
211 // Functions for querying the current scrolled position, negating the effects of overhang
212 // and adjusting for page scale.
213 IntSize scrollOffsetForFixedPosition() const;
215 bool fixedElementsLayoutRelativeToFrame() const;
217 void beginDeferredRepaints();
218 void endDeferredRepaints();
219 void checkStopDelayingDeferredRepaints();
220 void stopDelayingDeferredRepaints();
221 void startDeferredRepaintTimer(double delay);
222 void resetDeferredRepaintDelay();
224 void beginDisableRepaints();
225 void endDisableRepaints();
226 bool repaintsDisabled() { return m_disableRepaints > 0; }
228 #if ENABLE(DASHBOARD_SUPPORT)
229 void updateDashboardRegions();
231 void updateControlTints();
233 void restoreScrollbar();
235 void scheduleEvent(PassRefPtr<Event>, PassRefPtr<Node>);
236 void pauseScheduledEvents();
237 void resumeScheduledEvents();
238 void postLayoutTimerFired(Timer<FrameView>*);
240 bool wasScrolledByUser() const;
241 void setWasScrolledByUser(bool);
243 bool safeToPropagateScrollToParent() const { return m_safeToPropagateScrollToParent; }
244 void setSafeToPropagateScrollToParent(bool isSafe) { m_safeToPropagateScrollToParent = isSafe; }
246 void addWidgetToUpdate(RenderEmbeddedObject*);
247 void removeWidgetToUpdate(RenderEmbeddedObject*);
249 virtual void paintContents(GraphicsContext*, const IntRect& damageRect);
251 void setPaintBehavior(PaintBehavior);
252 PaintBehavior paintBehavior() const;
253 bool isPainting() const;
254 bool hasEverPainted() const { return m_lastPaintTime; }
255 void setLastPaintTime(double lastPaintTime) { m_lastPaintTime = lastPaintTime; }
256 void setNodeToDraw(Node*);
258 virtual void paintOverhangAreas(GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
259 virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
260 virtual void paintScrollbar(GraphicsContext*, Scrollbar*, const IntRect&) OVERRIDE;
262 Color documentBackgroundColor() const;
264 bool isInChildFrameWithFrameFlattening() const;
266 static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting
268 void updateLayoutAndStyleIfNeededRecursive();
269 void flushDeferredRepaints();
271 void incrementVisuallyNonEmptyCharacterCount(unsigned);
272 void incrementVisuallyNonEmptyPixelCount(const IntSize&);
273 void setIsVisuallyNonEmpty() { m_isVisuallyNonEmpty = true; }
274 bool isVisuallyNonEmpty() const { return m_isVisuallyNonEmpty; }
275 void enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize);
277 void forceLayout(bool allowSubtree = false);
278 void forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor, AdjustViewSizeOrNot);
280 // FIXME: This method is retained because of embedded WebViews in AppKit. When a WebView is embedded inside
281 // some enclosing view with auto-pagination, no call happens to resize the view. The new pagination model
282 // needs the view to resize as a result of the breaks, but that means that the enclosing view has to potentially
283 // resize around that view. Auto-pagination uses the bounds of the actual view that's being printed to determine
284 // the edges of the print operation, so the resize is necessary if the enclosing view's bounds depend on the
285 // web document's bounds.
287 // This is already a problem if the view needs to be a different size because of printer fonts or because of print stylesheets.
288 // Mail/Dictionary work around this problem by using the _layoutForPrinting SPI
289 // to at least get print stylesheets and printer fonts into play, but since WebKit doesn't know about the page offset or
290 // page size, it can't actually paginate correctly during _layoutForPrinting.
292 // We can eventually move Mail to a newer SPI that would let them opt in to the layout-time pagination model,
293 // but that doesn't solve the general problem of how other AppKit views could opt in to the better model.
295 // NO OTHER PLATFORM BESIDES MAC SHOULD USE THIS METHOD.
296 void adjustPageHeightDeprecated(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
298 bool scrollToFragment(const KURL&);
299 bool scrollToAnchor(const String&);
300 void maintainScrollPositionAtAnchor(Node*);
301 void scrollElementToRect(Element*, const IntRect&);
303 // Methods to convert points and rects between the coordinate space of the renderer, and this view.
304 virtual IntRect convertFromRenderer(const RenderObject*, const IntRect&) const;
305 virtual IntRect convertToRenderer(const RenderObject*, const IntRect&) const;
306 virtual IntPoint convertFromRenderer(const RenderObject*, const IntPoint&) const;
307 virtual IntPoint convertToRenderer(const RenderObject*, const IntPoint&) const;
309 bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
311 enum ScrollbarModesCalculationStrategy { RulesFromWebContentOnly, AnyRule };
312 void calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy = AnyRule);
315 static void setRepaintThrottlingDeferredRepaintDelay(double p);
316 // Negative value would mean that first few repaints happen without a delay
317 static void setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p);
318 // The delay grows on each repaint to this maximum value
319 static void setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p);
320 // On each repaint the delay increses by this amount
321 static void setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p);
323 virtual IntPoint currentMousePosition() const;
325 // FIXME: Remove this method once plugin loading is decoupled from layout.
326 void flushAnyPendingPostLayoutTasks();
328 virtual bool shouldSuspendScrollAnimations() const;
329 virtual void scrollbarStyleChanged(int newStyle, bool forceUpdate);
331 void setAnimatorsAreActive();
333 RenderBox* embeddedContentBox() const;
335 void setTracksRepaints(bool);
336 bool isTrackingRepaints() const { return m_isTrackingRepaints; }
337 void resetTrackedRepaints() { m_trackedRepaintRects.clear(); }
338 const Vector<IntRect>& trackedRepaintRects() const { return m_trackedRepaintRects; }
340 typedef HashSet<ScrollableArea*> ScrollableAreaSet;
341 void addScrollableArea(ScrollableArea*);
342 void removeScrollableArea(ScrollableArea*);
343 bool containsScrollableArea(ScrollableArea*) const;
344 const ScrollableAreaSet* scrollableAreas() const { return m_scrollableAreas.get(); }
346 virtual void removeChild(Widget*) OVERRIDE;
348 // This function exists for ports that need to handle wheel events manually.
349 // On Mac WebKit1 the underlying NSScrollView just does the scrolling, but on most other platforms
350 // we need this function in order to do the scroll ourselves.
351 bool wheelEvent(const PlatformWheelEvent&);
354 virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
355 virtual void scrollContentsSlowPath(const IntRect& updateRect);
357 virtual bool isVerticalDocument() const;
358 virtual bool isFlippedDocument() const;
361 explicit FrameView(Frame*);
366 virtual bool isFrameView() const;
368 friend class RenderWidget;
369 bool useSlowRepaints(bool considerOverlap = true) const;
370 bool useSlowRepaintsIfNotOverlapped() const;
371 void updateCanBlitOnScrollRecursively();
372 bool contentsInCompositedLayer() const;
374 void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
376 void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow);
378 void paintControlTints();
380 void forceLayoutParentViewIfNeeded();
381 void performPostLayoutTasks();
382 void autoSizeIfEnabled();
384 virtual void repaintContentRectangle(const IntRect&, bool immediate);
385 virtual void contentsResized() OVERRIDE;
386 virtual void visibleContentsResized();
388 virtual void delegatesScrollingDidChange();
390 // Override ScrollView methods to do point conversion via renderers, in order to
391 // take transforms into account.
392 virtual IntRect convertToContainingView(const IntRect&) const;
393 virtual IntRect convertFromContainingView(const IntRect&) const;
394 virtual IntPoint convertToContainingView(const IntPoint&) const;
395 virtual IntPoint convertFromContainingView(const IntPoint&) const;
397 // ScrollableArea interface
398 virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
399 virtual bool isActive() const;
400 virtual void getTickmarks(Vector<IntRect>&) const;
401 virtual void scrollTo(const IntSize&);
402 virtual void setVisibleScrollerThumbRect(const IntRect&);
403 virtual bool isOnActivePage() const;
404 virtual ScrollableArea* enclosingScrollableArea() const;
405 virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
407 void updateScrollableAreaSet();
409 #if USE(ACCELERATED_COMPOSITING)
410 virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE;
411 virtual GraphicsLayer* layerForVerticalScrollbar() const OVERRIDE;
412 virtual GraphicsLayer* layerForScrollCorner() const OVERRIDE;
413 #if ENABLE(RUBBER_BANDING)
414 virtual GraphicsLayer* layerForOverhangAreas() const OVERRIDE;
418 virtual void notifyPageThatContentAreaWillPaint() const;
420 virtual bool scrollAnimatorEnabled() const;
422 void deferredRepaintTimerFired(Timer<FrameView>*);
423 void doDeferredRepaints();
424 void updateDeferredRepaintDelay();
425 double adjustedDeferredRepaintDelay() const;
427 bool updateWidgets();
428 void updateWidget(RenderEmbeddedObject*);
429 void scrollToAnchor();
430 void scrollPositionChanged();
432 bool hasCustomScrollbars() const;
434 virtual void updateScrollCorner();
436 FrameView* parentFrameView() const;
438 bool doLayoutWithFrameFlattening(bool allowSubtree);
440 virtual AXObjectCache* axObjectCache() const;
441 void notifyWidgetsInAllFrames(WidgetNotification);
443 static double sCurrentPaintTimeStamp; // used for detecting decoded resource thrash in the cache
446 LayoutSize m_margins;
448 typedef HashSet<RenderEmbeddedObject*> RenderEmbeddedObjectSet;
449 OwnPtr<RenderEmbeddedObjectSet> m_widgetUpdateSet;
450 RefPtr<Frame> m_frame;
452 bool m_doFullRepaint;
454 bool m_canHaveScrollbars;
455 bool m_cannotBlitToWindow;
457 bool m_contentIsOpaque;
458 unsigned m_slowRepaintObjectCount;
462 Timer<FrameView> m_layoutTimer;
463 bool m_delayedLayout;
464 RenderObject* m_layoutRoot;
466 bool m_layoutSchedulingEnabled;
468 bool m_inSynchronousPostLayout;
470 unsigned m_nestedLayoutCount;
471 Timer<FrameView> m_postLayoutTasksTimer;
472 bool m_firstLayoutCallbackPending;
475 bool m_isTransparent;
476 Color m_baseBackgroundColor;
477 IntSize m_lastViewportSize;
478 float m_lastZoomFactor;
481 String m_mediaTypeWhenNotPrinting;
483 OwnPtr<FrameActionScheduler> m_actionScheduler;
485 bool m_overflowStatusDirty;
486 bool m_horizontalOverflow;
487 bool m_verticalOverflow;
488 RenderObject* m_viewportRenderer;
490 bool m_wasScrolledByUser;
491 bool m_inProgrammaticScroll;
492 bool m_safeToPropagateScrollToParent;
494 unsigned m_deferringRepaints;
495 unsigned m_repaintCount;
496 Vector<LayoutRect> m_repaintRects;
497 Timer<FrameView> m_deferredRepaintTimer;
498 double m_deferredRepaintDelay;
499 double m_lastPaintTime;
501 unsigned m_disableRepaints;
503 bool m_isTrackingRepaints; // Used for testing.
504 Vector<IntRect> m_trackedRepaintRects;
506 bool m_shouldUpdateWhileOffscreen;
508 unsigned m_deferSetNeedsLayouts;
509 bool m_setNeedsLayoutWasDeferred;
511 RefPtr<Node> m_nodeToDraw;
512 PaintBehavior m_paintBehavior;
515 unsigned m_visuallyNonEmptyCharacterCount;
516 unsigned m_visuallyNonEmptyPixelCount;
517 bool m_isVisuallyNonEmpty;
518 bool m_firstVisuallyNonEmptyLayoutCallbackPending;
520 RefPtr<Node> m_maintainScrollPositionAnchor;
522 // Renderer to hold our custom scroll corner.
523 RenderScrollbarPart* m_scrollCorner;
525 // If true, automatically resize the frame view around its content.
526 bool m_shouldAutoSize;
528 // True if autosize has been run since m_shouldAutoSize was set.
529 bool m_didRunAutosize;
530 // The lower bound on the size when autosizing.
531 IntSize m_minAutoSize;
532 // The upper bound on the size when autosizing.
533 IntSize m_maxAutoSize;
535 OwnPtr<ScrollableAreaSet> m_scrollableAreas;
536 OwnPtr<FixedObjectSet> m_fixedObjects;
538 static double s_deferredRepaintDelay;
539 static double s_initialDeferredRepaintDelayDuringLoading;
540 static double s_maxDeferredRepaintDelayDuringLoading;
541 static double s_deferredRepaintDelayIncrementDuringLoading;
544 inline void FrameView::incrementVisuallyNonEmptyCharacterCount(unsigned count)
546 if (m_isVisuallyNonEmpty)
548 m_visuallyNonEmptyCharacterCount += count;
549 // Use a threshold value to prevent very small amounts of visible content from triggering didFirstVisuallyNonEmptyLayout.
550 // The first few hundred characters rarely contain the interesting content of the page.
551 static const unsigned visualCharacterThreshold = 200;
552 if (m_visuallyNonEmptyCharacterCount > visualCharacterThreshold)
553 setIsVisuallyNonEmpty();
556 inline void FrameView::incrementVisuallyNonEmptyPixelCount(const IntSize& size)
558 if (m_isVisuallyNonEmpty)
560 m_visuallyNonEmptyPixelCount += size.width() * size.height();
561 // Use a threshold value to prevent very small amounts of visible content from triggering didFirstVisuallyNonEmptyLayout
562 static const unsigned visualPixelThreshold = 32 * 32;
563 if (m_visuallyNonEmptyPixelCount > visualPixelThreshold)
564 setIsVisuallyNonEmpty();
567 inline int FrameView::mapFromLayoutToCSSUnits(LayoutUnit value)
569 return value / (m_frame->pageZoomFactor() * m_frame->frameScaleFactor());
572 inline LayoutUnit FrameView::mapFromCSSToLayoutUnits(int value)
574 return value * m_frame->pageZoomFactor() * m_frame->frameScaleFactor();
577 } // namespace WebCore
579 #endif // FrameView_h