Bug 271586 – Implement CSS3 column-rule-*. r+sr=roc,dbaron

This commit is contained in:
Michael Ventnor 2008-07-19 12:38:25 +02:00
parent f47f10ed4a
commit 8aeed81515
26 changed files with 367 additions and 17 deletions

View File

@ -406,7 +406,7 @@ interface nsIDOMCSS2Properties : nsISupports
// raises(DOMException) on setting
};
[scriptable, uuid(f1781ae4-00e6-4751-8698-2925f925fd76)]
[scriptable, uuid(5d8aab68-445b-4675-8661-8d722dbcb721)]
interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties
{
/* Non-DOM 2 extensions */
@ -600,4 +600,15 @@ interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties
attribute DOMString MozBorderImage;
// raises(DOMException) on setting
attribute DOMString MozColumnRule;
// raises(DOMException) on setting
attribute DOMString MozColumnRuleWidth;
// raises(DOMException) on setting
attribute DOMString MozColumnRuleStyle;
// raises(DOMException) on setting
attribute DOMString MozColumnRuleColor;
// raises(DOMException) on setting
};

View File

@ -49,6 +49,8 @@
#include "nsStyleConsts.h"
#include "nsCOMPtr.h"
#include "nsLayoutUtils.h"
#include "nsDisplayList.h"
#include "nsCSSRendering.h"
class nsColumnSetFrame : public nsHTMLContainerFrame {
public:
@ -96,6 +98,10 @@ public:
virtual nsIAtom* GetType() const;
virtual void PaintColumnRule(nsIRenderingContext* aCtx,
const nsRect& aDirtyRect,
const nsPoint& aPt);
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const {
return MakeFrameName(NS_LITERAL_STRING("ColumnSet"), aResult);
@ -192,6 +198,85 @@ nsColumnSetFrame::GetType() const
return nsGkAtoms::columnSetFrame;
}
static void
PaintColumnRule(nsIFrame* aFrame, nsIRenderingContext* aCtx,
const nsRect& aDirtyRect, nsPoint aPt)
{
static_cast<nsColumnSetFrame*>(aFrame)->PaintColumnRule(aCtx, aDirtyRect, aPt);
}
void
nsColumnSetFrame::PaintColumnRule(nsIRenderingContext* aCtx,
const nsRect& aDirtyRect,
const nsPoint& aPt)
{
nsIFrame* child = mFrames.FirstChild();
if (!child)
return; // no columns
nsIFrame* nextSibling = child->GetNextSibling();
if (!nextSibling)
return; // 1 column only - this means no gap to draw on
PRBool isRTL = GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
const nsStyleColumn* colStyle = GetStyleColumn();
PRUint8 ruleStyle;
// Per spec, inset => ridge and outset => groove
if (colStyle->mColumnRuleStyle == NS_STYLE_BORDER_STYLE_INSET)
ruleStyle = NS_STYLE_BORDER_STYLE_RIDGE;
else if (colStyle->mColumnRuleStyle == NS_STYLE_BORDER_STYLE_OUTSET)
ruleStyle = NS_STYLE_BORDER_STYLE_GROOVE;
else
ruleStyle = colStyle->mColumnRuleStyle;
nsPresContext* presContext = PresContext();
nscoord ruleWidth = colStyle->GetComputedColumnRuleWidth();
if (!ruleWidth)
return;
nscolor ruleColor;
if (colStyle->mColumnRuleColorIsForeground)
ruleColor = GetStyleColor()->mColor;
else
ruleColor = colStyle->mColumnRuleColor;
// In order to re-use a large amount of code, we treat the column rule as a border.
// We create a new border style object and fill in all the details of the column rule as
// the left border. PaintBorder() does all the rendering for us, so we not
// only save an enormous amount of code but we'll support all the line styles that
// we support on borders!
nsStyleBorder border(presContext);
border.SetBorderWidth(NS_SIDE_LEFT, ruleWidth);
border.SetBorderStyle(NS_SIDE_LEFT, ruleStyle);
border.SetBorderColor(NS_SIDE_LEFT, ruleColor);
while (nextSibling) {
// The frame tree goes RTL in RTL
nsIFrame* leftSibling = isRTL ? nextSibling : child;
nsIFrame* rightSibling = isRTL ? child : nextSibling;
// Each child frame's position coordinates is actually relative to this nsColumnSetFrame.
// linePt will be at the top-left edge to paint the line.
nsPoint edgeOfLeftSibling = leftSibling->GetRect().TopRight() + aPt;
nsPoint edgeOfRightSibling = rightSibling->GetRect().TopLeft() + aPt;
nsPoint linePt((edgeOfLeftSibling.x + edgeOfRightSibling.x - ruleWidth) / 2,
edgeOfLeftSibling.y);
nscoord minimumHeight = PR_MIN(nsLayoutUtils::CalculateContentBottom(child),
nsLayoutUtils::CalculateContentBottom(nextSibling));
nsRect lineRect(linePt, nsSize(ruleWidth, minimumHeight));
nsCSSRendering::PaintBorder(presContext, *aCtx, this, aDirtyRect,
lineRect, border, GetStyleContext(),
// Remember, we only have the "left" "border". Skip everything else
(1 << NS_SIDE_TOP | 1 << NS_SIDE_RIGHT | 1 << NS_SIDE_BOTTOM));
child = nextSibling;
nextSibling = nextSibling->GetNextSibling();
}
}
NS_IMETHODIMP
nsColumnSetFrame::SetInitialChildList(nsIAtom* aListName,
nsIFrame* aChildList)
@ -925,6 +1010,9 @@ nsColumnSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) {
nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
NS_ENSURE_SUCCESS(rv, rv);
aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
nsDisplayGeneric(this, ::PaintColumnRule, "ColumnRule"));
nsIFrame* kid = mFrames.FirstChild();
// Our children won't have backgrounds so it doesn't matter where we put them.

View File

@ -0,0 +1,2 @@
<div style="position: absolute; top: 20px; left: 517px; width: 6px; background-color: red; height: 100px;"></div>
<div style="position: absolute; top: 20px; left: 20px; -moz-column-count:2; -moz-column-gap: 0px;"><div style="height:200px; width: 500px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.</div></div>

View File

@ -0,0 +1 @@
<div style="position: absolute; top: 20px; left: 20px; -moz-column-count:2; -moz-column-gap: 0px; -moz-column-rule: 6px red solid;"><div style="height:200px; width: 500px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.</div></div>

View File

@ -0,0 +1,4 @@
<div style="position: absolute; top: 20px; left: 317px; width: 6px; background-color: red; height: 50px;"></div>
<div style="position: absolute; top: 20px; left: 617px; width: 6px; background-color: red; height: 50px;"></div>
<div style="position: absolute; top: 20px; left: 917px; width: 6px; background-color: red; height: 50px;"></div>
<div style="position: absolute; top: 20px; left: 20px; -moz-column-count:4; -moz-column-gap: 0px;"><div style="height:200px; width: 300px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.</div></div>

View File

@ -0,0 +1 @@
<div style="position: absolute; top: 20px; left: 20px; -moz-column-count:4; -moz-column-gap: 0px; -moz-column-rule: 6px red solid;"><div style="height:200px; width: 300px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.</div></div>

View File

@ -0,0 +1 @@
<div style="-moz-column-count:2; -moz-column-gap: 3px; -moz-column-rule: 6px red solid;"><div style="height:100px; width: 300px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.</div></div>

View File

@ -0,0 +1,2 @@
<!-- Make sure no-one regresses line styles on column rules -->
<div style="-moz-column-count:2; -moz-column-gap: 3px; -moz-column-rule: 6px red dotted;"><div style="height:100px; width: 300px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.</div></div>

View File

@ -16,3 +16,6 @@
== column-balancing-002.html column-balancing-002.ref.html
== column-balancing-003.html column-balancing-000.ref.html
== column-balancing-004.html column-balancing-004.ref.html
== columnrule-basic.html columnrule-basic-ref.html
== columnrule-complex.html columnrule-complex-ref.html
!= columnrule-linestyles.html columnrule-linestyles-notref.html

View File

@ -237,6 +237,7 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
iProp == eCSSProperty_border_left_color_value ||
iProp == eCSSProperty_border_left_color_ltr_source ||
iProp == eCSSProperty_border_left_color_rtl_source ||
iProp == eCSSProperty__moz_column_rule_color ||
iProp == eCSSProperty_outline_color) {
if (ShouldIgnoreColors(aRuleData)) {
if (iProp == eCSSProperty_background_color) {

View File

@ -578,6 +578,7 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty,
case eCSSProperty_border_left:
case eCSSProperty_border_start:
case eCSSProperty_border_end:
case eCSSProperty__moz_column_rule:
case eCSSProperty_outline: {
const nsCSSProperty* subprops =
nsCSSProps::SubpropertyEntryFor(aProperty);
@ -1123,6 +1124,7 @@ nsCSSDeclaration::ToString(nsAString& aString) const
PRInt32 bgColor = 0, bgImage = 0, bgRepeat = 0, bgAttachment = 0;
PRInt32 bgPosition = 0;
PRInt32 overflowX = 0, overflowY = 0;
PRInt32 columnRuleWidth = 0, columnRuleStyle = 0, columnRuleColor = 0;
PRUint32 borderPropertiesSet = 0, finalBorderPropertiesToSet = 0;
#ifdef MOZ_SVG
PRInt32 markerEnd = 0, markerMid = 0, markerStart = 0;
@ -1207,6 +1209,10 @@ nsCSSDeclaration::ToString(nsAString& aString) const
case eCSSProperty_overflow_x: overflowX = index+1; break;
case eCSSProperty_overflow_y: overflowY = index+1; break;
case eCSSProperty__moz_column_rule_width: columnRuleWidth = index+1; break;
case eCSSProperty__moz_column_rule_style: columnRuleStyle = index+1; break;
case eCSSProperty__moz_column_rule_color: columnRuleColor = index+1; break;
#ifdef MOZ_SVG
case eCSSProperty_marker_end: markerEnd = index+1; break;
case eCSSProperty_marker_mid: markerMid = index+1; break;
@ -1285,6 +1291,13 @@ nsCSSDeclaration::ToString(nsAString& aString) const
#ifdef MOZ_SVG
TryMarkerShorthand(aString, markerEnd, markerMid, markerStart);
#endif
if (columnRuleColor && columnRuleStyle && columnRuleWidth) {
TryBorderSideShorthand(aString, eCSSProperty__moz_column_rule,
columnRuleWidth, columnRuleStyle, columnRuleColor);
columnRuleWidth = columnRuleStyle = columnRuleColor = 0;
}
// FIXME The order of the declarations should depend on the *-source
// properties.
if (borderStartWidth && borderStartStyle && borderStartColor &&
@ -1374,6 +1387,10 @@ nsCSSDeclaration::ToString(nsAString& aString) const
NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_marker_start, markerStart)
#endif
NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty__moz_column_rule_width, columnRuleWidth)
NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty__moz_column_rule_style, columnRuleStyle)
NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty__moz_column_rule_color, columnRuleColor)
case eCSSProperty_margin_left_ltr_source:
case eCSSProperty_margin_left_rtl_source:
case eCSSProperty_margin_right_ltr_source:

View File

@ -3749,6 +3749,11 @@ static const nsCSSProperty kBorderEndIDs[] = {
eCSSProperty_border_end_style,
eCSSProperty_border_end_color
};
static const nsCSSProperty kColumnRuleIDs[] = {
eCSSProperty__moz_column_rule_width,
eCSSProperty__moz_column_rule_style,
eCSSProperty__moz_column_rule_color
};
PRBool CSSParserImpl::ParseEnum(nsresult& aErrorCode, nsCSSValue& aValue,
const PRInt32 aKeywordTable[])
@ -4499,6 +4504,8 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode,
case eCSSProperty_clip:
return ParseRect(mTempData.mDisplay.mClip, aErrorCode,
eCSSProperty_clip);
case eCSSProperty__moz_column_rule:
return ParseBorderSide(aErrorCode, kColumnRuleIDs, PR_FALSE);
case eCSSProperty_content:
return ParseContent(aErrorCode);
case eCSSProperty_counter_increment:
@ -4681,7 +4688,9 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
case eCSSProperty_border_top:
case eCSSProperty_border_width:
case eCSSProperty__moz_border_radius:
case eCSSProperty_box_shadow:
case eCSSProperty_clip:
case eCSSProperty__moz_column_rule:
case eCSSProperty_content:
case eCSSProperty_counter_increment:
case eCSSProperty_counter_reset:
@ -4707,7 +4716,6 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
case eCSSProperty_quotes:
case eCSSProperty_size:
case eCSSProperty_text_shadow:
case eCSSProperty_box_shadow:
case eCSSProperty_COUNT:
#ifdef MOZ_SVG
case eCSSProperty_fill:
@ -4782,6 +4790,7 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
case eCSSProperty_border_right_color_value: // for internal use
case eCSSProperty_border_start_color_value: // for internal use
case eCSSProperty_border_top_color:
case eCSSProperty__moz_column_rule_color:
return ParseVariant(aErrorCode, aValue, VARIANT_HCK,
nsCSSProps::kBorderColorKTable);
case eCSSProperty_border_bottom_style:
@ -4790,6 +4799,7 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
case eCSSProperty_border_right_style_value: // for internal use
case eCSSProperty_border_start_style_value: // for internal use
case eCSSProperty_border_top_style:
case eCSSProperty__moz_column_rule_style:
return ParseVariant(aErrorCode, aValue, VARIANT_HOK,
nsCSSProps::kBorderStyleKTable);
case eCSSProperty_border_bottom_width:
@ -4798,6 +4808,7 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
case eCSSProperty_border_right_width_value: // for internal use
case eCSSProperty_border_start_width_value: // for internal use
case eCSSProperty_border_top_width:
case eCSSProperty__moz_column_rule_width:
return ParsePositiveVariant(aErrorCode, aValue, VARIANT_HKL,
nsCSSProps::kBorderWidthKTable);
case eCSSProperty__moz_border_radius_topLeft:

View File

@ -376,6 +376,10 @@ CSS_PROP_COLOR(color, color, Color, Color, mColor, eCSSType_Value, nsnull)
CSS_PROP_COLUMN(-moz-column-count, _moz_column_count, MozColumnCount, Column, mColumnCount, eCSSType_Value, nsnull)
CSS_PROP_COLUMN(-moz-column-width, _moz_column_width, MozColumnWidth, Column, mColumnWidth, eCSSType_Value, nsnull)
CSS_PROP_COLUMN(-moz-column-gap, _moz_column_gap, MozColumnGap, Column, mColumnGap, eCSSType_Value, nsnull)
CSS_PROP_SHORTHAND(-moz-column-rule, _moz_column_rule, MozColumnRule)
CSS_PROP_COLUMN(-moz-column-rule-color, _moz_column_rule_color, MozColumnRuleColor, Column, mColumnRuleColor, eCSSType_Value, nsnull)
CSS_PROP_COLUMN(-moz-column-rule-style, _moz_column_rule_style, MozColumnRuleStyle, Column, mColumnRuleStyle, eCSSType_Value, kBorderStyleKTable)
CSS_PROP_COLUMN(-moz-column-rule-width, _moz_column_rule_width, MozColumnRuleWidth, Column, mColumnRuleWidth, eCSSType_Value, kBorderWidthKTable)
CSS_PROP_CONTENT(content, content, Content, Content, mContent, eCSSType_ValueList, kContentKTable)
CSS_PROP_CONTENT(counter-increment, counter_increment, CounterIncrement, Content, mCounterIncrement, eCSSType_CounterData, nsnull) // XXX bug 137285
CSS_PROP_CONTENT(counter-reset, counter_reset, CounterReset, Content, mCounterReset, eCSSType_CounterData, nsnull) // XXX bug 137285

View File

@ -1602,6 +1602,13 @@ static const nsCSSProperty gOutlineSubpropTable[] = {
eCSSProperty_UNKNOWN
};
static const nsCSSProperty gMozColumnRuleSubpropTable[] = {
eCSSProperty__moz_column_rule_width,
eCSSProperty__moz_column_rule_style,
eCSSProperty__moz_column_rule_color,
eCSSProperty_UNKNOWN
};
static const nsCSSProperty gOverflowSubpropTable[] = {
eCSSProperty_overflow_x,
eCSSProperty_overflow_y,

View File

@ -568,6 +568,9 @@ struct nsCSSColumn : public nsCSSStruct {
nsCSSValue mColumnCount;
nsCSSValue mColumnWidth;
nsCSSValue mColumnGap;
nsCSSValue mColumnRuleColor;
nsCSSValue mColumnRuleWidth;
nsCSSValue mColumnRuleStyle;
private:
nsCSSColumn(const nsCSSColumn& aOther); // NOT IMPLEMENTED
};

View File

@ -612,6 +612,55 @@ nsComputedDOMStyle::GetColumnGap(nsIDOMCSSValue** aValue)
return CallQueryInterface(val, aValue);
}
nsresult
nsComputedDOMStyle::GetColumnRuleWidth(nsIDOMCSSValue** aValue)
{
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
if (!val)
return NS_ERROR_OUT_OF_MEMORY;
SetValueToCoord(val, GetStyleColumn()->GetComputedColumnRuleWidth());
return CallQueryInterface(val, aValue);
}
nsresult
nsComputedDOMStyle::GetColumnRuleStyle(nsIDOMCSSValue** aValue)
{
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
if (!val)
return NS_ERROR_OUT_OF_MEMORY;
const nsStyleColumn* column = GetStyleColumn();
if (column->mColumnRuleStyle == NS_STYLE_BORDER_STYLE_NONE) {
val->SetIdent(nsGkAtoms::none);
} else {
const nsAFlatCString& style =
nsCSSProps::ValueToKeyword(column->mColumnRuleStyle,
nsCSSProps::kBorderStyleKTable);
val->SetIdent(style);
}
return CallQueryInterface(val, aValue);
}
nsresult
nsComputedDOMStyle::GetColumnRuleColor(nsIDOMCSSValue** aValue)
{
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
if (!val)
return NS_ERROR_OUT_OF_MEMORY;
const nsStyleColumn* column = GetStyleColumn();
nscolor ruleColor;
if (column->mColumnRuleColorIsForeground) {
ruleColor = GetStyleColor()->mColor;
} else {
ruleColor = column->mColumnRuleColor;
}
SetToRGBAColor(val, ruleColor);
return CallQueryInterface(val, aValue);
}
nsresult
nsComputedDOMStyle::GetContent(nsIDOMCSSValue** aValue)
{
@ -3949,6 +3998,10 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(_moz_column_count, ColumnCount),
COMPUTED_STYLE_MAP_ENTRY(_moz_column_width, ColumnWidth),
COMPUTED_STYLE_MAP_ENTRY(_moz_column_gap, ColumnGap),
//// COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule, ColumnRule),
COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_color, ColumnRuleColor),
COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_width, ColumnRuleWidth),
COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_style, ColumnRuleStyle),
COMPUTED_STYLE_MAP_ENTRY(float_edge, FloatEdge),
COMPUTED_STYLE_MAP_ENTRY(force_broken_image_icon, ForceBrokenImageIcon),
COMPUTED_STYLE_MAP_ENTRY(image_region, ImageRegion),

View File

@ -284,6 +284,9 @@ private:
nsresult GetColumnCount(nsIDOMCSSValue** aValue);
nsresult GetColumnWidth(nsIDOMCSSValue** aValue);
nsresult GetColumnGap(nsIDOMCSSValue** aValue);
nsresult GetColumnRuleWidth(nsIDOMCSSValue** aValue);
nsresult GetColumnRuleStyle(nsIDOMCSSValue** aValue);
nsresult GetColumnRuleColor(nsIDOMCSSValue** aValue);
#ifdef MOZ_SVG
/* SVG properties */

View File

@ -1703,7 +1703,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
case eStyleStruct_Column:
{
nsStyleColumn* column = new (mPresContext) nsStyleColumn();
nsStyleColumn* column = new (mPresContext) nsStyleColumn(mPresContext);
if (NS_LIKELY(column != nsnull)) {
aContext->SetStyle(eStyleStruct_Column, column);
}
@ -4712,7 +4712,7 @@ nsRuleNode::ComputeColumnData(void* aStartStruct,
nsRuleNode* aHighestNode,
const RuleDetail aRuleDetail, PRBool aInherited)
{
COMPUTE_START_RESET(Column, (), column, parent, Column, columnData)
COMPUTE_START_RESET(Column, (mPresContext), column, parent, Column, columnData)
// column-width: length, auto, inherit
SetCoord(columnData.mColumnWidth,
@ -4739,6 +4739,61 @@ nsRuleNode::ComputeColumnData(void* aStartStruct,
column->mColumnCount = parent->mColumnCount;
}
// column-rule-width: length, enum, inherit
const nsCSSValue& widthValue = columnData.mColumnRuleWidth;
if (eCSSUnit_Initial == widthValue.GetUnit()) {
column->SetColumnRuleWidth(
(mPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM]);
}
else if (eCSSUnit_Enumerated == widthValue.GetUnit()) {
NS_ASSERTION(widthValue.GetIntValue() == NS_STYLE_BORDER_WIDTH_THIN ||
widthValue.GetIntValue() == NS_STYLE_BORDER_WIDTH_MEDIUM ||
widthValue.GetIntValue() == NS_STYLE_BORDER_WIDTH_THICK,
"Unexpected enum value");
column->SetColumnRuleWidth(
(mPresContext->GetBorderWidthTable())[widthValue.GetIntValue()]);
}
else if (eCSSUnit_Inherit == widthValue.GetUnit()) {
column->SetColumnRuleWidth(parent->GetComputedColumnRuleWidth());
inherited = PR_TRUE;
}
else if (widthValue.IsLengthUnit()) {
column->SetColumnRuleWidth(CalcLength(widthValue, aContext,
mPresContext, inherited));
}
// column-rule-style: enum, none, inherit
const nsCSSValue& styleValue = columnData.mColumnRuleStyle;
if (eCSSUnit_Enumerated == styleValue.GetUnit()) {
column->mColumnRuleStyle = styleValue.GetIntValue();
}
else if (eCSSUnit_None == styleValue.GetUnit() ||
eCSSUnit_Initial == styleValue.GetUnit()) {
column->mColumnRuleStyle = NS_STYLE_BORDER_STYLE_NONE;
}
else if (eCSSUnit_Inherit == styleValue.GetUnit()) {
inherited = PR_TRUE;
column->mColumnRuleStyle = parent->mColumnRuleStyle;
}
// column-rule-color: color, inherit
const nsCSSValue& colorValue = columnData.mColumnRuleColor;
if (eCSSUnit_Inherit == colorValue.GetUnit()) {
inherited = PR_TRUE;
column->mColumnRuleColorIsForeground = PR_FALSE;
if (parent->mColumnRuleColorIsForeground) {
column->mColumnRuleColor = parentContext->GetStyleColor()->mColor;
} else {
column->mColumnRuleColor = parent->mColumnRuleColor;
}
}
else if (eCSSUnit_Initial == colorValue.GetUnit()) {
column->mColumnRuleColorIsForeground = PR_TRUE;
}
else if (SetColor(colorValue, 0, mPresContext, aContext, column->mColumnRuleColor, inherited)) {
column->mColumnRuleColorIsForeground = PR_FALSE;
}
COMPUTE_END_RESET(Column, column)
}

View File

@ -816,7 +816,11 @@ void nsStyleContext::DumpRegressionData(nsPresContext* aPresContext, FILE* out,
column->mColumnWidth.ToString(str);
fprintf(out, "%s ", NS_ConvertUTF16toUTF8(str).get());
column->mColumnGap.ToString(str);
fprintf(out, "%s", NS_ConvertUTF16toUTF8(str).get());
fprintf(out, "%s ", NS_ConvertUTF16toUTF8(str).get());
fprintf(out, "%d %d %ld",
(int)column->GetComputedColumnRuleWidth(),
(int)column->mColumnRuleStyle,
(long)column->mColumnRuleColor);
fprintf(out, "\" />\n");
// XUL

View File

@ -658,11 +658,18 @@ nsChangeHint nsStyleXUL::MaxDifference()
// --------------------
// nsStyleColumn
//
nsStyleColumn::nsStyleColumn()
{
nsStyleColumn::nsStyleColumn(nsPresContext* aPresContext)
{
mColumnCount = NS_STYLE_COLUMN_COUNT_AUTO;
mColumnWidth.SetAutoValue();
mColumnGap.SetNormalValue();
mColumnRuleWidth = (aPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
mColumnRuleStyle = NS_STYLE_BORDER_STYLE_NONE;
mColumnRuleColor = NS_RGB(0, 0, 0);
mColumnRuleColorIsForeground = PR_TRUE;
mTwipsPerPixel = aPresContext->AppUnitsPerDevPixel();
}
nsStyleColumn::~nsStyleColumn()
@ -682,11 +689,17 @@ nsChangeHint nsStyleColumn::CalcDifference(const nsStyleColumn& aOther) const
// We force column count changes to do a reframe, because it's tricky to handle
// some edge cases where the column count gets smaller and content overflows.
// XXX not ideal
return nsChangeHint_ReconstructFrame;
return NS_STYLE_HINT_FRAMECHANGE;
if (mColumnWidth != aOther.mColumnWidth ||
mColumnGap != aOther.mColumnGap)
return nsChangeHint_ReflowFrame;
return NS_STYLE_HINT_REFLOW;
if (GetComputedColumnRuleWidth() != aOther.GetComputedColumnRuleWidth() ||
mColumnRuleStyle != aOther.mColumnRuleStyle ||
mColumnRuleColor != aOther.mColumnRuleColor ||
mColumnRuleColorIsForeground != aOther.mColumnRuleColorIsForeground)
return NS_STYLE_HINT_VISUAL;
return NS_STYLE_HINT_NONE;
}
@ -695,8 +708,7 @@ nsChangeHint nsStyleColumn::CalcDifference(const nsStyleColumn& aOther) const
/* static */
nsChangeHint nsStyleColumn::MaxDifference()
{
return NS_CombineHint(nsChangeHint_ReconstructFrame,
nsChangeHint_ReflowFrame);
return NS_STYLE_HINT_FRAMECHANGE;
}
#endif

View File

@ -398,6 +398,13 @@ class nsCSSShadowArray {
((l) > 0) ? PR_MAX( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
PR_MIN(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
// Returns if the given border style type is visible or not
static PRBool IsVisibleBorderStyle(PRUint8 aStyle)
{
return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
}
struct nsStyleBorder {
nsStyleBorder(nsPresContext* aContext);
nsStyleBorder(const nsStyleBorder& aBorder);
@ -445,9 +452,7 @@ struct nsStyleBorder {
// HasVisibleStyle will be false even though there *is* a border.
PRBool HasVisibleStyle(PRUint8 aSide)
{
PRUint8 style = GetBorderStyle(aSide);
return (style != NS_STYLE_BORDER_STYLE_NONE &&
style != NS_STYLE_BORDER_STYLE_HIDDEN);
return IsVisibleBorderStyle(GetBorderStyle(aSide));
}
// aBorderWidth is in twips
@ -1304,7 +1309,7 @@ struct nsStyleXUL {
};
struct nsStyleColumn {
nsStyleColumn();
nsStyleColumn(nsPresContext* aPresContext);
nsStyleColumn(const nsStyleColumn& aSource);
~nsStyleColumn();
@ -1324,6 +1329,22 @@ struct nsStyleColumn {
PRUint32 mColumnCount; // [reset] see nsStyleConsts.h
nsStyleCoord mColumnWidth; // [reset]
nsStyleCoord mColumnGap; // [reset] coord
nscolor mColumnRuleColor; // [reset]
PRUint8 mColumnRuleStyle; // [reset]
PRPackedBool mColumnRuleColorIsForeground;
void SetColumnRuleWidth(nscoord aWidth) {
mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
}
nscoord GetComputedColumnRuleWidth() const {
return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
}
protected:
nscoord mColumnRuleWidth; // [reset] coord
nscoord mTwipsPerPixel;
};
#ifdef MOZ_SVG

View File

@ -153,7 +153,7 @@ STYLE_STRUCT_RESET(SVGReset,nsnull, ())
STYLE_STRUCT_TEST_CODE(} else {)
STYLE_STRUCT_TEST_CODE( NS_ASSERTION(STYLE_STRUCT_TEST == 22, "out of range");)
#endif
STYLE_STRUCT_RESET(Column, nsnull, ())
STYLE_STRUCT_RESET(Column, nsnull, (SSARG_PRESCONTEXT))
STYLE_STRUCT_TEST_CODE(})
#ifdef UNDEF_STYLE_STRUCT_INHERITED

View File

@ -361,6 +361,42 @@ var gCSSProperties = {
other_values: [ "15px", "50%" ],
invalid_values: [ "20", "-1px" ]
},
"-moz-column-rule-width": {
domProp: "MozColumnRuleWidth",
inherited: false,
type: CSS_TYPE_LONGHAND,
prerequisites: { "-moz-column-rule-style": "solid" },
initial_values: [ "medium" ],
other_values: [ "thin", "15px" ],
invalid_values: [ "20", "-1px", "red", "50%" ]
},
"-moz-column-rule-style": {
domProp: "MozColumnRuleStyle",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "solid", "hidden", "ridge", "groove", "inset", "outset", "double", "dotted", "dashed" ],
invalid_values: [ "20", "foo" ]
},
"-moz-column-rule-color": {
domProp: "MozColumnRuleColor",
inherited: false,
type: CSS_TYPE_LONGHAND,
prerequisites: { "color": "green" },
initial_values: [ "currentColor" ],
other_values: [ "red", "blue", "#ffff00" ],
invalid_values: [ ]
},
"-moz-column-rule": {
domProp: "MozColumnRule",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
prerequisites: { "color": "green" },
subproperties: [ "-moz-column-rule-width", "-moz-column-rule-style", "-moz-column-rule-color" ],
initial_values: [ "medium none currentColor" ],
other_values: [ "2px blue solid", "red dotted 1px", "ridge 4px orange" ],
invalid_values: [ "2px 3px 4px red", "dotted dashed", "5px dashed green 3px" ]
},
"-moz-float-edge": {
domProp: "MozFloatEdge",
inherited: false,

View File

@ -9,7 +9,7 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style type="text/css">
#one, #three { background: blue; color: yellow; border: thin solid red; }
#one, #three { background: blue; color: yellow; border: thin solid red; -moz-column-rule: 2px solid green; }
#two { background: transparent; border: thin solid; }
#five, #six {border: thick solid red; -moz-border-start-color:green; -moz-border-end-color:blue}
@ -87,6 +87,8 @@ function part1()
"border-left-color applies");
is(cs1.borderBottomColor, cs3.borderBottomColor,
"border-top-color applies");
is(cs1.MozColumnRuleColor, cs3.MozColumnRuleColor,
"-moz-column-rule-color applies");
isnot(cs5.borderRightColor, cs2.borderRightColor,
"-moz-border-end-color applies");
isnot(cs5.borderLeftColor, cs2.borderLeftColor,
@ -106,6 +108,8 @@ function part1()
"border-left-color applies");
isnot(cs3.borderBottomColor, cs4.borderBottomColor,
"border-bottom-color applies");
isnot(cs2.MozColumnRuleColor, cs3.MozColumnRuleColor,
"-moz-column-rule-color applies");
transparentBackgroundColor = cs2.backgroundColor;
inputBackgroundColor = cs4.backgroundColor;
inputColor = cs4.color;
@ -137,6 +141,8 @@ function part2()
"-moz-border-end-color is blocked");
is(cs1.borderBottomColor, cs2.borderBottomColor,
"border-bottom-color is blocked");
is(cs2.MozColumnRuleColor, cs3.MozColumnRuleColor,
"-moz-column-rule-color is blocked");
is(cs3.backgroundColor, cs1.backgroundColor, "background-color transparency preserved (opaque)");
is(cs3.color, cs4.color, "color is blocked");
is(cs3.borderTopColor, cs4.borderTopColor, "border-top-color is blocked");

View File

@ -30,6 +30,7 @@ var gKnownFails = {
"-moz-border-end": true,
"-moz-border-radius": true,
"-moz-border-start": true,
"-moz-column-rule": true,
"-moz-outline-radius": true,
"background": true,
"border": true,
@ -53,6 +54,7 @@ var gKnownFails2 = {
"-moz-border-end": true,
"-moz-border-radius": true,
"-moz-border-start": true,
"-moz-column-rule": true,
"-moz-outline-radius": true,
"background": true,
"border": true,

View File

@ -30,6 +30,7 @@ var gKnownFails = {
"-moz-border-end": true,
"-moz-border-radius": true,
"-moz-border-start": true,
"-moz-column-rule": true,
"-moz-outline-radius": true,
"background": true,
"border": true,
@ -53,6 +54,7 @@ var gKnownFails2 = {
"-moz-border-end": true,
"-moz-border-radius": true,
"-moz-border-start": true,
"-moz-column-rule": true,
"-moz-outline-radius": true,
"background": true,
"border": true,