mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:27:35 +00:00
LibWeb: Emit "focusin" and "focusout" events
This commit is contained in:
parent
cd7b5b18e4
commit
934aa6af6a
7 changed files with 78 additions and 0 deletions
6
Tests/LibWeb/Text/expected/focus-events.txt
Normal file
6
Tests/LibWeb/Text/expected/focus-events.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
focus target=<INPUT id="a">
|
||||||
|
focusin target=<INPUT id="a">
|
||||||
|
blur target=<INPUT id="a">
|
||||||
|
focusout target=<INPUT id="a">
|
||||||
|
focus target=<INPUT id="b">
|
||||||
|
focusin target=<INPUT id="b">
|
54
Tests/LibWeb/Text/input/focus-events.html
Normal file
54
Tests/LibWeb/Text/input/focus-events.html
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<script src="include.js"></script>
|
||||||
|
<style>
|
||||||
|
.input {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<input class="input" id="a" />
|
||||||
|
<input class="input" id="b" />
|
||||||
|
<script>
|
||||||
|
function elementToString(e) {
|
||||||
|
let element_string = `<${e.nodeName} `;
|
||||||
|
if (e.id) element_string += `id="${e.id}"`;
|
||||||
|
element_string += ">";
|
||||||
|
return element_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("focusin", function (e) {
|
||||||
|
const target = elementToString(e.target);
|
||||||
|
println(`focusin target=${target}`);
|
||||||
|
});
|
||||||
|
document.addEventListener("focusout", function (e) {
|
||||||
|
const target = elementToString(e.target);
|
||||||
|
println(`focusout target=${target}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const a = document.getElementById("a");
|
||||||
|
const b = document.getElementById("b");
|
||||||
|
|
||||||
|
function onFocus(e) {
|
||||||
|
const target = elementToString(e.target);
|
||||||
|
println(`focus target=${target}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBlur(e) {
|
||||||
|
const target = elementToString(e.target);
|
||||||
|
println(`blur target=${target}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.addEventListener("focus", onFocus);
|
||||||
|
a.addEventListener("blur", onBlur);
|
||||||
|
b.addEventListener("focus", onFocus);
|
||||||
|
b.addEventListener("blur", onBlur);
|
||||||
|
|
||||||
|
asyncTest(async done => {
|
||||||
|
a.focus();
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 0));
|
||||||
|
b.focus();
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 0));
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -41,6 +41,8 @@ interface mixin GlobalEventHandlers {
|
||||||
attribute EventHandler onended;
|
attribute EventHandler onended;
|
||||||
attribute OnErrorEventHandler onerror;
|
attribute OnErrorEventHandler onerror;
|
||||||
attribute EventHandler onfocus;
|
attribute EventHandler onfocus;
|
||||||
|
attribute EventHandler onfocusin;
|
||||||
|
attribute EventHandler onfocusout;
|
||||||
attribute EventHandler onformdata;
|
attribute EventHandler onformdata;
|
||||||
attribute EventHandler oninput;
|
attribute EventHandler oninput;
|
||||||
attribute EventHandler oninvalid;
|
attribute EventHandler oninvalid;
|
||||||
|
|
|
@ -141,6 +141,8 @@ namespace AttributeNames {
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onended) \
|
__ENUMERATE_HTML_ATTRIBUTE(onended) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onerror) \
|
__ENUMERATE_HTML_ATTRIBUTE(onerror) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onfocus) \
|
__ENUMERATE_HTML_ATTRIBUTE(onfocus) \
|
||||||
|
__ENUMERATE_HTML_ATTRIBUTE(onfocusin) \
|
||||||
|
__ENUMERATE_HTML_ATTRIBUTE(onfocusout) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onformdata) \
|
__ENUMERATE_HTML_ATTRIBUTE(onformdata) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onhashchange) \
|
__ENUMERATE_HTML_ATTRIBUTE(onhashchange) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(oninput) \
|
__ENUMERATE_HTML_ATTRIBUTE(oninput) \
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace Web::HTML::EventNames {
|
||||||
__ENUMERATE_HTML_EVENT(error) \
|
__ENUMERATE_HTML_EVENT(error) \
|
||||||
__ENUMERATE_HTML_EVENT(finish) \
|
__ENUMERATE_HTML_EVENT(finish) \
|
||||||
__ENUMERATE_HTML_EVENT(focus) \
|
__ENUMERATE_HTML_EVENT(focus) \
|
||||||
|
__ENUMERATE_HTML_EVENT(focusin) \
|
||||||
|
__ENUMERATE_HTML_EVENT(focusout) \
|
||||||
__ENUMERATE_HTML_EVENT(formdata) \
|
__ENUMERATE_HTML_EVENT(formdata) \
|
||||||
__ENUMERATE_HTML_EVENT(hashchange) \
|
__ENUMERATE_HTML_EVENT(hashchange) \
|
||||||
__ENUMERATE_HTML_EVENT(input) \
|
__ENUMERATE_HTML_EVENT(input) \
|
||||||
|
|
|
@ -79,6 +79,11 @@ static void run_focus_update_steps(Vector<JS::Handle<DOM::Node>> old_chain, Vect
|
||||||
blur_event->set_related_target(related_blur_target);
|
blur_event->set_related_target(related_blur_target);
|
||||||
blur_event_target->dispatch_event(blur_event);
|
blur_event_target->dispatch_event(blur_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto focusout_event = UIEvents::FocusEvent::create(blur_event_target->realm(), HTML::EventNames::focusout);
|
||||||
|
focusout_event->set_bubbles(true);
|
||||||
|
focusout_event->set_related_target(related_blur_target);
|
||||||
|
blur_event_target->dispatch_event(focusout_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: 3. Apply any relevant platform-specific conventions for focusing new focus target.
|
// FIXME: 3. Apply any relevant platform-specific conventions for focusing new focus target.
|
||||||
|
@ -123,6 +128,11 @@ static void run_focus_update_steps(Vector<JS::Handle<DOM::Node>> old_chain, Vect
|
||||||
auto focus_event = UIEvents::FocusEvent::create(focus_event_target->realm(), HTML::EventNames::focus);
|
auto focus_event = UIEvents::FocusEvent::create(focus_event_target->realm(), HTML::EventNames::focus);
|
||||||
focus_event->set_related_target(related_focus_target);
|
focus_event->set_related_target(related_focus_target);
|
||||||
focus_event_target->dispatch_event(focus_event);
|
focus_event_target->dispatch_event(focus_event);
|
||||||
|
|
||||||
|
auto focusin_event = UIEvents::FocusEvent::create(focus_event_target->realm(), HTML::EventNames::focusin);
|
||||||
|
focusin_event->set_bubbles(true);
|
||||||
|
focusin_event->set_related_target(related_focus_target);
|
||||||
|
focus_event_target->dispatch_event(focusin_event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
E(onended, HTML::EventNames::ended) \
|
E(onended, HTML::EventNames::ended) \
|
||||||
E(onerror, HTML::EventNames::error) \
|
E(onerror, HTML::EventNames::error) \
|
||||||
E(onfocus, HTML::EventNames::focus) \
|
E(onfocus, HTML::EventNames::focus) \
|
||||||
|
E(onfocusin, HTML::EventNames::focusin) \
|
||||||
|
E(onfocusout, HTML::EventNames::focusout) \
|
||||||
E(onformdata, HTML::EventNames::formdata) \
|
E(onformdata, HTML::EventNames::formdata) \
|
||||||
E(oninput, HTML::EventNames::input) \
|
E(oninput, HTML::EventNames::input) \
|
||||||
E(oninvalid, HTML::EventNames::invalid) \
|
E(oninvalid, HTML::EventNames::invalid) \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue