OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
7 * Copyright (C) 2010 Google Inc. All rights reserved. | 7 * Copyright (C) 2010 Google Inc. All rights reserved. |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 void LayoutBoxModelObject::setSelectionState(SelectionState state) { | 78 void LayoutBoxModelObject::setSelectionState(SelectionState state) { |
79 if (state == SelectionInside && getSelectionState() != SelectionNone) | 79 if (state == SelectionInside && getSelectionState() != SelectionNone) |
80 return; | 80 return; |
81 | 81 |
82 if ((state == SelectionStart && getSelectionState() == SelectionEnd) || | 82 if ((state == SelectionStart && getSelectionState() == SelectionEnd) || |
83 (state == SelectionEnd && getSelectionState() == SelectionStart)) | 83 (state == SelectionEnd && getSelectionState() == SelectionStart)) |
84 LayoutObject::setSelectionState(SelectionBoth); | 84 LayoutObject::setSelectionState(SelectionBoth); |
85 else | 85 else |
86 LayoutObject::setSelectionState(state); | 86 LayoutObject::setSelectionState(state); |
87 | 87 |
88 // FIXME: We should consider whether it is OK propagating to ancestor LayoutIn
lines. | 88 // FIXME: We should consider whether it is OK propagating to ancestor |
89 // This is a workaround for http://webkit.org/b/32123 | 89 // LayoutInlines. This is a workaround for http://webkit.org/b/32123 |
90 // The containing block can be null in case of an orphaned tree. | 90 // The containing block can be null in case of an orphaned tree. |
91 LayoutBlock* containingBlock = this->containingBlock(); | 91 LayoutBlock* containingBlock = this->containingBlock(); |
92 if (containingBlock && !containingBlock->isLayoutView()) | 92 if (containingBlock && !containingBlock->isLayoutView()) |
93 containingBlock->setSelectionState(state); | 93 containingBlock->setSelectionState(state); |
94 } | 94 } |
95 | 95 |
96 void LayoutBoxModelObject::contentChanged(ContentChangeType changeType) { | 96 void LayoutBoxModelObject::contentChanged(ContentChangeType changeType) { |
97 if (!hasLayer()) | 97 if (!hasLayer()) |
98 return; | 98 return; |
99 | 99 |
(...skipping 13 matching lines...) Expand all Loading... |
113 } | 113 } |
114 | 114 |
115 bool LayoutBoxModelObject::hasLocalEquivalentBackground() const { | 115 bool LayoutBoxModelObject::hasLocalEquivalentBackground() const { |
116 int minBorderWidth = std::min( | 116 int minBorderWidth = std::min( |
117 style()->borderTopWidth(), | 117 style()->borderTopWidth(), |
118 std::min( | 118 std::min( |
119 style()->borderLeftWidth(), | 119 style()->borderLeftWidth(), |
120 std::min(style()->borderRightWidth(), style()->borderBottomWidth()))); | 120 std::min(style()->borderRightWidth(), style()->borderBottomWidth()))); |
121 bool outlineOverlapsPaddingBox = style()->outlineOffset() < -minBorderWidth; | 121 bool outlineOverlapsPaddingBox = style()->outlineOffset() < -minBorderWidth; |
122 bool hasCustomScrollbars = false; | 122 bool hasCustomScrollbars = false; |
123 // TODO(flackr): Detect opaque custom scrollbars which would cover up a border
-box | 123 // TODO(flackr): Detect opaque custom scrollbars which would cover up a |
124 // background. | 124 // border-box background. |
125 if (PaintLayerScrollableArea* scrollableArea = getScrollableArea()) { | 125 if (PaintLayerScrollableArea* scrollableArea = getScrollableArea()) { |
126 if ((scrollableArea->horizontalScrollbar() && | 126 if ((scrollableArea->horizontalScrollbar() && |
127 scrollableArea->horizontalScrollbar()->isCustomScrollbar()) || | 127 scrollableArea->horizontalScrollbar()->isCustomScrollbar()) || |
128 (scrollableArea->verticalScrollbar() && | 128 (scrollableArea->verticalScrollbar() && |
129 scrollableArea->verticalScrollbar()->isCustomScrollbar())) { | 129 scrollableArea->verticalScrollbar()->isCustomScrollbar())) { |
130 hasCustomScrollbars = true; | 130 hasCustomScrollbars = true; |
131 } | 131 } |
132 } | 132 } |
133 | 133 |
134 // TODO(flackr): When we correctly clip the scrolling contents layer we can | 134 // TODO(flackr): When we correctly clip the scrolling contents layer we can |
135 // paint locally equivalent backgrounds into it. https://crbug.com/645957 | 135 // paint locally equivalent backgrounds into it. https://crbug.com/645957 |
136 if (!style()->hasAutoClip()) | 136 if (!style()->hasAutoClip()) |
137 return false; | 137 return false; |
138 | 138 |
139 // TODO(flackr): Remove this when box shadows are still painted correctly when
painting | 139 // TODO(flackr): Remove this when box shadows are still painted correctly when |
140 // into the composited scrolling contents layer. https://crbug.com/646464 | 140 // painting into the composited scrolling contents layer. |
| 141 // https://crbug.com/646464 |
141 if (style()->boxShadow()) | 142 if (style()->boxShadow()) |
142 return false; | 143 return false; |
143 | 144 |
144 const FillLayer* layer = &(style()->backgroundLayers()); | 145 const FillLayer* layer = &(style()->backgroundLayers()); |
145 for (; layer; layer = layer->next()) { | 146 for (; layer; layer = layer->next()) { |
146 if (layer->attachment() == LocalBackgroundAttachment) | 147 if (layer->attachment() == LocalBackgroundAttachment) |
147 continue; | 148 continue; |
148 | 149 |
149 // If the outline draws inside the border, it intends to draw on top of the
scroller's background, | 150 // If the outline draws inside the border, it intends to draw on top of the |
150 // however because it is painted into a layer behind the scrolling contents
layer we avoid auto | 151 // scroller's background, however because it is painted into a layer behind |
151 // promoting in this case to avoid obscuring the outline. | 152 // the scrolling contents layer we avoid auto promoting in this case to |
152 // TODO(flackr): Outlines should be drawn on top of the scrolling contents l
ayer so that | 153 // avoid obscuring the outline. |
153 // they cannot be covered up by composited scrolling contents. | 154 // TODO(flackr): Outlines should be drawn on top of the scrolling contents |
| 155 // layer so that they cannot be covered up by composited scrolling contents. |
154 if (outlineOverlapsPaddingBox) | 156 if (outlineOverlapsPaddingBox) |
155 return false; | 157 return false; |
156 | 158 |
157 // Solid color layers with an effective background clip of the padding box c
an be treated | 159 // Solid color layers with an effective background clip of the padding box |
158 // as local. | 160 // can be treated as local. |
159 if (!layer->image() && !layer->next() && | 161 if (!layer->image() && !layer->next() && |
160 resolveColor(CSSPropertyBackgroundColor).alpha() > 0) { | 162 resolveColor(CSSPropertyBackgroundColor).alpha() > 0) { |
161 EFillBox clip = layer->clip(); | 163 EFillBox clip = layer->clip(); |
162 if (clip == PaddingFillBox) | 164 if (clip == PaddingFillBox) |
163 continue; | 165 continue; |
164 // A border box can be treated as a padding box if the border is opaque or
there is | 166 // A border box can be treated as a padding box if the border is opaque or |
165 // no border and we don't have custom scrollbars. | 167 // there is no border and we don't have custom scrollbars. |
166 if (clip == BorderFillBox && !hasCustomScrollbars && | 168 if (clip == BorderFillBox && !hasCustomScrollbars && |
167 (style()->borderTopWidth() == 0 || | 169 (style()->borderTopWidth() == 0 || |
168 !resolveColor(CSSPropertyBorderTopColor).hasAlpha()) && | 170 !resolveColor(CSSPropertyBorderTopColor).hasAlpha()) && |
169 (style()->borderLeftWidth() == 0 || | 171 (style()->borderLeftWidth() == 0 || |
170 !resolveColor(CSSPropertyBorderLeftColor).hasAlpha()) && | 172 !resolveColor(CSSPropertyBorderLeftColor).hasAlpha()) && |
171 (style()->borderRightWidth() == 0 || | 173 (style()->borderRightWidth() == 0 || |
172 !resolveColor(CSSPropertyBorderRightColor).hasAlpha()) && | 174 !resolveColor(CSSPropertyBorderRightColor).hasAlpha()) && |
173 (style()->borderBottomWidth() == 0 || | 175 (style()->borderBottomWidth() == 0 || |
174 !resolveColor(CSSPropertyBorderBottomColor).hasAlpha())) { | 176 !resolveColor(CSSPropertyBorderBottomColor).hasAlpha())) { |
175 continue; | 177 continue; |
176 } | 178 } |
177 // A content fill box can be treated as a padding fill box if there is no
padding. | 179 // A content fill box can be treated as a padding fill box if there is no |
| 180 // padding. |
178 if (clip == ContentFillBox && style()->paddingTop().isZero() && | 181 if (clip == ContentFillBox && style()->paddingTop().isZero() && |
179 style()->paddingLeft().isZero() && style()->paddingRight().isZero() && | 182 style()->paddingLeft().isZero() && style()->paddingRight().isZero() && |
180 style()->paddingBottom().isZero()) { | 183 style()->paddingBottom().isZero()) { |
181 continue; | 184 continue; |
182 } | 185 } |
183 } | 186 } |
184 return false; | 187 return false; |
185 } | 188 } |
186 return true; | 189 return true; |
187 } | 190 } |
188 | 191 |
189 LayoutBoxModelObject::~LayoutBoxModelObject() { | 192 LayoutBoxModelObject::~LayoutBoxModelObject() { |
190 // Our layer should have been destroyed and cleared by now | 193 // Our layer should have been destroyed and cleared by now |
191 ASSERT(!hasLayer()); | 194 ASSERT(!hasLayer()); |
192 ASSERT(!m_layer); | 195 ASSERT(!m_layer); |
193 } | 196 } |
194 | 197 |
195 void LayoutBoxModelObject::willBeDestroyed() { | 198 void LayoutBoxModelObject::willBeDestroyed() { |
196 ImageQualityController::remove(*this); | 199 ImageQualityController::remove(*this); |
197 | 200 |
198 // A continuation of this LayoutObject should be destroyed at subclasses. | 201 // A continuation of this LayoutObject should be destroyed at subclasses. |
199 ASSERT(!continuation()); | 202 ASSERT(!continuation()); |
200 | 203 |
201 if (isPositioned()) { | 204 if (isPositioned()) { |
202 // Don't use this->view() because the document's layoutView has been set to
0 during destruction. | 205 // Don't use this->view() because the document's layoutView has been set to |
| 206 // 0 during destruction. |
203 if (LocalFrame* frame = this->frame()) { | 207 if (LocalFrame* frame = this->frame()) { |
204 if (FrameView* frameView = frame->view()) { | 208 if (FrameView* frameView = frame->view()) { |
205 if (style()->hasViewportConstrainedPosition()) | 209 if (style()->hasViewportConstrainedPosition()) |
206 frameView->removeViewportConstrainedObject(this); | 210 frameView->removeViewportConstrainedObject(this); |
207 } | 211 } |
208 } | 212 } |
209 } | 213 } |
210 | 214 |
211 LayoutObject::willBeDestroyed(); | 215 LayoutObject::willBeDestroyed(); |
212 | 216 |
213 destroyLayer(); | 217 destroyLayer(); |
214 } | 218 } |
215 | 219 |
216 void LayoutBoxModelObject::styleWillChange(StyleDifference diff, | 220 void LayoutBoxModelObject::styleWillChange(StyleDifference diff, |
217 const ComputedStyle& newStyle) { | 221 const ComputedStyle& newStyle) { |
218 // This object's layer may cease to be a stacking context, in which case the p
aint | 222 // This object's layer may cease to be a stacking context, in which case the |
219 // invalidation container of the children may change. Thus we need to invalida
te paint | 223 // paint invalidation container of the children may change. Thus we need to |
220 // eagerly for all such children. | 224 // invalidate paint eagerly for all such children. |
221 if (hasLayer() && enclosingLayer()->stackingNode() && | 225 if (hasLayer() && enclosingLayer()->stackingNode() && |
222 enclosingLayer()->stackingNode()->isStackingContext() && | 226 enclosingLayer()->stackingNode()->isStackingContext() && |
223 !newStyle.isStackingContext()) { | 227 !newStyle.isStackingContext()) { |
224 // The following disablers are valid because we need to invalidate based on
the current | 228 // The following disablers are valid because we need to invalidate based on |
225 // status. | 229 // the current status. |
226 DisableCompositingQueryAsserts compositingDisabler; | 230 DisableCompositingQueryAsserts compositingDisabler; |
227 DisablePaintInvalidationStateAsserts paintDisabler; | 231 DisablePaintInvalidationStateAsserts paintDisabler; |
228 ObjectPaintInvalidator(*this) | 232 ObjectPaintInvalidator(*this) |
229 .invalidatePaintIncludingNonCompositingDescendants(); | 233 .invalidatePaintIncludingNonCompositingDescendants(); |
230 } | 234 } |
231 | 235 |
232 FloatStateForStyleChange::setWasFloating(this, isFloating()); | 236 FloatStateForStyleChange::setWasFloating(this, isFloating()); |
233 | 237 |
234 if (const ComputedStyle* oldStyle = style()) { | 238 if (const ComputedStyle* oldStyle = style()) { |
235 if (hasLayer() && diff.needsPaintInvalidationSubtree()) { | 239 if (hasLayer() && diff.needsPaintInvalidationSubtree()) { |
(...skipping 12 matching lines...) Expand all Loading... |
248 bool hadTransform = hasTransformRelatedProperty(); | 252 bool hadTransform = hasTransformRelatedProperty(); |
249 bool hadLayer = hasLayer(); | 253 bool hadLayer = hasLayer(); |
250 bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer(); | 254 bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer(); |
251 bool wasFloatingBeforeStyleChanged = | 255 bool wasFloatingBeforeStyleChanged = |
252 FloatStateForStyleChange::wasFloating(this); | 256 FloatStateForStyleChange::wasFloating(this); |
253 bool wasHorizontalWritingMode = isHorizontalWritingMode(); | 257 bool wasHorizontalWritingMode = isHorizontalWritingMode(); |
254 | 258 |
255 LayoutObject::styleDidChange(diff, oldStyle); | 259 LayoutObject::styleDidChange(diff, oldStyle); |
256 updateFromStyle(); | 260 updateFromStyle(); |
257 | 261 |
258 // When an out-of-flow-positioned element changes its display between block an
d inline-block, | 262 // When an out-of-flow-positioned element changes its display between block |
259 // then an incremental layout on the element's containing block lays out the e
lement through | 263 // and inline-block, then an incremental layout on the element's containing |
260 // LayoutPositionedObjects, which skips laying out the element's parent. | 264 // block lays out the element through LayoutPositionedObjects, which skips |
261 // The element's parent needs to relayout so that it calls | 265 // laying out the element's parent. |
262 // LayoutBlockFlow::setStaticInlinePositionForChild with the out-of-flow-posit
ioned child, so | 266 // The element's parent needs to relayout so that it calls LayoutBlockFlow:: |
263 // that when it's laid out, its LayoutBox::computePositionedLogicalWidth/Heigh
t takes into | 267 // setStaticInlinePositionForChild with the out-of-flow-positioned child, so |
264 // account its new inline/block position rather than its old block/inline posi
tion. | 268 // that when it's laid out, its LayoutBox::computePositionedLogicalWidth/ |
| 269 // Height takes into account its new inline/block position rather than its old |
| 270 // block/inline position. |
265 // Position changes and other types of display changes are handled elsewhere. | 271 // Position changes and other types of display changes are handled elsewhere. |
266 if (oldStyle && isOutOfFlowPositioned() && parent() && | 272 if (oldStyle && isOutOfFlowPositioned() && parent() && |
267 (parent() != containingBlock()) && | 273 (parent() != containingBlock()) && |
268 (styleRef().position() == oldStyle->position()) && | 274 (styleRef().position() == oldStyle->position()) && |
269 (styleRef().originalDisplay() != oldStyle->originalDisplay()) && | 275 (styleRef().originalDisplay() != oldStyle->originalDisplay()) && |
270 ((styleRef().originalDisplay() == EDisplay::Block) || | 276 ((styleRef().originalDisplay() == EDisplay::Block) || |
271 (styleRef().originalDisplay() == EDisplay::InlineBlock)) && | 277 (styleRef().originalDisplay() == EDisplay::InlineBlock)) && |
272 ((oldStyle->originalDisplay() == EDisplay::Block) || | 278 ((oldStyle->originalDisplay() == EDisplay::Block) || |
273 (oldStyle->originalDisplay() == EDisplay::InlineBlock))) | 279 (oldStyle->originalDisplay() == EDisplay::InlineBlock))) |
274 parent()->setNeedsLayout(LayoutInvalidationReason::ChildChanged, | 280 parent()->setNeedsLayout(LayoutInvalidationReason::ChildChanged, |
275 MarkContainerChain); | 281 MarkContainerChain); |
276 | 282 |
277 PaintLayerType type = layerTypeRequired(); | 283 PaintLayerType type = layerTypeRequired(); |
278 if (type != NoPaintLayer) { | 284 if (type != NoPaintLayer) { |
279 if (!layer() && layerCreationAllowedForSubtree()) { | 285 if (!layer() && layerCreationAllowedForSubtree()) { |
280 if (wasFloatingBeforeStyleChanged && isFloating()) | 286 if (wasFloatingBeforeStyleChanged && isFloating()) |
281 setChildNeedsLayout(); | 287 setChildNeedsLayout(); |
282 createLayer(); | 288 createLayer(); |
283 if (parent() && !needsLayout()) { | 289 if (parent() && !needsLayout()) { |
284 // FIXME: We should call a specialized version of this function. | 290 // FIXME: We should call a specialized version of this function. |
285 layer()->updateLayerPositionsAfterLayout(); | 291 layer()->updateLayerPositionsAfterLayout(); |
286 } | 292 } |
287 } | 293 } |
288 } else if (layer() && layer()->parent()) { | 294 } else if (layer() && layer()->parent()) { |
289 PaintLayer* parentLayer = layer()->parent(); | 295 PaintLayer* parentLayer = layer()->parent(); |
290 setHasTransformRelatedProperty( | 296 // Either a transform wasn't specified or the object doesn't support |
291 false); // Either a transform wasn't specified or the object doesn't su
pport transforms, so just null out the bit. | 297 // transforms, so just null out the bit. |
| 298 setHasTransformRelatedProperty(false); |
292 setHasReflection(false); | 299 setHasReflection(false); |
293 layer() | 300 // Calls destroyLayer() which clears m_layer. |
294 ->removeOnlyThisLayerAfterStyleChange(); // calls destroyLayer() which
clears m_layer | 301 layer()->removeOnlyThisLayerAfterStyleChange(); |
295 if (wasFloatingBeforeStyleChanged && isFloating()) | 302 if (wasFloatingBeforeStyleChanged && isFloating()) |
296 setChildNeedsLayout(); | 303 setChildNeedsLayout(); |
297 if (hadTransform) | 304 if (hadTransform) |
298 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( | 305 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( |
299 LayoutInvalidationReason::StyleChange); | 306 LayoutInvalidationReason::StyleChange); |
300 if (!needsLayout()) { | 307 if (!needsLayout()) { |
301 // FIXME: We should call a specialized version of this function. | 308 // FIXME: We should call a specialized version of this function. |
302 parentLayer->updateLayerPositionsAfterLayout(); | 309 parentLayer->updateLayerPositionsAfterLayout(); |
303 } | 310 } |
304 } | 311 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 | 368 |
362 if (FrameView* frameView = view()->frameView()) { | 369 if (FrameView* frameView = view()->frameView()) { |
363 bool newStyleIsViewportConstained = style()->position() == FixedPosition; | 370 bool newStyleIsViewportConstained = style()->position() == FixedPosition; |
364 bool oldStyleIsViewportConstrained = | 371 bool oldStyleIsViewportConstrained = |
365 oldStyle && oldStyle->position() == FixedPosition; | 372 oldStyle && oldStyle->position() == FixedPosition; |
366 bool newStyleIsSticky = style()->position() == StickyPosition; | 373 bool newStyleIsSticky = style()->position() == StickyPosition; |
367 bool oldStyleIsSticky = oldStyle && oldStyle->position() == StickyPosition; | 374 bool oldStyleIsSticky = oldStyle && oldStyle->position() == StickyPosition; |
368 | 375 |
369 if (newStyleIsSticky != oldStyleIsSticky) { | 376 if (newStyleIsSticky != oldStyleIsSticky) { |
370 if (newStyleIsSticky) { | 377 if (newStyleIsSticky) { |
371 // During compositing inputs update we'll have the scroll | 378 // During compositing inputs update we'll have the scroll ancestor |
372 // ancestor without having to walk up the tree and can compute | 379 // without having to walk up the tree and can compute the sticky |
373 // the sticky position constraints then. | 380 // position constraints then. |
374 if (layer()) | 381 if (layer()) |
375 layer()->setNeedsCompositingInputsUpdate(); | 382 layer()->setNeedsCompositingInputsUpdate(); |
376 | 383 |
377 // TODO(pdr): When slimming paint v2 is enabled, we will need to | 384 // TODO(pdr): When slimming paint v2 is enabled, we will need to |
378 // invalidate the scroll paint property subtree for this so main | 385 // invalidate the scroll paint property subtree for this so main thread |
379 // thread scroll reasons are recomputed. | 386 // scroll reasons are recomputed. |
380 } else { | 387 } else { |
381 // This may get re-added to viewport constrained objects if the object w
ent | 388 // This may get re-added to viewport constrained objects if the object |
382 // from sticky to fixed. | 389 // went from sticky to fixed. |
383 frameView->removeViewportConstrainedObject(this); | 390 frameView->removeViewportConstrainedObject(this); |
384 | 391 |
385 // Remove sticky constraints for this layer. | 392 // Remove sticky constraints for this layer. |
386 if (layer()) { | 393 if (layer()) { |
387 DisableCompositingQueryAsserts disabler; | 394 DisableCompositingQueryAsserts disabler; |
388 if (const PaintLayer* ancestorOverflowLayer = | 395 if (const PaintLayer* ancestorOverflowLayer = |
389 layer()->ancestorOverflowLayer()) | 396 layer()->ancestorOverflowLayer()) |
390 ancestorOverflowLayer->getScrollableArea() | 397 ancestorOverflowLayer->getScrollableArea() |
391 ->invalidateStickyConstraintsFor(layer()); | 398 ->invalidateStickyConstraintsFor(layer()); |
392 } | 399 } |
393 | 400 |
394 // TODO(pdr): When slimming paint v2 is enabled, we will need to | 401 // TODO(pdr): When slimming paint v2 is enabled, we will need to |
395 // invalidate the scroll paint property subtree for this so main | 402 // invalidate the scroll paint property subtree for this so main thread |
396 // thread scroll reasons are recomputed. | 403 // scroll reasons are recomputed. |
397 } | 404 } |
398 } | 405 } |
399 | 406 |
400 if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { | 407 if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { |
401 if (newStyleIsViewportConstained && layer()) | 408 if (newStyleIsViewportConstained && layer()) |
402 frameView->addViewportConstrainedObject(this); | 409 frameView->addViewportConstrainedObject(this); |
403 else | 410 else |
404 frameView->removeViewportConstrainedObject(this); | 411 frameView->removeViewportConstrainedObject(this); |
405 } | 412 } |
406 } | 413 } |
407 } | 414 } |
408 | 415 |
409 void LayoutBoxModelObject::invalidateStickyConstraints() { | 416 void LayoutBoxModelObject::invalidateStickyConstraints() { |
410 if (!layer()) | 417 if (!layer()) |
411 return; | 418 return; |
412 | 419 |
413 // This intentionally uses the stale ancestor overflow layer compositing | 420 // This intentionally uses the stale ancestor overflow layer compositing input |
414 // input as if we have saved constraints for this layer they were saved | 421 // as if we have saved constraints for this layer they were saved in the |
415 // in the previous frame. | 422 // previous frame. |
416 DisableCompositingQueryAsserts disabler; | 423 DisableCompositingQueryAsserts disabler; |
417 if (const PaintLayer* ancestorOverflowLayer = | 424 if (const PaintLayer* ancestorOverflowLayer = |
418 layer()->ancestorOverflowLayer()) | 425 layer()->ancestorOverflowLayer()) |
419 ancestorOverflowLayer->getScrollableArea() | 426 ancestorOverflowLayer->getScrollableArea() |
420 ->invalidateAllStickyConstraints(); | 427 ->invalidateAllStickyConstraints(); |
421 } | 428 } |
422 | 429 |
423 void LayoutBoxModelObject::createLayer() { | 430 void LayoutBoxModelObject::createLayer() { |
424 ASSERT(!m_layer); | 431 ASSERT(!m_layer); |
425 m_layer = wrapUnique(new PaintLayer(this)); | 432 m_layer = wrapUnique(new PaintLayer(this)); |
(...skipping 14 matching lines...) Expand all Loading... |
440 return m_layer ? m_layer->getScrollableArea() : 0; | 447 return m_layer ? m_layer->getScrollableArea() : 0; |
441 } | 448 } |
442 | 449 |
443 void LayoutBoxModelObject::addLayerHitTestRects( | 450 void LayoutBoxModelObject::addLayerHitTestRects( |
444 LayerHitTestRects& rects, | 451 LayerHitTestRects& rects, |
445 const PaintLayer* currentLayer, | 452 const PaintLayer* currentLayer, |
446 const LayoutPoint& layerOffset, | 453 const LayoutPoint& layerOffset, |
447 const LayoutRect& containerRect) const { | 454 const LayoutRect& containerRect) const { |
448 if (hasLayer()) { | 455 if (hasLayer()) { |
449 if (isLayoutView()) { | 456 if (isLayoutView()) { |
450 // LayoutView is handled with a special fast-path, but it needs to know th
e current layer. | 457 // LayoutView is handled with a special fast-path, but it needs to know |
| 458 // the current layer. |
451 LayoutObject::addLayerHitTestRects(rects, layer(), LayoutPoint(), | 459 LayoutObject::addLayerHitTestRects(rects, layer(), LayoutPoint(), |
452 LayoutRect()); | 460 LayoutRect()); |
453 } else { | 461 } else { |
454 // Since a LayoutObject never lives outside it's container Layer, we can s
witch | 462 // Since a LayoutObject never lives outside it's container Layer, we can |
455 // to marking entire layers instead. This may sometimes mark more than nec
essary (when | 463 // switch to marking entire layers instead. This may sometimes mark more |
456 // a layer is made of disjoint objects) but in practice is a significant p
erformance | 464 // than necessary (when a layer is made of disjoint objects) but in |
457 // savings. | 465 // practice is a significant performance savings. |
458 layer()->addLayerHitTestRects(rects); | 466 layer()->addLayerHitTestRects(rects); |
459 } | 467 } |
460 } else { | 468 } else { |
461 LayoutObject::addLayerHitTestRects(rects, currentLayer, layerOffset, | 469 LayoutObject::addLayerHitTestRects(rects, currentLayer, layerOffset, |
462 containerRect); | 470 containerRect); |
463 } | 471 } |
464 } | 472 } |
465 | 473 |
466 static bool hasPercentageTransform(const ComputedStyle& style) { | 474 static bool hasPercentageTransform(const ComputedStyle& style) { |
467 if (TransformOperation* translate = style.translate()) { | 475 if (TransformOperation* translate = style.translate()) { |
(...skipping 26 matching lines...) Expand all Loading... |
494 this->previousPaintInvalidationRect(); | 502 this->previousPaintInvalidationRect(); |
495 LayoutPoint previousPosition = previousPositionFromPaintInvalidationBacking(); | 503 LayoutPoint previousPosition = previousPositionFromPaintInvalidationBacking(); |
496 PaintInvalidationReason reason = | 504 PaintInvalidationReason reason = |
497 invalidatePaintIfNeeded(newPaintInvalidationState); | 505 invalidatePaintIfNeeded(newPaintInvalidationState); |
498 clearPaintInvalidationFlags(); | 506 clearPaintInvalidationFlags(); |
499 | 507 |
500 if (previousPosition != previousPositionFromPaintInvalidationBacking()) | 508 if (previousPosition != previousPositionFromPaintInvalidationBacking()) |
501 newPaintInvalidationState | 509 newPaintInvalidationState |
502 .setForceSubtreeInvalidationCheckingWithinContainer(); | 510 .setForceSubtreeInvalidationCheckingWithinContainer(); |
503 | 511 |
504 // TODO(wangxianzhu): Combine this function into LayoutObject::invalidateTreeI
fNeeded() when removing the following workarounds. | 512 // TODO(wangxianzhu): Combine this function into LayoutObject:: |
| 513 // invalidateTreeIfNeeded() when removing the following workarounds. |
505 | 514 |
506 // TODO(wangxianzhu): This is a workaround for crbug.com/533277. Will remove w
hen we enable paint offset caching. | 515 // TODO(wangxianzhu): This is a workaround for crbug.com/533277. Will remove |
| 516 // when we enable paint offset caching. |
507 if (reason != PaintInvalidationNone && hasPercentageTransform(styleRef())) | 517 if (reason != PaintInvalidationNone && hasPercentageTransform(styleRef())) |
508 newPaintInvalidationState | 518 newPaintInvalidationState |
509 .setForceSubtreeInvalidationCheckingWithinContainer(); | 519 .setForceSubtreeInvalidationCheckingWithinContainer(); |
510 | 520 |
511 // TODO(wangxianzhu): This is a workaround for crbug.com/490725. We don't have
enough saved information to do accurate check | 521 // TODO(wangxianzhu): This is a workaround for crbug.com/490725. We don't have |
512 // of clipping change. Will remove when we remove rect-based paint invalidatio
n. | 522 // enough saved information to do accurate check of clipping change. Will |
| 523 // remove when we remove rect-based paint invalidation. |
513 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | 524 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
514 previousPaintInvalidationRect != this->previousPaintInvalidationRect() && | 525 previousPaintInvalidationRect != this->previousPaintInvalidationRect() && |
515 !usesCompositedScrolling() | 526 !usesCompositedScrolling() |
516 // Note that isLayoutView() below becomes unnecessary after the launch of
root layer scrolling. | 527 // Note that isLayoutView() below becomes unnecessary after the launch of |
| 528 // root layer scrolling. |
517 && (hasOverflowClip() || isLayoutView())) | 529 && (hasOverflowClip() || isLayoutView())) |
518 newPaintInvalidationState | 530 newPaintInvalidationState |
519 .setForceSubtreeInvalidationRectUpdateWithinContainer(); | 531 .setForceSubtreeInvalidationRectUpdateWithinContainer(); |
520 | 532 |
521 newPaintInvalidationState.updateForChildren(reason); | 533 newPaintInvalidationState.updateForChildren(reason); |
522 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); | 534 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); |
523 } | 535 } |
524 | 536 |
525 void LayoutBoxModelObject::addOutlineRectsForNormalChildren( | 537 void LayoutBoxModelObject::addOutlineRectsForNormalChildren( |
526 Vector<LayoutRect>& rects, | 538 Vector<LayoutRect>& rects, |
527 const LayoutPoint& additionalOffset, | 539 const LayoutPoint& additionalOffset, |
528 IncludeBlockVisualOverflowOrNot includeBlockOverflows) const { | 540 IncludeBlockVisualOverflowOrNot includeBlockOverflows) const { |
529 for (LayoutObject* child = slowFirstChild(); child; | 541 for (LayoutObject* child = slowFirstChild(); child; |
530 child = child->nextSibling()) { | 542 child = child->nextSibling()) { |
531 // Outlines of out-of-flow positioned descendants are handled in LayoutBlock
::addOutlineRects(). | 543 // Outlines of out-of-flow positioned descendants are handled in |
| 544 // LayoutBlock::addOutlineRects(). |
532 if (child->isOutOfFlowPositioned()) | 545 if (child->isOutOfFlowPositioned()) |
533 continue; | 546 continue; |
534 | 547 |
535 // Outline of an element continuation or anonymous block continuation is add
ed when we iterate the continuation chain. | 548 // Outline of an element continuation or anonymous block continuation is |
| 549 // added when we iterate the continuation chain. |
536 // See LayoutBlock::addOutlineRects() and LayoutInline::addOutlineRects(). | 550 // See LayoutBlock::addOutlineRects() and LayoutInline::addOutlineRects(). |
537 if (child->isElementContinuation() || | 551 if (child->isElementContinuation() || |
538 (child->isLayoutBlockFlow() && | 552 (child->isLayoutBlockFlow() && |
539 toLayoutBlockFlow(child)->isAnonymousBlockContinuation())) | 553 toLayoutBlockFlow(child)->isAnonymousBlockContinuation())) |
540 continue; | 554 continue; |
541 | 555 |
542 addOutlineRectsForDescendant(*child, rects, additionalOffset, | 556 addOutlineRectsForDescendant(*child, rects, additionalOffset, |
543 includeBlockOverflows); | 557 includeBlockOverflows); |
544 } | 558 } |
545 } | 559 } |
(...skipping 17 matching lines...) Expand all Loading... |
563 } | 577 } |
564 | 578 |
565 if (descendant.isBox()) { | 579 if (descendant.isBox()) { |
566 descendant.addOutlineRects( | 580 descendant.addOutlineRects( |
567 rects, additionalOffset + toLayoutBox(descendant).locationOffset(), | 581 rects, additionalOffset + toLayoutBox(descendant).locationOffset(), |
568 includeBlockOverflows); | 582 includeBlockOverflows); |
569 return; | 583 return; |
570 } | 584 } |
571 | 585 |
572 if (descendant.isLayoutInline()) { | 586 if (descendant.isLayoutInline()) { |
573 // As an optimization, an ancestor has added rects for its line boxes coveri
ng descendants' | 587 // As an optimization, an ancestor has added rects for its line boxes |
574 // line boxes, so descendants don't need to add line boxes again. For exampl
e, if the parent | 588 // covering descendants' line boxes, so descendants don't need to add line |
575 // is a LayoutBlock, it adds rects for its RootOutlineBoxes which cover the
line boxes of | 589 // boxes again. For example, if the parent is a LayoutBlock, it adds rects |
576 // this LayoutInline. So the LayoutInline needs to add rects for children an
d continuations only. | 590 // for its RootOutlineBoxes which cover the line boxes of this LayoutInline. |
| 591 // So the LayoutInline needs to add rects for children and continuations |
| 592 // only. |
577 toLayoutInline(descendant) | 593 toLayoutInline(descendant) |
578 .addOutlineRectsForChildrenAndContinuations(rects, additionalOffset, | 594 .addOutlineRectsForChildrenAndContinuations(rects, additionalOffset, |
579 includeBlockOverflows); | 595 includeBlockOverflows); |
580 return; | 596 return; |
581 } | 597 } |
582 | 598 |
583 descendant.addOutlineRects(rects, additionalOffset, includeBlockOverflows); | 599 descendant.addOutlineRects(rects, additionalOffset, includeBlockOverflows); |
584 } | 600 } |
585 | 601 |
586 bool LayoutBoxModelObject::hasNonEmptyLayoutSize() const { | 602 bool LayoutBoxModelObject::hasNonEmptyLayoutSize() const { |
(...skipping 27 matching lines...) Expand all Loading... |
614 | 630 |
615 static inline bool isOutOfFlowPositionedWithImplicitHeight( | 631 static inline bool isOutOfFlowPositionedWithImplicitHeight( |
616 const LayoutBoxModelObject* child) { | 632 const LayoutBoxModelObject* child) { |
617 return child->isOutOfFlowPositioned() && | 633 return child->isOutOfFlowPositioned() && |
618 !child->style()->logicalTop().isAuto() && | 634 !child->style()->logicalTop().isAuto() && |
619 !child->style()->logicalBottom().isAuto(); | 635 !child->style()->logicalBottom().isAuto(); |
620 } | 636 } |
621 | 637 |
622 LayoutBlock* LayoutBoxModelObject::containingBlockForAutoHeightDetection( | 638 LayoutBlock* LayoutBoxModelObject::containingBlockForAutoHeightDetection( |
623 Length logicalHeight) const { | 639 Length logicalHeight) const { |
624 // For percentage heights: The percentage is calculated with respect to the he
ight of the generated box's | 640 // For percentage heights: The percentage is calculated with respect to the |
625 // containing block. If the height of the containing block is not specified ex
plicitly (i.e., it depends | 641 // height of the generated box's containing block. If the height of the |
626 // on content height), and this element is not absolutely positioned, the use
d height is calculated | 642 // containing block is not specified explicitly (i.e., it depends on content |
627 // as if 'auto' was specified. | 643 // height), and this element is not absolutely positioned, the used height is |
| 644 // calculated as if 'auto' was specified. |
628 if (!logicalHeight.isPercentOrCalc() || isOutOfFlowPositioned()) | 645 if (!logicalHeight.isPercentOrCalc() || isOutOfFlowPositioned()) |
629 return nullptr; | 646 return nullptr; |
630 | 647 |
631 // Anonymous block boxes are ignored when resolving percentage values that wou
ld refer to it: | 648 // Anonymous block boxes are ignored when resolving percentage values that |
632 // the closest non-anonymous ancestor box is used instead. | 649 // would refer to it: the closest non-anonymous ancestor box is used instead. |
633 LayoutBlock* cb = containingBlock(); | 650 LayoutBlock* cb = containingBlock(); |
634 while (cb->isAnonymous()) | 651 while (cb->isAnonymous()) |
635 cb = cb->containingBlock(); | 652 cb = cb->containingBlock(); |
636 | 653 |
637 // Matching LayoutBox::percentageLogicalHeightIsResolvableFromBlock() by | 654 // Matching LayoutBox::percentageLogicalHeightIsResolvableFromBlock() by |
638 // ignoring table cell's attribute value, where it says that table cells viola
te | 655 // ignoring table cell's attribute value, where it says that table cells |
639 // what the CSS spec says to do with heights. Basically we | 656 // violate what the CSS spec says to do with heights. Basically we don't care |
640 // don't care if the cell specified a height or not. | 657 // if the cell specified a height or not. |
641 if (cb->isTableCell()) | 658 if (cb->isTableCell()) |
642 return nullptr; | 659 return nullptr; |
643 | 660 |
644 // Match LayoutBox::availableLogicalHeightUsing by special casing | 661 // Match LayoutBox::availableLogicalHeightUsing by special casing the layout |
645 // the layout view. The available height is taken from the frame. | 662 // view. The available height is taken from the frame. |
646 if (cb->isLayoutView()) | 663 if (cb->isLayoutView()) |
647 return nullptr; | 664 return nullptr; |
648 | 665 |
649 if (isOutOfFlowPositionedWithImplicitHeight(cb)) | 666 if (isOutOfFlowPositionedWithImplicitHeight(cb)) |
650 return nullptr; | 667 return nullptr; |
651 | 668 |
652 return cb; | 669 return cb; |
653 } | 670 } |
654 | 671 |
655 bool LayoutBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight( | 672 bool LayoutBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight( |
656 bool checkingContainingBlock) const { | 673 bool checkingContainingBlock) const { |
657 // TODO(rego): Check if we can somehow reuse LayoutBlock::availableLogicalHeig
htForPercentageComputation() (see http://crbug.com/635655). | 674 // TODO(rego): Check if we can somehow reuse LayoutBlock:: |
| 675 // availableLogicalHeightForPercentageComputation() (see crbug.com/635655). |
658 const LayoutBox* thisBox = isBox() ? toLayoutBox(this) : nullptr; | 676 const LayoutBox* thisBox = isBox() ? toLayoutBox(this) : nullptr; |
659 Length logicalHeightLength = style()->logicalHeight(); | 677 Length logicalHeightLength = style()->logicalHeight(); |
660 LayoutBlock* cb = containingBlockForAutoHeightDetection(logicalHeightLength); | 678 LayoutBlock* cb = containingBlockForAutoHeightDetection(logicalHeightLength); |
661 if (logicalHeightLength.isPercentOrCalc() && cb && isBox()) | 679 if (logicalHeightLength.isPercentOrCalc() && cb && isBox()) |
662 cb->addPercentHeightDescendant(const_cast<LayoutBox*>(toLayoutBox(this))); | 680 cb->addPercentHeightDescendant(const_cast<LayoutBox*>(toLayoutBox(this))); |
663 if (thisBox && thisBox->isFlexItem()) { | 681 if (thisBox && thisBox->isFlexItem()) { |
664 LayoutFlexibleBox& flexBox = toLayoutFlexibleBox(*parent()); | 682 LayoutFlexibleBox& flexBox = toLayoutFlexibleBox(*parent()); |
665 if (flexBox.childLogicalHeightForPercentageResolution(*thisBox) != | 683 if (flexBox.childLogicalHeightForPercentageResolution(*thisBox) != |
666 LayoutUnit(-1)) | 684 LayoutUnit(-1)) |
667 return false; | 685 return false; |
668 } | 686 } |
669 if (thisBox && thisBox->isGridItem()) { | 687 if (thisBox && thisBox->isGridItem()) { |
670 if (checkingContainingBlock && thisBox->hasOverrideLogicalContentHeight()) | 688 if (checkingContainingBlock && thisBox->hasOverrideLogicalContentHeight()) |
671 return false; | 689 return false; |
672 if (!checkingContainingBlock && | 690 if (!checkingContainingBlock && |
673 thisBox->hasOverrideContainingBlockLogicalHeight()) | 691 thisBox->hasOverrideContainingBlockLogicalHeight()) |
674 return false; | 692 return false; |
675 } | 693 } |
676 if (logicalHeightLength.isAuto() && | 694 if (logicalHeightLength.isAuto() && |
677 !isOutOfFlowPositionedWithImplicitHeight(this)) | 695 !isOutOfFlowPositionedWithImplicitHeight(this)) |
678 return true; | 696 return true; |
679 | 697 |
680 if (document().inQuirksMode()) | 698 if (document().inQuirksMode()) |
681 return false; | 699 return false; |
682 | 700 |
683 // If the height of the containing block computes to 'auto', then it hasn't be
en 'specified explicitly'. | 701 // If the height of the containing block computes to 'auto', then it hasn't |
| 702 // been 'specified explicitly'. |
684 if (cb) | 703 if (cb) |
685 return cb->hasAutoHeightOrContainingBlockWithAutoHeight(true); | 704 return cb->hasAutoHeightOrContainingBlockWithAutoHeight(true); |
686 return false; | 705 return false; |
687 } | 706 } |
688 | 707 |
689 bool LayoutBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() | 708 bool LayoutBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() |
690 const { | 709 const { |
691 return hasAutoHeightOrContainingBlockWithAutoHeight(false); | 710 return hasAutoHeightOrContainingBlockWithAutoHeight(false); |
692 } | 711 } |
693 | 712 |
694 LayoutSize LayoutBoxModelObject::relativePositionOffset() const { | 713 LayoutSize LayoutBoxModelObject::relativePositionOffset() const { |
695 LayoutSize offset = accumulateInFlowPositionOffsets(); | 714 LayoutSize offset = accumulateInFlowPositionOffsets(); |
696 | 715 |
697 LayoutBlock* containingBlock = this->containingBlock(); | 716 LayoutBlock* containingBlock = this->containingBlock(); |
698 | 717 |
699 // Objects that shrink to avoid floats normally use available line width when
computing containing block width. However | 718 // Objects that shrink to avoid floats normally use available line width when |
700 // in the case of relative positioning using percentages, we can't do this. T
he offset should always be resolved using the | 719 // computing containing block width. However in the case of relative |
701 // available width of the containing block. Therefore we don't use containing
BlockLogicalWidthForContent() here, but instead explicitly | 720 // positioning using percentages, we can't do this. The offset should always |
702 // call availableWidth on our containing block. | 721 // be resolved using the available width of the containing block. Therefore we |
| 722 // don't use containingBlockLogicalWidthForContent() here, but instead |
| 723 // explicitly call availableWidth on our containing block. |
703 if (!style()->left().isAuto()) { | 724 if (!style()->left().isAuto()) { |
704 if (!style()->right().isAuto() && | 725 if (!style()->right().isAuto() && |
705 !containingBlock->style()->isLeftToRightDirection()) | 726 !containingBlock->style()->isLeftToRightDirection()) |
706 offset.setWidth( | 727 offset.setWidth( |
707 -valueForLength(style()->right(), containingBlock->availableWidth())); | 728 -valueForLength(style()->right(), containingBlock->availableWidth())); |
708 else | 729 else |
709 offset.expand( | 730 offset.expand( |
710 valueForLength(style()->left(), containingBlock->availableWidth()), | 731 valueForLength(style()->left(), containingBlock->availableWidth()), |
711 LayoutUnit()); | 732 LayoutUnit()); |
712 } else if (!style()->right().isAuto()) { | 733 } else if (!style()->right().isAuto()) { |
713 offset.expand( | 734 offset.expand( |
714 -valueForLength(style()->right(), containingBlock->availableWidth()), | 735 -valueForLength(style()->right(), containingBlock->availableWidth()), |
715 LayoutUnit()); | 736 LayoutUnit()); |
716 } | 737 } |
717 | 738 |
718 // If the containing block of a relatively positioned element does not | 739 // If the containing block of a relatively positioned element does not specify |
719 // specify a height, a percentage top or bottom offset should be resolved as | 740 // a height, a percentage top or bottom offset should be resolved as auto. |
720 // auto. An exception to this is if the containing block has the WinIE quirk | 741 // An exception to this is if the containing block has the WinIE quirk where |
721 // where <html> and <body> assume the size of the viewport. In this case, | 742 // <html> and <body> assume the size of the viewport. In this case, calculate |
722 // calculate the percent offset based on this height. | 743 // the percent offset based on this height. |
723 // See <https://bugs.webkit.org/show_bug.cgi?id=26396>. | 744 // See <https://bugs.webkit.org/show_bug.cgi?id=26396>. |
724 if (!style()->top().isAuto() && | 745 if (!style()->top().isAuto() && |
725 (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight() || | 746 (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight() || |
726 !style()->top().isPercentOrCalc() || | 747 !style()->top().isPercentOrCalc() || |
727 containingBlock->stretchesToViewport())) | 748 containingBlock->stretchesToViewport())) |
728 offset.expand( | 749 offset.expand( |
729 LayoutUnit(), | 750 LayoutUnit(), |
730 valueForLength(style()->top(), containingBlock->availableHeight())); | 751 valueForLength(style()->top(), containingBlock->availableHeight())); |
731 | 752 |
732 else if (!style()->bottom().isAuto() && | 753 else if (!style()->bottom().isAuto() && |
(...skipping 23 matching lines...) Expand all Loading... |
756 } | 777 } |
757 LayoutBox* scrollAncestor = | 778 LayoutBox* scrollAncestor = |
758 layer()->ancestorOverflowLayer()->isRootLayer() | 779 layer()->ancestorOverflowLayer()->isRootLayer() |
759 ? nullptr | 780 ? nullptr |
760 : toLayoutBox(layer()->ancestorOverflowLayer()->layoutObject()); | 781 : toLayoutBox(layer()->ancestorOverflowLayer()->layoutObject()); |
761 | 782 |
762 LayoutUnit maxContainerWidth = | 783 LayoutUnit maxContainerWidth = |
763 containingBlock->isLayoutView() | 784 containingBlock->isLayoutView() |
764 ? containingBlock->logicalWidth() | 785 ? containingBlock->logicalWidth() |
765 : containingBlock->containingBlockLogicalWidthForContent(); | 786 : containingBlock->containingBlockLogicalWidthForContent(); |
766 // Sticky positioned element ignore any override logical width on the containi
ng block (as they don't call | 787 // Sticky positioned element ignore any override logical width on the |
767 // containingBlockLogicalWidthForContent). It's unclear whether this is totall
y fine. | 788 // containing block, as they don't call containingBlockLogicalWidthForContent. |
768 // Compute the container-relative area within which the sticky element is allo
wed to move. | 789 // It's unclear whether this is totally fine. |
| 790 // Compute the container-relative area within which the sticky element is |
| 791 // allowed to move. |
769 LayoutUnit maxWidth = containingBlock->availableLogicalWidth(); | 792 LayoutUnit maxWidth = containingBlock->availableLogicalWidth(); |
770 | 793 |
771 // Map the containing block to the scroll ancestor without transforms. | 794 // Map the containing block to the scroll ancestor without transforms. |
772 FloatRect scrollContainerRelativePaddingBoxRect( | 795 FloatRect scrollContainerRelativePaddingBoxRect( |
773 containingBlock->layoutOverflowRect()); | 796 containingBlock->layoutOverflowRect()); |
774 if (containingBlock != scrollAncestor) { | 797 if (containingBlock != scrollAncestor) { |
775 FloatQuad localQuad(FloatRect(containingBlock->paddingBoxRect())); | 798 FloatQuad localQuad(FloatRect(containingBlock->paddingBoxRect())); |
776 TransformState transformState(TransformState::ApplyTransformDirection, | 799 TransformState transformState(TransformState::ApplyTransformDirection, |
777 localQuad.boundingBox().center(), localQuad); | 800 localQuad.boundingBox().center(), localQuad); |
778 containingBlock->mapLocalToAncestor(scrollAncestor, transformState, | 801 containingBlock->mapLocalToAncestor(scrollAncestor, transformState, |
779 ApplyContainerFlip); | 802 ApplyContainerFlip); |
780 transformState.flatten(); | 803 transformState.flatten(); |
781 scrollContainerRelativePaddingBoxRect = | 804 scrollContainerRelativePaddingBoxRect = |
782 transformState.lastPlanarQuad().boundingBox(); | 805 transformState.lastPlanarQuad().boundingBox(); |
783 | 806 |
784 // The sticky position constraint rects should be independent of the current
scroll position, so after | 807 // The sticky position constraint rects should be independent of the current |
785 // mapping we add in the scroll position to get the container's position wit
hin the ancestor scroller's | 808 // scroll position, so after mapping we add in the scroll position to get |
786 // unscrolled layout overflow. | 809 // the container's position within the ancestor scroller's unscrolled layout |
| 810 // overflow. |
787 ScrollOffset scrollOffset( | 811 ScrollOffset scrollOffset( |
788 scrollAncestor | 812 scrollAncestor |
789 ? toFloatSize(scrollAncestor->getScrollableArea()->scrollPosition()) | 813 ? toFloatSize(scrollAncestor->getScrollableArea()->scrollPosition()) |
790 : FloatSize()); | 814 : FloatSize()); |
791 scrollContainerRelativePaddingBoxRect.move(scrollOffset); | 815 scrollContainerRelativePaddingBoxRect.move(scrollOffset); |
792 } | 816 } |
793 | 817 |
794 LayoutRect scrollContainerRelativeContainingBlockRect( | 818 LayoutRect scrollContainerRelativeContainingBlockRect( |
795 scrollContainerRelativePaddingBoxRect); | 819 scrollContainerRelativePaddingBoxRect); |
796 // This is removing the padding of the containing block's overflow rect to get
the flow | 820 // This is removing the padding of the containing block's overflow rect to get |
797 // box rectangle and removing the margin of the sticky element to ensure that
space between | 821 // the flow box rectangle and removing the margin of the sticky element to |
798 // the sticky element and its containing flow box. It is an open issue whether
the margin | 822 // ensure that space between the sticky element and its containing flow box. |
799 // should collapse (See https://www.w3.org/TR/css-position-3/#sticky-pos). | 823 // It is an open issue whether the margin should collapse. |
| 824 // See https://www.w3.org/TR/css-position-3/#sticky-pos |
800 scrollContainerRelativeContainingBlockRect.contractEdges( | 825 scrollContainerRelativeContainingBlockRect.contractEdges( |
801 minimumValueForLength(containingBlock->style()->paddingTop(), | 826 minimumValueForLength(containingBlock->style()->paddingTop(), |
802 maxContainerWidth) + | 827 maxContainerWidth) + |
803 minimumValueForLength(style()->marginTop(), maxWidth), | 828 minimumValueForLength(style()->marginTop(), maxWidth), |
804 minimumValueForLength(containingBlock->style()->paddingRight(), | 829 minimumValueForLength(containingBlock->style()->paddingRight(), |
805 maxContainerWidth) + | 830 maxContainerWidth) + |
806 minimumValueForLength(style()->marginRight(), maxWidth), | 831 minimumValueForLength(style()->marginRight(), maxWidth), |
807 minimumValueForLength(containingBlock->style()->paddingBottom(), | 832 minimumValueForLength(containingBlock->style()->paddingBottom(), |
808 maxContainerWidth) + | 833 maxContainerWidth) + |
809 minimumValueForLength(style()->marginBottom(), maxWidth), | 834 minimumValueForLength(style()->marginBottom(), maxWidth), |
810 minimumValueForLength(containingBlock->style()->paddingLeft(), | 835 minimumValueForLength(containingBlock->style()->paddingLeft(), |
811 maxContainerWidth) + | 836 maxContainerWidth) + |
812 minimumValueForLength(style()->marginLeft(), maxWidth)); | 837 minimumValueForLength(style()->marginLeft(), maxWidth)); |
813 | 838 |
814 constraints.setScrollContainerRelativeContainingBlockRect( | 839 constraints.setScrollContainerRelativeContainingBlockRect( |
815 FloatRect(scrollContainerRelativeContainingBlockRect)); | 840 FloatRect(scrollContainerRelativeContainingBlockRect)); |
816 | 841 |
817 FloatRect stickyBoxRect = | 842 FloatRect stickyBoxRect = |
818 isLayoutInline() ? FloatRect(toLayoutInline(this)->linesBoundingBox()) | 843 isLayoutInline() ? FloatRect(toLayoutInline(this)->linesBoundingBox()) |
819 : FloatRect(toLayoutBox(this)->frameRect()); | 844 : FloatRect(toLayoutBox(this)->frameRect()); |
820 FloatRect flippedStickyBoxRect = stickyBoxRect; | 845 FloatRect flippedStickyBoxRect = stickyBoxRect; |
821 containingBlock->flipForWritingMode(flippedStickyBoxRect); | 846 containingBlock->flipForWritingMode(flippedStickyBoxRect); |
822 FloatPoint stickyLocation = | 847 FloatPoint stickyLocation = |
823 flippedStickyBoxRect.location() + skippedContainersOffset; | 848 flippedStickyBoxRect.location() + skippedContainersOffset; |
824 | 849 |
825 // The scrollContainerRelativePaddingBoxRect's position is the padding box so
we need to remove the border when finding | 850 // The scrollContainerRelativePaddingBoxRect's position is the padding box so |
826 // the position of the sticky box within the scroll ancestor if the container
is not our scroll ancestor. | 851 // we need to remove the border when finding the position of the sticky box |
| 852 // within the scroll ancestor if the container is not our scroll ancestor. |
827 if (containingBlock != scrollAncestor) { | 853 if (containingBlock != scrollAncestor) { |
828 FloatSize containerBorderOffset(containingBlock->borderLeft(), | 854 FloatSize containerBorderOffset(containingBlock->borderLeft(), |
829 containingBlock->borderTop()); | 855 containingBlock->borderTop()); |
830 stickyLocation -= containerBorderOffset; | 856 stickyLocation -= containerBorderOffset; |
831 } | 857 } |
832 constraints.setScrollContainerRelativeStickyBoxRect( | 858 constraints.setScrollContainerRelativeStickyBoxRect( |
833 FloatRect(scrollContainerRelativePaddingBoxRect.location() + | 859 FloatRect(scrollContainerRelativePaddingBoxRect.location() + |
834 toFloatSize(stickyLocation), | 860 toFloatSize(stickyLocation), |
835 flippedStickyBoxRect.size())); | 861 flippedStickyBoxRect.size())); |
836 | 862 |
837 // We skip the right or top sticky offset if there is not enough space to hono
r both the left/right or top/bottom offsets. | 863 // We skip the right or top sticky offset if there is not enough space to |
| 864 // honor both the left/right or top/bottom offsets. |
838 LayoutUnit horizontalOffsets = | 865 LayoutUnit horizontalOffsets = |
839 minimumValueForLength(style()->right(), | 866 minimumValueForLength(style()->right(), |
840 LayoutUnit(constrainingSize.width())) + | 867 LayoutUnit(constrainingSize.width())) + |
841 minimumValueForLength(style()->left(), | 868 minimumValueForLength(style()->left(), |
842 LayoutUnit(constrainingSize.width())); | 869 LayoutUnit(constrainingSize.width())); |
843 bool skipRight = false; | 870 bool skipRight = false; |
844 bool skipLeft = false; | 871 bool skipLeft = false; |
845 if (!style()->left().isAuto() && !style()->right().isAuto()) { | 872 if (!style()->left().isAuto() && !style()->right().isAuto()) { |
846 if (horizontalOffsets > | 873 if (horizontalOffsets > |
847 scrollContainerRelativeContainingBlockRect.width() || | 874 scrollContainerRelativeContainingBlockRect.width() || |
(...skipping 12 matching lines...) Expand all Loading... |
860 } | 887 } |
861 | 888 |
862 if (!style()->right().isAuto() && !skipRight) { | 889 if (!style()->right().isAuto() && !skipRight) { |
863 constraints.setRightOffset(minimumValueForLength( | 890 constraints.setRightOffset(minimumValueForLength( |
864 style()->right(), LayoutUnit(constrainingSize.width()))); | 891 style()->right(), LayoutUnit(constrainingSize.width()))); |
865 constraints.addAnchorEdge( | 892 constraints.addAnchorEdge( |
866 StickyPositionScrollingConstraints::AnchorEdgeRight); | 893 StickyPositionScrollingConstraints::AnchorEdgeRight); |
867 } | 894 } |
868 | 895 |
869 bool skipBottom = false; | 896 bool skipBottom = false; |
870 // TODO(flackr): Exclude top or bottom edge offset depending on the writing mo
de when related | 897 // TODO(flackr): Exclude top or bottom edge offset depending on the writing |
871 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style/2
014May/0286.html | 898 // mode when related sections are fixed in spec. |
| 899 // See http://lists.w3.org/Archives/Public/www-style/2014May/0286.html |
872 LayoutUnit verticalOffsets = | 900 LayoutUnit verticalOffsets = |
873 minimumValueForLength(style()->top(), | 901 minimumValueForLength(style()->top(), |
874 LayoutUnit(constrainingSize.height())) + | 902 LayoutUnit(constrainingSize.height())) + |
875 minimumValueForLength(style()->bottom(), | 903 minimumValueForLength(style()->bottom(), |
876 LayoutUnit(constrainingSize.height())); | 904 LayoutUnit(constrainingSize.height())); |
877 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { | 905 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { |
878 if (verticalOffsets > scrollContainerRelativeContainingBlockRect.height() || | 906 if (verticalOffsets > scrollContainerRelativeContainingBlockRect.height() || |
879 verticalOffsets + scrollContainerRelativeContainingBlockRect.height() > | 907 verticalOffsets + scrollContainerRelativeContainingBlockRect.height() > |
880 constrainingSize.height()) { | 908 constrainingSize.height()) { |
881 skipBottom = true; | 909 skipBottom = true; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 constrainingRect.contract( | 941 constrainingRect.contract( |
914 FloatSize(enclosingClippingBox->paddingLeft() + | 942 FloatSize(enclosingClippingBox->paddingLeft() + |
915 enclosingClippingBox->paddingRight(), | 943 enclosingClippingBox->paddingRight(), |
916 enclosingClippingBox->paddingTop() + | 944 enclosingClippingBox->paddingTop() + |
917 enclosingClippingBox->paddingBottom())); | 945 enclosingClippingBox->paddingBottom())); |
918 return constrainingRect; | 946 return constrainingRect; |
919 } | 947 } |
920 | 948 |
921 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const { | 949 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const { |
922 const PaintLayer* ancestorOverflowLayer = layer()->ancestorOverflowLayer(); | 950 const PaintLayer* ancestorOverflowLayer = layer()->ancestorOverflowLayer(); |
923 // TODO: Force compositing input update if we ask for offset before compositin
g inputs have been computed? | 951 // TODO: Force compositing input update if we ask for offset before |
| 952 // compositing inputs have been computed? |
924 if (!ancestorOverflowLayer) | 953 if (!ancestorOverflowLayer) |
925 return LayoutSize(); | 954 return LayoutSize(); |
926 FloatRect constrainingRect = computeStickyConstrainingRect(); | 955 FloatRect constrainingRect = computeStickyConstrainingRect(); |
927 PaintLayerScrollableArea* scrollableArea = | 956 PaintLayerScrollableArea* scrollableArea = |
928 ancestorOverflowLayer->getScrollableArea(); | 957 ancestorOverflowLayer->getScrollableArea(); |
929 | 958 |
930 // The sticky offset is physical, so we can just return the delta computed in
absolute coords (though it may be wrong with transforms). | 959 // The sticky offset is physical, so we can just return the delta computed in |
931 // TODO: Force compositing input update if we ask for offset with stale compos
iting inputs. | 960 // absolute coords (though it may be wrong with transforms). |
| 961 // TODO: Force compositing input update if we ask for offset with stale |
| 962 // compositing inputs. |
932 if (!scrollableArea->stickyConstraintsMap().contains(layer())) | 963 if (!scrollableArea->stickyConstraintsMap().contains(layer())) |
933 return LayoutSize(); | 964 return LayoutSize(); |
934 return LayoutSize( | 965 return LayoutSize( |
935 scrollableArea->stickyConstraintsMap().get(layer()).computeStickyOffset( | 966 scrollableArea->stickyConstraintsMap().get(layer()).computeStickyOffset( |
936 constrainingRect)); | 967 constrainingRect)); |
937 } | 968 } |
938 | 969 |
939 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( | 970 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( |
940 const LayoutPoint& startPoint, | 971 const LayoutPoint& startPoint, |
941 const Element* element) const { | 972 const Element* element) const { |
942 // If the element is the HTML body element or doesn't have a parent | 973 // If the element is the HTML body element or doesn't have a parent |
943 // return 0 and stop this algorithm. | 974 // return 0 and stop this algorithm. |
944 if (isBody() || !parent()) | 975 if (isBody() || !parent()) |
945 return LayoutPoint(); | 976 return LayoutPoint(); |
946 | 977 |
947 LayoutPoint referencePoint = startPoint; | 978 LayoutPoint referencePoint = startPoint; |
948 | 979 |
949 // If the base element is null, return the distance between the canvas origin
and | 980 // If the base element is null, return the distance between the canvas origin |
950 // the left border edge of the element and stop this algorithm. | 981 // and the left border edge of the element and stop this algorithm. |
951 if (!element) | 982 if (!element) |
952 return referencePoint; | 983 return referencePoint; |
953 | 984 |
954 if (const LayoutBoxModelObject* offsetParent = | 985 if (const LayoutBoxModelObject* offsetParent = |
955 element->layoutBoxModelObject()) { | 986 element->layoutBoxModelObject()) { |
956 if (!isOutOfFlowPositioned()) { | 987 if (!isOutOfFlowPositioned()) { |
957 if (isInFlowPositioned()) | 988 if (isInFlowPositioned()) |
958 referencePoint.move(offsetForInFlowPosition()); | 989 referencePoint.move(offsetForInFlowPosition()); |
959 | 990 |
960 // Note that we may fail to find |offsetParent| while walking the containe
r chain, if | 991 // Note that we may fail to find |offsetParent| while walking the |
961 // |offsetParent| is an inline split into continuations. | 992 // container chain, if |offsetParent| is an inline split into |
962 // <body style="display:inline;" id="offsetParent"><div></div><span id="th
is"> | 993 // continuations: <body style="display:inline;" id="offsetParent"><div> |
| 994 // </div><span id="this"> |
963 // This is why we have to do a nullptr check here. | 995 // This is why we have to do a nullptr check here. |
964 // offset(Left|Top) is generally broken when offsetParent is inline. | 996 // offset(Left|Top) is generally broken when offsetParent is inline. |
965 for (const LayoutObject* current = container(); | 997 for (const LayoutObject* current = container(); |
966 current && current != offsetParent; current = current->container()) { | 998 current && current != offsetParent; current = current->container()) { |
967 // FIXME: What are we supposed to do inside SVG content? | 999 // FIXME: What are we supposed to do inside SVG content? |
968 referencePoint.move(current->columnOffset(referencePoint)); | 1000 referencePoint.move(current->columnOffset(referencePoint)); |
969 if (current->isBox() && !current->isTableRow()) | 1001 if (current->isBox() && !current->isTableRow()) |
970 referencePoint.moveBy(toLayoutBox(current)->topLeftLocation()); | 1002 referencePoint.moveBy(toLayoutBox(current)->topLeftLocation()); |
971 } | 1003 } |
972 | 1004 |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped); | 1230 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped); |
1199 if (!container) | 1231 if (!container) |
1200 return nullptr; | 1232 return nullptr; |
1201 | 1233 |
1202 bool isInline = isLayoutInline(); | 1234 bool isInline = isLayoutInline(); |
1203 bool isFixedPos = !isInline && style()->position() == FixedPosition; | 1235 bool isFixedPos = !isInline && style()->position() == FixedPosition; |
1204 bool containsFixedPosition = canContainFixedPositionObjects(); | 1236 bool containsFixedPosition = canContainFixedPositionObjects(); |
1205 | 1237 |
1206 LayoutSize adjustmentForSkippedAncestor; | 1238 LayoutSize adjustmentForSkippedAncestor; |
1207 if (ancestorSkipped) { | 1239 if (ancestorSkipped) { |
1208 // There can't be a transform between paintInvalidationContainer and ancesto
rToStopAt, because transforms create containers, so it should be safe | 1240 // There can't be a transform between paintInvalidationContainer and |
1209 // to just subtract the delta between the ancestor and ancestorToStopAt. | 1241 // ancestorToStopAt, because transforms create containers, so it should be |
| 1242 // safe to just subtract the delta between the ancestor and |
| 1243 // ancestorToStopAt. |
1210 adjustmentForSkippedAncestor = | 1244 adjustmentForSkippedAncestor = |
1211 -ancestorToStopAt->offsetFromAncestorContainer(container); | 1245 -ancestorToStopAt->offsetFromAncestorContainer(container); |
1212 } | 1246 } |
1213 | 1247 |
1214 LayoutSize containerOffset = offsetFromContainer(container); | 1248 LayoutSize containerOffset = offsetFromContainer(container); |
1215 bool offsetDependsOnPoint; | 1249 bool offsetDependsOnPoint; |
1216 if (isLayoutFlowThread()) { | 1250 if (isLayoutFlowThread()) { |
1217 containerOffset += columnOffset(LayoutPoint()); | 1251 containerOffset += columnOffset(LayoutPoint()); |
1218 offsetDependsOnPoint = true; | 1252 offsetDependsOnPoint = true; |
1219 } else { | 1253 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
1242 geometryMap.push(this, containerOffset, flags, LayoutSize()); | 1276 geometryMap.push(this, containerOffset, flags, LayoutSize()); |
1243 } | 1277 } |
1244 | 1278 |
1245 return ancestorSkipped ? ancestorToStopAt : container; | 1279 return ancestorSkipped ? ancestorToStopAt : container; |
1246 } | 1280 } |
1247 | 1281 |
1248 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, | 1282 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, |
1249 LayoutObject* child, | 1283 LayoutObject* child, |
1250 LayoutObject* beforeChild, | 1284 LayoutObject* beforeChild, |
1251 bool fullRemoveInsert) { | 1285 bool fullRemoveInsert) { |
1252 // We assume that callers have cleared their positioned objects list for child
moves (!fullRemoveInsert) so the | 1286 // We assume that callers have cleared their positioned objects list for child |
1253 // positioned layoutObject maps don't become stale. It would be too slow to do
the map lookup on each call. | 1287 // moves (!fullRemoveInsert) so the positioned layoutObject maps don't become |
| 1288 // stale. It would be too slow to do the map lookup on each call. |
1254 ASSERT(!fullRemoveInsert || !isLayoutBlock() || | 1289 ASSERT(!fullRemoveInsert || !isLayoutBlock() || |
1255 !toLayoutBlock(this)->hasPositionedObjects()); | 1290 !toLayoutBlock(this)->hasPositionedObjects()); |
1256 | 1291 |
1257 ASSERT(this == child->parent()); | 1292 ASSERT(this == child->parent()); |
1258 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); | 1293 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); |
1259 | 1294 |
1260 // If a child is moving from a block-flow to an inline-flow parent then any fl
oats currently intruding into | 1295 // If a child is moving from a block-flow to an inline-flow parent then any |
1261 // the child can no longer do so. This can happen if a block becomes floating
or out-of-flow and is moved | 1296 // floats currently intruding into the child can no longer do so. This can |
1262 // to an anonymous block. Remove all floats from their float-lists immediately
as markAllDescendantsWithFloatsForLayout | 1297 // happen if a block becomes floating or out-of-flow and is moved to an |
1263 // won't attempt to remove floats from parents that have inline-flow if we try
later. | 1298 // anonymous block. Remove all floats from their float-lists immediately as |
| 1299 // markAllDescendantsWithFloatsForLayout won't attempt to remove floats from |
| 1300 // parents that have inline-flow if we try later. |
1264 if (child->isLayoutBlockFlow() && toBoxModelObject->childrenInline() && | 1301 if (child->isLayoutBlockFlow() && toBoxModelObject->childrenInline() && |
1265 !childrenInline()) { | 1302 !childrenInline()) { |
1266 toLayoutBlockFlow(child)->removeFloatingObjectsFromDescendants(); | 1303 toLayoutBlockFlow(child)->removeFloatingObjectsFromDescendants(); |
1267 ASSERT(!toLayoutBlockFlow(child)->containsFloats()); | 1304 ASSERT(!toLayoutBlockFlow(child)->containsFloats()); |
1268 } | 1305 } |
1269 | 1306 |
1270 if (fullRemoveInsert && isLayoutBlock() && child->isBox()) | 1307 if (fullRemoveInsert && isLayoutBlock() && child->isBox()) |
1271 toLayoutBox(child)->removeFromPercentHeightContainer(); | 1308 toLayoutBox(child)->removeFromPercentHeightContainer(); |
1272 | 1309 |
1273 if (fullRemoveInsert && (toBoxModelObject->isLayoutBlock() || | 1310 if (fullRemoveInsert && (toBoxModelObject->isLayoutBlock() || |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1306 // Save our next sibling as moveChildTo will clear it. | 1343 // Save our next sibling as moveChildTo will clear it. |
1307 LayoutObject* nextSibling = child->nextSibling(); | 1344 LayoutObject* nextSibling = child->nextSibling(); |
1308 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); | 1345 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); |
1309 child = nextSibling; | 1346 child = nextSibling; |
1310 } | 1347 } |
1311 } | 1348 } |
1312 | 1349 |
1313 bool LayoutBoxModelObject::backgroundStolenForBeingBody( | 1350 bool LayoutBoxModelObject::backgroundStolenForBeingBody( |
1314 const ComputedStyle* rootElementStyle) const { | 1351 const ComputedStyle* rootElementStyle) const { |
1315 // http://www.w3.org/TR/css3-background/#body-background | 1352 // http://www.w3.org/TR/css3-background/#body-background |
1316 // If the root element is <html> with no background, and a <body> child elemen
t exists, | 1353 // If the root element is <html> with no background, and a <body> child |
1317 // the root element steals the first <body> child element's background. | 1354 // element exists, the root element steals the first <body> child element's |
| 1355 // background. |
1318 if (!isBody()) | 1356 if (!isBody()) |
1319 return false; | 1357 return false; |
1320 | 1358 |
1321 Element* rootElement = document().documentElement(); | 1359 Element* rootElement = document().documentElement(); |
1322 if (!isHTMLHtmlElement(rootElement)) | 1360 if (!isHTMLHtmlElement(rootElement)) |
1323 return false; | 1361 return false; |
1324 | 1362 |
1325 if (!rootElementStyle) | 1363 if (!rootElementStyle) |
1326 rootElementStyle = rootElement->ensureComputedStyle(); | 1364 rootElementStyle = rootElement->ensureComputedStyle(); |
1327 if (rootElementStyle->hasBackground()) | 1365 if (rootElementStyle->hasBackground()) |
1328 return false; | 1366 return false; |
1329 | 1367 |
1330 if (node() != document().firstBodyElement()) | 1368 if (node() != document().firstBodyElement()) |
1331 return false; | 1369 return false; |
1332 | 1370 |
1333 return true; | 1371 return true; |
1334 } | 1372 } |
1335 | 1373 |
1336 } // namespace blink | 1374 } // namespace blink |
OLD | NEW |