mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Final nits; fix custom elements rare data usage; s/owner_s_r/containing_s_r
Clarify special case for containing_shadow_root and add it to layout accessor
This commit is contained in:
parent
9b2eb77530
commit
68bee1c771
6 changed files with 95 additions and 89 deletions
|
@ -711,7 +711,7 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.element
|
self.element
|
||||||
.upcast()
|
.upcast()
|
||||||
.owner_shadow_root_for_layout()
|
.containing_shadow_root_for_layout()
|
||||||
.map(ServoShadowRoot::from_layout_js)
|
.map(ServoShadowRoot::from_layout_js)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,10 +347,7 @@ impl Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_custom_element_definition(&self) -> Option<Rc<CustomElementDefinition>> {
|
pub fn get_custom_element_definition(&self) -> Option<Rc<CustomElementDefinition>> {
|
||||||
if let Some(rare_data) = self.rare_data().as_ref() {
|
self.rare_data().as_ref()?.custom_element_definition.clone()
|
||||||
return rare_data.custom_element_definition.clone();
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_callback_reaction(&self, function: Rc<Function>, args: Box<[Heap<JSVal>]>) {
|
pub fn push_callback_reaction(&self, function: Rc<Function>, args: Box<[Heap<JSVal>]>) {
|
||||||
|
@ -366,28 +363,32 @@ impl Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_reaction_queue(&self) {
|
pub fn clear_reaction_queue(&self) {
|
||||||
self.ensure_rare_data()
|
if let Some(ref mut rare_data) = *self.rare_data_mut() {
|
||||||
.custom_element_reaction_queue
|
rare_data.custom_element_reaction_queue.clear();
|
||||||
.clear();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invoke_reactions(&self) {
|
pub fn invoke_reactions(&self) {
|
||||||
if let Some(rare_data) = self.rare_data().as_ref() {
|
loop {
|
||||||
// TODO: This is not spec compliant, as this will allow some reactions to be processed
|
|
||||||
// after clear_reaction_queue has been called.
|
|
||||||
rooted_vec!(let mut reactions);
|
rooted_vec!(let mut reactions);
|
||||||
while !rare_data.custom_element_reaction_queue.is_empty() {
|
match *self.rare_data_mut() {
|
||||||
mem::swap(
|
Some(ref mut data) => {
|
||||||
&mut *reactions,
|
mem::swap(&mut *reactions, &mut data.custom_element_reaction_queue)
|
||||||
&mut self.ensure_rare_data().custom_element_reaction_queue,
|
},
|
||||||
);
|
None => break,
|
||||||
|
};
|
||||||
|
|
||||||
|
if reactions.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for reaction in reactions.iter() {
|
for reaction in reactions.iter() {
|
||||||
reaction.invoke(self);
|
reaction.invoke(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
reactions.clear();
|
reactions.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// style will be `None` for elements in a `display: none` subtree. otherwise, the element has a
|
/// style will be `None` for elements in a `display: none` subtree. otherwise, the element has a
|
||||||
/// layout box iff it doesn't have `display: none`.
|
/// layout box iff it doesn't have `display: none`.
|
||||||
|
@ -442,11 +443,16 @@ impl Element {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_shadow_host(&self) -> bool {
|
fn shadow_root(&self) -> Option<DomRoot<ShadowRoot>> {
|
||||||
if let Some(rare_data) = self.rare_data().as_ref() {
|
self.rare_data()
|
||||||
return rare_data.shadow_root.is_some();
|
.as_ref()?
|
||||||
|
.shadow_root
|
||||||
|
.as_ref()
|
||||||
|
.map(|sr| DomRoot::from_ref(&**sr))
|
||||||
}
|
}
|
||||||
false
|
|
||||||
|
pub fn is_shadow_host(&self) -> bool {
|
||||||
|
self.shadow_root().is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://dom.spec.whatwg.org/#dom-element-attachshadow
|
/// https://dom.spec.whatwg.org/#dom-element-attachshadow
|
||||||
|
@ -1065,10 +1071,12 @@ impl LayoutElementHelpers for LayoutDom<Element> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn get_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> {
|
unsafe fn get_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> {
|
||||||
if let Some(rare_data) = (*self.unsafe_get()).rare_data_for_layout().as_ref() {
|
(*self.unsafe_get())
|
||||||
return rare_data.shadow_root.as_ref().map(|sr| sr.to_layout());
|
.rare_data_for_layout()
|
||||||
}
|
.as_ref()?
|
||||||
None
|
.shadow_root
|
||||||
|
.as_ref()
|
||||||
|
.map(|sr| sr.to_layout())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2742,21 +2750,21 @@ impl VirtualMethods for Element {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let owner_shadow_root = self.upcast::<Node>().owner_shadow_root();
|
let containing_shadow_root = self.upcast::<Node>().containing_shadow_root();
|
||||||
if node.is_connected() {
|
if node.is_connected() {
|
||||||
let value = attr.value().as_atom().clone();
|
let value = attr.value().as_atom().clone();
|
||||||
match mutation {
|
match mutation {
|
||||||
AttributeMutation::Set(old_value) => {
|
AttributeMutation::Set(old_value) => {
|
||||||
if let Some(old_value) = old_value {
|
if let Some(old_value) = old_value {
|
||||||
let old_value = old_value.as_atom().clone();
|
let old_value = old_value.as_atom().clone();
|
||||||
if let Some(ref shadow_root) = owner_shadow_root {
|
if let Some(ref shadow_root) = containing_shadow_root {
|
||||||
shadow_root.unregister_named_element(self, old_value);
|
shadow_root.unregister_named_element(self, old_value);
|
||||||
} else {
|
} else {
|
||||||
doc.unregister_named_element(self, old_value);
|
doc.unregister_named_element(self, old_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if value != atom!("") {
|
if value != atom!("") {
|
||||||
if let Some(ref shadow_root) = owner_shadow_root {
|
if let Some(ref shadow_root) = containing_shadow_root {
|
||||||
shadow_root.register_named_element(self, value);
|
shadow_root.register_named_element(self, value);
|
||||||
} else {
|
} else {
|
||||||
doc.register_named_element(self, value);
|
doc.register_named_element(self, value);
|
||||||
|
@ -2765,7 +2773,7 @@ impl VirtualMethods for Element {
|
||||||
},
|
},
|
||||||
AttributeMutation::Removed => {
|
AttributeMutation::Removed => {
|
||||||
if value != atom!("") {
|
if value != atom!("") {
|
||||||
if let Some(ref shadow_root) = owner_shadow_root {
|
if let Some(ref shadow_root) = containing_shadow_root {
|
||||||
shadow_root.unregister_named_element(self, value);
|
shadow_root.unregister_named_element(self, value);
|
||||||
} else {
|
} else {
|
||||||
doc.unregister_named_element(self, value);
|
doc.unregister_named_element(self, value);
|
||||||
|
@ -2812,8 +2820,7 @@ impl VirtualMethods for Element {
|
||||||
|
|
||||||
let doc = document_from_node(self);
|
let doc = document_from_node(self);
|
||||||
|
|
||||||
if let Some(rare_data) = self.rare_data().as_ref() {
|
if let Some(ref shadow_root) = self.shadow_root() {
|
||||||
if let Some(ref shadow_root) = rare_data.shadow_root {
|
|
||||||
doc.register_shadow_root(&shadow_root);
|
doc.register_shadow_root(&shadow_root);
|
||||||
let shadow_root = shadow_root.upcast::<Node>();
|
let shadow_root = shadow_root.upcast::<Node>();
|
||||||
shadow_root.set_flag(NodeFlags::IS_CONNECTED, context.tree_connected);
|
shadow_root.set_flag(NodeFlags::IS_CONNECTED, context.tree_connected);
|
||||||
|
@ -2822,14 +2829,13 @@ impl VirtualMethods for Element {
|
||||||
node.bind_to_tree(context);
|
node.bind_to_tree(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if !context.tree_connected {
|
if !context.tree_connected {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref value) = *self.id_attribute.borrow() {
|
if let Some(ref value) = *self.id_attribute.borrow() {
|
||||||
if let Some(shadow_root) = self.upcast::<Node>().owner_shadow_root() {
|
if let Some(shadow_root) = self.upcast::<Node>().containing_shadow_root() {
|
||||||
shadow_root.register_named_element(self, value.clone());
|
shadow_root.register_named_element(self, value.clone());
|
||||||
} else {
|
} else {
|
||||||
doc.register_named_element(self, value.clone());
|
doc.register_named_element(self, value.clone());
|
||||||
|
@ -2852,8 +2858,7 @@ impl VirtualMethods for Element {
|
||||||
|
|
||||||
let doc = document_from_node(self);
|
let doc = document_from_node(self);
|
||||||
|
|
||||||
if let Some(rare_data) = self.rare_data().as_ref() {
|
if let Some(ref shadow_root) = self.shadow_root() {
|
||||||
if let Some(ref shadow_root) = rare_data.shadow_root {
|
|
||||||
doc.unregister_shadow_root(&shadow_root);
|
doc.unregister_shadow_root(&shadow_root);
|
||||||
let shadow_root = shadow_root.upcast::<Node>();
|
let shadow_root = shadow_root.upcast::<Node>();
|
||||||
shadow_root.set_flag(NodeFlags::IS_CONNECTED, false);
|
shadow_root.set_flag(NodeFlags::IS_CONNECTED, false);
|
||||||
|
@ -2862,7 +2867,6 @@ impl VirtualMethods for Element {
|
||||||
node.unbind_from_tree(context);
|
node.unbind_from_tree(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let fullscreen = doc.GetFullscreenElement();
|
let fullscreen = doc.GetFullscreenElement();
|
||||||
if fullscreen.deref() == Some(self) {
|
if fullscreen.deref() == Some(self) {
|
||||||
|
@ -2931,7 +2935,7 @@ impl<'a> SelectorsElement for DomRoot<Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn containing_shadow_host(&self) -> Option<Self> {
|
fn containing_shadow_host(&self) -> Option<Self> {
|
||||||
if let Some(shadow_root) = self.upcast::<Node>().owner_shadow_root() {
|
if let Some(shadow_root) = self.upcast::<Node>().containing_shadow_root() {
|
||||||
Some(shadow_root.Host())
|
Some(shadow_root.Host())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl HTMLBaseElement {
|
||||||
/// Update the cached base element in response to binding or unbinding from
|
/// Update the cached base element in response to binding or unbinding from
|
||||||
/// a tree.
|
/// a tree.
|
||||||
pub fn bind_unbind(&self, tree_in_doc: bool) {
|
pub fn bind_unbind(&self, tree_in_doc: bool) {
|
||||||
if !tree_in_doc || self.upcast::<Node>().owner_shadow_root().is_some() {
|
if !tree_in_doc || self.upcast::<Node>().containing_shadow_root().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -639,6 +639,11 @@ macro_rules! impl_rare_data (
|
||||||
self.rare_data.borrow()
|
self.rare_data.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn rare_data_mut(&self) -> RefMut<Option<Box<$type>>> {
|
||||||
|
self.rare_data.borrow_mut()
|
||||||
|
}
|
||||||
|
|
||||||
fn ensure_rare_data(&self) -> RefMut<Box<$type>> {
|
fn ensure_rare_data(&self) -> RefMut<Box<$type>> {
|
||||||
let mut rare_data = self.rare_data.borrow_mut();
|
let mut rare_data = self.rare_data.borrow_mut();
|
||||||
if rare_data.is_none() {
|
if rare_data.is_none() {
|
||||||
|
|
|
@ -282,10 +282,10 @@ impl Node {
|
||||||
|
|
||||||
for node in new_child.traverse_preorder(ShadowIncluding::No) {
|
for node in new_child.traverse_preorder(ShadowIncluding::No) {
|
||||||
if parent_in_shadow_tree {
|
if parent_in_shadow_tree {
|
||||||
if let Some(shadow_root) = self.owner_shadow_root() {
|
if let Some(shadow_root) = self.containing_shadow_root() {
|
||||||
node.set_owner_shadow_root(&*shadow_root);
|
node.set_containing_shadow_root(&*shadow_root);
|
||||||
}
|
}
|
||||||
debug_assert!(node.owner_shadow_root().is_some());
|
debug_assert!(node.containing_shadow_root().is_some());
|
||||||
}
|
}
|
||||||
node.set_flag(NodeFlags::IS_IN_DOC, parent_in_doc);
|
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_IN_SHADOW_TREE, parent_in_shadow_tree);
|
||||||
|
@ -946,21 +946,21 @@ impl Node {
|
||||||
self.owner_doc.set(Some(document));
|
self.owner_doc.set(Some(document));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn owner_shadow_root(&self) -> Option<DomRoot<ShadowRoot>> {
|
pub fn containing_shadow_root(&self) -> Option<DomRoot<ShadowRoot>> {
|
||||||
|
// NodeRareData contains the shadow root the node belongs to,
|
||||||
|
// but this node may be a shadow root itself.
|
||||||
if let Some(ref shadow_root) = self.downcast::<ShadowRoot>() {
|
if let Some(ref shadow_root) = self.downcast::<ShadowRoot>() {
|
||||||
return Some(DomRoot::from_ref(shadow_root));
|
return Some(DomRoot::from_ref(shadow_root));
|
||||||
}
|
}
|
||||||
if let Some(rare_data) = self.rare_data().as_ref() {
|
self.rare_data()
|
||||||
return rare_data
|
.as_ref()?
|
||||||
.owner_shadow_root
|
.containing_shadow_root
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|sr| DomRoot::from_ref(&**sr));
|
.map(|sr| DomRoot::from_ref(&**sr))
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_owner_shadow_root(&self, shadow_root: &ShadowRoot) {
|
pub fn set_containing_shadow_root(&self, shadow_root: &ShadowRoot) {
|
||||||
self.ensure_rare_data().owner_shadow_root = Some(Dom::from_ref(shadow_root));
|
self.ensure_rare_data().containing_shadow_root = Some(Dom::from_ref(shadow_root));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_in_html_doc(&self) -> bool {
|
pub fn is_in_html_doc(&self) -> bool {
|
||||||
|
@ -1195,7 +1195,7 @@ pub trait LayoutNodeHelpers {
|
||||||
unsafe fn next_sibling_ref(&self) -> Option<LayoutDom<Node>>;
|
unsafe fn next_sibling_ref(&self) -> Option<LayoutDom<Node>>;
|
||||||
|
|
||||||
unsafe fn owner_doc_for_layout(&self) -> LayoutDom<Document>;
|
unsafe fn owner_doc_for_layout(&self) -> LayoutDom<Document>;
|
||||||
unsafe fn owner_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>>;
|
unsafe fn containing_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>>;
|
||||||
|
|
||||||
unsafe fn is_element_for_layout(&self) -> bool;
|
unsafe fn is_element_for_layout(&self) -> bool;
|
||||||
unsafe fn get_flag(&self, flag: NodeFlags) -> bool;
|
unsafe fn get_flag(&self, flag: NodeFlags) -> bool;
|
||||||
|
@ -1280,14 +1280,16 @@ impl LayoutNodeHelpers for LayoutDom<Node> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn owner_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> {
|
unsafe fn containing_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> {
|
||||||
if let Some(rare_data) = (*self.unsafe_get()).rare_data_for_layout().as_ref() {
|
if let Some(ref shadow_root) = self.downcast::<ShadowRoot>() {
|
||||||
return rare_data
|
return Some(*shadow_root);
|
||||||
.owner_shadow_root
|
|
||||||
.as_ref()
|
|
||||||
.map(|sr| sr.to_layout());
|
|
||||||
}
|
}
|
||||||
None
|
(*self.unsafe_get())
|
||||||
|
.rare_data_for_layout()
|
||||||
|
.as_ref()?
|
||||||
|
.containing_shadow_root
|
||||||
|
.as_ref()
|
||||||
|
.map(|sr| sr.to_layout())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2292,19 +2294,13 @@ impl NodeMethods for Node {
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-node-getrootnode
|
// https://dom.spec.whatwg.org/#dom-node-getrootnode
|
||||||
fn GetRootNode(&self, options: &GetRootNodeOptions) -> DomRoot<Node> {
|
fn GetRootNode(&self, options: &GetRootNodeOptions) -> DomRoot<Node> {
|
||||||
if options.composed {
|
if let Some(shadow_root) = self.containing_shadow_root() {
|
||||||
if let Some(rare_data) = self.rare_data().as_ref() {
|
return if options.composed {
|
||||||
if let Some(ref shadow_root) = rare_data.owner_shadow_root {
|
|
||||||
// shadow-including root.
|
// shadow-including root.
|
||||||
return shadow_root.Host().upcast::<Node>().GetRootNode(options);
|
shadow_root.Host().upcast::<Node>().GetRootNode(options)
|
||||||
}
|
} else {
|
||||||
}
|
DomRoot::from_ref(shadow_root.upcast::<Node>())
|
||||||
}
|
};
|
||||||
|
|
||||||
if let Some(rare_data) = self.rare_data().as_ref() {
|
|
||||||
if let Some(ref shadow_root) = rare_data.owner_shadow_root {
|
|
||||||
return DomRoot::from_ref(shadow_root.upcast::<Node>());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.is_in_doc() {
|
if self.is_in_doc() {
|
||||||
|
@ -2837,7 +2833,7 @@ pub fn document_from_node<T: DerivedFrom<Node> + DomObject>(derived: &T) -> DomR
|
||||||
pub fn containing_shadow_root<T: DerivedFrom<Node> + DomObject>(
|
pub fn containing_shadow_root<T: DerivedFrom<Node> + DomObject>(
|
||||||
derived: &T,
|
derived: &T,
|
||||||
) -> Option<DomRoot<ShadowRoot>> {
|
) -> Option<DomRoot<ShadowRoot>> {
|
||||||
derived.upcast().owner_shadow_root()
|
derived.upcast().containing_shadow_root()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub struct NodeRareData {
|
||||||
/// The shadow root the node belongs to.
|
/// The shadow root the node belongs to.
|
||||||
/// This is None if the node is not in a shadow tree or
|
/// This is None if the node is not in a shadow tree or
|
||||||
/// if it is a ShadowRoot.
|
/// if it is a ShadowRoot.
|
||||||
pub owner_shadow_root: Option<Dom<ShadowRoot>>,
|
pub containing_shadow_root: Option<Dom<ShadowRoot>>,
|
||||||
/// Registered observers for this node.
|
/// Registered observers for this node.
|
||||||
pub mutation_observers: Vec<RegisteredObserver>,
|
pub mutation_observers: Vec<RegisteredObserver>,
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ pub struct NodeRareData {
|
||||||
#[must_root]
|
#[must_root]
|
||||||
pub struct ElementRareData {
|
pub struct ElementRareData {
|
||||||
/// https://dom.spec.whatwg.org/#dom-element-shadowroot
|
/// https://dom.spec.whatwg.org/#dom-element-shadowroot
|
||||||
|
/// The ShadowRoot this element is host of.
|
||||||
/// XXX This is currently not exposed to web content. Only for
|
/// XXX This is currently not exposed to web content. Only for
|
||||||
/// internal use.
|
/// internal use.
|
||||||
pub shadow_root: Option<Dom<ShadowRoot>>,
|
pub shadow_root: Option<Dom<ShadowRoot>>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue