diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index bbeff75d99d..1ba991a5d5e 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -707,10 +707,6 @@ pub trait ThreadSafeLayoutNode : Clone + Copy + Sized + PartialEq { }) } - // TODO(emilio): Since the ::-details-* pseudos are internal, just affecting - // one element, and only changing `display` property when the element `open` - // attribute changes, this should be eligible for not being cascaded - // eagerly, reading the display property from layout instead. #[inline] fn get_details_summary_pseudo(&self) -> Option { if self.is_element() && @@ -729,18 +725,29 @@ pub trait ThreadSafeLayoutNode : Clone + Copy + Sized + PartialEq { #[inline] fn get_details_content_pseudo(&self) -> Option { - if self.is_element() && - self.as_element().get_local_name() == &atom!("details") && - self.as_element().get_namespace() == &ns!(html) { - self.borrow_layout_data().unwrap() - .style_data.per_pseudo - .get(&PseudoElement::DetailsContent) - .map(|style| { - self.with_pseudo(PseudoElementType::DetailsContent(style.get_box().display)) - }) - } else { - None + if !self.is_element() { + return None; } + + let element = self.as_element(); + if element.get_local_name() != &atom!("details") || + element.get_namespace() != &ns!(html) { + return None; + } + + self.borrow_layout_data().unwrap() + .style_data + .precomputed + .non_eagerly_cascaded_pseudo_elements + .get(&PseudoElement::DetailsContent) + .map(|style| { + let display = if element.get_attr(&ns!(), &atom!("open")).is_some() { + style.get_box().display + } else { + display::T::none + }; + self.with_pseudo(PseudoElementType::DetailsContent(display)) + }) } /// Borrows the layout data immutably. Fails on a conflicting borrow. @@ -763,11 +770,19 @@ pub trait ThreadSafeLayoutNode : Clone + Copy + Sized + PartialEq { fn style(&self) -> Ref> { Ref::map(self.borrow_layout_data().unwrap(), |data| { let style = match self.get_pseudo_element_type() { - PseudoElementType::Before(_) => data.style_data.per_pseudo.get(&PseudoElement::Before), - PseudoElementType::After(_) => data.style_data.per_pseudo.get(&PseudoElement::After), - PseudoElementType::DetailsSummary(_) => data.style_data.per_pseudo.get(&PseudoElement::DetailsSummary), - PseudoElementType::DetailsContent(_) => data.style_data.per_pseudo.get(&PseudoElement::DetailsContent), - PseudoElementType::Normal => data.style_data.style.as_ref(), + PseudoElementType::Before(_) + => data.style_data.per_pseudo.get(&PseudoElement::Before), + PseudoElementType::After(_) + => data.style_data.per_pseudo.get(&PseudoElement::After), + PseudoElementType::DetailsSummary(_) + => data.style_data.per_pseudo.get(&PseudoElement::DetailsSummary), + PseudoElementType::DetailsContent(_) + => data.style_data + .precomputed + .non_eagerly_cascaded_pseudo_elements + .get(&PseudoElement::DetailsContent), + PseudoElementType::Normal + => data.style_data.style.as_ref(), }; style.unwrap() }) @@ -1165,8 +1180,8 @@ impl Iterator for ThreadSafeLayoutNodeChildrenIterator bool { match *pseudo { PseudoElement::Before | PseudoElement::After | PseudoElement::Selection | - PseudoElement::DetailsContent | PseudoElement::DetailsSummary => true, + PseudoElement::DetailsContent => false, } } diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs index 7e4c97b04f5..052400333c5 100644 --- a/components/style/selector_matching.rs +++ b/components/style/selector_matching.rs @@ -90,7 +90,7 @@ pub struct PrecomputedStyleData { /// are eagerly computed once, and then just looked up in the table, /// since they only appear in rules of the form *|*::pseudo-element pub non_eagerly_cascaded_pseudo_elements: HashMap, BuildHasherDefault<::fnv::FnvHasher>>, } @@ -277,7 +277,7 @@ impl Stylist { &declarations, false, None, None, box StdoutErrorReporter); - precomputed.non_eagerly_cascaded_pseudo_elements.insert(pseudo, computed); + precomputed.non_eagerly_cascaded_pseudo_elements.insert(pseudo, Arc::new(computed)); } }) } @@ -287,7 +287,7 @@ impl Stylist { } pub fn get_non_eagerly_cascaded_pseudo_element_style(&self, - pseudo: &Impl::PseudoElement) -> Option { + pseudo: &Impl::PseudoElement) -> Option> { debug_assert!(!Impl::is_eagerly_cascaded_pseudo_element(pseudo)); self.precomputed .non_eagerly_cascaded_pseudo_elements diff --git a/resources/servo.css b/resources/servo.css index 5fe1b27bf46..0ef23b8f86d 100644 --- a/resources/servo.css +++ b/resources/servo.css @@ -51,15 +51,11 @@ details::-servo-details-summary { details[open]::-servo-details-summary { list-style: disclosure-open; } -details::-servo-details-content { +*|*::-servo-details-content { margin-left: 40px; overflow: hidden; - display: none; -} -details[open]::-servo-details-content { display: block; } - /* * Until servo supports svg properly, make sure to at least prevent svg * children from being layed out and rendered like usual html.