forked from mirrors/gecko-dev
Bug 1897605. Implement parsing of CSS 'anchor-scope'. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D210874
This commit is contained in:
parent
64564eb0ab
commit
060c48abc9
12 changed files with 180 additions and 7 deletions
|
|
@ -10,6 +10,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
|||
"discrete",
|
||||
new Set([
|
||||
"anchor-name",
|
||||
"anchor-scope",
|
||||
"align-content",
|
||||
"align-items",
|
||||
"align-self",
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ use.counter:
|
|||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
# Total of 2303 use counter metrics (excludes denominators).
|
||||
# Total of 2305 use counter metrics (excludes denominators).
|
||||
# Total of 354 'page' use counters.
|
||||
use.counter.page:
|
||||
svgsvgelement_getelementbyid:
|
||||
|
|
@ -15541,7 +15541,7 @@ use.counter.deprecated_ops.doc:
|
|||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
# Total of 698 'CSS (page)' use counters.
|
||||
# Total of 699 'CSS (page)' use counters.
|
||||
use.counter.css.page:
|
||||
css_align_content:
|
||||
type: counter
|
||||
|
|
@ -18603,6 +18603,23 @@ use.counter.css.page:
|
|||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
css_anchor_scope:
|
||||
type: counter
|
||||
description: >
|
||||
Whether a page used the CSS property anchor-scope.
|
||||
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_animation_composition:
|
||||
type: counter
|
||||
description: >
|
||||
|
|
@ -27409,7 +27426,7 @@ use.counter.css.page:
|
|||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
# Total of 698 'CSS (document)' use counters.
|
||||
# Total of 699 'CSS (document)' use counters.
|
||||
use.counter.css.doc:
|
||||
css_align_content:
|
||||
type: counter
|
||||
|
|
@ -30471,6 +30488,23 @@ use.counter.css.doc:
|
|||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
css_anchor_scope:
|
||||
type: counter
|
||||
description: >
|
||||
Whether a document used the CSS property anchor-scope.
|
||||
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_animation_composition:
|
||||
type: counter
|
||||
description: >
|
||||
|
|
|
|||
|
|
@ -621,6 +621,7 @@ cbindgen-types = [
|
|||
{ gecko = "StyleBaselineSource", servo = "crate::values::computed::BaselineSource" },
|
||||
{ gecko = "StyleAu", servo = "app_units::Au" },
|
||||
{ gecko = "StyleAnchorName", servo = "crate::values::computed::position::AnchorName" },
|
||||
{ gecko = "StyleAnchorScope", servo = "crate::values::computed::position::AnchorScope" },
|
||||
]
|
||||
|
||||
mapped-generic-types = [
|
||||
|
|
|
|||
|
|
@ -2093,7 +2093,8 @@ nsStyleDisplay::nsStyleDisplay()
|
|||
mBaselineSource(StyleBaselineSource::Auto),
|
||||
mWebkitLineClamp(0),
|
||||
mShapeMargin(LengthPercentage::Zero()),
|
||||
mShapeOutside(StyleShapeOutside::None()) {
|
||||
mShapeOutside(StyleShapeOutside::None()),
|
||||
mAnchorScope(StyleAnchorScope::None()) {
|
||||
MOZ_COUNT_CTOR(nsStyleDisplay);
|
||||
}
|
||||
|
||||
|
|
@ -2152,7 +2153,8 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
|
|||
mShapeImageThreshold(aSource.mShapeImageThreshold),
|
||||
mShapeMargin(aSource.mShapeMargin),
|
||||
mShapeOutside(aSource.mShapeOutside),
|
||||
mAnchorName(aSource.mAnchorName) {
|
||||
mAnchorName(aSource.mAnchorName),
|
||||
mAnchorScope(aSource.mAnchorScope) {
|
||||
MOZ_COUNT_CTOR(nsStyleDisplay);
|
||||
}
|
||||
|
||||
|
|
@ -2524,7 +2526,8 @@ nsChangeHint nsStyleDisplay::CalcDifference(
|
|||
mContainerType != aNewData.mContainerType ||
|
||||
mContain != aNewData.mContain ||
|
||||
mContainerName != aNewData.mContainerName ||
|
||||
mAnchorName != aNewData.mAnchorName)) {
|
||||
mAnchorName != aNewData.mAnchorName ||
|
||||
mAnchorScope != aNewData.mAnchorScope)) {
|
||||
hint |= nsChangeHint_NeutralChange;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1320,6 +1320,10 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
// anchor positioned elements may reference.
|
||||
mozilla::StyleAnchorName mAnchorName;
|
||||
|
||||
// 'none', 'all', or a list of one or more `<dashed-ident>` identifiers that
|
||||
// may identify anchor positioning anchor elements.
|
||||
mozilla::StyleAnchorScope mAnchorScope;
|
||||
|
||||
mozilla::Maybe<mozilla::WindowButtonType> GetWindowButtonType() const {
|
||||
if (MOZ_LIKELY(mDefaultAppearance == mozilla::StyleAppearance::None)) {
|
||||
return mozilla::Nothing();
|
||||
|
|
|
|||
|
|
@ -13312,6 +13312,31 @@ if (IsCSSPropertyPrefEnabled("layout.css.anchor-positioning.enabled")) {
|
|||
"--foo,",
|
||||
],
|
||||
};
|
||||
|
||||
gCSSProperties["anchor-scope"] = {
|
||||
domProp: "anchorScope",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: ["none"],
|
||||
other_values: [
|
||||
"all",
|
||||
"--foo",
|
||||
"--foo, --baz",
|
||||
"--foo,--baz",
|
||||
"--foo ,--baz",
|
||||
],
|
||||
invalid_values: [
|
||||
"all, --foo",
|
||||
"--foo, all",
|
||||
"--foo --bar",
|
||||
"foo",
|
||||
"none bar",
|
||||
"none --baz",
|
||||
"--foo bar",
|
||||
",--foo",
|
||||
"--foo,",
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
if (false) {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,19 @@ ${helpers.predefined_type(
|
|||
affects="",
|
||||
)}
|
||||
|
||||
// Changes do not invalidate our element. We handle notify/invalidating
|
||||
// any affected descendants elsewhere.
|
||||
${helpers.predefined_type(
|
||||
"anchor-scope",
|
||||
"AnchorScope",
|
||||
"computed::AnchorScope::none()",
|
||||
engines="gecko",
|
||||
animation_value_type="discrete",
|
||||
gecko_pref="layout.css.anchor-positioning.enabled",
|
||||
spec="https://drafts.csswg.org/css-anchor-position-1/#propdef-scope",
|
||||
affects="",
|
||||
)}
|
||||
|
||||
${helpers.predefined_type(
|
||||
"float",
|
||||
"Float",
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ pub use self::outline::OutlineStyle;
|
|||
pub use self::page::{PageName, PageOrientation, PageSize, PageSizeOrientation, PaperSize};
|
||||
pub use self::percentage::{NonNegativePercentage, Percentage};
|
||||
pub use self::position::AnchorName;
|
||||
pub use self::position::AnchorScope;
|
||||
pub use self::position::AspectRatio;
|
||||
pub use self::position::{
|
||||
GridAutoFlow, GridTemplateAreas, MasonryAutoFlow, Position, PositionOrAuto, ZIndex,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use crate::values::generics::position::Position as GenericPosition;
|
|||
use crate::values::generics::position::PositionComponent as GenericPositionComponent;
|
||||
use crate::values::generics::position::PositionOrAuto as GenericPositionOrAuto;
|
||||
use crate::values::generics::position::ZIndex as GenericZIndex;
|
||||
pub use crate::values::specified::position::{AnchorName, GridAutoFlow, GridTemplateAreas, MasonryAutoFlow};
|
||||
pub use crate::values::specified::position::{AnchorName, AnchorScope, GridAutoFlow, GridTemplateAreas, MasonryAutoFlow};
|
||||
use crate::Zero;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ pub use self::page::{PageName, PageOrientation, PageSize, PageSizeOrientation, P
|
|||
pub use self::percentage::{NonNegativePercentage, Percentage};
|
||||
pub use self::position::AspectRatio;
|
||||
pub use self::position::AnchorName;
|
||||
pub use self::position::AnchorScope;
|
||||
pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, PositionOrAuto};
|
||||
pub use self::position::{MasonryAutoFlow, MasonryItemOrder, MasonryPlacement};
|
||||
pub use self::position::{PositionComponent, ZIndex};
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ use std::collections::hash_map::Entry;
|
|||
use std::fmt::{self, Write};
|
||||
use style_traits::values::specified::AllowedNumericType;
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
use style_traits::{KeywordsCollectFn, SpecifiedValueInfo};
|
||||
use style_traits::arc_slice::ArcSlice;
|
||||
|
||||
/// The specified value of a CSS `<position>`
|
||||
|
|
@ -407,6 +408,94 @@ impl ToCss for AnchorName {
|
|||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-anchor-position-1/#propdef-scope
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
ToComputedValue,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
pub enum AnchorScope {
|
||||
/// `none`
|
||||
None,
|
||||
/// `all`
|
||||
All,
|
||||
/// `<dashed-ident>#`
|
||||
Idents(#[ignore_malloc_size_of = "Arc"] crate::ArcSlice<DashedIdent>),
|
||||
}
|
||||
|
||||
impl AnchorScope {
|
||||
/// Return the `none` value.
|
||||
pub fn none() -> Self {
|
||||
Self::None
|
||||
}
|
||||
|
||||
/// Returns whether this is the `none` value.
|
||||
pub fn is_none(&self) -> bool {
|
||||
*self == Self::None
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for AnchorScope {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
let first = input.expect_ident()?;
|
||||
if first.eq_ignore_ascii_case("none") {
|
||||
return Ok(Self::None);
|
||||
}
|
||||
if first.eq_ignore_ascii_case("all") {
|
||||
return Ok(Self::All);
|
||||
}
|
||||
// Authors using more than a handful of anchored elements is likely
|
||||
// uncommon, so we only pre-allocate for 8 on the stack here.
|
||||
let mut idents: SmallVec<[DashedIdent; 8]> = smallvec![DashedIdent::from_ident(
|
||||
location,
|
||||
first,
|
||||
)?];
|
||||
while input.try_parse(|input| input.expect_comma()).is_ok() {
|
||||
idents.push(DashedIdent::parse(context, input)?);
|
||||
}
|
||||
Ok(AnchorScope::Idents(ArcSlice::from_iter(idents.drain(..))))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for AnchorScope {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
Self::None => dest.write_str("none")?,
|
||||
Self::All => dest.write_str("all")?,
|
||||
Self::Idents(ref idents) => {
|
||||
if let Some((ref first, rest)) = idents.split_first() {
|
||||
first.to_css(dest)?;
|
||||
for name in rest {
|
||||
dest.write_str(", ")?;
|
||||
name.to_css(dest)?;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecifiedValueInfo for AnchorScope {
|
||||
fn collect_completion_keywords(f: KeywordsCollectFn) {
|
||||
// It would be nice if we could also list all the author defined dashed
|
||||
// idents in the doc, but that's not practical.
|
||||
f(&["none", "all"])
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a side, either horizontal or vertical, of a CSS position.
|
||||
pub trait Side {
|
||||
/// Returns the start side.
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ exclude = [
|
|||
]
|
||||
include = [
|
||||
"AnchorName",
|
||||
"AnchorScope",
|
||||
"AnimationTimeline",
|
||||
"AnimationIterationCount",
|
||||
"AnimationDirection",
|
||||
|
|
|
|||
Loading…
Reference in a new issue