Support custom element callback reactions

This commit is contained in:
Connor Brewster 2017-06-21 14:40:34 -06:00
parent 596ed557d2
commit 4665991503
19 changed files with 314 additions and 252 deletions

View file

@ -30,6 +30,7 @@ use dom::bindings::str::{DOMString, USVString};
use dom::bindings::xmlname::namespace_from_domstring;
use dom::characterdata::{CharacterData, LayoutCharacterDataHelpers};
use dom::cssstylesheet::CSSStyleSheet;
use dom::customelementregistry::CallbackReaction;
use dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
use dom::documentfragment::DocumentFragment;
use dom::documenttype::DocumentType;
@ -66,6 +67,7 @@ use ref_slice::ref_slice;
use script_layout_interface::{HTMLCanvasData, OpaqueStyleAndLayoutData, SVGSVGData};
use script_layout_interface::{LayoutElementType, LayoutNodeType, TrustedNodeAddress};
use script_layout_interface::message::Msg;
use script_thread::ScriptThread;
use script_traits::DocumentActivity;
use script_traits::UntrustedNodeAddress;
use selectors::matching::{matches_selector_list, MatchingContext, MatchingMode};
@ -313,6 +315,10 @@ impl Node {
// e.g. when removing a <form>.
vtable_for(&&*node).unbind_from_tree(&context);
node.style_and_layout_data.get().map(|d| node.dispose(d));
// https://dom.spec.whatwg.org/#concept-node-remove step 14
if let Some(element) = node.as_custom_element() {
ScriptThread::enqueue_callback_reaction(&*element, CallbackReaction::Disconnected);
}
}
self.owner_doc().content_and_heritage_changed(self, NodeDamage::OtherNodeDamage);
@ -322,6 +328,15 @@ impl Node {
pub fn to_untrusted_node_address(&self) -> UntrustedNodeAddress {
UntrustedNodeAddress(self.reflector().get_jsobject().get() as *const c_void)
}
pub fn as_custom_element(&self) -> Option<Root<Element>> {
self.downcast::<Element>()
.and_then(|element| if element.get_custom_element_definition().is_some() {
Some(Root::from_ref(element))
} else {
None
})
}
}
pub struct QuerySelectorIterator {
@ -1401,13 +1416,20 @@ impl Node {
let old_doc = node.owner_doc();
// Step 2.
node.remove_self();
// Step 3.
if &*old_doc != document {
// Step 3.
// Step 3.1.
for descendant in node.traverse_preorder() {
descendant.set_owner_doc(document);
}
// Step 4.
for descendant in node.traverse_preorder() {
// Step 3.2.
if let Some(element) = node.as_custom_element() {
ScriptThread::enqueue_callback_reaction(&*element,
CallbackReaction::Adopted(old_doc.clone(), Root::from_ref(document)));
}
// Step 3.3.
vtable_for(&descendant).adopting_steps(&old_doc);
}
}
@ -1615,6 +1637,9 @@ impl Node {
// Step 7.1.
parent.add_child(*kid, child);
// Step 7.2: insertion steps.
if let Some(element) = kid.as_custom_element() {
ScriptThread::enqueue_callback_reaction(&*element, CallbackReaction::Connected);
}
}
if let SuppressObserver::Unsuppressed = suppress_observers {
vtable_for(&parent).children_changed(