diff options
author | Bobby Holley <bobbyholley@gmail.com> | 2017-04-27 14:51:23 -0700 |
---|---|---|
committer | Bobby Holley <bobbyholley@gmail.com> | 2017-04-29 16:07:41 -0700 |
commit | 71ecff849bf7fb6e40dcb74092b36315c3ba5c33 (patch) | |
tree | 5c7a7cd577427d6251182662972dbc8649f0ae8f | |
parent | 080ff126b57248898422b1118f3776863b047aef (diff) | |
download | servo-71ecff849bf7fb6e40dcb74092b36315c3ba5c33.tar.gz servo-71ecff849bf7fb6e40dcb74092b36315c3ba5c33.zip |
Use a single rule hash for both lower_name and name.
Right now in the common case we're doing twice the work during stylist update,
and also checking is_html_element_in_html_document twice during lookup. This
patch aligns us with what Gecko does.
MozReview-Commit-ID: D4TyG30BP8C
-rw-r--r-- | components/style/stylist.rs | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/components/style/stylist.rs b/components/style/stylist.rs index d26d617d8c9..65d04630fd3 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1050,9 +1050,6 @@ pub struct SelectorMap { pub class_hash: FnvHashMap<Atom, Vec<Rule>>, /// A hash from local name to rules which contain that local name selector. pub local_name_hash: FnvHashMap<LocalName, Vec<Rule>>, - /// Same as local_name_hash, but keys are lower-cased. - /// For HTML elements in HTML documents. - pub lower_local_name_hash: FnvHashMap<LocalName, Vec<Rule>>, /// Rules that don't have ID, class, or element selectors. pub other_rules: Vec<Rule>, /// Whether this hash is empty. @@ -1071,7 +1068,6 @@ impl SelectorMap { id_hash: HashMap::default(), class_hash: HashMap::default(), local_name_hash: HashMap::default(), - lower_local_name_hash: HashMap::default(), other_rules: Vec::new(), empty: true, } @@ -1120,14 +1116,9 @@ impl SelectorMap { cascade_level); }); - let local_name_hash = if element.is_html_element_in_html_document() { - &self.lower_local_name_hash - } else { - &self.local_name_hash - }; SelectorMap::get_matching_rules_from_hash(element, parent_bf, - local_name_hash, + &self.local_name_hash, element.get_local_name(), matching_rules_list, relations, @@ -1260,8 +1251,22 @@ impl SelectorMap { } if let Some(LocalNameSelector { name, lower_name }) = SelectorMap::get_local_name(&rule) { - find_push(&mut self.local_name_hash, name, rule.clone()); - find_push(&mut self.lower_local_name_hash, lower_name, rule); + // If the local name in the selector isn't lowercase, insert it into + // the rule hash twice. This means that, during lookup, we can always + // find the rules based on the local name of the element, regardless + // of whether it's an html element in an html document (in which case + // we match against lower_name) or not (in which case we match against + // name). + // + // In the case of a non-html-element-in-html-document with a + // lowercase localname and a non-lowercase selector, the rulehash + // lookup may produce superfluous selectors, but the subsequent + // selector matching work will filter them out. + if name != lower_name { + find_push(&mut self.local_name_hash, lower_name, rule.clone()); + } + find_push(&mut self.local_name_hash, name, rule); + return; } |