script: Use atom comparison in more places, especially for attributes.

75% improvement in style recalc for Guardians of the Galaxy.
This commit is contained in:
Patrick Walton 2014-09-12 13:28:37 -07:00
parent d168501555
commit ee2ccc4f87
31 changed files with 305 additions and 237 deletions

View file

@ -108,20 +108,14 @@ impl SelectorMap {
None => {}
}
match element.get_attr(&ns!(""), "class") {
Some(ref class_attr) => {
// FIXME: Store classes pre-split as atoms to make the loop below faster.
for class in class_attr.split(SELECTOR_WHITESPACE) {
SelectorMap::get_matching_rules_from_hash(node,
parent_bf,
&self.class_hash,
&Atom::from_slice(class),
matching_rules_list,
shareable);
}
}
None => {}
}
element.each_class(|class| {
SelectorMap::get_matching_rules_from_hash(node,
parent_bf,
&self.class_hash,
class,
matching_rules_list,
shareable);
});
let local_name_hash = if node.is_html_element_in_html_document() {
&self.lower_local_name_hash
@ -699,12 +693,12 @@ fn matches_compound_selector_internal<'a,
/// will almost certainly break as nodes will start mistakenly sharing styles. (See the code in
/// `main/css/matching.rs`.)
#[inline]
pub fn matches_simple_selector<'a, E:TElement<'a>,
N:TNode<'a, E>>(
selector: &SimpleSelector,
element: &N,
shareable: &mut bool)
-> bool {
pub fn matches_simple_selector<'a,E,N>(
selector: &SimpleSelector,
element: &N,
shareable: &mut bool)
-> bool
where E:TElement<'a>, N:TNode<'a,E> {
match *selector {
LocalNameSelector(LocalName { ref name, ref lower_name }) => {
let name = if element.is_html_element_in_html_document() { lower_name } else { name };
@ -718,7 +712,6 @@ pub fn matches_simple_selector<'a, E:TElement<'a>,
element.get_namespace() == namespace
}
// TODO: case-sensitivity depends on the document type and quirks mode
// TODO: cache and intern IDs on elements.
IDSelector(ref id) => {
*shareable = false;
let element = element.as_element();
@ -726,10 +719,9 @@ pub fn matches_simple_selector<'a, E:TElement<'a>,
attr == *id
})
}
// TODO: cache and intern class names on elements.
ClassSelector(ref class) => {
let element = element.as_element();
element.has_class(class.as_slice())
element.has_class(class)
}
AttrExists(ref attr) => {
@ -876,6 +868,7 @@ pub fn matches_simple_selector<'a, E:TElement<'a>,
}
}
#[inline]
fn url_is_visited(_url: &str) -> bool {
// FIXME: implement this.
// This function will probably need to take a "session"
@ -884,15 +877,14 @@ fn url_is_visited(_url: &str) -> bool {
}
#[inline]
fn matches_generic_nth_child<'a,
E:TElement<'a>,
N:TNode<'a, E>>(
fn matches_generic_nth_child<'a,E,N>(
element: &N,
a: i32,
b: i32,
is_of_type: bool,
is_from_end: bool)
-> bool {
-> bool
where E: TElement<'a>, N: TNode<'a,E> {
let mut node = element.clone();
// fail if we can't find a parent or if the node is the root element
// of the document (Cf. Selectors Level 3)