diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index ffb7c31de93..c2b2517d92e 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -44,6 +44,7 @@ use dom::event::{Event, EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; use dom::focusevent::FocusEvent; use dom::forcetouchevent::ForceTouchEvent; +use dom::hashchangeevent::HashChangeEvent; use dom::htmlanchorelement::HTMLAnchorElement; use dom::htmlappletelement::HTMLAppletElement; use dom::htmlareaelement::HTMLAreaElement; @@ -69,6 +70,8 @@ use dom::mouseevent::MouseEvent; use dom::node::{self, CloneChildrenFlag, Node, NodeDamage, window_from_node}; use dom::nodeiterator::NodeIterator; use dom::nodelist::NodeList; +use dom::pagetransitionevent::PageTransitionEvent; +use dom::popstateevent::PopStateEvent; use dom::processinginstruction::ProcessingInstruction; use dom::progressevent::ProgressEvent; use dom::range::Range; @@ -2195,6 +2198,12 @@ impl DocumentMethods for Document { Ok(Root::upcast(ErrorEvent::new_uninitialized(GlobalRef::Window(&self.window)))), "closeevent" => Ok(Root::upcast(CloseEvent::new_uninitialized(GlobalRef::Window(&self.window)))), + "popstateevent" => + Ok(Root::upcast(PopStateEvent::new_uninitialized(GlobalRef::Window(&self.window)))), + "hashchangeevent" => + Ok(Root::upcast(HashChangeEvent::new_uninitialized(GlobalRef::Window(&self.window)))), + "pagetransitionevent" => + Ok(Root::upcast(PageTransitionEvent::new_uninitialized(GlobalRef::Window(&self.window)))), _ => Err(Error::NotSupported), } diff --git a/components/script/dom/hashchangeevent.rs b/components/script/dom/hashchangeevent.rs new file mode 100644 index 00000000000..95308f17eed --- /dev/null +++ b/components/script/dom/hashchangeevent.rs @@ -0,0 +1,87 @@ +/* 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::bindings::codegen::Bindings::EventBinding::EventMethods; +use dom::bindings::codegen::Bindings::HashChangeEventBinding; +use dom::bindings::codegen::Bindings::HashChangeEventBinding::HashChangeEventMethods; +use dom::bindings::error::Fallible; +use dom::bindings::global::GlobalRef; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::Root; +use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::str::USVString; +use dom::event::Event; +use string_cache::Atom; +use util::str::DOMString; + +// https://html.spec.whatwg.org/multipage/#hashchangeevent +#[dom_struct] +pub struct HashChangeEvent { + event: Event, + old_url: String, + new_url: String, +} + +impl HashChangeEvent { + fn new_inherited(old_url: String, new_url: String) -> HashChangeEvent { + HashChangeEvent { + event: Event::new_inherited(), + old_url: old_url, + new_url: new_url, + } + } + + pub fn new_uninitialized(global: GlobalRef) + -> Root { + reflect_dom_object(box HashChangeEvent::new_inherited(String::new(), String::new()), + global, + HashChangeEventBinding::Wrap) + } + + pub fn new(global: GlobalRef, + type_: Atom, + bubbles: bool, + cancelable: bool, + old_url: String, + new_url: String) + -> Root { + let ev = reflect_dom_object(box HashChangeEvent::new_inherited(old_url, new_url), + global, + HashChangeEventBinding::Wrap); + { + let event = ev.upcast::(); + event.init_event(type_, bubbles, cancelable); + } + ev + } + + pub fn Constructor(global: GlobalRef, + type_: DOMString, + init: &HashChangeEventBinding::HashChangeEventInit) + -> Fallible> { + Ok(HashChangeEvent::new(global, + Atom::from(type_), + init.parent.bubbles, + init.parent.cancelable, + init.oldURL.0.clone(), + init.newURL.0.clone())) + } +} + +impl HashChangeEventMethods for HashChangeEvent { + // https://html.spec.whatwg.org/multipage/#dom-hashchangeevent-oldurl + fn OldURL(&self) -> USVString { + USVString(self.old_url.clone()) + } + + // https://html.spec.whatwg.org/multipage/#dom-hashchangeevent-newurl + fn NewURL(&self) -> USVString { + USVString(self.new_url.clone()) + } + + // https://dom.spec.whatwg.org/#dom-event-istrusted + fn IsTrusted(&self) -> bool { + self.event.IsTrusted() + } +} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 4aee5546399..cfa41a1ae19 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -264,6 +264,7 @@ pub mod filereader; pub mod focusevent; pub mod forcetouchevent; pub mod formdata; +pub mod hashchangeevent; pub mod htmlanchorelement; pub mod htmlappletelement; pub mod htmlareaelement; @@ -350,10 +351,12 @@ pub mod navigatorinfo; pub mod node; pub mod nodeiterator; pub mod nodelist; +pub mod pagetransitionevent; pub mod performance; pub mod performancetiming; pub mod plugin; pub mod pluginarray; +pub mod popstateevent; pub mod processinginstruction; pub mod progressevent; pub mod radionodelist; diff --git a/components/script/dom/pagetransitionevent.rs b/components/script/dom/pagetransitionevent.rs new file mode 100644 index 00000000000..2baa8d0693c --- /dev/null +++ b/components/script/dom/pagetransitionevent.rs @@ -0,0 +1,76 @@ +/* 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::bindings::codegen::Bindings::EventBinding::EventMethods; +use dom::bindings::codegen::Bindings::PageTransitionEventBinding; +use dom::bindings::codegen::Bindings::PageTransitionEventBinding::PageTransitionEventMethods; +use dom::bindings::error::Fallible; +use dom::bindings::global::GlobalRef; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::Root; +use dom::bindings::reflector::reflect_dom_object; +use dom::event::Event; +use std::cell::Cell; +use string_cache::Atom; +use util::str::DOMString; + +// https://html.spec.whatwg.org/multipage/#pagetransitionevent +#[dom_struct] +pub struct PageTransitionEvent { + event: Event, + persisted: Cell, +} + +impl PageTransitionEvent { + fn new_inherited() -> PageTransitionEvent { + PageTransitionEvent { + event: Event::new_inherited(), + persisted: Cell::new(false), + } + } + + pub fn new_uninitialized(global: GlobalRef) -> Root { + reflect_dom_object(box PageTransitionEvent::new_inherited(), + global, + PageTransitionEventBinding::Wrap) + } + + pub fn new(global: GlobalRef, + type_: Atom, + bubbles: bool, + cancelable: bool, + persisted: bool) + -> Root { + let ev = PageTransitionEvent::new_uninitialized(global); + ev.persisted.set(persisted); + { + let event = ev.upcast::(); + event.init_event(type_, bubbles, cancelable); + } + ev + } + + pub fn Constructor(global: GlobalRef, + type_: DOMString, + init: &PageTransitionEventBinding::PageTransitionEventInit) + -> Fallible> { + Ok(PageTransitionEvent::new(global, + Atom::from(type_), + init.parent.bubbles, + init.parent.cancelable, + init.persisted)) + } +} + +impl PageTransitionEventMethods for PageTransitionEvent { + // https://html.spec.whatwg.org/multipage/#dom-pagetransitionevent-persisted + fn Persisted(&self) -> bool { + self.persisted.get() + } + + // https://dom.spec.whatwg.org/#dom-event-istrusted + fn IsTrusted(&self) -> bool { + self.event.IsTrusted() + } +} diff --git a/components/script/dom/popstateevent.rs b/components/script/dom/popstateevent.rs new file mode 100644 index 00000000000..dd55e06b5a2 --- /dev/null +++ b/components/script/dom/popstateevent.rs @@ -0,0 +1,79 @@ +/* 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::bindings::codegen::Bindings::EventBinding::EventMethods; +use dom::bindings::codegen::Bindings::PopStateEventBinding; +use dom::bindings::codegen::Bindings::PopStateEventBinding::PopStateEventMethods; +use dom::bindings::error::Fallible; +use dom::bindings::global::GlobalRef; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::{MutHeapJSVal, Root}; +use dom::bindings::reflector::reflect_dom_object; +use dom::event::Event; +use js::jsapi::{HandleValue, JSContext}; +use js::jsval::JSVal; +use string_cache::Atom; +use util::str::DOMString; + +// https://html.spec.whatwg.org/multipage/#the-popstateevent-interface +#[dom_struct] +pub struct PopStateEvent { + event: Event, + #[ignore_heap_size_of = "Defined in rust-mozjs"] + state: MutHeapJSVal, +} + +impl PopStateEvent { + fn new_inherited() -> PopStateEvent { + PopStateEvent { + event: Event::new_inherited(), + state: MutHeapJSVal::new(), + } + } + + pub fn new_uninitialized(global: GlobalRef) -> Root { + reflect_dom_object(box PopStateEvent::new_inherited(), + global, + PopStateEventBinding::Wrap) + } + + pub fn new(global: GlobalRef, + type_: Atom, + bubbles: bool, + cancelable: bool, + state: HandleValue) + -> Root { + let ev = PopStateEvent::new_uninitialized(global); + ev.state.set(state.get()); + { + let event = ev.upcast::(); + event.init_event(type_, bubbles, cancelable); + } + ev + } + + #[allow(unsafe_code)] + pub fn Constructor(global: GlobalRef, + type_: DOMString, + init: &PopStateEventBinding::PopStateEventInit) + -> Fallible> { + Ok(PopStateEvent::new(global, + Atom::from(type_), + init.parent.bubbles, + init.parent.cancelable, + unsafe { HandleValue::from_marked_location(&init.state) })) + } +} + +impl PopStateEventMethods for PopStateEvent { + // https://html.spec.whatwg.org/multipage/#dom-popstateevent-state + fn State(&self, _cx: *mut JSContext) -> JSVal { + self.state.get() + } + + // https://dom.spec.whatwg.org/#dom-event-istrusted + fn IsTrusted(&self) -> bool { + self.event.IsTrusted() + } +} diff --git a/components/script/dom/webidls/HashChangeEvent.webidl b/components/script/dom/webidls/HashChangeEvent.webidl new file mode 100644 index 00000000000..924c300cdfe --- /dev/null +++ b/components/script/dom/webidls/HashChangeEvent.webidl @@ -0,0 +1,15 @@ +/* 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/#hashchangeevent +[Constructor(DOMString type, optional HashChangeEventInit eventInitDict)/*, Exposed=(Window,Worker)*/] +interface HashChangeEvent : Event { + readonly attribute USVString oldURL; + readonly attribute USVString newURL; +}; + +dictionary HashChangeEventInit : EventInit { + USVString oldURL = ""; + USVString newURL = ""; +}; diff --git a/components/script/dom/webidls/PageTransitionEvent.webidl b/components/script/dom/webidls/PageTransitionEvent.webidl new file mode 100644 index 00000000000..f96eda200f4 --- /dev/null +++ b/components/script/dom/webidls/PageTransitionEvent.webidl @@ -0,0 +1,13 @@ +/* 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/#the-pagetransitionevent-interface +[Constructor(DOMString type, optional PageTransitionEventInit eventInitDict)/*, Exposed=(Window,Worker)*/] +interface PageTransitionEvent : Event { + readonly attribute boolean persisted; +}; + +dictionary PageTransitionEventInit : EventInit { + boolean persisted = false; +}; diff --git a/components/script/dom/webidls/PopStateEvent.webidl b/components/script/dom/webidls/PopStateEvent.webidl new file mode 100644 index 00000000000..99372b392a6 --- /dev/null +++ b/components/script/dom/webidls/PopStateEvent.webidl @@ -0,0 +1,13 @@ +/* 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/#the-popstateevent-interface +[Constructor(DOMString type, optional PopStateEventInit eventInitDict)/*, Exposed=(Window,Worker)*/] +interface PopStateEvent : Event { + readonly attribute any state; +}; + +dictionary PopStateEventInit : EventInit { + any state = null; +}; diff --git a/tests/wpt/metadata/dom/nodes/Document-createEvent.html.ini b/tests/wpt/metadata/dom/nodes/Document-createEvent.html.ini index 0fd08c4242c..c8062768eb4 100644 --- a/tests/wpt/metadata/dom/nodes/Document-createEvent.html.ini +++ b/tests/wpt/metadata/dom/nodes/Document-createEvent.html.ini @@ -109,24 +109,6 @@ [createEvent('DRAGEVENT') should be initialized correctly.] expected: FAIL - [HashChangeEvent should be an alias for HashChangeEvent.] - expected: FAIL - - [createEvent('HashChangeEvent') should be initialized correctly.] - expected: FAIL - - [hashchangeevent should be an alias for HashChangeEvent.] - expected: FAIL - - [createEvent('hashchangeevent') should be initialized correctly.] - expected: FAIL - - [HASHCHANGEEVENT should be an alias for HashChangeEvent.] - expected: FAIL - - [createEvent('HASHCHANGEEVENT') should be initialized correctly.] - expected: FAIL - [IDBVersionChangeEvent should be an alias for IDBVersionChangeEvent.] expected: FAIL @@ -145,42 +127,6 @@ [createEvent('IDBVERSIONCHANGEEVENT') should be initialized correctly.] expected: FAIL - [PageTransitionEvent should be an alias for PageTransitionEvent.] - expected: FAIL - - [createEvent('PageTransitionEvent') should be initialized correctly.] - expected: FAIL - - [pagetransitionevent should be an alias for PageTransitionEvent.] - expected: FAIL - - [createEvent('pagetransitionevent') should be initialized correctly.] - expected: FAIL - - [PAGETRANSITIONEVENT should be an alias for PageTransitionEvent.] - expected: FAIL - - [createEvent('PAGETRANSITIONEVENT') should be initialized correctly.] - expected: FAIL - - [PopStateEvent should be an alias for PopStateEvent.] - expected: FAIL - - [createEvent('PopStateEvent') should be initialized correctly.] - expected: FAIL - - [popstateevent should be an alias for PopStateEvent.] - expected: FAIL - - [createEvent('popstateevent') should be initialized correctly.] - expected: FAIL - - [POPSTATEEVENT should be an alias for PopStateEvent.] - expected: FAIL - - [createEvent('POPSTATEEVENT') should be initialized correctly.] - expected: FAIL - [SVGZoomEvent should be an alias for SVGZoomEvent.] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini index ff811c0abff..bd6d242444a 100644 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini +++ b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini @@ -1,11 +1,5 @@ [PopStateEvent.html] type: testharness - [initPopStateEvent] - expected: FAIL - [Dispatching a synthetic PopStateEvent] expected: FAIL - [document.createEvent] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/events.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/events.html.ini deleted file mode 100644 index 8bd47801777..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/events.html.ini +++ /dev/null @@ -1,50 +0,0 @@ -[events.html] - type: testharness - [Constructing pageshow event] - expected: FAIL - - [Constructing pagehide event] - expected: FAIL - - [Constructing pageshow event, persisted true] - expected: FAIL - - [Constructing pagehide event, persisted true] - expected: FAIL - - [Constructing pageshow event, empty options] - expected: FAIL - - [Constructing pagehide event, empty options] - expected: FAIL - - [Constructing pageshow event, missing options] - expected: FAIL - - [Constructing pagehide event, missing options] - expected: FAIL - - [Constructing pageshow event, persisted:null] - expected: FAIL - - [Constructing pagehide event, persisted:null] - expected: FAIL - - [Constructing pageshow event, persisted:undefined] - expected: FAIL - - [Constructing pagehide event, persisted:undefined] - expected: FAIL - - [Constructing pageshow event, bubbles:true] - expected: FAIL - - [Constructing pagehide event, bubbles:true] - expected: FAIL - - [Constructing pageshow event, cancelable:true] - expected: FAIL - - [Constructing pagehide event, cancelable:true] - expected: FAIL - diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 6dcd1da4bf7..dd0d180c3bf 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -6207,117 +6207,6 @@ [Location interface: calling replace(DOMString) on window.location with too few arguments must throw TypeError] expected: FAIL - [PopStateEvent interface: existence and properties of interface object] - expected: FAIL - - [PopStateEvent interface object length] - expected: FAIL - - [PopStateEvent interface: existence and properties of interface prototype object] - expected: FAIL - - [PopStateEvent interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [PopStateEvent interface: attribute state] - expected: FAIL - - [PopStateEvent must be primary interface of new PopStateEvent("popstate", { data: {} })] - expected: FAIL - - [Stringification of new PopStateEvent("popstate", { data: {} })] - expected: FAIL - - [PopStateEvent interface: new PopStateEvent("popstate", { data: {} }) must inherit property "state" with the proper type (0)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "type" with the proper type (0)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "target" with the proper type (1)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "currentTarget" with the proper type (2)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "NONE" with the proper type (3)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "CAPTURING_PHASE" with the proper type (4)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "AT_TARGET" with the proper type (5)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "BUBBLING_PHASE" with the proper type (6)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "eventPhase" with the proper type (7)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "stopPropagation" with the proper type (8)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "stopImmediatePropagation" with the proper type (9)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "bubbles" with the proper type (10)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "cancelable" with the proper type (11)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "preventDefault" with the proper type (12)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "defaultPrevented" with the proper type (13)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must have own property "isTrusted"] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "timeStamp" with the proper type (15)] - expected: FAIL - - [Event interface: new PopStateEvent("popstate", { data: {} }) must inherit property "initEvent" with the proper type (16)] - expected: FAIL - - [Event interface: calling initEvent(DOMString,boolean,boolean) on new PopStateEvent("popstate", { data: {} }) with too few arguments must throw TypeError] - expected: FAIL - - [HashChangeEvent interface: existence and properties of interface object] - expected: FAIL - - [HashChangeEvent interface object length] - expected: FAIL - - [HashChangeEvent interface: existence and properties of interface prototype object] - expected: FAIL - - [HashChangeEvent interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [HashChangeEvent interface: attribute oldURL] - expected: FAIL - - [HashChangeEvent interface: attribute newURL] - expected: FAIL - - [PageTransitionEvent interface: existence and properties of interface object] - expected: FAIL - - [PageTransitionEvent interface object length] - expected: FAIL - - [PageTransitionEvent interface: existence and properties of interface prototype object] - expected: FAIL - - [PageTransitionEvent interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [PageTransitionEvent interface: attribute persisted] - expected: FAIL - [BeforeUnloadEvent interface: existence and properties of interface object] expected: FAIL @@ -8064,15 +7953,6 @@ [History interface object name] expected: FAIL - [PopStateEvent interface object name] - expected: FAIL - - [HashChangeEvent interface object name] - expected: FAIL - - [PageTransitionEvent interface object name] - expected: FAIL - [BeforeUnloadEvent interface object name] expected: FAIL diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html index 3ebf039d115..589c961a8ee 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html @@ -97,6 +97,7 @@ var interfaceNamesInGlobalScope = [ "FileReader", "FocusEvent", "FormData", + "HashChangeEvent", "HTMLAnchorElement", "HTMLAppletElement", "HTMLAreaElement", @@ -184,10 +185,12 @@ var interfaceNamesInGlobalScope = [ "NodeFilter", "NodeIterator", "NodeList", + "PageTransitionEvent", "Performance", "PerformanceTiming", "Plugin", "PluginArray", + "PopStateEvent", "ProcessingInstruction", "ProgressEvent", "RadioNodeList",