From d013f547e1e774d37a73767b9b02f7ac926d4369 Mon Sep 17 00:00:00 2001 From: Michael Ventnor Date: Tue, 23 Aug 2011 14:18:22 +1000 Subject: [PATCH] Bug 446569 - Implement prefixed CSS3 columns shorthand r=dbaron --- dom/interfaces/css/nsIDOMCSS2Properties.idl | 5 ++- layout/style/Declaration.cpp | 9 ++++ layout/style/nsCSSParser.cpp | 49 +++++++++++++++++++++ layout/style/nsCSSPropList.h | 5 +++ layout/style/nsCSSProperty.h | 3 +- layout/style/nsCSSProps.cpp | 6 +++ layout/style/test/property_database.js | 10 +++++ 7 files changed, 85 insertions(+), 2 deletions(-) diff --git a/dom/interfaces/css/nsIDOMCSS2Properties.idl b/dom/interfaces/css/nsIDOMCSS2Properties.idl index d34a97920d4..f3b4c6cf036 100644 --- a/dom/interfaces/css/nsIDOMCSS2Properties.idl +++ b/dom/interfaces/css/nsIDOMCSS2Properties.idl @@ -51,7 +51,7 @@ * http://www.w3.org/TR/DOM-Level-2-Style */ -[builtinclass, scriptable, uuid(10f43750-b379-11e0-aff2-0800200c9a66)] +[builtinclass, scriptable, uuid(286466f1-4246-4574-afdb-2f8a03ad7cc8)] interface nsIDOMCSS2Properties : nsISupports { attribute DOMString background; @@ -657,6 +657,9 @@ interface nsIDOMCSS2Properties : nsISupports attribute DOMString MozBorderImage; // raises(DOMException) on setting + attribute DOMString MozColumns; + // raises(DOMException) on setting + attribute DOMString MozColumnRule; // raises(DOMException) on setting diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 291db23e307..c52eb2d7dbc 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -769,6 +769,15 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const AppendValueToString(eCSSProperty_marker_end, aValue); break; } + case eCSSProperty__moz_columns: { + // Two values, column-count and column-width, separated by a space. + const nsCSSProperty* subprops = + nsCSSProps::SubpropertyEntryFor(aProperty); + AppendValueToString(subprops[0], aValue); + aValue.Append(PRUnichar(' ')); + AppendValueToString(subprops[1], aValue); + break; + } default: NS_ABORT_IF_FALSE(false, "no other shorthands"); break; diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 1dd924e35a6..f72950e63e8 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -492,6 +492,7 @@ protected: // for 'clip' and '-moz-image-region' PRBool ParseRect(nsCSSProperty aPropID); + PRBool ParseColumns(); PRBool ParseContent(); PRBool ParseCounterData(nsCSSProperty aPropID); PRBool ParseCursor(); @@ -5492,6 +5493,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID) case eCSSProperty_clip: return ParseRect(eCSSProperty_clip); + case eCSSProperty__moz_columns: + return ParseColumns(); case eCSSProperty__moz_column_rule: return ParseBorderSide(kColumnRuleIDs, PR_FALSE); case eCSSProperty_content: @@ -5587,6 +5590,10 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue, return ParseVariant(aValue, VARIANT_NONE | VARIANT_INHERIT, nsnull); } + if (aPropID == eCSSPropertyExtra_x_auto_value) { + return ParseVariant(aValue, VARIANT_AUTO | VARIANT_INHERIT, nsnull); + } + if (aPropID < 0 || aPropID >= eCSSProperty_COUNT_no_shorthands) { NS_ABORT_IF_FALSE(PR_FALSE, "not a single value property"); return PR_FALSE; @@ -6846,6 +6853,48 @@ CSSParserImpl::ParseRect(nsCSSProperty aPropID) return PR_TRUE; } +PRBool +CSSParserImpl::ParseColumns() +{ + // We use a similar "fake value" hack to ParseListStyle, because + // "auto" is acceptable for both column-count and column-width. + // If the fake "auto" value is found, and one of the real values isn't, + // that means the fake auto value is meant for the real value we didn't + // find. + static const nsCSSProperty columnIDs[] = { + eCSSPropertyExtra_x_auto_value, + eCSSProperty__moz_column_count, + eCSSProperty__moz_column_width + }; + const PRInt32 numProps = NS_ARRAY_LENGTH(columnIDs); + + nsCSSValue values[numProps]; + PRInt32 found = ParseChoice(values, columnIDs, numProps); + if (found < 1 || !ExpectEndProperty()) { + return PR_FALSE; + } + if ((found & (1|2|4)) == (1|2|4) && + values[0].GetUnit() == eCSSUnit_Auto) { + // We filled all 3 values, which is invalid + return PR_FALSE; + } + + if ((found & 2) == 0) { + // Provide auto column-count + values[1].SetAutoValue(); + } + if ((found & 4) == 0) { + // Provide auto column-width + values[2].SetAutoValue(); + } + + // Start at index 1 to skip the fake auto value. + for (PRInt32 index = 1; index < numProps; index++) { + AppendValue(columnIDs[index], values[index]); + } + return PR_TRUE; +} + #define VARIANT_CONTENT (VARIANT_STRING | VARIANT_URL | VARIANT_COUNTER | VARIANT_ATTR | \ VARIANT_KEYWORD) PRBool diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index bdd1bce579c..7f538c5a7d3 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1239,6 +1239,11 @@ CSS_PROP_COLOR( nsnull, offsetof(nsStyleColor, mColor), eStyleAnimType_Color) +CSS_PROP_SHORTHAND( + -moz-columns, + _moz_columns, + CSS_PROP_DOMPROP_PREFIXED(Columns), + CSS_PROPERTY_PARSE_FUNCTION) CSS_PROP_COLUMN( -moz-column-count, _moz_column_count, diff --git a/layout/style/nsCSSProperty.h b/layout/style/nsCSSProperty.h index be09eadaf80..043d8ff9de7 100644 --- a/layout/style/nsCSSProperty.h +++ b/layout/style/nsCSSProperty.h @@ -76,7 +76,8 @@ enum nsCSSProperty { eCSSPropertyExtra_all_properties, // Extra dummy values for nsCSSParser internal use. - eCSSPropertyExtra_x_none_value + eCSSPropertyExtra_x_none_value, + eCSSPropertyExtra_x_auto_value }; // The "descriptors" that can appear in a @font-face rule. diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 2116bf2479a..7a1df69f496 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -1968,6 +1968,12 @@ static const nsCSSProperty gOutlineSubpropTable[] = { eCSSProperty_UNKNOWN }; +static const nsCSSProperty gColumnsSubpropTable[] = { + eCSSProperty__moz_column_count, + eCSSProperty__moz_column_width, + eCSSProperty_UNKNOWN +}; + static const nsCSSProperty gColumnRuleSubpropTable[] = { // nsCSSDeclaration.cpp outputs the subproperties in this order. // It also depends on the color being third. diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 66ecd88ae75..2d5fcde568f 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -472,6 +472,16 @@ var gCSSProperties = { other_values: [ "border-box", "padding-box" ], invalid_values: [ "margin-box", "content", "padding", "border", "margin" ] }, + "-moz-columns": { + domProp: "MozColumns", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ "-moz-column-count", "-moz-column-width" ], + initial_values: [ "auto", "auto auto" ], + other_values: [ "3", "20px", "2 10px", "10px 2", "2 auto", "auto 2", "auto 50px", "50px auto" ], + invalid_values: [ "5%", "-1px", "-1", "3 5", "10px 4px", "10 2px 5in", "30px -1", + "auto 3 5px", "5 auto 20px", "auto auto auto" ] + }, "-moz-column-count": { domProp: "MozColumnCount", inherited: false,