Implement MutationObserver.disconnect()

This commit is contained in:
Fabrice Desré 2018-05-02 13:30:02 -07:00
parent 2c9ef9e558
commit 5bfa819038
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"] #[ignore_malloc_size_of = "can't measure Rc values"]
callback: Rc<MutationCallback>, callback: Rc<MutationCallback>,
record_queue: DomRefCell<Vec<DomRoot<MutationRecord>>>, record_queue: DomRefCell<Vec<DomRoot<MutationRecord>>>,
node_list: DomRefCell<Vec<DomRoot<Node>>>,
} }
pub enum Mutation<'a> { pub enum Mutation<'a> {
@ -38,7 +39,7 @@ pub enum Mutation<'a> {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
pub struct RegisteredObserver { pub struct RegisteredObserver {
observer: DomRoot<MutationObserver>, pub observer: DomRoot<MutationObserver>,
options: ObserverOptions, options: ObserverOptions,
} }
@ -64,6 +65,7 @@ impl MutationObserver {
reflector_: Reflector::new(), reflector_: Reflector::new(),
callback: callback, callback: callback,
record_queue: DomRefCell::new(vec![]), record_queue: DomRefCell::new(vec![]),
node_list: DomRefCell::new(vec![]),
} }
} }
@ -286,6 +288,8 @@ impl MutationObserverMethods for MutationObserver {
child_list child_list
}, },
}); });
self.node_list.borrow_mut().push(DomRoot::from_ref(target));
} }
Ok(()) Ok(())
@ -297,4 +301,16 @@ impl MutationObserverMethods for MutationObserver {
self.record_queue.borrow_mut().clear(); self.record_queue.borrow_mut().clear();
records 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() 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. /// Dumps the subtree rooted at this node, for debugging.
pub fn dump(&self) { pub fn dump(&self) {
self.dump_indent(0); self.dump_indent(0);

View file

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

View file

@ -1,6 +1,5 @@
[Element-classlist.html] [Element-classlist.html]
type: testharness type: testharness
expected: TIMEOUT
[classList.remove("a") with attribute value null (HTML node)] [classList.remove("a") with attribute value null (HTML node)]
expected: FAIL 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] [MutationObserver-document.html]
type: testharness type: testharness
[setup test]
expected: FAIL
[parser insertion mutations] [parser insertion mutations]
expected: FAIL expected: FAIL

View file

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