diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 7c7c9cc3505..a916ee73512 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -391,6 +391,11 @@ impl<'le> TElement for ServoLayoutElement<'le> { self.get_attr(namespace, attr).is_some() } + #[inline] + fn attr_equals(&self, namespace: &Namespace, attr: &Atom, val: &Atom) -> bool { + self.get_attr(namespace, attr).map_or(false, |x| x == val) + } + #[inline] fn get_attr(&self, namespace: &Namespace, name: &Atom) -> Option<&str> { unsafe { diff --git a/components/style/dom.rs b/components/style/dom.rs index 436bf57aebd..9cdce7b3852 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -208,6 +208,7 @@ pub trait TElement : Sized + Copy + Clone + ElementExt + PresentationalHintsSynt fn get_state(&self) -> ElementState; fn has_attr(&self, namespace: &Namespace, attr: &Atom) -> bool; + fn attr_equals(&self, namespace: &Namespace, attr: &Atom, value: &Atom) -> bool; fn get_attr<'a>(&'a self, namespace: &Namespace, attr: &Atom) -> Option<&'a str>; diff --git a/components/style/matching.rs b/components/style/matching.rs index aa7d751267d..f97ee2aab2c 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -39,11 +39,9 @@ fn create_common_style_affecting_attributes_from_element(element: & } } CommonStyleAffectingAttributeMode::IsEqual(target_value, flag) => { - match element.get_attr(&ns!(), &attribute_info.atom) { - Some(element_value) if element_value == target_value => { - flags.insert(flag) - } - _ => {} + let atom = Atom::from(target_value); // FIXME(bholley): This goes away in the next patch. + if element.attr_equals(&ns!(), &attribute_info.atom, &atom) { + flags.insert(flag) } } } @@ -301,19 +299,14 @@ impl StyleSharingCandidate { } } CommonStyleAffectingAttributeMode::IsEqual(target_value, flag) => { - match element.get_attr(&ns!(), &attribute_info.atom) { - Some(ref element_value) if self.common_style_affecting_attributes - .contains(flag) && - *element_value != target_value => { + let atom = Atom::from(target_value); // FIXME(bholley): This goes away in the next patch. + let contains = self.common_style_affecting_attributes.contains(flag); + if element.has_attr(&ns!(), &attribute_info.atom) { + if !contains || !element.attr_equals(&ns!(), &attribute_info.atom, &atom) { return false } - Some(_) if !self.common_style_affecting_attributes.contains(flag) => { - return false - } - None if self.common_style_affecting_attributes.contains(flag) => { - return false - } - _ => {} + } else if contains { + return false } } } diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index 7dc4545be2f..247d3b9216c 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -369,6 +369,17 @@ impl<'le> TElement for GeckoElement<'le> { } } + #[inline] + fn attr_equals(&self, namespace: &Namespace, attr: &Atom, val: &Atom) -> bool { + unsafe { + bindings::Gecko_AttrEquals(self.element, + namespace.0.as_ptr(), + attr.as_ptr(), + val.as_ptr(), + /* ignoreCase = */ false) + } + } + #[inline] fn get_attr<'a>(&'a self, namespace: &Namespace, name: &Atom) -> Option<&'a str> { unsafe {