diff options
Diffstat (limited to 'components/style')
-rw-r--r-- | components/style/legacy.rs | 58 | ||||
-rw-r--r-- | components/style/lib.rs | 8 | ||||
-rw-r--r-- | components/style/node.rs | 4 | ||||
-rw-r--r-- | components/style/selector_matching.rs | 13 | ||||
-rw-r--r-- | components/style/selectors.rs | 9 |
5 files changed, 84 insertions, 8 deletions
diff --git a/components/style/legacy.rs b/components/style/legacy.rs index 4a4e8a428f0..8eb9a7d1e56 100644 --- a/components/style/legacy.rs +++ b/components/style/legacy.rs @@ -6,7 +6,9 @@ //! `<input size>`, and so forth. use node::{TElement, TElementAttributes, TNode}; -use properties::{SpecifiedValue, WidthDeclaration, specified}; +use properties::{BorderBottomWidthDeclaration, BorderLeftWidthDeclaration}; +use properties::{BorderRightWidthDeclaration, BorderTopWidthDeclaration, SpecifiedValue}; +use properties::{WidthDeclaration, specified}; use selector_matching::{DeclarationBlock, Stylist}; use servo_util::geometry::Au; @@ -25,6 +27,12 @@ pub enum IntegerAttribute { SizeIntegerAttribute, } +/// Legacy presentational attributes that take a nonnegative integer as defined in HTML5 § 2.4.4.2. +pub enum UnsignedIntegerAttribute { + /// `<td border>` + BorderUnsignedIntegerAttribute, +} + /// Extension methods for `Stylist` that cause rules to be synthesized for legacy attributes. pub trait PresentationalHintSynthesis { /// Synthesizes rules from various HTML attributes (mostly legacy junk from HTML4) that confer @@ -39,6 +47,16 @@ pub trait PresentationalHintSynthesis { TElementAttributes, N: TNode<'a,E>, V: VecLike<DeclarationBlock>; + /// Synthesizes rules for the legacy `border` attribute. + fn synthesize_presentational_hint_for_legacy_border_attribute<'a,E,V>( + &self, + element: E, + matching_rules_list: &mut V, + shareable: &mut bool) + where + E: TElement<'a> + + TElementAttributes, + V: VecLike<DeclarationBlock>; } impl PresentationalHintSynthesis for Stylist { @@ -68,7 +86,17 @@ impl PresentationalHintSynthesis for Stylist { WidthDeclaration(SpecifiedValue(width_value)))); *shareable = false } - }; + } + self.synthesize_presentational_hint_for_legacy_border_attribute( + element, + matching_rules_list, + shareable); + } + name if *name == atom!("table") => { + self.synthesize_presentational_hint_for_legacy_border_attribute( + element, + matching_rules_list, + shareable); } name if *name == atom!("input") => { match element.get_integer_attribute(SizeIntegerAttribute) { @@ -94,5 +122,31 @@ impl PresentationalHintSynthesis for Stylist { _ => {} } } + + fn synthesize_presentational_hint_for_legacy_border_attribute<'a,E,V>( + &self, + element: E, + matching_rules_list: &mut V, + shareable: &mut bool) + where + E: TElement<'a> + + TElementAttributes, + V: VecLike<DeclarationBlock> { + match element.get_unsigned_integer_attribute(BorderUnsignedIntegerAttribute) { + None => {} + Some(length) => { + let width_value = specified::Au_(Au::from_px(length as int)); + matching_rules_list.vec_push(DeclarationBlock::from_declaration( + BorderTopWidthDeclaration(SpecifiedValue(width_value)))); + matching_rules_list.vec_push(DeclarationBlock::from_declaration( + BorderLeftWidthDeclaration(SpecifiedValue(width_value)))); + matching_rules_list.vec_push(DeclarationBlock::from_declaration( + BorderBottomWidthDeclaration(SpecifiedValue(width_value)))); + matching_rules_list.vec_push(DeclarationBlock::from_declaration( + BorderRightWidthDeclaration(SpecifiedValue(width_value)))); + *shareable = false + } + } + } } diff --git a/components/style/lib.rs b/components/style/lib.rs index e6e0e77f7a5..23a674151b4 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -41,7 +41,8 @@ pub use selector_matching::{DeclarationBlock, CommonStyleAffectingAttributes}; pub use selector_matching::{CommonStyleAffectingAttributeInfo, CommonStyleAffectingAttributeMode}; pub use selector_matching::{AttrIsPresentMode, AttrIsEqualMode}; pub use selector_matching::{matches, matches_simple_selector, common_style_affecting_attributes}; -pub use selector_matching::{RECOMMENDED_SELECTOR_BLOOM_FILTER_SIZE,SELECTOR_WHITESPACE}; +pub use selector_matching::{rare_style_affecting_attributes}; +pub use selector_matching::{RECOMMENDED_SELECTOR_BLOOM_FILTER_SIZE, SELECTOR_WHITESPACE}; pub use properties::{cascade, cascade_anonymous, computed}; pub use properties::{PropertyDeclaration, ComputedValues, computed_values, style_structs}; pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes @@ -51,9 +52,10 @@ pub use properties::{Left, Right, Bottom, Top}; pub use node::{TElement, TElementAttributes, TNode}; pub use selectors::{PseudoElement, Before, After, SelectorList, parse_selector_list_from_str}; pub use selectors::{AttrSelector, NamespaceConstraint, SpecificNamespace, AnyNamespace}; -pub use selectors::{SimpleSelector,LocalNameSelector}; +pub use selectors::{SimpleSelector, LocalNameSelector}; pub use cssparser::{Color, RGBA}; -pub use legacy::{IntegerAttribute, LengthAttribute, SizeIntegerAttribute, WidthLengthAttribute}; +pub use legacy::{BorderUnsignedIntegerAttribute, IntegerAttribute, LengthAttribute}; +pub use legacy::{SizeIntegerAttribute, UnsignedIntegerAttribute, WidthLengthAttribute}; pub use font_face::{Source, LocalSource, UrlSource_}; mod stylesheets; diff --git a/components/style/node.rs b/components/style/node.rs index 5a765f2798d..3d9ad18e623 100644 --- a/components/style/node.rs +++ b/components/style/node.rs @@ -5,7 +5,7 @@ //! Traits that nodes must implement. Breaks the otherwise-cyclic dependency between layout and //! style. -use legacy::{IntegerAttribute, LengthAttribute}; +use legacy::{IntegerAttribute, LengthAttribute, UnsignedIntegerAttribute}; use selectors::AttrSelector; use servo_util::str::LengthOrPercentageOrAuto; use string_cache::{Atom, Namespace}; @@ -47,6 +47,7 @@ pub trait TElement<'a> : Copy { fn get_enabled_state(self) -> bool; fn get_checked_state(self) -> bool; fn has_class(self, name: &Atom) -> bool; + fn has_nonzero_border(self) -> bool; // Ordinarily I wouldn't use callbacks like this, but the alternative is // really messy, since there is a `JSRef` and a `RefCell` involved. Maybe @@ -58,4 +59,5 @@ pub trait TElement<'a> : Copy { pub trait TElementAttributes : Copy { fn get_length_attribute(self, attribute: LengthAttribute) -> LengthOrPercentageOrAuto; fn get_integer_attribute(self, attribute: IntegerAttribute) -> Option<i32>; + fn get_unsigned_integer_attribute(self, attribute: UnsignedIntegerAttribute) -> Option<u32>; } diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs index 228ff41af05..b1fbd5042e8 100644 --- a/components/style/selector_matching.rs +++ b/components/style/selector_matching.rs @@ -799,6 +799,13 @@ pub fn common_style_affecting_attributes() -> [CommonStyleAffectingAttributeInfo ] } +/// Attributes that, if present, disable style sharing. All legacy HTML attributes must be in +/// either this list or `common_style_affecting_attributes`. See the comment in +/// `synthesize_presentational_hints_for_legacy_attributes`. +pub fn rare_style_affecting_attributes() -> [Atom, ..1] { + [ atom!("border") ] +} + /// Determines whether the given element matches the given single selector. /// /// NB: If you add support for any new kinds of selectors to this routine, be sure to set @@ -993,6 +1000,12 @@ pub fn matches_simple_selector<'a,E,N>(selector: &SimpleSelector, matches_generic_nth_child(element, 0, 1, true, true) } + ServoNonzeroBorder => { + *shareable = false; + let elem = element.as_element(); + elem.has_nonzero_border() + } + Negation(ref negated) => { *shareable = false; !negated.iter().all(|s| matches_simple_selector(s, element, shareable)) diff --git a/components/style/selectors.rs b/components/style/selectors.rs index da0e2b7b638..9cb3f240dd4 100644 --- a/components/style/selectors.rs +++ b/components/style/selectors.rs @@ -79,7 +79,8 @@ pub enum SimpleSelector { NthLastOfType(i32, i32), FirstOfType, LastOfType, - OnlyOfType + OnlyOfType, + ServoNonzeroBorder, // ... } @@ -231,7 +232,7 @@ fn compute_specificity(mut selector: &CompoundSelector, // | &Empty | &Lang(*) | &NthChild(..) | &NthLastChild(..) | &NthOfType(..) | &NthLastOfType(..) - | &FirstOfType | &LastOfType | &OnlyOfType + | &FirstOfType | &LastOfType | &OnlyOfType | &ServoNonzeroBorder => specificity.class_like_selectors += 1, &NamespaceSelector(..) => (), &Negation(ref negated) @@ -506,6 +507,10 @@ fn parse_simple_pseudo_class(name: &str) -> Result<SimpleSelector, ()> { "first-of-type" => Ok(FirstOfType), "last-of-type" => Ok(LastOfType), "only-of-type" => Ok(OnlyOfType), + "-servo-nonzero-border" => { + // TODO(pcwalton): Have some mechanism whereby we forbid Web content from using this. + Ok(ServoNonzeroBorder) + } // "empty" => Ok(Empty), _ => Err(()) } |