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

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

Issue 346603007: Remove position: sticky (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 140
141 RenderStyle* styleToUse = style(); 141 RenderStyle* styleToUse = style();
142 setHasBoxDecorations(calculateHasBoxDecorations()); 142 setHasBoxDecorations(calculateHasBoxDecorations());
143 setInline(styleToUse->isDisplayInlineType()); 143 setInline(styleToUse->isDisplayInlineType());
144 setPositionState(styleToUse->position()); 144 setPositionState(styleToUse->position());
145 setHorizontalWritingMode(styleToUse->isHorizontalWritingMode()); 145 setHorizontalWritingMode(styleToUse->isHorizontalWritingMode());
146 } 146 }
147 147
148 static LayoutSize accumulateInFlowPositionOffsets(const RenderObject* child) 148 static LayoutSize accumulateInFlowPositionOffsets(const RenderObject* child)
149 { 149 {
150 if (!child->isAnonymousBlock() || !child->isInFlowPositioned()) 150 if (!child->isAnonymousBlock() || !child->isRelPositioned())
151 return LayoutSize(); 151 return LayoutSize();
152 LayoutSize offset; 152 LayoutSize offset;
153 RenderObject* p = toRenderBlock(child)->inlineElementContinuation(); 153 RenderObject* p = toRenderBlock(child)->inlineElementContinuation();
154 while (p && p->isRenderInline()) { 154 while (p && p->isRenderInline()) {
155 if (p->isInFlowPositioned()) { 155 if (p->isRelPositioned()) {
156 RenderInline* renderInline = toRenderInline(p); 156 RenderInline* renderInline = toRenderInline(p);
157 offset += renderInline->offsetForInFlowPosition(); 157 offset += renderInline->offsetForInFlowPosition();
158 } 158 }
159 p = p->parent(); 159 p = p->parent();
160 } 160 }
161 return offset; 161 return offset;
162 } 162 }
163 163
164 bool RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() const 164 bool RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() const
165 { 165 {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 Element* element = offsetParent(); 253 Element* element = offsetParent();
254 if (!element) 254 if (!element)
255 return referencePoint; 255 return referencePoint;
256 256
257 if (const RenderBoxModelObject* offsetParent = element->renderBoxModelObject ()) { 257 if (const RenderBoxModelObject* offsetParent = element->renderBoxModelObject ()) {
258 if (offsetParent->isBox() && !offsetParent->isBody()) 258 if (offsetParent->isBox() && !offsetParent->isBody())
259 referencePoint.move(-toRenderBox(offsetParent)->borderLeft(), -toRen derBox(offsetParent)->borderTop()); 259 referencePoint.move(-toRenderBox(offsetParent)->borderLeft(), -toRen derBox(offsetParent)->borderTop());
260 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { 260 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) {
261 if (isRelPositioned()) 261 if (isRelPositioned())
262 referencePoint.move(relativePositionOffset()); 262 referencePoint.move(relativePositionOffset());
263 else if (isStickyPositioned())
264 referencePoint.move(stickyPositionOffset());
265 263
266 RenderObject* current; 264 RenderObject* current;
267 for (current = parent(); current != offsetParent && current->parent( ); current = current->parent()) { 265 for (current = parent(); current != offsetParent && current->parent( ); current = current->parent()) {
268 // FIXME: What are we supposed to do inside SVG content? 266 // FIXME: What are we supposed to do inside SVG content?
269 if (!isOutOfFlowPositioned()) { 267 if (!isOutOfFlowPositioned()) {
270 if (current->isBox() && !current->isTableRow()) 268 if (current->isBox() && !current->isTableRow())
271 referencePoint.moveBy(toRenderBox(current)->topLeftLocat ion()); 269 referencePoint.moveBy(toRenderBox(current)->topLeftLocat ion());
272 referencePoint.move(current->parent()->columnOffset(referenc ePoint)); 270 referencePoint.move(current->parent()->columnOffset(referenc ePoint));
273 } 271 }
274 } 272 }
275 273
276 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent ->isPositioned()) 274 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent ->isPositioned())
277 referencePoint.moveBy(toRenderBox(offsetParent)->topLeftLocation ()); 275 referencePoint.moveBy(toRenderBox(offsetParent)->topLeftLocation ());
278 } 276 }
279 } 277 }
280 278
281 return referencePoint; 279 return referencePoint;
282 } 280 }
283 281
284 void RenderBoxModelObject::computeStickyPositionConstraints(StickyPositionViewpo rtConstraints& constraints, const FloatRect& constrainingRect) const
285 {
286 RenderBlock* containingBlock = this->containingBlock();
287
288 LayoutRect containerContentRect = containingBlock->contentBoxRect();
289 LayoutUnit maxWidth = containingBlock->availableLogicalWidth();
290
291 // Sticky positioned element ignore any override logical width on the contai ning block (as they don't call
292 // containingBlockLogicalWidthForContent). It's unclear whether this is tota lly fine.
293 LayoutBoxExtent minMargin(minimumValueForLength(style()->marginTop(), maxWid th),
294 minimumValueForLength(style()->marginRight(), maxWidth),
295 minimumValueForLength(style()->marginBottom(), maxWidth),
296 minimumValueForLength(style()->marginLeft(), maxWidth));
297
298 // Compute the container-relative area within which the sticky element is al lowed to move.
299 containerContentRect.contract(minMargin);
300 // Map to the view to avoid including page scale factor.
301 constraints.setAbsoluteContainingBlockRect(containingBlock->localToContainer Quad(FloatRect(containerContentRect), view()).boundingBox());
302
303 LayoutRect stickyBoxRect = frameRectForStickyPositioning();
304 LayoutRect flippedStickyBoxRect = stickyBoxRect;
305 containingBlock->flipForWritingMode(flippedStickyBoxRect);
306 LayoutPoint stickyLocation = flippedStickyBoxRect.location();
307
308 // FIXME: sucks to call localToAbsolute again, but we can't just offset from the previously computed rect if there are transforms.
309 // Map to the view to avoid including page scale factor.
310 FloatRect absContainerFrame = containingBlock->localToContainerQuad(FloatRec t(FloatPoint(), containingBlock->size()), view()).boundingBox();
311
312 if (containingBlock->hasOverflowClip()) {
313 IntSize scrollOffset = containingBlock->layer()->scrollableArea()->adjus tedScrollOffset();
314 stickyLocation -= scrollOffset;
315 }
316
317 // We can't call localToAbsolute on |this| because that will recur. FIXME: F or now, assume that |this| is not transformed.
318 FloatRect absoluteStickyBoxRect(absContainerFrame.location() + stickyLocatio n, flippedStickyBoxRect.size());
319 constraints.setAbsoluteStickyBoxRect(absoluteStickyBoxRect);
320
321 float horizontalOffsets = constraints.rightOffset() + constraints.leftOffset ();
322 bool skipRight = false;
323 bool skipLeft = false;
324 if (!style()->left().isAuto() && !style()->right().isAuto()) {
325 if (horizontalOffsets > containerContentRect.width().toFloat()
326 || horizontalOffsets + containerContentRect.width().toFloat() > cons trainingRect.width()) {
327 skipRight = style()->isLeftToRightDirection();
328 skipLeft = !skipRight;
329 }
330 }
331
332 if (!style()->left().isAuto() && !skipLeft) {
333 constraints.setLeftOffset(floatValueForLength(style()->left(), constrain ingRect.width()));
334 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
335 }
336
337 if (!style()->right().isAuto() && !skipRight) {
338 constraints.setRightOffset(floatValueForLength(style()->right(), constra iningRect.width()));
339 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight);
340 }
341
342 bool skipBottom = false;
343 // FIXME(ostap): Exclude top or bottom edge offset depending on the writing mode when related
344 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style /2014May/0286.html
345 float verticalOffsets = constraints.topOffset() + constraints.bottomOffset() ;
346 if (!style()->top().isAuto() && !style()->bottom().isAuto()) {
347 if (verticalOffsets > containerContentRect.height().toFloat()
348 || verticalOffsets + containerContentRect.height().toFloat() > const rainingRect.height()) {
349 skipBottom = true;
350 }
351 }
352
353 if (!style()->top().isAuto()) {
354 constraints.setTopOffset(floatValueForLength(style()->top(), constrainin gRect.height()));
355 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
356 }
357
358 if (!style()->bottom().isAuto() && !skipBottom) {
359 constraints.setBottomOffset(floatValueForLength(style()->bottom(), const rainingRect.height()));
360 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom);
361 }
362 }
363
364 LayoutSize RenderBoxModelObject::stickyPositionOffset() const
365 {
366 FloatRect constrainingRect;
367
368 ASSERT(hasLayer());
369 RenderLayer* enclosingClippingLayer = layer()->enclosingOverflowClipLayer(Ex cludeSelf);
370 if (enclosingClippingLayer) {
371 RenderBox* enclosingClippingBox = toRenderBox(enclosingClippingLayer->re nderer());
372 LayoutRect clipRect = enclosingClippingBox->overflowClipRect(LayoutPoint ());
373 clipRect.move(enclosingClippingBox->paddingLeft(), enclosingClippingBox- >paddingTop());
374 clipRect.contract(LayoutSize(enclosingClippingBox->paddingLeft() + enclo singClippingBox->paddingRight(),
375 enclosingClippingBox->paddingTop() + enclosingClippingBox->paddingBo ttom()));
376 constrainingRect = enclosingClippingBox->localToContainerQuad(FloatRect( clipRect), view()).boundingBox();
377 } else {
378 LayoutRect viewportRect = view()->frameView()->viewportConstrainedVisibl eContentRect();
379 constrainingRect = viewportRect;
380 }
381
382 StickyPositionViewportConstraints constraints;
383 computeStickyPositionConstraints(constraints, constrainingRect);
384
385 // The sticky offset is physical, so we can just return the delta computed i n absolute coords (though it may be wrong with transforms).
386 return LayoutSize(constraints.computeStickyOffset(constrainingRect));
387 }
388
389 LayoutSize RenderBoxModelObject::offsetForInFlowPosition() const 282 LayoutSize RenderBoxModelObject::offsetForInFlowPosition() const
390 { 283 {
391 if (isRelPositioned()) 284 return isRelPositioned() ? relativePositionOffset() : LayoutSize();
392 return relativePositionOffset();
393
394 if (isStickyPositioned())
395 return stickyPositionOffset();
396
397 return LayoutSize();
398 } 285 }
399 286
400 LayoutUnit RenderBoxModelObject::offsetLeft() const 287 LayoutUnit RenderBoxModelObject::offsetLeft() const
401 { 288 {
402 // Note that RenderInline and RenderBox override this to pass a different 289 // Note that RenderInline and RenderBox override this to pass a different
403 // startPoint to adjustedPositionRelativeToOffsetParent. 290 // startPoint to adjustedPositionRelativeToOffsetParent.
404 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); 291 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x();
405 } 292 }
406 293
407 LayoutUnit RenderBoxModelObject::offsetTop() const 294 LayoutUnit RenderBoxModelObject::offsetTop() const
(...skipping 2433 matching lines...) Expand 10 before | Expand all | Expand 10 after
2841 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); 2728 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent());
2842 for (RenderObject* child = startChild; child && child != endChild; ) { 2729 for (RenderObject* child = startChild; child && child != endChild; ) {
2843 // Save our next sibling as moveChildTo will clear it. 2730 // Save our next sibling as moveChildTo will clear it.
2844 RenderObject* nextSibling = child->nextSibling(); 2731 RenderObject* nextSibling = child->nextSibling();
2845 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); 2732 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert);
2846 child = nextSibling; 2733 child = nextSibling;
2847 } 2734 }
2848 } 2735 }
2849 2736
2850 } // namespace WebCore 2737 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderBoxModelObject.h ('k') | Source/core/rendering/RenderFlowThread.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698