Auto merge of #20740 - fabricedesre:mutation-observer-disconnect, r=jdm

Implement MutationObserver.disconnect()

<!-- Please describe your changes on the following line: -->
This implements https://dom.spec.whatwg.org/#dom-mutationobserver-disconnect
I added a `node_list` to the `MutationObserver` struct to keep track of the nodes involved in an observer because otherwise I could not find a way to unregister the observers on the node themselves without traversing the whole document tree. Let me know if there's something I missed.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20740)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-05-18 18:27:50 -04:00 committed by GitHub
commit fe1a057bd1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 25 additions and 15 deletions

View file

@ -27,6 +27,7 @@ pub struct MutationObserver {
#[ignore_malloc_size_of = "can't measure Rc values"]
callback: Rc<MutationCallback>,
record_queue: DomRefCell<Vec<DomRoot<MutationRecord>>>,
node_list: DomRefCell<Vec<DomRoot<Node>>>,
}
pub enum Mutation<'a> {
@ -38,7 +39,7 @@ pub enum Mutation<'a> {
#[derive(JSTraceable, MallocSizeOf)]
pub struct RegisteredObserver {
observer: DomRoot<MutationObserver>,
pub observer: DomRoot<MutationObserver>,
options: ObserverOptions,
}
@ -64,6 +65,7 @@ impl MutationObserver {
reflector_: Reflector::new(),
callback: callback,
record_queue: DomRefCell::new(vec![]),
node_list: DomRefCell::new(vec![]),
}
}
@ -286,6 +288,8 @@ impl MutationObserverMethods for MutationObserver {
child_list
},
});
self.node_list.borrow_mut().push(DomRoot::from_ref(target));
}
Ok(())
@ -297,4 +301,16 @@ impl MutationObserverMethods for MutationObserver {
self.record_queue.borrow_mut().clear();
records
}
/// https://dom.spec.whatwg.org/#dom-mutationobserver-disconnect
fn Disconnect(&self) {
// Step 1
let mut nodes = self.node_list.borrow_mut();
for node in nodes.drain(..) {
node.remove_mutation_observer(self);
}
// Step 2
self.record_queue.borrow_mut().clear();
}
}

View file

@ -392,6 +392,13 @@ impl Node {
self.mutation_observers.borrow_mut()
}
/// Removes the mutation observer for a given node.
pub fn remove_mutation_observer(&self, observer: &MutationObserver) {
self.mutation_observers.borrow_mut().retain(|reg_obs| {
&*reg_obs.observer != observer
})
}
/// Dumps the subtree rooted at this node, for debugging.
pub fn dump(&self) {
self.dump_indent(0);

View file

@ -11,7 +11,7 @@
interface MutationObserver {
[Throws]
void observe(Node target, optional MutationObserverInit options);
//void disconnect();
void disconnect();
sequence<MutationRecord> takeRecords();
};

View file

@ -1,6 +1,5 @@
[Element-classlist.html]
type: testharness
expected: TIMEOUT
[classList.remove("a") with attribute value null (HTML node)]
expected: FAIL

View file

@ -1,8 +0,0 @@
[MutationObserver-disconnect.html]
type: testharness
[subtree mutations]
expected: FAIL
[disconnect discarded some mutations]
expected: FAIL

View file

@ -1,7 +1,5 @@
[MutationObserver-document.html]
type: testharness
[setup test]
expected: FAIL
[parser insertion mutations]
expected: FAIL

View file

@ -1,2 +0,0 @@
[MutationObserver-takeRecords.html]
type: testharness