1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2009, 2010 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#ifndef RenderWidget_h
23#define RenderWidget_h
24
25#include "OverlapTestRequestClient.h"
26#include "RenderReplaced.h"
27#include "Widget.h"
28
29namespace WebCore {
30
31class WidgetHierarchyUpdatesSuspensionScope {
32public:
33    WidgetHierarchyUpdatesSuspensionScope()
34    {
35        s_widgetHierarchyUpdateSuspendCount++;
36    }
37    ~WidgetHierarchyUpdatesSuspensionScope()
38    {
39        ASSERT(s_widgetHierarchyUpdateSuspendCount);
40        if (s_widgetHierarchyUpdateSuspendCount == 1)
41            moveWidgets();
42        s_widgetHierarchyUpdateSuspendCount--;
43    }
44
45    static bool isSuspended() { return s_widgetHierarchyUpdateSuspendCount; }
46    static void scheduleWidgetToMove(Widget* widget, FrameView* frame) { widgetNewParentMap().set(widget, frame); }
47
48private:
49    typedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap;
50    static WidgetToParentMap& widgetNewParentMap();
51
52    void moveWidgets();
53
54    static unsigned s_widgetHierarchyUpdateSuspendCount;
55};
56
57class RenderWidget : public RenderReplaced, private OverlapTestRequestClient {
58public:
59    virtual ~RenderWidget();
60
61    Widget* widget() const { return m_widget.get(); }
62    virtual void setWidget(PassRefPtr<Widget>);
63
64    static RenderWidget* find(const Widget*);
65
66    void updateWidgetPosition();
67    void widgetPositionsUpdated();
68    IntRect windowClipRect() const;
69
70    void notifyWidget(WidgetNotification);
71
72    RenderArena* ref() { ++m_refCount; return renderArena(); }
73    void deref(RenderArena*);
74
75protected:
76    RenderWidget(Element*);
77
78    FrameView* frameView() const { return m_frameView; }
79
80    void clearWidget();
81
82    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
83    virtual void layout();
84    virtual void paint(PaintInfo&, const LayoutPoint&);
85    virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
86    virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
87
88    virtual void paintContents(PaintInfo&, const LayoutPoint&);
89
90private:
91    virtual bool isWidget() const { return true; }
92
93    virtual void willBeDestroyed();
94    virtual void destroy();
95    virtual void setSelectionState(SelectionState);
96    virtual void setOverlapTestResult(bool);
97
98    bool setWidgetGeometry(const LayoutRect&);
99    bool updateWidgetGeometry();
100
101    RefPtr<Widget> m_widget;
102    FrameView* m_frameView;
103    IntRect m_clipRect; // The rectangle needs to remain correct after scrolling, so it is stored in content view coordinates, and not clipped to window.
104    int m_refCount;
105};
106
107inline RenderWidget* toRenderWidget(RenderObject* object)
108{
109    ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isWidget());
110    return static_cast<RenderWidget*>(object);
111}
112
113inline const RenderWidget* toRenderWidget(const RenderObject* object)
114{
115    ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isWidget());
116    return static_cast<const RenderWidget*>(object);
117}
118
119// This will catch anyone doing an unnecessary cast.
120void toRenderWidget(const RenderWidget*);
121
122} // namespace WebCore
123
124#endif // RenderWidget_h
125