mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-01 13:49:16 +00:00
LibWeb: Don't compare the focus chain's GC::Root contents by reference
The focus chain always consists of newly created GC::Root objects, so the condition always produced `false`. The fix is to use GC::Root's overloaded operator== method, which compares the pointers of the stored type. This fixes Figma dropdowns and context menus instantly disappearing upon opening them. This is because they become focused when they insert them. Because of this bug, it would fire blur events all the way up to and including the window. Figma listens for the blur event on the window, and when received, it will instantly hide dropdowns and context menus. The intention behind this seems to be hiding them when the user clicks off the browser window, or switches tab.
This commit is contained in:
parent
fac88b698f
commit
bf34b63439
Notes:
github-actions[bot]
2025-01-30 18:31:37 +00:00
Author: https://github.com/Lubrsi
Commit: bf34b63439
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3408
4 changed files with 89 additions and 4 deletions
|
@ -44,7 +44,7 @@ static void run_focus_update_steps(Vector<GC::Root<DOM::Node>> old_chain, Vector
|
|||
// pop the last entry from old chain and the last entry from new chain and redo this step.
|
||||
while (!old_chain.is_empty()
|
||||
&& !new_chain.is_empty()
|
||||
&& &old_chain.last() == &new_chain.last()) {
|
||||
&& old_chain.last() == new_chain.last()) {
|
||||
(void)old_chain.take_last();
|
||||
(void)new_chain.take_last();
|
||||
}
|
||||
|
|
30
Tests/LibWeb/Text/expected/focus-chain.txt
Normal file
30
Tests/LibWeb/Text/expected/focus-chain.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
== div3 focus
|
||||
DIV#3 received focus event, target: DIV#3, currentTarget: DIV#3
|
||||
DIV#3 received focusin event, target: DIV#3, currentTarget: DIV#3
|
||||
DIV#2 received focusin event, target: DIV#3, currentTarget: DIV#2
|
||||
DIV#1 received focusin event, target: DIV#3, currentTarget: DIV#1
|
||||
window received focusin event, target: DIV#3, currentTarget: window
|
||||
== div5 focus
|
||||
DIV#3 received blur event, target: DIV#3, currentTarget: DIV#3
|
||||
DIV#3 received focusout event, target: DIV#3, currentTarget: DIV#3
|
||||
DIV#2 received focusout event, target: DIV#3, currentTarget: DIV#2
|
||||
DIV#1 received focusout event, target: DIV#3, currentTarget: DIV#1
|
||||
window received focusout event, target: DIV#3, currentTarget: window
|
||||
DIV#5 received focus event, target: DIV#5, currentTarget: DIV#5
|
||||
DIV#5 received focusin event, target: DIV#5, currentTarget: DIV#5
|
||||
DIV#4 received focusin event, target: DIV#5, currentTarget: DIV#4
|
||||
DIV#1 received focusin event, target: DIV#5, currentTarget: DIV#1
|
||||
window received focusin event, target: DIV#5, currentTarget: window
|
||||
== div1 focus
|
||||
DIV#5 received blur event, target: DIV#5, currentTarget: DIV#5
|
||||
DIV#5 received focusout event, target: DIV#5, currentTarget: DIV#5
|
||||
DIV#4 received focusout event, target: DIV#5, currentTarget: DIV#4
|
||||
DIV#1 received focusout event, target: DIV#5, currentTarget: DIV#1
|
||||
window received focusout event, target: DIV#5, currentTarget: window
|
||||
DIV#1 received focus event, target: DIV#1, currentTarget: DIV#1
|
||||
DIV#1 received focusin event, target: DIV#1, currentTarget: DIV#1
|
||||
window received focusin event, target: DIV#1, currentTarget: window
|
||||
== window focus
|
||||
DIV#1 received blur event, target: DIV#1, currentTarget: DIV#1
|
||||
DIV#1 received focusout event, target: DIV#1, currentTarget: DIV#1
|
||||
window received focusout event, target: DIV#1, currentTarget: window
|
|
@ -2,6 +2,6 @@ Harness status: OK
|
|||
|
||||
Found 2 tests
|
||||
|
||||
2 Fail
|
||||
Fail relatedTarget should not leak at capturing phase, at window object.
|
||||
Fail relatedTarget should not leak at target.
|
||||
2 Pass
|
||||
Pass relatedTarget should not leak at capturing phase, at window object.
|
||||
Pass relatedTarget should not leak at target.
|
55
Tests/LibWeb/Text/input/focus-chain.html
Normal file
55
Tests/LibWeb/Text/input/focus-chain.html
Normal file
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<div id="1">
|
||||
<div id="2">
|
||||
<div id="3"></div>
|
||||
</div>
|
||||
<div id="4">
|
||||
<div id="5"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
function targetToString(target) {
|
||||
if (target[Symbol.toStringTag] === "Window")
|
||||
return "window";
|
||||
|
||||
return `${target.tagName}#${target.id}`;
|
||||
}
|
||||
|
||||
const div1 = document.getElementById("1");
|
||||
const div2 = document.getElementById("2");
|
||||
const div3 = document.getElementById("3");
|
||||
const div4 = document.getElementById("4");
|
||||
const div5 = document.getElementById("5");
|
||||
|
||||
[window, div1, div2, div3, div4, div5].forEach(focusTarget => {
|
||||
const focusTargetString = targetToString(focusTarget);
|
||||
|
||||
focusTarget.onblur = (event) => {
|
||||
println(`${focusTargetString} received blur event, target: ${targetToString(event.target)}, currentTarget: ${targetToString(event.currentTarget)}`);
|
||||
};
|
||||
|
||||
focusTarget.onfocus = (event) => {
|
||||
println(`${focusTargetString} received focus event, target: ${targetToString(event.target)}, currentTarget: ${targetToString(event.currentTarget)}`);
|
||||
};
|
||||
|
||||
focusTarget.onfocusin = (event) => {
|
||||
println(`${focusTargetString} received focusin event, target: ${targetToString(event.target)}, currentTarget: ${targetToString(event.currentTarget)}`);
|
||||
};
|
||||
|
||||
focusTarget.onfocusout = (event) => {
|
||||
println(`${focusTargetString} received focusout event, target: ${targetToString(event.target)}, currentTarget: ${targetToString(event.currentTarget)}`);
|
||||
};
|
||||
});
|
||||
|
||||
println("== div3 focus");
|
||||
div3.focus();
|
||||
println("== div5 focus");
|
||||
div5.focus();
|
||||
println("== div1 focus");
|
||||
div1.focus();
|
||||
println("== window focus");
|
||||
window.focus();
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue