1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 07:27:45 +00:00

LibWeb: Basic implementation of global event handlers :^)

Document and HTMLElement now inherit from HTML::GlobalEventHandlers
which allows them to support "onfoo" event handler attributes.

These are assignable both via IDL attributes and content attributes.

Event listeners constructed this way get a special "attribute" flag
on them so we know which one to replace if you reassign them.
This also allows them to coexist with EventTarget.addEventListener().

This is all a bit sloppy, but it works decently for a first cut.
The Window object should also inherit GlobalEventHandlers, but since
we don't generate it from IDL, I haven't taken that step here.

Also this would be a lot nicer if we supported IDL mixins.
This commit is contained in:
Andreas Kling 2021-02-03 22:47:50 +01:00
parent b43db4cc50
commit a59b1825ce
15 changed files with 391 additions and 2 deletions

View file

@ -55,6 +55,7 @@ enum class QuirksMode {
class Document
: public ParentNode
, public NonElementParentNode<Document>
, public HTML::GlobalEventHandlers
, public Bindings::ScriptExecutionContext {
public:
using WrapperType = Bindings::DocumentWrapper;
@ -233,8 +234,12 @@ public:
private:
explicit Document(const URL&);
// ^DOM::Node
virtual RefPtr<Layout::Node> create_layout_node() override;
// ^HTML::GlobalEventHandlers
virtual EventTarget& global_event_handlers_to_event_target() final { return *this; }
void tear_down_layout_tree();
void increment_referencing_node_count()

View file

@ -36,4 +36,75 @@ interface Document : Node {
attribute DOMString title;
// FIXME: These should all come from a GlobalEventHandlers mixin
attribute EventHandler onabort;
attribute EventHandler onauxclick;
attribute EventHandler onblur;
attribute EventHandler oncancel;
attribute EventHandler oncanplay;
attribute EventHandler oncanplaythrough;
attribute EventHandler onchange;
attribute EventHandler onclick;
attribute EventHandler onclose;
attribute EventHandler oncontextmenu;
attribute EventHandler oncuechange;
attribute EventHandler ondblclick;
attribute EventHandler ondrag;
attribute EventHandler ondragend;
attribute EventHandler ondragenter;
attribute EventHandler ondragleave;
attribute EventHandler ondragover;
attribute EventHandler ondragstart;
attribute EventHandler ondrop;
attribute EventHandler ondurationchange;
attribute EventHandler onemptied;
attribute EventHandler onended;
// FIXME: Should be an OnErrorEventHandler
attribute EventHandler onerror;
attribute EventHandler onfocus;
attribute EventHandler onformdata;
attribute EventHandler oninput;
attribute EventHandler oninvalid;
attribute EventHandler onkeydown;
attribute EventHandler onkeypress;
attribute EventHandler onkeyup;
attribute EventHandler onload;
attribute EventHandler onloadeddata;
attribute EventHandler onloadedmetadata;
attribute EventHandler onloadstart;
attribute EventHandler onmousedown;
[LegacyLenientThis] attribute EventHandler onmouseenter;
[LegacyLenientThis] attribute EventHandler onmouseleave;
attribute EventHandler onmousemove;
attribute EventHandler onmouseout;
attribute EventHandler onmouseover;
attribute EventHandler onmouseup;
attribute EventHandler onpause;
attribute EventHandler onplay;
attribute EventHandler onplaying;
attribute EventHandler onprogress;
attribute EventHandler onratechange;
attribute EventHandler onreset;
attribute EventHandler onresize;
attribute EventHandler onscroll;
attribute EventHandler onsecuritypolicyviolation;
attribute EventHandler onseeked;
attribute EventHandler onseeking;
attribute EventHandler onselect;
attribute EventHandler onslotchange;
attribute EventHandler onstalled;
attribute EventHandler onsubmit;
attribute EventHandler onsuspend;
attribute EventHandler ontimeupdate;
attribute EventHandler ontoggle;
attribute EventHandler onvolumechange;
attribute EventHandler onwaiting;
attribute EventHandler onwebkitanimationend;
attribute EventHandler onwebkitanimationiteration;
attribute EventHandler onwebkitanimationstart;
attribute EventHandler onwebkittransitionend;
attribute EventHandler onwheel;
};

View file

@ -38,8 +38,9 @@ class EventListener
public:
using WrapperType = Bindings::EventListenerWrapper;
explicit EventListener(JS::Handle<JS::Function> function)
explicit EventListener(JS::Handle<JS::Function> function, bool is_attribute = false)
: m_function(move(function))
, m_attribute(is_attribute)
{
}
@ -60,6 +61,8 @@ public:
bool removed() const { return m_removed; }
void set_removed(bool removed) { m_removed = removed; }
bool is_attribute() const { return m_attribute; }
private:
FlyString m_type;
JS::Handle<JS::Function> m_function;
@ -67,6 +70,7 @@ private:
bool m_passive { false };
bool m_once { false };
bool m_removed { false };
bool m_attribute { false };
};
}

View file

@ -61,6 +61,7 @@ public:
NonnullRefPtr<EventListener> listener;
};
Vector<EventListenerRegistration>& listeners() { return m_listeners; }
const Vector<EventListenerRegistration>& listeners() const { return m_listeners; }
Function<void(const Event&)> activation_behaviour;