aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorVincent Ricard <magic@magicninja.org>2020-09-25 22:04:05 +0200
committerVincent Ricard <magic@magicninja.org>2020-09-26 11:53:47 +0200
commitddfa9ca5b4639618b1617a86fcbeb2d74e819ed1 (patch)
tree04b0258022bc2a7be6e206359b3913de2fa192e8 /components
parent8ab389c10cfcb107cfe58fde514f5724b51909fd (diff)
downloadservo-ddfa9ca5b4639618b1617a86fcbeb2d74e819ed1.tar.gz
servo-ddfa9ca5b4639618b1617a86fcbeb2d74e819ed1.zip
Implements HTMLDetailsElement toggle
Diffstat (limited to 'components')
-rw-r--r--components/script/dom/element.rs4
-rw-r--r--components/script/dom/htmldetailselement.rs7
-rw-r--r--components/script/dom/htmlelement.rs61
3 files changed, 71 insertions, 1 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 6bf7064f048..e7316ecfeb9 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -3309,6 +3309,10 @@ impl Element {
let element = self.downcast::<HTMLLabelElement>().unwrap();
Some(element as &dyn Activatable)
},
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLElement)) => {
+ let element = self.downcast::<HTMLElement>().unwrap();
+ Some(element as &dyn Activatable)
+ },
_ => None,
};
element.and_then(|elem| {
diff --git a/components/script/dom/htmldetailselement.rs b/components/script/dom/htmldetailselement.rs
index 314611707ea..5ec9ab68604 100644
--- a/components/script/dom/htmldetailselement.rs
+++ b/components/script/dom/htmldetailselement.rs
@@ -11,7 +11,7 @@ use crate::dom::document::Document;
use crate::dom::element::AttributeMutation;
use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlelement::HTMLElement;
-use crate::dom::node::{window_from_node, Node};
+use crate::dom::node::{window_from_node, Node, NodeDamage};
use crate::dom::virtualmethods::VirtualMethods;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
@@ -49,6 +49,10 @@ impl HTMLDetailsElement {
document,
)
}
+
+ pub fn toggle(&self) {
+ self.SetOpen(!self.Open());
+ }
}
impl HTMLDetailsElementMethods for HTMLDetailsElement {
@@ -83,6 +87,7 @@ impl VirtualMethods for HTMLDetailsElement {
}),
window.upcast(),
);
+ self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage)
}
}
}
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index 282e980f2d6..0b1cb499fe2 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use crate::dom::activation::Activatable;
use crate::dom::attr::Attr;
use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
@@ -19,9 +20,11 @@ use crate::dom::document::{Document, FocusType};
use crate::dom::documentfragment::DocumentFragment;
use crate::dom::domstringmap::DOMStringMap;
use crate::dom::element::{AttributeMutation, Element};
+use crate::dom::event::Event;
use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlbodyelement::HTMLBodyElement;
use crate::dom::htmlbrelement::HTMLBRElement;
+use crate::dom::htmldetailselement::HTMLDetailsElement;
use crate::dom::htmlframesetelement::HTMLFrameSetElement;
use crate::dom::htmlhtmlelement::HTMLHtmlElement;
use crate::dom::htmlinputelement::{HTMLInputElement, InputType};
@@ -783,6 +786,49 @@ impl HTMLElement {
None
}
+
+ // https://html.spec.whatwg.org/multipage/#the-summary-element:activation-behaviour
+ pub fn summary_activation_behavior(&self) {
+ // Step 1
+ if !self.is_summary_for_its_parent_details() {
+ return;
+ }
+
+ // Step 2
+ let parent_details = self.upcast::<Node>().GetParentNode().unwrap();
+
+ // Step 3
+ parent_details
+ .downcast::<HTMLDetailsElement>()
+ .unwrap()
+ .toggle();
+ }
+
+ // https://html.spec.whatwg.org/multipage/#summary-for-its-parent-details
+ fn is_summary_for_its_parent_details(&self) -> bool {
+ // Step 1
+ let summary_node = self.upcast::<Node>();
+ if !summary_node.has_parent() {
+ return false;
+ }
+
+ // Step 2
+ let parent = &summary_node.GetParentNode().unwrap();
+
+ // Step 3
+ if !parent.is::<HTMLDetailsElement>() {
+ return false;
+ }
+
+ // Step 4 & 5
+ let first_summary_element = parent
+ .child_elements()
+ .find(|el| el.local_name() == &local_name!("summary"));
+ match first_summary_element {
+ Some(first_summary) => &*first_summary == self.upcast::<Element>(),
+ None => false,
+ }
+ }
}
impl VirtualMethods for HTMLElement {
@@ -819,3 +865,18 @@ impl VirtualMethods for HTMLElement {
}
}
}
+
+impl Activatable for HTMLElement {
+ fn as_element(&self) -> &Element {
+ self.upcast::<Element>()
+ }
+
+ fn is_instance_activatable(&self) -> bool {
+ self.as_element().local_name() == &local_name!("summary")
+ }
+
+ // Basically used to make the HTMLSummaryElement activatable (which has no IDL definition)
+ fn activation_behavior(&self, _event: &Event, _target: &EventTarget) {
+ self.summary_activation_behavior();
+ }
+}