Bug 945584: Part 1 - Style support for scroll snapping attributes, r=cam

- Implemented style support for new attributes:
  - scroll-snap-type
  - scroll-snap-type-x
  - scroll-snap-type-y
  - scroll-snap-points-x
  - scroll-snap-points-y
  - scroll-snap-destination
  - scroll-snap-coordinate

--HG--
extra : rebase_source : 0a9a79c7d139a3c752f55395c697f23004d6ef34
This commit is contained in:
Kearwood Gilbert 2014-02-04 14:54:22 +13:00
Родитель c9764f7296
Коммит c9e0efb870
15 изменённых файлов: 601 добавлений и 10 удалений

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

@ -1080,6 +1080,19 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
AppendValueToString(subprops[0], aValue, aSerialization); AppendValueToString(subprops[0], aValue, aSerialization);
break; break;
} }
case eCSSProperty_scroll_snap_type: {
const nsCSSValue& xValue =
*data->ValueFor(eCSSProperty_scroll_snap_type_x);
const nsCSSValue& yValue =
*data->ValueFor(eCSSProperty_scroll_snap_type_y);
if (xValue == yValue) {
AppendValueToString(eCSSProperty_scroll_snap_type_x, aValue,
aSerialization);
}
// If scroll-snap-type-x and scroll-snap-type-y are not equal,
// we don't have a shorthand that can express. Bail.
break;
}
case eCSSProperty_all: case eCSSProperty_all:
// If we got here, then we didn't have all "inherit" or "initial" or // If we got here, then we didn't have all "inherit" or "initial" or
// "unset" values for all of the longhand property components of 'all'. // "unset" values for all of the longhand property components of 'all'.

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

@ -344,6 +344,7 @@ CSS_KEY(lowercase, lowercase)
CSS_KEY(ltr, ltr) CSS_KEY(ltr, ltr)
CSS_KEY(luminance, luminance) CSS_KEY(luminance, luminance)
CSS_KEY(luminosity, luminosity) CSS_KEY(luminosity, luminosity)
CSS_KEY(mandatory, mandatory)
CSS_KEY(manipulation, manipulation) CSS_KEY(manipulation, manipulation)
CSS_KEY(manual, manual) CSS_KEY(manual, manual)
CSS_KEY(margin-box, margin_box) CSS_KEY(margin-box, margin_box)
@ -417,6 +418,7 @@ CSS_KEY(progress, progress)
CSS_KEY(progressive, progressive) CSS_KEY(progressive, progressive)
CSS_KEY(proportional-nums, proportional_nums) CSS_KEY(proportional-nums, proportional_nums)
CSS_KEY(proportional-width, proportional_width) CSS_KEY(proportional-width, proportional_width)
CSS_KEY(proximity, proximity)
CSS_KEY(pt, pt) CSS_KEY(pt, pt)
CSS_KEY(px, px) CSS_KEY(px, px)
CSS_KEY(rad, rad) CSS_KEY(rad, rad)

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

@ -954,6 +954,10 @@ protected:
bool ParseMarker(); bool ParseMarker();
bool ParsePaintOrder(); bool ParsePaintOrder();
bool ParseAll(); bool ParseAll();
bool ParseScrollSnapType();
bool ParseScrollSnapPoints(nsCSSValue& aValue, nsCSSProperty aPropID);
bool ParseScrollSnapDestination(nsCSSValue& aValue);
bool ParseScrollSnapCoordinate(nsCSSValue& aValue);
/** /**
* Parses a variable value from a custom property declaration. * Parses a variable value from a custom property declaration.
@ -10131,6 +10135,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
return ParsePaintOrder(); return ParsePaintOrder();
case eCSSProperty_clip_path: case eCSSProperty_clip_path:
return ParseClipPath(); return ParseClipPath();
case eCSSProperty_scroll_snap_type:
return ParseScrollSnapType();
case eCSSProperty_all: case eCSSProperty_all:
return ParseAll(); return ParseAll();
default: default:
@ -10191,6 +10197,14 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
return ParseListStyleType(aValue); return ParseListStyleType(aValue);
case eCSSProperty_marks: case eCSSProperty_marks:
return ParseMarks(aValue); return ParseMarks(aValue);
case eCSSProperty_scroll_snap_points_x:
return ParseScrollSnapPoints(aValue, eCSSProperty_scroll_snap_points_x);
case eCSSProperty_scroll_snap_points_y:
return ParseScrollSnapPoints(aValue, eCSSProperty_scroll_snap_points_y);
case eCSSProperty_scroll_snap_destination:
return ParseScrollSnapDestination(aValue);
case eCSSProperty_scroll_snap_coordinate:
return ParseScrollSnapCoordinate(aValue);
case eCSSProperty_text_align: case eCSSProperty_text_align:
return ParseTextAlign(aValue); return ParseTextAlign(aValue);
case eCSSProperty_text_align_last: case eCSSProperty_text_align_last:
@ -10596,8 +10610,8 @@ CSSParserImpl::ParseBackgroundItem(CSSParserImpl::BackgroundParseState& aState)
return haveSomething; return haveSomething;
} }
// This function is very similar to ParseBackgroundPosition and // This function is very similar to ParseScrollSnapCoordinate,
// ParseBackgroundSize. // ParseBackgroundPosition, and ParseBackgroundSize.
bool bool
CSSParserImpl::ParseValueList(nsCSSProperty aPropID) CSSParserImpl::ParseValueList(nsCSSProperty aPropID)
{ {
@ -10672,7 +10686,8 @@ CSSParserImpl::ParseBackgroundRepeatValues(nsCSSValuePair& aValue)
return false; return false;
} }
// This function is very similar to ParseBackgroundList and ParseBackgroundSize. // This function is very similar to ParseScrollSnapCoordinate,
// ParseBackgroundList, and ParseBackgroundSize.
bool bool
CSSParserImpl::ParseBackgroundPosition() CSSParserImpl::ParseBackgroundPosition()
{ {
@ -10976,8 +10991,8 @@ CSSParserImpl::ParsePositionValue(nsCSSValue& aOut)
return true; return true;
} }
// This function is very similar to ParseBackgroundList and // This function is very similar to ParseScrollSnapCoordinate,
// ParseBackgroundPosition. // ParseBackgroundList, and ParseBackgroundPosition.
bool bool
CSSParserImpl::ParseBackgroundSize() CSSParserImpl::ParseBackgroundSize()
{ {
@ -15054,6 +15069,94 @@ CSSParserImpl::ParseVariableDeclaration(CSSVariableDeclarations::Type* aType,
return true; return true;
} }
bool
CSSParserImpl::ParseScrollSnapType()
{
nsCSSValue value;
if (!ParseVariant(value, VARIANT_HK, nsCSSProps::kScrollSnapTypeKTable)) {
return false;
}
AppendValue(eCSSProperty_scroll_snap_type_x, value);
AppendValue(eCSSProperty_scroll_snap_type_y, value);
return true;
}
bool
CSSParserImpl::ParseScrollSnapPoints(nsCSSValue& aValue, nsCSSProperty aPropID)
{
if (ParseVariant(aValue, VARIANT_INHERIT | VARIANT_NONE, nullptr)) {
return true;
}
if (!GetToken(true)) {
return false;
}
if (mToken.mType == eCSSToken_Function &&
nsCSSKeywords::LookupKeyword(mToken.mIdent) == eCSSKeyword_repeat) {
nsCSSValue lengthValue;
if (!ParseNonNegativeVariant(lengthValue,
VARIANT_LENGTH | VARIANT_PERCENT | VARIANT_CALC,
nullptr)) {
REPORT_UNEXPECTED(PEExpectedNonnegativeNP);
SkipUntil(')');
return false;
}
if (!ExpectSymbol(')', true)) {
REPORT_UNEXPECTED(PEExpectedCloseParen);
SkipUntil(')');
return false;
}
nsRefPtr<nsCSSValue::Array> functionArray =
aValue.InitFunction(eCSSKeyword_repeat, 1);
functionArray->Item(1) = lengthValue;
return true;
}
return false;
}
bool
CSSParserImpl::ParseScrollSnapDestination(nsCSSValue& aValue)
{
if (ParseVariant(aValue, VARIANT_INHERIT, nullptr)) {
return true;
}
nsCSSValue itemValue;
if (!ParsePositionValue(aValue)) {
REPORT_UNEXPECTED_TOKEN(PEExpectedPosition);
return false;
}
return true;
}
// This function is very similar to ParseBackgroundPosition, ParseBackgroundList
// and ParseBackgroundSize.
bool
CSSParserImpl::ParseScrollSnapCoordinate(nsCSSValue& aValue)
{
if (ParseVariant(aValue, VARIANT_INHERIT | VARIANT_NONE, nullptr)) {
return true;
}
nsCSSValue itemValue;
if (!ParsePositionValue(itemValue)) {
REPORT_UNEXPECTED_TOKEN(PEExpectedPosition);
return false;
}
nsCSSValueList* item = aValue.SetListValue();
for (;;) {
item->mValue = itemValue;
if (!ExpectSymbol(',', true)) {
break;
}
if (!ParsePositionValue(itemValue)) {
REPORT_UNEXPECTED_TOKEN(PEExpectedPosition);
return false;
}
item->mNext = new nsCSSValueList;
item = item->mNext;
}
return true;
}
bool bool
CSSParserImpl::ParseValueWithVariables(CSSVariableDeclarations::Type* aType, CSSParserImpl::ParseValueWithVariables(CSSVariableDeclarations::Type* aType,
bool* aDropBackslash, bool* aDropBackslash,

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

@ -3060,6 +3060,81 @@ CSS_PROP_DISPLAY(
kScrollBehaviorKTable, kScrollBehaviorKTable,
CSS_PROP_NO_OFFSET, CSS_PROP_NO_OFFSET,
eStyleAnimType_None) eStyleAnimType_None)
CSS_PROP_DISPLAY(
scroll-snap-type-x,
scroll_snap_type_x,
ScrollSnapTypeX,
CSS_PROPERTY_PARSE_VALUE,
"layout.css.scroll-snap.enabled",
VARIANT_HK,
kScrollSnapTypeKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_DISPLAY(
scroll-snap-type-y,
scroll_snap_type_y,
ScrollSnapTypeY,
CSS_PROPERTY_PARSE_VALUE,
"layout.css.scroll-snap.enabled",
VARIANT_HK,
kScrollSnapTypeKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_SHORTHAND(
scroll-snap-type,
scroll_snap_type,
ScrollSnapType,
CSS_PROPERTY_PARSE_FUNCTION,
"layout.css.scroll-snap.enabled")
CSS_PROP_DISPLAY(
scroll-snap-points-x,
scroll_snap_points_x,
ScrollSnapPointsX,
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
CSS_PROPERTY_STORES_CALC,
"layout.css.scroll-snap.enabled",
0,
nullptr,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_DISPLAY(
scroll-snap-points-y,
scroll_snap_points_y,
ScrollSnapPointsY,
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
CSS_PROPERTY_STORES_CALC,
"layout.css.scroll-snap.enabled",
0,
nullptr,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_DISPLAY(
scroll-snap-destination,
scroll_snap_destination,
ScrollSnapDestination,
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
CSS_PROPERTY_STORES_CALC,
"layout.css.scroll-snap.enabled",
0,
kBackgroundPositionKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_DISPLAY(
scroll-snap-coordinate,
scroll_snap_coordinate,
ScrollSnapCoordinate,
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
CSS_PROPERTY_STORES_CALC,
"layout.css.scroll-snap.enabled",
0,
kBackgroundPositionKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_BACKENDONLY( CSS_PROP_BACKENDONLY(
size, size,
size, size,

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

@ -1660,6 +1660,13 @@ const KTableValue nsCSSProps::kScrollBehaviorKTable[] = {
eCSSKeyword_UNKNOWN,-1 eCSSKeyword_UNKNOWN,-1
}; };
const KTableValue nsCSSProps::kScrollSnapTypeKTable[] = {
eCSSKeyword_none, NS_STYLE_SCROLL_SNAP_TYPE_NONE,
eCSSKeyword_mandatory, NS_STYLE_SCROLL_SNAP_TYPE_MANDATORY,
eCSSKeyword_proximity, NS_STYLE_SCROLL_SNAP_TYPE_PROXIMITY,
eCSSKeyword_UNKNOWN,-1
};
const KTableValue nsCSSProps::kStackSizingKTable[] = { const KTableValue nsCSSProps::kStackSizingKTable[] = {
eCSSKeyword_ignore, NS_STYLE_STACK_SIZING_IGNORE, eCSSKeyword_ignore, NS_STYLE_STACK_SIZING_IGNORE,
eCSSKeyword_stretch_to_fit, NS_STYLE_STACK_SIZING_STRETCH_TO_FIT, eCSSKeyword_stretch_to_fit, NS_STYLE_STACK_SIZING_STRETCH_TO_FIT,
@ -2593,6 +2600,12 @@ static const nsCSSProperty gMozTransformSubpropTable[] = {
eCSSProperty_UNKNOWN eCSSProperty_UNKNOWN
}; };
static const nsCSSProperty gScrollSnapTypeSubpropTable[] = {
eCSSProperty_scroll_snap_type_x,
eCSSProperty_scroll_snap_type_y,
eCSSProperty_UNKNOWN
};
const nsCSSProperty *const const nsCSSProperty *const
nsCSSProps::kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands] = { nsCSSProps::kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands] = {
#define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) privatename_ #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) privatename_

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

@ -670,6 +670,7 @@ public:
static const KTableValue kRubyAlignKTable[]; static const KTableValue kRubyAlignKTable[];
static const KTableValue kRubyPositionKTable[]; static const KTableValue kRubyPositionKTable[];
static const KTableValue kScrollBehaviorKTable[]; static const KTableValue kScrollBehaviorKTable[];
static const KTableValue kScrollSnapTypeKTable[];
static const KTableValue kSpeakKTable[]; static const KTableValue kSpeakKTable[];
static const KTableValue kSpeakHeaderKTable[]; static const KTableValue kSpeakHeaderKTable[];
static const KTableValue kSpeakNumeralKTable[]; static const KTableValue kSpeakNumeralKTable[];

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

@ -2730,6 +2730,100 @@ nsComputedDOMStyle::DoGetScrollBehavior()
return val; return val;
} }
CSSValue*
nsComputedDOMStyle::DoGetScrollSnapType()
{
const nsStyleDisplay* display = StyleDisplay();
if (display->mScrollSnapTypeX != display->mScrollSnapTypeY) {
// No value to return. We can't express this combination of
// values as a shorthand.
return nullptr;
}
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollSnapTypeX,
nsCSSProps::kScrollSnapTypeKTable));
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetScrollSnapTypeX()
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollSnapTypeX,
nsCSSProps::kScrollSnapTypeKTable));
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetScrollSnapTypeY()
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollSnapTypeY,
nsCSSProps::kScrollSnapTypeKTable));
return val;
}
CSSValue*
nsComputedDOMStyle::GetScrollSnapPoints(const nsStyleCoord& aCoord)
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
if (aCoord.GetUnit() == eStyleUnit_None) {
val->SetIdent(eCSSKeyword_none);
} else {
nsAutoString argumentString;
SetCssTextToCoord(argumentString, aCoord);
nsAutoString tmp;
tmp.AppendLiteral("repeat(");
tmp.Append(argumentString);
tmp.Append(')');
val->SetString(tmp);
}
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetScrollSnapPointsX()
{
return GetScrollSnapPoints(StyleDisplay()->mScrollSnapPointsX);
}
CSSValue*
nsComputedDOMStyle::DoGetScrollSnapPointsY()
{
return GetScrollSnapPoints(StyleDisplay()->mScrollSnapPointsY);
}
CSSValue*
nsComputedDOMStyle::DoGetScrollSnapDestination()
{
nsDOMCSSValueList* valueList = GetROCSSValueList(false);
SetValueToPosition(StyleDisplay()->mScrollSnapDestination, valueList);
return valueList;
}
CSSValue*
nsComputedDOMStyle::DoGetScrollSnapCoordinate()
{
const nsStyleDisplay* sd = StyleDisplay();
if (sd->mScrollSnapCoordinate.IsEmpty()) {
// Having no snap coordinates is interpreted as "none"
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
val->SetIdent(eCSSKeyword_none);
return val;
} else {
nsDOMCSSValueList* valueList = GetROCSSValueList(true);
for (size_t i = 0, i_end = sd->mScrollSnapCoordinate.Length(); i < i_end; ++i) {
nsDOMCSSValueList* itemList = GetROCSSValueList(false);
valueList->AppendCSSValue(itemList);
SetValueToPosition(sd->mScrollSnapCoordinate[i], itemList);
}
return valueList;
}
}
CSSValue* CSSValue*
nsComputedDOMStyle::DoGetOutlineWidth() nsComputedDOMStyle::DoGetOutlineWidth()
{ {

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

@ -208,6 +208,7 @@ private:
void GetImageRectString(nsIURI* aURI, void GetImageRectString(nsIURI* aURI,
const nsStyleSides& aCropRect, const nsStyleSides& aCropRect,
nsString& aString); nsString& aString);
mozilla::dom::CSSValue* GetScrollSnapPoints(const nsStyleCoord& aCoord);
void AppendTimingFunction(nsDOMCSSValueList *aValueList, void AppendTimingFunction(nsDOMCSSValueList *aValueList,
const nsTimingFunction& aTimingFunction); const nsTimingFunction& aTimingFunction);
@ -433,6 +434,13 @@ private:
mozilla::dom::CSSValue* DoGetTransformStyle(); mozilla::dom::CSSValue* DoGetTransformStyle();
mozilla::dom::CSSValue* DoGetOrient(); mozilla::dom::CSSValue* DoGetOrient();
mozilla::dom::CSSValue* DoGetScrollBehavior(); mozilla::dom::CSSValue* DoGetScrollBehavior();
mozilla::dom::CSSValue* DoGetScrollSnapType();
mozilla::dom::CSSValue* DoGetScrollSnapTypeX();
mozilla::dom::CSSValue* DoGetScrollSnapTypeY();
mozilla::dom::CSSValue* DoGetScrollSnapPointsX();
mozilla::dom::CSSValue* DoGetScrollSnapPointsY();
mozilla::dom::CSSValue* DoGetScrollSnapDestination();
mozilla::dom::CSSValue* DoGetScrollSnapCoordinate();
/* User interface properties */ /* User interface properties */
mozilla::dom::CSSValue* DoGetCursor(); mozilla::dom::CSSValue* DoGetCursor();

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

@ -200,6 +200,12 @@ COMPUTED_STYLE_PROP(right, Right)
COMPUTED_STYLE_PROP(ruby_align, RubyAlign) COMPUTED_STYLE_PROP(ruby_align, RubyAlign)
COMPUTED_STYLE_PROP(ruby_position, RubyPosition) COMPUTED_STYLE_PROP(ruby_position, RubyPosition)
COMPUTED_STYLE_PROP(scroll_behavior, ScrollBehavior) COMPUTED_STYLE_PROP(scroll_behavior, ScrollBehavior)
COMPUTED_STYLE_PROP(scroll_snap_type_x, ScrollSnapTypeX)
COMPUTED_STYLE_PROP(scroll_snap_type_y, ScrollSnapTypeY)
COMPUTED_STYLE_PROP(scroll_snap_points_x, ScrollSnapPointsX)
COMPUTED_STYLE_PROP(scroll_snap_points_y, ScrollSnapPointsY)
COMPUTED_STYLE_PROP(scroll_snap_destination, ScrollSnapDestination)
COMPUTED_STYLE_PROP(scroll_snap_coordinate, ScrollSnapCoordinate)
//// COMPUTED_STYLE_PROP(size, Size) //// COMPUTED_STYLE_PROP(size, Size)
COMPUTED_STYLE_PROP(table_layout, TableLayout) COMPUTED_STYLE_PROP(table_layout, TableLayout)
COMPUTED_STYLE_PROP(text_align, TextAlign) COMPUTED_STYLE_PROP(text_align, TextAlign)

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

@ -77,6 +77,14 @@ using namespace mozilla::dom;
NS_SET_IMAGE_REQUEST(method_, context_, requestgetter_(doc)) \ NS_SET_IMAGE_REQUEST(method_, context_, requestgetter_(doc)) \
} }
/* Helper function to convert a CSS <position> specified value into its
* computed-style form. */
static void
ComputePositionValue(nsStyleContext* aStyleContext,
const nsCSSValue& aValue,
nsStyleBackground::Position& aComputedValue,
bool& aCanStoreInRuleTree);
/* /*
* For storage of an |nsRuleNode|'s children in a PLDHashTable. * For storage of an |nsRuleNode|'s children in a PLDHashTable.
*/ */
@ -5252,6 +5260,141 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
parentDisplay->mScrollBehavior, NS_STYLE_SCROLL_BEHAVIOR_AUTO, parentDisplay->mScrollBehavior, NS_STYLE_SCROLL_BEHAVIOR_AUTO,
0, 0, 0, 0); 0, 0, 0, 0);
// scroll-snap-type-x: none, enum, inherit, initial
SetDiscrete(*aRuleData->ValueForScrollSnapTypeX(), display->mScrollSnapTypeX,
canStoreInRuleTree,
SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
parentDisplay->mScrollSnapTypeX, NS_STYLE_SCROLL_SNAP_TYPE_NONE,
0, 0, 0, 0);
// scroll-snap-type-y: none, enum, inherit, initial
SetDiscrete(*aRuleData->ValueForScrollSnapTypeY(), display->mScrollSnapTypeY,
canStoreInRuleTree,
SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
parentDisplay->mScrollSnapTypeY, NS_STYLE_SCROLL_SNAP_TYPE_NONE,
0, 0, 0, 0);
// scroll-snap-points-x: none, inherit, initial
const nsCSSValue& scrollSnapPointsX = *aRuleData->ValueForScrollSnapPointsX();
switch (scrollSnapPointsX.GetUnit()) {
case eCSSUnit_Initial:
case eCSSUnit_Unset:
case eCSSUnit_None:
case eCSSUnit_Null:
display->mScrollSnapPointsX.SetNoneValue();
break;
case eCSSUnit_Inherit:
display->mScrollSnapPointsX = parentDisplay->mScrollSnapPointsX;
canStoreInRuleTree = false;
break;
case eCSSUnit_Function: {
nsCSSValue::Array* func = scrollSnapPointsX.GetArrayValue();
NS_ASSERTION(func->Item(0).GetKeywordValue() == eCSSKeyword_repeat,
"Expected repeat(), got another function name");
nsStyleCoord coord;
if (SetCoord(func->Item(1), coord, nsStyleCoord(),
SETCOORD_LP | SETCOORD_STORE_CALC |
SETCOORD_CALC_CLAMP_NONNEGATIVE,
aContext, mPresContext, canStoreInRuleTree)) {
NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord ||
coord.GetUnit() == eStyleUnit_Percent ||
coord.GetUnit() == eStyleUnit_Calc,
"unexpected unit");
display->mScrollSnapPointsX = coord;
}
break;
}
default:
NS_NOTREACHED("unexpected unit");
}
// scroll-snap-points-y: none, inherit, initial
const nsCSSValue& scrollSnapPointsY = *aRuleData->ValueForScrollSnapPointsY();
switch (scrollSnapPointsY.GetUnit()) {
case eCSSUnit_Initial:
case eCSSUnit_Unset:
case eCSSUnit_None:
case eCSSUnit_Null:
display->mScrollSnapPointsY.SetNoneValue();
break;
case eCSSUnit_Inherit:
display->mScrollSnapPointsY = parentDisplay->mScrollSnapPointsY;
canStoreInRuleTree = false;
break;
case eCSSUnit_Function: {
nsCSSValue::Array* func = scrollSnapPointsY.GetArrayValue();
NS_ASSERTION(func->Item(0).GetKeywordValue() == eCSSKeyword_repeat,
"Expected repeat(), got another function name");
nsStyleCoord coord;
if (SetCoord(func->Item(1), coord, nsStyleCoord(),
SETCOORD_LP | SETCOORD_STORE_CALC |
SETCOORD_CALC_CLAMP_NONNEGATIVE,
aContext, mPresContext, canStoreInRuleTree)) {
NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord ||
coord.GetUnit() == eStyleUnit_Percent ||
coord.GetUnit() == eStyleUnit_Calc,
"unexpected unit");
display->mScrollSnapPointsY = coord;
}
break;
}
default:
NS_NOTREACHED("unexpected unit");
}
// scroll-snap-destination: inherit, initial
const nsCSSValue& snapDestination = *aRuleData->ValueForScrollSnapDestination();
switch (snapDestination.GetUnit()) {
case eCSSUnit_Initial:
case eCSSUnit_Unset:
case eCSSUnit_Null:
display->mScrollSnapDestination.SetInitialZeroValues();
break;
case eCSSUnit_Inherit:
display->mScrollSnapDestination = parentDisplay->mScrollSnapDestination;
canStoreInRuleTree = false;
break;
default: {
ComputePositionValue(aContext, snapDestination,
display->mScrollSnapDestination, canStoreInRuleTree);
}
}
// scroll-snap-coordinate: none, inherit, initial
typedef nsStyleBackground::Position Position;
const nsCSSValue& snapCoordinate = *aRuleData->ValueForScrollSnapCoordinate();
switch (snapCoordinate.GetUnit()) {
case eCSSUnit_Initial:
case eCSSUnit_Unset:
case eCSSUnit_None:
case eCSSUnit_Null:
// Unset and Initial is none, indicated by an empty array
display->mScrollSnapCoordinate.Clear();
break;
case eCSSUnit_Inherit:
display->mScrollSnapCoordinate = parentDisplay->mScrollSnapCoordinate;
canStoreInRuleTree = false;
break;
case eCSSUnit_List: {
display->mScrollSnapCoordinate.Clear();
const nsCSSValueList* item = snapCoordinate.GetListValue();
do {
NS_ASSERTION(item->mValue.GetUnit() != eCSSUnit_Null &&
item->mValue.GetUnit() != eCSSUnit_Inherit &&
item->mValue.GetUnit() != eCSSUnit_Initial &&
item->mValue.GetUnit() != eCSSUnit_Unset,
"unexpected unit");
Position* pos = display->mScrollSnapCoordinate.AppendElement();
ComputePositionValue(aContext, item->mValue, *pos, canStoreInRuleTree);
item = item->mNext;
} while(item);
break;
}
default:
NS_NOTREACHED("unexpected unit");
}
// isolation: enum, inherit, initial // isolation: enum, inherit, initial
SetDiscrete(*aRuleData->ValueForIsolation(), display->mIsolation, SetDiscrete(*aRuleData->ValueForIsolation(), display->mIsolation,
canStoreInRuleTree, canStoreInRuleTree,

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

@ -1074,6 +1074,11 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
#define NS_STYLE_SCROLL_BEHAVIOR_AUTO 0 #define NS_STYLE_SCROLL_BEHAVIOR_AUTO 0
#define NS_STYLE_SCROLL_BEHAVIOR_SMOOTH 1 #define NS_STYLE_SCROLL_BEHAVIOR_SMOOTH 1
// See nsStyleDisplay::mScrollSnapType{X,Y}
#define NS_STYLE_SCROLL_SNAP_TYPE_NONE 0
#define NS_STYLE_SCROLL_SNAP_TYPE_MANDATORY 1
#define NS_STYLE_SCROLL_SNAP_TYPE_PROXIMITY 2
/***************************************************************************** /*****************************************************************************
* Constants for media features. * * Constants for media features. *
*****************************************************************************/ *****************************************************************************/

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

@ -2279,6 +2279,17 @@ nsStyleBackground::Position::SetInitialPercentValues(float aPercentVal)
mYPosition.mHasPercent = true; mYPosition.mHasPercent = true;
} }
void
nsStyleBackground::Position::SetInitialZeroValues()
{
mXPosition.mPercent = 0;
mXPosition.mLength = 0;
mXPosition.mHasPercent = false;
mYPosition.mPercent = 0;
mYPosition.mLength = 0;
mYPosition.mHasPercent = false;
}
bool bool
nsStyleBackground::Size::DependsOnPositioningAreaSize(const nsStyleImage& aImage) const nsStyleBackground::Size::DependsOnPositioningAreaSize(const nsStyleImage& aImage) const
{ {
@ -2590,6 +2601,12 @@ nsStyleDisplay::nsStyleDisplay()
mIsolation = NS_STYLE_ISOLATION_AUTO; mIsolation = NS_STYLE_ISOLATION_AUTO;
mTouchAction = NS_STYLE_TOUCH_ACTION_AUTO; mTouchAction = NS_STYLE_TOUCH_ACTION_AUTO;
mScrollBehavior = NS_STYLE_SCROLL_BEHAVIOR_AUTO; mScrollBehavior = NS_STYLE_SCROLL_BEHAVIOR_AUTO;
mScrollSnapTypeX = NS_STYLE_SCROLL_SNAP_TYPE_NONE;
mScrollSnapTypeY = NS_STYLE_SCROLL_SNAP_TYPE_NONE;
mScrollSnapPointsX.SetNoneValue();
mScrollSnapPointsY.SetNoneValue();
// Initial value for mScrollSnapDestination is "0px 0px"
mScrollSnapDestination.SetInitialZeroValues();
mTransitions.AppendElement(); mTransitions.AppendElement();
MOZ_ASSERT(mTransitions.Length() == 1, MOZ_ASSERT(mTransitions.Length() == 1,
@ -2640,6 +2657,12 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
, mWillChange(aSource.mWillChange) , mWillChange(aSource.mWillChange)
, mTouchAction(aSource.mTouchAction) , mTouchAction(aSource.mTouchAction)
, mScrollBehavior(aSource.mScrollBehavior) , mScrollBehavior(aSource.mScrollBehavior)
, mScrollSnapTypeX(aSource.mScrollSnapTypeX)
, mScrollSnapTypeY(aSource.mScrollSnapTypeY)
, mScrollSnapPointsX(aSource.mScrollSnapPointsX)
, mScrollSnapPointsY(aSource.mScrollSnapPointsY)
, mScrollSnapDestination(aSource.mScrollSnapDestination)
, mScrollSnapCoordinate(aSource.mScrollSnapCoordinate)
, mBackfaceVisibility(aSource.mBackfaceVisibility) , mBackfaceVisibility(aSource.mBackfaceVisibility)
, mTransformStyle(aSource.mTransformStyle) , mTransformStyle(aSource.mTransformStyle)
, mSpecifiedTransform(aSource.mSpecifiedTransform) , mSpecifiedTransform(aSource.mSpecifiedTransform)
@ -2680,12 +2703,19 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
|| mOverflowX != aOther.mOverflowX || mOverflowX != aOther.mOverflowX
|| mOverflowY != aOther.mOverflowY || mOverflowY != aOther.mOverflowY
|| mScrollBehavior != aOther.mScrollBehavior || mScrollBehavior != aOther.mScrollBehavior
|| mScrollSnapTypeX != aOther.mScrollSnapTypeX
|| mScrollSnapTypeY != aOther.mScrollSnapTypeY
|| mScrollSnapPointsX != aOther.mScrollSnapPointsX
|| mScrollSnapPointsY != aOther.mScrollSnapPointsY
|| mScrollSnapDestination != aOther.mScrollSnapDestination
|| mResize != aOther.mResize) || mResize != aOther.mResize)
NS_UpdateHint(hint, nsChangeHint_ReconstructFrame); NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
/* Note: When mScrollBehavior is changed, the nsChangeHint_NeutralChange is /* Note: When mScrollBehavior, mScrollSnapTypeX, mScrollSnapTypeY,
* not sufficient to enter nsCSSFrameConstructor::PropagateScrollToViewport. * mScrollSnapPointsX, mScrollSnapPointsY, or mScrollSnapDestination are
* By using the same hint as used when the overflow css property changes, * changed, nsChangeHint_NeutralChange is not sufficient to enter
* nsCSSFrameConstructor::PropagateScrollToViewport. By using the same hint
* as used when the overflow css property changes,
* nsChangeHint_ReconstructFrame, PropagateScrollToViewport will be called. * nsChangeHint_ReconstructFrame, PropagateScrollToViewport will be called.
* *
* The scroll-behavior css property is not expected to change often (the * The scroll-behavior css property is not expected to change often (the
@ -2864,7 +2894,8 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
mAnimationDirectionCount != aOther.mAnimationDirectionCount || mAnimationDirectionCount != aOther.mAnimationDirectionCount ||
mAnimationFillModeCount != aOther.mAnimationFillModeCount || mAnimationFillModeCount != aOther.mAnimationFillModeCount ||
mAnimationPlayStateCount != aOther.mAnimationPlayStateCount || mAnimationPlayStateCount != aOther.mAnimationPlayStateCount ||
mAnimationIterationCountCount != aOther.mAnimationIterationCountCount)) { mAnimationIterationCountCount != aOther.mAnimationIterationCountCount ||
mScrollSnapCoordinate != aOther.mScrollSnapCoordinate)) {
NS_UpdateHint(hint, nsChangeHint_NeutralChange); NS_UpdateHint(hint, nsChangeHint_NeutralChange);
} }

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

@ -390,6 +390,10 @@ struct nsStyleBackground {
// initial property-value (e.g. 0.0f for "0% 0%", or 0.5f for "50% 50%") // initial property-value (e.g. 0.0f for "0% 0%", or 0.5f for "50% 50%")
void SetInitialPercentValues(float aPercentVal); void SetInitialPercentValues(float aPercentVal);
// Sets both mXPosition and mYPosition to 0 (app units) for the
// initial property-value as a length with no percentage component.
void SetInitialZeroValues();
// True if the effective background image position described by this depends // True if the effective background image position described by this depends
// on the size of the corresponding frame. // on the size of the corresponding frame.
bool DependsOnPositioningAreaSize() const { bool DependsOnPositioningAreaSize() const {
@ -2011,6 +2015,11 @@ struct nsStyleDisplay {
return nsChangeHint(0); return nsChangeHint(0);
} }
// XXXdholbert, XXXkgilbert nsStyleBackground::Position should probably be
// moved to a different scope, since we're now using it in multiple style
// structs.
typedef nsStyleBackground::Position Position;
// We guarantee that if mBinding is non-null, so are mBinding->GetURI() and // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
// mBinding->mOriginPrincipal. // mBinding->mOriginPrincipal.
nsRefPtr<mozilla::css::URLValue> mBinding; // [reset] nsRefPtr<mozilla::css::URLValue> mBinding; // [reset]
@ -2047,6 +2056,12 @@ struct nsStyleDisplay {
uint8_t mTouchAction; // [reset] see nsStyleConsts.h uint8_t mTouchAction; // [reset] see nsStyleConsts.h
uint8_t mScrollBehavior; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_BEHAVIOR_* uint8_t mScrollBehavior; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_BEHAVIOR_*
uint8_t mScrollSnapTypeX; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
uint8_t mScrollSnapTypeY; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
nsStyleCoord mScrollSnapPointsX; // [reset]
nsStyleCoord mScrollSnapPointsY; // [reset]
Position mScrollSnapDestination; // [reset]
nsTArray<Position> mScrollSnapCoordinate; // [reset]
// mSpecifiedTransform is the list of transform functions as // mSpecifiedTransform is the list of transform functions as
// specified, or null to indicate there is no transform. (inherit or // specified, or null to indicate there is no transform. (inherit or

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

@ -6388,6 +6388,85 @@ if (SpecialPowers.getBoolPref("layout.css.scroll-behavior.property-enabled")) {
}; };
} }
if (SpecialPowers.getBoolPref("layout.css.scroll-snap.enabled")) {
gCSSProperties["scroll-snap-type-x"] = {
domProp: "scrollSnapTypeX",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: ["mandatory", "proximity"],
invalid_values: [ "auto", "1px" ]
};
gCSSProperties["scroll-snap-type-y"] = {
domProp: "scrollSnapTypeY",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: ["mandatory", "proximity"],
invalid_values: [ "auto", "1px" ]
};
gCSSProperties["scroll-snap-type"] = {
domProp: "scrollSnapType",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: [ "scroll-snap-type-x", "scroll-snap-type-y" ],
initial_values: [ "none" ],
other_values: [ "mandatory", "proximity" ],
invalid_values: [ "auto", "1px" ]
};
gCSSProperties["scroll-snap-points-x"] = {
domProp: "scrollSnapPointsX",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "repeat(100%)", "repeat(120px)", "repeat(calc(3*25px))" ],
invalid_values: [ "auto", "1px", "left", "rgb(1,2,3)" ]
}
gCSSProperties["scroll-snap-points-y"] = {
domProp: "scrollSnapPointsY",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "repeat(100%)", "repeat(120px)", "repeat(calc(3*25px))" ],
invalid_values: [ "auto", "1px", "top", "rgb(1,2,3)" ]
}
gCSSProperties["scroll-snap-destination"] = {
domProp: "scrollSnapDestination",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "0px 0px" ],
other_values: [ "25% 25%", "6px 5px", "20% 3em", "0 0", "0in 1in",
"top", "right", "top left", "top right", "center",
"calc(2px)",
"calc(50%)",
"calc(3*25px)",
"calc(3*25px) 5px",
"5px calc(3*25px)",
"calc(20%) calc(3*25px)",
"calc(25px*3)",
"calc(3*25px + 50%)"],
invalid_values: [ "auto", "none", "default" ]
}
gCSSProperties["scroll-snap-coordinate"] = {
domProp: "scrollSnapCoordinate",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "25% 25%", "top", "0px 100px, 10em 50%",
"top left, top right, bottom left, bottom right, center",
"calc(2px)",
"calc(50%)",
"calc(3*25px)",
"calc(3*25px) 5px",
"5px calc(3*25px)",
"calc(20%) calc(3*25px)",
"calc(25px*3)",
"calc(3*25px + 50%)",
"calc(20%) calc(3*25px), center"],
invalid_values: [ "auto", "default" ]
}
}
if (SpecialPowers.getBoolPref("layout.css.unset-value.enabled")) { if (SpecialPowers.getBoolPref("layout.css.unset-value.enabled")) {
gCSSProperties["animation-direction"].invalid_values.push("normal, unset"); gCSSProperties["animation-direction"].invalid_values.push("normal, unset");
gCSSProperties["animation-name"].invalid_values.push("bounce, unset", "unset, bounce"); gCSSProperties["animation-name"].invalid_values.push("bounce, unset", "unset, bounce");

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

@ -2094,6 +2094,9 @@ pref("layout.css.isolation.enabled", true);
// Is support for CSS Filters enabled? // Is support for CSS Filters enabled?
pref("layout.css.filters.enabled", true); pref("layout.css.filters.enabled", true);
// Is support for scroll-snap enabled?
pref("layout.css.scroll-snap.enabled", false);
// Is support for basic shapes in clip-path enabled? // Is support for basic shapes in clip-path enabled?
pref("layout.css.clip-path-shapes.enabled", false); pref("layout.css.clip-path-shapes.enabled", false);