diff options
-rw-r--r-- | components/layout/wrapper.rs | 6 | ||||
-rw-r--r-- | components/script/dom/attr.rs | 10 | ||||
-rw-r--r-- | components/script/dom/element.rs | 16 | ||||
-rw-r--r-- | components/style/node.rs | 1 | ||||
-rw-r--r-- | components/style/selector_matching.rs | 6 | ||||
-rw-r--r-- | tests/ref/basic.list | 3 | ||||
-rw-r--r-- | tests/ref/multiple_css_class_a.html | 19 | ||||
-rw-r--r-- | tests/ref/multiple_css_class_b.html | 15 |
8 files changed, 71 insertions, 5 deletions
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index d052c263655..8f948a9a128 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -417,6 +417,12 @@ impl<'le> TElement for LayoutElement<'le> { self.element.node.get_enabled_state_for_layout() } } + + fn has_class(&self, name: &str) -> bool { + unsafe { + self.element.has_class_for_layout(name) + } + } } fn get_content(content_list: &content::T) -> String { diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 02945088bbb..4da59b96b55 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -188,6 +188,7 @@ impl<'a> AttrHelpers for JSRef<'a, Attr> { pub trait AttrHelpersForLayout { unsafe fn value_ref_forever(&self) -> &'static str; unsafe fn value_atom_forever(&self) -> Option<Atom>; + unsafe fn value_tokens_forever(&self) -> Option<Items<Atom>>; unsafe fn local_name_atom_forever(&self) -> Atom; } @@ -207,6 +208,15 @@ impl AttrHelpersForLayout for Attr { } } + unsafe fn value_tokens_forever(&self) -> Option<Items<Atom>> { + // cast to point to T in RefCell<T> directly + let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(self.value.deref()); + match *value { + TokenListAttrValue(_, ref tokens) => Some(tokens.iter()), + _ => None, + } + } + unsafe fn local_name_atom_forever(&self) -> Atom { self.local_name.clone() } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index a4df58eb06e..30b2601f04e 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -168,6 +168,7 @@ impl Element { pub trait RawLayoutElementHelpers { unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str) -> Option<&'static str>; unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &str) -> Option<Atom>; + unsafe fn has_class_for_layout(&self, name: &str) -> bool; } impl RawLayoutElementHelpers for Element { @@ -200,6 +201,18 @@ impl RawLayoutElementHelpers for Element { (*attr).value_atom_forever() }) } + + #[inline] + unsafe fn has_class_for_layout(&self, name: &str) -> bool { + let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs); + (*attrs).iter().find(|attr: & &JS<Attr>| { + let attr = attr.unsafe_get(); + (*attr).local_name_atom_forever().as_slice() == "class" + }).map_or(false, |attr| { + let attr = attr.unsafe_get(); + (*attr).value_tokens_forever().map(|mut tokens| { tokens.any(|atom| atom.as_slice() == name) }) + }.take().unwrap()) + } } pub trait LayoutElementHelpers { @@ -955,4 +968,7 @@ impl<'a> style::TElement for JSRef<'a, Element> { let node: &JSRef<Node> = NodeCast::from_ref(self); node.get_enabled_state() } + fn has_class(&self, name: &str) -> bool { + (self as &AttributeHandlers).has_class(name) + } } diff --git a/components/style/node.rs b/components/style/node.rs index 85a4429e767..cdd7cabf8e7 100644 --- a/components/style/node.rs +++ b/components/style/node.rs @@ -30,5 +30,6 @@ pub trait TElement { fn get_id(&self) -> Option<Atom>; fn get_disabled_state(&self) -> bool; fn get_enabled_state(&self) -> bool; + fn has_class(&self, name: &str) -> bool; } diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs index 0747495b14f..766e2b8bce1 100644 --- a/components/style/selector_matching.rs +++ b/components/style/selector_matching.rs @@ -626,11 +626,7 @@ fn matches_simple_selector<E:TElement, // TODO: cache and intern class names on elements. ClassSelector(ref class) => { let element = element.as_element(); - element.get_attr(&namespace::Null, "class") - .map_or(false, |attr| { - // TODO: case-sensitivity depends on the document type and quirks mode - attr.split(SELECTOR_WHITESPACE).any(|c| c == class.as_slice()) - }) + element.has_class(class.as_slice()) } AttrExists(ref attr) => { diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 5f9fb191ef9..40df098bd79 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -113,3 +113,6 @@ flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html == abs_float_pref_width_a.html abs_float_pref_width_ref.html == alpha_png_a.html alpha_png_b.html == background_image_position_a.html background_image_position_ref.html + +# The following tests fails the ref-tests +#== multiple_css_class_a.html multiple_css_class_b.html diff --git a/tests/ref/multiple_css_class_a.html b/tests/ref/multiple_css_class_a.html new file mode 100644 index 00000000000..bdca7589fdf --- /dev/null +++ b/tests/ref/multiple_css_class_a.html @@ -0,0 +1,19 @@ +<html> + <head> + <style> + .foo { + height: 100px; + } + .bar { + width: 100px; + } + .baz { + background: green; + } + </style> + </head> + <body> + <div class="foo bar baz foobar"> + </div> + </body> +</html> diff --git a/tests/ref/multiple_css_class_b.html b/tests/ref/multiple_css_class_b.html new file mode 100644 index 00000000000..dd64a4f690c --- /dev/null +++ b/tests/ref/multiple_css_class_b.html @@ -0,0 +1,15 @@ +<html> + <head> + <style> + .bar { + height: 100px; + width: 100px; + background: green; + } + </style> + </head> + <body> + <div class="foo bar baz foobar"> + </div> + </body> +</html> |