aboutsummaryrefslogtreecommitdiffstats
path: root/components/style/bloom.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/style/bloom.rs')
-rw-r--r--components/style/bloom.rs39
1 files changed, 34 insertions, 5 deletions
diff --git a/components/style/bloom.rs b/components/style/bloom.rs
index e8ba95aeb94..7633d154fe8 100644
--- a/components/style/bloom.rs
+++ b/components/style/bloom.rs
@@ -8,7 +8,6 @@
#![deny(missing_docs)]
use dom::{SendElement, TElement};
-use matching::MatchMethods;
use selectors::bloom::BloomFilter;
/// A struct that allows us to fast-reject deep descendant selectors avoiding
@@ -50,6 +49,26 @@ pub struct StyleBloom<E: TElement> {
elements: Vec<SendElement<E>>,
}
+fn each_relevant_element_hash<E, F>(element: E, mut f: F)
+ where E: TElement,
+ F: FnMut(u32),
+{
+ f(element.get_local_name().get_hash());
+ f(element.get_namespace().get_hash());
+
+ if let Some(id) = element.get_id() {
+ f(id.get_hash());
+ }
+
+ // TODO: case-sensitivity depends on the document type and quirks mode.
+ //
+ // TODO(emilio): It's not clear whether that's relevant here though?
+ // Classes and ids should be normalized already I think.
+ element.each_class(|class| {
+ f(class.get_hash())
+ });
+}
+
impl<E: TElement> StyleBloom<E> {
/// Create an empty `StyleBloom`.
pub fn new() -> Self {
@@ -72,15 +91,26 @@ impl<E: TElement> StyleBloom<E> {
assert!(element.parent_element().is_none());
}
}
- element.insert_into_bloom_filter(&mut *self.filter);
+ self.push_internal(element);
+ }
+
+ /// Same as `push`, but without asserting, in order to use it from
+ /// `rebuild`.
+ fn push_internal(&mut self, element: E) {
+ each_relevant_element_hash(element, |hash| {
+ self.filter.insert_hash(hash);
+ });
self.elements.push(unsafe { SendElement::new(element) });
}
/// Pop the last element in the bloom filter and return it.
fn pop(&mut self) -> Option<E> {
let popped = self.elements.pop().map(|el| *el);
+
if let Some(popped) = popped {
- popped.remove_from_bloom_filter(&mut self.filter);
+ each_relevant_element_hash(popped, |hash| {
+ self.filter.remove_hash(hash);
+ })
}
popped
@@ -103,8 +133,7 @@ impl<E: TElement> StyleBloom<E> {
self.clear();
while let Some(parent) = element.parent_element() {
- parent.insert_into_bloom_filter(&mut *self.filter);
- self.elements.push(unsafe { SendElement::new(parent) });
+ self.push_internal(parent);
element = parent;
}