Allow domain-like as URL location input (#35756)

* Allow domain-like as URL location input

Before this patch, domain with subdomain (e.g. book.servo.org) won't be
treated as URL location.

This patch retifies that by adding Firefox's location bar behavior:

  - book.servo.org is URL location
  - book.servo.org. is URL location
  - .book.servo.org is not URL location

Fixes #35754.

Signed-off-by: Kafji <k@kafji.net>

* Chain location input interpretation attempts

Signed-off-by: Kafji <k@kafji.net>

---------

Signed-off-by: Kafji <k@kafji.net>
This commit is contained in:
Kafji 2025-03-10 10:24:48 +07:00 committed by GitHub
parent 48aacc43b7
commit 34047f8da8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 94 additions and 9 deletions

View file

@ -63,13 +63,35 @@ pub fn get_default_url(
/// interpret the string as a search term.
pub(crate) fn location_bar_input_to_url(request: &str, searchpage: &str) -> Option<ServoUrl> {
let request = request.trim();
ServoUrl::parse(request).ok().or_else(|| {
if request.starts_with('/') {
ServoUrl::parse(&format!("file://{}", request)).ok()
} else if request.contains('/') || is_reg_domain(request) {
ServoUrl::parse(&format!("https://{}", request)).ok()
} else {
ServoUrl::parse(&searchpage.replace("%s", request)).ok()
}
})
ServoUrl::parse(request)
.ok()
.or_else(|| try_as_file(request))
.or_else(|| try_as_domain(request))
.or_else(|| try_as_search_page(request, searchpage))
}
fn try_as_file(request: &str) -> Option<ServoUrl> {
if request.starts_with('/') {
return ServoUrl::parse(&format!("file://{}", request)).ok();
}
None
}
fn try_as_domain(request: &str) -> Option<ServoUrl> {
fn is_domain_like(s: &str) -> bool {
!s.starts_with('/') && s.contains('/') ||
(!s.contains(' ') && !s.starts_with('.') && s.split('.').count() > 1)
}
if !request.contains(' ') && is_reg_domain(request) || is_domain_like(request) {
return ServoUrl::parse(&format!("https://{}", request)).ok();
}
None
}
fn try_as_search_page(request: &str, searchpage: &str) -> Option<ServoUrl> {
if request.is_empty() {
return None;
}
ServoUrl::parse(&searchpage.replace("%s", request)).ok()
}