зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1288626 Part 8 - Add shape-outside support to style system. r=heycam
I have to move the definition of FragmentOrURL, StyleBasicShape and StyleShapeSource prior to where nsStyleDisplay::mShapeOutside is defined since the template struct need to be fully defined before using as a member variable. Use SetIdent() in CreatePrimitiveValueForBasicShapeOrURL() in nsComputedDOMStyle.cpp per bug 1288626 comment 6. MozReview-Commit-ID: 1KZS299CFul
This commit is contained in:
Родитель
62e2bf343b
Коммит
82b2646797
|
@ -823,6 +823,7 @@ PropertySupportsVariant(nsCSSProperty aPropertyID, uint32_t aVariant)
|
||||||
case eCSSProperty_content:
|
case eCSSProperty_content:
|
||||||
case eCSSProperty_cursor:
|
case eCSSProperty_cursor:
|
||||||
case eCSSProperty_clip_path:
|
case eCSSProperty_clip_path:
|
||||||
|
case eCSSProperty_shape_outside:
|
||||||
supported = VARIANT_URL;
|
supported = VARIANT_URL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -1066,6 +1066,7 @@ protected:
|
||||||
|
|
||||||
bool ParseShadowItem(nsCSSValue& aValue, bool aIsBoxShadow);
|
bool ParseShadowItem(nsCSSValue& aValue, bool aIsBoxShadow);
|
||||||
bool ParseShadowList(nsCSSProperty aProperty);
|
bool ParseShadowList(nsCSSProperty aProperty);
|
||||||
|
bool ParseShapeOutside(nsCSSValue& aValue);
|
||||||
bool ParseTransitionProperty();
|
bool ParseTransitionProperty();
|
||||||
bool ParseTransitionTimingFunctionValues(nsCSSValue& aValue);
|
bool ParseTransitionTimingFunctionValues(nsCSSValue& aValue);
|
||||||
bool ParseTransitionTimingFunctionValueComponent(float& aComponent,
|
bool ParseTransitionTimingFunctionValueComponent(float& aComponent,
|
||||||
|
@ -1324,6 +1325,8 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Functions for basic shapes */
|
/* Functions for basic shapes */
|
||||||
|
bool ParseReferenceBoxAndBasicShape(nsCSSValue& aValue,
|
||||||
|
const KTableEntry aBoxKeywordTable[]);
|
||||||
bool ParseBasicShape(nsCSSValue& aValue, bool* aConsumedTokens);
|
bool ParseBasicShape(nsCSSValue& aValue, bool* aConsumedTokens);
|
||||||
bool ParsePolygonFunction(nsCSSValue& aValue);
|
bool ParsePolygonFunction(nsCSSValue& aValue);
|
||||||
bool ParseCircleOrEllipseFunction(nsCSSKeyword, nsCSSValue& aValue);
|
bool ParseCircleOrEllipseFunction(nsCSSKeyword, nsCSSValue& aValue);
|
||||||
|
@ -11759,6 +11762,8 @@ CSSParserImpl::ParseSingleValuePropertyByFunction(nsCSSValue& aValue,
|
||||||
return ParseScrollSnapDestination(aValue);
|
return ParseScrollSnapDestination(aValue);
|
||||||
case eCSSProperty_scroll_snap_coordinate:
|
case eCSSProperty_scroll_snap_coordinate:
|
||||||
return ParseScrollSnapCoordinate(aValue);
|
return ParseScrollSnapCoordinate(aValue);
|
||||||
|
case eCSSProperty_shape_outside:
|
||||||
|
return ParseShapeOutside(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:
|
||||||
|
@ -16165,20 +16170,13 @@ CSSParserImpl::ParseBasicShape(nsCSSValue& aValue, bool* aConsumedTokens)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse a clip-path url to a <clipPath> element or a basic shape. */
|
bool
|
||||||
bool CSSParserImpl::ParseClipPath()
|
CSSParserImpl::ParseReferenceBoxAndBasicShape(
|
||||||
|
nsCSSValue& aValue,
|
||||||
|
const KTableEntry aBoxKeywordTable[])
|
||||||
{
|
{
|
||||||
nsCSSValue value;
|
|
||||||
if (!ParseSingleTokenVariant(value, VARIANT_HUO, nullptr)) {
|
|
||||||
if (!nsLayoutUtils::CSSClipPathShapesEnabled()) {
|
|
||||||
// With CSS Clip Path Shapes disabled, we should only accept
|
|
||||||
// SVG clipPath reference and none.
|
|
||||||
REPORT_UNEXPECTED_TOKEN(PEExpectedNoneOrURL);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCSSValue referenceBox;
|
nsCSSValue referenceBox;
|
||||||
bool hasBox = ParseEnum(referenceBox, nsCSSProps::kClipPathGeometryBoxKTable);
|
bool hasBox = ParseEnum(referenceBox, aBoxKeywordTable);
|
||||||
|
|
||||||
const bool boxCameFirst = hasBox;
|
const bool boxCameFirst = hasBox;
|
||||||
|
|
||||||
|
@ -16194,7 +16192,7 @@ bool CSSParserImpl::ParseClipPath()
|
||||||
|
|
||||||
// Check if the second argument is a reference box if the first wasn't.
|
// Check if the second argument is a reference box if the first wasn't.
|
||||||
if (!hasBox) {
|
if (!hasBox) {
|
||||||
hasBox = ParseEnum(referenceBox, nsCSSProps::kClipPathGeometryBoxKTable);
|
hasBox = ParseEnum(referenceBox, aBoxKeywordTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<nsCSSValue::Array> fullValue =
|
RefPtr<nsCSSValue::Array> fullValue =
|
||||||
|
@ -16210,13 +16208,45 @@ bool CSSParserImpl::ParseClipPath()
|
||||||
fullValue->Item(0) = basicShape;
|
fullValue->Item(0) = basicShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
value.SetArrayValue(fullValue, eCSSUnit_Array);
|
aValue.SetArrayValue(fullValue, eCSSUnit_Array);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse a clip-path url to a <clipPath> element or a basic shape. */
|
||||||
|
bool CSSParserImpl::ParseClipPath()
|
||||||
|
{
|
||||||
|
nsCSSValue value;
|
||||||
|
if (!ParseSingleTokenVariant(value, VARIANT_HUO, nullptr)) {
|
||||||
|
if (!nsLayoutUtils::CSSClipPathShapesEnabled()) {
|
||||||
|
// With CSS Clip Path Shapes disabled, we should only accept
|
||||||
|
// SVG clipPath reference and none.
|
||||||
|
REPORT_UNEXPECTED_TOKEN(PEExpectedNoneOrURL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ParseReferenceBoxAndBasicShape(
|
||||||
|
value, nsCSSProps::kClipPathGeometryBoxKTable)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AppendValue(eCSSProperty_clip_path, value);
|
AppendValue(eCSSProperty_clip_path, value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// none | [ <basic-shape> || <shape-box> ] | <image>
|
||||||
|
bool
|
||||||
|
CSSParserImpl::ParseShapeOutside(nsCSSValue& aValue)
|
||||||
|
{
|
||||||
|
if (ParseSingleTokenVariant(aValue, VARIANT_HUO, nullptr)) {
|
||||||
|
// 'inherit', 'initial', 'unset', 'none', and <image> url must be alone.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseReferenceBoxAndBasicShape(
|
||||||
|
aValue, nsCSSProps::kShapeOutsideShapeBoxKTable);
|
||||||
|
}
|
||||||
|
|
||||||
bool CSSParserImpl::ParseTransformOrigin(bool aPerspective)
|
bool CSSParserImpl::ParseTransformOrigin(bool aPerspective)
|
||||||
{
|
{
|
||||||
nsCSSValuePair position;
|
nsCSSValuePair position;
|
||||||
|
|
|
@ -3708,6 +3708,18 @@ CSS_PROP_DISPLAY(
|
||||||
kScrollSnapTypeKTable,
|
kScrollSnapTypeKTable,
|
||||||
CSS_PROP_NO_OFFSET,
|
CSS_PROP_NO_OFFSET,
|
||||||
eStyleAnimType_None)
|
eStyleAnimType_None)
|
||||||
|
CSS_PROP_DISPLAY(
|
||||||
|
shape-outside,
|
||||||
|
shape_outside,
|
||||||
|
ShapeOutside,
|
||||||
|
CSS_PROPERTY_PARSE_VALUE |
|
||||||
|
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
|
||||||
|
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
|
||||||
|
"layout.css.shape-outside.enabled",
|
||||||
|
0,
|
||||||
|
nullptr,
|
||||||
|
CSS_PROP_NO_OFFSET,
|
||||||
|
eStyleAnimType_None) // FIXME: Bug 1289049 for adding animation support
|
||||||
CSS_PROP_SVG(
|
CSS_PROP_SVG(
|
||||||
shape-rendering,
|
shape-rendering,
|
||||||
shape_rendering,
|
shape_rendering,
|
||||||
|
|
|
@ -2341,6 +2341,14 @@ const KTableEntry nsCSSProps::kMaskTypeKTable[] = {
|
||||||
{ eCSSKeyword_UNKNOWN, -1 }
|
{ eCSSKeyword_UNKNOWN, -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const KTableEntry nsCSSProps::kShapeOutsideShapeBoxKTable[] = {
|
||||||
|
{ eCSSKeyword_content_box, StyleShapeOutsideShapeBox::Content },
|
||||||
|
{ eCSSKeyword_padding_box, StyleShapeOutsideShapeBox::Padding },
|
||||||
|
{ eCSSKeyword_border_box, StyleShapeOutsideShapeBox::Border },
|
||||||
|
{ eCSSKeyword_margin_box, StyleShapeOutsideShapeBox::Margin },
|
||||||
|
{ eCSSKeyword_UNKNOWN, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
const KTableEntry nsCSSProps::kShapeRenderingKTable[] = {
|
const KTableEntry nsCSSProps::kShapeRenderingKTable[] = {
|
||||||
{ eCSSKeyword_auto, NS_STYLE_SHAPE_RENDERING_AUTO },
|
{ eCSSKeyword_auto, NS_STYLE_SHAPE_RENDERING_AUTO },
|
||||||
{ eCSSKeyword_optimizespeed, NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED },
|
{ eCSSKeyword_optimizespeed, NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED },
|
||||||
|
|
|
@ -742,6 +742,7 @@ public:
|
||||||
static const KTableEntry kFillRuleKTable[];
|
static const KTableEntry kFillRuleKTable[];
|
||||||
static const KTableEntry kFilterFunctionKTable[];
|
static const KTableEntry kFilterFunctionKTable[];
|
||||||
static const KTableEntry kImageRenderingKTable[];
|
static const KTableEntry kImageRenderingKTable[];
|
||||||
|
static const KTableEntry kShapeOutsideShapeBoxKTable[];
|
||||||
static const KTableEntry kShapeRenderingKTable[];
|
static const KTableEntry kShapeRenderingKTable[];
|
||||||
static const KTableEntry kStrokeLinecapKTable[];
|
static const KTableEntry kStrokeLinecapKTable[];
|
||||||
static const KTableEntry kStrokeLinejoinKTable[];
|
static const KTableEntry kStrokeLinejoinKTable[];
|
||||||
|
|
|
@ -1428,6 +1428,12 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
|
||||||
aResult);
|
aResult);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case eCSSProperty_shape_outside:
|
||||||
|
AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
|
||||||
|
nsCSSProps::kShapeOutsideShapeBoxKTable),
|
||||||
|
aResult);
|
||||||
|
break;
|
||||||
|
|
||||||
case eCSSProperty_contain:
|
case eCSSProperty_contain:
|
||||||
if (intValue & NS_STYLE_CONTAIN_STRICT) {
|
if (intValue & NS_STYLE_CONTAIN_STRICT) {
|
||||||
NS_ASSERTION(intValue == (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS),
|
NS_ASSERTION(intValue == (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS),
|
||||||
|
@ -2522,7 +2528,8 @@ nsCSSValuePairList::AppendToString(nsCSSProperty aProperty,
|
||||||
|
|
||||||
if (nsCSSProps::PropHasFlags(aProperty,
|
if (nsCSSProps::PropHasFlags(aProperty,
|
||||||
CSS_PROPERTY_VALUE_LIST_USES_COMMAS) ||
|
CSS_PROPERTY_VALUE_LIST_USES_COMMAS) ||
|
||||||
aProperty == eCSSProperty_clip_path)
|
aProperty == eCSSProperty_clip_path ||
|
||||||
|
aProperty == eCSSProperty_shape_outside)
|
||||||
aResult.Append(char16_t(','));
|
aResult.Append(char16_t(','));
|
||||||
aResult.Append(char16_t(' '));
|
aResult.Append(char16_t(' '));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5995,10 +5995,12 @@ nsComputedDOMStyle::CreatePrimitiveValueForBasicShape(
|
||||||
return functionValue.forget();
|
return functionValue.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ReferenceBox>
|
||||||
already_AddRefed<CSSValue>
|
already_AddRefed<CSSValue>
|
||||||
nsComputedDOMStyle::CreatePrimitiveValueForClipPath(
|
nsComputedDOMStyle::CreatePrimitiveValueForShapeSource(
|
||||||
const StyleBasicShape* aStyleBasicShape,
|
const StyleBasicShape* aStyleBasicShape,
|
||||||
StyleClipPathGeometryBox aSizingBox)
|
ReferenceBox aReferenceBox,
|
||||||
|
const KTableEntry aBoxKeywordTable[])
|
||||||
{
|
{
|
||||||
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
|
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
|
||||||
if (aStyleBasicShape) {
|
if (aStyleBasicShape) {
|
||||||
|
@ -6006,36 +6008,35 @@ nsComputedDOMStyle::CreatePrimitiveValueForClipPath(
|
||||||
CreatePrimitiveValueForBasicShape(aStyleBasicShape));
|
CreatePrimitiveValueForBasicShape(aStyleBasicShape));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aSizingBox == StyleClipPathGeometryBox::NoBox) {
|
if (aReferenceBox == ReferenceBox::NoBox) {
|
||||||
return valueList.forget();
|
return valueList.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString boxString;
|
|
||||||
AppendASCIItoUTF16(
|
|
||||||
nsCSSProps::ValueToKeyword(aSizingBox,
|
|
||||||
nsCSSProps::kClipPathGeometryBoxKTable),
|
|
||||||
boxString);
|
|
||||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||||
val->SetString(boxString);
|
val->SetIdent(nsCSSProps::ValueToKeywordEnum(aReferenceBox, aBoxKeywordTable));
|
||||||
valueList->AppendCSSValue(val.forget());
|
valueList->AppendCSSValue(val.forget());
|
||||||
|
|
||||||
return valueList.forget();
|
return valueList.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ReferenceBox>
|
||||||
already_AddRefed<CSSValue>
|
already_AddRefed<CSSValue>
|
||||||
nsComputedDOMStyle::DoGetClipPath()
|
nsComputedDOMStyle::GetShapeSource(
|
||||||
|
const StyleShapeSource<ReferenceBox>& aShapeSource,
|
||||||
|
const KTableEntry aBoxKeywordTable[])
|
||||||
{
|
{
|
||||||
const nsStyleSVGReset* svg = StyleSVGReset();
|
switch (aShapeSource.GetType()) {
|
||||||
switch (svg->mClipPath.GetType()) {
|
|
||||||
case StyleShapeSourceType::Shape:
|
case StyleShapeSourceType::Shape:
|
||||||
return CreatePrimitiveValueForClipPath(svg->mClipPath.GetBasicShape(),
|
return CreatePrimitiveValueForShapeSource(aShapeSource.GetBasicShape(),
|
||||||
svg->mClipPath.GetReferenceBox());
|
aShapeSource.GetReferenceBox(),
|
||||||
|
aBoxKeywordTable);
|
||||||
case StyleShapeSourceType::Box:
|
case StyleShapeSourceType::Box:
|
||||||
return CreatePrimitiveValueForClipPath(nullptr,
|
return CreatePrimitiveValueForShapeSource(nullptr,
|
||||||
svg->mClipPath.GetReferenceBox());
|
aShapeSource.GetReferenceBox(),
|
||||||
|
aBoxKeywordTable);
|
||||||
case StyleShapeSourceType::URL: {
|
case StyleShapeSourceType::URL: {
|
||||||
// Bug 1288812 - we should only serialize fragment for local-ref URL.
|
// Bug 1288812 - we should only serialize fragment for local-ref URL.
|
||||||
nsCOMPtr<nsIURI> pathURI = svg->mClipPath.GetURL()->GetSourceURL();
|
nsCOMPtr<nsIURI> pathURI = aShapeSource.GetURL()->GetSourceURL();
|
||||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||||
val->SetURI(pathURI);
|
val->SetURI(pathURI);
|
||||||
return val.forget();
|
return val.forget();
|
||||||
|
@ -6051,6 +6052,20 @@ nsComputedDOMStyle::DoGetClipPath()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<CSSValue>
|
||||||
|
nsComputedDOMStyle::DoGetClipPath()
|
||||||
|
{
|
||||||
|
return GetShapeSource(StyleSVGReset()->mClipPath,
|
||||||
|
nsCSSProps::kClipPathGeometryBoxKTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<CSSValue>
|
||||||
|
nsComputedDOMStyle::DoGetShapeOutside()
|
||||||
|
{
|
||||||
|
return GetShapeSource(StyleDisplay()->mShapeOutside,
|
||||||
|
nsCSSProps::kShapeOutsideShapeBoxKTable);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsComputedDOMStyle::SetCssTextToCoord(nsAString& aCssText,
|
nsComputedDOMStyle::SetCssTextToCoord(nsAString& aCssText,
|
||||||
const nsStyleCoord& aCoord)
|
const nsStyleCoord& aCoord)
|
||||||
|
|
|
@ -481,6 +481,7 @@ private:
|
||||||
already_AddRefed<CSSValue> DoGetScrollSnapPointsY();
|
already_AddRefed<CSSValue> DoGetScrollSnapPointsY();
|
||||||
already_AddRefed<CSSValue> DoGetScrollSnapDestination();
|
already_AddRefed<CSSValue> DoGetScrollSnapDestination();
|
||||||
already_AddRefed<CSSValue> DoGetScrollSnapCoordinate();
|
already_AddRefed<CSSValue> DoGetScrollSnapCoordinate();
|
||||||
|
already_AddRefed<CSSValue> DoGetShapeOutside();
|
||||||
|
|
||||||
/* User interface properties */
|
/* User interface properties */
|
||||||
already_AddRefed<CSSValue> DoGetCursor();
|
already_AddRefed<CSSValue> DoGetCursor();
|
||||||
|
@ -643,9 +644,17 @@ private:
|
||||||
already_AddRefed<CSSValue> CreatePrimitiveValueForStyleFilter(
|
already_AddRefed<CSSValue> CreatePrimitiveValueForStyleFilter(
|
||||||
const nsStyleFilter& aStyleFilter);
|
const nsStyleFilter& aStyleFilter);
|
||||||
|
|
||||||
already_AddRefed<CSSValue> CreatePrimitiveValueForClipPath(
|
template<typename ReferenceBox>
|
||||||
|
already_AddRefed<CSSValue>
|
||||||
|
GetShapeSource(const mozilla::StyleShapeSource<ReferenceBox>& aShapeSource,
|
||||||
|
const KTableEntry aBoxKeywordTable[]);
|
||||||
|
|
||||||
|
template<typename ReferenceBox>
|
||||||
|
already_AddRefed<CSSValue>
|
||||||
|
CreatePrimitiveValueForShapeSource(
|
||||||
const mozilla::StyleBasicShape* aStyleBasicShape,
|
const mozilla::StyleBasicShape* aStyleBasicShape,
|
||||||
mozilla::StyleClipPathGeometryBox aSizingBox);
|
ReferenceBox aReferenceBox,
|
||||||
|
const KTableEntry aBoxKeywordTable[]);
|
||||||
|
|
||||||
// Helper function for computing basic shape styles.
|
// Helper function for computing basic shape styles.
|
||||||
already_AddRefed<CSSValue> CreatePrimitiveValueForBasicShape(
|
already_AddRefed<CSSValue> CreatePrimitiveValueForBasicShape(
|
||||||
|
|
|
@ -217,6 +217,7 @@ COMPUTED_STYLE_PROP(scroll_snap_points_x, ScrollSnapPointsX)
|
||||||
COMPUTED_STYLE_PROP(scroll_snap_points_y, ScrollSnapPointsY)
|
COMPUTED_STYLE_PROP(scroll_snap_points_y, ScrollSnapPointsY)
|
||||||
COMPUTED_STYLE_PROP(scroll_snap_type_x, ScrollSnapTypeX)
|
COMPUTED_STYLE_PROP(scroll_snap_type_x, ScrollSnapTypeX)
|
||||||
COMPUTED_STYLE_PROP(scroll_snap_type_y, ScrollSnapTypeY)
|
COMPUTED_STYLE_PROP(scroll_snap_type_y, ScrollSnapTypeY)
|
||||||
|
COMPUTED_STYLE_PROP(shape_outside, ShapeOutside)
|
||||||
//// 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)
|
||||||
|
|
|
@ -119,6 +119,14 @@ SetImageRequest(function<void(imgRequestProxy*)> aCallback,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ReferenceBox>
|
||||||
|
static void
|
||||||
|
SetStyleShapeSourceToCSSValue(StyleShapeSource<ReferenceBox>* aShapeSource,
|
||||||
|
const nsCSSValue* aValue,
|
||||||
|
nsStyleContext* aStyleContext,
|
||||||
|
nsPresContext* aPresContext,
|
||||||
|
RuleNodeCacheConditions& aConditions);
|
||||||
|
|
||||||
/* Helper function to convert a CSS <position> specified value into its
|
/* Helper function to convert a CSS <position> specified value into its
|
||||||
* computed-style form. */
|
* computed-style form. */
|
||||||
static void
|
static void
|
||||||
|
@ -6434,6 +6442,35 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
|
||||||
parentDisplay->mOrient,
|
parentDisplay->mOrient,
|
||||||
NS_STYLE_ORIENT_INLINE);
|
NS_STYLE_ORIENT_INLINE);
|
||||||
|
|
||||||
|
// shape-outside: none | [ <basic-shape> || <shape-box> ] | <image>
|
||||||
|
const nsCSSValue* shapeOutsideValue = aRuleData->ValueForShapeOutside();
|
||||||
|
switch (shapeOutsideValue->GetUnit()) {
|
||||||
|
case eCSSUnit_Null:
|
||||||
|
break;
|
||||||
|
case eCSSUnit_None:
|
||||||
|
case eCSSUnit_Initial:
|
||||||
|
case eCSSUnit_Unset:
|
||||||
|
display->mShapeOutside = StyleShapeOutside();
|
||||||
|
break;
|
||||||
|
case eCSSUnit_Inherit:
|
||||||
|
conditions.SetUncacheable();
|
||||||
|
display->mShapeOutside = parentDisplay->mShapeOutside;
|
||||||
|
break;
|
||||||
|
case eCSSUnit_URL: {
|
||||||
|
display->mShapeOutside = StyleShapeOutside();
|
||||||
|
display->mShapeOutside.SetURL(shapeOutsideValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eCSSUnit_Array: {
|
||||||
|
display->mShapeOutside = StyleShapeOutside();
|
||||||
|
SetStyleShapeSourceToCSSValue(&display->mShapeOutside, shapeOutsideValue,
|
||||||
|
aContext, mPresContext, conditions);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
MOZ_ASSERT_UNREACHABLE("Unrecognized shape-outside unit!");
|
||||||
|
}
|
||||||
|
|
||||||
COMPUTE_END_RESET(Display, display)
|
COMPUTE_END_RESET(Display, display)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9730,8 +9767,10 @@ GetStyleBasicShapeFromCSSValue(const nsCSSValue& aValue,
|
||||||
return basicShape.forget();
|
return basicShape.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ReferenceBox>
|
||||||
static void
|
static void
|
||||||
SetStyleClipPathToCSSValue(StyleClipPath* aStyleClipPath,
|
SetStyleShapeSourceToCSSValue(
|
||||||
|
StyleShapeSource<ReferenceBox>* aShapeSource,
|
||||||
const nsCSSValue* aValue,
|
const nsCSSValue* aValue,
|
||||||
nsStyleContext* aStyleContext,
|
nsStyleContext* aStyleContext,
|
||||||
nsPresContext* aPresContext,
|
nsPresContext* aPresContext,
|
||||||
|
@ -9742,32 +9781,28 @@ SetStyleClipPathToCSSValue(StyleClipPath* aStyleClipPath,
|
||||||
|
|
||||||
const nsCSSValue::Array* array = aValue->GetArrayValue();
|
const nsCSSValue::Array* array = aValue->GetArrayValue();
|
||||||
MOZ_ASSERT(array->Count() == 1 || array->Count() == 2,
|
MOZ_ASSERT(array->Count() == 1 || array->Count() == 2,
|
||||||
"Expect one or both of a shape function and geometry-box");
|
"Expect one or both of a shape function and a reference box");
|
||||||
|
|
||||||
StyleClipPathGeometryBox sizingBox = StyleClipPathGeometryBox::NoBox;
|
ReferenceBox referenceBox = ReferenceBox::NoBox;
|
||||||
RefPtr<StyleBasicShape> basicShape;
|
RefPtr<StyleBasicShape> basicShape;
|
||||||
|
|
||||||
for (size_t i = 0; i < array->Count(); ++i) {
|
for (size_t i = 0; i < array->Count(); ++i) {
|
||||||
if (array->Item(i).GetUnit() == eCSSUnit_Enumerated) {
|
const nsCSSValue& item = array->Item(i);
|
||||||
int32_t type = array->Item(i).GetIntValue();
|
if (item.GetUnit() == eCSSUnit_Enumerated) {
|
||||||
if (type > uint8_t(StyleClipPathGeometryBox::View) ||
|
referenceBox = static_cast<ReferenceBox>(item.GetIntValue());
|
||||||
type < uint8_t(StyleClipPathGeometryBox::NoBox)) {
|
} else if (item.GetUnit() == eCSSUnit_Function) {
|
||||||
NS_NOTREACHED("unexpected reference box");
|
basicShape = GetStyleBasicShapeFromCSSValue(item, aStyleContext,
|
||||||
return;
|
|
||||||
}
|
|
||||||
sizingBox = static_cast<StyleClipPathGeometryBox>(type);
|
|
||||||
} else if (array->Item(i).GetUnit() == eCSSUnit_Function) {
|
|
||||||
basicShape = GetStyleBasicShapeFromCSSValue(array->Item(i), aStyleContext,
|
|
||||||
aPresContext, aConditions);
|
aPresContext, aConditions);
|
||||||
} else {
|
} else {
|
||||||
NS_NOTREACHED("unexpected value");
|
MOZ_ASSERT_UNREACHABLE("Unexpected unit!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basicShape) {
|
if (basicShape) {
|
||||||
aStyleClipPath->SetBasicShape(basicShape, sizingBox);
|
aShapeSource->SetBasicShape(basicShape, referenceBox);
|
||||||
} else {
|
} else {
|
||||||
aStyleClipPath->SetReferenceBox(sizingBox);
|
aShapeSource->SetReferenceBox(referenceBox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9892,7 +9927,7 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
|
||||||
}
|
}
|
||||||
case eCSSUnit_Array: {
|
case eCSSUnit_Array: {
|
||||||
svgReset->mClipPath = StyleClipPath();
|
svgReset->mClipPath = StyleClipPath();
|
||||||
SetStyleClipPathToCSSValue(&svgReset->mClipPath, clipPathValue, aContext,
|
SetStyleShapeSourceToCSSValue(&svgReset->mClipPath, clipPathValue, aContext,
|
||||||
mPresContext, conditions);
|
mPresContext, conditions);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,15 @@ enum class StyleFloatEdge : uint8_t {
|
||||||
MarginBox,
|
MarginBox,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// shape-box for shape-outside
|
||||||
|
enum class StyleShapeOutsideShapeBox : uint8_t {
|
||||||
|
NoBox,
|
||||||
|
Content,
|
||||||
|
Padding,
|
||||||
|
Border,
|
||||||
|
Margin
|
||||||
|
};
|
||||||
|
|
||||||
// Shape source type
|
// Shape source type
|
||||||
// X11 has a #define for None causing conflicts, so we use None_ here
|
// X11 has a #define for None causing conflicts, so we use None_ here
|
||||||
enum class StyleShapeSourceType : uint8_t {
|
enum class StyleShapeSourceType : uint8_t {
|
||||||
|
|
|
@ -3076,6 +3076,7 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
|
||||||
, mAnimationFillModeCount(aSource.mAnimationFillModeCount)
|
, mAnimationFillModeCount(aSource.mAnimationFillModeCount)
|
||||||
, mAnimationPlayStateCount(aSource.mAnimationPlayStateCount)
|
, mAnimationPlayStateCount(aSource.mAnimationPlayStateCount)
|
||||||
, mAnimationIterationCountCount(aSource.mAnimationIterationCountCount)
|
, mAnimationIterationCountCount(aSource.mAnimationIterationCountCount)
|
||||||
|
, mShapeOutside(aSource.mShapeOutside)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsStyleDisplay);
|
MOZ_COUNT_CTOR(nsStyleDisplay);
|
||||||
|
|
||||||
|
@ -3300,7 +3301,8 @@ nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const
|
||||||
mAnimationFillModeCount != aNewData.mAnimationFillModeCount ||
|
mAnimationFillModeCount != aNewData.mAnimationFillModeCount ||
|
||||||
mAnimationPlayStateCount != aNewData.mAnimationPlayStateCount ||
|
mAnimationPlayStateCount != aNewData.mAnimationPlayStateCount ||
|
||||||
mAnimationIterationCountCount != aNewData.mAnimationIterationCountCount ||
|
mAnimationIterationCountCount != aNewData.mAnimationIterationCountCount ||
|
||||||
mScrollSnapCoordinate != aNewData.mScrollSnapCoordinate)) {
|
mScrollSnapCoordinate != aNewData.mScrollSnapCoordinate ||
|
||||||
|
mShapeOutside != aNewData.mShapeOutside)) {
|
||||||
hint |= nsChangeHint_NeutralChange;
|
hint |= nsChangeHint_NeutralChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2387,6 +2387,40 @@ private:
|
||||||
void AssignFromKeyword(int32_t aTimingFunctionType);
|
void AssignFromKeyword(int32_t aTimingFunctionType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct FragmentOrURL
|
||||||
|
{
|
||||||
|
FragmentOrURL() : mIsLocalRef(false) {}
|
||||||
|
FragmentOrURL(const FragmentOrURL& aSource)
|
||||||
|
: mIsLocalRef(false)
|
||||||
|
{ *this = aSource; }
|
||||||
|
|
||||||
|
void SetValue(const nsCSSValue* aValue);
|
||||||
|
void SetNull();
|
||||||
|
|
||||||
|
FragmentOrURL& operator=(const FragmentOrURL& aOther);
|
||||||
|
bool operator==(const FragmentOrURL& aOther) const;
|
||||||
|
bool operator!=(const FragmentOrURL& aOther) const {
|
||||||
|
return !(*this == aOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EqualsExceptRef(nsIURI* aURI) const;
|
||||||
|
|
||||||
|
nsIURI* GetSourceURL() const { return mURL; }
|
||||||
|
void GetSourceString(nsString& aRef) const;
|
||||||
|
|
||||||
|
// When matching a url with mIsLocalRef set, resolve it against aURI;
|
||||||
|
// Otherwise, ignore aURL and return mURL directly.
|
||||||
|
already_AddRefed<nsIURI> Resolve(nsIURI* aURI) const;
|
||||||
|
already_AddRefed<nsIURI> Resolve(nsIContent* aContent) const;
|
||||||
|
|
||||||
|
bool IsLocalRef() const { return mIsLocalRef; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsCOMPtr<nsIURI> mURL;
|
||||||
|
bool mIsLocalRef;
|
||||||
|
};
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
struct StyleTransition
|
struct StyleTransition
|
||||||
|
@ -2490,6 +2524,259 @@ private:
|
||||||
float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
|
float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StyleBasicShape final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit StyleBasicShape(StyleBasicShapeType type)
|
||||||
|
: mType(type),
|
||||||
|
mFillRule(NS_STYLE_FILL_RULE_NONZERO)
|
||||||
|
{
|
||||||
|
mPosition.SetInitialPercentValues(0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleBasicShapeType GetShapeType() const { return mType; }
|
||||||
|
nsCSSKeyword GetShapeTypeName() const;
|
||||||
|
|
||||||
|
int32_t GetFillRule() const { return mFillRule; }
|
||||||
|
void SetFillRule(int32_t aFillRule)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mType == StyleBasicShapeType::Polygon, "expected polygon");
|
||||||
|
mFillRule = aFillRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef nsStyleImageLayers::Position Position;
|
||||||
|
Position& GetPosition() {
|
||||||
|
MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
|
||||||
|
mType == StyleBasicShapeType::Ellipse,
|
||||||
|
"expected circle or ellipse");
|
||||||
|
return mPosition;
|
||||||
|
}
|
||||||
|
const Position& GetPosition() const {
|
||||||
|
MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
|
||||||
|
mType == StyleBasicShapeType::Ellipse,
|
||||||
|
"expected circle or ellipse");
|
||||||
|
return mPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasRadius() const {
|
||||||
|
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
|
||||||
|
nsStyleCoord zero;
|
||||||
|
zero.SetCoordValue(0);
|
||||||
|
NS_FOR_CSS_HALF_CORNERS(corner) {
|
||||||
|
if (mRadius.Get(corner) != zero) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nsStyleCorners& GetRadius() {
|
||||||
|
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
|
||||||
|
return mRadius;
|
||||||
|
}
|
||||||
|
const nsStyleCorners& GetRadius() const {
|
||||||
|
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
|
||||||
|
return mRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mCoordinates has coordinates for polygon or radii for
|
||||||
|
// ellipse and circle.
|
||||||
|
nsTArray<nsStyleCoord>& Coordinates()
|
||||||
|
{
|
||||||
|
return mCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsTArray<nsStyleCoord>& Coordinates() const
|
||||||
|
{
|
||||||
|
return mCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const StyleBasicShape& aOther) const
|
||||||
|
{
|
||||||
|
return mType == aOther.mType &&
|
||||||
|
mFillRule == aOther.mFillRule &&
|
||||||
|
mCoordinates == aOther.mCoordinates &&
|
||||||
|
mPosition == aOther.mPosition &&
|
||||||
|
mRadius == aOther.mRadius;
|
||||||
|
}
|
||||||
|
bool operator!=(const StyleBasicShape& aOther) const {
|
||||||
|
return !(*this == aOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_INLINE_DECL_REFCOUNTING(StyleBasicShape);
|
||||||
|
|
||||||
|
private:
|
||||||
|
~StyleBasicShape() {}
|
||||||
|
|
||||||
|
StyleBasicShapeType mType;
|
||||||
|
int32_t mFillRule;
|
||||||
|
|
||||||
|
// mCoordinates has coordinates for polygon or radii for
|
||||||
|
// ellipse and circle.
|
||||||
|
nsTArray<nsStyleCoord> mCoordinates;
|
||||||
|
Position mPosition;
|
||||||
|
nsStyleCorners mRadius;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ReferenceBox>
|
||||||
|
struct StyleShapeSource
|
||||||
|
{
|
||||||
|
StyleShapeSource()
|
||||||
|
: mURL(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
StyleShapeSource(const StyleShapeSource& aSource)
|
||||||
|
: StyleShapeSource()
|
||||||
|
{
|
||||||
|
if (aSource.mType == StyleShapeSourceType::URL) {
|
||||||
|
CopyURL(aSource);
|
||||||
|
} else if (aSource.mType == StyleShapeSourceType::Shape) {
|
||||||
|
SetBasicShape(aSource.mBasicShape, aSource.mReferenceBox);
|
||||||
|
} else if (aSource.mType == StyleShapeSourceType::Box) {
|
||||||
|
SetReferenceBox(aSource.mReferenceBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~StyleShapeSource()
|
||||||
|
{
|
||||||
|
ReleaseRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleShapeSource& operator=(const StyleShapeSource& aOther)
|
||||||
|
{
|
||||||
|
if (this == &aOther) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aOther.mType == StyleShapeSourceType::URL) {
|
||||||
|
CopyURL(aOther);
|
||||||
|
} else if (aOther.mType == StyleShapeSourceType::Shape) {
|
||||||
|
SetBasicShape(aOther.mBasicShape, aOther.mReferenceBox);
|
||||||
|
} else if (aOther.mType == StyleShapeSourceType::Box) {
|
||||||
|
SetReferenceBox(aOther.mReferenceBox);
|
||||||
|
} else {
|
||||||
|
ReleaseRef();
|
||||||
|
mReferenceBox = ReferenceBox::NoBox;
|
||||||
|
mType = StyleShapeSourceType::None_;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const StyleShapeSource& aOther) const
|
||||||
|
{
|
||||||
|
if (mType != aOther.mType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mType == StyleShapeSourceType::URL) {
|
||||||
|
return mURL == aOther.mURL;
|
||||||
|
} else if (mType == StyleShapeSourceType::Shape) {
|
||||||
|
return *mBasicShape == *aOther.mBasicShape &&
|
||||||
|
mReferenceBox == aOther.mReferenceBox;
|
||||||
|
} else if (mType == StyleShapeSourceType::Box) {
|
||||||
|
return mReferenceBox == aOther.mReferenceBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const StyleShapeSource& aOther) const
|
||||||
|
{
|
||||||
|
return !(*this == aOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleShapeSourceType GetType() const
|
||||||
|
{
|
||||||
|
return mType;
|
||||||
|
}
|
||||||
|
|
||||||
|
FragmentOrURL* GetURL() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mType == StyleShapeSourceType::URL, "Wrong shape source type!");
|
||||||
|
return mURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetURL(const nsCSSValue* aValue)
|
||||||
|
{
|
||||||
|
if (!aValue->GetURLValue()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseRef();
|
||||||
|
|
||||||
|
mURL = new FragmentOrURL();
|
||||||
|
mURL->SetValue(aValue);
|
||||||
|
mType = StyleShapeSourceType::URL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleBasicShape* GetBasicShape() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mType == StyleShapeSourceType::Shape, "Wrong shape source type!");
|
||||||
|
return mBasicShape;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBasicShape(StyleBasicShape* aBasicShape,
|
||||||
|
ReferenceBox aReferenceBox)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aBasicShape, "expected pointer");
|
||||||
|
ReleaseRef();
|
||||||
|
mBasicShape = aBasicShape;
|
||||||
|
mBasicShape->AddRef();
|
||||||
|
mReferenceBox = aReferenceBox;
|
||||||
|
mType = StyleShapeSourceType::Shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReferenceBox GetReferenceBox() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mType == StyleShapeSourceType::Box ||
|
||||||
|
mType == StyleShapeSourceType::Shape,
|
||||||
|
"Wrong shape source type!");
|
||||||
|
return mReferenceBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetReferenceBox(ReferenceBox aReferenceBox)
|
||||||
|
{
|
||||||
|
ReleaseRef();
|
||||||
|
mReferenceBox = aReferenceBox;
|
||||||
|
mType = StyleShapeSourceType::Box;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ReleaseRef()
|
||||||
|
{
|
||||||
|
if (mType == StyleShapeSourceType::Shape) {
|
||||||
|
NS_ASSERTION(mBasicShape, "expected pointer");
|
||||||
|
mBasicShape->Release();
|
||||||
|
} else if (mType == StyleShapeSourceType::URL) {
|
||||||
|
NS_ASSERTION(mURL, "expected pointer");
|
||||||
|
delete mURL;
|
||||||
|
}
|
||||||
|
// Both mBasicShape and mURL are pointers in a union. Nulling one of them
|
||||||
|
// nulls both of them.
|
||||||
|
mURL = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CopyURL(const StyleShapeSource& aOther)
|
||||||
|
{
|
||||||
|
ReleaseRef();
|
||||||
|
|
||||||
|
mURL = new FragmentOrURL(*aOther.mURL);
|
||||||
|
mType = StyleShapeSourceType::URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* operator new(size_t) = delete;
|
||||||
|
|
||||||
|
union {
|
||||||
|
StyleBasicShape* mBasicShape;
|
||||||
|
FragmentOrURL* mURL;
|
||||||
|
};
|
||||||
|
StyleShapeSourceType mType = StyleShapeSourceType::None_;
|
||||||
|
ReferenceBox mReferenceBox = ReferenceBox::NoBox;
|
||||||
|
};
|
||||||
|
|
||||||
|
using StyleClipPath = StyleShapeSource<StyleClipPathGeometryBox>;
|
||||||
|
using StyleShapeOutside = StyleShapeSource<StyleShapeOutsideShapeBox>;
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
|
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
|
||||||
|
@ -2611,6 +2898,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
|
||||||
mAnimationPlayStateCount,
|
mAnimationPlayStateCount,
|
||||||
mAnimationIterationCountCount;
|
mAnimationIterationCountCount;
|
||||||
|
|
||||||
|
mozilla::StyleShapeOutside mShapeOutside; // [reset]
|
||||||
|
|
||||||
bool IsBlockInsideStyle() const {
|
bool IsBlockInsideStyle() const {
|
||||||
return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
|
return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
|
||||||
NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
|
NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
|
||||||
|
@ -3233,39 +3522,6 @@ protected:
|
||||||
nscoord mTwipsPerPixel;
|
nscoord mTwipsPerPixel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FragmentOrURL
|
|
||||||
{
|
|
||||||
FragmentOrURL() : mIsLocalRef(false) {}
|
|
||||||
FragmentOrURL(const FragmentOrURL& aSource)
|
|
||||||
: mIsLocalRef(false)
|
|
||||||
{ *this = aSource; }
|
|
||||||
|
|
||||||
void SetValue(const nsCSSValue* aValue);
|
|
||||||
void SetNull();
|
|
||||||
|
|
||||||
FragmentOrURL& operator=(const FragmentOrURL& aOther);
|
|
||||||
bool operator==(const FragmentOrURL& aOther) const;
|
|
||||||
bool operator!=(const FragmentOrURL& aOther) const {
|
|
||||||
return !(*this == aOther);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EqualsExceptRef(nsIURI* aURI) const;
|
|
||||||
|
|
||||||
nsIURI* GetSourceURL() const { return mURL; }
|
|
||||||
void GetSourceString(nsString& aRef) const;
|
|
||||||
|
|
||||||
// When matching a url with mIsLocalRef set, resolve it against aURI;
|
|
||||||
// Otherwise, ignore aURL and return mURL directly.
|
|
||||||
already_AddRefed<nsIURI> Resolve(nsIURI* aURI) const;
|
|
||||||
already_AddRefed<nsIURI> Resolve(nsIContent* aContent) const;
|
|
||||||
|
|
||||||
bool IsLocalRef() const { return mIsLocalRef; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsCOMPtr<nsIURI> mURL;
|
|
||||||
bool mIsLocalRef;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum nsStyleSVGPaintType {
|
enum nsStyleSVGPaintType {
|
||||||
eStyleSVGPaintType_None = 1,
|
eStyleSVGPaintType_None = 1,
|
||||||
eStyleSVGPaintType_Color,
|
eStyleSVGPaintType_Color,
|
||||||
|
@ -3436,262 +3692,6 @@ private:
|
||||||
uint8_t mContextFlags; // [inherited]
|
uint8_t mContextFlags; // [inherited]
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
|
|
||||||
class StyleBasicShape final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit StyleBasicShape(StyleBasicShapeType type)
|
|
||||||
: mType(type),
|
|
||||||
mFillRule(NS_STYLE_FILL_RULE_NONZERO)
|
|
||||||
{
|
|
||||||
mPosition.SetInitialPercentValues(0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
StyleBasicShapeType GetShapeType() const { return mType; }
|
|
||||||
nsCSSKeyword GetShapeTypeName() const;
|
|
||||||
|
|
||||||
int32_t GetFillRule() const { return mFillRule; }
|
|
||||||
void SetFillRule(int32_t aFillRule)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mType == StyleBasicShapeType::Polygon, "expected polygon");
|
|
||||||
mFillRule = aFillRule;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef nsStyleImageLayers::Position Position;
|
|
||||||
Position& GetPosition() {
|
|
||||||
MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
|
|
||||||
mType == StyleBasicShapeType::Ellipse,
|
|
||||||
"expected circle or ellipse");
|
|
||||||
return mPosition;
|
|
||||||
}
|
|
||||||
const Position& GetPosition() const {
|
|
||||||
MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
|
|
||||||
mType == StyleBasicShapeType::Ellipse,
|
|
||||||
"expected circle or ellipse");
|
|
||||||
return mPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasRadius() const {
|
|
||||||
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
|
|
||||||
nsStyleCoord zero;
|
|
||||||
zero.SetCoordValue(0);
|
|
||||||
NS_FOR_CSS_HALF_CORNERS(corner) {
|
|
||||||
if (mRadius.Get(corner) != zero) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
nsStyleCorners& GetRadius() {
|
|
||||||
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
|
|
||||||
return mRadius;
|
|
||||||
}
|
|
||||||
const nsStyleCorners& GetRadius() const {
|
|
||||||
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
|
|
||||||
return mRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
// mCoordinates has coordinates for polygon or radii for
|
|
||||||
// ellipse and circle.
|
|
||||||
nsTArray<nsStyleCoord>& Coordinates()
|
|
||||||
{
|
|
||||||
return mCoordinates;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsTArray<nsStyleCoord>& Coordinates() const
|
|
||||||
{
|
|
||||||
return mCoordinates;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const StyleBasicShape& aOther) const
|
|
||||||
{
|
|
||||||
return mType == aOther.mType &&
|
|
||||||
mFillRule == aOther.mFillRule &&
|
|
||||||
mCoordinates == aOther.mCoordinates &&
|
|
||||||
mPosition == aOther.mPosition &&
|
|
||||||
mRadius == aOther.mRadius;
|
|
||||||
}
|
|
||||||
bool operator!=(const StyleBasicShape& aOther) const {
|
|
||||||
return !(*this == aOther);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_INLINE_DECL_REFCOUNTING(StyleBasicShape);
|
|
||||||
|
|
||||||
private:
|
|
||||||
~StyleBasicShape() {}
|
|
||||||
|
|
||||||
StyleBasicShapeType mType;
|
|
||||||
int32_t mFillRule;
|
|
||||||
|
|
||||||
// mCoordinates has coordinates for polygon or radii for
|
|
||||||
// ellipse and circle.
|
|
||||||
nsTArray<nsStyleCoord> mCoordinates;
|
|
||||||
Position mPosition;
|
|
||||||
nsStyleCorners mRadius;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ReferenceBox>
|
|
||||||
struct StyleShapeSource
|
|
||||||
{
|
|
||||||
StyleShapeSource()
|
|
||||||
: mURL(nullptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
StyleShapeSource(const StyleShapeSource& aSource)
|
|
||||||
: StyleShapeSource()
|
|
||||||
{
|
|
||||||
if (aSource.mType == StyleShapeSourceType::URL) {
|
|
||||||
CopyURL(aSource);
|
|
||||||
} else if (aSource.mType == StyleShapeSourceType::Shape) {
|
|
||||||
SetBasicShape(aSource.mBasicShape, aSource.mReferenceBox);
|
|
||||||
} else if (aSource.mType == StyleShapeSourceType::Box) {
|
|
||||||
SetReferenceBox(aSource.mReferenceBox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~StyleShapeSource()
|
|
||||||
{
|
|
||||||
ReleaseRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
StyleShapeSource& operator=(const StyleShapeSource& aOther)
|
|
||||||
{
|
|
||||||
if (this == &aOther) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aOther.mType == StyleShapeSourceType::URL) {
|
|
||||||
CopyURL(aOther);
|
|
||||||
} else if (aOther.mType == StyleShapeSourceType::Shape) {
|
|
||||||
SetBasicShape(aOther.mBasicShape, aOther.mReferenceBox);
|
|
||||||
} else if (aOther.mType == StyleShapeSourceType::Box) {
|
|
||||||
SetReferenceBox(aOther.mReferenceBox);
|
|
||||||
} else {
|
|
||||||
ReleaseRef();
|
|
||||||
mReferenceBox = ReferenceBox::NoBox;
|
|
||||||
mType = StyleShapeSourceType::None_;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const StyleShapeSource& aOther) const
|
|
||||||
{
|
|
||||||
if (mType != aOther.mType) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mType == StyleShapeSourceType::URL) {
|
|
||||||
return mURL == aOther.mURL;
|
|
||||||
} else if (mType == StyleShapeSourceType::Shape) {
|
|
||||||
return *mBasicShape == *aOther.mBasicShape &&
|
|
||||||
mReferenceBox == aOther.mReferenceBox;
|
|
||||||
} else if (mType == StyleShapeSourceType::Box) {
|
|
||||||
return mReferenceBox == aOther.mReferenceBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const StyleShapeSource& aOther) const
|
|
||||||
{
|
|
||||||
return !(*this == aOther);
|
|
||||||
}
|
|
||||||
|
|
||||||
StyleShapeSourceType GetType() const
|
|
||||||
{
|
|
||||||
return mType;
|
|
||||||
}
|
|
||||||
|
|
||||||
FragmentOrURL* GetURL() const
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mType == StyleShapeSourceType::URL, "Wrong shape source type!");
|
|
||||||
return mURL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SetURL(const nsCSSValue* aValue)
|
|
||||||
{
|
|
||||||
if (!aValue->GetURLValue()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseRef();
|
|
||||||
|
|
||||||
mURL = new FragmentOrURL();
|
|
||||||
mURL->SetValue(aValue);
|
|
||||||
mType = StyleShapeSourceType::URL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
StyleBasicShape* GetBasicShape() const
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mType == StyleShapeSourceType::Shape, "Wrong shape source type!");
|
|
||||||
return mBasicShape;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetBasicShape(StyleBasicShape* aBasicShape,
|
|
||||||
ReferenceBox aReferenceBox)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aBasicShape, "expected pointer");
|
|
||||||
ReleaseRef();
|
|
||||||
mBasicShape = aBasicShape;
|
|
||||||
mBasicShape->AddRef();
|
|
||||||
mReferenceBox = aReferenceBox;
|
|
||||||
mType = StyleShapeSourceType::Shape;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReferenceBox GetReferenceBox() const
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mType == StyleShapeSourceType::Box ||
|
|
||||||
mType == StyleShapeSourceType::Shape,
|
|
||||||
"Wrong shape source type!");
|
|
||||||
return mReferenceBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetReferenceBox(ReferenceBox aReferenceBox)
|
|
||||||
{
|
|
||||||
ReleaseRef();
|
|
||||||
mReferenceBox = aReferenceBox;
|
|
||||||
mType = StyleShapeSourceType::Box;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void ReleaseRef()
|
|
||||||
{
|
|
||||||
if (mType == StyleShapeSourceType::Shape) {
|
|
||||||
NS_ASSERTION(mBasicShape, "expected pointer");
|
|
||||||
mBasicShape->Release();
|
|
||||||
} else if (mType == StyleShapeSourceType::URL) {
|
|
||||||
NS_ASSERTION(mURL, "expected pointer");
|
|
||||||
delete mURL;
|
|
||||||
}
|
|
||||||
// Both mBasicShape and mURL are pointers in a union. Nulling one of them
|
|
||||||
// nulls both of them.
|
|
||||||
mURL = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CopyURL(const StyleShapeSource& aOther)
|
|
||||||
{
|
|
||||||
ReleaseRef();
|
|
||||||
|
|
||||||
mURL = new FragmentOrURL(*aOther.mURL);
|
|
||||||
mType = StyleShapeSourceType::URL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* operator new(size_t) = delete;
|
|
||||||
|
|
||||||
union {
|
|
||||||
StyleBasicShape* mBasicShape;
|
|
||||||
FragmentOrURL* mURL;
|
|
||||||
};
|
|
||||||
StyleShapeSourceType mType = StyleShapeSourceType::None_;
|
|
||||||
ReferenceBox mReferenceBox = ReferenceBox::NoBox;
|
|
||||||
};
|
|
||||||
|
|
||||||
using StyleClipPath = StyleShapeSource<StyleClipPathGeometryBox>;
|
|
||||||
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
struct nsStyleFilter
|
struct nsStyleFilter
|
||||||
{
|
{
|
||||||
nsStyleFilter();
|
nsStyleFilter();
|
||||||
|
|
|
@ -5598,16 +5598,7 @@ if (IsCSSPropertyPrefEnabled("svg.transform-box.enabled")) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsCSSPropertyPrefEnabled("layout.css.clip-path-shapes.enabled")) {
|
var basicShapeOtherValues = [
|
||||||
gCSSProperties["clip-path"] = {
|
|
||||||
domProp: "clipPath",
|
|
||||||
inherited: false,
|
|
||||||
type: CSS_TYPE_LONGHAND,
|
|
||||||
initial_values: [ "none" ],
|
|
||||||
other_values: [
|
|
||||||
// SVG reference clip-path
|
|
||||||
"url(#my-clip-path)",
|
|
||||||
|
|
||||||
"polygon(20px 20px)",
|
"polygon(20px 20px)",
|
||||||
"polygon(20px 20%)",
|
"polygon(20px 20%)",
|
||||||
"polygon(20% 20%)",
|
"polygon(20% 20%)",
|
||||||
|
@ -5622,9 +5613,6 @@ if (IsCSSPropertyPrefEnabled("layout.css.clip-path-shapes.enabled")) {
|
||||||
"padding-box",
|
"padding-box",
|
||||||
"border-box",
|
"border-box",
|
||||||
"margin-box",
|
"margin-box",
|
||||||
"fill-box",
|
|
||||||
"stroke-box",
|
|
||||||
"view-box",
|
|
||||||
|
|
||||||
"polygon(0 0) content-box",
|
"polygon(0 0) content-box",
|
||||||
"border-box polygon(0 0)",
|
"border-box polygon(0 0)",
|
||||||
|
@ -5633,9 +5621,6 @@ if (IsCSSPropertyPrefEnabled("layout.css.clip-path-shapes.enabled")) {
|
||||||
"polygon(evenodd, 20vh 20em) padding-box",
|
"polygon(evenodd, 20vh 20em) padding-box",
|
||||||
"polygon(evenodd, 20vh calc(20% + 20em)) border-box",
|
"polygon(evenodd, 20vh calc(20% + 20em)) border-box",
|
||||||
"polygon(evenodd, 20vh 20vw) margin-box",
|
"polygon(evenodd, 20vh 20vw) margin-box",
|
||||||
"polygon(evenodd, 20pt 20cm) fill-box",
|
|
||||||
"polygon(evenodd, 20ex 20pc) stroke-box",
|
|
||||||
"polygon(evenodd, 20rem 20in) view-box",
|
|
||||||
|
|
||||||
"circle()",
|
"circle()",
|
||||||
"circle(at center)",
|
"circle(at center)",
|
||||||
|
@ -5678,8 +5663,9 @@ if (IsCSSPropertyPrefEnabled("layout.css.clip-path-shapes.enabled")) {
|
||||||
"inset(1px 2px round 3px / 3px)",
|
"inset(1px 2px round 3px / 3px)",
|
||||||
"inset(1px 2px 3px round 3px 2em / 20%)",
|
"inset(1px 2px 3px round 3px 2em / 20%)",
|
||||||
"inset(1px 2px 3px 4px round 3px 2vw 20% / 20px 3em 2vh 20%)",
|
"inset(1px 2px 3px 4px round 3px 2vw 20% / 20px 3em 2vh 20%)",
|
||||||
],
|
];
|
||||||
invalid_values: [
|
|
||||||
|
var basicShapeInvalidValues = [
|
||||||
"url(#test) url(#tes2)",
|
"url(#test) url(#tes2)",
|
||||||
"polygon (0 0)",
|
"polygon (0 0)",
|
||||||
"polygon(20px, 40px)",
|
"polygon(20px, 40px)",
|
||||||
|
@ -5759,8 +5745,9 @@ if (IsCSSPropertyPrefEnabled("layout.css.clip-path-shapes.enabled")) {
|
||||||
"inset(1px round)",
|
"inset(1px round)",
|
||||||
"inset(1px calc(2px + rubbish))",
|
"inset(1px calc(2px + rubbish))",
|
||||||
"inset(1px round 2px calc(3px + rubbish))",
|
"inset(1px round 2px calc(3px + rubbish))",
|
||||||
],
|
];
|
||||||
unbalanced_values: [
|
|
||||||
|
var basicShapeUnbalancedValues = [
|
||||||
"polygon(30% 30%",
|
"polygon(30% 30%",
|
||||||
"polygon(nonzero, 20% 20px",
|
"polygon(nonzero, 20% 20px",
|
||||||
"polygon(evenodd, 20px 20px",
|
"polygon(evenodd, 20px 20px",
|
||||||
|
@ -5776,7 +5763,42 @@ if (IsCSSPropertyPrefEnabled("layout.css.clip-path-shapes.enabled")) {
|
||||||
"inset(1px 2px 3px 4px",
|
"inset(1px 2px 3px 4px",
|
||||||
"inset(1px 2px 3px 4px round 5px",
|
"inset(1px 2px 3px 4px round 5px",
|
||||||
"inset(1px 2px 3px 4px round 5px / 6px",
|
"inset(1px 2px 3px 4px round 5px / 6px",
|
||||||
]
|
];
|
||||||
|
|
||||||
|
if (IsCSSPropertyPrefEnabled("layout.css.clip-path-shapes.enabled")) {
|
||||||
|
gCSSProperties["clip-path"] = {
|
||||||
|
domProp: "clipPath",
|
||||||
|
inherited: false,
|
||||||
|
type: CSS_TYPE_LONGHAND,
|
||||||
|
initial_values: [ "none" ],
|
||||||
|
other_values: [
|
||||||
|
// SVG reference clip-path
|
||||||
|
"url(#my-clip-path)",
|
||||||
|
|
||||||
|
"fill-box",
|
||||||
|
"stroke-box",
|
||||||
|
"view-box",
|
||||||
|
|
||||||
|
"polygon(evenodd, 20pt 20cm) fill-box",
|
||||||
|
"polygon(evenodd, 20ex 20pc) stroke-box",
|
||||||
|
"polygon(evenodd, 20rem 20in) view-box",
|
||||||
|
].concat(basicShapeOtherValues),
|
||||||
|
invalid_values: basicShapeInvalidValues,
|
||||||
|
unbalanced_values: basicShapeUnbalancedValues,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsCSSPropertyPrefEnabled("layout.css.shape-outside.enabled")) {
|
||||||
|
gCSSProperties["shape-outside"] = {
|
||||||
|
domProp: "shapeOutside",
|
||||||
|
inherited: false,
|
||||||
|
type: CSS_TYPE_LONGHAND,
|
||||||
|
initial_values: [ "none" ],
|
||||||
|
other_values: [
|
||||||
|
"url(#my-shape-outside)",
|
||||||
|
].concat(basicShapeOtherValues),
|
||||||
|
invalid_values: basicShapeInvalidValues,
|
||||||
|
unbalanced_values: basicShapeUnbalancedValues,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2603,6 +2603,9 @@ pref("layout.css.scroll-behavior.damping-ratio", "1.0");
|
||||||
// Is support for scroll-snap enabled?
|
// Is support for scroll-snap enabled?
|
||||||
pref("layout.css.scroll-snap.enabled", true);
|
pref("layout.css.scroll-snap.enabled", true);
|
||||||
|
|
||||||
|
// Is support for CSS shape-outside enabled?
|
||||||
|
pref("layout.css.shape-outside.enabled", false);
|
||||||
|
|
||||||
// Is support for document.fonts enabled?
|
// Is support for document.fonts enabled?
|
||||||
pref("layout.css.font-loading-api.enabled", true);
|
pref("layout.css.font-loading-api.enabled", true);
|
||||||
|
|
||||||
|
|
|
@ -176,6 +176,9 @@ user_pref("layout.css.prefixes.webkit", true);
|
||||||
// Enable -webkit-{min|max}-device-pixel-ratio media queries for testing
|
// Enable -webkit-{min|max}-device-pixel-ratio media queries for testing
|
||||||
user_pref("layout.css.prefixes.device-pixel-ratio-webkit", true);
|
user_pref("layout.css.prefixes.device-pixel-ratio-webkit", true);
|
||||||
|
|
||||||
|
// Enable CSS shape-outside for testing
|
||||||
|
user_pref("layout.css.shape-outside.enabled", true);
|
||||||
|
|
||||||
// Disable spammy layout warnings because they pollute test logs
|
// Disable spammy layout warnings because they pollute test logs
|
||||||
user_pref("layout.spammy_warnings.enabled", false);
|
user_pref("layout.spammy_warnings.enabled", false);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче