Chromium Code Reviews| Index: Source/WebCore/css/CSSComputedStyleDeclaration.cpp |
| diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp |
| index 5a4be66d108de6ab0db6e6fccbd9c175321b3fa2..6983292ebfffb195ad5ad7532537296d667ad676 100644 |
| --- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp |
| +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp |
| @@ -632,6 +632,81 @@ static PassRefPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propert |
| } |
| positionList->append(zoomAdjustedPixelValueForLength(layer->yPosition(), style)); |
| return positionList.release(); |
| + |
| +} |
| + |
| +static Length getOffsetComputedStyle(RenderStyle* style, CSSPropertyID propertyID) { |
|
eseidel
2013/04/12 07:33:50
Blink style moves { to the next line.
mithro-old
2013/04/26 05:30:38
Done.
|
| + // If specified as a length, the corresponding absolute length; if specified as |
| + // a percentage, the specified value; otherwise, 'auto'. Hence, we can just |
| + // return the value in the style. |
| + // |
| + // See http://www.w3.org/TR/CSS21/cascade.html#computed-value |
| + switch (propertyID) { |
| + case CSSPropertyLeft: |
| + return style->left(); |
| + case CSSPropertyRight: |
| + return style->right(); |
| + case CSSPropertyTop: |
| + return style->top(); |
| + case CSSPropertyBottom: |
| + return style->bottom(); |
| + default: |
| + ASSERT_NOT_REACHED(); |
| + } |
| + |
| + return Length(0); |
| +} |
| + |
| +static LayoutUnit getOffsetUsedStyleRelative(RenderBox* box, RenderStyle* style, CSSPropertyID propertyID) { |
| + // For relatively positioned boxes, the offset is with respect to the top edges |
| + // of the box itself. This ties together top/bottom and left/right to be |
| + // opposites of each other. |
| + // |
| + // See http://www.w3.org/TR/CSS2/visuren.html#relative-positioning |
| + // |
| + // Specifically; |
| + // Since boxes are not split or stretched as a result of 'left' or |
| + // 'right', the used values are always: left = -right. |
| + // and |
| + // Since boxes are not split or stretched as a result of 'top' or |
| + // 'bottom', the used values are always: top = -bottom. |
| + switch (propertyID) { |
| + case CSSPropertyTop: |
| + return box->relativePositionOffset().height(); |
| + case CSSPropertyBottom: |
| + return -(box->relativePositionOffset().height()); |
| + case CSSPropertyLeft: |
| + return box->relativePositionOffset().width(); |
| + case CSSPropertyRight: |
| + return -(box->relativePositionOffset().width()); |
| + default: |
| + ASSERT_NOT_REACHED(); |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +static LayoutUnit getOffsetUsedStyleAbsolute(RenderBlock* container, RenderBox* box, RenderStyle* style, CSSPropertyID propertyID) { |
| + // For absoultely positioned boxes, the offset is how far an box's margin |
| + // edge is offset below the edge of the box's containing block. |
| + // See http://www.w3.org/TR/CSS2/visuren.html#position-props |
| + |
| + // Margins are included in Webkit's offsetTop/offsetLeft so we need to |
| + // remove them here. |
| + switch (propertyID) { |
| + case CSSPropertyTop: |
| + return box->offsetTop() - box->marginTop(); |
| + case CSSPropertyBottom: |
| + return container->clientHeight() - (box->offsetTop() + box->offsetHeight()) - box->marginBottom(); |
| + case CSSPropertyLeft: |
| + return box->offsetLeft() - box->marginLeft(); |
| + case CSSPropertyRight: |
| + return container->clientWidth() - (box->offsetLeft() + box->offsetWidth()) - box->marginRight(); |
| + default: |
| + ASSERT_NOT_REACHED(); |
| + } |
| + |
| + return 0; |
| } |
| static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, CSSPropertyID propertyID, const RenderObject* renderer, RenderView* renderView) |
| @@ -639,39 +714,22 @@ static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, CSSProper |
| if (!style) |
| return 0; |
| - Length l; |
| - switch (propertyID) { |
| - case CSSPropertyLeft: |
| - l = style->left(); |
| - break; |
| - case CSSPropertyRight: |
| - l = style->right(); |
| - break; |
| - case CSSPropertyTop: |
| - l = style->top(); |
| - break; |
| - case CSSPropertyBottom: |
| - l = style->bottom(); |
| - break; |
| - default: |
| - return 0; |
| - } |
| + // If the element is not displayed; return the "computed value". |
| + if (!renderView || !renderer || !renderer->isBox()) { |
| + return zoomAdjustedPixelValueForLength(getOffsetComputedStyle(style, propertyID), style); |
| - if (l.isPercent() && renderer && renderer->isBox()) { |
| - LayoutUnit containingBlockSize = (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ? |
| - toRenderBox(renderer)->containingBlockLogicalWidthForContent() : |
| - toRenderBox(renderer)->containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding); |
| - return zoomAdjustedPixelValue(valueForLength(l, containingBlockSize, 0), style); |
| - } if (l.isViewportPercentage()) |
| - return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style); |
| - if (l.isAuto()) { |
| - // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined. |
| - // In other words if left is auto and right is not auto, then left's computed value is negative right(). |
| - // So we should get the opposite length unit and see if it is auto. |
| - return cssValuePool().createValue(l); |
| + // We should return the "used value". |
| + } else { |
| + LayoutUnit length = 0; |
| + RenderBox* box = toRenderBox(renderer); |
| + RenderBlock* containingBlock = renderer->containingBlock(); |
| + if (box->isRelPositioned() || !containingBlock) { |
| + length = getOffsetUsedStyleRelative(box, style, propertyID); |
| + } else { |
| + length = getOffsetUsedStyleAbsolute(containingBlock, box, style, propertyID); |
| + } |
| + return zoomAdjustedPixelValue(length, style); |
| } |
| - |
| - return zoomAdjustedPixelValueForLength(l, style); |
| } |
| PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const |
| @@ -1515,6 +1573,13 @@ Node* CSSComputedStyleDeclaration::styledNode() const |
| return m_node.get(); |
| } |
| +// In CSS 2.1 the returned object should actually contain the "used values" |
| +// rather then the "computed values" (despite the name saying otherwise). |
| +// |
| +// See; |
| +// http://www.w3.org/TR/CSS21/cascade.html#used-value |
| +// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration |
| +// https://developer.mozilla.org/en-US/docs/DOM/window.getComputedStyle |
| PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const |
| { |
| Node* styledNode = this->styledNode(); |