1/*
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.
8
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.
13
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.
18
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.
23*/
24
25#ifndef FrameView_h
26#define FrameView_h
27
28#include "Frame.h"
29#include "IntSize.h"
30#include "Page.h"
31#include "RenderObject.h" // For PaintBehavior
32#include "ScrollView.h"
33#include <wtf/Forward.h>
34#include <wtf/OwnPtr.h>
35
36namespace WebCore {
37
38class Color;
39class Event;
40class FrameActionScheduler;
41class FrameViewPrivate;
42class IntRect;
43class Node;
44class PlatformMouseEvent;
45class RenderLayer;
46class RenderObject;
47class RenderEmbeddedObject;
48class RenderScrollbarPart;
49
50template <typename T> class Timer;
51
52class FrameView : public ScrollView {
53public:
54    friend class RenderView;
55
56    static PassRefPtr<FrameView> create(Frame*);
57    static PassRefPtr<FrameView> create(Frame*, const IntSize& initialSize);
58
59    virtual ~FrameView();
60
61    virtual HostWindow* hostWindow() const;
62
63    virtual void invalidateRect(const IntRect&);
64    virtual void setFrameRect(const IntRect&);
65#if ENABLE(REQUEST_ANIMATION_FRAME)
66    void scheduleAnimation();
67#endif
68
69    Frame* frame() const { return m_frame.get(); }
70    void clearFrame();
71
72    int marginWidth() const { return m_margins.width(); } // -1 means default
73    int marginHeight() const { return m_margins.height(); } // -1 means default
74    void setMarginWidth(int);
75    void setMarginHeight(int);
76
77    virtual void setCanHaveScrollbars(bool);
78    void updateCanHaveScrollbars();
79
80    virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
81
82    virtual bool avoidScrollbarCreation() const;
83
84    virtual void setContentsSize(const IntSize&);
85
86    void layout(bool allowSubtree = true);
87    bool didFirstLayout() const;
88    void layoutTimerFired(Timer<FrameView>*);
89    void scheduleRelayout();
90    void scheduleRelayoutOfSubtree(RenderObject*);
91    void unscheduleRelayout();
92    bool layoutPending() const;
93    bool isInLayout() const { return m_inLayout; }
94
95    RenderObject* layoutRoot(bool onlyDuringLayout = false) const;
96    int layoutCount() const { return m_layoutCount; }
97
98    bool needsLayout() const;
99    void setNeedsLayout();
100
101    bool needsFullRepaint() const { return m_doFullRepaint; }
102
103#if ENABLE(REQUEST_ANIMATION_FRAME)
104    void serviceScriptedAnimations(DOMTimeStamp);
105#endif
106
107#if USE(ACCELERATED_COMPOSITING)
108    void updateCompositingLayers();
109    bool syncCompositingStateForThisFrame();
110
111    // Called when changes to the GraphicsLayer hierarchy have to be synchronized with
112    // content rendered via the normal painting path.
113    void setNeedsOneShotDrawingSynchronization();
114#endif
115#if ENABLE(ANDROID_OVERFLOW_SCROLL)
116    bool hasOverflowScroll() const { return m_hasOverflowScroll; }
117#endif
118
119#if PLATFORM(ANDROID)
120    void updatePositionedObjects();
121#endif
122
123    bool hasCompositedContent() const;
124    bool hasCompositedContentIncludingDescendants() const;
125    bool hasCompositingAncestor() const;
126    void enterCompositingMode();
127    bool isEnclosedInCompositingLayer() const;
128
129    // Only used with accelerated compositing, but outside the #ifdef to make linkage easier.
130    // Returns true if the sync was completed.
131    bool syncCompositingStateIncludingSubframes();
132
133    // Returns true when a paint with the PaintBehaviorFlattenCompositingLayers flag set gives
134    // a faithful representation of the content.
135    bool isSoftwareRenderable() const;
136
137    void didMoveOnscreen();
138    void willMoveOffscreen();
139
140    void resetScrollbars();
141    void resetScrollbarsAndClearContentsSize();
142    void detachCustomScrollbars();
143
144    void clear();
145
146    bool isTransparent() const;
147    void setTransparent(bool isTransparent);
148
149    Color baseBackgroundColor() const;
150    void setBaseBackgroundColor(const Color&);
151    void updateBackgroundRecursively(const Color&, bool);
152
153    bool shouldUpdateWhileOffscreen() const;
154    void setShouldUpdateWhileOffscreen(bool);
155    bool shouldUpdate(bool = false) const;
156
157    void adjustViewSize();
158
159    virtual IntRect windowClipRect(bool clipToContents = true) const;
160    IntRect windowClipRectForLayer(const RenderLayer*, bool clipToLayerContents) const;
161
162    virtual IntRect windowResizerRect() const;
163
164    void setScrollPosition(const IntPoint&);
165    void scrollPositionChangedViaPlatformWidget();
166    virtual void repaintFixedElementsAfterScrolling();
167
168    String mediaType() const;
169    void setMediaType(const String&);
170    void adjustMediaTypeForPrinting(bool printing);
171
172    void setUseSlowRepaints();
173    void setIsOverlapped(bool);
174    bool isOverlapped() const { return m_isOverlapped; }
175    bool isOverlappedIncludingAncestors() const;
176    void setContentIsOpaque(bool);
177
178    void addSlowRepaintObject();
179    void removeSlowRepaintObject();
180
181    void addFixedObject();
182    void removeFixedObject();
183
184    // Functions for querying the current scrolled position, negating the effects of overhang
185    // and adjusting for page scale.
186    int scrollXForFixedPosition() const;
187    int scrollYForFixedPosition() const;
188    IntSize scrollOffsetForFixedPosition() const;
189
190    void beginDeferredRepaints();
191    void endDeferredRepaints();
192    void checkStopDelayingDeferredRepaints();
193    void resetDeferredRepaintDelay();
194
195#if ENABLE(DASHBOARD_SUPPORT)
196    void updateDashboardRegions();
197#endif
198    void updateControlTints();
199
200    void restoreScrollbar();
201
202    void scheduleEvent(PassRefPtr<Event>, PassRefPtr<Node>);
203    void pauseScheduledEvents();
204    void resumeScheduledEvents();
205    void postLayoutTimerFired(Timer<FrameView>*);
206
207    bool wasScrolledByUser() const;
208    void setWasScrolledByUser(bool);
209
210    void addWidgetToUpdate(RenderEmbeddedObject*);
211    void removeWidgetToUpdate(RenderEmbeddedObject*);
212
213    virtual void paintContents(GraphicsContext*, const IntRect& damageRect);
214    void setPaintBehavior(PaintBehavior);
215    PaintBehavior paintBehavior() const;
216    bool isPainting() const;
217    bool hasEverPainted() const { return m_lastPaintTime; }
218    void setNodeToDraw(Node*);
219
220    virtual void paintOverhangAreas(GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
221    virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
222
223    static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting
224
225    void updateLayoutAndStyleIfNeededRecursive();
226    void flushDeferredRepaints();
227
228    void setIsVisuallyNonEmpty() { m_isVisuallyNonEmpty = true; }
229
230    void forceLayout(bool allowSubtree = false);
231    void forceLayoutForPagination(const FloatSize& pageSize, float maximumShrinkFactor, Frame::AdjustViewSizeOrNot);
232
233    // FIXME: This method is retained because of embedded WebViews in AppKit.  When a WebView is embedded inside
234    // some enclosing view with auto-pagination, no call happens to resize the view.  The new pagination model
235    // needs the view to resize as a result of the breaks, but that means that the enclosing view has to potentially
236    // resize around that view.  Auto-pagination uses the bounds of the actual view that's being printed to determine
237    // the edges of the print operation, so the resize is necessary if the enclosing view's bounds depend on the
238    // web document's bounds.
239    //
240    // This is already a problem if the view needs to be a different size because of printer fonts or because of print stylesheets.
241    // Mail/Dictionary work around this problem by using the _layoutForPrinting SPI
242    // to at least get print stylesheets and printer fonts into play, but since WebKit doesn't know about the page offset or
243    // page size, it can't actually paginate correctly during _layoutForPrinting.
244    //
245    // We can eventually move Mail to a newer SPI that would let them opt in to the layout-time pagination model,
246    // but that doesn't solve the general problem of how other AppKit views could opt in to the better model.
247    //
248    // NO OTHER PLATFORM BESIDES MAC SHOULD USE THIS METHOD.
249    void adjustPageHeightDeprecated(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
250
251    bool scrollToFragment(const KURL&);
252    bool scrollToAnchor(const String&);
253    void maintainScrollPositionAtAnchor(Node*);
254
255    // Methods to convert points and rects between the coordinate space of the renderer, and this view.
256    virtual IntRect convertFromRenderer(const RenderObject*, const IntRect&) const;
257    virtual IntRect convertToRenderer(const RenderObject*, const IntRect&) const;
258    virtual IntPoint convertFromRenderer(const RenderObject*, const IntPoint&) const;
259    virtual IntPoint convertToRenderer(const RenderObject*, const IntPoint&) const;
260
261    bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
262
263    void calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode);
264
265    // Normal delay
266    static void setRepaintThrottlingDeferredRepaintDelay(double p);
267    // Negative value would mean that first few repaints happen without a delay
268    static void setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p);
269    // The delay grows on each repaint to this maximum value
270    static void setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p);
271    // On each repaint the delay increses by this amount
272    static void setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p);
273
274    virtual IntPoint currentMousePosition() const;
275
276    // FIXME: Remove this method once plugin loading is decoupled from layout.
277    void flushAnyPendingPostLayoutTasks();
278
279    virtual bool shouldSuspendScrollAnimations() const;
280
281protected:
282    virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
283    virtual void scrollContentsSlowPath(const IntRect& updateRect);
284
285    virtual bool isVerticalDocument() const;
286    virtual bool isFlippedDocument() const;
287
288private:
289    FrameView(Frame*);
290
291    void reset();
292    void init();
293
294    virtual bool isFrameView() const;
295
296    friend class RenderWidget;
297    bool useSlowRepaints() const;
298    bool useSlowRepaintsIfNotOverlapped() const;
299    void updateCanBlitOnScrollRecursively();
300
301    bool hasFixedObjects() const { return m_fixedObjectCount > 0; }
302
303    void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
304
305    void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow);
306
307    void performPostLayoutTasks();
308
309    virtual void repaintContentRectangle(const IntRect&, bool immediate);
310    virtual void contentsResized();
311    virtual void visibleContentsResized();
312
313    // Override ScrollView methods to do point conversion via renderers, in order to
314    // take transforms into account.
315    virtual IntRect convertToContainingView(const IntRect&) const;
316    virtual IntRect convertFromContainingView(const IntRect&) const;
317    virtual IntPoint convertToContainingView(const IntPoint&) const;
318    virtual IntPoint convertFromContainingView(const IntPoint&) const;
319
320    // ScrollableArea interface
321    virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
322    virtual bool isActive() const;
323    virtual void getTickmarks(Vector<IntRect>&) const;
324    virtual void scrollTo(const IntSize&);
325    virtual void didCompleteRubberBand(const IntSize&) const;
326    virtual void scrollbarStyleChanged();
327#if USE(ACCELERATED_COMPOSITING)
328    virtual GraphicsLayer* layerForHorizontalScrollbar() const;
329    virtual GraphicsLayer* layerForVerticalScrollbar() const;
330    virtual GraphicsLayer* layerForScrollCorner() const;
331#endif
332
333    virtual void notifyPageThatContentAreaWillPaint() const;
334    virtual void disconnectFromPage() { m_page = 0; }
335
336    void deferredRepaintTimerFired(Timer<FrameView>*);
337    void doDeferredRepaints();
338    void updateDeferredRepaintDelay();
339    double adjustedDeferredRepaintDelay() const;
340
341    bool updateWidgets();
342    void updateWidget(RenderEmbeddedObject*);
343    void scrollToAnchor();
344    void scrollPositionChanged();
345
346    bool hasCustomScrollbars() const;
347
348    virtual void updateScrollCorner();
349
350    FrameView* parentFrameView() const;
351
352    virtual AXObjectCache* axObjectCache() const;
353    void notifyWidgetsInAllFrames(WidgetNotification);
354
355    static double sCurrentPaintTimeStamp; // used for detecting decoded resource thrash in the cache
356
357    IntSize m_size;
358    IntSize m_margins;
359
360    typedef HashSet<RenderEmbeddedObject*> RenderEmbeddedObjectSet;
361    OwnPtr<RenderEmbeddedObjectSet> m_widgetUpdateSet;
362    RefPtr<Frame> m_frame;
363
364    bool m_doFullRepaint;
365
366    bool m_canHaveScrollbars;
367    bool m_useSlowRepaints;
368    bool m_isOverlapped;
369    bool m_contentIsOpaque;
370    unsigned m_slowRepaintObjectCount;
371    unsigned m_fixedObjectCount;
372
373    int m_borderX;
374    int m_borderY;
375
376    Timer<FrameView> m_layoutTimer;
377    bool m_delayedLayout;
378    RenderObject* m_layoutRoot;
379
380    bool m_layoutSchedulingEnabled;
381    bool m_inLayout;
382    bool m_hasPendingPostLayoutTasks;
383    bool m_inSynchronousPostLayout;
384    int m_layoutCount;
385    unsigned m_nestedLayoutCount;
386    Timer<FrameView> m_postLayoutTasksTimer;
387    bool m_firstLayoutCallbackPending;
388
389    bool m_firstLayout;
390    bool m_isTransparent;
391    Color m_baseBackgroundColor;
392    IntSize m_lastLayoutSize;
393    float m_lastZoomFactor;
394
395    String m_mediaType;
396    String m_mediaTypeWhenNotPrinting;
397
398    OwnPtr<FrameActionScheduler> m_actionScheduler;
399
400    bool m_overflowStatusDirty;
401    bool m_horizontalOverflow;
402    bool m_verticalOverflow;
403    RenderObject* m_viewportRenderer;
404
405    bool m_wasScrolledByUser;
406    bool m_inProgrammaticScroll;
407
408    unsigned m_deferringRepaints;
409    unsigned m_repaintCount;
410    Vector<IntRect> m_repaintRects;
411    Timer<FrameView> m_deferredRepaintTimer;
412    double m_deferredRepaintDelay;
413    double m_lastPaintTime;
414
415    bool m_shouldUpdateWhileOffscreen;
416
417    unsigned m_deferSetNeedsLayouts;
418    bool m_setNeedsLayoutWasDeferred;
419
420    RefPtr<Node> m_nodeToDraw;
421    PaintBehavior m_paintBehavior;
422    bool m_isPainting;
423
424    bool m_isVisuallyNonEmpty;
425    bool m_firstVisuallyNonEmptyLayoutCallbackPending;
426
427    RefPtr<Node> m_maintainScrollPositionAnchor;
428
429    // Renderer to hold our custom scroll corner.
430    RenderScrollbarPart* m_scrollCorner;
431
432    Page* m_page;
433
434    static double s_deferredRepaintDelay;
435    static double s_initialDeferredRepaintDelayDuringLoading;
436    static double s_maxDeferredRepaintDelayDuringLoading;
437    static double s_deferredRepaintDelayIncrementDuringLoading;
438#if ENABLE(ANDROID_OVERFLOW_SCROLL)
439    bool m_hasOverflowScroll;
440#endif
441};
442
443} // namespace WebCore
444
445#endif // FrameView_h
446