a8751e83f911b48bb23f8a11fb9f41c1312f5503
[WebKit-https.git] / Source / WebCore / rendering / RenderPart.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 2000 Simon Hausmann <hausmann@kde.org>
4  *           (C) 2000 Stefan Schimanski (1Stein@gmx.de)
5  * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
6  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #include "config.h"
26 #include "RenderPart.h"
27
28 #include "Frame.h"
29 #include "FrameView.h"
30 #include "HTMLFrameElementBase.h"
31 #include "HitTestResult.h"
32 #include "PluginViewBase.h"
33 #include "RenderLayer.h"
34 #include "RenderSVGRoot.h"
35 #include "RenderView.h"
36
37 using namespace std;
38
39 namespace WebCore {
40
41 RenderPart::RenderPart(Element* node)
42     : RenderWidget(node)
43 {
44     setInline(false);
45 }
46
47 RenderPart::~RenderPart()
48 {
49     clearWidget();
50 }
51
52 void RenderPart::setWidget(PassRefPtr<Widget> widget)
53 {
54     if (widget == this->widget())
55         return;
56
57     RenderWidget::setWidget(widget);
58
59     // make sure the scrollbars are set correctly for restore
60     // ### find better fix
61     viewCleared();
62 }
63
64 void RenderPart::viewCleared()
65 {
66 }
67
68 #if USE(ACCELERATED_COMPOSITING)
69 bool RenderPart::requiresLayer() const
70 {
71     if (RenderWidget::requiresLayer())
72         return true;
73     
74     return requiresAcceleratedCompositing();
75 }
76
77 bool RenderPart::requiresAcceleratedCompositing() const
78 {
79     // There are two general cases in which we can return true. First, if this is a plugin 
80     // renderer and the plugin has a layer, then we need a layer. Second, if this is 
81     // a renderer with a contentDocument and that document needs a layer, then we need
82     // a layer.
83     if (widget() && widget()->isPluginViewBase() && static_cast<PluginViewBase*>(widget())->platformLayer())
84         return true;
85
86     if (!node() || !node()->isFrameOwnerElement())
87         return false;
88
89     HTMLFrameOwnerElement* element = static_cast<HTMLFrameOwnerElement*>(node());
90     if (Document* contentDocument = element->contentDocument()) {
91         if (RenderView* view = contentDocument->renderView())
92             return view->usesCompositing();
93     }
94
95     return false;
96 }
97 #endif
98
99 bool RenderPart::needsPreferredWidthsRecalculation() const
100 {
101     if (RenderWidget::needsPreferredWidthsRecalculation())
102         return true;
103     return embeddedContentBox();
104 }
105
106 RenderBox* RenderPart::embeddedContentBox() const
107 {
108     if (!node() || !widget() || !widget()->isFrameView())
109         return 0;
110     return static_cast<FrameView*>(widget())->embeddedContentBox();
111 }
112
113 bool RenderPart::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
114 {
115     if (!widget() || !widget()->isFrameView() || !request.allowsChildFrameContent())
116         return RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action);
117
118     FrameView* childFrameView = static_cast<FrameView*>(widget());
119     RenderView* childRoot = childFrameView->renderView();
120
121     if (childRoot) {
122         LayoutPoint adjustedLocation = accumulatedOffset + location();
123         LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - childFrameView->scrollOffset();
124         HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset);
125         HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildFrameHitTest);
126         HitTestResult childFrameResult(newHitTestLocation);
127
128         bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult);
129
130         if (newHitTestLocation.isRectBasedTest())
131             result.append(childFrameResult);
132         else if (isInsideChildFrame)
133             result = childFrameResult;
134
135         if (isInsideChildFrame)
136             return true;
137
138         if (request.allowsFrameScrollbars()) {
139             // ScrollView scrollbars are not the same as RenderLayer scrollbars tested by RenderLayer::hitTestOverflowControls,
140             // so we need to test ScrollView scrollbars separately here.
141             // FIXME: Consider if this test could be done unconditionally.
142             Scrollbar* frameScrollbar = childFrameView->scrollbarAtPoint(newHitTestLocation.roundedPoint());
143             if (frameScrollbar)
144                 result.setScrollbar(frameScrollbar);
145         }
146     }
147
148     return RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action);
149 }
150
151 }