diff options
author | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-01-25 13:00:26 +0100 |
---|---|---|
committer | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-04-26 10:17:45 +0200 |
commit | 640fc04743e38491e582a6ba30ded5bebb0a3ebb (patch) | |
tree | 7afea3eec1f1638d44968de3cf63e26cc58d8727 | |
parent | 48975840dd3a4becfc5ee6adccabd303e06fc554 (diff) | |
download | servo-640fc04743e38491e582a6ba30ded5bebb0a3ebb.tar.gz servo-640fc04743e38491e582a6ba30ded5bebb0a3ebb.zip |
Implement shadow-including root, set node as in doc when connected. Makes JS work in shadow trees
-rw-r--r-- | components/script/dom/element.rs | 9 | ||||
-rw-r--r-- | components/script/dom/htmlscriptelement.rs | 6 | ||||
-rw-r--r-- | components/script/dom/node.rs | 30 | ||||
-rw-r--r-- | components/script/dom/shadowroot.rs | 9 | ||||
-rw-r--r-- | components/script/dom/webidls/Node.webidl | 6 |
5 files changed, 44 insertions, 16 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 599efd4a8cc..20b51fbfaa1 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -14,7 +14,7 @@ use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods; use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function; use crate::dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods; -use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; +use crate::dom::bindings::codegen::Bindings::NodeBinding::{GetRootNodeOptions, NodeMethods}; use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use crate::dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions}; use crate::dom::bindings::codegen::UnionTypes::NodeOrString; @@ -484,9 +484,6 @@ impl Element { return Err(Error::InvalidState); } - self.upcast::<Node>() - .set_flag(NodeFlags::IS_IN_SHADOW_TREE, true); - // Steps 4, 5 and 6. Ok(self .shadow_root @@ -3293,7 +3290,9 @@ impl Element { /// <https://dom.spec.whatwg.org/#connected> pub fn is_connected(&self) -> bool { let node = self.upcast::<Node>(); - let root = node.GetRootNode(); + let mut options = GetRootNodeOptions::empty(); + options.composed = true; // shadow included. + let root = node.GetRootNode(&options); root.is::<Document>() } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 627cfc7e779..12399c3b58e 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -778,12 +778,12 @@ impl VirtualMethods for HTMLScriptElement { } } - fn bind_to_tree(&self, tree_in_doc: bool) { + fn bind_to_tree(&self, is_connected: bool) { if let Some(ref s) = self.super_type() { - s.bind_to_tree(tree_in_doc); + s.bind_to_tree(is_connected); } - if tree_in_doc && !self.parser_inserted.get() { + if is_connected && !self.parser_inserted.get() { let script = Trusted::new(self); document_from_node(self).add_delayed_task(task!(ScriptDelayedInitialize: move || { script.root().prepare(); diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 4aa6f390b16..d27b6fad873 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -10,9 +10,12 @@ use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterData use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use crate::dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods; -use crate::dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods}; +use crate::dom::bindings::codegen::Bindings::NodeBinding::{ + GetRootNodeOptions, NodeConstants, NodeMethods, +}; use crate::dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; use crate::dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods; +use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::ShadowRootBinding::ShadowRootMethods; use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use crate::dom::bindings::codegen::InheritTypes::DocumentFragmentTypeId; use crate::dom::bindings::codegen::UnionTypes::NodeOrString; @@ -274,14 +277,23 @@ impl Node { let parent_in_doc = self.is_in_doc(); let parent_in_shadow_tree = self.is_in_shadow_tree(); for node in new_child.traverse_preorder() { - node.set_flag(NodeFlags::IS_IN_DOC, parent_in_doc); - node.set_flag(NodeFlags::IS_IN_SHADOW_TREE, parent_in_shadow_tree); if parent_in_shadow_tree { - node.set_owner_shadow_root(&*self.owner_shadow_root()); + if let Some(shadow_root) = self.downcast::<ShadowRoot>() { + node.set_owner_shadow_root(&*shadow_root); + } else { + node.set_owner_shadow_root(&*self.owner_shadow_root()); + } } + let is_connected = if let Some(element) = node.downcast::<Element>() { + element.is_connected() + } else { + false + }; + node.set_flag(NodeFlags::IS_IN_DOC, parent_in_doc || is_connected); + node.set_flag(NodeFlags::IS_IN_SHADOW_TREE, parent_in_shadow_tree); // Out-of-document elements never have the descendants flag set. debug_assert!(!node.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS)); - vtable_for(&&*node).bind_to_tree(parent_in_doc); + vtable_for(&&*node).bind_to_tree(is_connected); } } @@ -2163,7 +2175,13 @@ impl NodeMethods for Node { } // https://dom.spec.whatwg.org/#dom-node-getrootnode - fn GetRootNode(&self) -> DomRoot<Node> { + fn GetRootNode(&self, options: &GetRootNodeOptions) -> DomRoot<Node> { + if options.composed { + if let Some(shadow_root) = self.owner_shadow_root.get() { + // shadow-including root. + return shadow_root.Host().upcast::<Node>().GetRootNode(options); + } + } self.inclusive_ancestors().last().unwrap() } diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index e543750e6da..a7a3bb693e5 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -4,6 +4,7 @@ use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::ShadowRootBinding::ShadowRootMethods; use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{self, ShadowRootMode}; +use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::num::Finite; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; @@ -12,6 +13,7 @@ use crate::dom::document::Document; use crate::dom::documentfragment::DocumentFragment; use crate::dom::documentorshadowroot::{DocumentOrShadowRoot, DocumentOrShadowRootImpl}; use crate::dom::element::Element; +use crate::dom::node::{Node, NodeFlags}; use crate::dom::stylesheetlist::StyleSheetList; use crate::dom::window::Window; use dom_struct::dom_struct; @@ -28,10 +30,15 @@ pub struct ShadowRoot { } impl ShadowRoot { + #[allow(unrooted_must_root)] fn new_inherited(host: &Element, document: &Document) -> ShadowRoot { let has_browsing_context = true; + let document_fragment = DocumentFragment::new_inherited(document); + document_fragment + .upcast::<Node>() + .set_flag(NodeFlags::IS_IN_SHADOW_TREE, true); ShadowRoot { - document_fragment: DocumentFragment::new_inherited(document), + document_fragment, document_or_shadow_root: DocumentOrShadowRootImpl::new( document.window(), has_browsing_context, diff --git a/components/script/dom/webidls/Node.webidl b/components/script/dom/webidls/Node.webidl index cddb776e416..479bec28a1f 100644 --- a/components/script/dom/webidls/Node.webidl +++ b/components/script/dom/webidls/Node.webidl @@ -32,7 +32,7 @@ interface Node : EventTarget { readonly attribute Document? ownerDocument; [Pure] - Node getRootNode(); + Node getRootNode(optional GetRootNodeOptions options); [Pure] readonly attribute Node? parentNode; @@ -92,3 +92,7 @@ interface Node : EventTarget { [CEReactions, Throws] Node removeChild(Node child); }; + +dictionary GetRootNodeOptions { + boolean composed = false; +}; |