LibWeb: Implement WindowEventHandlers

This commit is contained in:
Luke Wilde 2022-06-27 19:48:54 +01:00 committed by Linus Groh
parent ebf2184636
commit 3fe66bddf4
Notes: sideshowbarker 2024-07-17 09:52:33 +09:00
15 changed files with 186 additions and 9 deletions

View file

@ -137,10 +137,11 @@ void WindowObject::initialize_global_object()
// WebAssembly "namespace"
define_direct_property("WebAssembly", heap().allocate<WebAssemblyObject>(*this, *this), JS::Attribute::Enumerable | JS::Attribute::Configurable);
// HTML::GlobalEventHandlers
// HTML::GlobalEventHandlers and HTML::WindowEventHandlers
#define __ENUMERATE(attribute, event_name) \
define_native_accessor(#attribute, attribute##_getter, attribute##_setter, attr);
ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE);
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE);
#undef __ENUMERATE
ADD_WINDOW_OBJECT_INTERFACES;
@ -719,6 +720,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::name_setter)
return JS::js_undefined(); \
}
ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE)
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
}

View file

@ -17,6 +17,7 @@
#include <LibWeb/Bindings/CrossOriginAbstractOperations.h>
#include <LibWeb/Forward.h>
#include <LibWeb/HTML/GlobalEventHandlers.h>
#include <LibWeb/HTML/WindowEventHandlers.h>
namespace Web {
namespace Bindings {
@ -140,6 +141,7 @@ private:
JS_DECLARE_NATIVE_FUNCTION(attribute##_getter); \
JS_DECLARE_NATIVE_FUNCTION(attribute##_setter);
ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE);
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE);
#undef __ENUMERATE
NonnullRefPtr<HTML::Window> m_impl;

View file

@ -226,6 +226,7 @@ set(SOURCES
HTML/TextMetrics.cpp
HTML/Timer.cpp
HTML/Window.cpp
HTML/WindowEventHandlers.cpp
HTML/Worker.cpp
HTML/WorkerDebugConsoleClient.cpp
HTML/WorkerGlobalScope.cpp

View file

@ -6,6 +6,10 @@ typedef EventHandlerNonNull? EventHandler;
callback OnErrorEventHandlerNonNull = any ((Event or DOMString) event, optional DOMString source, optional unsigned long lineno, optional unsigned long colno, optional any error);
typedef OnErrorEventHandlerNonNull? OnErrorEventHandler;
[LegacyTreatNonObjectAsNull]
callback OnBeforeUnloadEventHandlerNonNull = DOMString? (Event event);
typedef OnBeforeUnloadEventHandlerNonNull? OnBeforeUnloadEventHandler;
interface mixin GlobalEventHandlers {
attribute EventHandler onabort;
attribute EventHandler onauxclick;
@ -77,3 +81,22 @@ interface mixin GlobalEventHandlers {
attribute EventHandler onwebkittransitionend;
attribute EventHandler onwheel;
};
interface mixin WindowEventHandlers {
attribute EventHandler onafterprint;
attribute EventHandler onbeforeprint;
attribute OnBeforeUnloadEventHandler onbeforeunload;
attribute EventHandler onhashchange;
attribute EventHandler onlanguagechange;
attribute EventHandler onmessage;
attribute EventHandler onmessageerror;
attribute EventHandler onoffline;
attribute EventHandler ononline;
attribute EventHandler onpagehide;
attribute EventHandler onpageshow;
attribute EventHandler onpopstate;
attribute EventHandler onrejectionhandled;
attribute EventHandler onstorage;
attribute EventHandler onunhandledrejection;
attribute EventHandler onunload;
};

View file

@ -98,7 +98,10 @@ namespace AttributeNames {
__ENUMERATE_HTML_ATTRIBUTE(novalidate) \
__ENUMERATE_HTML_ATTRIBUTE(nowrap) \
__ENUMERATE_HTML_ATTRIBUTE(onabort) \
__ENUMERATE_HTML_ATTRIBUTE(onafterprint) \
__ENUMERATE_HTML_ATTRIBUTE(onauxclick) \
__ENUMERATE_HTML_ATTRIBUTE(onbeforeprint) \
__ENUMERATE_HTML_ATTRIBUTE(onbeforeunload) \
__ENUMERATE_HTML_ATTRIBUTE(onblur) \
__ENUMERATE_HTML_ATTRIBUTE(oncancel) \
__ENUMERATE_HTML_ATTRIBUTE(oncanplay) \
@ -122,15 +125,19 @@ namespace AttributeNames {
__ENUMERATE_HTML_ATTRIBUTE(onerror) \
__ENUMERATE_HTML_ATTRIBUTE(onfocus) \
__ENUMERATE_HTML_ATTRIBUTE(onformdata) \
__ENUMERATE_HTML_ATTRIBUTE(onhashchange) \
__ENUMERATE_HTML_ATTRIBUTE(oninput) \
__ENUMERATE_HTML_ATTRIBUTE(oninvalid) \
__ENUMERATE_HTML_ATTRIBUTE(onkeydown) \
__ENUMERATE_HTML_ATTRIBUTE(onkeypress) \
__ENUMERATE_HTML_ATTRIBUTE(onkeyup) \
__ENUMERATE_HTML_ATTRIBUTE(onlanguagechange) \
__ENUMERATE_HTML_ATTRIBUTE(onload) \
__ENUMERATE_HTML_ATTRIBUTE(onloadeddata) \
__ENUMERATE_HTML_ATTRIBUTE(onloadedmetadata) \
__ENUMERATE_HTML_ATTRIBUTE(onloadstart) \
__ENUMERATE_HTML_ATTRIBUTE(onmessage) \
__ENUMERATE_HTML_ATTRIBUTE(onmessageerror) \
__ENUMERATE_HTML_ATTRIBUTE(onmousedown) \
__ENUMERATE_HTML_ATTRIBUTE(onmouseenter) \
__ENUMERATE_HTML_ATTRIBUTE(onmouseleave) \
@ -138,11 +145,17 @@ namespace AttributeNames {
__ENUMERATE_HTML_ATTRIBUTE(onmouseout) \
__ENUMERATE_HTML_ATTRIBUTE(onmouseover) \
__ENUMERATE_HTML_ATTRIBUTE(onmouseup) \
__ENUMERATE_HTML_ATTRIBUTE(onoffline) \
__ENUMERATE_HTML_ATTRIBUTE(ononline) \
__ENUMERATE_HTML_ATTRIBUTE(onpagehide) \
__ENUMERATE_HTML_ATTRIBUTE(onpageshow) \
__ENUMERATE_HTML_ATTRIBUTE(onpause) \
__ENUMERATE_HTML_ATTRIBUTE(onplay) \
__ENUMERATE_HTML_ATTRIBUTE(onplaying) \
__ENUMERATE_HTML_ATTRIBUTE(onpopstate) \
__ENUMERATE_HTML_ATTRIBUTE(onprogress) \
__ENUMERATE_HTML_ATTRIBUTE(onratechange) \
__ENUMERATE_HTML_ATTRIBUTE(onrejectionhandled) \
__ENUMERATE_HTML_ATTRIBUTE(onreset) \
__ENUMERATE_HTML_ATTRIBUTE(onresize) \
__ENUMERATE_HTML_ATTRIBUTE(onscroll) \
@ -152,10 +165,13 @@ namespace AttributeNames {
__ENUMERATE_HTML_ATTRIBUTE(onselect) \
__ENUMERATE_HTML_ATTRIBUTE(onslotchange) \
__ENUMERATE_HTML_ATTRIBUTE(onstalled) \
__ENUMERATE_HTML_ATTRIBUTE(onstorage) \
__ENUMERATE_HTML_ATTRIBUTE(onsubmit) \
__ENUMERATE_HTML_ATTRIBUTE(onsuspend) \
__ENUMERATE_HTML_ATTRIBUTE(ontimeupdate) \
__ENUMERATE_HTML_ATTRIBUTE(ontoggle) \
__ENUMERATE_HTML_ATTRIBUTE(onunhandledrejection) \
__ENUMERATE_HTML_ATTRIBUTE(onunload) \
__ENUMERATE_HTML_ATTRIBUTE(onvolumechange) \
__ENUMERATE_HTML_ATTRIBUTE(onwaiting) \
__ENUMERATE_HTML_ATTRIBUTE(onwebkitanimationend) \

View file

@ -4,11 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Interpreter.h>
#include <LibJS/Parser.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/IDLEventListener.h>
#include <LibWeb/HTML/EventHandler.h>
#include <LibWeb/DOM/EventTarget.h>
#include <LibWeb/HTML/EventNames.h>
#include <LibWeb/HTML/GlobalEventHandlers.h>
#include <LibWeb/UIEvents/EventNames.h>

View file

@ -55,6 +55,14 @@ void HTMLBodyElement::parse_attribute(FlyString const& name, String const& value
} else if (name.equals_ignoring_case("background")) {
m_background_style_value = CSS::ImageStyleValue::create(document().parse_url(value));
}
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
if (name == HTML::AttributeNames::attribute_name) { \
element_event_handler_attribute_changed(event_name, value); \
}
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
}
DOM::EventTarget& HTMLBodyElement::global_event_handlers_to_event_target(FlyString const& event_name)
@ -67,4 +75,11 @@ DOM::EventTarget& HTMLBodyElement::global_event_handlers_to_event_target(FlyStri
return *this;
}
DOM::EventTarget& HTMLBodyElement::window_event_handlers_to_event_target()
{
// All WindowEventHandlers on HTMLFrameSetElement (e.g. document.body.onrejectionhandled) are mapped to window.on{event}.
// NOTE: document.body can return either a HTMLBodyElement or HTMLFrameSetElement, so both these elements must support this mapping.
return document().window();
}
}

View file

@ -7,10 +7,13 @@
#pragma once
#include <LibWeb/HTML/HTMLElement.h>
#include <LibWeb/HTML/WindowEventHandlers.h>
namespace Web::HTML {
class HTMLBodyElement final : public HTMLElement {
class HTMLBodyElement final
: public HTMLElement
, public WindowEventHandlers {
public:
using WrapperType = Bindings::HTMLBodyElementWrapper;
@ -24,6 +27,9 @@ private:
// ^HTML::GlobalEventHandlers
virtual EventTarget& global_event_handlers_to_event_target(FlyString const& event_name) override;
// ^HTML::WindowEventHandlers
virtual EventTarget& window_event_handlers_to_event_target() override;
RefPtr<CSS::ImageStyleValue> m_background_style_value;
};

View file

@ -1,3 +1,4 @@
#import <DOM/EventHandler.idl>
#import <HTML/HTMLElement.idl>
interface HTMLBodyElement : HTMLElement {
@ -10,3 +11,5 @@ interface HTMLBodyElement : HTMLElement {
[Reflect] attribute DOMString background;
};
HTMLBodyElement includes WindowEventHandlers;

View file

@ -4,7 +4,9 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/HTMLFrameSetElement.h>
#include <LibWeb/HTML/Window.h>
namespace Web::HTML {
@ -15,6 +17,19 @@ HTMLFrameSetElement::HTMLFrameSetElement(DOM::Document& document, DOM::Qualified
HTMLFrameSetElement::~HTMLFrameSetElement() = default;
void HTMLFrameSetElement::parse_attribute(FlyString const& name, String const& value)
{
HTMLElement::parse_attribute(name, value);
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
if (name == HTML::AttributeNames::attribute_name) { \
element_event_handler_attribute_changed(event_name, value); \
}
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
}
DOM::EventTarget& HTMLFrameSetElement::global_event_handlers_to_event_target(FlyString const& event_name)
{
// NOTE: This is a little weird, but IIUC document.body.onload actually refers to window.onload
@ -25,4 +40,11 @@ DOM::EventTarget& HTMLFrameSetElement::global_event_handlers_to_event_target(Fly
return *this;
}
DOM::EventTarget& HTMLFrameSetElement::window_event_handlers_to_event_target()
{
// All WindowEventHandlers on HTMLFrameSetElement (e.g. document.body.onrejectionhandled) are mapped to window.on{event}.
// NOTE: document.body can return either a HTMLBodyElement or HTMLFrameSetElement, so both these elements must support this mapping.
return document().window();
}
}

View file

@ -7,20 +7,28 @@
#pragma once
#include <LibWeb/HTML/HTMLElement.h>
#include <LibWeb/HTML/WindowEventHandlers.h>
namespace Web::HTML {
// NOTE: This element is marked as obsolete, but is still listed as required by the specification.
class HTMLFrameSetElement final : public HTMLElement {
class HTMLFrameSetElement final
: public HTMLElement
, public WindowEventHandlers {
public:
using WrapperType = Bindings::HTMLFrameSetElementWrapper;
HTMLFrameSetElement(DOM::Document&, DOM::QualifiedName);
virtual ~HTMLFrameSetElement() override;
virtual void parse_attribute(FlyString const&, String const&) override;
private:
// ^HTML::GlobalEventHandlers
virtual EventTarget& global_event_handlers_to_event_target(FlyString const& event_name) override;
// ^HTML::WindowEventHandlers
virtual EventTarget& window_event_handlers_to_event_target() override;
};
}

View file

@ -1,3 +1,4 @@
#import <DOM/EventHandler.idl>
#import <HTML/HTMLElement.idl>
interface HTMLFrameSetElement : HTMLElement {
@ -6,3 +7,5 @@ interface HTMLFrameSetElement : HTMLElement {
[Reflect] attribute DOMString rows;
};
HTMLFrameSetElement includes WindowEventHandlers;

View file

@ -21,6 +21,7 @@
#include <LibWeb/HTML/AnimationFrameCallbackDriver.h>
#include <LibWeb/HTML/BrowsingContext.h>
#include <LibWeb/HTML/GlobalEventHandlers.h>
#include <LibWeb/HTML/WindowEventHandlers.h>
namespace Web::HTML {
@ -30,7 +31,8 @@ class Window final
: public RefCounted<Window>
, public Weakable<Window>
, public DOM::EventTarget
, public HTML::GlobalEventHandlers {
, public HTML::GlobalEventHandlers
, public HTML::WindowEventHandlers {
public:
static NonnullRefPtr<Window> create_with_document(DOM::Document&);
~Window();
@ -130,6 +132,9 @@ private:
// ^HTML::GlobalEventHandlers
virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const&) override { return *this; }
// ^HTML::WindowEventHandlers
virtual DOM::EventTarget& window_event_handlers_to_event_target() override { return *this; }
enum class Repeat {
Yes,
No,

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/DOM/EventTarget.h>
#include <LibWeb/HTML/EventNames.h>
#include <LibWeb/HTML/WindowEventHandlers.h>
namespace Web::HTML {
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
void WindowEventHandlers::set_##attribute_name(Optional<Bindings::CallbackType> value) \
{ \
window_event_handlers_to_event_target().set_event_handler_attribute(event_name, move(value)); \
} \
Bindings::CallbackType* WindowEventHandlers::attribute_name() \
{ \
return window_event_handlers_to_event_target().event_handler_attribute(event_name); \
}
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
WindowEventHandlers::~WindowEventHandlers() = default;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Forward.h>
#include <LibWeb/Forward.h>
#define ENUMERATE_WINDOW_EVENT_HANDLERS(E) \
E(onafterprint, HTML::EventNames::afterprint) \
E(onbeforeprint, HTML::EventNames::beforeprint) \
E(onbeforeunload, HTML::EventNames::beforeunload) \
E(onhashchange, HTML::EventNames::hashchange) \
E(onlanguagechange, HTML::EventNames::languagechange) \
E(onmessage, HTML::EventNames::message) \
E(onmessageerror, HTML::EventNames::messageerror) \
E(onoffline, HTML::EventNames::offline) \
E(ononline, HTML::EventNames::online) \
E(onpagehide, HTML::EventNames::pagehide) \
E(onpageshow, HTML::EventNames::pageshow) \
E(onpopstate, HTML::EventNames::popstate) \
E(onrejectionhandled, HTML::EventNames::rejectionhandled) \
E(onstorage, HTML::EventNames::storage) \
E(onunhandledrejection, HTML::EventNames::unhandledrejection) \
E(onunload, HTML::EventNames::unload)
namespace Web::HTML {
class WindowEventHandlers {
public:
virtual ~WindowEventHandlers();
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
void set_##attribute_name(Optional<Bindings::CallbackType>); \
Bindings::CallbackType* attribute_name();
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
protected:
virtual DOM::EventTarget& window_event_handlers_to_event_target() = 0;
};
}