mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1898887. Implement parsing of CSS 'inset-area' property. r=emilio,firefox-style-system-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D211955
This commit is contained in:
parent
d4a8bd78d9
commit
745b6de9a7
@ -98,6 +98,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
|||||||
"ime-mode",
|
"ime-mode",
|
||||||
"-moz-inert",
|
"-moz-inert",
|
||||||
"initial-letter",
|
"initial-letter",
|
||||||
|
"inset-area",
|
||||||
"isolation",
|
"isolation",
|
||||||
"justify-content",
|
"justify-content",
|
||||||
"justify-items",
|
"justify-items",
|
||||||
|
@ -107,7 +107,7 @@ use.counter:
|
|||||||
send_in_pings:
|
send_in_pings:
|
||||||
- use-counters
|
- use-counters
|
||||||
|
|
||||||
# Total of 2329 use counter metrics (excludes denominators).
|
# Total of 2343 use counter metrics (excludes denominators).
|
||||||
# Total of 364 'page' use counters.
|
# Total of 364 'page' use counters.
|
||||||
use.counter.page:
|
use.counter.page:
|
||||||
svgsvgelement_getelementbyid:
|
svgsvgelement_getelementbyid:
|
||||||
@ -14177,7 +14177,7 @@ use.counter.worker.service:
|
|||||||
send_in_pings:
|
send_in_pings:
|
||||||
- use-counters
|
- use-counters
|
||||||
|
|
||||||
# Total of 50 'deprecated operations (page)' use counters.
|
# Total of 56 'deprecated operations (page)' use counters.
|
||||||
use.counter.deprecated_ops.page:
|
use.counter.deprecated_ops.page:
|
||||||
domsubtree_modified:
|
domsubtree_modified:
|
||||||
type: counter
|
type: counter
|
||||||
@ -15131,7 +15131,7 @@ use.counter.deprecated_ops.page:
|
|||||||
send_in_pings:
|
send_in_pings:
|
||||||
- use-counters
|
- use-counters
|
||||||
|
|
||||||
# Total of 50 'deprecated operations (document)' use counters.
|
# Total of 56 'deprecated operations (document)' use counters.
|
||||||
use.counter.deprecated_ops.doc:
|
use.counter.deprecated_ops.doc:
|
||||||
domsubtree_modified:
|
domsubtree_modified:
|
||||||
type: counter
|
type: counter
|
||||||
@ -16085,7 +16085,7 @@ use.counter.deprecated_ops.doc:
|
|||||||
send_in_pings:
|
send_in_pings:
|
||||||
- use-counters
|
- use-counters
|
||||||
|
|
||||||
# Total of 701 'CSS (page)' use counters.
|
# Total of 702 'CSS (page)' use counters.
|
||||||
use.counter.css.page:
|
use.counter.css.page:
|
||||||
css_align_content:
|
css_align_content:
|
||||||
type: counter
|
type: counter
|
||||||
@ -16903,6 +16903,23 @@ use.counter.css.page:
|
|||||||
send_in_pings:
|
send_in_pings:
|
||||||
- use-counters
|
- use-counters
|
||||||
|
|
||||||
|
css_inset_area:
|
||||||
|
type: counter
|
||||||
|
description: >
|
||||||
|
Whether a page used the CSS property inset-area.
|
||||||
|
Compare against `use.counter.top_level_content_documents_destroyed`
|
||||||
|
to calculate the rate.
|
||||||
|
bugs:
|
||||||
|
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||||
|
data_reviews:
|
||||||
|
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||||
|
notification_emails:
|
||||||
|
- dom-core@mozilla.com
|
||||||
|
- emilio@mozilla.com
|
||||||
|
expires: never
|
||||||
|
send_in_pings:
|
||||||
|
- use-counters
|
||||||
|
|
||||||
css_isolation:
|
css_isolation:
|
||||||
type: counter
|
type: counter
|
||||||
description: >
|
description: >
|
||||||
@ -28004,7 +28021,7 @@ use.counter.css.page:
|
|||||||
send_in_pings:
|
send_in_pings:
|
||||||
- use-counters
|
- use-counters
|
||||||
|
|
||||||
# Total of 701 'CSS (document)' use counters.
|
# Total of 702 'CSS (document)' use counters.
|
||||||
use.counter.css.doc:
|
use.counter.css.doc:
|
||||||
css_align_content:
|
css_align_content:
|
||||||
type: counter
|
type: counter
|
||||||
@ -28822,6 +28839,23 @@ use.counter.css.doc:
|
|||||||
send_in_pings:
|
send_in_pings:
|
||||||
- use-counters
|
- use-counters
|
||||||
|
|
||||||
|
css_inset_area:
|
||||||
|
type: counter
|
||||||
|
description: >
|
||||||
|
Whether a document used the CSS property inset-area.
|
||||||
|
Compare against `use.counter.content_documents_destroyed`
|
||||||
|
to calculate the rate.
|
||||||
|
bugs:
|
||||||
|
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||||
|
data_reviews:
|
||||||
|
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||||
|
notification_emails:
|
||||||
|
- dom-core@mozilla.com
|
||||||
|
- emilio@mozilla.com
|
||||||
|
expires: never
|
||||||
|
send_in_pings:
|
||||||
|
- use-counters
|
||||||
|
|
||||||
css_isolation:
|
css_isolation:
|
||||||
type: counter
|
type: counter
|
||||||
description: >
|
description: >
|
||||||
@ -39922,4 +39956,3 @@ use.counter.css.doc:
|
|||||||
expires: never
|
expires: never
|
||||||
send_in_pings:
|
send_in_pings:
|
||||||
- use-counters
|
- use-counters
|
||||||
|
|
||||||
|
@ -627,6 +627,7 @@ cbindgen-types = [
|
|||||||
{ gecko = "StyleAnchorScope", servo = "crate::values::computed::position::AnchorScope" },
|
{ gecko = "StyleAnchorScope", servo = "crate::values::computed::position::AnchorScope" },
|
||||||
{ gecko = "StylePositionAnchor", servo = "crate::values::computed::position::PositionAnchor" },
|
{ gecko = "StylePositionAnchor", servo = "crate::values::computed::position::PositionAnchor" },
|
||||||
{ gecko = "StylePositionVisibility", servo = "crate::values::computed::position::PositionVisibility" },
|
{ gecko = "StylePositionVisibility", servo = "crate::values::computed::position::PositionVisibility" },
|
||||||
|
{ gecko = "StyleInsetArea", servo = "crate::values::computed::position::InsetArea" },
|
||||||
{ gecko = "StyleFontVariantEastAsian", servo = "crate::values::computed::font::FontVariantEastAsian" },
|
{ gecko = "StyleFontVariantEastAsian", servo = "crate::values::computed::font::FontVariantEastAsian" },
|
||||||
{ gecko = "StyleFontVariantLigatures", servo = "crate::values::computed::font::FontVariantLigatures" },
|
{ gecko = "StyleFontVariantLigatures", servo = "crate::values::computed::font::FontVariantLigatures" },
|
||||||
{ gecko = "StyleFontVariantNumeric", servo = "crate::values::computed::font::FontVariantNumeric" },
|
{ gecko = "StyleFontVariantNumeric", servo = "crate::values::computed::font::FontVariantNumeric" },
|
||||||
|
@ -1051,6 +1051,8 @@ nsStylePosition::nsStylePosition()
|
|||||||
mMaxHeight(StyleMaxSize::None()),
|
mMaxHeight(StyleMaxSize::None()),
|
||||||
mPositionAnchor(StylePositionAnchor::Auto()),
|
mPositionAnchor(StylePositionAnchor::Auto()),
|
||||||
mPositionVisibility(StylePositionVisibility::ALWAYS),
|
mPositionVisibility(StylePositionVisibility::ALWAYS),
|
||||||
|
mInsetArea(StyleInsetArea{StyleInsetAreaKeyword::None,
|
||||||
|
StyleInsetAreaKeyword::None}),
|
||||||
mFlexBasis(StyleFlexBasis::Size(StyleSize::Auto())),
|
mFlexBasis(StyleFlexBasis::Size(StyleSize::Auto())),
|
||||||
mAspectRatio(StyleAspectRatio::Auto()),
|
mAspectRatio(StyleAspectRatio::Auto()),
|
||||||
mGridAutoFlow(StyleGridAutoFlow::ROW),
|
mGridAutoFlow(StyleGridAutoFlow::ROW),
|
||||||
@ -1101,6 +1103,7 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
|
|||||||
mMaxHeight(aSource.mMaxHeight),
|
mMaxHeight(aSource.mMaxHeight),
|
||||||
mPositionAnchor(aSource.mPositionAnchor),
|
mPositionAnchor(aSource.mPositionAnchor),
|
||||||
mPositionVisibility(aSource.mPositionVisibility),
|
mPositionVisibility(aSource.mPositionVisibility),
|
||||||
|
mInsetArea(aSource.mInsetArea),
|
||||||
mFlexBasis(aSource.mFlexBasis),
|
mFlexBasis(aSource.mFlexBasis),
|
||||||
mGridAutoColumns(aSource.mGridAutoColumns),
|
mGridAutoColumns(aSource.mGridAutoColumns),
|
||||||
mGridAutoRows(aSource.mGridAutoRows),
|
mGridAutoRows(aSource.mGridAutoRows),
|
||||||
@ -1285,7 +1288,8 @@ nsChangeHint nsStylePosition::CalcDifference(
|
|||||||
hint |= nsChangeHint_NeutralChange;
|
hint |= nsChangeHint_NeutralChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPositionVisibility != aNewData.mPositionVisibility) {
|
if (mPositionVisibility != aNewData.mPositionVisibility ||
|
||||||
|
mInsetArea != aNewData.mInsetArea) {
|
||||||
hint |= nsChangeHint_NeutralChange;
|
hint |= nsChangeHint_NeutralChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,6 +747,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
|
|||||||
// element.
|
// element.
|
||||||
mozilla::StylePositionAnchor mPositionAnchor;
|
mozilla::StylePositionAnchor mPositionAnchor;
|
||||||
mozilla::StylePositionVisibility mPositionVisibility;
|
mozilla::StylePositionVisibility mPositionVisibility;
|
||||||
|
mozilla::StyleInsetArea mInsetArea;
|
||||||
|
|
||||||
mozilla::StyleFlexBasis mFlexBasis;
|
mozilla::StyleFlexBasis mFlexBasis;
|
||||||
StyleImplicitGridTracks mGridAutoColumns;
|
StyleImplicitGridTracks mGridAutoColumns;
|
||||||
|
@ -13338,6 +13338,85 @@ if (IsCSSPropertyPrefEnabled("layout.css.anchor-positioning.enabled")) {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gCSSProperties["inset-area"] = {
|
||||||
|
domProp: "insetArea",
|
||||||
|
inherited: false,
|
||||||
|
type: CSS_TYPE_LONGHAND,
|
||||||
|
initial_values: ["none"],
|
||||||
|
other_values: [
|
||||||
|
"center",
|
||||||
|
"span-all",
|
||||||
|
"left",
|
||||||
|
"right",
|
||||||
|
"span-left",
|
||||||
|
"span-right",
|
||||||
|
"x-start",
|
||||||
|
"x-end",
|
||||||
|
"span-x-start",
|
||||||
|
"span-x-end",
|
||||||
|
"x-self-start",
|
||||||
|
"x-self-end",
|
||||||
|
"span-x-self-start",
|
||||||
|
"span-x-self-end",
|
||||||
|
"top",
|
||||||
|
"bottom",
|
||||||
|
"span-top",
|
||||||
|
"span-bottom",
|
||||||
|
"y-start",
|
||||||
|
"y-end",
|
||||||
|
"span-y-start",
|
||||||
|
"span-y-end",
|
||||||
|
"y-self-start",
|
||||||
|
"y-self-end",
|
||||||
|
"span-y-self-start",
|
||||||
|
"span-y-self-end",
|
||||||
|
"block-start",
|
||||||
|
"block-end",
|
||||||
|
"span-block-start",
|
||||||
|
"span-block-end",
|
||||||
|
"inline-start",
|
||||||
|
"inline-end",
|
||||||
|
"span-inline-start",
|
||||||
|
"span-inline-end",
|
||||||
|
"self-block-start",
|
||||||
|
"self-block-end",
|
||||||
|
"span-self-block-start",
|
||||||
|
"span-self-block-end",
|
||||||
|
"self-inline-start",
|
||||||
|
"self-inline-end",
|
||||||
|
"span-self-inline-start",
|
||||||
|
"span-self-inline-end",
|
||||||
|
"start",
|
||||||
|
"end",
|
||||||
|
"span-start",
|
||||||
|
"span-end",
|
||||||
|
"self-start",
|
||||||
|
"self-end",
|
||||||
|
"span-self-start",
|
||||||
|
"span-self-end",
|
||||||
|
"center span-all",
|
||||||
|
"left center",
|
||||||
|
"span-left bottom",
|
||||||
|
"span-block-end inline-start",
|
||||||
|
"span-inline-start block-end",
|
||||||
|
"self-block-end span-self-inline-start",
|
||||||
|
"start center",
|
||||||
|
"span-start span-end",
|
||||||
|
"self-end span-self-start",
|
||||||
|
],
|
||||||
|
invalid_values: [
|
||||||
|
"auto",
|
||||||
|
"none left",
|
||||||
|
"left self-top",
|
||||||
|
"right block-end",
|
||||||
|
"top self-end",
|
||||||
|
"y-self-end x-end",
|
||||||
|
"inline-start self-block-end",
|
||||||
|
"span-self-inline-start start",
|
||||||
|
"end span-self-start",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
gCSSProperties["position-anchor"] = {
|
gCSSProperties["position-anchor"] = {
|
||||||
domProp: "positionAnchor",
|
domProp: "positionAnchor",
|
||||||
inherited: false,
|
inherited: false,
|
||||||
|
@ -566,6 +566,8 @@ class Longhand(Property):
|
|||||||
"ImageRendering",
|
"ImageRendering",
|
||||||
"InitialLetter",
|
"InitialLetter",
|
||||||
"Integer",
|
"Integer",
|
||||||
|
"InsetArea",
|
||||||
|
"InsetAreaKeyword",
|
||||||
"JustifyContent",
|
"JustifyContent",
|
||||||
"JustifyItems",
|
"JustifyItems",
|
||||||
"JustifySelf",
|
"JustifySelf",
|
||||||
|
@ -354,6 +354,18 @@ ${helpers.predefined_type(
|
|||||||
affects="layout",
|
affects="layout",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"inset-area",
|
||||||
|
"InsetArea",
|
||||||
|
"computed::InsetArea::none()",
|
||||||
|
engines="gecko",
|
||||||
|
initial_specified_value="specified::InsetArea::none()",
|
||||||
|
animation_value_type="discrete",
|
||||||
|
gecko_pref="layout.css.anchor-positioning.enabled",
|
||||||
|
spec="https://drafts.csswg.org/css-anchor-position-1/#typedef-inset-area",
|
||||||
|
affects="layout",
|
||||||
|
)}
|
||||||
|
|
||||||
${helpers.single_keyword(
|
${helpers.single_keyword(
|
||||||
"box-sizing",
|
"box-sizing",
|
||||||
"content-box border-box",
|
"content-box border-box",
|
||||||
|
@ -92,6 +92,7 @@ pub use self::position::AnchorName;
|
|||||||
pub use self::position::AnchorScope;
|
pub use self::position::AnchorScope;
|
||||||
pub use self::position::PositionAnchor;
|
pub use self::position::PositionAnchor;
|
||||||
pub use self::position::PositionVisibility;
|
pub use self::position::PositionVisibility;
|
||||||
|
pub use self::position::{InsetArea, InsetAreaKeyword};
|
||||||
pub use self::position::AspectRatio;
|
pub use self::position::AspectRatio;
|
||||||
pub use self::position::{
|
pub use self::position::{
|
||||||
GridAutoFlow, GridTemplateAreas, MasonryAutoFlow, Position, PositionOrAuto, ZIndex,
|
GridAutoFlow, GridTemplateAreas, MasonryAutoFlow, Position, PositionOrAuto, ZIndex,
|
||||||
|
@ -14,7 +14,7 @@ use crate::values::generics::position::PositionComponent as GenericPositionCompo
|
|||||||
use crate::values::generics::position::PositionOrAuto as GenericPositionOrAuto;
|
use crate::values::generics::position::PositionOrAuto as GenericPositionOrAuto;
|
||||||
use crate::values::generics::position::ZIndex as GenericZIndex;
|
use crate::values::generics::position::ZIndex as GenericZIndex;
|
||||||
pub use crate::values::specified::position::{GridAutoFlow, GridTemplateAreas, MasonryAutoFlow};
|
pub use crate::values::specified::position::{GridAutoFlow, GridTemplateAreas, MasonryAutoFlow};
|
||||||
pub use crate::values::specified::position::{AnchorName, AnchorScope, PositionAnchor, PositionVisibility};
|
pub use crate::values::specified::position::{AnchorName, AnchorScope, InsetArea, InsetAreaKeyword, PositionAnchor, PositionVisibility};
|
||||||
use crate::Zero;
|
use crate::Zero;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ToCss};
|
use style_traits::{CssWriter, ToCss};
|
||||||
|
@ -83,6 +83,7 @@ pub use self::percentage::{NonNegativePercentage, Percentage};
|
|||||||
pub use self::position::AspectRatio;
|
pub use self::position::AspectRatio;
|
||||||
pub use self::position::AnchorName;
|
pub use self::position::AnchorName;
|
||||||
pub use self::position::AnchorScope;
|
pub use self::position::AnchorScope;
|
||||||
|
pub use self::position::{InsetArea, InsetAreaKeyword};
|
||||||
pub use self::position::PositionAnchor;
|
pub use self::position::PositionAnchor;
|
||||||
pub use self::position::PositionVisibility;
|
pub use self::position::PositionVisibility;
|
||||||
pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, PositionOrAuto};
|
pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, PositionOrAuto};
|
||||||
|
@ -535,6 +535,345 @@ impl PositionVisibility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
MallocSizeOf,
|
||||||
|
Parse,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToComputedValue,
|
||||||
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
|
)]
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
#[repr(u8)]
|
||||||
|
/// Possible values for the `inset-area` preperty's keywords.
|
||||||
|
/// https://drafts.csswg.org/css-anchor-position-1/#propdef-inset-area
|
||||||
|
pub enum InsetAreaKeyword {
|
||||||
|
None,
|
||||||
|
|
||||||
|
// Common (shared) keywords:
|
||||||
|
Center,
|
||||||
|
SpanAll,
|
||||||
|
|
||||||
|
// Horizontal keywords:
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
SpanLeft,
|
||||||
|
SpanRight,
|
||||||
|
XStart,
|
||||||
|
XEnd,
|
||||||
|
SpanXStart,
|
||||||
|
SpanXEnd,
|
||||||
|
XSelfStart,
|
||||||
|
XSelfEnd,
|
||||||
|
SpanXSelfStart,
|
||||||
|
SpanXSelfEnd,
|
||||||
|
// Vertical keywords:
|
||||||
|
Top,
|
||||||
|
Bottom,
|
||||||
|
SpanTop,
|
||||||
|
SpanBottom,
|
||||||
|
YStart,
|
||||||
|
YEnd,
|
||||||
|
SpanYStart,
|
||||||
|
SpanYEnd,
|
||||||
|
YSelfStart,
|
||||||
|
YSelfEnd,
|
||||||
|
SpanYSelfStart,
|
||||||
|
SpanYSelfEnd,
|
||||||
|
|
||||||
|
// Block keywords:
|
||||||
|
BlockStart,
|
||||||
|
BlockEnd,
|
||||||
|
SpanBlockStart,
|
||||||
|
SpanBlockEnd,
|
||||||
|
// Inline keywords:
|
||||||
|
InlineStart,
|
||||||
|
InlineEnd,
|
||||||
|
SpanInlineStart,
|
||||||
|
SpanInlineEnd,
|
||||||
|
|
||||||
|
// "Self" block keywords:
|
||||||
|
SelfBlockStart,
|
||||||
|
SelfBlockEnd,
|
||||||
|
SpanSelfBlockStart,
|
||||||
|
SpanSelfBlockEnd,
|
||||||
|
// "Self" inline keywords:
|
||||||
|
SelfInlineStart,
|
||||||
|
SelfInlineEnd,
|
||||||
|
SpanSelfInlineStart,
|
||||||
|
SpanSelfInlineEnd,
|
||||||
|
|
||||||
|
// Inferred axis keywords:
|
||||||
|
Start,
|
||||||
|
End,
|
||||||
|
SpanStart,
|
||||||
|
SpanEnd,
|
||||||
|
|
||||||
|
// "Self" inferred axis keywords:
|
||||||
|
SelfStart,
|
||||||
|
SelfEnd,
|
||||||
|
SpanSelfStart,
|
||||||
|
SpanSelfEnd,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for InsetAreaKeyword {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
impl InsetAreaKeyword {
|
||||||
|
#[inline]
|
||||||
|
pub fn none() -> Self {
|
||||||
|
Self::None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_none(&self) -> bool {
|
||||||
|
*self == Self::None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Is a value that's common to all compatible keyword groupings.
|
||||||
|
pub fn is_common(&self) -> bool {
|
||||||
|
*self == Self::Center || *self == Self::SpanAll
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_horizontal(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::Left |
|
||||||
|
Self::Right |
|
||||||
|
Self::SpanLeft |
|
||||||
|
Self::SpanRight |
|
||||||
|
Self::XStart |
|
||||||
|
Self::XEnd |
|
||||||
|
Self::SpanXStart |
|
||||||
|
Self::SpanXEnd |
|
||||||
|
Self::XSelfStart |
|
||||||
|
Self::XSelfEnd |
|
||||||
|
Self::SpanXSelfStart |
|
||||||
|
Self::SpanXSelfEnd
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn is_vertical(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::Top |
|
||||||
|
Self::Bottom |
|
||||||
|
Self::SpanTop |
|
||||||
|
Self::SpanBottom |
|
||||||
|
Self::YStart |
|
||||||
|
Self::YEnd |
|
||||||
|
Self::SpanYStart |
|
||||||
|
Self::SpanYEnd |
|
||||||
|
Self::YSelfStart |
|
||||||
|
Self::YSelfEnd |
|
||||||
|
Self::SpanYSelfStart |
|
||||||
|
Self::SpanYSelfEnd
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_block(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::BlockStart | Self::BlockEnd | Self::SpanBlockStart | Self::SpanBlockEnd
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn is_inline(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::InlineStart | Self::InlineEnd | Self::SpanInlineStart | Self::SpanInlineEnd
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_self_block(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::SelfBlockStart |
|
||||||
|
Self::SelfBlockEnd |
|
||||||
|
Self::SpanSelfBlockStart |
|
||||||
|
Self::SpanSelfBlockEnd
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn is_self_inline(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::SelfInlineStart |
|
||||||
|
Self::SelfInlineEnd |
|
||||||
|
Self::SpanSelfInlineStart |
|
||||||
|
Self::SpanSelfInlineEnd
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_inferred_logical(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::Start | Self::End | Self::SpanStart | Self::SpanEnd
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_self_inferred_logical(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::SelfStart | Self::SelfEnd | Self::SpanSelfStart | Self::SpanSelfEnd
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_compatible_pairing(first: InsetAreaKeyword, second: InsetAreaKeyword) -> bool {
|
||||||
|
if first.is_none() || second.is_none() {
|
||||||
|
// `none` is not allowed as one of the keywords when two keywords are
|
||||||
|
// provided.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if first.is_common() || second.is_common() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if first.is_horizontal() {
|
||||||
|
return second.is_vertical();
|
||||||
|
}
|
||||||
|
if first.is_vertical() {
|
||||||
|
return second.is_horizontal();
|
||||||
|
}
|
||||||
|
if first.is_block() {
|
||||||
|
return second.is_inline();
|
||||||
|
}
|
||||||
|
if first.is_inline() {
|
||||||
|
return second.is_block();
|
||||||
|
}
|
||||||
|
if first.is_self_block() {
|
||||||
|
return second.is_self_inline();
|
||||||
|
}
|
||||||
|
if first.is_self_inline() {
|
||||||
|
return second.is_self_block();
|
||||||
|
}
|
||||||
|
if first.is_inferred_logical() {
|
||||||
|
return second.is_inferred_logical();
|
||||||
|
}
|
||||||
|
if first.is_self_inferred_logical() {
|
||||||
|
return second.is_self_inferred_logical();
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert!(false, "Not reached");
|
||||||
|
|
||||||
|
// Return false to increase the chances of this being reported to us if we
|
||||||
|
// ever were to get here.
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
MallocSizeOf,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToComputedValue,
|
||||||
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
|
)]
|
||||||
|
#[repr(C)]
|
||||||
|
/// https://drafts.csswg.org/css-anchor-position-1/#propdef-inset-area
|
||||||
|
pub struct InsetArea {
|
||||||
|
/// First keyword, if any.
|
||||||
|
pub first: InsetAreaKeyword,
|
||||||
|
/// Second keyword, if any.
|
||||||
|
#[css(skip_if = "InsetAreaKeyword::is_none")]
|
||||||
|
pub second: InsetAreaKeyword,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
impl InsetArea {
|
||||||
|
#[inline]
|
||||||
|
pub fn none() -> Self {
|
||||||
|
Self {
|
||||||
|
first: InsetAreaKeyword::None,
|
||||||
|
second: InsetAreaKeyword::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_none(&self) -> bool {
|
||||||
|
self.first.is_none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for InsetArea {
|
||||||
|
fn parse<'i, 't>(
|
||||||
|
_context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
let mut first = InsetAreaKeyword::parse(input)?;
|
||||||
|
if first.is_none() {
|
||||||
|
return Ok(Self::none());
|
||||||
|
}
|
||||||
|
|
||||||
|
let location = input.current_source_location();
|
||||||
|
let second = input.try_parse(InsetAreaKeyword::parse);
|
||||||
|
if let Ok(InsetAreaKeyword::None) = second {
|
||||||
|
// `none` is only allowed as a single value
|
||||||
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
|
}
|
||||||
|
let mut second = second.unwrap_or(InsetAreaKeyword::None);
|
||||||
|
if second.is_none() {
|
||||||
|
// Either there was no second keyword and try_parse returned a
|
||||||
|
// BasicParseErrorKind::EndOfInput, or else the second "keyword"
|
||||||
|
// was invalid. We assume the former case here, and if it's the
|
||||||
|
// latter case then our caller detects the error (try_parse will,
|
||||||
|
// have rewound, leaving an unparsed token).
|
||||||
|
return Ok(Self { first, second });
|
||||||
|
}
|
||||||
|
|
||||||
|
if !is_compatible_pairing(first, second) {
|
||||||
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize by applying the shortest serialization principle:
|
||||||
|
// https://drafts.csswg.org/cssom/#serializing-css-values
|
||||||
|
if first.is_inferred_logical() ||
|
||||||
|
second.is_inferred_logical() ||
|
||||||
|
first.is_self_inferred_logical() ||
|
||||||
|
second.is_self_inferred_logical() ||
|
||||||
|
(first.is_common() && second.is_common())
|
||||||
|
{
|
||||||
|
// In these cases we must not change the order of the keywords
|
||||||
|
// since their meaning is inferred from their order. However, if
|
||||||
|
// both keywords are the same, only one should be set.
|
||||||
|
if first == second {
|
||||||
|
second = InsetAreaKeyword::None;
|
||||||
|
}
|
||||||
|
} else if second == InsetAreaKeyword::SpanAll {
|
||||||
|
// Span-all is the default behavior, so specifying `span-all` is
|
||||||
|
// superfluous.
|
||||||
|
second = InsetAreaKeyword::None;
|
||||||
|
} else if first == InsetAreaKeyword::SpanAll {
|
||||||
|
// Same here, but the non-superfluous keyword must come first.
|
||||||
|
first = second;
|
||||||
|
second = InsetAreaKeyword::None;
|
||||||
|
} else if first.is_vertical() ||
|
||||||
|
second.is_horizontal() ||
|
||||||
|
first.is_inline() ||
|
||||||
|
second.is_block() ||
|
||||||
|
first.is_self_inline() ||
|
||||||
|
second.is_self_block()
|
||||||
|
{
|
||||||
|
// Canonical order is horizontal before vertical, block before inline.
|
||||||
|
std::mem::swap(&mut first, &mut second);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { first, second })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents a side, either horizontal or vertical, of a CSS position.
|
/// Represents a side, either horizontal or vertical, of a CSS position.
|
||||||
pub trait Side {
|
pub trait Side {
|
||||||
/// Returns the start side.
|
/// Returns the start side.
|
||||||
|
@ -105,6 +105,8 @@ include = [
|
|||||||
"FontVariantEastAsian",
|
"FontVariantEastAsian",
|
||||||
"FontVariantLigatures",
|
"FontVariantLigatures",
|
||||||
"FontVariantNumeric",
|
"FontVariantNumeric",
|
||||||
|
"InsetArea",
|
||||||
|
"InsetAreaKeyword",
|
||||||
"ComputedFontStretchRange",
|
"ComputedFontStretchRange",
|
||||||
"ComputedFontStyleDescriptor",
|
"ComputedFontStyleDescriptor",
|
||||||
"ComputedFontWeightRange",
|
"ComputedFontWeightRange",
|
||||||
|
Loading…
Reference in New Issue
Block a user