1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2009, 2010, 2013 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#pragma once
23
24#include "HTMLFrameOwnerElement.h"
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 using WidgetToParentMap = HashMap<RefPtr<Widget>, FrameView*>;
50 static WidgetToParentMap& widgetNewParentMap();
51
52 WEBCORE_EXPORT void moveWidgets();
53 WEBCORE_EXPORT static unsigned s_widgetHierarchyUpdateSuspendCount;
54};
55
56class RenderWidget : public RenderReplaced, private OverlapTestRequestClient {
57 WTF_MAKE_ISO_ALLOCATED(RenderWidget);
58public:
59 virtual ~RenderWidget();
60
61 HTMLFrameOwnerElement& frameOwnerElement() const { return downcast<HTMLFrameOwnerElement>(nodeForNonAnonymous()); }
62
63 Widget* widget() const { return m_widget.get(); }
64 WEBCORE_EXPORT void setWidget(RefPtr<Widget>&&);
65
66 static RenderWidget* find(const Widget&);
67
68 enum class ChildWidgetState { Valid, Destroyed };
69 ChildWidgetState updateWidgetPosition() WARN_UNUSED_RETURN;
70 WEBCORE_EXPORT IntRect windowClipRect() const;
71
72 bool requiresAcceleratedCompositing() const;
73
74 void ref() { ++m_refCount; }
75 void deref();
76
77protected:
78 RenderWidget(HTMLFrameOwnerElement&, RenderStyle&&);
79
80 void willBeDestroyed() override;
81 void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
82 void layout() override;
83 void paint(PaintInfo&, const LayoutPoint&) override;
84 bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
85 virtual void paintContents(PaintInfo&, const LayoutPoint&);
86 bool requiresLayer() const override;
87
88private:
89 void element() const = delete;
90
91 bool isWidget() const final { return true; }
92
93 bool needsPreferredWidthsRecalculation() const final;
94 RenderBox* embeddedContentBox() const final;
95
96 void setSelectionState(SelectionState) final;
97 void setOverlapTestResult(bool) final;
98
99 bool setWidgetGeometry(const LayoutRect&);
100 bool updateWidgetGeometry();
101
102 RefPtr<Widget> m_widget;
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 unsigned m_refCount { 1 };
105};
106
107inline void RenderWidget::deref()
108{
109 ASSERT(m_refCount);
110 if (!--m_refCount)
111 delete this;
112}
113
114} // namespace WebCore
115
116SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderWidget, isWidget())
117