Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Side by Side Diff: Source/core/rendering/RenderPart.cpp

Issue 625073002: Merge RenderWidget into single subclass, RenderPart (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: s/widget/part wherever it made sense Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Simon Hausmann <hausmann@kde.org> 3 * (C) 2000 Simon Hausmann <hausmann@kde.org>
4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de) 4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de)
5 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. 5 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
6 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version. 11 * version 2 of the License, or (at your option) any later version.
12 * 12 *
13 * This library is distributed in the hope that it will be useful, 13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details. 16 * Library General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU Library General Public License 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 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, 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA. 21 * Boston, MA 02110-1301, USA.
22 * 22 *
23 */ 23 */
24 24
25 #include "config.h" 25 #include "config.h"
26 #include "core/rendering/RenderPart.h" 26 #include "core/rendering/RenderPart.h"
27 27
28 #include "core/accessibility/AXObjectCache.h"
28 #include "core/frame/FrameView.h" 29 #include "core/frame/FrameView.h"
29 #include "core/frame/LocalFrame.h" 30 #include "core/frame/LocalFrame.h"
30 #include "core/html/HTMLFrameElementBase.h" 31 #include "core/html/HTMLFrameElementBase.h"
32 #include "core/paint/BoxPainter.h"
31 #include "core/plugins/PluginView.h" 33 #include "core/plugins/PluginView.h"
34 #include "core/rendering/GraphicsContextAnnotator.h"
32 #include "core/rendering/HitTestResult.h" 35 #include "core/rendering/HitTestResult.h"
33 #include "core/rendering/RenderLayer.h" 36 #include "core/rendering/RenderLayer.h"
34 #include "core/rendering/RenderView.h" 37 #include "core/rendering/RenderView.h"
35 #include "core/rendering/svg/RenderSVGRoot.h" 38 #include "core/rendering/svg/RenderSVGRoot.h"
36 39
37 namespace blink { 40 namespace blink {
38 41
39 RenderPart::RenderPart(Element* node) 42 RenderPart::RenderPart(Element* element)
40 : RenderWidget(node) 43 : RenderReplaced(element)
44 #if !ENABLE(OILPAN)
45 // Reference counting is used to prevent the part from being destroyed
46 // while inside the Widget code, which might not be able to handle that.
47 , m_refCount(1)
48 #endif
41 { 49 {
50 ASSERT(element);
51 frameView()->addPart(this);
42 setInline(false); 52 setInline(false);
43 } 53 }
44 54
55 #if !ENABLE(OILPAN)
56 void RenderPart::deref()
57 {
58 if (--m_refCount <= 0)
59 postDestroy();
60 }
61 #endif
62
63 void RenderPart::willBeDestroyed()
64 {
65 frameView()->removePart(this);
66
67 if (AXObjectCache* cache = document().existingAXObjectCache()) {
68 cache->childrenChanged(this->parent());
69 cache->remove(this);
70 }
71
72 Element* element = toElement(node());
73 if (element && element->isFrameOwnerElement())
74 toHTMLFrameOwnerElement(element)->setWidget(nullptr);
75
76 RenderReplaced::willBeDestroyed();
77 }
78
79 void RenderPart::destroy()
80 {
81 #if ENABLE(ASSERT) && ENABLE(OILPAN)
82 ASSERT(!m_didCallDestroy);
83 m_didCallDestroy = true;
84 #endif
85 willBeDestroyed();
86 clearNode();
87 #if ENABLE(OILPAN)
88 // In Oilpan, postDestroy doesn't delete |this|. So calling it here is safe
89 // though |this| will be referred in FrameView.
90 postDestroy();
91 #else
92 deref();
93 #endif
94 }
95
45 RenderPart::~RenderPart() 96 RenderPart::~RenderPart()
46 { 97 {
98 #if !ENABLE(OILPAN)
99 ASSERT(m_refCount <= 0);
100 #endif
101 }
102
103 Widget* RenderPart::widget() const
104 {
105 // Plugin widgets are stored in their DOM node. This includes HTMLAppletElem ent.
106 Element* element = toElement(node());
107
108 if (element && element->isFrameOwnerElement())
109 return toHTMLFrameOwnerElement(element)->ownedWidget();
110
111 return 0;
47 } 112 }
48 113
49 LayerType RenderPart::layerTypeRequired() const 114 LayerType RenderPart::layerTypeRequired() const
50 { 115 {
51 LayerType type = RenderWidget::layerTypeRequired(); 116 LayerType type = RenderReplaced::layerTypeRequired();
52 if (type != NoLayer) 117 if (type != NoLayer)
53 return type; 118 return type;
54 return ForcedLayer; 119 return ForcedLayer;
55 } 120 }
56 121
57 bool RenderPart::requiresAcceleratedCompositing() const 122 bool RenderPart::requiresAcceleratedCompositing() const
58 { 123 {
59 // There are two general cases in which we can return true. First, if this i s a plugin 124 // There are two general cases in which we can return true. First, if this i s a plugin
60 // renderer and the plugin has a layer, then we need a layer. Second, if thi s is 125 // renderer and the plugin has a layer, then we need a layer. Second, if thi s is
61 // a renderer with a contentDocument and that document needs a layer, then w e need 126 // a renderer with a contentDocument and that document needs a layer, then w e need
(...skipping 11 matching lines...) Expand all
73 if (Document* contentDocument = element->contentDocument()) { 138 if (Document* contentDocument = element->contentDocument()) {
74 if (RenderView* view = contentDocument->renderView()) 139 if (RenderView* view = contentDocument->renderView())
75 return view->usesCompositing(); 140 return view->usesCompositing();
76 } 141 }
77 142
78 return false; 143 return false;
79 } 144 }
80 145
81 bool RenderPart::needsPreferredWidthsRecalculation() const 146 bool RenderPart::needsPreferredWidthsRecalculation() const
82 { 147 {
83 if (RenderWidget::needsPreferredWidthsRecalculation()) 148 if (RenderReplaced::needsPreferredWidthsRecalculation())
84 return true; 149 return true;
85 return embeddedContentBox(); 150 return embeddedContentBox();
86 } 151 }
87 152
153 bool RenderPart::nodeAtPointOverWidget(const HitTestRequest& request, HitTestRes ult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accu mulatedOffset, HitTestAction action)
154 {
155 bool hadResult = result.innerNode();
156 bool inside = RenderReplaced::nodeAtPoint(request, result, locationInContain er, accumulatedOffset, action);
157
158 // Check to see if we are really over the widget itself (and not just in the border/padding area).
159 if ((inside || result.isRectBasedTest()) && !hadResult && result.innerNode() == node())
160 result.setIsOverWidget(contentBoxRect().contains(result.localPoint()));
161 return inside;
162 }
163
88 bool RenderPart::nodeAtPoint(const HitTestRequest& request, HitTestResult& resul t, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOff set, HitTestAction action) 164 bool RenderPart::nodeAtPoint(const HitTestRequest& request, HitTestResult& resul t, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOff set, HitTestAction action)
89 { 165 {
90 if (!widget() || !widget()->isFrameView() || !request.allowsChildFrameConten t()) 166 if (!widget() || !widget()->isFrameView() || !request.allowsChildFrameConten t())
91 return RenderWidget::nodeAtPoint(request, result, locationInContainer, a ccumulatedOffset, action); 167 return nodeAtPointOverWidget(request, result, locationInContainer, accum ulatedOffset, action);
92 168
93 // FIXME: Until RemoteFrames use RemoteFrameViews, we need an explicit check here. 169 // FIXME: Until RemoteFrames use RemoteFrameViews, we need an explicit check here.
94 if (toFrameView(widget())->frame().isRemoteFrameTemporary()) 170 if (toFrameView(widget())->frame().isRemoteFrameTemporary())
95 return RenderWidget::nodeAtPoint(request, result, locationInContainer, a ccumulatedOffset, action); 171 return nodeAtPointOverWidget(request, result, locationInContainer, accum ulatedOffset, action);
96 172
97 FrameView* childFrameView = toFrameView(widget()); 173 FrameView* childFrameView = toFrameView(widget());
98 RenderView* childRoot = childFrameView->renderView(); 174 RenderView* childRoot = childFrameView->renderView();
99 175
100 if (childRoot) { 176 if (childRoot) {
101 LayoutPoint adjustedLocation = accumulatedOffset + location(); 177 LayoutPoint adjustedLocation = accumulatedOffset + location();
102 LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), bo rderTop() + paddingTop()) - childFrameView->scrollOffset(); 178 LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), bo rderTop() + paddingTop()) - childFrameView->scrollOffset();
103 HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocatio n - contentOffset); 179 HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocatio n - contentOffset);
104 HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildF rameHitTest); 180 HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildF rameHitTest);
105 HitTestResult childFrameResult(newHitTestLocation); 181 HitTestResult childFrameResult(newHitTestLocation);
106 182
107 bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTe stLocation, childFrameResult); 183 bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTe stLocation, childFrameResult);
108 184
109 if (newHitTestLocation.isRectBasedTest()) 185 if (newHitTestLocation.isRectBasedTest())
110 result.append(childFrameResult); 186 result.append(childFrameResult);
111 else if (isInsideChildFrame) 187 else if (isInsideChildFrame)
112 result = childFrameResult; 188 result = childFrameResult;
113 189
114 if (isInsideChildFrame) 190 if (isInsideChildFrame)
115 return true; 191 return true;
116 } 192 }
117 193
118 return RenderWidget::nodeAtPoint(request, result, locationInContainer, accum ulatedOffset, action); 194 return nodeAtPointOverWidget(request, result, locationInContainer, accumulat edOffset, action);
119 } 195 }
120 196
121 CompositingReasons RenderPart::additionalCompositingReasons() const 197 CompositingReasons RenderPart::additionalCompositingReasons() const
122 { 198 {
123 if (requiresAcceleratedCompositing()) 199 if (requiresAcceleratedCompositing())
124 return CompositingReasonIFrame; 200 return CompositingReasonIFrame;
125 return CompositingReasonNone; 201 return CompositingReasonNone;
126 } 202 }
127 203
128 } 204 void RenderPart::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl e)
205 {
206 RenderReplaced::styleDidChange(diff, oldStyle);
207 Widget* widget = this->widget();
208
209 if (!widget)
210 return;
211
212 if (style()->visibility() != VISIBLE) {
213 widget->hide();
214 } else {
215 widget->show();
216 }
217 }
218
219 void RenderPart::layout()
220 {
221 ASSERT(needsLayout());
222
223 clearNeedsLayout();
224 }
225
226 void RenderPart::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
227 {
228 ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
229
230 if (!shouldPaint(paintInfo, paintOffset))
231 return;
232
233 LayoutPoint adjustedPaintOffset = paintOffset + location();
234
235 if (hasBoxDecorationBackground() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
236 paintBoxDecorationBackground(paintInfo, adjustedPaintOffset);
237
238 if (paintInfo.phase == PaintPhaseMask) {
239 paintMask(paintInfo, adjustedPaintOffset);
240 return;
241 }
242
243 if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSe lfOutline) && style()->hasOutline())
244 paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size()));
245
246 if (paintInfo.phase != PaintPhaseForeground)
247 return;
248
249 if (style()->hasBorderRadius()) {
250 LayoutRect borderRect = LayoutRect(adjustedPaintOffset, size());
251
252 if (borderRect.isEmpty())
253 return;
254
255 // Push a clip if we have a border radius, since we want to round the fo reground content that gets painted.
256 paintInfo.context->save();
257 RoundedRect roundedInnerRect = style()->getRoundedInnerBorderFor(borderR ect,
258 paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddin gLeft() + borderLeft(), paddingRight() + borderRight(), true, true);
259 BoxPainter::clipRoundedInnerRect(paintInfo.context, borderRect, roundedI nnerRect);
260 }
261
262 if (this->widget())
263 paintContents(paintInfo, paintOffset);
264
265 if (style()->hasBorderRadius())
266 paintInfo.context->restore();
267
268 // Paint a partially transparent wash over selected widgets.
269 if (isSelected() && !document().printing()) {
270 LayoutRect rect = localSelectionRect();
271 rect.moveBy(adjustedPaintOffset);
272 paintInfo.context->fillRect(pixelSnappedIntRect(rect), selectionBackgrou ndColor());
273 }
274
275 if (canResize())
276 layer()->scrollableArea()->paintResizer(paintInfo.context, roundedIntPoi nt(adjustedPaintOffset), paintInfo.rect);
277 }
278
279 void RenderPart::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOff set)
280 {
281 LayoutPoint adjustedPaintOffset = paintOffset + location();
282
283 Widget* widget = this->widget();
284 RELEASE_ASSERT(widget);
285
286 // Tell the widget to paint now. This is the only time the widget is allowed
287 // to paint itself. That way it will composite properly with z-indexed layer s.
288 IntPoint widgetLocation = widget->frameRect().location();
289 IntPoint paintLocation(roundToInt(adjustedPaintOffset.x() + borderLeft() + p addingLeft()),
290 roundToInt(adjustedPaintOffset.y() + borderTop() + paddingTop()));
291 IntRect paintRect = paintInfo.rect;
292
293 IntSize widgetPaintOffset = paintLocation - widgetLocation;
294 // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
295 // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
296 if (!widgetPaintOffset.isZero()) {
297 paintInfo.context->translate(widgetPaintOffset.width(), widgetPaintOffse t.height());
298 paintRect.move(-widgetPaintOffset);
299 }
300 widget->paint(paintInfo.context, paintRect);
301
302 if (!widgetPaintOffset.isZero())
303 paintInfo.context->translate(-widgetPaintOffset.width(), -widgetPaintOff set.height());
304 }
305
306 CursorDirective RenderPart::getCursor(const LayoutPoint& point, Cursor& cursor) const
307 {
308 if (widget() && widget()->isPluginView()) {
309 // A plug-in is responsible for setting the cursor when the pointer is o ver it.
310 return DoNotSetCursor;
311 }
312 return RenderReplaced::getCursor(point, cursor);
313 }
314
315 void RenderPart::updateOnWidgetChange()
316 {
317 Widget* widget = this->widget();
318 if (!widget)
319 return;
320
321 if (!style())
322 return;
323
324 if (!needsLayout())
325 updateWidgetGeometry();
326
327 if (style()->visibility() != VISIBLE) {
328 widget->hide();
329 } else {
330 widget->show();
331 // FIXME: Why do we issue a full paint invalidation in this case, but no t the other?
332 setShouldDoFullPaintInvalidation();
333 }
334 }
335
336 void RenderPart::updateWidgetPosition()
337 {
338 Widget* widget = this->widget();
339 if (!widget || !node()) // Check the node in case destroy() has been called.
340 return;
341
342 bool boundsChanged = updateWidgetGeometry();
343
344 // If the frame bounds got changed, or if view needs layout (possibly indica ting
345 // content size is wrong) we have to do a layout to set the right widget siz e.
346 if (widget && widget->isFrameView()) {
347 FrameView* frameView = toFrameView(widget);
348 // Check the frame's page to make sure that the frame isn't in the proce ss of being destroyed.
349 if ((boundsChanged || frameView->needsLayout()) && frameView->frame().pa ge())
350 frameView->layout();
351 }
352 }
353
354 void RenderPart::widgetPositionsUpdated()
355 {
356 Widget* widget = this->widget();
357 if (!widget)
358 return;
359 widget->widgetPositionsUpdated();
360 }
361
362 bool RenderPart::updateWidgetGeometry()
363 {
364 Widget* widget = this->widget();
365 ASSERT(widget);
366
367 LayoutRect contentBox = contentBoxRect();
368 LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(contentBox)).bou ndingBox());
369 if (widget->isFrameView()) {
370 contentBox.setLocation(absoluteContentBox.location());
371 return setWidgetGeometry(contentBox);
372 }
373
374 return setWidgetGeometry(absoluteContentBox);
375 }
376
377 // Widgets are always placed on integer boundaries, so rounding the size is actu ally
378 // the desired behavior. This function is here because it's otherwise seldom wha t we
379 // want to do with a LayoutRect.
380 static inline IntRect roundedIntRect(const LayoutRect& rect)
381 {
382 return IntRect(roundedIntPoint(rect.location()), roundedIntSize(rect.size()) );
383 }
384
385 bool RenderPart::setWidgetGeometry(const LayoutRect& frame)
386 {
387 if (!node())
388 return false;
389
390 Widget* widget = this->widget();
391 ASSERT(widget);
392
393 IntRect newFrame = roundedIntRect(frame);
394
395 if (widget->frameRect() == newFrame)
396 return false;
397
398 RefPtrWillBeRawPtr<RenderPart> protector(this);
399 RefPtrWillBeRawPtr<Node> protectedNode(node());
400 widget->setFrameRect(newFrame);
401 return widget->frameRect().size() != newFrame.size();
402 }
403
404 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698