mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:07:36 +00:00
LibWeb: Emit "selectionchange" event on document
This commit is contained in:
parent
9ce8189f21
commit
cd7b5b18e4
7 changed files with 71 additions and 0 deletions
6
Tests/LibWeb/Text/expected/selectionchange-event.txt
Normal file
6
Tests/LibWeb/Text/expected/selectionchange-event.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
Ladybird is an ongoing project to build an independent web browser from scratch.
|
||||||
|
Events:
|
||||||
|
selectionchange anchorNode=<#text > anchorOffset=1 type=Caret focusNode=<#text > focusOffset=1 isCollapsed=true
|
||||||
|
selectionchange anchorNode=<#text > anchorOffset=1 type=Caret focusNode=<#text > focusOffset=1 isCollapsed=true
|
||||||
|
selectionchange anchorNode=<#text > anchorOffset=2 type=Caret focusNode=<#text > focusOffset=2 isCollapsed=true
|
46
Tests/LibWeb/Text/input/selectionchange-event.html
Normal file
46
Tests/LibWeb/Text/input/selectionchange-event.html
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<script src="include.js"></script>
|
||||||
|
<style>
|
||||||
|
#editable {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
font-size: 30px;
|
||||||
|
width: 400px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="editable" contenteditable="true">
|
||||||
|
Ladybird is an ongoing project to build an independent web browser from scratch.
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
asyncTest(async done => {
|
||||||
|
function elementToString(e) {
|
||||||
|
let element_string = `<${e.nodeName} `;
|
||||||
|
if (e.id) element_string += `id="${e.id}" `;
|
||||||
|
element_string += ">";
|
||||||
|
return element_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("selectionchange", function (e) {
|
||||||
|
const selection = window.getSelection();
|
||||||
|
println(
|
||||||
|
`selectionchange anchorNode=${elementToString(selection.anchorNode)} anchorOffset=${
|
||||||
|
selection.anchorOffset
|
||||||
|
} type=${selection.type} focusNode=${elementToString(
|
||||||
|
selection.focusNode
|
||||||
|
)} focusOffset=${selection.focusOffset} isCollapsed=${selection.isCollapsed}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const editable = document.getElementById("editable");
|
||||||
|
|
||||||
|
println("Events:");
|
||||||
|
|
||||||
|
internals.click(20, 10);
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 0));
|
||||||
|
internals.click(30, 10);
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 0));
|
||||||
|
internals.click(40, 10);
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 0));
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -70,6 +70,7 @@ interface mixin GlobalEventHandlers {
|
||||||
attribute EventHandler onseeked;
|
attribute EventHandler onseeked;
|
||||||
attribute EventHandler onseeking;
|
attribute EventHandler onseeking;
|
||||||
attribute EventHandler onselect;
|
attribute EventHandler onselect;
|
||||||
|
attribute EventHandler onselectionchange;
|
||||||
attribute EventHandler onslotchange;
|
attribute EventHandler onslotchange;
|
||||||
attribute EventHandler onstalled;
|
attribute EventHandler onstalled;
|
||||||
attribute EventHandler onsubmit;
|
attribute EventHandler onsubmit;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <LibWeb/DOM/DocumentFragment.h>
|
#include <LibWeb/DOM/DocumentFragment.h>
|
||||||
#include <LibWeb/DOM/DocumentType.h>
|
#include <LibWeb/DOM/DocumentType.h>
|
||||||
#include <LibWeb/DOM/ElementFactory.h>
|
#include <LibWeb/DOM/ElementFactory.h>
|
||||||
|
#include <LibWeb/DOM/Event.h>
|
||||||
#include <LibWeb/DOM/Node.h>
|
#include <LibWeb/DOM/Node.h>
|
||||||
#include <LibWeb/DOM/ProcessingInstruction.h>
|
#include <LibWeb/DOM/ProcessingInstruction.h>
|
||||||
#include <LibWeb/DOM/Range.h>
|
#include <LibWeb/DOM/Range.h>
|
||||||
|
@ -100,6 +101,20 @@ void Range::update_associated_selection()
|
||||||
layout_root->recompute_selection_states();
|
layout_root->recompute_selection_states();
|
||||||
layout_root->paintable()->set_needs_display();
|
layout_root->paintable()->set_needs_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/selection-api/#selectionchange-event
|
||||||
|
// When the selection is dissociated with its range, associated with a new range or the associated range's boundary
|
||||||
|
// point is mutated either by the user or the content script, the user agent must queue a task on the user interaction
|
||||||
|
// task source to fire an event named selectionchange, which does not bubble and is not cancelable, at the document
|
||||||
|
// associated with the selection.
|
||||||
|
auto document = m_associated_selection->document();
|
||||||
|
queue_global_task(HTML::Task::Source::UserInteraction, relevant_global_object(*document), [document] {
|
||||||
|
EventInit event_init;
|
||||||
|
event_init.bubbles = false;
|
||||||
|
event_init.cancelable = false;
|
||||||
|
auto event = DOM::Event::create(document->realm(), HTML::EventNames::selectionchange, event_init);
|
||||||
|
document->dispatch_event(event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#concept-range-root
|
// https://dom.spec.whatwg.org/#concept-range-root
|
||||||
|
|
|
@ -180,6 +180,7 @@ namespace AttributeNames {
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onseeked) \
|
__ENUMERATE_HTML_ATTRIBUTE(onseeked) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onseeking) \
|
__ENUMERATE_HTML_ATTRIBUTE(onseeking) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onselect) \
|
__ENUMERATE_HTML_ATTRIBUTE(onselect) \
|
||||||
|
__ENUMERATE_HTML_ATTRIBUTE(onselectionchange) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onslotchange) \
|
__ENUMERATE_HTML_ATTRIBUTE(onslotchange) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onstalled) \
|
__ENUMERATE_HTML_ATTRIBUTE(onstalled) \
|
||||||
__ENUMERATE_HTML_ATTRIBUTE(onstorage) \
|
__ENUMERATE_HTML_ATTRIBUTE(onstorage) \
|
||||||
|
|
|
@ -88,6 +88,7 @@ namespace Web::HTML::EventNames {
|
||||||
__ENUMERATE_HTML_EVENT(scroll) \
|
__ENUMERATE_HTML_EVENT(scroll) \
|
||||||
__ENUMERATE_HTML_EVENT(scrollend) \
|
__ENUMERATE_HTML_EVENT(scrollend) \
|
||||||
__ENUMERATE_HTML_EVENT(securitypolicyviolation) \
|
__ENUMERATE_HTML_EVENT(securitypolicyviolation) \
|
||||||
|
__ENUMERATE_HTML_EVENT(selectionchange) \
|
||||||
__ENUMERATE_HTML_EVENT(seeked) \
|
__ENUMERATE_HTML_EVENT(seeked) \
|
||||||
__ENUMERATE_HTML_EVENT(seeking) \
|
__ENUMERATE_HTML_EVENT(seeking) \
|
||||||
__ENUMERATE_HTML_EVENT(select) \
|
__ENUMERATE_HTML_EVENT(select) \
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
E(onseeked, HTML::EventNames::seeked) \
|
E(onseeked, HTML::EventNames::seeked) \
|
||||||
E(onseeking, HTML::EventNames::seeking) \
|
E(onseeking, HTML::EventNames::seeking) \
|
||||||
E(onselect, HTML::EventNames::select) \
|
E(onselect, HTML::EventNames::select) \
|
||||||
|
E(onselectionchange, HTML::EventNames::selectionchange) \
|
||||||
E(onslotchange, HTML::EventNames::slotchange) \
|
E(onslotchange, HTML::EventNames::slotchange) \
|
||||||
E(onstalled, HTML::EventNames::stalled) \
|
E(onstalled, HTML::EventNames::stalled) \
|
||||||
E(onsubmit, HTML::EventNames::submit) \
|
E(onsubmit, HTML::EventNames::submit) \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue