mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 20:29:18 +00:00
LibWeb: Reset find-in-page index if selection is cleared
Previously, if the user made a find-in-page query, then cleared the selection made by that query, subsequent queries would inadvertently advance to the next match instead of reselecting the first match.
This commit is contained in:
parent
5f10f8c54c
commit
9e556972ae
Notes:
github-actions[bot]
2025-02-09 18:20:56 +00:00
Author: https://github.com/tcl3
Commit: 9e556972ae
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3496
Reviewed-by: https://github.com/nico
Reviewed-by: https://github.com/trflynn89
3 changed files with 37 additions and 22 deletions
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
|
* Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
|
||||||
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||||
* Copyright (c) 2024, Tim Ledbetter <timledbetter@gmail.com>
|
* Copyright (c) 2024-2025, Tim Ledbetter <tim.ledbetter@ladybird.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -593,38 +593,39 @@ Page::FindInPageResult Page::perform_find_in_page_query(FindInPageQuery const& q
|
||||||
|
|
||||||
Vector<GC::Root<DOM::Range>> all_matches;
|
Vector<GC::Root<DOM::Range>> all_matches;
|
||||||
|
|
||||||
auto find_current_match_index = [this, &direction](auto& document, auto& matches) -> size_t {
|
auto active_range = [](auto& document) -> GC::Ptr<DOM::Range> {
|
||||||
|
auto selection = document.get_selection();
|
||||||
|
if (!selection || selection->is_collapsed())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return selection->range();
|
||||||
|
};
|
||||||
|
|
||||||
|
auto find_current_match_index = [this](DOM::Range& range, auto const& matches) -> Optional<size_t> {
|
||||||
// Always return the first match if there is no active query.
|
// Always return the first match if there is no active query.
|
||||||
if (!m_last_find_in_page_query.has_value())
|
if (!m_last_find_in_page_query.has_value())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto selection = document.get_selection();
|
|
||||||
if (!selection)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
auto range = selection->range();
|
|
||||||
if (!range)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < matches.size(); ++i) {
|
for (size_t i = 0; i < matches.size(); ++i) {
|
||||||
auto boundary_comparison_or_error = matches[i]->compare_boundary_points(DOM::Range::HowToCompareBoundaryPoints::START_TO_START, *range);
|
auto boundary_comparison_or_error = matches[i]->compare_boundary_points(DOM::Range::HowToCompareBoundaryPoints::START_TO_START, range);
|
||||||
if (!boundary_comparison_or_error.is_error() && boundary_comparison_or_error.value() >= 0) {
|
if (!boundary_comparison_or_error.is_error() && boundary_comparison_or_error.value() >= 0)
|
||||||
// If the match occurs after the current selection then we don't need to increment the match index later on.
|
|
||||||
if (boundary_comparison_or_error.value() && direction == SearchDirection::Forward)
|
|
||||||
direction = {};
|
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto should_update_match_index = false;
|
||||||
for (auto const& document : documents_in_active_window()) {
|
for (auto const& document : documents_in_active_window()) {
|
||||||
auto matches = document->find_matching_text(query.string, query.case_sensitivity);
|
auto matches = document->find_matching_text(query.string, query.case_sensitivity);
|
||||||
if (document == top_level_traversable()->active_document()) {
|
if (document == top_level_traversable()->active_document()) {
|
||||||
auto new_match_index = find_current_match_index(*document, matches);
|
if (auto range = active_range(*document)) {
|
||||||
m_find_in_page_match_index = new_match_index + all_matches.size();
|
auto new_match_index = find_current_match_index(*range, matches);
|
||||||
|
should_update_match_index = true;
|
||||||
|
m_find_in_page_match_index = new_match_index.value_or(0) + all_matches.size();
|
||||||
|
} else {
|
||||||
|
m_find_in_page_match_index = all_matches.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
all_matches.extend(move(matches));
|
all_matches.extend(move(matches));
|
||||||
|
@ -637,8 +638,8 @@ Page::FindInPageResult Page::perform_find_in_page_query(FindInPageQuery const& q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direction.has_value()) {
|
if (direction.has_value() && should_update_match_index) {
|
||||||
if (direction.value() == SearchDirection::Forward) {
|
if (direction == SearchDirection::Forward) {
|
||||||
if (m_find_in_page_match_index >= all_matches.size() - 1) {
|
if (m_find_in_page_match_index >= all_matches.size() - 1) {
|
||||||
if (query.wrap_around == WrapAround::No)
|
if (query.wrap_around == WrapAround::No)
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
window.find("test") initial result: true
|
||||||
|
window.find("test") after clearing the previous selection: true
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<div>test</div>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
let result = window.find("test");
|
||||||
|
println(`window.find("test") initial result: ${result}`);
|
||||||
|
window.getSelection().removeAllRanges();
|
||||||
|
result = window.find("test");
|
||||||
|
println(`window.find("test") after clearing the previous selection: ${result}`);
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue