Bug 1083134 - Part 3.1: Cascade block-axis logical properties with their physical equivalents. r=dbaron

This commit is contained in:
Cameron McCormack 2015-01-17 15:22:51 +11:00
Родитель 0d6e5754f9
Коммит cf8408ead3
2 изменённых файлов: 98 добавлений и 60 удалений

Просмотреть файл

@ -16,6 +16,7 @@
#include "nsStyleSet.h"
#include "nsStyleContext.h"
#include "nsIDocument.h"
#include "WritingModes.h"
using namespace mozilla;
@ -171,51 +172,34 @@ MapSinglePropertyInto(nsCSSProperty aProp,
static inline void
EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData)
{
uint8_t direction = aRuleData->mStyleContext->StyleVisibility()->mDirection;
bool ltr = direction == NS_STYLE_DIRECTION_LTR;
bool isBlock =
nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_BLOCK_AXIS);
bool isEnd =
nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_END_EDGE);
switch (aProperty) {
case eCSSProperty_margin_end:
aProperty = ltr ? eCSSProperty_margin_right : eCSSProperty_margin_left;
break;
case eCSSProperty_margin_start:
aProperty = ltr ? eCSSProperty_margin_left : eCSSProperty_margin_right;
break;
case eCSSProperty_padding_end:
aProperty = ltr ? eCSSProperty_padding_right : eCSSProperty_padding_left;
break;
case eCSSProperty_padding_start:
aProperty = ltr ? eCSSProperty_padding_left : eCSSProperty_padding_right;
break;
case eCSSProperty_border_end_color:
aProperty = ltr ? eCSSProperty_border_right_color :
eCSSProperty_border_left_color;
break;
case eCSSProperty_border_end_style:
aProperty = ltr ? eCSSProperty_border_right_style :
eCSSProperty_border_left_style;
break;
case eCSSProperty_border_end_width:
aProperty = ltr ? eCSSProperty_border_right_width :
eCSSProperty_border_left_width;
break;
case eCSSProperty_border_start_color:
aProperty = ltr ? eCSSProperty_border_left_color :
eCSSProperty_border_right_color;
break;
case eCSSProperty_border_start_style:
aProperty = ltr ? eCSSProperty_border_left_style :
eCSSProperty_border_right_style;
break;
case eCSSProperty_border_start_width:
aProperty = ltr ? eCSSProperty_border_left_width :
eCSSProperty_border_right_width;
break;
default:
NS_ABORT_IF_FALSE(nsCSSProps::PropHasFlags(aProperty,
CSS_PROPERTY_LOGICAL),
"unhandled logical property");
LogicalEdge edge = isEnd ? eLogicalEdgeEnd : eLogicalEdgeStart;
// We handle block axis logical properties separately to save a bit of
// work that the WritingMode constructor does that is unnecessary
// unless we have an inline axis property.
mozilla::css::Side side;
if (isBlock) {
uint8_t wm = aRuleData->mStyleContext->StyleVisibility()->mWritingMode;
side = WritingMode::PhysicalSideForBlockAxis(wm, edge);
} else {
WritingMode wm(aRuleData->mStyleContext);
side = wm.PhysicalSideForInlineAxis(edge);
}
nsCSSProperty shorthand = nsCSSProps::BoxShorthandFor(aProperty);
const nsCSSProperty* subprops = nsCSSProps::SubpropertyEntryFor(shorthand);
MOZ_ASSERT(subprops[0] != eCSSProperty_UNKNOWN &&
subprops[1] != eCSSProperty_UNKNOWN &&
subprops[2] != eCSSProperty_UNKNOWN &&
subprops[3] != eCSSProperty_UNKNOWN &&
subprops[4] == eCSSProperty_UNKNOWN,
"expected four-element subproperty table");
aProperty = subprops[side];
}
void

Просмотреть файл

@ -4542,24 +4542,78 @@ var gCSSProperties = {
function logical_box_prop_get_computed(cs, property)
{
var ltr = cs.getPropertyValue("direction") == "ltr";
// http://dev.w3.org/csswg/css-writing-modes-3/#logical-to-physical
// Use defaults for these two properties in case the vertical text
// pref (which they live behind) is turned off.
var writingMode = cs.getPropertyValue("writing-mode") || "horizontal-tb";
var textOrientation = cs.getPropertyValue("text-orientation") || "mixed";
var direction = cs.getPropertyValue("direction");
// We only need to distinguish between text-orientation values of
// sideways-left and {mixed,upright,sideways-right} (which we will
// call "others").
if (textOrientation == "sideways") {
// text-orientation does not contribute to the logical to physical
// mapping when writing-mode is horizontal-tb, so it doesn't matter
// that we convert it to sideways-left in that case.
textOrientation = writingMode == "vertical-rl" ? "others" : "sideways-left";
} else if (textOrientation != "sideways-left") {
textOrientation = "others";
}
// keys in blockMappings are writing-mode values
var blockMappings = {
"horizontal-tb": { "start": "top", "end": "bottom" },
"vertical-rl": { "start": "right", "end": "left" },
"vertical-lr": { "start": "left", "end": "right" },
};
// keys in inlineMappings are regular expressions that match against
// a {writing-mode,text-orientation,direction} triple as a space-
// separated string
var inlineMappings = {
"horizontal-tb \\S+ ltr": { "start": "left", "end": "right" },
"horizontal-tb \\S+ rtl": { "start": "right", "end": "left" },
"vertical-.. sideways-left ltr": { "start": "bottom", "end": "top" },
"vertical-.. sideways-left rtl": { "start": "top", "end": "bottom" },
"vertical-.. others ltr": { "start": "top", "end": "bottom" },
"vertical-.. others rtl": { "start": "bottom", "end": "top" },
};
var blockMapping = blockMappings[writingMode];
var inlineMapping;
// test each regular expression in inlineMappings against the
// {writing-mode,text-orientation,direction} triple
var key = `${writingMode} ${textOrientation} ${direction}`;
for (var k in inlineMappings) {
if (new RegExp(k).test(key)) {
inlineMapping = inlineMappings[k];
break;
}
}
if (!blockMapping || !inlineMapping) {
throw "Unexpected writing mode property values";
}
function physicalize(aProperty, aMapping, aLogicalPrefix) {
for (var logicalSide in aMapping) {
var physicalSide = aMapping[logicalSide];
logicalSide = aLogicalPrefix + logicalSide;
aProperty = aProperty.replace(logicalSide, physicalSide);
}
return aProperty;
}
if (/^-moz-/.test(property)) {
property = property.substring(5);
if (ltr) {
property = property.replace("-start", "-left")
.replace("-end", "-right");
} else {
property = property.replace("-start", "-right")
.replace("-end", "-left");
}
} else if (/-inline-(start|end)/.test(property)) {
if (ltr) {
property = property.replace("-inline-start", "-left")
.replace("-inline-end", "-right");
} else {
property = property.replace("-inline-start", "-right")
.replace("-inline-end", "-left");
}
property = physicalize(property.substring(5), inlineMapping, "");
} else if (/-(block|inline)-(start|end)/.test(property)) {
property = physicalize(property, blockMapping, "block-");
property = physicalize(property, inlineMapping, "inline-");
} else {
throw "Unexpected property";
}