Skip to content

Commit

Permalink
LibWeb: Implement a minimal version of Window.find()
Browse files Browse the repository at this point in the history
This is a non-standard API that other browsers implement, which
highlights matching text in the current window.

This is just a thin wrapper around our find in page functionality, the
main motivation for adding this API is that it allows us to write tests
for our find in page implementation.
  • Loading branch information
tcl3 committed Jun 26, 2024
1 parent 2de7d6e commit 6521cb5
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Tests/LibWeb/Text/expected/Window-find.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
window.find(): false
window.find(this): true, selection from: 0 to 4
window.find(this): false
window.find(A): true, selection from: 8 to 9
window.find(t): true, selection from: 10 to 11
window.find(t): true, selection from: 13 to 14
window.find(t): false
40 changes: 40 additions & 0 deletions Tests/LibWeb/Text/input/HTML/Window-find.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script src="../include.js"></script>
<div id="textContainer">
<div style="display: none">This is hidden</div>
<div style="visibility: hidden">This is also hidden</div>
<span>this is a test</span>
</div>
<script>
function windowFindTest(string) {
const result = window.find(string);
const selection = window.getSelection();
if (result && selection && selection.rangeCount === 1) {
const range = selection.getRangeAt(0);
println(`window.find(${string}): ${result}, selection from: ${range.startOffset} to ${range.endOffset}`);
} else {
println(`window.find(${string}): ${result}`);
}
}

function testBody() {
println(`window.find(): ${window.find()}`);
windowFindTest("this");
windowFindTest("this");
windowFindTest("A");
windowFindTest("t");
windowFindTest("t");
windowFindTest("t");
document.getElementById("textContainer").remove();
}

test(() => {
// This hides the test output until the test is complete.
const testOutputTextContainer = document.getElementById("out");
try {
testOutputTextContainer.style.display = "none";
testBody();
} finally {
testOutputTextContainer.style.display = "block";
}
});
</script>
22 changes: 22 additions & 0 deletions Userland/Libraries/LibWeb/HTML/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1712,4 +1712,26 @@ Window::NamedObjects Window::named_objects(StringView name)
return objects;
}

bool Window::find(String const& string)
{
if (string.is_empty())
return false;

auto& page = this->page();
Optional<Page::FindInPageResult> result;
if (auto last_query = page.last_find_in_page_query(); last_query.has_value() && last_query->string == string) {
result = page.find_in_page_next_match();
} else {
Page::FindInPageQuery query {
string,
CaseSensitivity::CaseInsensitive,
Page::WrapAround::No,
};

result = page.find_in_page(query);
}

return result.has_value() && result->total_match_count.has_value() && *result->total_match_count > 0;
}

}
2 changes: 2 additions & 0 deletions Userland/Libraries/LibWeb/HTML/Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ class Window final
[[nodiscard]] Vector<FlyString> supported_property_names() const override;
[[nodiscard]] WebIDL::ExceptionOr<JS::Value> named_item_value(FlyString const&) const override;

bool find(String const& string);

private:
explicit Window(JS::Realm&);

Expand Down
4 changes: 4 additions & 0 deletions Userland/Libraries/LibWeb/HTML/Window.idl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ interface Window : EventTarget {

undefined captureEvents();
undefined releaseEvents();

// This function is non-standard. We broadly follow the behavior described here:
// https://developer.mozilla.org/en-US/docs/Web/API/Window/find
boolean find(optional DOMString string = "");
};
Window includes AnimationFrameProvider;
Window includes GlobalEventHandlers;
Expand Down
1 change: 1 addition & 0 deletions Userland/Libraries/LibWeb/Page/Page.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ class Page final : public JS::Cell {
FindInPageResult find_in_page(FindInPageQuery const&);
FindInPageResult find_in_page_next_match();
FindInPageResult find_in_page_previous_match();
Optional<FindInPageQuery> last_find_in_page_query() const { return m_last_find_in_page_query; }

private:
explicit Page(JS::NonnullGCPtr<PageClient>);
Expand Down

0 comments on commit 6521cb5

Please sign in to comment.