1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:57:35 +00:00

LibWeb: Only make certain <body> and <frameset> events apply to Window

Previously we forwarded all event handler attributes to Window from
these two elements, however, we are only supposed to forward blur,
error, focus, load, resize and scroll.
This commit is contained in:
Luke Wilde 2022-06-27 19:20:09 +01:00 committed by Linus Groh
parent a50a48f6b4
commit ebf2184636
11 changed files with 37 additions and 16 deletions

View file

@ -353,7 +353,7 @@ private:
explicit Document(const AK::URL&); explicit Document(const AK::URL&);
// ^HTML::GlobalEventHandlers // ^HTML::GlobalEventHandlers
virtual EventTarget& global_event_handlers_to_event_target() final { return *this; } virtual EventTarget& global_event_handlers_to_event_target(FlyString const&) final { return *this; }
void tear_down_layout_tree(); void tear_down_layout_tree();

View file

@ -218,7 +218,7 @@ ExceptionOr<bool> EventTarget::dispatch_event_binding(NonnullRefPtr<Event> event
} }
// https://html.spec.whatwg.org/multipage/webappapis.html#window-reflecting-body-element-event-handler-set // https://html.spec.whatwg.org/multipage/webappapis.html#window-reflecting-body-element-event-handler-set
static bool is_window_reflecting_body_element_event_handler(FlyString const& name) bool is_window_reflecting_body_element_event_handler(FlyString const& name)
{ {
return name.is_one_of( return name.is_one_of(
HTML::EventNames::blur, HTML::EventNames::blur,

View file

@ -86,4 +86,6 @@ private:
JS::ThrowCompletionOr<void> process_event_handler_for_event(FlyString const& name, Event& event); JS::ThrowCompletionOr<void> process_event_handler_for_event(FlyString const& name, Event& event);
}; };
bool is_window_reflecting_body_element_event_handler(FlyString const& name);
} }

View file

@ -16,14 +16,14 @@
namespace Web::HTML { namespace Web::HTML {
#undef __ENUMERATE #undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \ #define __ENUMERATE(attribute_name, event_name) \
void GlobalEventHandlers::set_##attribute_name(Optional<Bindings::CallbackType> value) \ void GlobalEventHandlers::set_##attribute_name(Optional<Bindings::CallbackType> value) \
{ \ { \
global_event_handlers_to_event_target().set_event_handler_attribute(event_name, move(value)); \ global_event_handlers_to_event_target(event_name).set_event_handler_attribute(event_name, move(value)); \
} \ } \
Bindings::CallbackType* GlobalEventHandlers::attribute_name() \ Bindings::CallbackType* GlobalEventHandlers::attribute_name() \
{ \ { \
return global_event_handlers_to_event_target().event_handler_attribute(event_name); \ return global_event_handlers_to_event_target(event_name).event_handler_attribute(event_name); \
} }
ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE) ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE #undef __ENUMERATE

View file

@ -91,7 +91,7 @@ public:
#undef __ENUMERATE #undef __ENUMERATE
protected: protected:
virtual DOM::EventTarget& global_event_handlers_to_event_target() = 0; virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const& event_name) = 0;
}; };
} }

View file

@ -57,10 +57,14 @@ void HTMLBodyElement::parse_attribute(FlyString const& name, String const& value
} }
} }
DOM::EventTarget& HTMLBodyElement::global_event_handlers_to_event_target() DOM::EventTarget& HTMLBodyElement::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 // NOTE: This is a little weird, but IIUC document.body.onload actually refers to window.onload
return document().window(); // NOTE: document.body can return either a HTMLBodyElement or HTMLFrameSetElement, so both these elements must support this mapping.
if (DOM::is_window_reflecting_body_element_event_handler(event_name))
return document().window();
return *this;
} }
} }

View file

@ -22,7 +22,7 @@ public:
private: private:
// ^HTML::GlobalEventHandlers // ^HTML::GlobalEventHandlers
virtual EventTarget& global_event_handlers_to_event_target() override; virtual EventTarget& global_event_handlers_to_event_target(FlyString const& event_name) override;
RefPtr<CSS::ImageStyleValue> m_background_style_value; RefPtr<CSS::ImageStyleValue> m_background_style_value;
}; };

View file

@ -54,7 +54,7 @@ protected:
private: private:
// ^HTML::GlobalEventHandlers // ^HTML::GlobalEventHandlers
virtual DOM::EventTarget& global_event_handlers_to_event_target() override { return *this; } virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const&) override { return *this; }
enum class ContentEditableState { enum class ContentEditableState {
True, True,

View file

@ -14,4 +14,15 @@ HTMLFrameSetElement::HTMLFrameSetElement(DOM::Document& document, DOM::Qualified
} }
HTMLFrameSetElement::~HTMLFrameSetElement() = default; HTMLFrameSetElement::~HTMLFrameSetElement() = default;
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
// NOTE: document.body can return either a HTMLBodyElement or HTMLFrameSetElement, so both these elements must support this mapping.
if (DOM::is_window_reflecting_body_element_event_handler(event_name))
return document().window();
return *this;
}
} }

View file

@ -17,6 +17,10 @@ public:
HTMLFrameSetElement(DOM::Document&, DOM::QualifiedName); HTMLFrameSetElement(DOM::Document&, DOM::QualifiedName);
virtual ~HTMLFrameSetElement() override; virtual ~HTMLFrameSetElement() override;
private:
// ^HTML::GlobalEventHandlers
virtual EventTarget& global_event_handlers_to_event_target(FlyString const& event_name) override;
}; };
} }

View file

@ -128,7 +128,7 @@ private:
explicit Window(DOM::Document&); explicit Window(DOM::Document&);
// ^HTML::GlobalEventHandlers // ^HTML::GlobalEventHandlers
virtual DOM::EventTarget& global_event_handlers_to_event_target() override { return *this; } virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const&) override { return *this; }
enum class Repeat { enum class Repeat {
Yes, Yes,