Auto merge of #15133 - nox:events, r=jdm

Various events-related improvements

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15133)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-01-21 06:16:47 -08:00 committed by GitHub
commit ef6e0bf72d
20 changed files with 54 additions and 88 deletions

View file

@ -13,7 +13,7 @@ use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object; use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString; use dom::bindings::str::DOMString;
use dom::event::{Event, EventBubbles, EventCancelable}; use dom::event::{Event, EventBubbles, EventCancelable};
use dom::globalscope::GlobalScope; use dom::window::Window;
use servo_atoms::Atom; use servo_atoms::Atom;
// https://html.spec.whatwg.org/multipage/#beforeunloadevent // https://html.spec.whatwg.org/multipage/#beforeunloadevent
@ -31,17 +31,17 @@ impl BeforeUnloadEvent {
} }
} }
pub fn new_uninitialized(global: &GlobalScope) -> Root<BeforeUnloadEvent> { pub fn new_uninitialized(window: &Window) -> Root<BeforeUnloadEvent> {
reflect_dom_object(box BeforeUnloadEvent::new_inherited(), reflect_dom_object(box BeforeUnloadEvent::new_inherited(),
global, window,
BeforeUnloadEventBinding::Wrap) BeforeUnloadEventBinding::Wrap)
} }
pub fn new(global: &GlobalScope, pub fn new(window: &Window,
type_: Atom, type_: Atom,
bubbles: EventBubbles, bubbles: EventBubbles,
cancelable: EventCancelable) -> Root<BeforeUnloadEvent> { cancelable: EventCancelable) -> Root<BeforeUnloadEvent> {
let ev = BeforeUnloadEvent::new_uninitialized(global); let ev = BeforeUnloadEvent::new_uninitialized(window);
{ {
let event = ev.upcast::<Event>(); let event = ev.upcast::<Event>();
event.init_event(type_, bool::from(bubbles), event.init_event(type_, bool::from(bubbles),

View file

@ -7,6 +7,7 @@ use devtools_traits::ScriptToDevtoolsControlMsg;
use document_loader::{DocumentLoader, LoadType}; use document_loader::{DocumentLoader, LoadType};
use dom::activation::{ActivationSource, synthetic_click_activation}; use dom::activation::{ActivationSource, synthetic_click_activation};
use dom::attr::Attr; use dom::attr::Attr;
use dom::beforeunloadevent::BeforeUnloadEvent;
use dom::bindings::callback::ExceptionHandling; use dom::bindings::callback::ExceptionHandling;
use dom::bindings::cell::DOMRefCell; use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods; use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
@ -2603,6 +2604,8 @@ impl DocumentMethods for Document {
fn CreateEvent(&self, mut interface: DOMString) -> Fallible<Root<Event>> { fn CreateEvent(&self, mut interface: DOMString) -> Fallible<Root<Event>> {
interface.make_ascii_lowercase(); interface.make_ascii_lowercase();
match &*interface { match &*interface {
"beforeunloadevent" =>
Ok(Root::upcast(BeforeUnloadEvent::new_uninitialized(&self.window))),
"closeevent" => "closeevent" =>
Ok(Root::upcast(CloseEvent::new_uninitialized(self.window.upcast()))), Ok(Root::upcast(CloseEvent::new_uninitialized(self.window.upcast()))),
"customevent" => "customevent" =>
@ -2612,9 +2615,9 @@ impl DocumentMethods for Document {
"events" | "event" | "htmlevents" | "svgevents" => "events" | "event" | "htmlevents" | "svgevents" =>
Ok(Event::new_uninitialized(&self.window.upcast())), Ok(Event::new_uninitialized(&self.window.upcast())),
"focusevent" => "focusevent" =>
Ok(Root::upcast(FocusEvent::new_uninitialized(self.window.upcast()))), Ok(Root::upcast(FocusEvent::new_uninitialized(&self.window))),
"hashchangeevent" => "hashchangeevent" =>
Ok(Root::upcast(HashChangeEvent::new_uninitialized(&self.window.upcast()))), Ok(Root::upcast(HashChangeEvent::new_uninitialized(&self.window))),
"keyboardevent" => "keyboardevent" =>
Ok(Root::upcast(KeyboardEvent::new_uninitialized(&self.window))), Ok(Root::upcast(KeyboardEvent::new_uninitialized(&self.window))),
"messageevent" => "messageevent" =>
@ -2622,9 +2625,9 @@ impl DocumentMethods for Document {
"mouseevent" | "mouseevents" => "mouseevent" | "mouseevents" =>
Ok(Root::upcast(MouseEvent::new_uninitialized(&self.window))), Ok(Root::upcast(MouseEvent::new_uninitialized(&self.window))),
"pagetransitionevent" => "pagetransitionevent" =>
Ok(Root::upcast(PageTransitionEvent::new_uninitialized(self.window.upcast()))), Ok(Root::upcast(PageTransitionEvent::new_uninitialized(&self.window))),
"popstateevent" => "popstateevent" =>
Ok(Root::upcast(PopStateEvent::new_uninitialized(self.window.upcast()))), Ok(Root::upcast(PopStateEvent::new_uninitialized(&self.window))),
"progressevent" => "progressevent" =>
Ok(Root::upcast(ProgressEvent::new_uninitialized(self.window.upcast()))), Ok(Root::upcast(ProgressEvent::new_uninitialized(self.window.upcast()))),
"storageevent" => { "storageevent" => {

View file

@ -12,7 +12,6 @@ use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString; use dom::bindings::str::DOMString;
use dom::event::{EventBubbles, EventCancelable}; use dom::event::{EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget; use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
use dom::uievent::UIEvent; use dom::uievent::UIEvent;
use dom::window::Window; use dom::window::Window;
use std::default::Default; use std::default::Default;
@ -31,9 +30,9 @@ impl FocusEvent {
} }
} }
pub fn new_uninitialized(global: &GlobalScope) -> Root<FocusEvent> { pub fn new_uninitialized(window: &Window) -> Root<FocusEvent> {
reflect_dom_object(box FocusEvent::new_inherited(), reflect_dom_object(box FocusEvent::new_inherited(),
global, window,
FocusEventBinding::Wrap) FocusEventBinding::Wrap)
} }
@ -44,7 +43,7 @@ impl FocusEvent {
view: Option<&Window>, view: Option<&Window>,
detail: i32, detail: i32,
related_target: Option<&EventTarget>) -> Root<FocusEvent> { related_target: Option<&EventTarget>) -> Root<FocusEvent> {
let ev = FocusEvent::new_uninitialized(window.upcast()); let ev = FocusEvent::new_uninitialized(window);
ev.upcast::<UIEvent>().InitUIEvent(type_, ev.upcast::<UIEvent>().InitUIEvent(type_,
bool::from(can_bubble), bool::from(can_bubble),
bool::from(cancelable), bool::from(cancelable),

View file

@ -11,7 +11,7 @@ use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object; use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::{DOMString, USVString}; use dom::bindings::str::{DOMString, USVString};
use dom::event::Event; use dom::event::Event;
use dom::globalscope::GlobalScope; use dom::window::Window;
use servo_atoms::Atom; use servo_atoms::Atom;
// https://html.spec.whatwg.org/multipage/#hashchangeevent // https://html.spec.whatwg.org/multipage/#hashchangeevent
@ -31,13 +31,13 @@ impl HashChangeEvent {
} }
} }
pub fn new_uninitialized(global: &GlobalScope) -> Root<HashChangeEvent> { pub fn new_uninitialized(window: &Window) -> Root<HashChangeEvent> {
reflect_dom_object(box HashChangeEvent::new_inherited(String::new(), String::new()), reflect_dom_object(box HashChangeEvent::new_inherited(String::new(), String::new()),
global, window,
HashChangeEventBinding::Wrap) HashChangeEventBinding::Wrap)
} }
pub fn new(global: &GlobalScope, pub fn new(window: &Window,
type_: Atom, type_: Atom,
bubbles: bool, bubbles: bool,
cancelable: bool, cancelable: bool,
@ -45,7 +45,7 @@ impl HashChangeEvent {
new_url: String) new_url: String)
-> Root<HashChangeEvent> { -> Root<HashChangeEvent> {
let ev = reflect_dom_object(box HashChangeEvent::new_inherited(old_url, new_url), let ev = reflect_dom_object(box HashChangeEvent::new_inherited(old_url, new_url),
global, window,
HashChangeEventBinding::Wrap); HashChangeEventBinding::Wrap);
{ {
let event = ev.upcast::<Event>(); let event = ev.upcast::<Event>();
@ -54,11 +54,11 @@ impl HashChangeEvent {
ev ev
} }
pub fn Constructor(global: &GlobalScope, pub fn Constructor(window: &Window,
type_: DOMString, type_: DOMString,
init: &HashChangeEventBinding::HashChangeEventInit) init: &HashChangeEventBinding::HashChangeEventInit)
-> Fallible<Root<HashChangeEvent>> { -> Fallible<Root<HashChangeEvent>> {
Ok(HashChangeEvent::new(global, Ok(HashChangeEvent::new(window,
Atom::from(type_), Atom::from(type_),
init.parent.bubbles, init.parent.bubbles,
init.parent.cancelable, init.parent.cancelable,

View file

@ -11,7 +11,7 @@ use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object; use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString; use dom::bindings::str::DOMString;
use dom::event::Event; use dom::event::Event;
use dom::globalscope::GlobalScope; use dom::window::Window;
use servo_atoms::Atom; use servo_atoms::Atom;
use std::cell::Cell; use std::cell::Cell;
@ -30,19 +30,19 @@ impl PageTransitionEvent {
} }
} }
pub fn new_uninitialized(global: &GlobalScope) -> Root<PageTransitionEvent> { pub fn new_uninitialized(window: &Window) -> Root<PageTransitionEvent> {
reflect_dom_object(box PageTransitionEvent::new_inherited(), reflect_dom_object(box PageTransitionEvent::new_inherited(),
global, window,
PageTransitionEventBinding::Wrap) PageTransitionEventBinding::Wrap)
} }
pub fn new(global: &GlobalScope, pub fn new(window: &Window,
type_: Atom, type_: Atom,
bubbles: bool, bubbles: bool,
cancelable: bool, cancelable: bool,
persisted: bool) persisted: bool)
-> Root<PageTransitionEvent> { -> Root<PageTransitionEvent> {
let ev = PageTransitionEvent::new_uninitialized(global); let ev = PageTransitionEvent::new_uninitialized(window);
ev.persisted.set(persisted); ev.persisted.set(persisted);
{ {
let event = ev.upcast::<Event>(); let event = ev.upcast::<Event>();
@ -51,11 +51,11 @@ impl PageTransitionEvent {
ev ev
} }
pub fn Constructor(global: &GlobalScope, pub fn Constructor(window: &Window,
type_: DOMString, type_: DOMString,
init: &PageTransitionEventBinding::PageTransitionEventInit) init: &PageTransitionEventBinding::PageTransitionEventInit)
-> Fallible<Root<PageTransitionEvent>> { -> Fallible<Root<PageTransitionEvent>> {
Ok(PageTransitionEvent::new(global, Ok(PageTransitionEvent::new(window,
Atom::from(type_), Atom::from(type_),
init.parent.bubbles, init.parent.bubbles,
init.parent.cancelable, init.parent.cancelable,

View file

@ -11,7 +11,7 @@ use dom::bindings::js::{MutHeapJSVal, Root};
use dom::bindings::reflector::reflect_dom_object; use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString; use dom::bindings::str::DOMString;
use dom::event::Event; use dom::event::Event;
use dom::globalscope::GlobalScope; use dom::window::Window;
use js::jsapi::{HandleValue, JSContext}; use js::jsapi::{HandleValue, JSContext};
use js::jsval::JSVal; use js::jsval::JSVal;
use servo_atoms::Atom; use servo_atoms::Atom;
@ -32,19 +32,19 @@ impl PopStateEvent {
} }
} }
pub fn new_uninitialized(global: &GlobalScope) -> Root<PopStateEvent> { pub fn new_uninitialized(window: &Window) -> Root<PopStateEvent> {
reflect_dom_object(box PopStateEvent::new_inherited(), reflect_dom_object(box PopStateEvent::new_inherited(),
global, window,
PopStateEventBinding::Wrap) PopStateEventBinding::Wrap)
} }
pub fn new(global: &GlobalScope, pub fn new(window: &Window,
type_: Atom, type_: Atom,
bubbles: bool, bubbles: bool,
cancelable: bool, cancelable: bool,
state: HandleValue) state: HandleValue)
-> Root<PopStateEvent> { -> Root<PopStateEvent> {
let ev = PopStateEvent::new_uninitialized(global); let ev = PopStateEvent::new_uninitialized(window);
ev.state.set(state.get()); ev.state.set(state.get());
{ {
let event = ev.upcast::<Event>(); let event = ev.upcast::<Event>();
@ -54,11 +54,11 @@ impl PopStateEvent {
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn Constructor(global: &GlobalScope, pub fn Constructor(window: &Window,
type_: DOMString, type_: DOMString,
init: &PopStateEventBinding::PopStateEventInit) init: &PopStateEventBinding::PopStateEventInit)
-> Fallible<Root<PopStateEvent>> { -> Fallible<Root<PopStateEvent>> {
Ok(PopStateEvent::new(global, Ok(PopStateEvent::new(window,
Atom::from(type_), Atom::from(type_),
init.parent.bubbles, init.parent.bubbles,
init.parent.cancelable, init.parent.cancelable,

View file

@ -12,7 +12,6 @@ use dom::bindings::num::Finite;
use dom::bindings::reflector::reflect_dom_object; use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString; use dom::bindings::str::DOMString;
use dom::event::Event; use dom::event::Event;
use dom::globalscope::GlobalScope;
use dom::window::Window; use dom::window::Window;
use servo_atoms::Atom; use servo_atoms::Atom;
@ -25,7 +24,7 @@ pub struct TransitionEvent {
} }
impl TransitionEvent { impl TransitionEvent {
pub fn new_inherited(init: &TransitionEventInit) -> TransitionEvent { fn new_inherited(init: &TransitionEventInit) -> TransitionEvent {
TransitionEvent { TransitionEvent {
event: Event::new_inherited(), event: Event::new_inherited(),
property_name: Atom::from(init.propertyName.clone()), property_name: Atom::from(init.propertyName.clone()),
@ -34,11 +33,11 @@ impl TransitionEvent {
} }
} }
pub fn new(global: &GlobalScope, pub fn new(window: &Window,
type_: Atom, type_: Atom,
init: &TransitionEventInit) -> Root<TransitionEvent> { init: &TransitionEventInit) -> Root<TransitionEvent> {
let ev = reflect_dom_object(box TransitionEvent::new_inherited(init), let ev = reflect_dom_object(box TransitionEvent::new_inherited(init),
global, window,
TransitionEventBinding::Wrap); TransitionEventBinding::Wrap);
{ {
let event = ev.upcast::<Event>(); let event = ev.upcast::<Event>();
@ -50,8 +49,7 @@ impl TransitionEvent {
pub fn Constructor(window: &Window, pub fn Constructor(window: &Window,
type_: DOMString, type_: DOMString,
init: &TransitionEventInit) -> Fallible<Root<TransitionEvent>> { init: &TransitionEventInit) -> Fallible<Root<TransitionEvent>> {
let global = window.upcast::<GlobalScope>(); Ok(TransitionEvent::new(window, Atom::from(type_), init))
Ok(TransitionEvent::new(global, Atom::from(type_), init))
} }
} }

View file

@ -6,7 +6,7 @@
* https://html.spec.whatwg.org/multipage/#beforeunloadevent * https://html.spec.whatwg.org/multipage/#beforeunloadevent
*/ */
[Exposed=(Window,Worker)] [Exposed=Window]
interface BeforeUnloadEvent : Event { interface BeforeUnloadEvent : Event {
attribute DOMString returnValue; attribute DOMString returnValue;
}; };

View file

@ -3,7 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://w3c.github.io/uievents/#interface-FocusEvent // https://w3c.github.io/uievents/#interface-FocusEvent
[Constructor(DOMString typeArg, optional FocusEventInit focusEventInitDict)] [Constructor(DOMString typeArg, optional FocusEventInit focusEventInitDict),
Exposed=Window]
interface FocusEvent : UIEvent { interface FocusEvent : UIEvent {
readonly attribute EventTarget? relatedTarget; readonly attribute EventTarget? relatedTarget;
}; };

View file

@ -3,7 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#hashchangeevent // https://html.spec.whatwg.org/multipage/#hashchangeevent
[Constructor(DOMString type, optional HashChangeEventInit eventInitDict), Exposed=(Window,Worker)] [Constructor(DOMString type, optional HashChangeEventInit eventInitDict),
Exposed=Window]
interface HashChangeEvent : Event { interface HashChangeEvent : Event {
readonly attribute USVString oldURL; readonly attribute USVString oldURL;
readonly attribute USVString newURL; readonly attribute USVString newURL;

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#location // https://html.spec.whatwg.org/multipage/#location
[Exposed=(Window,Worker), Unforgeable] interface Location { [Exposed=Window, Unforgeable] interface Location {
/*stringifier*/ attribute USVString href; /*stringifier*/ attribute USVString href;
readonly attribute USVString origin; readonly attribute USVString origin;
attribute USVString protocol; attribute USVString protocol;

View file

@ -3,7 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://w3c.github.io/uievents/#interface-mouseevent // https://w3c.github.io/uievents/#interface-mouseevent
[Constructor(DOMString typeArg, optional MouseEventInit mouseEventInitDict)] [Constructor(DOMString typeArg, optional MouseEventInit mouseEventInitDict),
Exposed=Window]
interface MouseEvent : UIEvent { interface MouseEvent : UIEvent {
readonly attribute long screenX; readonly attribute long screenX;
readonly attribute long screenY; readonly attribute long screenY;

View file

@ -3,7 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#the-pagetransitionevent-interface // https://html.spec.whatwg.org/multipage/#the-pagetransitionevent-interface
[Constructor(DOMString type, optional PageTransitionEventInit eventInitDict), Exposed=(Window,Worker)] [Constructor(DOMString type, optional PageTransitionEventInit eventInitDict),
Exposed=Window]
interface PageTransitionEvent : Event { interface PageTransitionEvent : Event {
readonly attribute boolean persisted; readonly attribute boolean persisted;
}; };

View file

@ -3,7 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#the-popstateevent-interface // https://html.spec.whatwg.org/multipage/#the-popstateevent-interface
[Constructor(DOMString type, optional PopStateEventInit eventInitDict), Exposed=(Window,Worker)] [Constructor(DOMString type, optional PopStateEventInit eventInitDict),
Exposed=Window]
interface PopStateEvent : Event { interface PopStateEvent : Event {
readonly attribute any state; readonly attribute any state;
}; };

View file

@ -1624,7 +1624,7 @@ impl ScriptThread {
// FIXME: Handle pseudo-elements properly // FIXME: Handle pseudo-elements properly
pseudoElement: DOMString::new() pseudoElement: DOMString::new()
}; };
let transition_event = TransitionEvent::new(window.upcast(), let transition_event = TransitionEvent::new(&window,
atom!("transitionend"), atom!("transitionend"),
&init); &init);
transition_event.upcast::<Event>().fire(node.upcast()); transition_event.upcast::<Event>().fire(node.upcast());

View file

@ -3,9 +3,6 @@
[If the event's initialized flag is not set, an InvalidStateError must be thrown (AnimationEvent).] [If the event's initialized flag is not set, an InvalidStateError must be thrown (AnimationEvent).]
expected: FAIL expected: FAIL
[If the event's initialized flag is not set, an InvalidStateError must be thrown (BeforeUnloadEvent).]
expected: FAIL
[If the event's initialized flag is not set, an InvalidStateError must be thrown (CompositionEvent).] [If the event's initialized flag is not set, an InvalidStateError must be thrown (CompositionEvent).]
expected: FAIL expected: FAIL

View file

@ -19,24 +19,6 @@
[createEvent('ANIMATIONEVENT') should be initialized correctly.] [createEvent('ANIMATIONEVENT') should be initialized correctly.]
expected: FAIL expected: FAIL
[BeforeUnloadEvent should be an alias for BeforeUnloadEvent.]
expected: FAIL
[createEvent('BeforeUnloadEvent') should be initialized correctly.]
expected: FAIL
[beforeunloadevent should be an alias for BeforeUnloadEvent.]
expected: FAIL
[createEvent('beforeunloadevent') should be initialized correctly.]
expected: FAIL
[BEFOREUNLOADEVENT should be an alias for BeforeUnloadEvent.]
expected: FAIL
[createEvent('BEFOREUNLOADEVENT') should be initialized correctly.]
expected: FAIL
[CompositionEvent should be an alias for CompositionEvent.] [CompositionEvent should be an alias for CompositionEvent.]
expected: FAIL expected: FAIL

View file

@ -1,14 +0,0 @@
[002.worker.html]
type: testharness
[The Location interface object should not be exposed.]
expected: FAIL
[The PopStateEvent interface object should not be exposed.]
expected: FAIL
[The HashChangeEvent interface object should not be exposed.]
expected: FAIL
[The PageTransitionEvent interface object should not be exposed.]
expected: FAIL

View file

@ -7,7 +7,6 @@ importScripts("interfaces.js");
// IMPORTANT: Do not change the list below without review from a DOM peer! // IMPORTANT: Do not change the list below without review from a DOM peer!
test_interfaces([ test_interfaces([
"BeforeUnloadEvent",
"Blob", "Blob",
"CloseEvent", "CloseEvent",
"CSSStyleDeclaration", "CSSStyleDeclaration",
@ -30,21 +29,17 @@ test_interfaces([
"FileReader", "FileReader",
"FileReaderSync", "FileReaderSync",
"FormData", "FormData",
"HashChangeEvent",
"Headers", "Headers",
"History", "History",
"ImageData", "ImageData",
"Location",
"MediaError", "MediaError",
"MessageEvent", "MessageEvent",
"MimeType", "MimeType",
"MimeTypeArray", "MimeTypeArray",
"PageTransitionEvent",
"Performance", "Performance",
"PerformanceTiming", "PerformanceTiming",
"Plugin", "Plugin",
"PluginArray", "PluginArray",
"PopStateEvent",
"ProgressEvent", "ProgressEvent",
"Request", "Request",
"Response", "Response",

View file

@ -16,6 +16,7 @@ var unexpected = [
"DrawingStyle", "DrawingStyle",
"CanvasGradient", "CanvasGradient",
"CanvasPattern", "CanvasPattern",
"BeforeUnloadEvent",
"PopStateEvent", "PopStateEvent",
"HashChangeEvent", "HashChangeEvent",
"PageTransitionEvent", "PageTransitionEvent",