diff options
author | Lanza <dev@lanza.fr> | 2016-01-11 12:46:39 +0100 |
---|---|---|
committer | Lanza <dev@lanza.fr> | 2016-01-20 16:15:37 +0100 |
commit | cfc3500dbf9f1dd9b966c4010fb01b21bfd5d80b (patch) | |
tree | a1a5495ba76bfa69a09d886c4c4709053df1a9e4 /components/script/dom | |
parent | 6663f28f0de308c9365b360cd8ad9ee9e43127ee (diff) | |
download | servo-cfc3500dbf9f1dd9b966c4010fb01b21bfd5d80b.tar.gz servo-cfc3500dbf9f1dd9b966c4010fb01b21bfd5d80b.zip |
Implement HTMLDetailsElement. Fixes #9216
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/create.rs | 3 | ||||
-rw-r--r-- | components/script/dom/htmldetailselement.rs | 107 | ||||
-rw-r--r-- | components/script/dom/macros.rs | 1 | ||||
-rw-r--r-- | components/script/dom/mod.rs | 1 | ||||
-rw-r--r-- | components/script/dom/virtualmethods.rs | 4 | ||||
-rw-r--r-- | components/script/dom/webidls/EventHandler.webidl | 1 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLDetailsElement.webidl | 9 |
7 files changed, 125 insertions, 1 deletions
diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs index 75a08464af7..4f095b905b1 100644 --- a/components/script/dom/create.rs +++ b/components/script/dom/create.rs @@ -17,6 +17,7 @@ use dom::htmlbuttonelement::HTMLButtonElement; use dom::htmlcanvaselement::HTMLCanvasElement; use dom::htmldataelement::HTMLDataElement; use dom::htmldatalistelement::HTMLDataListElement; +use dom::htmldetailselement::HTMLDetailsElement; use dom::htmldialogelement::HTMLDialogElement; use dom::htmldirectoryelement::HTMLDirectoryElement; use dom::htmldivelement::HTMLDivElement; @@ -138,7 +139,7 @@ pub fn create_element(name: QualName, atom!("datalist") => make!(HTMLDataListElement), atom!("dd") => make!(HTMLElement), atom!("del") => make!(HTMLModElement), - atom!("details") => make!(HTMLElement), + atom!("details") => make!(HTMLDetailsElement), atom!("dfn") => make!(HTMLElement), atom!("dialog") => make!(HTMLDialogElement), atom!("dir") => make!(HTMLDirectoryElement), diff --git a/components/script/dom/htmldetailselement.rs b/components/script/dom/htmldetailselement.rs new file mode 100644 index 00000000000..947c0ee42d7 --- /dev/null +++ b/components/script/dom/htmldetailselement.rs @@ -0,0 +1,107 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::attr::Attr; +use dom::bindings::codegen::Bindings::HTMLDetailsElementBinding; +use dom::bindings::codegen::Bindings::HTMLDetailsElementBinding::HTMLDetailsElementMethods; +use dom::bindings::global::GlobalRef; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::Root; +use dom::bindings::refcounted::Trusted; +use dom::document::Document; +use dom::element::AttributeMutation; +use dom::eventtarget::EventTarget; +use dom::htmlelement::HTMLElement; +use dom::node::{Node, window_from_node}; +use dom::virtualmethods::VirtualMethods; +use script_thread::ScriptThreadEventCategory::DomEvent; +use script_thread::{CommonScriptMsg, Runnable}; +use std::cell::Cell; +use string_cache::Atom; +use util::str::DOMString; + +#[dom_struct] +pub struct HTMLDetailsElement { + htmlelement: HTMLElement, + toggle_counter: Cell<u32> +} + +impl HTMLDetailsElement { + fn new_inherited(localName: Atom, + prefix: Option<DOMString>, + document: &Document) -> HTMLDetailsElement { + HTMLDetailsElement { + htmlelement: + HTMLElement::new_inherited(localName, prefix, document), + toggle_counter: Cell::new(0) + } + } + + #[allow(unrooted_must_root)] + pub fn new(localName: Atom, + prefix: Option<DOMString>, + document: &Document) -> Root<HTMLDetailsElement> { + let element = HTMLDetailsElement::new_inherited(localName, prefix, document); + Node::reflect_node(box element, document, HTMLDetailsElementBinding::Wrap) + } + + pub fn check_toggle_count(&self, number: u32) -> bool { + number == self.toggle_counter.get() + } +} + +impl HTMLDetailsElementMethods for HTMLDetailsElement { + // https://html.spec.whatwg.org/multipage/#dom-details-open + make_bool_getter!(Open, "open"); + + // https://html.spec.whatwg.org/multipage/#dom-details-open + make_bool_setter!(SetOpen, "open"); +} + +impl VirtualMethods for HTMLDetailsElement { + fn super_type(&self) -> Option<&VirtualMethods> { + Some(self.upcast::<HTMLElement>() as &VirtualMethods) + } + + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { + self.super_type().unwrap().attribute_mutated(attr, mutation); + + if attr.local_name() == &atom!("open") { + let counter = self.toggle_counter.get() + 1; + self.toggle_counter.set(counter); + ToggleEventRunnable::send(&self, counter); + } + } +} + +pub struct ToggleEventRunnable { + element: Trusted<HTMLDetailsElement>, + toggle_number: u32 +} + +impl ToggleEventRunnable { + pub fn send(node: &HTMLDetailsElement, toggle_number: u32) { + let window = window_from_node(node); + let window = window.r(); + let chan = window.dom_manipulation_thread_source(); + let handler = Trusted::new(node, chan.clone()); + let dispatcher = ToggleEventRunnable { + element: handler, + toggle_number: toggle_number, + }; + let _ = chan.send(CommonScriptMsg::RunnableMsg(DomEvent, box dispatcher)); + } +} + +impl Runnable for ToggleEventRunnable { + fn handler(self: Box<ToggleEventRunnable>) { + let target = self.element.root(); + let window = window_from_node(target.upcast::<Node>()); + + if target.check_toggle_count(self.toggle_number) { + target.upcast::<EventTarget>() + .fire_simple_event("toggle", GlobalRef::Window(window.r())); + } + } +} diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index 60ed65860f8..1bfa576a1d6 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -346,5 +346,6 @@ macro_rules! global_event_handlers( event_handler!(change, GetOnchange, SetOnchange); event_handler!(reset, GetOnreset, SetOnreset); event_handler!(submit, GetOnsubmit, SetOnsubmit); + event_handler!(toggle, GetOntoggle, SetOntoggle); ) ); diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 54f7486797a..0a9a7217c53 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -266,6 +266,7 @@ pub mod htmlcanvaselement; pub mod htmlcollection; pub mod htmldataelement; pub mod htmldatalistelement; +pub mod htmldetailselement; pub mod htmldialogelement; pub mod htmldirectoryelement; pub mod htmldivelement; diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index 3540fbddf0f..2e8391671a8 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -17,6 +17,7 @@ use dom::htmlbaseelement::HTMLBaseElement; use dom::htmlbodyelement::HTMLBodyElement; use dom::htmlbuttonelement::HTMLButtonElement; use dom::htmlcanvaselement::HTMLCanvasElement; +use dom::htmldetailselement::HTMLDetailsElement; use dom::htmlelement::HTMLElement; use dom::htmlfieldsetelement::HTMLFieldSetElement; use dom::htmlfontelement::HTMLFontElement; @@ -145,6 +146,9 @@ pub fn vtable_for(node: &Node) -> &VirtualMethods { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLCanvasElement)) => { node.downcast::<HTMLCanvasElement>().unwrap() as &VirtualMethods } + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLDetailsElement)) => { + node.downcast::<HTMLDetailsElement>().unwrap() as &VirtualMethods + } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFieldSetElement)) => { node.downcast::<HTMLFieldSetElement>().unwrap() as &VirtualMethods } diff --git a/components/script/dom/webidls/EventHandler.webidl b/components/script/dom/webidls/EventHandler.webidl index 24382756aec..91753edf9c7 100644 --- a/components/script/dom/webidls/EventHandler.webidl +++ b/components/script/dom/webidls/EventHandler.webidl @@ -33,6 +33,7 @@ interface GlobalEventHandlers { attribute EventHandler onchange; attribute EventHandler onreset; attribute EventHandler onsubmit; + attribute EventHandler ontoggle; }; [NoInterfaceObject] diff --git a/components/script/dom/webidls/HTMLDetailsElement.webidl b/components/script/dom/webidls/HTMLDetailsElement.webidl new file mode 100644 index 00000000000..062444d8312 --- /dev/null +++ b/components/script/dom/webidls/HTMLDetailsElement.webidl @@ -0,0 +1,9 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// https://html.spec.whatwg.org/multipage/#htmldetailselement +interface HTMLDetailsElement : HTMLElement { + attribute boolean open; +}; |