mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-28 13:18:19 +00:00
LibWeb: Do not modify selection if editing host is already selected
If an editing host receives focus, we would always set a new selection range. However, we only need to do that if we're not already part of the active range. This corresponds to behavior shown by Chrome and Firefox.
This commit is contained in:
parent
8537f0fa82
commit
c9d4913bb4
Notes:
github-actions[bot]
2025-08-01 08:10:42 +00:00
Author: https://github.com/gmta
Commit: c9d4913bb4
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5666
3 changed files with 39 additions and 0 deletions
|
@ -18,6 +18,7 @@
|
|||
#include <LibWeb/DOM/IDLEventListener.h>
|
||||
#include <LibWeb/DOM/LiveNodeList.h>
|
||||
#include <LibWeb/DOM/Position.h>
|
||||
#include <LibWeb/DOM/Range.h>
|
||||
#include <LibWeb/DOM/ShadowRoot.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/CloseWatcher.h>
|
||||
|
@ -41,6 +42,7 @@
|
|||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/Namespace.h>
|
||||
#include <LibWeb/Painting/PaintableBox.h>
|
||||
#include <LibWeb/Selection/Selection.h>
|
||||
#include <LibWeb/UIEvents/EventNames.h>
|
||||
#include <LibWeb/UIEvents/PointerEvent.h>
|
||||
#include <LibWeb/WebIDL/DOMException.h>
|
||||
|
@ -2039,6 +2041,12 @@ void HTMLElement::did_receive_focus()
|
|||
auto editing_host = document().editing_host_manager();
|
||||
editing_host->set_active_contenteditable_element(this);
|
||||
|
||||
// Don't update the selection if we're already part of the active range.
|
||||
if (auto range = document().get_selection()->range()) {
|
||||
if (is_inclusive_ancestor_of(range->start_container()) || is_inclusive_ancestor_of(range->end_container()))
|
||||
return;
|
||||
}
|
||||
|
||||
DOM::Text* text = nullptr;
|
||||
for_each_in_inclusive_subtree_of_type<DOM::Text>([&](auto& node) {
|
||||
text = &node;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Range: [object Text] 1 [object Text] 2
|
||||
document.activeElement: [object HTMLDivElement]
|
||||
Selection must be the same as above:
|
||||
Range: [object Text] 1 [object Text] 2
|
||||
document.activeElement: [object HTMLDivElement]
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<div contenteditable>foo</div>
|
||||
<script src="include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const divElm = document.querySelector('div[contenteditable]');
|
||||
|
||||
// Select the middle 'o'
|
||||
let range = document.createRange();
|
||||
range.setStart(divElm.childNodes[0], 1);
|
||||
range.setEnd(divElm.childNodes[0], 2);
|
||||
getSelection().addRange(range);
|
||||
|
||||
println(`Range: ${range.startContainer} ${range.startOffset} ${range.endContainer} ${range.endOffset}`);
|
||||
println(`document.activeElement: ${document.activeElement}`);
|
||||
|
||||
// Refocus on the editing host
|
||||
document.body.focus();
|
||||
divElm.focus();
|
||||
|
||||
println('Selection must be the same as above:');
|
||||
range = getSelection().getRangeAt(0);
|
||||
println(`Range: ${range.startContainer} ${range.startOffset} ${range.endContainer} ${range.endOffset}`);
|
||||
println(`document.activeElement: ${document.activeElement}`);
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue