diff options
author | Vincent Ricard <magic@magicninja.org> | 2020-09-25 22:04:05 +0200 |
---|---|---|
committer | Vincent Ricard <magic@magicninja.org> | 2020-09-26 11:53:47 +0200 |
commit | ddfa9ca5b4639618b1617a86fcbeb2d74e819ed1 (patch) | |
tree | 04b0258022bc2a7be6e206359b3913de2fa192e8 /components | |
parent | 8ab389c10cfcb107cfe58fde514f5724b51909fd (diff) | |
download | servo-ddfa9ca5b4639618b1617a86fcbeb2d74e819ed1.tar.gz servo-ddfa9ca5b4639618b1617a86fcbeb2d74e819ed1.zip |
Implements HTMLDetailsElement toggle
Diffstat (limited to 'components')
-rw-r--r-- | components/script/dom/element.rs | 4 | ||||
-rw-r--r-- | components/script/dom/htmldetailselement.rs | 7 | ||||
-rw-r--r-- | components/script/dom/htmlelement.rs | 61 |
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(); + } +} |