diff --git a/components/script/dom/htmldialogelement.rs b/components/script/dom/htmldialogelement.rs index 621eefcd8a4..1afd7f0d76f 100644 --- a/components/script/dom/htmldialogelement.rs +++ b/components/script/dom/htmldialogelement.rs @@ -5,11 +5,14 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::HTMLDialogElementBinding; use dom::bindings::codegen::Bindings::HTMLDialogElementBinding::HTMLDialogElementMethods; +use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::bindings::str::DOMString; use dom::document::Document; +use dom::element::Element; +use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; -use dom::node::Node; +use dom::node::{Node, window_from_node}; use string_cache::Atom; #[dom_struct] @@ -56,4 +59,26 @@ impl HTMLDialogElementMethods for HTMLDialogElement { fn SetReturnValue(&self, return_value: DOMString) { *self.return_value.borrow_mut() = return_value; } + + // https://html.spec.whatwg.org/multipage/#dom-dialog-close + fn Close(&self, return_value: Option) { + let element = self.upcast::(); + let target = self.upcast::(); + let win = window_from_node(self); + + // Step 1 & 2 + if element.remove_attribute(&ns!(), &atom!("open")).is_none() { + return; + } + + // Step 3 + if let Some(new_value) = return_value { + *self.return_value.borrow_mut() = new_value; + } + + // TODO: Step 4 implement pending dialog stack removal + + // Step 5 + win.dom_manipulation_task_source().queue_simple_event(target, atom!("close"), win.r()); + } } diff --git a/components/script/dom/webidls/HTMLDialogElement.webidl b/components/script/dom/webidls/HTMLDialogElement.webidl index 78a14e1e2a0..0ac76a0465e 100644 --- a/components/script/dom/webidls/HTMLDialogElement.webidl +++ b/components/script/dom/webidls/HTMLDialogElement.webidl @@ -8,5 +8,5 @@ interface HTMLDialogElement : HTMLElement { attribute DOMString returnValue; //void show(optional (MouseEvent or Element) anchor); //void showModal(optional (MouseEvent or Element) anchor); - //void close(optional DOMString returnValue); + void close(optional DOMString returnValue); }; diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index c444dcc4a8a..f767443f366 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -4374,9 +4374,6 @@ [HTMLDialogElement interface: operation showModal([object Object\],[object Object\])] expected: FAIL - [HTMLDialogElement interface: operation close(DOMString)] - expected: FAIL - [HTMLScriptElement interface: attribute async] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/interactive-elements/the-dialog-element/dialog-close.html.ini b/tests/wpt/metadata/html/semantics/interactive-elements/the-dialog-element/dialog-close.html.ini index f3efb4a6ccf..436d9b2601c 100644 --- a/tests/wpt/metadata/html/semantics/interactive-elements/the-dialog-element/dialog-close.html.ini +++ b/tests/wpt/metadata/html/semantics/interactive-elements/the-dialog-element/dialog-close.html.ini @@ -1,17 +1,5 @@ [dialog-close.html] type: testharness - [close() fires a close event] - expected: FAIL - [close() on a that doesn't have an open attribute throws an InvalidStateError exception] expected: FAIL - [close() removes the open attribute and set the returnValue to the first argument] - expected: FAIL - - [close() without argument removes the open attribute and there's no returnValue] - expected: FAIL - - [close() should set the returnValue IDL attribute but not the JS property] - expected: FAIL - diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-close.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-close.html index a3d07f053dc..9029612b241 100644 --- a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-close.html +++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-close.html @@ -36,10 +36,9 @@ was_queued = false; test(function(){ - assert_throws("INVALID_STATE_ERR", function() { - d1.close(); - }); - }, "close() on a that doesn't have an open attribute throws an InvalidStateError exception"); + d1.close("closedialog"); + assert_equals(d1.returnValue, ""); + }, "close() on a that doesn't have an open attribute aborts the steps"); test(function(){ assert_true(d2.open);