mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Add is_connected flag to node and use it to replace most uses of is_in_doc
This commit is contained in:
parent
640fc04743
commit
441357b74e
29 changed files with 111 additions and 96 deletions
|
@ -1050,7 +1050,7 @@ fn inner_text_collection_steps<N: LayoutNode>(
|
|||
|
||||
// Step 3.
|
||||
let display = style.get_box().display;
|
||||
if !child.is_in_document() || display == Display::None {
|
||||
if !child.is_connected() || display == Display::None {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -260,8 +260,8 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
|
|||
None
|
||||
}
|
||||
|
||||
fn is_in_document(&self) -> bool {
|
||||
unsafe { self.node.get_flag(NodeFlags::IS_IN_DOC) }
|
||||
fn is_connected(&self) -> bool {
|
||||
unsafe { self.node.get_flag(NodeFlags::IS_CONNECTED) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,7 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
|||
}
|
||||
|
||||
unsafe fn set_dirty_descendants(&self) {
|
||||
debug_assert!(self.as_node().is_in_document());
|
||||
debug_assert!(self.as_node().is_connected());
|
||||
self.as_node()
|
||||
.node
|
||||
.set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, true)
|
||||
|
|
|
@ -246,7 +246,7 @@ impl CSSStyleDeclaration {
|
|||
},
|
||||
CSSStyleOwner::Element(ref el) => {
|
||||
let node = el.upcast::<Node>();
|
||||
if !node.is_in_doc() {
|
||||
if !node.is_connected() {
|
||||
// TODO: Node should be matched against the style rules of this window.
|
||||
// Firefox is currently the only browser to implement this.
|
||||
return DOMString::new();
|
||||
|
|
|
@ -680,7 +680,7 @@ impl Document {
|
|||
}
|
||||
|
||||
pub fn content_and_heritage_changed(&self, node: &Node) {
|
||||
if node.is_in_doc() {
|
||||
if node.is_connected() {
|
||||
node.note_dirty_descendants();
|
||||
}
|
||||
|
||||
|
@ -749,7 +749,7 @@ impl Document {
|
|||
"Adding named element to document {:p}: {:p} id={}",
|
||||
self, element, id
|
||||
);
|
||||
assert!(element.upcast::<Node>().is_in_doc());
|
||||
assert!(element.upcast::<Node>().is_connected());
|
||||
assert!(!id.is_empty());
|
||||
|
||||
let root = self.GetDocumentElement().expect(
|
||||
|
@ -2481,12 +2481,12 @@ impl LayoutDocumentHelpers for LayoutDom<Document> {
|
|||
let mut elements = (*self.unsafe_get())
|
||||
.pending_restyles
|
||||
.borrow_mut_for_layout();
|
||||
// Elements were in a document when they were adding to this list, but that
|
||||
// Elements were in a document when they were added to this list, but that
|
||||
// may no longer be true when the next layout occurs.
|
||||
let result = elements
|
||||
.drain()
|
||||
.map(|(k, v)| (k.to_layout(), v))
|
||||
.filter(|&(ref k, _)| k.upcast::<Node>().get_flag(NodeFlags::IS_IN_DOC))
|
||||
.filter(|&(ref k, _)| k.upcast::<Node>().get_flag(NodeFlags::IS_CONNECTED))
|
||||
.collect();
|
||||
result
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::dom::attr::{Attr, AttrHelpersForLayout};
|
|||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::DocumentFragmentBinding::DocumentFragmentBinding::DocumentFragmentMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::ElementBinding;
|
||||
use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
||||
|
@ -1202,7 +1203,13 @@ impl Element {
|
|||
}
|
||||
|
||||
pub fn root_element(&self) -> DomRoot<Element> {
|
||||
if self.node.is_in_doc() {
|
||||
if self.node.is_in_shadow_tree() {
|
||||
self.upcast::<Node>()
|
||||
.owner_shadow_root()
|
||||
.upcast::<DocumentFragment>()
|
||||
.GetFirstElementChild()
|
||||
.unwrap()
|
||||
} else if self.node.is_in_doc() {
|
||||
self.upcast::<Node>()
|
||||
.owner_doc()
|
||||
.GetDocumentElement()
|
||||
|
@ -2718,7 +2725,7 @@ impl VirtualMethods for Element {
|
|||
None
|
||||
}
|
||||
});
|
||||
if node.is_in_doc() {
|
||||
if node.is_connected() {
|
||||
let value = attr.value().as_atom().clone();
|
||||
match mutation {
|
||||
AttributeMutation::Set(old_value) => {
|
||||
|
@ -2764,16 +2771,16 @@ impl VirtualMethods for Element {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
if let Some(f) = self.as_maybe_form_control() {
|
||||
f.bind_form_control_to_tree();
|
||||
}
|
||||
|
||||
if !tree_in_doc {
|
||||
if !tree_connected {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2792,7 +2799,7 @@ impl VirtualMethods for Element {
|
|||
f.unbind_form_control_from_tree();
|
||||
}
|
||||
|
||||
if !context.tree_in_doc {
|
||||
if !context.tree_connected {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,8 @@ impl HTMLBaseElement {
|
|||
|
||||
/// Update the cached base element in response to binding or unbinding from
|
||||
/// a tree.
|
||||
pub fn bind_unbind(&self, tree_in_doc: bool) {
|
||||
if !tree_in_doc {
|
||||
pub fn bind_unbind(&self, tree_connected: bool) {
|
||||
if !tree_connected {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -119,13 +119,13 @@ impl VirtualMethods for HTMLBaseElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
self.super_type().unwrap().bind_to_tree(tree_in_doc);
|
||||
self.bind_unbind(tree_in_doc);
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
self.super_type().unwrap().bind_to_tree(tree_connected);
|
||||
self.bind_unbind(tree_connected);
|
||||
}
|
||||
|
||||
fn unbind_from_tree(&self, context: &UnbindContext) {
|
||||
self.super_type().unwrap().unbind_from_tree(context);
|
||||
self.bind_unbind(context.tree_in_doc);
|
||||
self.bind_unbind(context.tree_connected);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,12 +149,12 @@ impl VirtualMethods for HTMLBodyElement {
|
|||
.attribute_affects_presentational_hints(attr)
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
if !tree_in_doc {
|
||||
if !tree_connected {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -232,9 +232,9 @@ impl VirtualMethods for HTMLButtonElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
self.upcast::<Element>()
|
||||
|
|
|
@ -459,7 +459,7 @@ impl HTMLElementMethods for HTMLElement {
|
|||
let element = self.upcast::<Element>();
|
||||
|
||||
// Step 1.
|
||||
let element_not_rendered = !node.is_in_doc() || !element.has_css_layout_box();
|
||||
let element_not_rendered = !node.is_connected() || !element.has_css_layout_box();
|
||||
if element_not_rendered {
|
||||
return node.GetTextContent().unwrap();
|
||||
}
|
||||
|
|
|
@ -1100,7 +1100,7 @@ pub trait FormControl: DomObject {
|
|||
let form_id = elem.get_string_attribute(&local_name!("form"));
|
||||
let node = elem.upcast::<Node>();
|
||||
|
||||
if self.is_listed() && !form_id.is_empty() && node.is_in_doc() {
|
||||
if self.is_listed() && !form_id.is_empty() && node.is_connected() {
|
||||
let doc = document_from_node(node);
|
||||
doc.register_form_id_listener(form_id, self);
|
||||
}
|
||||
|
|
|
@ -81,9 +81,9 @@ impl VirtualMethods for HTMLHeadElement {
|
|||
fn super_type(&self) -> Option<&dyn VirtualMethods> {
|
||||
Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods)
|
||||
}
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
load_script(self);
|
||||
}
|
||||
|
|
|
@ -584,7 +584,7 @@ impl VirtualMethods for HTMLIFrameElement {
|
|||
// may be in a different script thread. Instread, we check to see if the parent
|
||||
// is in a document tree and has a browsing context, which is what causes
|
||||
// the child browsing context to be created.
|
||||
if self.upcast::<Node>().is_in_doc_with_browsing_context() {
|
||||
if self.upcast::<Node>().is_connected_with_browsing_context() {
|
||||
debug!("iframe src set while in browsing context.");
|
||||
self.process_the_iframe_attributes(ProcessingMode::NotFirstTime);
|
||||
}
|
||||
|
@ -610,9 +610,9 @@ impl VirtualMethods for HTMLIFrameElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
let iframe = Trusted::new(self);
|
||||
|
@ -624,9 +624,9 @@ impl VirtualMethods for HTMLIFrameElement {
|
|||
// browsing context, set the element's nested browsing context
|
||||
// to the newly-created browsing context, and then process the
|
||||
// iframe attributes for the "first time"."
|
||||
if this.upcast::<Node>().is_in_doc_with_browsing_context() {
|
||||
if this.upcast::<Node>().is_connected_with_browsing_context() {
|
||||
debug!("iframe bound to browsing context.");
|
||||
debug_assert!(tree_in_doc, "is_in_doc_with_bc, but not tree_in_doc");
|
||||
debug_assert!(tree_connected, "is_connected_with_bc, but not tree_connected");
|
||||
this.create_nested_browsing_context();
|
||||
this.process_the_iframe_attributes(ProcessingMode::FirstTime);
|
||||
}
|
||||
|
|
|
@ -1645,12 +1645,12 @@ impl VirtualMethods for HTMLImageElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
let document = document_from_node(self);
|
||||
if tree_in_doc {
|
||||
if tree_connected {
|
||||
document.register_responsive_image(self);
|
||||
}
|
||||
|
||||
|
|
|
@ -1422,9 +1422,9 @@ impl VirtualMethods for HTMLInputElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
self.upcast::<Element>()
|
||||
.check_ancestors_disabled_state_for_form_control();
|
||||
|
|
|
@ -56,9 +56,9 @@ impl VirtualMethods for HTMLLegendElement {
|
|||
Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods)
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
self.upcast::<Element>()
|
||||
|
|
|
@ -183,7 +183,7 @@ impl VirtualMethods for HTMLLinkElement {
|
|||
|
||||
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||
if !self.upcast::<Node>().is_in_doc() || mutation.is_removal() {
|
||||
if !self.upcast::<Node>().is_connected() || mutation.is_removal() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -222,12 +222,12 @@ impl VirtualMethods for HTMLLinkElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
if tree_in_doc {
|
||||
if tree_connected {
|
||||
let element = self.upcast();
|
||||
|
||||
let rel = get_attr(element, &local_name!("rel"));
|
||||
|
|
|
@ -2009,7 +2009,7 @@ impl VirtualMethods for HTMLMediaElement {
|
|||
fn unbind_from_tree(&self, context: &UnbindContext) {
|
||||
self.super_type().unwrap().unbind_from_tree(context);
|
||||
|
||||
if context.tree_in_doc {
|
||||
if context.tree_connected {
|
||||
let task = MediaElementMicrotask::PauseIfNotInDocumentTask {
|
||||
elem: DomRoot::from_ref(self),
|
||||
};
|
||||
|
@ -2061,7 +2061,7 @@ impl MicrotaskRunnable for MediaElementMicrotask {
|
|||
}
|
||||
},
|
||||
&MediaElementMicrotask::PauseIfNotInDocumentTask { ref elem } => {
|
||||
if !elem.upcast::<Node>().is_in_doc() {
|
||||
if !elem.upcast::<Node>().is_connected() {
|
||||
elem.internal_pause_steps();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -171,12 +171,12 @@ impl VirtualMethods for HTMLMetaElement {
|
|||
Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods)
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
if tree_in_doc {
|
||||
if tree_connected {
|
||||
self.process_attributes();
|
||||
}
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ impl VirtualMethods for HTMLMetaElement {
|
|||
s.unbind_from_tree(context);
|
||||
}
|
||||
|
||||
if context.tree_in_doc {
|
||||
if context.tree_connected {
|
||||
self.process_referrer_attribute();
|
||||
|
||||
if let Some(s) = self.stylesheet.borrow_mut().take() {
|
||||
|
|
|
@ -235,9 +235,9 @@ impl VirtualMethods for HTMLOptionElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
self.upcast::<Element>()
|
||||
|
|
|
@ -372,7 +372,7 @@ impl HTMLScriptElement {
|
|||
}
|
||||
|
||||
// Step 5.
|
||||
if !self.upcast::<Node>().is_in_doc() {
|
||||
if !self.upcast::<Node>().is_connected() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -760,7 +760,7 @@ impl VirtualMethods for HTMLScriptElement {
|
|||
match *attr.local_name() {
|
||||
local_name!("src") => {
|
||||
if let AttributeMutation::Set(_) = mutation {
|
||||
if !self.parser_inserted.get() && self.upcast::<Node>().is_in_doc() {
|
||||
if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() {
|
||||
self.prepare();
|
||||
}
|
||||
}
|
||||
|
@ -773,7 +773,7 @@ impl VirtualMethods for HTMLScriptElement {
|
|||
if let Some(ref s) = self.super_type() {
|
||||
s.children_changed(mutation);
|
||||
}
|
||||
if !self.parser_inserted.get() && self.upcast::<Node>().is_in_doc() {
|
||||
if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() {
|
||||
self.prepare();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -382,9 +382,9 @@ impl VirtualMethods for HTMLSelectElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
self.upcast::<Element>()
|
||||
|
|
|
@ -82,8 +82,8 @@ impl VirtualMethods for HTMLSourceElement {
|
|||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#the-source-element:nodes-are-inserted>
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
self.super_type().unwrap().bind_to_tree(tree_in_doc);
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
self.super_type().unwrap().bind_to_tree(tree_connected);
|
||||
let parent = self.upcast::<Node>().GetParentNode().unwrap();
|
||||
if let Some(media) = parent.downcast::<HTMLMediaElement>() {
|
||||
media.handle_source_child_insertion();
|
||||
|
|
|
@ -185,14 +185,14 @@ impl VirtualMethods for HTMLStyleElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
self.super_type().unwrap().bind_to_tree(tree_in_doc);
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
self.super_type().unwrap().bind_to_tree(tree_connected);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#update-a-style-block
|
||||
// Handles the case when:
|
||||
// "The element is not on the stack of open elements of an HTML parser or XML parser,
|
||||
// and it becomes connected or disconnected."
|
||||
if tree_in_doc && !self.in_stack_of_open_elements.get() {
|
||||
if tree_connected && !self.in_stack_of_open_elements.get() {
|
||||
self.parse_own_css();
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ impl VirtualMethods for HTMLStyleElement {
|
|||
s.unbind_from_tree(context);
|
||||
}
|
||||
|
||||
if context.tree_in_doc {
|
||||
if context.tree_connected {
|
||||
if let Some(s) = self.stylesheet.borrow_mut().take() {
|
||||
document_from_node(self).remove_stylesheet(self.upcast(), &s)
|
||||
}
|
||||
|
|
|
@ -466,9 +466,9 @@ impl VirtualMethods for HTMLTextAreaElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
|
||||
self.upcast::<Element>()
|
||||
|
|
|
@ -69,17 +69,17 @@ impl VirtualMethods for HTMLTitleElement {
|
|||
s.children_changed(mutation);
|
||||
}
|
||||
let node = self.upcast::<Node>();
|
||||
if node.is_in_doc() {
|
||||
if node.is_connected() {
|
||||
node.owner_doc().title_changed();
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
let node = self.upcast::<Node>();
|
||||
if tree_in_doc {
|
||||
if tree_connected {
|
||||
node.owner_doc().title_changed();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,8 +190,11 @@ bitflags! {
|
|||
/// Whether this element has already handled the stored snapshot.
|
||||
const HANDLED_SNAPSHOT = 1 << 8;
|
||||
|
||||
// Whether this node participates in a shadow tree.
|
||||
/// Whether this node participates in a shadow tree.
|
||||
const IS_IN_SHADOW_TREE = 1 << 9;
|
||||
|
||||
/// Specifies whether this node's shadow-including root is a document.
|
||||
const IS_CONNECTED = 1 << 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,8 +292,9 @@ impl Node {
|
|||
} else {
|
||||
false
|
||||
};
|
||||
node.set_flag(NodeFlags::IS_IN_DOC, parent_in_doc || is_connected);
|
||||
node.set_flag(NodeFlags::IS_IN_DOC, parent_in_doc);
|
||||
node.set_flag(NodeFlags::IS_IN_SHADOW_TREE, parent_in_shadow_tree);
|
||||
node.set_flag(NodeFlags::IS_CONNECTED, is_connected);
|
||||
// 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(is_connected);
|
||||
|
@ -492,6 +496,10 @@ impl Node {
|
|||
self.flags.get().contains(NodeFlags::IS_IN_SHADOW_TREE)
|
||||
}
|
||||
|
||||
pub fn is_connected(&self) -> bool {
|
||||
self.flags.get().contains(NodeFlags::IS_CONNECTED)
|
||||
}
|
||||
|
||||
/// Returns the type ID of this node.
|
||||
pub fn type_id(&self) -> NodeTypeId {
|
||||
match *self.eventtarget.type_id() {
|
||||
|
@ -550,7 +558,7 @@ impl Node {
|
|||
|
||||
// FIXME(emilio): This and the function below should move to Element.
|
||||
pub fn note_dirty_descendants(&self) {
|
||||
debug_assert!(self.is_in_doc());
|
||||
debug_assert!(self.is_connected());
|
||||
|
||||
for ancestor in self.inclusive_ancestors() {
|
||||
if ancestor.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS) {
|
||||
|
@ -583,7 +591,7 @@ impl Node {
|
|||
|
||||
pub fn dirty(&self, damage: NodeDamage) {
|
||||
self.rev_version();
|
||||
if !self.is_in_doc() {
|
||||
if !self.is_connected() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -917,8 +925,8 @@ impl Node {
|
|||
self.owner_doc().is_html_document()
|
||||
}
|
||||
|
||||
pub fn is_in_doc_with_browsing_context(&self) -> bool {
|
||||
self.is_in_doc() && self.owner_doc().browsing_context().is_some()
|
||||
pub fn is_connected_with_browsing_context(&self) -> bool {
|
||||
self.is_connected() && self.owner_doc().browsing_context().is_some()
|
||||
}
|
||||
|
||||
pub fn children(&self) -> impl Iterator<Item = DomRoot<Node>> {
|
||||
|
@ -2915,8 +2923,8 @@ pub struct UnbindContext<'a> {
|
|||
prev_sibling: Option<&'a Node>,
|
||||
/// The next sibling of the inclusive ancestor that was removed.
|
||||
pub next_sibling: Option<&'a Node>,
|
||||
/// Whether the tree is in a document.
|
||||
pub tree_in_doc: bool,
|
||||
/// Whether the tree is connected.
|
||||
pub tree_connected: bool,
|
||||
}
|
||||
|
||||
impl<'a> UnbindContext<'a> {
|
||||
|
@ -2932,7 +2940,7 @@ impl<'a> UnbindContext<'a> {
|
|||
parent: parent,
|
||||
prev_sibling: prev_sibling,
|
||||
next_sibling: next_sibling,
|
||||
tree_in_doc: parent.is_in_doc(),
|
||||
tree_connected: parent.is_connected(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,15 +90,15 @@ pub trait VirtualMethods {
|
|||
}
|
||||
}
|
||||
|
||||
/// Called when a Node is appended to a tree, where 'tree_in_doc' indicates
|
||||
/// Called when a Node is appended to a tree, where 'tree_connected' indicates
|
||||
/// whether the tree is part of a Document.
|
||||
fn bind_to_tree(&self, tree_in_doc: bool) {
|
||||
fn bind_to_tree(&self, tree_connected: bool) {
|
||||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
s.bind_to_tree(tree_connected);
|
||||
}
|
||||
}
|
||||
|
||||
/// Called when a Node is removed from a tree, where 'tree_in_doc'
|
||||
/// Called when a Node is removed from a tree, where 'tree_connected'
|
||||
/// indicates whether the tree is part of a Document.
|
||||
/// Implements removing steps:
|
||||
/// <https://dom.spec.whatwg.org/#concept-node-remove-ext>
|
||||
|
|
|
@ -185,8 +185,8 @@ pub trait TNode: Sized + Copy + Clone + Debug + NodeInfo + PartialEq {
|
|||
DomChildren(self.first_child())
|
||||
}
|
||||
|
||||
/// Returns whether the node is attached to a document.
|
||||
fn is_in_document(&self) -> bool;
|
||||
/// Returns whether the node is connected.
|
||||
fn is_connected(&self) -> bool;
|
||||
|
||||
/// Iterate over the DOM children of a node, in preorder.
|
||||
fn dom_descendants(&self) -> DomDescendants<Self> {
|
||||
|
|
|
@ -231,7 +231,7 @@ where
|
|||
// Optimize for when the root is a document or a shadow root and the element
|
||||
// is connected to that root.
|
||||
if root.as_document().is_some() {
|
||||
debug_assert!(element.as_node().is_in_document(), "Not connected?");
|
||||
debug_assert!(element.as_node().is_connected(), "Not connected?");
|
||||
debug_assert_eq!(
|
||||
root,
|
||||
root.owner_doc().as_node(),
|
||||
|
@ -275,18 +275,18 @@ where
|
|||
return Err(());
|
||||
}
|
||||
|
||||
if root.is_in_document() {
|
||||
if root.is_connected() {
|
||||
if let Some(shadow) = root.as_shadow_root() {
|
||||
return shadow.elements_with_id(id);
|
||||
}
|
||||
|
||||
if let Some(shadow) = root.as_element().and_then(|e| e.containing_shadow()) {
|
||||
return shadow.elements_with_id(id);
|
||||
}
|
||||
|
||||
return root.owner_doc().elements_with_id(id);
|
||||
}
|
||||
|
||||
if let Some(shadow) = root.as_shadow_root() {
|
||||
return shadow.elements_with_id(id);
|
||||
}
|
||||
|
||||
if let Some(shadow) = root.as_element().and_then(|e| e.containing_shadow()) {
|
||||
return shadow.elements_with_id(id);
|
||||
}
|
||||
|
||||
Err(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue