diff options
Diffstat (limited to 'components/script/dom/node.rs')
-rw-r--r-- | components/script/dom/node.rs | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index bf24682ede7..03a4ac59f16 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -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( |