do not rely on UWP URL parser

This commit is contained in:
Paul Rouget 2019-11-06 07:38:19 +01:00
parent 147c042c5a
commit 1c3da95b70
7 changed files with 67 additions and 35 deletions

View file

@ -152,6 +152,12 @@ pub fn servo_version() -> String {
servo::config::servo_version()
}
/// Test if a url is valid.
pub fn is_uri_valid(url: &str) -> bool {
info!("load_uri: {}", url);
ServoUrl::parse(url).is_ok()
}
/// Initialize Servo. At that point, we need a valid GL context.
/// In the future, this will be done in multiple steps.
pub fn init(

View file

@ -186,16 +186,17 @@ fn do_redirect_stdout_stderr() -> Result<(), ()> {
Ok(())
}
fn call<F>(f: F)
fn call<T, F>(f: F) -> T
where
F: Fn(&mut ServoGlue) -> Result<(), &'static str>,
F: Fn(&mut ServoGlue) -> Result<T, &'static str>,
{
if let Err(e) = SERVO.with(|s| match s.borrow_mut().as_mut() {
match SERVO.with(|s| match s.borrow_mut().as_mut() {
Some(ref mut s) => (f)(s),
None => Err("Servo not available in this thread"),
}) {
panic!(e);
};
Err(e) => panic!(e),
Ok(r) => r,
}
}
/// Callback used by Servo internals
@ -430,13 +431,23 @@ pub extern "C" fn perform_updates() {
}
#[no_mangle]
pub extern "C" fn load_uri(url: *const c_char) {
pub extern "C" fn is_uri_valid(url: *const c_char) -> bool {
catch_any_panic(|| {
debug!("is_uri_valid");
let url = unsafe { CStr::from_ptr(url) };
let url = url.to_str().expect("Can't read string");
simpleservo::is_uri_valid(url)
})
}
#[no_mangle]
pub extern "C" fn load_uri(url: *const c_char) -> bool {
catch_any_panic(|| {
debug!("load_url");
let url = unsafe { CStr::from_ptr(url) };
let url = url.to_str().expect("Can't read string");
call(|s| s.load_uri(url));
});
call(|s| Ok(s.load_uri(url).is_ok()))
})
}
#[no_mangle]

View file

@ -116,7 +116,7 @@ void BrowserPage::OnURLEdited(IInspectable const &,
servoControl().Focus(FocusState::Programmatic);
auto input = urlTextbox().Text();
auto uri = servoControl().LoadURIOrSearch(input);
urlTextbox().Text(uri.ToString());
urlTextbox().Text(uri);
}
}

View file

@ -66,7 +66,10 @@ public:
void Reload() { capi::reload(); }
void Stop() { capi::stop(); }
void LoadUri(hstring uri) { capi::load_uri(*hstring2char(uri)); }
bool LoadUri(hstring uri) { return capi::load_uri(*hstring2char(uri)); }
bool IsUriValid(hstring uri) {
return capi::is_uri_valid(*hstring2char(uri));
}
void Scroll(float dx, float dy, float x, float y) {
capi::scroll((int32_t)dx, (int32_t)dy, (int32_t)x, (int32_t)y);
}

View file

@ -195,25 +195,43 @@ void ServoControl::Reload() {
void ServoControl::Stop() {
RunOnGLThread([=] { mServo->Stop(); });
}
Uri ServoControl::LoadURIOrSearch(hstring input) {
auto uri = TryParseURI(input);
if (uri == std::nullopt) {
hstring ServoControl::LoadURIOrSearch(hstring input) {
// Initial input is valid
if (mServo->IsUriValid(input)) {
TryLoadUri(input);
return input;
}
// Not valid. Maybe it's just missing the scheme.
hstring with_scheme = L"https://" + input;
// If the user only types "mozilla" we don't want to go to
// https://mozilla even though it's a valid url.
bool has_dot = wcsstr(input.c_str(), L".") != nullptr;
hstring input2 = L"https://" + input;
uri = TryParseURI(input2);
if (uri == std::nullopt || !has_dot) {
hstring input3 =
if (mServo->IsUriValid(with_scheme) && has_dot) {
TryLoadUri(with_scheme);
return with_scheme;
}
// Doesn't look like a URI. Let's search for the string.
hstring searchUri =
L"https://duckduckgo.com/html/?q=" + Uri::EscapeComponent(input);
uri = TryParseURI(input3);
TryLoadUri(searchUri);
return searchUri;
}
}
auto finalUri = uri.value();
void ServoControl::TryLoadUri(hstring input) {
if (!mLooping) {
mInitialURL = finalUri.ToString();
mInitialURL = input;
} else {
RunOnGLThread([=] { mServo->LoadUri(finalUri.ToString()); });
RunOnGLThread([=] {
if (!mServo->LoadUri(input)) {
RunOnUIThread([=] {
Windows::UI::Popups::MessageDialog msg{L"URI not valid"};
msg.ShowAsync();
});
}
});
}
return finalUri;
}
void ServoControl::RunOnGLThread(std::function<void()> task) {

View file

@ -14,7 +14,7 @@ struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
void Reload();
void Stop();
void Shutdown();
Windows::Foundation::Uri LoadURIOrSearch(hstring);
hstring LoadURIOrSearch(hstring);
void OnLoaded(IInspectable const &,
Windows::UI::Xaml::RoutedEventArgs const &);
@ -110,14 +110,6 @@ private:
void StopRenderLoop();
void Loop();
std::optional<Windows::Foundation::Uri> TryParseURI(hstring input) {
try {
return Windows::Foundation::Uri(input);
} catch (hresult_invalid_argument const &) {
return {};
}
}
void OnSurfaceTapped(IInspectable const &,
Windows::UI::Xaml::Input::TappedRoutedEventArgs const &);
@ -147,6 +139,8 @@ private:
template <typename Callable> void RunOnUIThread(Callable);
void RunOnGLThread(std::function<void()>);
void TryLoadUri(hstring);
std::unique_ptr<servo::Servo> mServo;
EGLSurface mRenderSurface{EGL_NO_SURFACE};
OpenGLES mOpenGLES;

View file

@ -9,7 +9,7 @@ namespace ServoApp {
void GoForward();
void Reload();
void Stop();
Windows.Foundation.Uri LoadURIOrSearch(String url);
String LoadURIOrSearch(String url);
void SetTransientMode(Boolean transient);
void SetArgs(String args);
void Shutdown();