diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2019-11-04 17:04:52 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-04 17:04:52 -0500 |
commit | 4886788a8ed975cbc1ae4f05cd8ce0ab41cd30e2 (patch) | |
tree | 2137039290d48b317a93ebfb594792d2a4540f26 /components | |
parent | 1d450ba1f30b970d5ae007f42139190f8d265ce1 (diff) | |
parent | 83f8bec0b535d7c1f8068fc46dc41e5096ae95b2 (diff) | |
download | servo-4886788a8ed975cbc1ae4f05cd8ce0ab41cd30e2.tar.gz servo-4886788a8ed975cbc1ae4f05cd8ce0ab41cd30e2.zip |
Auto merge of #24641 - emilio:gecko-sync, r=emilio
style: Sync changes from mozilla-central.
See individual commits for details.
https://bugzilla.mozilla.org/show_bug.cgi?id=1593642
Diffstat (limited to 'components')
38 files changed, 265 insertions, 300 deletions
diff --git a/components/malloc_size_of/lib.rs b/components/malloc_size_of/lib.rs index af7147d8edb..1d5cbeaff1e 100644 --- a/components/malloc_size_of/lib.rs +++ b/components/malloc_size_of/lib.rs @@ -837,6 +837,7 @@ malloc_size_of_is_0!(app_units::Au); malloc_size_of_is_0!(cssparser::RGBA, cssparser::TokenSerializationType); +#[cfg(feature = "servo")] malloc_size_of_is_0!(csp::Destination); #[cfg(feature = "url")] diff --git a/components/selectors/context.rs b/components/selectors/context.rs index d159891ff02..44d586c8d84 100644 --- a/components/selectors/context.rs +++ b/components/selectors/context.rs @@ -189,15 +189,6 @@ where } } - /// Override the quirks mode we're matching against. - /// - /// FIXME(emilio): This is a hack for XBL quirks-mode mismatches. - #[inline] - pub fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) { - self.quirks_mode = quirks_mode; - self.classes_and_ids_case_sensitivity = quirks_mode.classes_and_ids_case_sensitivity(); - } - /// Whether we're matching a nested selector. #[inline] pub fn is_nested(&self) -> bool { diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index 45acc13e7e1..49b7f3dbd32 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -667,7 +667,7 @@ where match *selector { Component::Combinator(_) => unreachable!(), - Component::Part(ref part) => element.is_part(part), + Component::Part(ref parts) => parts.iter().all(|part| element.is_part(part)), Component::Slotted(ref selector) => { // <slots> are never flattened tree slottables. !element.is_html_slot_element() && diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 982dff793a8..507121bbf97 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -607,7 +607,7 @@ impl<Impl: SelectorImpl> Selector<Impl> { } #[inline] - pub fn part(&self) -> Option<&Impl::PartName> { + pub fn parts(&self) -> Option<&[Impl::PartName]> { if !self.is_part() { return None; } @@ -1013,7 +1013,7 @@ pub enum Component<Impl: SelectorImpl> { Slotted(Selector<Impl>), /// The `::part` pseudo-element. /// https://drafts.csswg.org/css-shadow-parts/#part - Part(#[shmem(field_bound)] Impl::PartName), + Part(#[shmem(field_bound)] Box<[Impl::PartName]>), /// The `:host` pseudo-class: /// /// https://drafts.csswg.org/css-scoping/#host-selector @@ -1302,9 +1302,14 @@ impl<Impl: SelectorImpl> ToCss for Component<Impl> { selector.to_css(dest)?; dest.write_char(')') }, - Part(ref part_name) => { + Part(ref part_names) => { dest.write_str("::part(")?; - display_to_css_identifier(part_name, dest)?; + for (i, name) in part_names.iter().enumerate() { + if i != 0 { + dest.write_char(' ')?; + } + display_to_css_identifier(name, dest)?; + } dest.write_char(')') }, PseudoElement(ref p) => p.to_css(dest), @@ -1626,7 +1631,7 @@ enum SimpleSelectorParseResult<Impl: SelectorImpl> { SimpleSelector(Component<Impl>), PseudoElement(Impl::PseudoElement), SlottedPseudo(Selector<Impl>), - PartPseudo(Impl::PartName), + PartPseudo(Box<[Impl::PartName]>), } #[derive(Debug)] @@ -2029,10 +2034,10 @@ where SimpleSelectorParseResult::SimpleSelector(s) => { builder.push_simple_selector(s); }, - SimpleSelectorParseResult::PartPseudo(part_name) => { + SimpleSelectorParseResult::PartPseudo(part_names) => { state.insert(SelectorParsingState::AFTER_PART); builder.push_combinator(Combinator::Part); - builder.push_simple_selector(Component::Part(part_name)); + builder.push_simple_selector(Component::Part(part_names)); }, SimpleSelectorParseResult::SlottedPseudo(selector) => { state.insert(SelectorParsingState::AFTER_SLOTTED); @@ -2193,10 +2198,15 @@ where input.new_custom_error(SelectorParseErrorKind::InvalidState) ); } - let name = input.parse_nested_block(|input| { - Ok(input.expect_ident()?.as_ref().into()) + let names = input.parse_nested_block(|input| { + let mut result = Vec::with_capacity(1); + result.push(input.expect_ident()?.as_ref().into()); + while !input.is_exhausted() { + result.push(input.expect_ident()?.as_ref().into()); + } + Ok(result.into_boxed_slice()) })?; - return Ok(Some(SimpleSelectorParseResult::PartPseudo(name))); + return Ok(Some(SimpleSelectorParseResult::PartPseudo(names))); } if P::parse_slotted(parser) && name.eq_ignore_ascii_case("slotted") { if !state.allows_slotted() { @@ -3051,8 +3061,7 @@ pub mod tests { assert!(parse("::part()").is_err()); assert!(parse("::part(42)").is_err()); - // Though note https://github.com/w3c/csswg-drafts/issues/3502 - assert!(parse("::part(foo bar)").is_err()); + assert!(parse("::part(foo bar)").is_ok()); assert!(parse("::part(foo):hover").is_ok()); assert!(parse("::part(foo) + bar").is_err()); diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 1a727387b7e..f15c64e2f56 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -25,7 +25,6 @@ servo-layout-2020 = [] gecko_debug = [] gecko_refcount_logging = [] gecko_profiler = [] -moz_xbl = [] [dependencies] app_units = "0.7" diff --git a/components/style/build_gecko.rs b/components/style/build_gecko.rs index 86d2098d063..a502b7d45f9 100644 --- a/components/style/build_gecko.rs +++ b/components/style/build_gecko.rs @@ -109,7 +109,10 @@ fn add_headers_recursively(path: PathBuf, added_paths: &mut HashSet<PathBuf>) { fn add_include(name: &str) -> String { let mut added_paths = ADDED_PATHS.lock().unwrap(); - let file = search_include(name).expect("Include not found!"); + let file = match search_include(name) { + Some(file) => file, + None => panic!("Include not found: {}", name), + }; let result = String::from(file.to_str().unwrap()); add_headers_recursively(file, &mut *added_paths); result diff --git a/components/style/dom.rs b/components/style/dom.rs index 7d56cc543e7..2ea64bbb3dc 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -776,14 +776,6 @@ pub trait TElement: return data.hint.has_animation_hint(); } - /// Returns the anonymous content for the current element's XBL binding, - /// given if any. - /// - /// This is used in Gecko for XBL. - fn xbl_binding_anonymous_content(&self) -> Option<Self::ConcreteNode> { - None - } - /// The shadow root this element is a host of. fn shadow_root(&self) -> Option<<Self::ConcreteNode as TNode>::ConcreteShadowRoot>; diff --git a/components/style/gecko/media_features.rs b/components/style/gecko/media_features.rs index ce084c9d16b..e3de8dbfaaa 100644 --- a/components/style/gecko/media_features.rs +++ b/components/style/gecko/media_features.rs @@ -598,8 +598,7 @@ lazy_static! { atom!("device-pixel-ratio"), AllowsRanges::Yes, Evaluator::Float(eval_device_pixel_ratio), - ParsingRequirements::WEBKIT_PREFIX | - ParsingRequirements::WEBKIT_DEVICE_PIXEL_RATIO_PREF_ENABLED, + ParsingRequirements::WEBKIT_PREFIX, ), // -webkit-transform-3d. feature!( diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index fd0ac9db8a6..c2c4a0c0feb 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -44,8 +44,6 @@ use crate::gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWThe use crate::gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::nsChangeHint; -#[cfg(feature = "moz_xbl")] -use crate::gecko_bindings::structs::nsXBLBinding as RawGeckoXBLBinding; use crate::gecko_bindings::structs::Document_DocumentTheme as DocumentTheme; use crate::gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; use crate::gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT; @@ -86,8 +84,6 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::mem; use std::ptr; -#[cfg(not(feature = "moz_xbl"))] -use values::Impossible; #[inline] fn elements_with_id<'a, 'le>( @@ -317,7 +313,7 @@ impl<'ln> GeckoNode<'ln> { } if let Some(parent) = parent_el { - if parent.shadow_root().is_some() || parent.xbl_binding().is_some() { + if parent.shadow_root().is_some() { return false; } } @@ -530,52 +526,6 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> { } } -/// A Simple wrapper over a non-null Gecko `nsXBLBinding` pointer. -#[cfg(feature = "moz_xbl")] -#[derive(Clone, Copy)] -pub struct GeckoXBLBinding<'lb>(pub &'lb RawGeckoXBLBinding); - -#[cfg(feature = "moz_xbl")] -impl<'lb> GeckoXBLBinding<'lb> { - #[inline] - fn base_binding(&self) -> Option<Self> { - unsafe { self.0.mNextBinding.mRawPtr.as_ref().map(GeckoXBLBinding) } - } - - #[inline] - fn anon_content(&self) -> *const nsIContent { - self.0.mContent.raw::<nsIContent>() - } - - // This duplicates the logic in Gecko's - // nsBindingManager::GetBindingWithContent. - fn binding_with_content(&self) -> Option<Self> { - let mut binding = *self; - loop { - if !binding.anon_content().is_null() { - return Some(binding); - } - binding = binding.base_binding()?; - } - } -} - -/// A stub wraper for GeckoXBLBinding. -#[cfg(not(feature = "moz_xbl"))] -pub struct GeckoXBLBinding<'lb>(&'lb Impossible); - -#[cfg(not(feature = "moz_xbl"))] -impl<'lb> GeckoXBLBinding<'lb> { - #[inline] - fn anon_content(&self) -> *const nsIContent { - match *self.0 {} - } - - fn binding_with_content(&self) -> Option<Self> { - None - } -} - /// A simple wrapper over a non-null Gecko `Element` pointer. #[derive(Clone, Copy)] pub struct GeckoElement<'le>(pub &'le RawGeckoElement); @@ -701,39 +651,6 @@ impl<'le> GeckoElement<'le> { }) } - #[cfg(feature = "moz_xbl")] - #[inline] - fn may_be_in_binding_manager(&self) -> bool { - self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) != 0 - } - - #[cfg(feature = "moz_xbl")] - #[inline] - fn xbl_binding(&self) -> Option<GeckoXBLBinding<'le>> { - if !self.may_be_in_binding_manager() { - return None; - } - - let slots = self.extended_slots()?; - unsafe { slots.mXBLBinding.mRawPtr.as_ref().map(GeckoXBLBinding) } - } - - #[cfg(not(feature = "moz_xbl"))] - #[inline] - fn xbl_binding(&self) -> Option<GeckoXBLBinding<'le>> { - None - } - - #[inline] - fn xbl_binding_with_content(&self) -> Option<GeckoXBLBinding<'le>> { - self.xbl_binding().and_then(|b| b.binding_with_content()) - } - - #[inline] - fn has_xbl_binding_with_content(&self) -> bool { - !self.xbl_binding_with_content().is_none() - } - #[inline] fn namespace_id(&self) -> i32 { self.as_node().node_info().mInner.mNamespaceID @@ -1107,9 +1024,8 @@ impl<'le> TElement for GeckoElement<'le> { // This condition is similar to the check that // StyleChildrenIterator::IsNeeded does, except that it might return // true if we used to (but no longer) have anonymous content from - // ::before/::after, XBL bindings, or nsIAnonymousContentCreators. + // ::before/::after, or nsIAnonymousContentCreators. if self.is_in_anonymous_subtree() || - self.has_xbl_binding_with_content() || self.is_html_slot_element() || self.shadow_root().is_some() || self.may_have_anonymous_children() @@ -1595,11 +1511,6 @@ impl<'le> TElement for GeckoElement<'le> { self.may_have_animations() && unsafe { Gecko_ElementHasCSSTransitions(self.0) } } - fn xbl_binding_anonymous_content(&self) -> Option<GeckoNode<'le>> { - self.xbl_binding_with_content() - .map(|b| unsafe { GeckoNode::from_content(&*b.anon_content()) }) - } - fn might_need_transitions_update( &self, old_style: Option<&ComputedValues>, diff --git a/components/style/invalidation/element/document_state.rs b/components/style/invalidation/element/document_state.rs index 77b205f1b26..4e29e91eb0e 100644 --- a/components/style/invalidation/element/document_state.rs +++ b/components/style/invalidation/element/document_state.rs @@ -31,9 +31,6 @@ impl Default for InvalidationMatchingData { /// An invalidation processor for style changes due to state and attribute /// changes. pub struct DocumentStateInvalidationProcessor<'a, E: TElement, I> { - // TODO(emilio): We might want to just run everything for every possible - // binding along with the document data, or just apply the XBL stuff to the - // bound subtrees. rules: I, matching_context: MatchingContext<'a, E::Impl>, document_states_changed: DocumentState, diff --git a/components/style/invalidation/element/invalidator.rs b/components/style/invalidation/element/invalidator.rs index 2889c3e7b9d..3487d7b9353 100644 --- a/components/style/invalidation/element/invalidator.rs +++ b/components/style/invalidation/element/invalidator.rs @@ -28,7 +28,7 @@ where /// Whether the invalidation processor only cares about light-tree /// descendants of a given element, that is, doesn't invalidate - /// pseudo-elements, NAC, or XBL anon content. + /// pseudo-elements, NAC, shadow dom... fn light_tree_only(&self) -> bool { false } @@ -455,11 +455,6 @@ where let mut sibling_invalidations = InvalidationVector::new(); for child in parent.dom_children() { - // TODO(emilio): We handle <xbl:children> fine, because they appear - // in selector-matching (note bug 1374247, though). - // - // This probably needs a shadow root check on `child` here, and - // recursing if that's the case. let child = match child.as_element() { Some(e) => e, None => continue, @@ -574,13 +569,6 @@ where any_descendant |= self.invalidate_dom_descendants_of(root.as_node(), invalidations); } - // This is needed for XBL (technically) unconditionally, because XBL - // bindings do not block combinators in any way. However this is kinda - // broken anyway, since we should be looking at XBL rules too. - if let Some(anon_content) = self.element.xbl_binding_anonymous_content() { - any_descendant |= self.invalidate_dom_descendants_of(anon_content, invalidations); - } - if let Some(marker) = self.element.marker_pseudo_element() { any_descendant |= self.invalidate_pseudo_element_or_nac(marker, invalidations); } diff --git a/components/style/lib.rs b/components/style/lib.rs index 35070b0f254..354950f9c15 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -78,7 +78,6 @@ extern crate parking_lot; extern crate precomputed_hash; extern crate rayon; extern crate selectors; -#[cfg(feature = "servo")] #[macro_use] extern crate serde; pub extern crate servo_arc; diff --git a/components/style/media_queries/media_feature.rs b/components/style/media_queries/media_feature.rs index c5251f7419f..a273e7f51be 100644 --- a/components/style/media_queries/media_feature.rs +++ b/components/style/media_queries/media_feature.rs @@ -123,9 +123,6 @@ bitflags! { const CHROME_AND_UA_ONLY = 1 << 0; /// The feature requires a -webkit- prefix. const WEBKIT_PREFIX = 1 << 1; - /// The feature requires the webkit-device-pixel-ratio preference to be - /// enabled. - const WEBKIT_DEVICE_PIXEL_RATIO_PREF_ENABLED = 1 << 2; } } diff --git a/components/style/media_queries/media_feature_expression.rs b/components/style/media_queries/media_feature_expression.rs index d4124450dc5..4704fab0ffc 100644 --- a/components/style/media_queries/media_feature_expression.rs +++ b/components/style/media_queries/media_feature_expression.rs @@ -242,6 +242,17 @@ fn consume_operation_or_colon(input: &mut Parser) -> Result<Option<Operator>, () })) } +#[allow(unused_variables)] +fn disabled_by_pref(feature: &Atom) -> bool { + #[cfg(feature = "gecko")] + { + if *feature == atom!("-moz-touch-enabled") { + return !static_prefs::pref!("layout.css.moz-touch-enabled.enabled"); + } + } + false +} + impl MediaFeatureExpression { fn new( feature_index: usize, @@ -279,81 +290,53 @@ impl MediaFeatureExpression { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<Self, ParseError<'i>> { - // FIXME: remove extra indented block when lifetimes are non-lexical - let feature_index; - let feature; - let range; - { - let location = input.current_source_location(); - let ident = input.expect_ident()?; + let mut requirements = ParsingRequirements::empty(); + let location = input.current_source_location(); + let ident = input.expect_ident()?; - let mut requirements = ParsingRequirements::empty(); - - if context.in_ua_or_chrome_sheet() { - requirements.insert(ParsingRequirements::CHROME_AND_UA_ONLY); - } + if context.in_ua_or_chrome_sheet() { + requirements.insert(ParsingRequirements::CHROME_AND_UA_ONLY); + } - let result = { - let mut feature_name = &**ident; + let mut feature_name = &**ident; - #[cfg(feature = "gecko")] - { - if starts_with_ignore_ascii_case(feature_name, "-webkit-") { - feature_name = &feature_name[8..]; - requirements.insert(ParsingRequirements::WEBKIT_PREFIX); - if static_prefs::pref!("layout.css.prefixes.device-pixel-ratio-webkit") { - requirements.insert( - ParsingRequirements::WEBKIT_DEVICE_PIXEL_RATIO_PREF_ENABLED, - ); - } - } - } + if starts_with_ignore_ascii_case(feature_name, "-webkit-") { + feature_name = &feature_name[8..]; + requirements.insert(ParsingRequirements::WEBKIT_PREFIX); + } - let range = if starts_with_ignore_ascii_case(feature_name, "min-") { - feature_name = &feature_name[4..]; - Some(Range::Min) - } else if starts_with_ignore_ascii_case(feature_name, "max-") { - feature_name = &feature_name[4..]; - Some(Range::Max) - } else { - None - }; - - let atom = Atom::from(string_as_ascii_lowercase(feature_name)); - match MEDIA_FEATURES - .iter() - .enumerate() - .find(|(_, f)| f.name == atom) - { - Some((i, f)) => Ok((i, f, range)), - None => Err(()), - } - }; + let range = if starts_with_ignore_ascii_case(feature_name, "min-") { + feature_name = &feature_name[4..]; + Some(Range::Min) + } else if starts_with_ignore_ascii_case(feature_name, "max-") { + feature_name = &feature_name[4..]; + Some(Range::Max) + } else { + None + }; - match result { - Ok((i, f, r)) => { - feature_index = i; - feature = f; - range = r; - }, - Err(()) => { - return Err(location.new_custom_error( - StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), - )); - }, - } + let atom = Atom::from(string_as_ascii_lowercase(feature_name)); - if !(feature.requirements & !requirements).is_empty() { + let (feature_index, feature) = match MEDIA_FEATURES + .iter() + .enumerate() + .find(|(_, f)| f.name == atom) + { + Some((i, f)) => (i, f), + None => { return Err(location.new_custom_error( StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), - )); - } + )) + }, + }; - if range.is_some() && !feature.allows_ranges() { - return Err(location.new_custom_error( - StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), - )); - } + if disabled_by_pref(&feature.name) || + !requirements.contains(feature.requirements) || + (range.is_some() && !feature.allows_ranges()) + { + return Err(location.new_custom_error( + StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), + )); } let operator = input.try(consume_operation_or_colon); diff --git a/components/style/properties/counted_unknown_properties.py b/components/style/properties/counted_unknown_properties.py index 826bbf740a3..de36199e77a 100644 --- a/components/style/properties/counted_unknown_properties.py +++ b/components/style/properties/counted_unknown_properties.py @@ -13,7 +13,6 @@ # "offset" COUNTED_UNKNOWN_PROPERTIES = [ "-webkit-font-smoothing", - "zoom", "-webkit-tap-highlight-color", "speak", "text-size-adjust", diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 97321fcbd38..7783c7eebd3 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -276,11 +276,6 @@ impl ComputedValuesInner { pub fn get_raw_visited_style(&self) -> &Option<RawOffsetArc<ComputedValues>> { &self.visited_style } - - #[allow(non_snake_case)] - pub fn has_moz_binding(&self) -> bool { - !self.get_box().gecko.mBinding.is_none() - } } <%def name="declare_style_struct(style_struct)"> diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index 815dcab313e..a68b179c4c0 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -396,7 +396,7 @@ ${helpers.predefined_type( engines="gecko", animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", + flags="CREATES_STACKING_CONTEXT FIXPOS_CB CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.fxtf.org/motion-1/#offset-path-property", servo_restyle_damage="reflow_out_of_flow" )} @@ -409,6 +409,7 @@ ${helpers.predefined_type( engines="gecko", animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", + flags="CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.fxtf.org/motion-1/#offset-distance-property", servo_restyle_damage="reflow_out_of_flow" )} @@ -421,6 +422,7 @@ ${helpers.predefined_type( engines="gecko", animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", + flags="CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.fxtf.org/motion-1/#offset-rotate-property", servo_restyle_damage="reflow_out_of_flow" )} @@ -433,6 +435,7 @@ ${helpers.predefined_type( engines="gecko", animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", + flags="CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.fxtf.org/motion-1/#offset-anchor-property", servo_restyle_damage="reflow_out_of_flow", boxed=True @@ -453,7 +456,6 @@ ${helpers.predefined_type( "ScrollSnapAlign", "computed::ScrollSnapAlign::none()", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", spec="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align", animation_value_type="discrete", )} @@ -631,18 +633,6 @@ ${helpers.predefined_type( gecko_ffi_name="mAppearance", )} -${helpers.predefined_type( - "-moz-binding", - "url::UrlOrNone", - "computed::url::UrlOrNone::none()", - engines="gecko", - animation_value_type="none", - gecko_ffi_name="mBinding", - gecko_pref="layout.css.moz-binding.content.enabled", - enabled_in="chrome", - spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)", -)} - ${helpers.single_keyword( "-moz-orient", "inline block horizontal vertical", diff --git a/components/style/properties/longhands/margin.mako.rs b/components/style/properties/longhands/margin.mako.rs index 4ad056f05b2..80c765faab7 100644 --- a/components/style/properties/longhands/margin.mako.rs +++ b/components/style/properties/longhands/margin.mako.rs @@ -34,7 +34,6 @@ "Length", "computed::Length::zero()", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", logical=side[1], logical_group="scroll-margin", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-%s" % side[0], diff --git a/components/style/properties/longhands/padding.mako.rs b/components/style/properties/longhands/padding.mako.rs index 3089c0acb92..79668df7bbf 100644 --- a/components/style/properties/longhands/padding.mako.rs +++ b/components/style/properties/longhands/padding.mako.rs @@ -33,7 +33,6 @@ "NonNegativeLengthPercentageOrAuto", "computed::NonNegativeLengthPercentageOrAuto::auto()", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", logical=side[1], logical_group="scroll-padding", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-%s" % side[0], diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 24dfe1c57b6..fe4d3cceaf8 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -1876,7 +1876,19 @@ impl PropertyId { if let Some(id) = static_id(property_name) { return Ok(match *id { StaticId::Longhand(id) => PropertyId::Longhand(id), - StaticId::Shorthand(id) => PropertyId::Shorthand(id), + StaticId::Shorthand(id) => { + #[cfg(feature = "gecko")] + { + // We want to count `zoom` even if disabled. + if matches!(id, ShorthandId::Zoom) { + if let Some(counters) = use_counters { + counters.non_custom_properties.record(id.into()); + } + } + } + + PropertyId::Shorthand(id) + }, StaticId::LonghandAlias(id, alias) => PropertyId::LonghandAlias(id, alias), StaticId::ShorthandAlias(id, alias) => PropertyId::ShorthandAlias(id, alias), StaticId::CountedUnknown(unknown_prop) => { @@ -3065,10 +3077,6 @@ impl ComputedValuesInner { self.rules.as_ref().unwrap() } - /// Whether this style has a -moz-binding value. This is always false for - /// Servo for obvious reasons. - pub fn has_moz_binding(&self) -> bool { false } - #[inline] /// Returns whether the "content" property for the given style is completely /// ineffective, and would yield an empty `::before` or `::after` diff --git a/components/style/properties/shorthands/box.mako.rs b/components/style/properties/shorthands/box.mako.rs index 84d2cb220bd..7b4ce131922 100644 --- a/components/style/properties/shorthands/box.mako.rs +++ b/components/style/properties/shorthands/box.mako.rs @@ -441,3 +441,58 @@ ${helpers.two_properties_shorthand( } } </%helpers:shorthand> + +<%helpers:shorthand name="zoom" engines="gecko" + sub_properties="transform transform-origin" + gecko_pref="layout.css.zoom-transform-hack.enabled" + flags="SHORTHAND_IN_GETCS IS_LEGACY_SHORTHAND" + spec="Not a standard, only a compat hack"> + use crate::parser::Parse; + use crate::values::specified::{Number, NumberOrPercentage, TransformOrigin}; + use crate::values::generics::transform::{Transform, TransformOperation}; + + pub fn parse_value<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Longhands, ParseError<'i>> { + let zoom = match input.try(|input| NumberOrPercentage::parse(context, input)) { + Ok(number_or_percent) => number_or_percent.to_number(), + Err(..) => { + input.expect_ident_matching("normal")?; + Number::new(1.0) + }, + }; + + // Make sure that the initial value matches the values for the + // longhands, just for general sanity. + // + // FIXME: Should we just do this for the "normal" case? Seems weird + // either way, so maybe not? + Ok(if zoom.get() == 1.0 { + expanded! { + transform: Transform::none(), + transform_origin: TransformOrigin::initial_value(), + } + } else { + expanded! { + transform: Transform(vec![TransformOperation::Scale(zoom, zoom)].into()), + transform_origin: TransformOrigin::zero_zero(), + } + }) + } + + impl<'a> ToCss for LonghandsToSerialize<'a> { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { + if self.transform.0.is_empty() && *self.transform_origin == TransformOrigin::initial_value() { + return 1.0f32.to_css(dest); + } + if *self.transform_origin != TransformOrigin::zero_zero() { + return Ok(()) + } + match &*self.transform.0 { + [TransformOperation::Scale(x, y)] if x == y => x.to_css(dest), + _ => Ok(()), + } + } + } +</%helpers:shorthand> diff --git a/components/style/properties/shorthands/margin.mako.rs b/components/style/properties/shorthands/margin.mako.rs index 5d5f2101563..128fc5fb303 100644 --- a/components/style/properties/shorthands/margin.mako.rs +++ b/components/style/properties/shorthands/margin.mako.rs @@ -38,7 +38,6 @@ ${helpers.four_sides_shorthand( "specified::Length::parse", engines="gecko", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin", - gecko_pref="layout.css.scroll-snap-v1.enabled", )} ${helpers.two_properties_shorthand( @@ -48,7 +47,6 @@ ${helpers.two_properties_shorthand( "specified::Length::parse", engines="gecko", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-block", - gecko_pref="layout.css.scroll-snap-v1.enabled", )} ${helpers.two_properties_shorthand( @@ -58,5 +56,4 @@ ${helpers.two_properties_shorthand( "specified::Length::parse", engines="gecko", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-inline", - gecko_pref="layout.css.scroll-snap-v1.enabled", )} diff --git a/components/style/properties/shorthands/padding.mako.rs b/components/style/properties/shorthands/padding.mako.rs index 02db51a88d6..4d2ea361e15 100644 --- a/components/style/properties/shorthands/padding.mako.rs +++ b/components/style/properties/shorthands/padding.mako.rs @@ -36,7 +36,6 @@ ${helpers.four_sides_shorthand( "scroll-padding-%s", "specified::NonNegativeLengthPercentageOrAuto::parse", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding" )} @@ -46,7 +45,6 @@ ${helpers.two_properties_shorthand( "scroll-padding-block-end", "specified::NonNegativeLengthPercentageOrAuto::parse", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-block" )} @@ -56,7 +54,6 @@ ${helpers.two_properties_shorthand( "scroll-padding-inline-end", "specified::NonNegativeLengthPercentageOrAuto::parse", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-inline" )} diff --git a/components/style/stylist.rs b/components/style/stylist.rs index ed9af91af14..ab6fe309f3f 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -2032,11 +2032,17 @@ impl CascadeData { // Part is special, since given it doesn't have any // selectors inside, it's not worth using a whole // SelectorMap for it. - if let Some(part) = selector.part() { + if let Some(parts) = selector.parts() { + // ::part() has all semantics, so we just need to + // put any of them in the selector map. + // + // We choose the last one quite arbitrarily, + // expecting it's slightly more likely to be more + // specific. self.part_rules .get_or_insert_with(|| Box::new(Default::default())) .for_insertion(pseudo_element) - .try_entry(part.clone())? + .try_entry(parts.last().unwrap().clone())? .or_insert_with(SmallVec::new) .try_push(rule)?; } else { diff --git a/components/style/traversal.rs b/components/style/traversal.rs index 1f64e7f22f0..360f5b6a25c 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -267,7 +267,6 @@ pub trait DomTraversal<E: TElement>: Sync { context: &mut StyleContext<E>, parent: E, parent_data: &ElementData, - is_initial_style: bool, ) -> bool { debug_assert!( parent.has_current_styles_for_traversal(parent_data, context.shared.traversal_flags) @@ -279,21 +278,6 @@ pub trait DomTraversal<E: TElement>: Sync { return true; } - // Gecko-only XBL handling. - // - // When we apply the XBL binding during frame construction, we restyle - // the whole subtree again if the binding is valid, so assuming it's - // likely to load valid bindings, we avoid wasted work here, which may - // be a very big perf hit when elements with bindings are nested - // heavily. - if cfg!(feature = "gecko") && - is_initial_style && - parent_data.styles.primary().has_moz_binding() - { - debug!("Parent {:?} has XBL binding, deferring traversal", parent); - return true; - } - return false; } @@ -520,8 +504,8 @@ pub fn recalc_style_at<E, D, F>( !child_cascade_requirement.can_skip_cascade() || is_servo_nonincremental_layout(); - traverse_children = traverse_children && - !traversal.should_cull_subtree(context, element, &data, is_initial_style); + traverse_children = + traverse_children && !traversal.should_cull_subtree(context, element, &data); // Examine our children, and enqueue the appropriate ones for traversal. if traverse_children { diff --git a/components/style/values/computed/angle.rs b/components/style/values/computed/angle.rs index d8cdefb5263..ea321d22337 100644 --- a/components/style/values/computed/angle.rs +++ b/components/style/values/computed/angle.rs @@ -13,16 +13,17 @@ use std::{f32, f64}; use style_traits::{CssWriter, ToCss}; /// A computed angle in degrees. -#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( Add, Animate, Clone, Copy, Debug, + Deserialize, MallocSizeOf, PartialEq, PartialOrd, + Serialize, ToAnimatedZero, ToResolvedValue, )] diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 6d61198d364..53cf7cbd696 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -75,7 +75,9 @@ impl ToComputedValue for specified::Length { /// /// https://drafts.csswg.org/css-values-4/#typedef-length-percentage #[allow(missing_docs)] -#[derive(Clone, Copy, Debug, MallocSizeOf, ToAnimatedZero, ToResolvedValue)] +#[derive( + Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize, ToAnimatedZero, ToResolvedValue, +)] #[repr(C)] pub struct LengthPercentage { length: Length, @@ -605,15 +607,16 @@ impl Size { } /// The computed `<length>` value. -#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( Animate, Clone, ComputeSquaredDistance, Copy, + Deserialize, MallocSizeOf, PartialEq, PartialOrd, + Serialize, ToAnimatedValue, ToAnimatedZero, ToResolvedValue, diff --git a/components/style/values/computed/percentage.rs b/components/style/values/computed/percentage.rs index c22f8ed5683..b5a734367b2 100644 --- a/components/style/values/computed/percentage.rs +++ b/components/style/values/computed/percentage.rs @@ -12,7 +12,6 @@ use std::fmt; use style_traits::{CssWriter, ToCss}; /// A computed percentage. -#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( Animate, Clone, @@ -20,9 +19,11 @@ use style_traits::{CssWriter, ToCss}; Copy, Debug, Default, + Deserialize, MallocSizeOf, PartialEq, PartialOrd, + Serialize, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, diff --git a/components/style/values/generics/motion.rs b/components/style/values/generics/motion.rs index e9ccc045186..685eaad43e2 100644 --- a/components/style/values/generics/motion.rs +++ b/components/style/values/generics/motion.rs @@ -14,9 +14,11 @@ use crate::values::specified::SVGPathData; Clone, Copy, Debug, + Deserialize, MallocSizeOf, Parse, PartialEq, + Serialize, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, @@ -41,8 +43,10 @@ pub enum RaySize { Clone, ComputeSquaredDistance, Debug, + Deserialize, MallocSizeOf, PartialEq, + Serialize, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index acad3383014..01e5890d015 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -119,6 +119,10 @@ pub enum SystemColor { Buttonshadow, Buttontext, Captiontext, + #[parse(aliases = "-moz-field")] + Field, + #[parse(aliases = "-moz-fieldtext")] + Fieldtext, Graytext, Highlight, Highlighttext, @@ -139,8 +143,6 @@ pub enum SystemColor { Windowframe, Windowtext, MozButtondefault, - MozField, - MozFieldtext, MozDialog, MozDialogtext, /// Used to highlight valid regions to drop something onto. diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index c7a6ac1870c..7488e631e54 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -435,10 +435,7 @@ impl Gradient { let (color, mut p) = i.parse_nested_block(|i| { let p = match_ignore_ascii_case! { &function, "color-stop" => { - let p = match NumberOrPercentage::parse(context, i)? { - NumberOrPercentage::Number(number) => Percentage::new(number.value), - NumberOrPercentage::Percentage(p) => p, - }; + let p = NumberOrPercentage::parse(context, i)?.to_percentage(); i.expect_comma()?; p }, diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 160295c8f55..d10a399dd01 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -179,13 +179,26 @@ impl Parse for Number { impl Number { /// Returns a new number with the value `val`. - pub fn new(val: CSSFloat) -> Self { - Number { - value: val, - calc_clamping_mode: None, + fn new_with_clamping_mode( + value: CSSFloat, + calc_clamping_mode: Option<AllowedNumericType>, + ) -> Self { + Self { + value, + calc_clamping_mode, } } + /// Returns this percentage as a number. + pub fn to_percentage(&self) -> Percentage { + Percentage::new_with_clamping_mode(self.value, self.calc_clamping_mode) + } + + /// Returns a new number with the value `val`. + pub fn new(val: CSSFloat) -> Self { + Self::new_with_clamping_mode(val, None) + } + /// Returns whether this number came from a `calc()` expression. #[inline] pub fn was_calc(&self) -> bool { @@ -370,6 +383,22 @@ impl NumberOrPercentage { ) -> Result<Self, ParseError<'i>> { Self::parse_with_clamping_mode(context, input, AllowedNumericType::NonNegative) } + + /// Convert the number or the percentage to a number. + pub fn to_percentage(self) -> Percentage { + match self { + Self::Percentage(p) => p, + Self::Number(n) => n.to_percentage(), + } + } + + /// Convert the number or the percentage to a number. + pub fn to_number(self) -> Number { + match self { + Self::Percentage(p) => p.to_number(), + Self::Number(n) => n, + } + } } impl Parse for NumberOrPercentage { @@ -419,17 +448,7 @@ impl Parse for Opacity { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<Self, ParseError<'i>> { - let number = match NumberOrPercentage::parse(context, input)? { - NumberOrPercentage::Percentage(p) => Number { - value: p.get(), - calc_clamping_mode: if p.is_calc() { - Some(AllowedNumericType::All) - } else { - None - }, - }, - NumberOrPercentage::Number(n) => n, - }; + let number = NumberOrPercentage::parse(context, input)?.to_number(); Ok(Opacity(number)) } } diff --git a/components/style/values/specified/percentage.rs b/components/style/values/specified/percentage.rs index acfa6db64af..64cb02bb424 100644 --- a/components/style/values/specified/percentage.rs +++ b/components/style/values/specified/percentage.rs @@ -8,6 +8,7 @@ use crate::parser::{Parse, ParserContext}; use crate::values::computed::percentage::Percentage as ComputedPercentage; use crate::values::computed::{Context, ToComputedValue}; use crate::values::specified::calc::CalcNode; +use crate::values::specified::Number; use crate::values::{serialize_percentage, CSSFloat}; use cssparser::{Parser, Token}; use std::fmt::{self, Write}; @@ -46,13 +47,21 @@ impl ToCss for Percentage { impl Percentage { /// Creates a percentage from a numeric value. - pub fn new(value: CSSFloat) -> Self { + pub(super) fn new_with_clamping_mode( + value: CSSFloat, + calc_clamping_mode: Option<AllowedNumericType>, + ) -> Self { Self { value, - calc_clamping_mode: None, + calc_clamping_mode, } } + /// Creates a percentage from a numeric value. + pub fn new(value: CSSFloat) -> Self { + Self::new_with_clamping_mode(value, None) + } + /// `0%` #[inline] pub fn zero() -> Self { @@ -70,12 +79,18 @@ impl Percentage { calc_clamping_mode: None, } } + /// Gets the underlying value for this float. pub fn get(&self) -> CSSFloat { self.calc_clamping_mode .map_or(self.value, |mode| mode.clamp(self.value)) } + /// Returns this percentage as a number. + pub fn to_number(&self) -> Number { + Number::new_with_clamping_mode(self.value, self.calc_clamping_mode) + } + /// Returns whether this percentage is a `calc()` value. pub fn is_calc(&self) -> bool { self.calc_clamping_mode.is_some() diff --git a/components/style/values/specified/svg_path.rs b/components/style/values/specified/svg_path.rs index 4f49029b51e..9a94af6a82f 100644 --- a/components/style/values/specified/svg_path.rs +++ b/components/style/values/specified/svg_path.rs @@ -46,7 +46,7 @@ impl SVGPathData { /// Create a normalized copy of this path by converting each relative /// command to an absolute command. - fn normalize(&self) -> Box<[PathCommand]> { + pub fn normalize(&self) -> Self { let mut state = PathTraversalState { subpath_start: CoordPair::new(0.0, 0.0), pos: CoordPair::new(0.0, 0.0), @@ -56,7 +56,8 @@ impl SVGPathData { .iter() .map(|seg| seg.normalize(&mut state)) .collect::<Vec<_>>(); - result.into_boxed_slice() + + SVGPathData(crate::ArcSlice::from_iter(result.into_iter())) } } @@ -119,8 +120,9 @@ impl Animate for SVGPathData { // re-normalize again. let result = self .normalize() + .0 .iter() - .zip(other.normalize().iter()) + .zip(other.normalize().0.iter()) .map(|(a, b)| a.animate(&b, procedure)) .collect::<Result<Vec<_>, _>>()?; @@ -134,8 +136,9 @@ impl ComputeSquaredDistance for SVGPathData { return Err(()); } self.normalize() + .0 .iter() - .zip(other.normalize().iter()) + .zip(other.normalize().0.iter()) .map(|(this, other)| this.compute_squared_distance(&other)) .sum() } diff --git a/components/style/values/specified/transform.rs b/components/style/values/specified/transform.rs index 9d33fd4188f..157c6504856 100644 --- a/components/style/values/specified/transform.rs +++ b/components/style/values/specified/transform.rs @@ -33,6 +33,27 @@ pub type TransformOrigin = generic::TransformOrigin< Length, >; +impl TransformOrigin { + /// Returns the initial specified value for `transform-origin`. + #[inline] + pub fn initial_value() -> Self { + Self::new( + OriginComponent::Length(LengthPercentage::Percentage(ComputedPercentage(0.5))), + OriginComponent::Length(LengthPercentage::Percentage(ComputedPercentage(0.5))), + Length::zero(), + ) + } + + /// Returns the `0 0` value. + pub fn zero_zero() -> Self { + Self::new( + OriginComponent::Length(LengthPercentage::zero()), + OriginComponent::Length(LengthPercentage::zero()), + Length::zero(), + ) + } +} + impl Transform { /// Internal parse function for deciding if we wish to accept prefixed values or not /// @@ -260,7 +281,7 @@ impl Parse for TransformOrigin { let parse_depth = |input: &mut Parser| { input .try(|i| Length::parse(context, i)) - .unwrap_or(Length::from_px(0.)) + .unwrap_or(Length::zero()) }; match input.try(|i| OriginComponent::parse(context, i)) { Ok(x_origin @ OriginComponent::Center) => { diff --git a/components/style_traits/Cargo.toml b/components/style_traits/Cargo.toml index 213c09b08df..f3dd0df744f 100644 --- a/components/style_traits/Cargo.toml +++ b/components/style_traits/Cargo.toml @@ -10,7 +10,7 @@ name = "style_traits" path = "lib.rs" [features] -servo = ["serde", "servo_atoms", "cssparser/serde", "webrender_api", "servo_url", "euclid/serde"] +servo = ["servo_atoms", "cssparser/serde", "webrender_api", "servo_url", "euclid/serde"] gecko = [] [dependencies] @@ -22,7 +22,7 @@ lazy_static = "1" malloc_size_of = { path = "../malloc_size_of" } malloc_size_of_derive = "0.1" selectors = { path = "../selectors" } -serde = {version = "1.0", optional = true} +serde = "1.0" webrender_api = {git = "https://github.com/servo/webrender", optional = true} servo_atoms = {path = "../atoms", optional = true} servo_arc = { path = "../servo_arc" } diff --git a/components/style_traits/lib.rs b/components/style_traits/lib.rs index b2dcc8431cb..3fb17743c13 100644 --- a/components/style_traits/lib.rs +++ b/components/style_traits/lib.rs @@ -22,7 +22,6 @@ extern crate malloc_size_of; #[macro_use] extern crate malloc_size_of_derive; extern crate selectors; -#[cfg(feature = "servo")] #[macro_use] extern crate serde; extern crate servo_arc; diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs index 0c3166858a2..66c1d79cd07 100644 --- a/components/style_traits/values.rs +++ b/components/style_traits/values.rs @@ -507,7 +507,9 @@ pub mod specified { /// Whether to allow negative lengths or not. #[repr(u8)] - #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, ToShmem)] + #[derive( + Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, PartialOrd, Serialize, ToShmem, + )] pub enum AllowedNumericType { /// Allow all kind of numeric values. All, |