OLD | NEW |
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 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 | 63 |
64 Element* element = toElement(node()); | 64 Element* element = toElement(node()); |
65 if (element && element->isFrameOwnerElement()) | 65 if (element && element->isFrameOwnerElement()) |
66 toHTMLFrameOwnerElement(element)->setWidget(nullptr); | 66 toHTMLFrameOwnerElement(element)->setWidget(nullptr); |
67 | 67 |
68 LayoutReplaced::willBeDestroyed(); | 68 LayoutReplaced::willBeDestroyed(); |
69 } | 69 } |
70 | 70 |
71 void LayoutPart::destroy() { | 71 void LayoutPart::destroy() { |
72 willBeDestroyed(); | 72 willBeDestroyed(); |
73 // We call clearNode here because LayoutPart is ref counted. This call to dest
roy | 73 // We call clearNode here because LayoutPart is ref counted. This call to |
74 // may not actually destroy the layout object. We can keep it around because o
f | 74 // destroy may not actually destroy the layout object. We can keep it around |
75 // references from the FrameView class. (The actual destruction of the class h
appens | 75 // because of references from the FrameView class. (The actual destruction of |
76 // in postDestroy() which is called from deref()). | 76 // the class happens in postDestroy() which is called from deref()). |
77 // | 77 // |
78 // But, we've told the system we've destroyed the layoutObject, which happens
when | 78 // But, we've told the system we've destroyed the layoutObject, which happens |
79 // the DOM node is destroyed. So there is a good change the DOM node this obje
ct | 79 // when the DOM node is destroyed. So there is a good change the DOM node this |
80 // points too is invalid, so we have to clear the node so we make sure we don'
t | 80 // object points too is invalid, so we have to clear the node so we make sure |
81 // access it in the future. | 81 // we don't access it in the future. |
82 clearNode(); | 82 clearNode(); |
83 deref(); | 83 deref(); |
84 } | 84 } |
85 | 85 |
86 LayoutPart::~LayoutPart() { | 86 LayoutPart::~LayoutPart() { |
87 ASSERT(m_refCount <= 0); | 87 ASSERT(m_refCount <= 0); |
88 } | 88 } |
89 | 89 |
90 Widget* LayoutPart::widget() const { | 90 Widget* LayoutPart::widget() const { |
91 // Plugin widgets are stored in their DOM node. | 91 // Plugin widgets are stored in their DOM node. |
92 Element* element = toElement(node()); | 92 Element* element = toElement(node()); |
93 | 93 |
94 if (element && element->isFrameOwnerElement()) | 94 if (element && element->isFrameOwnerElement()) |
95 return toHTMLFrameOwnerElement(element)->ownedWidget(); | 95 return toHTMLFrameOwnerElement(element)->ownedWidget(); |
96 | 96 |
97 return nullptr; | 97 return nullptr; |
98 } | 98 } |
99 | 99 |
100 PaintLayerType LayoutPart::layerTypeRequired() const { | 100 PaintLayerType LayoutPart::layerTypeRequired() const { |
101 PaintLayerType type = LayoutReplaced::layerTypeRequired(); | 101 PaintLayerType type = LayoutReplaced::layerTypeRequired(); |
102 if (type != NoPaintLayer) | 102 if (type != NoPaintLayer) |
103 return type; | 103 return type; |
104 return ForcedPaintLayer; | 104 return ForcedPaintLayer; |
105 } | 105 } |
106 | 106 |
107 bool LayoutPart::requiresAcceleratedCompositing() const { | 107 bool LayoutPart::requiresAcceleratedCompositing() const { |
108 // There are two general cases in which we can return true. First, if this is
a plugin | 108 // There are two general cases in which we can return true. First, if this is |
109 // LayoutObject and the plugin has a layer, then we need a layer. Second, if t
his is | 109 // a plugin LayoutObject and the plugin has a layer, then we need a layer. |
110 // a LayoutObject with a contentDocument and that document needs a layer, then
we need | 110 // Second, if this is a LayoutObject with a contentDocument and that document |
111 // a layer. | 111 // needs a layer, then we need a layer. |
112 if (widget() && widget()->isPluginView() && | 112 if (widget() && widget()->isPluginView() && |
113 toPluginView(widget())->platformLayer()) | 113 toPluginView(widget())->platformLayer()) |
114 return true; | 114 return true; |
115 | 115 |
116 if (!node() || !node()->isFrameOwnerElement()) | 116 if (!node() || !node()->isFrameOwnerElement()) |
117 return false; | 117 return false; |
118 | 118 |
119 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(node()); | 119 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(node()); |
120 if (element->contentFrame() && element->contentFrame()->isRemoteFrame()) | 120 if (element->contentFrame() && element->contentFrame()->isRemoteFrame()) |
121 return true; | 121 return true; |
(...skipping 15 matching lines...) Expand all Loading... |
137 | 137 |
138 bool LayoutPart::nodeAtPointOverWidget( | 138 bool LayoutPart::nodeAtPointOverWidget( |
139 HitTestResult& result, | 139 HitTestResult& result, |
140 const HitTestLocation& locationInContainer, | 140 const HitTestLocation& locationInContainer, |
141 const LayoutPoint& accumulatedOffset, | 141 const LayoutPoint& accumulatedOffset, |
142 HitTestAction action) { | 142 HitTestAction action) { |
143 bool hadResult = result.innerNode(); | 143 bool hadResult = result.innerNode(); |
144 bool inside = LayoutReplaced::nodeAtPoint(result, locationInContainer, | 144 bool inside = LayoutReplaced::nodeAtPoint(result, locationInContainer, |
145 accumulatedOffset, action); | 145 accumulatedOffset, action); |
146 | 146 |
147 // Check to see if we are really over the widget itself (and not just in the b
order/padding area). | 147 // Check to see if we are really over the widget itself (and not just in the |
| 148 // border/padding area). |
148 if ((inside || result.isRectBasedTest()) && !hadResult && | 149 if ((inside || result.isRectBasedTest()) && !hadResult && |
149 result.innerNode() == node()) | 150 result.innerNode() == node()) |
150 result.setIsOverWidget(contentBoxRect().contains(result.localPoint())); | 151 result.setIsOverWidget(contentBoxRect().contains(result.localPoint())); |
151 return inside; | 152 return inside; |
152 } | 153 } |
153 | 154 |
154 bool LayoutPart::nodeAtPoint(HitTestResult& result, | 155 bool LayoutPart::nodeAtPoint(HitTestResult& result, |
155 const HitTestLocation& locationInContainer, | 156 const HitTestLocation& locationInContainer, |
156 const LayoutPoint& accumulatedOffset, | 157 const LayoutPoint& accumulatedOffset, |
157 HitTestAction action) { | 158 HitTestAction action) { |
158 if (!widget() || !widget()->isFrameView() || | 159 if (!widget() || !widget()->isFrameView() || |
159 !result.hitTestRequest().allowsChildFrameContent()) | 160 !result.hitTestRequest().allowsChildFrameContent()) |
160 return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, | 161 return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, |
161 action); | 162 action); |
162 | 163 |
163 // A hit test can never hit an off-screen element; only off-screen iframes are
throttled; | 164 // A hit test can never hit an off-screen element; only off-screen iframes are |
164 // therefore, hit tests can skip descending into throttled iframes. | 165 // throttled; therefore, hit tests can skip descending into throttled iframes. |
165 if (toFrameView(widget())->shouldThrottleRendering()) | 166 if (toFrameView(widget())->shouldThrottleRendering()) |
166 return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, | 167 return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, |
167 action); | 168 action); |
168 | 169 |
169 ASSERT(document().lifecycle().state() >= DocumentLifecycle::CompositingClean); | 170 ASSERT(document().lifecycle().state() >= DocumentLifecycle::CompositingClean); |
170 | 171 |
171 if (action == HitTestForeground) { | 172 if (action == HitTestForeground) { |
172 FrameView* childFrameView = toFrameView(widget()); | 173 FrameView* childFrameView = toFrameView(widget()); |
173 LayoutViewItem childRootItem = childFrameView->layoutViewItem(); | 174 LayoutViewItem childRootItem = childFrameView->layoutViewItem(); |
174 | 175 |
175 if (visibleToHitTestRequest(result.hitTestRequest()) && | 176 if (visibleToHitTestRequest(result.hitTestRequest()) && |
176 !childRootItem.isNull()) { | 177 !childRootItem.isNull()) { |
177 LayoutPoint adjustedLocation = accumulatedOffset + location(); | 178 LayoutPoint adjustedLocation = accumulatedOffset + location(); |
178 LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), | 179 LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), |
179 borderTop() + paddingTop()) - | 180 borderTop() + paddingTop()) - |
180 LayoutSize(childFrameView->scrollOffsetInt()); | 181 LayoutSize(childFrameView->scrollOffsetInt()); |
181 HitTestLocation newHitTestLocation(locationInContainer, | 182 HitTestLocation newHitTestLocation(locationInContainer, |
182 -adjustedLocation - contentOffset); | 183 -adjustedLocation - contentOffset); |
183 HitTestRequest newHitTestRequest(result.hitTestRequest().type() | | 184 HitTestRequest newHitTestRequest(result.hitTestRequest().type() | |
184 HitTestRequest::ChildFrameHitTest); | 185 HitTestRequest::ChildFrameHitTest); |
185 HitTestResult childFrameResult(newHitTestRequest, newHitTestLocation); | 186 HitTestResult childFrameResult(newHitTestRequest, newHitTestLocation); |
186 | 187 |
187 // The frame's layout and style must be up to date if we reach here. | 188 // The frame's layout and style must be up to date if we reach here. |
188 bool isInsideChildFrame = | 189 bool isInsideChildFrame = |
189 childRootItem.hitTestNoLifecycleUpdate(childFrameResult); | 190 childRootItem.hitTestNoLifecycleUpdate(childFrameResult); |
190 | 191 |
191 if (result.hitTestRequest().listBased()) { | 192 if (result.hitTestRequest().listBased()) { |
192 result.append(childFrameResult); | 193 result.append(childFrameResult); |
193 } else if (isInsideChildFrame) { | 194 } else if (isInsideChildFrame) { |
194 // Force the result not to be cacheable because the parent | 195 // Force the result not to be cacheable because the parent frame should |
195 // frame should not cache this result; as it won't be notified of | 196 // not cache this result; as it won't be notified of changes in the |
196 // changes in the child. | 197 // child. |
197 childFrameResult.setCacheable(false); | 198 childFrameResult.setCacheable(false); |
198 result = childFrameResult; | 199 result = childFrameResult; |
199 } | 200 } |
200 | 201 |
201 // Don't trust |isInsideChildFrame|. For rect-based hit-test, returns | 202 // Don't trust |isInsideChildFrame|. For rect-based hit-test, returns |
202 // true only when the hit test rect is totally within the iframe, | 203 // true only when the hit test rect is totally within the iframe, |
203 // i.e. nodeAtPointOverWidget() also returns true. | 204 // i.e. nodeAtPointOverWidget() also returns true. |
204 // Use a temporary HitTestResult because we don't want to collect the | 205 // Use a temporary HitTestResult because we don't want to collect the |
205 // iframe element itself if the hit-test rect is totally within the iframe
. | 206 // iframe element itself if the hit-test rect is totally within the |
| 207 // iframe. |
206 if (isInsideChildFrame) { | 208 if (isInsideChildFrame) { |
207 if (!locationInContainer.isRectBasedTest()) | 209 if (!locationInContainer.isRectBasedTest()) |
208 return true; | 210 return true; |
209 HitTestResult pointOverWidgetResult = result; | 211 HitTestResult pointOverWidgetResult = result; |
210 bool pointOverWidget = | 212 bool pointOverWidget = |
211 nodeAtPointOverWidget(pointOverWidgetResult, locationInContainer, | 213 nodeAtPointOverWidget(pointOverWidgetResult, locationInContainer, |
212 accumulatedOffset, action); | 214 accumulatedOffset, action); |
213 if (pointOverWidget) | 215 if (pointOverWidget) |
214 return true; | 216 return true; |
215 result = pointOverWidgetResult; | 217 result = pointOverWidgetResult; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 } | 261 } |
260 | 262 |
261 void LayoutPart::paintContents(const PaintInfo& paintInfo, | 263 void LayoutPart::paintContents(const PaintInfo& paintInfo, |
262 const LayoutPoint& paintOffset) const { | 264 const LayoutPoint& paintOffset) const { |
263 PartPainter(*this).paintContents(paintInfo, paintOffset); | 265 PartPainter(*this).paintContents(paintInfo, paintOffset); |
264 } | 266 } |
265 | 267 |
266 CursorDirective LayoutPart::getCursor(const LayoutPoint& point, | 268 CursorDirective LayoutPart::getCursor(const LayoutPoint& point, |
267 Cursor& cursor) const { | 269 Cursor& cursor) const { |
268 if (widget() && widget()->isPluginView()) { | 270 if (widget() && widget()->isPluginView()) { |
269 // A plugin is responsible for setting the cursor when the pointer is over i
t. | 271 // A plugin is responsible for setting the cursor when the pointer is over |
| 272 // it. |
270 return DoNotSetCursor; | 273 return DoNotSetCursor; |
271 } | 274 } |
272 return LayoutReplaced::getCursor(point, cursor); | 275 return LayoutReplaced::getCursor(point, cursor); |
273 } | 276 } |
274 | 277 |
275 LayoutRect LayoutPart::replacedContentRect() const { | 278 LayoutRect LayoutPart::replacedContentRect() const { |
276 // We don't propagate sub-pixel into sub-frame layout, in other words, the rec
t is snapped | 279 // We don't propagate sub-pixel into sub-frame layout, in other words, the |
277 // at the document boundary, and sub-pixel movement could cause the sub-frame
to layout | 280 // rect is snapped at the document boundary, and sub-pixel movement could |
278 // due to the 1px snap difference. In order to avoid that, the size of sub-fra
me is rounded | 281 // cause the sub-frame to layout due to the 1px snap difference. In order to |
279 // in advance. | 282 // avoid that, the size of sub-frame is rounded in advance. |
280 LayoutRect sizeRoundedRect = contentBoxRect(); | 283 LayoutRect sizeRoundedRect = contentBoxRect(); |
281 sizeRoundedRect.setSize(LayoutSize(roundedIntSize(sizeRoundedRect.size()))); | 284 sizeRoundedRect.setSize(LayoutSize(roundedIntSize(sizeRoundedRect.size()))); |
282 return sizeRoundedRect; | 285 return sizeRoundedRect; |
283 } | 286 } |
284 | 287 |
285 void LayoutPart::updateOnWidgetChange() { | 288 void LayoutPart::updateOnWidgetChange() { |
286 Widget* widget = this->widget(); | 289 Widget* widget = this->widget(); |
287 if (!widget) | 290 if (!widget) |
288 return; | 291 return; |
289 | 292 |
290 if (!style()) | 293 if (!style()) |
291 return; | 294 return; |
292 | 295 |
293 if (!needsLayout()) | 296 if (!needsLayout()) |
294 updateWidgetGeometryInternal(); | 297 updateWidgetGeometryInternal(); |
295 | 298 |
296 if (style()->visibility() != EVisibility::Visible) { | 299 if (style()->visibility() != EVisibility::Visible) { |
297 widget->hide(); | 300 widget->hide(); |
298 } else { | 301 } else { |
299 widget->show(); | 302 widget->show(); |
300 // FIXME: Why do we issue a full paint invalidation in this case, but not th
e other? | 303 // FIXME: Why do we issue a full paint invalidation in this case, but not |
| 304 // the other? |
301 setShouldDoFullPaintInvalidation(); | 305 setShouldDoFullPaintInvalidation(); |
302 } | 306 } |
303 } | 307 } |
304 | 308 |
305 void LayoutPart::updateWidgetGeometry() { | 309 void LayoutPart::updateWidgetGeometry() { |
306 Widget* widget = this->widget(); | 310 Widget* widget = this->widget(); |
307 if (!widget || !node()) // Check the node in case destroy() has been called. | 311 if (!widget || !node()) // Check the node in case destroy() has been called. |
308 return; | 312 return; |
309 | 313 |
310 LayoutRect newFrame = replacedContentRect(); | 314 LayoutRect newFrame = replacedContentRect(); |
(...skipping 20 matching lines...) Expand all Loading... |
331 frameView->layout(); | 335 frameView->layout(); |
332 | 336 |
333 widget->widgetGeometryMayHaveChanged(); | 337 widget->widgetGeometryMayHaveChanged(); |
334 } | 338 } |
335 | 339 |
336 void LayoutPart::updateWidgetGeometryInternal() { | 340 void LayoutPart::updateWidgetGeometryInternal() { |
337 Widget* widget = this->widget(); | 341 Widget* widget = this->widget(); |
338 ASSERT(widget); | 342 ASSERT(widget); |
339 | 343 |
340 // Ignore transform here, as we only care about the sub-pixel accumulation. | 344 // Ignore transform here, as we only care about the sub-pixel accumulation. |
341 // TODO(trchen): What about multicol? Need a LayoutBox function to query sub-p
ixel accumulation. | 345 // TODO(trchen): What about multicol? Need a LayoutBox function to query |
| 346 // sub-pixel accumulation. |
342 LayoutPoint absoluteLocation(localToAbsolute(FloatPoint())); | 347 LayoutPoint absoluteLocation(localToAbsolute(FloatPoint())); |
343 LayoutRect absoluteReplacedRect = replacedContentRect(); | 348 LayoutRect absoluteReplacedRect = replacedContentRect(); |
344 absoluteReplacedRect.moveBy(absoluteLocation); | 349 absoluteReplacedRect.moveBy(absoluteLocation); |
345 | 350 |
346 IntRect frameRect(IntPoint(), | 351 IntRect frameRect(IntPoint(), |
347 pixelSnappedIntRect(absoluteReplacedRect).size()); | 352 pixelSnappedIntRect(absoluteReplacedRect).size()); |
348 // Normally the location of the frame rect is ignored by the painter, but curr
ently it is | 353 // Normally the location of the frame rect is ignored by the painter, but |
349 // still used by a family of coordinate conversion function in Widget/FrameVie
w. This is | 354 // currently it is still used by a family of coordinate conversion function in |
350 // incorrect because coordinate conversion needs to take transform and into ac
count. | 355 // Widget/FrameView. This is incorrect because coordinate conversion needs to |
351 // A few callers still use the family of conversion function, including but no
t exhaustive: | 356 // take transform and into account. |
| 357 // A few callers still use the family of conversion function, including but |
| 358 // not exhaustive: |
352 // FrameView::updateViewportIntersectionIfNeeded() | 359 // FrameView::updateViewportIntersectionIfNeeded() |
353 // RemoteFrameView::frameRectsChanged(). | 360 // RemoteFrameView::frameRectsChanged(). |
354 // WebPluginContainerImpl::reportGeometry() | 361 // WebPluginContainerImpl::reportGeometry() |
355 // TODO(trchen): Remove this hack once we fixed all callers. | 362 // TODO(trchen): Remove this hack once we fixed all callers. |
356 FloatRect absoluteBoundingBox = | 363 FloatRect absoluteBoundingBox = |
357 localToAbsoluteQuad(FloatRect(replacedContentRect())).boundingBox(); | 364 localToAbsoluteQuad(FloatRect(replacedContentRect())).boundingBox(); |
358 frameRect.setLocation(roundedIntPoint(absoluteBoundingBox.location())); | 365 frameRect.setLocation(roundedIntPoint(absoluteBoundingBox.location())); |
359 | 366 |
360 // Why is the protector needed? | 367 // Why is the protector needed? |
361 RefPtr<LayoutPart> protector(this); | 368 RefPtr<LayoutPart> protector(this); |
(...skipping 20 matching lines...) Expand all Loading... |
382 } | 389 } |
383 | 390 |
384 bool LayoutPart::isThrottledFrameView() const { | 391 bool LayoutPart::isThrottledFrameView() const { |
385 if (!widget() || !widget()->isFrameView()) | 392 if (!widget() || !widget()->isFrameView()) |
386 return false; | 393 return false; |
387 const FrameView* frameView = toFrameView(widget()); | 394 const FrameView* frameView = toFrameView(widget()); |
388 return frameView->shouldThrottleRendering(); | 395 return frameView->shouldThrottleRendering(); |
389 } | 396 } |
390 | 397 |
391 } // namespace blink | 398 } // namespace blink |
OLD | NEW |