| 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 FloatSize scrollOffset( | 811 FloatSize scrollOffset( |
| 788 scrollAncestor | 812 scrollAncestor |
| 789 ? toFloatSize( | 813 ? toFloatSize( |
| 790 scrollAncestor->getScrollableArea()->adjustedScrollOffset()) | 814 scrollAncestor->getScrollableArea()->adjustedScrollOffset()) |
| 791 : FloatSize()); | 815 : FloatSize()); |
| 792 scrollContainerRelativePaddingBoxRect.move(scrollOffset); | 816 scrollContainerRelativePaddingBoxRect.move(scrollOffset); |
| 793 } | 817 } |
| 794 | 818 |
| 795 LayoutRect scrollContainerRelativeContainingBlockRect( | 819 LayoutRect scrollContainerRelativeContainingBlockRect( |
| 796 scrollContainerRelativePaddingBoxRect); | 820 scrollContainerRelativePaddingBoxRect); |
| 797 // This is removing the padding of the containing block's overflow rect to get
the flow | 821 // This is removing the padding of the containing block's overflow rect to get |
| 798 // box rectangle and removing the margin of the sticky element to ensure that
space between | 822 // the flow box rectangle and removing the margin of the sticky element to |
| 799 // the sticky element and its containing flow box. It is an open issue whether
the margin | 823 // ensure that space between the sticky element and its containing flow box. |
| 800 // should collapse (See https://www.w3.org/TR/css-position-3/#sticky-pos). | 824 // It is an open issue whether the margin should collapse. |
| 825 // See https://www.w3.org/TR/css-position-3/#sticky-pos |
| 801 scrollContainerRelativeContainingBlockRect.contractEdges( | 826 scrollContainerRelativeContainingBlockRect.contractEdges( |
| 802 minimumValueForLength(containingBlock->style()->paddingTop(), | 827 minimumValueForLength(containingBlock->style()->paddingTop(), |
| 803 maxContainerWidth) + | 828 maxContainerWidth) + |
| 804 minimumValueForLength(style()->marginTop(), maxWidth), | 829 minimumValueForLength(style()->marginTop(), maxWidth), |
| 805 minimumValueForLength(containingBlock->style()->paddingRight(), | 830 minimumValueForLength(containingBlock->style()->paddingRight(), |
| 806 maxContainerWidth) + | 831 maxContainerWidth) + |
| 807 minimumValueForLength(style()->marginRight(), maxWidth), | 832 minimumValueForLength(style()->marginRight(), maxWidth), |
| 808 minimumValueForLength(containingBlock->style()->paddingBottom(), | 833 minimumValueForLength(containingBlock->style()->paddingBottom(), |
| 809 maxContainerWidth) + | 834 maxContainerWidth) + |
| 810 minimumValueForLength(style()->marginBottom(), maxWidth), | 835 minimumValueForLength(style()->marginBottom(), maxWidth), |
| 811 minimumValueForLength(containingBlock->style()->paddingLeft(), | 836 minimumValueForLength(containingBlock->style()->paddingLeft(), |
| 812 maxContainerWidth) + | 837 maxContainerWidth) + |
| 813 minimumValueForLength(style()->marginLeft(), maxWidth)); | 838 minimumValueForLength(style()->marginLeft(), maxWidth)); |
| 814 | 839 |
| 815 constraints.setScrollContainerRelativeContainingBlockRect( | 840 constraints.setScrollContainerRelativeContainingBlockRect( |
| 816 FloatRect(scrollContainerRelativeContainingBlockRect)); | 841 FloatRect(scrollContainerRelativeContainingBlockRect)); |
| 817 | 842 |
| 818 FloatRect stickyBoxRect = | 843 FloatRect stickyBoxRect = |
| 819 isLayoutInline() ? FloatRect(toLayoutInline(this)->linesBoundingBox()) | 844 isLayoutInline() ? FloatRect(toLayoutInline(this)->linesBoundingBox()) |
| 820 : FloatRect(toLayoutBox(this)->frameRect()); | 845 : FloatRect(toLayoutBox(this)->frameRect()); |
| 821 FloatRect flippedStickyBoxRect = stickyBoxRect; | 846 FloatRect flippedStickyBoxRect = stickyBoxRect; |
| 822 containingBlock->flipForWritingMode(flippedStickyBoxRect); | 847 containingBlock->flipForWritingMode(flippedStickyBoxRect); |
| 823 FloatPoint stickyLocation = | 848 FloatPoint stickyLocation = |
| 824 flippedStickyBoxRect.location() + skippedContainersOffset; | 849 flippedStickyBoxRect.location() + skippedContainersOffset; |
| 825 | 850 |
| 826 // The scrollContainerRelativePaddingBoxRect's position is the padding box so
we need to remove the border when finding | 851 // The scrollContainerRelativePaddingBoxRect's position is the padding box so |
| 827 // the position of the sticky box within the scroll ancestor if the container
is not our scroll ancestor. | 852 // we need to remove the border when finding the position of the sticky box |
| 853 // within the scroll ancestor if the container is not our scroll ancestor. |
| 828 if (containingBlock != scrollAncestor) { | 854 if (containingBlock != scrollAncestor) { |
| 829 FloatSize containerBorderOffset(containingBlock->borderLeft(), | 855 FloatSize containerBorderOffset(containingBlock->borderLeft(), |
| 830 containingBlock->borderTop()); | 856 containingBlock->borderTop()); |
| 831 stickyLocation -= containerBorderOffset; | 857 stickyLocation -= containerBorderOffset; |
| 832 } | 858 } |
| 833 constraints.setScrollContainerRelativeStickyBoxRect( | 859 constraints.setScrollContainerRelativeStickyBoxRect( |
| 834 FloatRect(scrollContainerRelativePaddingBoxRect.location() + | 860 FloatRect(scrollContainerRelativePaddingBoxRect.location() + |
| 835 toFloatSize(stickyLocation), | 861 toFloatSize(stickyLocation), |
| 836 flippedStickyBoxRect.size())); | 862 flippedStickyBoxRect.size())); |
| 837 | 863 |
| 838 // 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. | 864 // We skip the right or top sticky offset if there is not enough space to |
| 865 // honor both the left/right or top/bottom offsets. |
| 839 LayoutUnit horizontalOffsets = | 866 LayoutUnit horizontalOffsets = |
| 840 minimumValueForLength(style()->right(), | 867 minimumValueForLength(style()->right(), |
| 841 LayoutUnit(constrainingSize.width())) + | 868 LayoutUnit(constrainingSize.width())) + |
| 842 minimumValueForLength(style()->left(), | 869 minimumValueForLength(style()->left(), |
| 843 LayoutUnit(constrainingSize.width())); | 870 LayoutUnit(constrainingSize.width())); |
| 844 bool skipRight = false; | 871 bool skipRight = false; |
| 845 bool skipLeft = false; | 872 bool skipLeft = false; |
| 846 if (!style()->left().isAuto() && !style()->right().isAuto()) { | 873 if (!style()->left().isAuto() && !style()->right().isAuto()) { |
| 847 if (horizontalOffsets > | 874 if (horizontalOffsets > |
| 848 scrollContainerRelativeContainingBlockRect.width() || | 875 scrollContainerRelativeContainingBlockRect.width() || |
| (...skipping 12 matching lines...) Expand all Loading... |
| 861 } | 888 } |
| 862 | 889 |
| 863 if (!style()->right().isAuto() && !skipRight) { | 890 if (!style()->right().isAuto() && !skipRight) { |
| 864 constraints.setRightOffset(minimumValueForLength( | 891 constraints.setRightOffset(minimumValueForLength( |
| 865 style()->right(), LayoutUnit(constrainingSize.width()))); | 892 style()->right(), LayoutUnit(constrainingSize.width()))); |
| 866 constraints.addAnchorEdge( | 893 constraints.addAnchorEdge( |
| 867 StickyPositionScrollingConstraints::AnchorEdgeRight); | 894 StickyPositionScrollingConstraints::AnchorEdgeRight); |
| 868 } | 895 } |
| 869 | 896 |
| 870 bool skipBottom = false; | 897 bool skipBottom = false; |
| 871 // TODO(flackr): Exclude top or bottom edge offset depending on the writing mo
de when related | 898 // TODO(flackr): Exclude top or bottom edge offset depending on the writing |
| 872 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style/2
014May/0286.html | 899 // mode when related sections are fixed in spec. |
| 900 // See http://lists.w3.org/Archives/Public/www-style/2014May/0286.html |
| 873 LayoutUnit verticalOffsets = | 901 LayoutUnit verticalOffsets = |
| 874 minimumValueForLength(style()->top(), | 902 minimumValueForLength(style()->top(), |
| 875 LayoutUnit(constrainingSize.height())) + | 903 LayoutUnit(constrainingSize.height())) + |
| 876 minimumValueForLength(style()->bottom(), | 904 minimumValueForLength(style()->bottom(), |
| 877 LayoutUnit(constrainingSize.height())); | 905 LayoutUnit(constrainingSize.height())); |
| 878 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { | 906 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { |
| 879 if (verticalOffsets > scrollContainerRelativeContainingBlockRect.height() || | 907 if (verticalOffsets > scrollContainerRelativeContainingBlockRect.height() || |
| 880 verticalOffsets + scrollContainerRelativeContainingBlockRect.height() > | 908 verticalOffsets + scrollContainerRelativeContainingBlockRect.height() > |
| 881 constrainingSize.height()) { | 909 constrainingSize.height()) { |
| 882 skipBottom = true; | 910 skipBottom = true; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 constrainingRect.contract( | 942 constrainingRect.contract( |
| 915 FloatSize(enclosingClippingBox->paddingLeft() + | 943 FloatSize(enclosingClippingBox->paddingLeft() + |
| 916 enclosingClippingBox->paddingRight(), | 944 enclosingClippingBox->paddingRight(), |
| 917 enclosingClippingBox->paddingTop() + | 945 enclosingClippingBox->paddingTop() + |
| 918 enclosingClippingBox->paddingBottom())); | 946 enclosingClippingBox->paddingBottom())); |
| 919 return constrainingRect; | 947 return constrainingRect; |
| 920 } | 948 } |
| 921 | 949 |
| 922 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const { | 950 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const { |
| 923 const PaintLayer* ancestorOverflowLayer = layer()->ancestorOverflowLayer(); | 951 const PaintLayer* ancestorOverflowLayer = layer()->ancestorOverflowLayer(); |
| 924 // TODO: Force compositing input update if we ask for offset before compositin
g inputs have been computed? | 952 // TODO: Force compositing input update if we ask for offset before |
| 953 // compositing inputs have been computed? |
| 925 if (!ancestorOverflowLayer) | 954 if (!ancestorOverflowLayer) |
| 926 return LayoutSize(); | 955 return LayoutSize(); |
| 927 FloatRect constrainingRect = computeStickyConstrainingRect(); | 956 FloatRect constrainingRect = computeStickyConstrainingRect(); |
| 928 PaintLayerScrollableArea* scrollableArea = | 957 PaintLayerScrollableArea* scrollableArea = |
| 929 ancestorOverflowLayer->getScrollableArea(); | 958 ancestorOverflowLayer->getScrollableArea(); |
| 930 | 959 |
| 931 // The sticky offset is physical, so we can just return the delta computed in
absolute coords (though it may be wrong with transforms). | 960 // The sticky offset is physical, so we can just return the delta computed in |
| 932 // TODO: Force compositing input update if we ask for offset with stale compos
iting inputs. | 961 // absolute coords (though it may be wrong with transforms). |
| 962 // TODO: Force compositing input update if we ask for offset with stale |
| 963 // compositing inputs. |
| 933 if (!scrollableArea->stickyConstraintsMap().contains(layer())) | 964 if (!scrollableArea->stickyConstraintsMap().contains(layer())) |
| 934 return LayoutSize(); | 965 return LayoutSize(); |
| 935 return LayoutSize( | 966 return LayoutSize( |
| 936 scrollableArea->stickyConstraintsMap().get(layer()).computeStickyOffset( | 967 scrollableArea->stickyConstraintsMap().get(layer()).computeStickyOffset( |
| 937 constrainingRect)); | 968 constrainingRect)); |
| 938 } | 969 } |
| 939 | 970 |
| 940 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( | 971 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( |
| 941 const LayoutPoint& startPoint, | 972 const LayoutPoint& startPoint, |
| 942 const Element* element) const { | 973 const Element* element) const { |
| 943 // If the element is the HTML body element or doesn't have a parent | 974 // If the element is the HTML body element or doesn't have a parent |
| 944 // return 0 and stop this algorithm. | 975 // return 0 and stop this algorithm. |
| 945 if (isBody() || !parent()) | 976 if (isBody() || !parent()) |
| 946 return LayoutPoint(); | 977 return LayoutPoint(); |
| 947 | 978 |
| 948 LayoutPoint referencePoint = startPoint; | 979 LayoutPoint referencePoint = startPoint; |
| 949 | 980 |
| 950 // If the base element is null, return the distance between the canvas origin
and | 981 // If the base element is null, return the distance between the canvas origin |
| 951 // the left border edge of the element and stop this algorithm. | 982 // and the left border edge of the element and stop this algorithm. |
| 952 if (!element) | 983 if (!element) |
| 953 return referencePoint; | 984 return referencePoint; |
| 954 | 985 |
| 955 if (const LayoutBoxModelObject* offsetParent = | 986 if (const LayoutBoxModelObject* offsetParent = |
| 956 element->layoutBoxModelObject()) { | 987 element->layoutBoxModelObject()) { |
| 957 if (!isOutOfFlowPositioned()) { | 988 if (!isOutOfFlowPositioned()) { |
| 958 if (isInFlowPositioned()) | 989 if (isInFlowPositioned()) |
| 959 referencePoint.move(offsetForInFlowPosition()); | 990 referencePoint.move(offsetForInFlowPosition()); |
| 960 | 991 |
| 961 // Note that we may fail to find |offsetParent| while walking the containe
r chain, if | 992 // Note that we may fail to find |offsetParent| while walking the |
| 962 // |offsetParent| is an inline split into continuations. | 993 // container chain, if |offsetParent| is an inline split into |
| 963 // <body style="display:inline;" id="offsetParent"><div></div><span id="th
is"> | 994 // continuations: <body style="display:inline;" id="offsetParent"><div> |
| 995 // </div><span id="this"> |
| 964 // This is why we have to do a nullptr check here. | 996 // This is why we have to do a nullptr check here. |
| 965 // offset(Left|Top) is generally broken when offsetParent is inline. | 997 // offset(Left|Top) is generally broken when offsetParent is inline. |
| 966 for (const LayoutObject* current = container(); | 998 for (const LayoutObject* current = container(); |
| 967 current && current != offsetParent; current = current->container()) { | 999 current && current != offsetParent; current = current->container()) { |
| 968 // FIXME: What are we supposed to do inside SVG content? | 1000 // FIXME: What are we supposed to do inside SVG content? |
| 969 referencePoint.move(current->columnOffset(referencePoint)); | 1001 referencePoint.move(current->columnOffset(referencePoint)); |
| 970 if (current->isBox() && !current->isTableRow()) | 1002 if (current->isBox() && !current->isTableRow()) |
| 971 referencePoint.moveBy(toLayoutBox(current)->topLeftLocation()); | 1003 referencePoint.moveBy(toLayoutBox(current)->topLeftLocation()); |
| 972 } | 1004 } |
| 973 | 1005 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1199 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped); | 1231 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped); |
| 1200 if (!container) | 1232 if (!container) |
| 1201 return nullptr; | 1233 return nullptr; |
| 1202 | 1234 |
| 1203 bool isInline = isLayoutInline(); | 1235 bool isInline = isLayoutInline(); |
| 1204 bool isFixedPos = !isInline && style()->position() == FixedPosition; | 1236 bool isFixedPos = !isInline && style()->position() == FixedPosition; |
| 1205 bool containsFixedPosition = canContainFixedPositionObjects(); | 1237 bool containsFixedPosition = canContainFixedPositionObjects(); |
| 1206 | 1238 |
| 1207 LayoutSize adjustmentForSkippedAncestor; | 1239 LayoutSize adjustmentForSkippedAncestor; |
| 1208 if (ancestorSkipped) { | 1240 if (ancestorSkipped) { |
| 1209 // There can't be a transform between paintInvalidationContainer and ancesto
rToStopAt, because transforms create containers, so it should be safe | 1241 // There can't be a transform between paintInvalidationContainer and |
| 1210 // to just subtract the delta between the ancestor and ancestorToStopAt. | 1242 // ancestorToStopAt, because transforms create containers, so it should be |
| 1243 // safe to just subtract the delta between the ancestor and |
| 1244 // ancestorToStopAt. |
| 1211 adjustmentForSkippedAncestor = | 1245 adjustmentForSkippedAncestor = |
| 1212 -ancestorToStopAt->offsetFromAncestorContainer(container); | 1246 -ancestorToStopAt->offsetFromAncestorContainer(container); |
| 1213 } | 1247 } |
| 1214 | 1248 |
| 1215 LayoutSize containerOffset = offsetFromContainer(container); | 1249 LayoutSize containerOffset = offsetFromContainer(container); |
| 1216 bool offsetDependsOnPoint; | 1250 bool offsetDependsOnPoint; |
| 1217 if (isLayoutFlowThread()) { | 1251 if (isLayoutFlowThread()) { |
| 1218 containerOffset += columnOffset(LayoutPoint()); | 1252 containerOffset += columnOffset(LayoutPoint()); |
| 1219 offsetDependsOnPoint = true; | 1253 offsetDependsOnPoint = true; |
| 1220 } else { | 1254 } else { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1243 geometryMap.push(this, containerOffset, flags, LayoutSize()); | 1277 geometryMap.push(this, containerOffset, flags, LayoutSize()); |
| 1244 } | 1278 } |
| 1245 | 1279 |
| 1246 return ancestorSkipped ? ancestorToStopAt : container; | 1280 return ancestorSkipped ? ancestorToStopAt : container; |
| 1247 } | 1281 } |
| 1248 | 1282 |
| 1249 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, | 1283 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, |
| 1250 LayoutObject* child, | 1284 LayoutObject* child, |
| 1251 LayoutObject* beforeChild, | 1285 LayoutObject* beforeChild, |
| 1252 bool fullRemoveInsert) { | 1286 bool fullRemoveInsert) { |
| 1253 // We assume that callers have cleared their positioned objects list for child
moves (!fullRemoveInsert) so the | 1287 // We assume that callers have cleared their positioned objects list for child |
| 1254 // positioned layoutObject maps don't become stale. It would be too slow to do
the map lookup on each call. | 1288 // moves (!fullRemoveInsert) so the positioned layoutObject maps don't become |
| 1289 // stale. It would be too slow to do the map lookup on each call. |
| 1255 ASSERT(!fullRemoveInsert || !isLayoutBlock() || | 1290 ASSERT(!fullRemoveInsert || !isLayoutBlock() || |
| 1256 !toLayoutBlock(this)->hasPositionedObjects()); | 1291 !toLayoutBlock(this)->hasPositionedObjects()); |
| 1257 | 1292 |
| 1258 ASSERT(this == child->parent()); | 1293 ASSERT(this == child->parent()); |
| 1259 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); | 1294 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); |
| 1260 | 1295 |
| 1261 // If a child is moving from a block-flow to an inline-flow parent then any fl
oats currently intruding into | 1296 // If a child is moving from a block-flow to an inline-flow parent then any |
| 1262 // the child can no longer do so. This can happen if a block becomes floating
or out-of-flow and is moved | 1297 // floats currently intruding into the child can no longer do so. This can |
| 1263 // to an anonymous block. Remove all floats from their float-lists immediately
as markAllDescendantsWithFloatsForLayout | 1298 // happen if a block becomes floating or out-of-flow and is moved to an |
| 1264 // won't attempt to remove floats from parents that have inline-flow if we try
later. | 1299 // anonymous block. Remove all floats from their float-lists immediately as |
| 1300 // markAllDescendantsWithFloatsForLayout won't attempt to remove floats from |
| 1301 // parents that have inline-flow if we try later. |
| 1265 if (child->isLayoutBlockFlow() && toBoxModelObject->childrenInline() && | 1302 if (child->isLayoutBlockFlow() && toBoxModelObject->childrenInline() && |
| 1266 !childrenInline()) { | 1303 !childrenInline()) { |
| 1267 toLayoutBlockFlow(child)->removeFloatingObjectsFromDescendants(); | 1304 toLayoutBlockFlow(child)->removeFloatingObjectsFromDescendants(); |
| 1268 ASSERT(!toLayoutBlockFlow(child)->containsFloats()); | 1305 ASSERT(!toLayoutBlockFlow(child)->containsFloats()); |
| 1269 } | 1306 } |
| 1270 | 1307 |
| 1271 if (fullRemoveInsert && isLayoutBlock() && child->isBox()) | 1308 if (fullRemoveInsert && isLayoutBlock() && child->isBox()) |
| 1272 toLayoutBox(child)->removeFromPercentHeightContainer(); | 1309 toLayoutBox(child)->removeFromPercentHeightContainer(); |
| 1273 | 1310 |
| 1274 if (fullRemoveInsert && (toBoxModelObject->isLayoutBlock() || | 1311 if (fullRemoveInsert && (toBoxModelObject->isLayoutBlock() || |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1307 // Save our next sibling as moveChildTo will clear it. | 1344 // Save our next sibling as moveChildTo will clear it. |
| 1308 LayoutObject* nextSibling = child->nextSibling(); | 1345 LayoutObject* nextSibling = child->nextSibling(); |
| 1309 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); | 1346 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); |
| 1310 child = nextSibling; | 1347 child = nextSibling; |
| 1311 } | 1348 } |
| 1312 } | 1349 } |
| 1313 | 1350 |
| 1314 bool LayoutBoxModelObject::backgroundStolenForBeingBody( | 1351 bool LayoutBoxModelObject::backgroundStolenForBeingBody( |
| 1315 const ComputedStyle* rootElementStyle) const { | 1352 const ComputedStyle* rootElementStyle) const { |
| 1316 // http://www.w3.org/TR/css3-background/#body-background | 1353 // http://www.w3.org/TR/css3-background/#body-background |
| 1317 // If the root element is <html> with no background, and a <body> child elemen
t exists, | 1354 // If the root element is <html> with no background, and a <body> child |
| 1318 // the root element steals the first <body> child element's background. | 1355 // element exists, the root element steals the first <body> child element's |
| 1356 // background. |
| 1319 if (!isBody()) | 1357 if (!isBody()) |
| 1320 return false; | 1358 return false; |
| 1321 | 1359 |
| 1322 Element* rootElement = document().documentElement(); | 1360 Element* rootElement = document().documentElement(); |
| 1323 if (!isHTMLHtmlElement(rootElement)) | 1361 if (!isHTMLHtmlElement(rootElement)) |
| 1324 return false; | 1362 return false; |
| 1325 | 1363 |
| 1326 if (!rootElementStyle) | 1364 if (!rootElementStyle) |
| 1327 rootElementStyle = rootElement->ensureComputedStyle(); | 1365 rootElementStyle = rootElement->ensureComputedStyle(); |
| 1328 if (rootElementStyle->hasBackground()) | 1366 if (rootElementStyle->hasBackground()) |
| 1329 return false; | 1367 return false; |
| 1330 | 1368 |
| 1331 if (node() != document().firstBodyElement()) | 1369 if (node() != document().firstBodyElement()) |
| 1332 return false; | 1370 return false; |
| 1333 | 1371 |
| 1334 return true; | 1372 return true; |
| 1335 } | 1373 } |
| 1336 | 1374 |
| 1337 } // namespace blink | 1375 } // namespace blink |
| OLD | NEW |