Source/WebCore/ChangeLog

 12017-05-26 Simon Fraser <simon.fraser@apple.com>
 2
 3 getComputedStyle returns percentage values for left / right / top / bottom
 4 https://bugs.webkit.org/show_bug.cgi?id=29084
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Fix getComputedStyle() to return pixel values for left / right / top / bottom, per spec.
 9
 10 This is mostly a merge of https://codereview.chromium.org/13871003/.
 11
 12 Behavior now matches Chrome and Firefox.
 13
 14 Test: fast/css/getComputedStyle/getComputedStyle-offsets.html
 15
 16 * css/CSSComputedStyleDeclaration.cpp:
 17 (WebCore::getOffsetComputedLength):
 18 (WebCore::getOffsetUsedStyleRelative):
 19 (WebCore::getOffsetUsedStyleAbsolute):
 20 (WebCore::positionOffsetValue):
 21 (WebCore::positionOffsetValueIsRendererDependent):
 22 (WebCore::isNonReplacedInline):
 23 (WebCore::isLayoutDependent):
 24 (WebCore::ComputedStyleExtractor::propertyValue):
 25
1262017-05-24 Commit Queue <commit-queue@webkit.org>
227
328 Unreviewed, rolling out r217319.

Source/WebCore/css/CSSComputedStyleDeclaration.cpp

@@static Ref<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, co
708708 return list;
709709}
710710
711 static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID)
 711static Length getOffsetComputedLength(const RenderStyle& style, CSSPropertyID propertyID)
712712{
713  Length length;
 713 // If specified as a length, the corresponding absolute length; if specified as
 714 // a percentage, the specified value; otherwise, 'auto'. Hence, we can just
 715 // return the value in the style.
 716 //
 717 // See http://www.w3.org/TR/CSS21/cascade.html#computed-value
714718 switch (propertyID) {
715  case CSSPropertyLeft:
716  length = style.left();
717  break;
718  case CSSPropertyRight:
719  length = style.right();
720  break;
721  case CSSPropertyTop:
722  length = style.top();
723  break;
724  case CSSPropertyBottom:
725  length = style.bottom();
726  break;
727  default:
728  return nullptr;
 719 case CSSPropertyLeft:
 720 return style.left();
 721 case CSSPropertyRight:
 722 return style.right();
 723 case CSSPropertyTop:
 724 return style.top();
 725 case CSSPropertyBottom:
 726 return style.bottom();
 727 default:
 728 ASSERT_NOT_REACHED();
729729 }
730730
731  if (style.hasOutOfFlowPosition()) {
732  if (length.isFixed())
733  return zoomAdjustedPixelValue(length.value(), style);
 731 return { };
 732}
734733
735  return CSSValuePool::singleton().createValue(length);
 734static LayoutUnit getOffsetUsedStyleRelative(RenderBox& box, CSSPropertyID propertyID)
 735{
 736 // For relatively positioned boxes, the offset is with respect to the top edges
 737 // of the box itself. This ties together top/bottom and left/right to be
 738 // opposites of each other.
 739 //
 740 // See http://www.w3.org/TR/CSS2/visuren.html#relative-positioning
 741 //
 742 // Specifically;
 743 // Since boxes are not split or stretched as a result of 'left' or
 744 // 'right', the used values are always: left = -right.
 745 // and
 746 // Since boxes are not split or stretched as a result of 'top' or
 747 // 'bottom', the used values are always: top = -bottom.
 748 switch (propertyID) {
 749 case CSSPropertyTop:
 750 return box.relativePositionOffset().height();
 751 case CSSPropertyBottom:
 752 return -(box.relativePositionOffset().height());
 753 case CSSPropertyLeft:
 754 return box.relativePositionOffset().width();
 755 case CSSPropertyRight:
 756 return -(box.relativePositionOffset().width());
 757 default:
 758 ASSERT_NOT_REACHED();
736759 }
737760
738  if (style.hasInFlowPosition()) {
739  // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
740  // In other words if left is auto and right is not auto, then left's computed value is negative right().
741  // So we should get the opposite length unit and see if it is auto.
742  return CSSValuePool::singleton().createValue(length);
 761 return 0;
 762}
 763
 764static LayoutUnit getOffsetUsedStyleAbsolute(RenderBlock& container, RenderBox& box, CSSPropertyID propertyID)
 765{
 766 // For absoultely positioned boxes, the offset is how far an box's margin
 767 // edge is offset below the edge of the box's containing block.
 768 // See http://www.w3.org/TR/CSS2/visuren.html#position-props
 769
 770 // Margins are included in offsetTop/offsetLeft so we need to remove them here.
 771 switch (propertyID) {
 772 case CSSPropertyTop:
 773 return box.offsetTop() - box.marginTop();
 774 case CSSPropertyBottom:
 775 return container.clientHeight() - (box.offsetTop() + box.offsetHeight()) - box.marginBottom();
 776 case CSSPropertyLeft:
 777 return box.offsetLeft() - box.marginLeft();
 778 case CSSPropertyRight:
 779 return container.clientWidth() - (box.offsetLeft() + box.offsetWidth()) - box.marginRight();
 780 default:
 781 ASSERT_NOT_REACHED();
743782 }
744783
745  return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
 784 return 0;
 785}
 786
 787static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID, RenderObject* renderer)
 788{
 789 // If the element is not displayed; return the "computed value".
 790 if (!renderer || !renderer->isBox())
 791 return zoomAdjustedPixelValueForLength(getOffsetComputedLength(style, propertyID), style);
 792
 793 // We should return the "used value".
 794 LayoutUnit length = 0;
 795 auto& box = downcast<RenderBox>(*renderer);
 796 RenderBlock* containingBlock = box.containingBlock();
 797 if (box.isRelPositioned() || !containingBlock)
 798 length = getOffsetUsedStyleRelative(box, propertyID);
 799 else
 800 length = getOffsetUsedStyleAbsolute(*containingBlock, box, propertyID);
 801
 802 return zoomAdjustedPixelValue(length, style);
746803}
747804
748805RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::currentColorOrValidColor(const RenderStyle* style, const Color& color) const

@@static bool paddingOrMarginIsRendererDependent(const RenderStyle* style, RenderO
21992256 return renderer && style && renderer->isBox() && !(style->*lengthGetter)().isFixed();
22002257}
22012258
 2259static bool positionOffsetValueIsRendererDependent(const RenderStyle* style, RenderObject* renderer)
 2260{
 2261 return renderer && style && renderer->isBox();
 2262}
 2263
22022264static CSSValueID convertToPageBreak(BreakBetween value)
22032265{
22042266 if (value == PageBreakBetween || value == LeftPageBreakBetween || value == RightPageBreakBetween

@@static CSSValueID convertToRegionBreak(BreakInside value)
22492311 return CSSValueAuto;
22502312}
22512313#endif
2252 
 2314
 2315static inline bool isNonReplacedInline(RenderObject& renderer)
 2316{
 2317 return renderer.isInline() && !renderer.isReplaced();
 2318}
 2319
22532320static bool isLayoutDependent(CSSPropertyID propertyID, const RenderStyle* style, RenderObject* renderer)
22542321{
22552322 switch (propertyID) {
 2323 case CSSPropertyTop:
 2324 case CSSPropertyBottom:
 2325 case CSSPropertyLeft:
 2326 case CSSPropertyRight:
 2327 return positionOffsetValueIsRendererDependent(style, renderer);
22562328 case CSSPropertyWidth:
22572329 case CSSPropertyHeight:
 2330 return renderer && !renderer->isRenderSVGModelObject() && !isNonReplacedInline(*renderer);
22582331 case CSSPropertyPerspectiveOrigin:
22592332 case CSSPropertyTransformOrigin:
22602333 case CSSPropertyTransform:
2261  case CSSPropertyFilter:
 2334 case CSSPropertyFilter: // Why are filters layout-dependent?
22622335#if ENABLE(FILTERS_LEVEL_2)
2263  case CSSPropertyWebkitBackdropFilter:
 2336 case CSSPropertyWebkitBackdropFilter: // Ditto for backdrop-filter.
22642337#endif
22652338 return true;
22662339 case CSSPropertyMargin: {

@@static bool isImplicitlyInheritedGridOrFlexProperty(CSSPropertyID propertyID)
23712444 }
23722445}
23732446
 2447// In CSS 2.1 the returned object should actually contain the "used values"
 2448// rather then the "computed values" (despite the name saying otherwise).
 2449//
 2450// See;
 2451// http://www.w3.org/TR/CSS21/cascade.html#used-value
 2452// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
 2453// https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle#Notes
23742454RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
23752455{
23762456 return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);

@@RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
28292909 case CSSPropertyBorderLeftWidth:
28302910 return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
28312911 case CSSPropertyBottom:
2832  return positionOffsetValue(*style, CSSPropertyBottom);
 2912 return positionOffsetValue(*style, CSSPropertyBottom, renderer);
28332913 case CSSPropertyWebkitBoxAlign:
28342914 return cssValuePool.createValue(style->boxAlign());
28352915#if ENABLE(CSS_BOX_DECORATION_BREAK)

@@RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
30773157 if (renderer && !renderer->isRenderSVGModelObject()) {
30783158 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
30793159 // the "height" property does not apply for non-replaced inline elements.
3080  if (!renderer->isReplaced() && renderer->isInline())
 3160 if (isNonReplacedInline(*renderer))
30813161 return cssValuePool.createIdentifierValue(CSSValueAuto);
30823162 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
30833163 }

@@RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
31153195 return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
31163196#endif
31173197 case CSSPropertyLeft:
3118  return positionOffsetValue(*style, CSSPropertyLeft);
 3198 return positionOffsetValue(*style, CSSPropertyLeft, renderer);
31193199 case CSSPropertyLetterSpacing:
31203200 if (!style->letterSpacing())
31213201 return cssValuePool.createIdentifierValue(CSSValueNormal);

@@RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
32533333 case CSSPropertyPosition:
32543334 return cssValuePool.createValue(style->position());
32553335 case CSSPropertyRight:
3256  return positionOffsetValue(*style, CSSPropertyRight);
 3336 return positionOffsetValue(*style, CSSPropertyRight, renderer);
32573337 case CSSPropertyWebkitRubyPosition:
32583338 return cssValuePool.createValue(style->rubyPosition());
32593339 case CSSPropertyTableLayout:

@@RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
33533433 case CSSPropertyTextTransform:
33543434 return cssValuePool.createValue(style->textTransform());
33553435 case CSSPropertyTop:
3356  return positionOffsetValue(*style, CSSPropertyTop);
 3436 return positionOffsetValue(*style, CSSPropertyTop, renderer);
33573437 case CSSPropertyUnicodeBidi:
33583438 return cssValuePool.createValue(style->unicodeBidi());
33593439 case CSSPropertyVerticalAlign:

@@RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
33933473 if (renderer && !renderer->isRenderSVGModelObject()) {
33943474 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
33953475 // the "width" property does not apply for non-replaced inline elements.
3396  if (!renderer->isReplaced() && renderer->isInline())
 3476 if (isNonReplacedInline(*renderer))
33973477 return cssValuePool.createIdentifierValue(CSSValueAuto);
33983478 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style);
33993479 }

LayoutTests/ChangeLog

 12017-05-26 Simon Fraser <simon.fraser@apple.com>
 2
 3 getComputedStyle returns percentage values for left / right / top / bottom
 4 https://bugs.webkit.org/show_bug.cgi?id=29084
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * fast/css/getComputedStyle/computed-style-expected.txt: New baseline.
 9 * fast/css/getComputedStyle/computed-style-negative-top-expected.txt:
 10 * fast/css/getComputedStyle/computed-style-negative-top.html: Convert to a real JS test, add more cases.
 11 * fast/css/getComputedStyle/getComputedStyle-offsets-expected.txt: Added.
 12 * fast/css/getComputedStyle/getComputedStyle-offsets.html: Added.
 13 * fast/css/getComputedStyle/getComputedStyle-zoom-and-background-size-expected.txt:
 14 * fast/css/getComputedStyle/getComputedStyle-zoom-and-background-size.html: It doesn't make any sense to test right/bottom.
 15
1162017-05-24 Joanmarie Diggs <jdiggs@igalia.com>
217
318 [ATK] Gardening needed after r217171

LayoutTests/fast/css/getComputedStyle/computed-style-expected.txt

@@border-top-left-radius: 0px;
3030border-top-right-radius: 0px;
3131border-top-style: none;
3232border-top-width: 0px;
33 bottom: auto;
 33bottom: 16px;
3434box-shadow: none;
3535box-sizing: content-box;
3636caption-side: top;

@@font-optical-sizing: auto;
5454hanging-punctuation: none;
5555height: 576px;
5656image-rendering: auto;
57 left: auto;
 57left: -8px;
5858letter-spacing: normal;
5959line-height: 18px;
6060list-style-image: none;

@@page-break-inside: auto;
8989pointer-events: auto;
9090position: static;
9191resize: none;
92 right: auto;
 92right: 8px;
9393speak: normal;
9494table-layout: auto;
9595tab-size: 8;

@@text-rendering: auto;
100100text-shadow: none;
101101text-overflow: clip;
102102text-transform: none;
103 top: auto;
 103top: -8px;
104104transform: none;
105105transform-origin: 392px 288px;
106106transform-style: flat;

LayoutTests/fast/css/getComputedStyle/computed-style-negative-top-expected.txt

1 Test succeeded! Top is -1px.
 1Test computed offsets on elements with negative top and left.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6
 7With no height
 8PASS style.top is '-1px'
 9PASS style.left is '-2px'
 10PASS style.bottom is '1px'
 11PASS style.right is '2px'
 12
 13With height:100%;
 14PASS style.top is '-1px'
 15PASS style.left is '-2px'
 16PASS style.bottom is '1px'
 17PASS style.right is '2px'
 18
 19With height:auto;
 20PASS style.top is '-1px'
 21PASS style.left is '-2px'
 22PASS style.bottom is '1px'
 23PASS style.right is '2px'
 24PASS successfullyParsed is true
 25
 26TEST COMPLETE
 27

LayoutTests/fast/css/getComputedStyle/computed-style-negative-top.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<script src="../../../resources/js-test-pre.js"></script>
 5</head>
 6<body>
 7<body>
 8 <div id="testContainer1" style="width: 100px; height: 200px;">
 9 <div id="test1" style="position:relative; top:-1px; left:-2px;"></div>
 10 </div>
 11
 12 <div id="testContainer2" style="width: 100px; height: 200px;">
 13 <div id="test2" style="position:relative; top:-1px; left:-2px; height:100%;"></div>
 14 </div>
 15
 16 <div id="testContainer3" style="width: 100px; height: 200px;">
 17 <div id="test3" style="position:relative; top:-1px; left:-2px; height:auto;"></div>
 18 </div>
 19
120<script>
2 function test() {
3  if (window.testRunner)
4  testRunner.dumpAsText();
5  var style = document.defaultView.getComputedStyle(document.getElementById("test"), "");
6  var result = document.getElementById("result");
7  if (style.top == "-1px")
8  result.appendChild(document.createTextNode("Test succeeded! Top is " + style.top + "."));
9  else
10  result.appendChild(document.createTextNode("Test failed! Top is " + style.top + "."));
 21description("Test computed offsets on elements with negative top and left.")
 22
 23var test = document.getElementById('test');
 24var style;
 25
 26function testStyle(name)
 27{
 28 debug('');
 29 debug(name);
 30 shouldBe("style.top", "'-1px'");
 31 shouldBe("style.left", "'-2px'");
 32 shouldBe("style.bottom", "'1px'");
 33 shouldBe("style.right", "'2px'");
1134}
 35
 36style = document.defaultView.getComputedStyle(document.getElementById("test1"), "");
 37testStyle("With no height");
 38
 39style = document.defaultView.getComputedStyle(document.getElementById("test2"), "");
 40testStyle("With height:100%;");
 41
 42style = document.defaultView.getComputedStyle(document.getElementById("test3"), "");
 43testStyle("With height:auto;");
 44
1245</script>
13 <body onload="test()">
14 <div id="test" style="position:relative; top:-1px"></div>
15 <div id="result"></div>
 46
 47<script src="../../../resources/js-test-post.js"></script>
1648</body>

LayoutTests/fast/css/getComputedStyle/getComputedStyle-offsets-expected.txt

 1Test to make sure top/bottom/left/right properly returns pixel values for any input.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6
 7No offsets (zero width/height)
 8
 9PASS getComputedStyle(test).top is '0px'
 10PASS getComputedStyle(test).left is '0px'
 11PASS getComputedStyle(test).right is '200px'
 12PASS getComputedStyle(test).bottom is '400px'
 13PASS getComputedStyle(test).width is '0px'
 14PASS getComputedStyle(test).height is '0px'
 15
 16test.setAttribute('style', 'padding: 5px;')
 17PASS getComputedStyle(test).top is '0px'
 18PASS getComputedStyle(test).left is '0px'
 19PASS getComputedStyle(test).right is '190px'
 20PASS getComputedStyle(test).bottom is '390px'
 21PASS getComputedStyle(test).width is '0px'
 22PASS getComputedStyle(test).height is '0px'
 23
 24test.setAttribute('style', 'border: solid 5px;')
 25PASS getComputedStyle(test).top is '0px'
 26PASS getComputedStyle(test).left is '0px'
 27PASS getComputedStyle(test).right is '190px'
 28PASS getComputedStyle(test).bottom is '390px'
 29PASS getComputedStyle(test).width is '0px'
 30PASS getComputedStyle(test).height is '0px'
 31
 32test.setAttribute('style', 'margin: 5px;')
 33PASS getComputedStyle(test).top is '0px'
 34PASS getComputedStyle(test).left is '0px'
 35PASS getComputedStyle(test).right is '190px'
 36PASS getComputedStyle(test).bottom is '390px'
 37PASS getComputedStyle(test).width is '0px'
 38PASS getComputedStyle(test).height is '0px'
 39test.setAttribute('style', '')
 40
 41test.parentNode.setAttribute('style', 'padding: 5px;')
 42PASS getComputedStyle(test).top is '5px'
 43PASS getComputedStyle(test).left is '5px'
 44PASS getComputedStyle(test).right is '205px'
 45PASS getComputedStyle(test).bottom is '405px'
 46PASS getComputedStyle(test).width is '0px'
 47PASS getComputedStyle(test).height is '0px'
 48
 49test.parentNode.setAttribute('style', 'border: solid 5px;')
 50PASS getComputedStyle(test).top is '0px'
 51PASS getComputedStyle(test).left is '0px'
 52PASS getComputedStyle(test).right is '200px'
 53PASS getComputedStyle(test).bottom is '400px'
 54PASS getComputedStyle(test).width is '0px'
 55PASS getComputedStyle(test).height is '0px'
 56
 57test.parentNode.setAttribute('style', 'margin: 5px;')
 58PASS getComputedStyle(test).top is '0px'
 59PASS getComputedStyle(test).left is '0px'
 60PASS getComputedStyle(test).right is '200px'
 61PASS getComputedStyle(test).bottom is '400px'
 62PASS getComputedStyle(test).width is '0px'
 63PASS getComputedStyle(test).height is '0px'
 64
 65No offsets (50px width/height)
 66
 67test.setAttribute('style', 'width: 50px; height: 50px;')
 68PASS getComputedStyle(test).top is '0px'
 69PASS getComputedStyle(test).left is '0px'
 70PASS getComputedStyle(test).right is '150px'
 71PASS getComputedStyle(test).bottom is '350px'
 72PASS getComputedStyle(test).width is '50px'
 73PASS getComputedStyle(test).height is '50px'
 74
 75test.setAttribute('style', 'width: 50px; height: 50px; padding: 5px;')
 76PASS getComputedStyle(test).top is '0px'
 77PASS getComputedStyle(test).left is '0px'
 78PASS getComputedStyle(test).right is '140px'
 79PASS getComputedStyle(test).bottom is '340px'
 80PASS getComputedStyle(test).width is '50px'
 81PASS getComputedStyle(test).height is '50px'
 82
 83test.setAttribute('style', 'width: 50px; height: 50px; border: solid 5px;')
 84PASS getComputedStyle(test).top is '0px'
 85PASS getComputedStyle(test).left is '0px'
 86PASS getComputedStyle(test).right is '140px'
 87PASS getComputedStyle(test).bottom is '340px'
 88PASS getComputedStyle(test).width is '50px'
 89PASS getComputedStyle(test).height is '50px'
 90
 91test.setAttribute('style', 'width: 50px; height: 50px; margin: 5px;')
 92PASS getComputedStyle(test).top is '0px'
 93PASS getComputedStyle(test).left is '0px'
 94PASS getComputedStyle(test).right is '140px'
 95PASS getComputedStyle(test).bottom is '340px'
 96PASS getComputedStyle(test).width is '50px'
 97PASS getComputedStyle(test).height is '50px'
 98test.removeAttribute('style', 'margin')
 99
 100test.setAttribute('style', 'width: 50px; height: 50px;')
 101
 102test.parentNode.setAttribute('style', 'padding: 5px;')
 103PASS getComputedStyle(test).top is '5px'
 104PASS getComputedStyle(test).left is '5px'
 105PASS getComputedStyle(test).right is '155px'
 106PASS getComputedStyle(test).bottom is '355px'
 107PASS getComputedStyle(test).width is '50px'
 108PASS getComputedStyle(test).height is '50px'
 109
 110test.parentNode.setAttribute('style', 'border: solid 5px;')
 111PASS getComputedStyle(test).top is '0px'
 112PASS getComputedStyle(test).left is '0px'
 113PASS getComputedStyle(test).right is '150px'
 114PASS getComputedStyle(test).bottom is '350px'
 115PASS getComputedStyle(test).width is '50px'
 116PASS getComputedStyle(test).height is '50px'
 117
 118test.parentNode.setAttribute('style', 'margin: 5px;')
 119PASS getComputedStyle(test).top is '0px'
 120PASS getComputedStyle(test).left is '0px'
 121PASS getComputedStyle(test).right is '150px'
 122PASS getComputedStyle(test).bottom is '350px'
 123PASS getComputedStyle(test).width is '50px'
 124PASS getComputedStyle(test).height is '50px'
 125
 126No offsets (100% width/height)
 127
 128test.setAttribute('style', 'width: 100%; height: 100%;')
 129PASS getComputedStyle(test).top is '0px'
 130PASS getComputedStyle(test).left is '0px'
 131PASS getComputedStyle(test).right is '0px'
 132PASS getComputedStyle(test).bottom is '0px'
 133PASS getComputedStyle(test).width is '200px'
 134PASS getComputedStyle(test).height is '400px'
 135
 136test.setAttribute('style', 'width: 100%; height: 100%; padding: 5px;')
 137PASS getComputedStyle(test).top is '0px'
 138PASS getComputedStyle(test).left is '0px'
 139PASS getComputedStyle(test).right is '-10px'
 140PASS getComputedStyle(test).bottom is '-10px'
 141PASS getComputedStyle(test).width is '200px'
 142PASS getComputedStyle(test).height is '400px'
 143test.removeAttribute('style', 'padding')
 144
 145test.setAttribute('style', 'width: 100%; height: 100%; border: solid 5px;')
 146PASS getComputedStyle(test).top is '0px'
 147PASS getComputedStyle(test).left is '0px'
 148PASS getComputedStyle(test).right is '-10px'
 149PASS getComputedStyle(test).bottom is '-10px'
 150PASS getComputedStyle(test).width is '200px'
 151PASS getComputedStyle(test).height is '400px'
 152test.removeAttribute('style', 'border')
 153
 154test.setAttribute('style', 'width: 100%; height: 100%; margin: 5px;')
 155PASS getComputedStyle(test).top is '0px'
 156PASS getComputedStyle(test).left is '0px'
 157PASS getComputedStyle(test).right is '-10px'
 158PASS getComputedStyle(test).bottom is '-10px'
 159PASS getComputedStyle(test).width is '200px'
 160PASS getComputedStyle(test).height is '400px'
 161test.removeAttribute('style', 'margin')
 162
 163test.setAttribute('style', 'width: 100%; height: 100%;')
 164
 165test.parentNode.setAttribute('style', 'padding: 5px;')
 166PASS getComputedStyle(test).top is '5px'
 167PASS getComputedStyle(test).left is '5px'
 168PASS getComputedStyle(test).right is '-5px'
 169PASS getComputedStyle(test).bottom is '-5px'
 170PASS getComputedStyle(test).width is '210px'
 171PASS getComputedStyle(test).height is '410px'
 172
 173test.parentNode.setAttribute('style', 'border: solid 5px;')
 174PASS getComputedStyle(test).top is '0px'
 175PASS getComputedStyle(test).left is '0px'
 176PASS getComputedStyle(test).right is '0px'
 177PASS getComputedStyle(test).bottom is '0px'
 178PASS getComputedStyle(test).width is '200px'
 179PASS getComputedStyle(test).height is '400px'
 180
 181test.parentNode.setAttribute('style', 'margin: 5px;')
 182PASS getComputedStyle(test).top is '0px'
 183PASS getComputedStyle(test).left is '0px'
 184PASS getComputedStyle(test).right is '0px'
 185PASS getComputedStyle(test).bottom is '0px'
 186PASS getComputedStyle(test).width is '200px'
 187PASS getComputedStyle(test).height is '400px'
 188
 189% offsets (top/left)
 190
 191test.setAttribute('style', 'top: 10%; left: 10%; width: 50%; height: 60%;')
 192PASS getComputedStyle(test).top is '40px'
 193PASS getComputedStyle(test).left is '20px'
 194PASS getComputedStyle(test).right is '80px'
 195PASS getComputedStyle(test).bottom is '120px'
 196PASS getComputedStyle(test).width is '100px'
 197PASS getComputedStyle(test).height is '240px'
 198
 199test.parentNode.setAttribute('style', 'padding: 25px;')
 200PASS getComputedStyle(test).top is '45px'
 201PASS getComputedStyle(test).left is '25px'
 202PASS getComputedStyle(test).right is '100px'
 203PASS getComputedStyle(test).bottom is '135px'
 204PASS getComputedStyle(test).width is '125px'
 205PASS getComputedStyle(test).height is '270px'
 206test.parentNode.removeAttribute('style', 'padding')
 207
 208test.parentNode.setAttribute('style', 'border: solid 25px;')
 209PASS getComputedStyle(test).top is '40px'
 210PASS getComputedStyle(test).left is '20px'
 211PASS getComputedStyle(test).right is '80px'
 212PASS getComputedStyle(test).bottom is '120px'
 213PASS getComputedStyle(test).width is '100px'
 214PASS getComputedStyle(test).height is '240px'
 215test.parentNode.removeAttribute('style', 'border')
 216
 217test.parentNode.setAttribute('style', 'margin: 25px;')
 218PASS getComputedStyle(test).top is '40px'
 219PASS getComputedStyle(test).left is '20px'
 220PASS getComputedStyle(test).right is '80px'
 221PASS getComputedStyle(test).bottom is '120px'
 222PASS getComputedStyle(test).width is '100px'
 223PASS getComputedStyle(test).height is '240px'
 224test.parentNode.removeAttribute('style', 'margin')
 225
 226% offsets (right/bottom)
 227
 228test.setAttribute('style', 'right: 10%; bottom: 10%; width: 90%; height: 80%;')
 229PASS getComputedStyle(test).top is '40px'
 230PASS getComputedStyle(test).left is '0px'
 231PASS getComputedStyle(test).right is '20px'
 232PASS getComputedStyle(test).bottom is '40px'
 233PASS getComputedStyle(test).width is '180px'
 234PASS getComputedStyle(test).height is '320px'
 235
 236test.parentNode.setAttribute('style', 'padding: 25px;')
 237PASS getComputedStyle(test).top is '45px'
 238PASS getComputedStyle(test).left is '0px'
 239PASS getComputedStyle(test).right is '25px'
 240PASS getComputedStyle(test).bottom is '45px'
 241PASS getComputedStyle(test).width is '225px'
 242PASS getComputedStyle(test).height is '360px'
 243test.parentNode.removeAttribute('style', 'padding')
 244
 245test.parentNode.setAttribute('style', 'border: solid 25px;')
 246PASS getComputedStyle(test).top is '40px'
 247PASS getComputedStyle(test).left is '0px'
 248PASS getComputedStyle(test).right is '20px'
 249PASS getComputedStyle(test).bottom is '40px'
 250PASS getComputedStyle(test).width is '180px'
 251PASS getComputedStyle(test).height is '320px'
 252test.parentNode.removeAttribute('style', 'border')
 253
 254test.parentNode.setAttribute('style', 'margin: 25px;')
 255PASS getComputedStyle(test).top is '40px'
 256PASS getComputedStyle(test).left is '0px'
 257PASS getComputedStyle(test).right is '20px'
 258PASS getComputedStyle(test).bottom is '40px'
 259PASS getComputedStyle(test).width is '180px'
 260PASS getComputedStyle(test).height is '320px'
 261test.parentNode.removeAttribute('style', 'margin')
 262
 263em offsets
 264
 265test.setAttribute('style', 'top: 1em; left: 2em; width: 3em; height: 4em;')
 266PASS getComputedStyle(test).top is '10px'
 267PASS getComputedStyle(test).left is '20px'
 268PASS getComputedStyle(test).right is '150px'
 269PASS getComputedStyle(test).bottom is '350px'
 270PASS getComputedStyle(test).width is '30px'
 271PASS getComputedStyle(test).height is '40px'
 272
 273test.parentNode.setAttribute('style', 'padding: 25px;')
 274PASS getComputedStyle(test).top is '10px'
 275PASS getComputedStyle(test).left is '20px'
 276PASS getComputedStyle(test).right is '200px'
 277PASS getComputedStyle(test).bottom is '400px'
 278PASS getComputedStyle(test).width is '30px'
 279PASS getComputedStyle(test).height is '40px'
 280
 281test.parentNode.setAttribute('style', 'border: solid 25px;')
 282PASS getComputedStyle(test).top is '10px'
 283PASS getComputedStyle(test).left is '20px'
 284PASS getComputedStyle(test).right is '150px'
 285PASS getComputedStyle(test).bottom is '350px'
 286PASS getComputedStyle(test).width is '30px'
 287PASS getComputedStyle(test).height is '40px'
 288
 289test.parentNode.setAttribute('style', 'margin: 25px;')
 290PASS getComputedStyle(test).top is '10px'
 291PASS getComputedStyle(test).left is '20px'
 292PASS getComputedStyle(test).right is '150px'
 293PASS getComputedStyle(test).bottom is '350px'
 294PASS getComputedStyle(test).width is '30px'
 295PASS getComputedStyle(test).height is '40px'
 296
 297Absolute Offsets
 298
 299test.setAttribute('style', 'position: absolute; top: 30px; height: 300px;')
 300PASS getComputedStyle(test).top is '30px'
 301PASS getComputedStyle(test).left is '0px'
 302PASS getComputedStyle(test).right is '200px'
 303PASS getComputedStyle(test).bottom is '70px'
 304PASS getComputedStyle(test).width is '0px'
 305PASS getComputedStyle(test).height is '300px'
 306
 307test.parentNode.setAttribute('style', 'padding: 25px;')
 308PASS getComputedStyle(test).top is '30px'
 309PASS getComputedStyle(test).left is '25px'
 310PASS getComputedStyle(test).right is '225px'
 311PASS getComputedStyle(test).bottom is '120px'
 312PASS getComputedStyle(test).width is '0px'
 313PASS getComputedStyle(test).height is '300px'
 314
 315test.parentNode.setAttribute('style', 'border: solid 25px;')
 316PASS getComputedStyle(test).top is '30px'
 317PASS getComputedStyle(test).left is '0px'
 318PASS getComputedStyle(test).right is '200px'
 319PASS getComputedStyle(test).bottom is '70px'
 320PASS getComputedStyle(test).width is '0px'
 321PASS getComputedStyle(test).height is '300px'
 322
 323test.parentNode.setAttribute('style', 'margin: 25px;')
 324PASS getComputedStyle(test).top is '30px'
 325PASS getComputedStyle(test).left is '0px'
 326PASS getComputedStyle(test).right is '200px'
 327PASS getComputedStyle(test).bottom is '70px'
 328PASS getComputedStyle(test).width is '0px'
 329PASS getComputedStyle(test).height is '300px'
 330PASS successfullyParsed is true
 331
 332TEST COMPLETE
 333

LayoutTests/fast/css/getComputedStyle/getComputedStyle-offsets.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<meta charset="utf-8">
 5<script src="../../../resources/js-test-pre.js"></script>
 6</head>
 7<body>
 8<style>
 9
 10.relative200x400 {
 11 position: relative;
 12 width: 200px;
 13 height: 400px;
 14 font-size: 10px;
 15}
 16
 17#test {
 18 position: absolute;
 19}
 20
 21</style>
 22<div id="tests">
 23<div class="relative200x400"><div id="test"></div></div>
 24</div>
 25<script>
 26
 27description("Test to make sure top/bottom/left/right properly returns pixel values for any input.")
 28
 29var test = document.getElementById('test');
 30
 31
 32//-----------------------------------------------------------------------------
 33debug('');
 34debug('No offsets (zero width/height)');
 35debug('');
 36shouldBe("getComputedStyle(test).top", "'0px'");
 37shouldBe("getComputedStyle(test).left", "'0px'");
 38shouldBe("getComputedStyle(test).right", "'200px'");
 39shouldBe("getComputedStyle(test).bottom", "'400px'");
 40shouldBe("getComputedStyle(test).width", "'0px'");
 41shouldBe("getComputedStyle(test).height", "'0px'");
 42
 43// On padding/border/margin on actual node
 44debug('');
 45evalAndLog("test.setAttribute('style', 'padding: 5px;')");
 46shouldBe("getComputedStyle(test).top", "'0px'");
 47shouldBe("getComputedStyle(test).left", "'0px'");
 48shouldBe("getComputedStyle(test).right", "'190px'");
 49shouldBe("getComputedStyle(test).bottom", "'390px'");
 50shouldBe("getComputedStyle(test).width", "'0px'");
 51shouldBe("getComputedStyle(test).height", "'0px'");
 52
 53debug('');
 54evalAndLog("test.setAttribute('style', 'border: solid 5px;')");
 55shouldBe("getComputedStyle(test).top", "'0px'");
 56shouldBe("getComputedStyle(test).left", "'0px'");
 57shouldBe("getComputedStyle(test).right", "'190px'");
 58shouldBe("getComputedStyle(test).bottom", "'390px'");
 59shouldBe("getComputedStyle(test).width", "'0px'");
 60shouldBe("getComputedStyle(test).height", "'0px'");
 61
 62debug('');
 63evalAndLog("test.setAttribute('style', 'margin: 5px;')");
 64shouldBe("getComputedStyle(test).top", "'0px'");
 65shouldBe("getComputedStyle(test).left", "'0px'");
 66shouldBe("getComputedStyle(test).right", "'190px'");
 67shouldBe("getComputedStyle(test).bottom", "'390px'");
 68shouldBe("getComputedStyle(test).width", "'0px'");
 69shouldBe("getComputedStyle(test).height", "'0px'");
 70
 71evalAndLog("test.setAttribute('style', '')");
 72
 73// On padding/border/margin on parent node
 74debug('');
 75evalAndLog("test.parentNode.setAttribute('style', 'padding: 5px;')");
 76shouldBe("getComputedStyle(test).top", "'5px'");
 77shouldBe("getComputedStyle(test).left", "'5px'");
 78shouldBe("getComputedStyle(test).right", "'205px'");
 79shouldBe("getComputedStyle(test).bottom", "'405px'");
 80shouldBe("getComputedStyle(test).width", "'0px'");
 81shouldBe("getComputedStyle(test).height", "'0px'");
 82
 83debug('');
 84evalAndLog("test.parentNode.setAttribute('style', 'border: solid 5px;')");
 85shouldBe("getComputedStyle(test).top", "'0px'");
 86shouldBe("getComputedStyle(test).left", "'0px'");
 87shouldBe("getComputedStyle(test).right", "'200px'");
 88shouldBe("getComputedStyle(test).bottom", "'400px'");
 89shouldBe("getComputedStyle(test).width", "'0px'");
 90shouldBe("getComputedStyle(test).height", "'0px'");
 91
 92debug('');
 93evalAndLog("test.parentNode.setAttribute('style', 'margin: 5px;')");
 94shouldBe("getComputedStyle(test).top", "'0px'");
 95shouldBe("getComputedStyle(test).left", "'0px'");
 96shouldBe("getComputedStyle(test).right", "'200px'");
 97shouldBe("getComputedStyle(test).bottom", "'400px'");
 98shouldBe("getComputedStyle(test).width", "'0px'");
 99shouldBe("getComputedStyle(test).height", "'0px'");
 100
 101//-----------------------------------------------------------------------------
 102debug('');
 103debug('No offsets (50px width/height)');
 104debug('');
 105var commonStyle = "width: 50px; height: 50px;";
 106evalAndLog("test.setAttribute('style', '" + commonStyle + "')");
 107shouldBe("getComputedStyle(test).top", "'0px'");
 108shouldBe("getComputedStyle(test).left", "'0px'");
 109shouldBe("getComputedStyle(test).right", "'150px'");
 110shouldBe("getComputedStyle(test).bottom", "'350px'");
 111shouldBe("getComputedStyle(test).width", "'50px'");
 112shouldBe("getComputedStyle(test).height", "'50px'");
 113
 114// On padding/border/margin on actual node
 115debug('');
 116evalAndLog("test.setAttribute('style', '" + commonStyle + " padding: 5px;')");
 117shouldBe("getComputedStyle(test).top", "'0px'");
 118shouldBe("getComputedStyle(test).left", "'0px'");
 119shouldBe("getComputedStyle(test).right", "'140px'");
 120shouldBe("getComputedStyle(test).bottom", "'340px'");
 121shouldBe("getComputedStyle(test).width", "'50px'");
 122shouldBe("getComputedStyle(test).height", "'50px'");
 123
 124debug('');
 125evalAndLog("test.setAttribute('style', '" + commonStyle + " border: solid 5px;')");
 126shouldBe("getComputedStyle(test).top", "'0px'");
 127shouldBe("getComputedStyle(test).left", "'0px'");
 128shouldBe("getComputedStyle(test).right", "'140px'");
 129shouldBe("getComputedStyle(test).bottom", "'340px'");
 130shouldBe("getComputedStyle(test).width", "'50px'");
 131shouldBe("getComputedStyle(test).height", "'50px'");
 132
 133debug('');
 134evalAndLog("test.setAttribute('style', '" + commonStyle + " margin: 5px;')");
 135shouldBe("getComputedStyle(test).top", "'0px'");
 136shouldBe("getComputedStyle(test).left", "'0px'");
 137shouldBe("getComputedStyle(test).right", "'140px'");
 138shouldBe("getComputedStyle(test).bottom", "'340px'");
 139shouldBe("getComputedStyle(test).width", "'50px'");
 140shouldBe("getComputedStyle(test).height", "'50px'");
 141evalAndLog("test.removeAttribute('style', 'margin')");
 142
 143// On padding/border/margin on parent node
 144debug('');
 145evalAndLog("test.setAttribute('style', '" + commonStyle + "')");
 146debug('');
 147evalAndLog("test.parentNode.setAttribute('style', 'padding: 5px;')");
 148shouldBe("getComputedStyle(test).top", "'5px'");
 149shouldBe("getComputedStyle(test).left", "'5px'");
 150shouldBe("getComputedStyle(test).right", "'155px'");
 151shouldBe("getComputedStyle(test).bottom", "'355px'");
 152shouldBe("getComputedStyle(test).width", "'50px'");
 153shouldBe("getComputedStyle(test).height", "'50px'");
 154
 155debug('');
 156evalAndLog("test.parentNode.setAttribute('style', 'border: solid 5px;')");
 157shouldBe("getComputedStyle(test).top", "'0px'");
 158shouldBe("getComputedStyle(test).left", "'0px'");
 159shouldBe("getComputedStyle(test).right", "'150px'");
 160shouldBe("getComputedStyle(test).bottom", "'350px'");
 161shouldBe("getComputedStyle(test).width", "'50px'");
 162shouldBe("getComputedStyle(test).height", "'50px'");
 163
 164debug('');
 165evalAndLog("test.parentNode.setAttribute('style', 'margin: 5px;')");
 166shouldBe("getComputedStyle(test).top", "'0px'");
 167shouldBe("getComputedStyle(test).left", "'0px'");
 168shouldBe("getComputedStyle(test).right", "'150px'");
 169shouldBe("getComputedStyle(test).bottom", "'350px'");
 170shouldBe("getComputedStyle(test).width", "'50px'");
 171shouldBe("getComputedStyle(test).height", "'50px'");
 172
 173
 174//-----------------------------------------------------------------------------
 175debug('');
 176debug('No offsets (100% width/height)');
 177debug('');
 178var commonStyle = "width: 100%; height: 100%;";
 179evalAndLog("test.setAttribute('style', '" + commonStyle + "')");
 180shouldBe("getComputedStyle(test).top", "'0px'");
 181shouldBe("getComputedStyle(test).left", "'0px'");
 182shouldBe("getComputedStyle(test).right", "'0px'");
 183shouldBe("getComputedStyle(test).bottom", "'0px'");
 184shouldBe("getComputedStyle(test).width", "'200px'");
 185shouldBe("getComputedStyle(test).height", "'400px'");
 186
 187// On padding/border/margin on actual node
 188debug('');
 189evalAndLog("test.setAttribute('style', '" + commonStyle + " padding: 5px;')");
 190shouldBe("getComputedStyle(test).top", "'0px'");
 191shouldBe("getComputedStyle(test).left", "'0px'");
 192shouldBe("getComputedStyle(test).right", "'-10px'");
 193shouldBe("getComputedStyle(test).bottom", "'-10px'");
 194shouldBe("getComputedStyle(test).width", "'200px'");
 195shouldBe("getComputedStyle(test).height", "'400px'");
 196evalAndLog("test.removeAttribute('style', 'padding')");
 197
 198debug('');
 199evalAndLog("test.setAttribute('style', '" + commonStyle + " border: solid 5px;')");
 200shouldBe("getComputedStyle(test).top", "'0px'");
 201shouldBe("getComputedStyle(test).left", "'0px'");
 202shouldBe("getComputedStyle(test).right", "'-10px'");
 203shouldBe("getComputedStyle(test).bottom", "'-10px'");
 204shouldBe("getComputedStyle(test).width", "'200px'");
 205shouldBe("getComputedStyle(test).height", "'400px'");
 206evalAndLog("test.removeAttribute('style', 'border')");
 207
 208debug('');
 209evalAndLog("test.setAttribute('style', '" + commonStyle + " margin: 5px;')");
 210shouldBe("getComputedStyle(test).top", "'0px'");
 211shouldBe("getComputedStyle(test).left", "'0px'");
 212shouldBe("getComputedStyle(test).right", "'-10px'");
 213shouldBe("getComputedStyle(test).bottom", "'-10px'");
 214shouldBe("getComputedStyle(test).width", "'200px'");
 215shouldBe("getComputedStyle(test).height", "'400px'");
 216evalAndLog("test.removeAttribute('style', 'margin')");
 217
 218// On padding/border/margin on parent node
 219debug('');
 220evalAndLog("test.setAttribute('style', '" + commonStyle + "')");
 221debug('');
 222evalAndLog("test.parentNode.setAttribute('style', 'padding: 5px;')");
 223shouldBe("getComputedStyle(test).top", "'5px'");
 224shouldBe("getComputedStyle(test).left", "'5px'");
 225shouldBe("getComputedStyle(test).right", "'-5px'");
 226shouldBe("getComputedStyle(test).bottom", "'-5px'");
 227shouldBe("getComputedStyle(test).width", "'210px'");
 228shouldBe("getComputedStyle(test).height", "'410px'");
 229
 230debug('');
 231evalAndLog("test.parentNode.setAttribute('style', 'border: solid 5px;')");
 232shouldBe("getComputedStyle(test).top", "'0px'");
 233shouldBe("getComputedStyle(test).left", "'0px'");
 234shouldBe("getComputedStyle(test).right", "'0px'");
 235shouldBe("getComputedStyle(test).bottom", "'0px'");
 236shouldBe("getComputedStyle(test).width", "'200px'");
 237shouldBe("getComputedStyle(test).height", "'400px'");
 238
 239debug('');
 240evalAndLog("test.parentNode.setAttribute('style', 'margin: 5px;')");
 241shouldBe("getComputedStyle(test).top", "'0px'");
 242shouldBe("getComputedStyle(test).left", "'0px'");
 243shouldBe("getComputedStyle(test).right", "'0px'");
 244shouldBe("getComputedStyle(test).bottom", "'0px'");
 245shouldBe("getComputedStyle(test).width", "'200px'");
 246shouldBe("getComputedStyle(test).height", "'400px'");
 247
 248//-----------------------------------------------------------------------------
 249debug('');
 250debug('% offsets (top/left)');
 251debug('');
 252evalAndLog("test.setAttribute('style', 'top: 10%; left: 10%; width: 50%; height: 60%;')");
 253shouldBe("getComputedStyle(test).top", "'40px'");
 254shouldBe("getComputedStyle(test).left", "'20px'");
 255shouldBe("getComputedStyle(test).right", "'80px'");
 256shouldBe("getComputedStyle(test).bottom", "'120px'");
 257shouldBe("getComputedStyle(test).width", "'100px'");
 258shouldBe("getComputedStyle(test).height", "'240px'");
 259
 260debug('');
 261evalAndLog("test.parentNode.setAttribute('style', 'padding: 25px;')");
 262shouldBe("getComputedStyle(test).top", "'45px'");
 263shouldBe("getComputedStyle(test).left", "'25px'");
 264shouldBe("getComputedStyle(test).right", "'100px'");
 265shouldBe("getComputedStyle(test).bottom", "'135px'");
 266shouldBe("getComputedStyle(test).width", "'125px'");
 267shouldBe("getComputedStyle(test).height", "'270px'");
 268evalAndLog("test.parentNode.removeAttribute('style', 'padding')");
 269
 270debug('');
 271evalAndLog("test.parentNode.setAttribute('style', 'border: solid 25px;')");
 272shouldBe("getComputedStyle(test).top", "'40px'");
 273shouldBe("getComputedStyle(test).left", "'20px'");
 274shouldBe("getComputedStyle(test).right", "'80px'");
 275shouldBe("getComputedStyle(test).bottom", "'120px'");
 276shouldBe("getComputedStyle(test).width", "'100px'");
 277shouldBe("getComputedStyle(test).height", "'240px'");
 278evalAndLog("test.parentNode.removeAttribute('style', 'border')");
 279
 280debug('');
 281evalAndLog("test.parentNode.setAttribute('style', 'margin: 25px;')");
 282shouldBe("getComputedStyle(test).top", "'40px'");
 283shouldBe("getComputedStyle(test).left", "'20px'");
 284shouldBe("getComputedStyle(test).right", "'80px'");
 285shouldBe("getComputedStyle(test).bottom", "'120px'");
 286shouldBe("getComputedStyle(test).width", "'100px'");
 287shouldBe("getComputedStyle(test).height", "'240px'");
 288evalAndLog("test.parentNode.removeAttribute('style', 'margin')");
 289
 290
 291//-----------------------------------------------------------------------------
 292debug('');
 293debug('% offsets (right/bottom)');
 294debug('');
 295evalAndLog("test.setAttribute('style', 'right: 10%; bottom: 10%; width: 90%; height: 80%;')");
 296shouldBe("getComputedStyle(test).top", "'40px'");
 297shouldBe("getComputedStyle(test).left", "'0px'");
 298shouldBe("getComputedStyle(test).right", "'20px'");
 299shouldBe("getComputedStyle(test).bottom", "'40px'");
 300shouldBe("getComputedStyle(test).width", "'180px'");
 301shouldBe("getComputedStyle(test).height", "'320px'");
 302
 303
 304// On padding/border/margin on parent node
 305debug('');
 306evalAndLog("test.parentNode.setAttribute('style', 'padding: 25px;')");
 307shouldBe("getComputedStyle(test).top", "'45px'");
 308shouldBe("getComputedStyle(test).left", "'0px'");
 309shouldBe("getComputedStyle(test).right", "'25px'");
 310shouldBe("getComputedStyle(test).bottom", "'45px'");
 311shouldBe("getComputedStyle(test).width", "'225px'");
 312shouldBe("getComputedStyle(test).height", "'360px'");
 313evalAndLog("test.parentNode.removeAttribute('style', 'padding')");
 314
 315debug('');
 316evalAndLog("test.parentNode.setAttribute('style', 'border: solid 25px;')");
 317shouldBe("getComputedStyle(test).top", "'40px'");
 318shouldBe("getComputedStyle(test).left", "'0px'");
 319shouldBe("getComputedStyle(test).right", "'20px'");
 320shouldBe("getComputedStyle(test).bottom", "'40px'");
 321shouldBe("getComputedStyle(test).width", "'180px'");
 322shouldBe("getComputedStyle(test).height", "'320px'");
 323evalAndLog("test.parentNode.removeAttribute('style', 'border')");
 324
 325debug('');
 326evalAndLog("test.parentNode.setAttribute('style', 'margin: 25px;')");
 327shouldBe("getComputedStyle(test).top", "'40px'");
 328shouldBe("getComputedStyle(test).left", "'0px'");
 329shouldBe("getComputedStyle(test).right", "'20px'");
 330shouldBe("getComputedStyle(test).bottom", "'40px'");
 331shouldBe("getComputedStyle(test).width", "'180px'");
 332shouldBe("getComputedStyle(test).height", "'320px'");
 333evalAndLog("test.parentNode.removeAttribute('style', 'margin')");
 334
 335
 336
 337//-----------------------------------------------------------------------------
 338debug('');
 339debug('em offsets');
 340debug('');
 341evalAndLog("test.setAttribute('style', 'top: 1em; left: 2em; width: 3em; height: 4em;')");
 342shouldBe("getComputedStyle(test).top", "'10px'");
 343shouldBe("getComputedStyle(test).left", "'20px'");
 344shouldBe("getComputedStyle(test).right", "'150px'");
 345shouldBe("getComputedStyle(test).bottom", "'350px'");
 346shouldBe("getComputedStyle(test).width", "'30px'");
 347shouldBe("getComputedStyle(test).height", "'40px'");
 348
 349// On padding/border/margin on parent node
 350debug('');
 351evalAndLog("test.parentNode.setAttribute('style', 'padding: 25px;')");
 352shouldBe("getComputedStyle(test).top", "'10px'");
 353shouldBe("getComputedStyle(test).left", "'20px'");
 354shouldBe("getComputedStyle(test).right", "'200px'");
 355shouldBe("getComputedStyle(test).bottom", "'400px'");
 356shouldBe("getComputedStyle(test).width", "'30px'");
 357shouldBe("getComputedStyle(test).height", "'40px'");
 358
 359debug('');
 360evalAndLog("test.parentNode.setAttribute('style', 'border: solid 25px;')");
 361shouldBe("getComputedStyle(test).top", "'10px'");
 362shouldBe("getComputedStyle(test).left", "'20px'");
 363shouldBe("getComputedStyle(test).right", "'150px'");
 364shouldBe("getComputedStyle(test).bottom", "'350px'");
 365shouldBe("getComputedStyle(test).width", "'30px'");
 366shouldBe("getComputedStyle(test).height", "'40px'");
 367
 368debug('');
 369evalAndLog("test.parentNode.setAttribute('style', 'margin: 25px;')");
 370shouldBe("getComputedStyle(test).top", "'10px'");
 371shouldBe("getComputedStyle(test).left", "'20px'");
 372shouldBe("getComputedStyle(test).right", "'150px'");
 373shouldBe("getComputedStyle(test).bottom", "'350px'");
 374shouldBe("getComputedStyle(test).width", "'30px'");
 375shouldBe("getComputedStyle(test).height", "'40px'");
 376
 377//-----------------------------------------------------------------------------
 378debug('');
 379debug('Absolute Offsets');
 380debug('');
 381evalAndLog("test.setAttribute('style', 'position: absolute; top: 30px; height: 300px;')");
 382shouldBe("getComputedStyle(test).top", "'30px'");
 383shouldBe("getComputedStyle(test).left", "'0px'");
 384shouldBe("getComputedStyle(test).right", "'200px'");
 385shouldBe("getComputedStyle(test).bottom", "'70px'");
 386shouldBe("getComputedStyle(test).width", "'0px'");
 387shouldBe("getComputedStyle(test).height", "'300px'");
 388
 389debug('');
 390evalAndLog("test.parentNode.setAttribute('style', 'padding: 25px;')");
 391shouldBe("getComputedStyle(test).top", "'30px'");
 392shouldBe("getComputedStyle(test).left", "'25px'");
 393shouldBe("getComputedStyle(test).right", "'225px'");
 394shouldBe("getComputedStyle(test).bottom", "'120px'");
 395shouldBe("getComputedStyle(test).width", "'0px'");
 396shouldBe("getComputedStyle(test).height", "'300px'");
 397
 398debug('');
 399evalAndLog("test.parentNode.setAttribute('style', 'border: solid 25px;')");
 400shouldBe("getComputedStyle(test).top", "'30px'");
 401shouldBe("getComputedStyle(test).left", "'0px'");
 402shouldBe("getComputedStyle(test).right", "'200px'");
 403shouldBe("getComputedStyle(test).bottom", "'70px'");
 404shouldBe("getComputedStyle(test).width", "'0px'");
 405shouldBe("getComputedStyle(test).height", "'300px'");
 406
 407debug('');
 408evalAndLog("test.parentNode.setAttribute('style', 'margin: 25px;')");
 409shouldBe("getComputedStyle(test).top", "'30px'");
 410shouldBe("getComputedStyle(test).left", "'0px'");
 411shouldBe("getComputedStyle(test).right", "'200px'");
 412shouldBe("getComputedStyle(test).bottom", "'70px'");
 413shouldBe("getComputedStyle(test).width", "'0px'");
 414shouldBe("getComputedStyle(test).height", "'300px'");
 415
 416</script>
 417<script src="../../../resources/js-test-post.js"></script>
 418</body>
 419</html>

LayoutTests/fast/css/getComputedStyle/getComputedStyle-zoom-and-background-size-expected.txt

@@outline-width PASS 2px 2px
3434position PASS absolute absolute
3535left PASS 20px 20px
3636top PASS 20px 20px
37 right PASS 50px 50px
38 bottom PASS 50px 50px
3937font-size PASS 20px 20px
4038width PASS 400px 400px
4139max-width PASS 900px 900px

@@outline-width PASS 2px 2px
8987position PASS absolute absolute
9088left PASS 20px 20px
9189top PASS 20px 20px
92 right PASS 50px 50px
93 bottom PASS 50px 50px
9490font-size PASS 20px 20px
9591width PASS 400px 400px
9692max-width PASS 900px 900px

LayoutTests/fast/css/getComputedStyle/getComputedStyle-zoom-and-background-size.html

137137
138138 "left": "20px",
139139 "top": "20px",
140  "right": "50px",
141  "bottom": "50px",
142140
143141 "font-size": "20px",
144142 "width": "400px",