Added: trunk/LayoutTests/fast/writing-mode/percentage-margins-absolute.html (0 => 136646)
--- trunk/LayoutTests/fast/writing-mode/percentage-margins-absolute.html (rev 0)
+++ trunk/LayoutTests/fast/writing-mode/percentage-margins-absolute.html 2012-12-05 08:02:47 UTC (rev 136646)
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=''></script>
+<script>
+description('Percentage margins on absolutely positioned elements are relative to the container\'s logical width');
+
+function testMargins(outerProperties, innerProperties, expectedProperties) {
+ var outer = document.createElement('div'),
+ inner = document.createElement('div'),
+ property, style;
+ for (property in outerProperties)
+ outer.style.setProperty(property, outerProperties[property]);
+ for (property in innerProperties)
+ inner.style.setProperty(property, innerProperties[property]);
+ outer.appendChild(inner);
+ document.body.appendChild(outer);
+ style = getComputedStyle(inner);
+ for (property in expectedProperties)
+ shouldBe('"' + style.getPropertyValue(property) + '"', '"' + expectedProperties[property] + '"');
+ document.body.removeChild(outer);
+}
+
+var WritingModes = {
+ 'HORIZONTAL-TB': 'horizontal-tb',
+ 'VERTICAL-LR': 'vertical-lr',
+ 'VERTICAL-RL': 'vertical-rl'
+}
+
+var outerProperties = {
+ position: 'relative',
+ width: '100px',
+ height: '200px',
+}, innerProperties = {
+ position: 'absolute',
+ width: '40px',
+ height: '160px',
+}, expectedProperties = {
+ margin: '10px 20px 30px 40px'
+};
+
+window._onload_ = function() {
+ for (var outerProperty in WritingModes) {
+ for (var innerProperty in WritingModes) {
+ outerProperties['-webkit-writing-mode'] = WritingModes[outerProperty];
+ innerProperties['-webkit-writing-mode'] = WritingModes[innerProperty];
+ innerProperties['margin'] = outerProperty === 'HORIZONTAL-TB' ? '10% 20% 30% 40%' : '5% 10% 15% 20%';
+ testMargins(outerProperties, innerProperties, expectedProperties);
+ }
+ }
+}
+</script>
+<script src=''></script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (136645 => 136646)
--- trunk/Source/WebCore/ChangeLog 2012-12-05 08:01:33 UTC (rev 136645)
+++ trunk/Source/WebCore/ChangeLog 2012-12-05 08:02:47 UTC (rev 136646)
@@ -1,3 +1,31 @@
+2012-12-05 Bear Travis <[email protected]>
+
+ Absolutely positioned non-replaced elements should resolve vertical margins against
+ their containing block's logical width
+ https://bugs.webkit.org/show_bug.cgi?id=103576
+
+ Reviewed by Emil A Eklund.
+
+ According to the CSS box model specification, all percentage margin & padding values,
+ including top & bottom, should be resolved based on the containing block's width.
+ http://www.w3.org/TR/CSS2/box.html#margin-properties
+ The writing modes specification has refined this definition to use the containing
+ block's logical width to resolve percentage margin & padding values.
+ http://dev.w3.org/csswg/css3-writing-modes/#dimension-mapping
+
+ Previously, positioned elements measured their container in the element's block
+ direction (containerLogicalHeight) to resolve margin-before/after, and in the inline
+ direction (containerLogicalWidth) to resolve margin-start/end. This patch measures the
+ container's logical width in its own inline direction (containerRelativeLogicalWidth)
+ to resolve all margin percentage values.
+
+ Test: fast/writing-mode/percentage-margins-absolute.html
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::computePositionedLogicalWidthUsing): Calculate the logical width
+ of the container, and use it to calculate margins.
+ (WebCore::RenderBox::computePositionedLogicalHeightUsing): Ditto.
+
2012-12-04 Kentaro Hara <[email protected]>
[V8] Replace String::New("symbol") with String::NewSymbol("symbol") (part 2)
Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (136645 => 136646)
--- trunk/Source/WebCore/rendering/RenderBox.cpp 2012-12-05 08:01:33 UTC (rev 136645)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp 2012-12-05 08:02:47 UTC (rev 136646)
@@ -2853,6 +2853,8 @@
LayoutUnit logicalLeftValue = 0;
+ const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, 0, 0, false);
+
bool logicalWidthIsAuto = logicalWidth.isIntrinsicOrAuto();
bool logicalLeftIsAuto = logicalLeft.isAuto();
bool logicalRightIsAuto = logicalRight.isAuto();
@@ -2900,16 +2902,16 @@
}
} else if (marginLogicalLeft.isAuto()) {
// Solve for left margin
- marginLogicalRightValue = valueForLength(marginLogicalRight, containerLogicalWidth, renderView);
+ marginLogicalRightValue = valueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
marginLogicalLeftValue = availableSpace - marginLogicalRightValue;
} else if (marginLogicalRight.isAuto()) {
// Solve for right margin
- marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
+ marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
marginLogicalRightValue = availableSpace - marginLogicalLeftValue;
} else {
// Over-constrained, solve for left if direction is RTL
- marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
- marginLogicalRightValue = valueForLength(marginLogicalRight, containerLogicalWidth, renderView);
+ marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
+ marginLogicalRightValue = valueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
// Use the containing block's direction rather than the parent block's
// per CSS 2.1 reference test abspos-non-replaced-width-margin-000.
@@ -2959,8 +2961,8 @@
// because the value is not used for any further calculations.
// Calculate margins, 'auto' margins are ignored.
- marginLogicalLeftValue = minimumValueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
- marginLogicalRightValue = minimumValueForLength(marginLogicalRight, containerLogicalWidth, renderView);
+ marginLogicalLeftValue = minimumValueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
+ marginLogicalRightValue = minimumValueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
const LayoutUnit availableSpace = containerLogicalWidth - (marginLogicalLeftValue + marginLogicalRightValue + bordersPlusPadding);
@@ -3185,6 +3187,8 @@
LayoutUnit logicalHeightValue;
LayoutUnit contentLogicalHeight = logicalHeight - bordersPlusPadding;
+ const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, 0, 0, false);
+
LayoutUnit logicalTopValue = 0;
bool logicalHeightIsAuto = logicalHeightLength.isAuto();
@@ -3223,16 +3227,16 @@
computedValues.m_margins.m_after = availableSpace - computedValues.m_margins.m_before; // account for odd valued differences
} else if (marginBefore.isAuto()) {
// Solve for top margin
- computedValues.m_margins.m_after = valueForLength(marginAfter, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_after = valueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
computedValues.m_margins.m_before = availableSpace - computedValues.m_margins.m_after;
} else if (marginAfter.isAuto()) {
// Solve for bottom margin
- computedValues.m_margins.m_before = valueForLength(marginBefore, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_before = valueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
computedValues.m_margins.m_after = availableSpace - computedValues.m_margins.m_before;
} else {
// Over-constrained, (no need solve for bottom)
- computedValues.m_margins.m_before = valueForLength(marginBefore, containerLogicalHeight, renderView);
- computedValues.m_margins.m_after = valueForLength(marginAfter, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_before = valueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
+ computedValues.m_margins.m_after = valueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
}
} else {
/*--------------------------------------------------------------------*\
@@ -3261,8 +3265,8 @@
// because the value is not used for any further calculations.
// Calculate margins, 'auto' margins are ignored.
- computedValues.m_margins.m_before = minimumValueForLength(marginBefore, containerLogicalHeight, renderView);
- computedValues.m_margins.m_after = minimumValueForLength(marginAfter, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_before = minimumValueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
+ computedValues.m_margins.m_after = minimumValueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
const LayoutUnit availableSpace = containerLogicalHeight - (computedValues.m_margins.m_before + computedValues.m_margins.m_after + bordersPlusPadding);