| Index: Source/core/css/CSSComputedStyleDeclaration.cpp
|
| diff --git a/Source/core/css/CSSComputedStyleDeclaration.cpp b/Source/core/css/CSSComputedStyleDeclaration.cpp
|
| index 4d09b550a6c6ebe5dc4fdd96a96c4d0531c439b0..766a2de1c47dd7d159f825ff0e7cabd9b7ffa12d 100644
|
| --- a/Source/core/css/CSSComputedStyleDeclaration.cpp
|
| +++ b/Source/core/css/CSSComputedStyleDeclaration.cpp
|
| @@ -623,46 +623,107 @@ static PassRefPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propert
|
| }
|
| positionList->append(zoomAdjustedPixelValueForLength(layer->yPosition(), style));
|
| return positionList.release();
|
| +
|
| }
|
|
|
| -static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, CSSPropertyID propertyID, const RenderObject* renderer, RenderView* renderView)
|
| +static Length getOffsetComputedStyle(RenderStyle* style, CSSPropertyID propertyID)
|
| {
|
| - if (!style)
|
| - return 0;
|
| + // 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();
|
| + }
|
|
|
| - Length l;
|
| + 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 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;
|
| + 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();
|
| }
|
|
|
| - 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);
|
| + 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 zoomAdjustedPixelValueForLength(l, style);
|
| + return 0;
|
| +}
|
| +
|
| +static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, CSSPropertyID propertyID, RenderObject* renderer, RenderView* renderView)
|
| +{
|
| + if (!style)
|
| + return 0;
|
| +
|
| + // If the element is not displayed; return the "computed value".
|
| + if (!renderView || !renderer || !renderer->isBox()) {
|
| + return zoomAdjustedPixelValueForLength(getOffsetComputedStyle(style, propertyID), style);
|
| +
|
| + // 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);
|
| + }
|
| }
|
|
|
| PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const
|
| @@ -1508,6 +1569,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();
|
|
|