diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs index e79982130c2..503897a5964 100644 --- a/components/layout/css/matching.rs +++ b/components/layout/css/matching.rs @@ -27,7 +27,7 @@ use std::slice::Iter; use std::sync::Arc; use std::sync::mpsc::Sender; use string_cache::{Atom, Namespace}; -use style::node::{TElement, TNode}; +use style::node::{TElement, TElementAttributes, TNode}; use style::properties::{ComputedValues, cascade}; use style::selector_matching::{Stylist, DeclarationBlock}; use util::arc_ptr_eq; @@ -289,6 +289,12 @@ impl StyleSharingCandidate { return false } + let mut matching_rules = vec![]; + element.synthesize_presentational_hints_for_legacy_attributes(&mut matching_rules); + if !matching_rules.is_empty() { + return false; + } + // FIXME(pcwalton): It's probably faster to iterate over all the element's attributes and // use the {common, rare}-style-affecting-attributes tables as lookup tables. diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 8c30d649db3..7d919f49f29 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -70,11 +70,13 @@ use std::sync::mpsc::Sender; use string_cache::{Atom, Namespace}; use style::computed_values::content::ContentItem; use style::computed_values::{content, display, white_space}; +use selectors::matching::DeclarationBlock; use selectors::parser::{NamespaceConstraint, AttrSelector}; +use selectors::smallvec::VecLike; use style::legacy::{IntegerAttribute, LengthAttribute, SimpleColorAttribute}; use style::legacy::{UnsignedIntegerAttribute}; use style::node::{TElement, TElementAttributes, TNode}; -use style::properties::PropertyDeclarationBlock; +use style::properties::{PropertyDeclaration, PropertyDeclarationBlock}; use url::Url; /// Allows some convenience methods on generic layout nodes. @@ -659,6 +661,14 @@ impl<'le> TElement<'le> for LayoutElement<'le> { } impl<'le> TElementAttributes for LayoutElement<'le> { + fn synthesize_presentational_hints_for_legacy_attributes(self, hints: &mut V) + where V: VecLike>> + { + unsafe { + self.element.synthesize_presentational_hints_for_legacy_attributes(hints); + } + } + fn get_length_attribute(self, length_attribute: LengthAttribute) -> LengthOrPercentageOrAuto { unsafe { self.element.get_length_attribute_for_layout(length_attribute) diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index cfe2c6b1acf..4e6644f0a97 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -68,8 +68,9 @@ use html5ever::serialize::SerializeOpts; use html5ever::serialize::TraversalScope; use html5ever::serialize::TraversalScope::{IncludeNode, ChildrenOnly}; use html5ever::tree_builder::{NoQuirks, LimitedQuirks, Quirks}; -use selectors::matching::matches; +use selectors::matching::{matches, DeclarationBlock}; use selectors::parser::parse_author_origin_selector_list_from_str; +use selectors::smallvec::VecLike; use string_cache::{Atom, Namespace, QualName}; use url::UrlParser; @@ -155,6 +156,9 @@ pub trait RawLayoutElementHelpers { unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom) -> Option; unsafe fn has_class_for_layout(&self, name: &Atom) -> bool; unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]>; + + unsafe fn synthesize_presentational_hints_for_legacy_attributes(&self, &mut V) + where V: VecLike>>; unsafe fn get_length_attribute_for_layout(&self, length_attribute: LengthAttribute) -> LengthOrPercentageOrAuto; unsafe fn get_integer_attribute_for_layout(&self, integer_attribute: IntegerAttribute) @@ -227,6 +231,11 @@ impl RawLayoutElementHelpers for Element { }) } + unsafe fn synthesize_presentational_hints_for_legacy_attributes(&self, _: &mut V) + where V: VecLike>> + { + } + #[inline] unsafe fn get_length_attribute_for_layout(&self, length_attribute: LengthAttribute) -> LengthOrPercentageOrAuto { diff --git a/components/style/legacy.rs b/components/style/legacy.rs index 2ce112a2f3a..a44193c8390 100644 --- a/components/style/legacy.rs +++ b/components/style/legacy.rs @@ -108,6 +108,14 @@ impl PresentationalHintSynthesis for Stylist { N::Element: TElementAttributes, V: VecLike>> { let element = node.as_element(); + + let length = matching_rules_list.vec_len(); + element.synthesize_presentational_hints_for_legacy_attributes(matching_rules_list); + if matching_rules_list.vec_len() != length { + // Never share style for elements with preshints + *shareable = false; + } + match element.get_local_name() { name if *name == atom!("td") => { match element.get_length_attribute(LengthAttribute::Width) { diff --git a/components/style/node.rs b/components/style/node.rs index c3bd70a44bf..4e667ef1286 100644 --- a/components/style/node.rs +++ b/components/style/node.rs @@ -7,11 +7,16 @@ use cssparser::RGBA; use legacy::{IntegerAttribute, LengthAttribute, SimpleColorAttribute, UnsignedIntegerAttribute}; +use properties::PropertyDeclaration; use util::str::LengthOrPercentageOrAuto; +use selectors::matching::DeclarationBlock; +use selectors::smallvec::VecLike; pub use selectors::tree::{TNode, TElement}; pub trait TElementAttributes : Copy { + fn synthesize_presentational_hints_for_legacy_attributes(self, &mut V) + where V: VecLike>>; fn get_length_attribute(self, attribute: LengthAttribute) -> LengthOrPercentageOrAuto; fn get_integer_attribute(self, attribute: IntegerAttribute) -> Option; fn get_unsigned_integer_attribute(self, attribute: UnsignedIntegerAttribute) -> Option;