aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/layout_task.rs7
-rw-r--r--components/layout/wrapper.rs6
-rw-r--r--components/script/dom/document.rs31
-rw-r--r--components/script/dom/element.rs5
-rw-r--r--components/style/restyle_hints.rs5
-rw-r--r--components/style/selector_matching.rs4
6 files changed, 23 insertions, 35 deletions
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs
index 7a615b02f6b..bdf1b613562 100644
--- a/components/layout/layout_task.rs
+++ b/components/layout/layout_task.rs
@@ -1213,13 +1213,12 @@ impl LayoutTask {
}
}
- let state_changes = document.drain_element_state_changes();
+ let modified_elements = document.drain_modified_elements();
if !needs_dirtying {
- for &(el, state_change) in state_changes.iter() {
- debug_assert!(!state_change.is_empty());
+ for &(el, old_state) in modified_elements.iter() {
let hint = rw_data.stylist.restyle_hint_for_state_change(&el,
el.get_state(),
- state_change);
+ old_state);
el.note_restyle_hint(hint);
}
}
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs
index 04d3470fb64..ae8462426e8 100644
--- a/components/layout/wrapper.rs
+++ b/components/layout/wrapper.rs
@@ -375,10 +375,10 @@ impl<'le> LayoutDocument<'le> {
self.as_node().children().find(LayoutNode::is_element)
}
- pub fn drain_element_state_changes(&self) -> Vec<(LayoutElement, ElementState)> {
+ pub fn drain_modified_elements(&self) -> Vec<(LayoutElement, ElementState)> {
unsafe {
- let changes = self.document.drain_element_state_changes();
- Vec::from_iter(changes.iter().map(|&(el, state)|
+ let elements = self.document.drain_modified_elements();
+ Vec::from_iter(elements.iter().map(|&(el, state)|
(LayoutElement {
element: el,
chain: PhantomData,
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 90e5697dd33..161a5639ceb 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -175,8 +175,8 @@ pub struct Document {
/// This field is set to the document itself for inert documents.
/// https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document
appropriate_template_contents_owner_document: MutNullableHeap<JS<Document>>,
- /// The collection of ElementStates that have been changed since the last restyle.
- element_state_changes: DOMRefCell<HashMap<JS<Element>, ElementState>>,
+ /// For each element that has had a state change since the last restyle, track the original state.
+ modified_elements: DOMRefCell<HashMap<JS<Element>, ElementState>>,
/// http://w3c.github.io/touch-events/#dfn-active-touch-point
active_touch_points: DOMRefCell<Vec<JS<Touch>>>,
}
@@ -308,7 +308,7 @@ impl Document {
pub fn needs_reflow(&self) -> bool {
self.GetDocumentElement().is_some() &&
- (self.upcast::<Node>().get_has_dirty_descendants() || !self.element_state_changes.borrow().is_empty())
+ (self.upcast::<Node>().get_has_dirty_descendants() || !self.modified_elements.borrow().is_empty())
}
/// Returns the first `base` element in the DOM that has an `href` attribute.
@@ -1230,7 +1230,7 @@ pub enum DocumentSource {
#[allow(unsafe_code)]
pub trait LayoutDocumentHelpers {
unsafe fn is_html_document_for_layout(&self) -> bool;
- unsafe fn drain_element_state_changes(&self) -> Vec<(LayoutJS<Element>, ElementState)>;
+ unsafe fn drain_modified_elements(&self) -> Vec<(LayoutJS<Element>, ElementState)>;
}
#[allow(unsafe_code)]
@@ -1242,9 +1242,9 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
#[inline]
#[allow(unrooted_must_root)]
- unsafe fn drain_element_state_changes(&self) -> Vec<(LayoutJS<Element>, ElementState)> {
- let mut changes = (*self.unsafe_get()).element_state_changes.borrow_mut_for_layout();
- let drain = changes.drain();
+ unsafe fn drain_modified_elements(&self) -> Vec<(LayoutJS<Element>, ElementState)> {
+ let mut elements = (*self.unsafe_get()).modified_elements.borrow_mut_for_layout();
+ let drain = elements.drain();
let layout_drain = drain.map(|(k, v)| (k.to_layout(), v));
Vec::from_iter(layout_drain)
}
@@ -1313,7 +1313,7 @@ impl Document {
reflow_timeout: Cell::new(None),
base_element: Default::default(),
appropriate_template_contents_owner_document: Default::default(),
- element_state_changes: DOMRefCell::new(HashMap::new()),
+ modified_elements: DOMRefCell::new(HashMap::new()),
active_touch_points: DOMRefCell::new(Vec::new()),
}
}
@@ -1380,18 +1380,9 @@ impl Document {
self.idmap.borrow().get(&id).map(|ref elements| Root::from_ref(&*(*elements)[0]))
}
- pub fn record_element_state_change(&self, el: &Element, which: ElementState) {
- let mut map = self.element_state_changes.borrow_mut();
- let empty;
- {
- let states = map.entry(JS::from_ref(el))
- .or_insert(ElementState::empty());
- states.toggle(which);
- empty = states.is_empty();
- }
- if empty {
- map.remove(&JS::from_ref(el));
- }
+ pub fn element_state_will_change(&self, el: &Element) {
+ let mut map = self.modified_elements.borrow_mut();
+ map.entry(JS::from_ref(el)).or_insert(el.get_state());
}
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 7d605ecd133..d420e9b5405 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -1814,14 +1814,13 @@ impl Element {
if state.contains(which) == value {
return
}
+ let node = self.upcast::<Node>();
+ node.owner_doc().element_state_will_change(self);
match value {
true => state.insert(which),
false => state.remove(which),
};
self.state.set(state);
-
- let node = self.upcast::<Node>();
- node.owner_doc().record_element_state_change(self, which);
}
pub fn get_active_state(&self) -> bool {
diff --git a/components/style/restyle_hints.rs b/components/style/restyle_hints.rs
index fe143c3e315..c180c13dcde 100644
--- a/components/style/restyle_hints.rs
+++ b/components/style/restyle_hints.rs
@@ -195,11 +195,10 @@ impl StateDependencySet {
StateDependencySet { deps: Vec::new() }
}
- pub fn compute_hint<E>(&self, el: &E, current_state: ElementState, state_changes: ElementState)
+ pub fn compute_hint<E>(&self, el: &E, current_state: ElementState, old_state: ElementState)
-> RestyleHint where E: Element, E: Clone {
let mut hint = RestyleHint::empty();
- let mut old_state = current_state;
- old_state.toggle(state_changes);
+ let state_changes = current_state ^ old_state;
for dep in &self.deps {
if state_changes.intersects(dep.state) {
let old_el: ElementWrapper<E> = ElementWrapper::new_with_override(el.clone(), old_state);
diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs
index 53f1a0d3589..8cc56e693eb 100644
--- a/components/style/selector_matching.rs
+++ b/components/style/selector_matching.rs
@@ -174,10 +174,10 @@ impl Stylist {
pub fn restyle_hint_for_state_change<E>(&self, element: &E,
current_state: ElementState,
- state_change: ElementState)
+ old_state: ElementState)
-> RestyleHint
where E: Element + Clone {
- self.state_deps.compute_hint(element, current_state, state_change)
+ self.state_deps.compute_hint(element, current_state, old_state)
}
pub fn set_device(&mut self, device: Device) {