mirror of
https://github.com/servo/servo.git
synced 2025-09-30 00:29:14 +01:00
libservo: Clean up interfaces for alert()/confirm()/prompt() (#35579)
Signed-off-by: Delan Azabani <dazabani@igalia.com>
This commit is contained in:
parent
03e953e22c
commit
276f6a3ba7
16 changed files with 278 additions and 222 deletions
|
@ -19,10 +19,11 @@ use log::{debug, error, info, warn};
|
|||
use raw_window_handle::{
|
||||
AndroidDisplayHandle, AndroidNdkWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||
};
|
||||
use servo::{LoadStatus, MediaSessionActionType};
|
||||
use servo::{
|
||||
AlertResponse, LoadStatus, MediaSessionActionType, PermissionRequest, SimpleDialog, WebView,
|
||||
};
|
||||
use simpleservo::{
|
||||
DeviceIntRect, EventLoopWaker, InitOptions, InputMethodType, MediaSessionPlaybackState,
|
||||
PromptResult, APP,
|
||||
DeviceIntRect, EventLoopWaker, InitOptions, InputMethodType, MediaSessionPlaybackState, APP,
|
||||
};
|
||||
|
||||
use super::app_state::{Coordinates, RunningAppState};
|
||||
|
@ -461,11 +462,8 @@ impl HostCallbacks {
|
|||
let jvm = env.get_java_vm().unwrap();
|
||||
HostCallbacks { callbacks, jvm }
|
||||
}
|
||||
}
|
||||
|
||||
impl HostTrait for HostCallbacks {
|
||||
fn prompt_alert(&self, message: String, _trusted: bool) {
|
||||
debug!("prompt_alert");
|
||||
fn show_alert(&self, message: String) {
|
||||
let mut env = self.jvm.get_env().unwrap();
|
||||
let Ok(string) = new_string_as_jvalue(&mut env, &message) else {
|
||||
return;
|
||||
|
@ -478,20 +476,41 @@ impl HostTrait for HostCallbacks {
|
|||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn prompt_ok_cancel(&self, message: String, _trusted: bool) -> PromptResult {
|
||||
warn!("Prompt not implemented. Cancelled. {}", message);
|
||||
PromptResult::Secondary
|
||||
impl HostTrait for HostCallbacks {
|
||||
fn request_permission(&self, _webview: WebView, request: PermissionRequest) {
|
||||
warn!("Permissions prompt not implemented. Denied.");
|
||||
request.deny();
|
||||
}
|
||||
|
||||
fn prompt_yes_no(&self, message: String, _trusted: bool) -> PromptResult {
|
||||
warn!("Prompt not implemented. Cancelled. {}", message);
|
||||
PromptResult::Secondary
|
||||
}
|
||||
|
||||
fn prompt_input(&self, message: String, default: String, _trusted: bool) -> Option<String> {
|
||||
warn!("Input prompt not implemented. {}", message);
|
||||
Some(default)
|
||||
fn show_simple_dialog(&self, _webview: WebView, dialog: SimpleDialog) {
|
||||
let _ = match dialog {
|
||||
SimpleDialog::Alert {
|
||||
message,
|
||||
response_sender,
|
||||
} => {
|
||||
debug!("SimpleDialog::Alert");
|
||||
// TODO: Indicate that this message is untrusted, and what origin it came from.
|
||||
self.show_alert(message);
|
||||
response_sender.send(AlertResponse::Ok)
|
||||
},
|
||||
SimpleDialog::Confirm {
|
||||
message,
|
||||
response_sender,
|
||||
} => {
|
||||
warn!("Confirm dialog not implemented. Cancelled. {}", message);
|
||||
response_sender.send(Default::default())
|
||||
},
|
||||
SimpleDialog::Prompt {
|
||||
message,
|
||||
response_sender,
|
||||
..
|
||||
} => {
|
||||
warn!("Prompt dialog not implemented. Cancelled. {}", message);
|
||||
response_sender.send(Default::default())
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn notify_load_status_changed(&self, load_status: LoadStatus) {
|
||||
|
|
|
@ -14,7 +14,7 @@ pub use servo::webrender_api::units::DeviceIntRect;
|
|||
/// and that perform_updates need to be called
|
||||
pub use servo::EventLoopWaker;
|
||||
use servo::{self, resources, Servo};
|
||||
pub use servo::{InputMethodType, MediaSessionPlaybackState, PromptResult, WindowRenderingContext};
|
||||
pub use servo::{InputMethodType, MediaSessionPlaybackState, WindowRenderingContext};
|
||||
|
||||
use crate::egl::android::resources::ResourceReaderInstance;
|
||||
use crate::egl::app_state::{
|
||||
|
|
|
@ -22,9 +22,9 @@ use servo::{
|
|||
AllowOrDenyRequest, ContextMenuResult, EmbedderProxy, EventLoopWaker, ImeEvent, InputEvent,
|
||||
InputMethodType, Key, KeyState, KeyboardEvent, LoadStatus, MediaSessionActionType,
|
||||
MediaSessionEvent, MouseButton, MouseButtonAction, MouseButtonEvent, MouseMoveEvent,
|
||||
NavigationRequest, PermissionRequest, PromptDefinition, PromptOrigin, PromptResult,
|
||||
RenderingContext, Servo, ServoDelegate, ServoError, TouchEvent, TouchEventType, TouchId,
|
||||
WebView, WebViewDelegate, WindowRenderingContext,
|
||||
NavigationRequest, PermissionRequest, RenderingContext, Servo, ServoDelegate, ServoError,
|
||||
SimpleDialog, TouchEvent, TouchEventType, TouchId, WebView, WebViewDelegate,
|
||||
WindowRenderingContext,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
|
@ -198,15 +198,10 @@ impl WebViewDelegate for RunningAppState {
|
|||
Some(new_webview)
|
||||
}
|
||||
|
||||
fn request_permission(&self, _webview: WebView, request: PermissionRequest) {
|
||||
let message = format!(
|
||||
"Do you want to grant permission for {:?}?",
|
||||
request.feature()
|
||||
);
|
||||
let result = match self.callbacks.host_callbacks.prompt_yes_no(message, true) {
|
||||
PromptResult::Primary => request.allow(),
|
||||
PromptResult::Secondary | PromptResult::Dismissed => request.deny(),
|
||||
};
|
||||
fn request_permission(&self, webview: WebView, request: PermissionRequest) {
|
||||
self.callbacks
|
||||
.host_callbacks
|
||||
.request_permission(webview, request);
|
||||
}
|
||||
|
||||
fn request_resize_to(&self, _webview: WebView, size: DeviceIntSize) {
|
||||
|
@ -231,21 +226,10 @@ impl WebViewDelegate for RunningAppState {
|
|||
}
|
||||
}
|
||||
|
||||
fn show_prompt(&self, _webview: WebView, prompt: PromptDefinition, origin: PromptOrigin) {
|
||||
let cb = &self.callbacks.host_callbacks;
|
||||
let trusted = origin == PromptOrigin::Trusted;
|
||||
let _ = match prompt {
|
||||
PromptDefinition::Alert(message, response_sender) => {
|
||||
cb.prompt_alert(message, trusted);
|
||||
response_sender.send(())
|
||||
},
|
||||
PromptDefinition::OkCancel(message, response_sender) => {
|
||||
response_sender.send(cb.prompt_ok_cancel(message, trusted))
|
||||
},
|
||||
PromptDefinition::Input(message, default, response_sender) => {
|
||||
response_sender.send(cb.prompt_input(message, default, trusted))
|
||||
},
|
||||
};
|
||||
fn show_simple_dialog(&self, webview: WebView, dialog: SimpleDialog) {
|
||||
self.callbacks
|
||||
.host_callbacks
|
||||
.show_simple_dialog(webview, dialog);
|
||||
}
|
||||
|
||||
fn show_ime(
|
||||
|
|
|
@ -3,18 +3,22 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use servo::webrender_api::units::DeviceIntRect;
|
||||
use servo::{InputMethodType, LoadStatus, MediaSessionPlaybackState, PromptResult};
|
||||
use servo::{
|
||||
InputMethodType, LoadStatus, MediaSessionPlaybackState, PermissionRequest, SimpleDialog,
|
||||
WebView,
|
||||
};
|
||||
|
||||
/// Callbacks. Implemented by embedder. Called by Servo.
|
||||
/// Callbacks implemented by embedder. Called by our RunningAppState, generally on behalf of Servo.
|
||||
pub trait HostTrait {
|
||||
/// Show alert.
|
||||
fn prompt_alert(&self, msg: String, trusted: bool);
|
||||
/// Ask Yes/No question.
|
||||
fn prompt_yes_no(&self, msg: String, trusted: bool) -> PromptResult;
|
||||
/// Ask Ok/Cancel question.
|
||||
fn prompt_ok_cancel(&self, msg: String, trusted: bool) -> PromptResult;
|
||||
/// Ask for string
|
||||
fn prompt_input(&self, msg: String, default: String, trusted: bool) -> Option<String>;
|
||||
/// Content in a [`WebView`] is requesting permission to access a feature requiring
|
||||
/// permission from the user. The embedder should allow or deny the request, either by
|
||||
/// reading a cached value or querying the user for permission via the user interface.
|
||||
fn request_permission(&self, _webview: WebView, _: PermissionRequest);
|
||||
/// Show the user a [simple dialog](https://html.spec.whatwg.org/multipage/#simple-dialogs) (`alert()`, `confirm()`,
|
||||
/// or `prompt()`). Since their messages are controlled by web content, they should be presented to the user in a
|
||||
/// way that makes them impossible to mistake for browser UI.
|
||||
/// TODO: This API needs to be reworked to match the new model of how responses are sent.
|
||||
fn show_simple_dialog(&self, _webview: WebView, dialog: SimpleDialog);
|
||||
/// Show context menu
|
||||
fn show_context_menu(&self, title: Option<String>, items: Vec<String>);
|
||||
/// Notify that the load status of the page has changed.
|
||||
|
|
|
@ -21,7 +21,10 @@ use napi_ohos::{Env, JsObject, JsString, NapiRaw};
|
|||
use ohos_ime::{AttachOptions, Ime, ImeProxy, RawTextEditorProxy};
|
||||
use ohos_ime_sys::types::InputMethod_EnterKeyType;
|
||||
use servo::style::Zero;
|
||||
use servo::{InputMethodType, LoadStatus, MediaSessionPlaybackState, PromptResult};
|
||||
use servo::{
|
||||
AlertResponse, InputMethodType, LoadStatus, MediaSessionPlaybackState, PermissionRequest,
|
||||
SimpleDialog, WebView,
|
||||
};
|
||||
use simpleservo::EventLoopWaker;
|
||||
use xcomponent_sys::{
|
||||
OH_NativeXComponent, OH_NativeXComponent_Callback, OH_NativeXComponent_GetKeyEvent,
|
||||
|
@ -671,6 +674,19 @@ impl HostCallbacks {
|
|||
ime_proxy: RefCell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn show_alert(&self, message: String) {
|
||||
match PROMPT_TOAST.get() {
|
||||
Some(prompt_fn) => {
|
||||
let status = prompt_fn.call(message, ThreadsafeFunctionCallMode::NonBlocking);
|
||||
if status != napi_ohos::Status::Ok {
|
||||
// Queue could be full.
|
||||
error!("show_alert failed with {status}");
|
||||
}
|
||||
},
|
||||
None => error!("PROMPT_TOAST not set. Dropping message {message}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ServoIme {
|
||||
|
@ -698,33 +714,38 @@ impl Ime for ServoIme {
|
|||
|
||||
#[allow(unused)]
|
||||
impl HostTrait for HostCallbacks {
|
||||
fn prompt_alert(&self, msg: String, _trusted: bool) {
|
||||
debug!("prompt_alert: {msg}");
|
||||
match PROMPT_TOAST.get() {
|
||||
Some(prompt_fn) => {
|
||||
let status = prompt_fn.call(msg, ThreadsafeFunctionCallMode::NonBlocking);
|
||||
if status != napi_ohos::Status::Ok {
|
||||
// Queue could be full.
|
||||
error!("prompt_alert failed with {status}");
|
||||
}
|
||||
fn request_permission(&self, _webview: WebView, request: PermissionRequest) {
|
||||
warn!("Permissions prompt not implemented. Denied.");
|
||||
request.deny();
|
||||
}
|
||||
|
||||
fn show_simple_dialog(&self, _webview: WebView, dialog: SimpleDialog) {
|
||||
let _ = match dialog {
|
||||
SimpleDialog::Alert {
|
||||
message,
|
||||
response_sender,
|
||||
} => {
|
||||
debug!("SimpleDialog::Alert");
|
||||
// TODO: Indicate that this message is untrusted, and what origin it came from.
|
||||
self.show_alert(message);
|
||||
response_sender.send(AlertResponse::Ok)
|
||||
},
|
||||
None => error!("PROMPT_TOAST not set. Dropping msg {msg}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn prompt_yes_no(&self, msg: String, trusted: bool) -> PromptResult {
|
||||
warn!("Prompt not implemented. Cancelled. {}", msg);
|
||||
PromptResult::Secondary
|
||||
}
|
||||
|
||||
fn prompt_ok_cancel(&self, msg: String, trusted: bool) -> PromptResult {
|
||||
warn!("Prompt not implemented. Cancelled. {}", msg);
|
||||
PromptResult::Secondary
|
||||
}
|
||||
|
||||
fn prompt_input(&self, msg: String, default: String, trusted: bool) -> Option<String> {
|
||||
warn!("Input prompt not implemented. Cancelled. {}", msg);
|
||||
Some(default)
|
||||
SimpleDialog::Confirm {
|
||||
message,
|
||||
response_sender,
|
||||
} => {
|
||||
warn!("Confirm dialog not implemented. Cancelled. {}", message);
|
||||
response_sender.send(Default::default())
|
||||
},
|
||||
SimpleDialog::Prompt {
|
||||
message,
|
||||
response_sender,
|
||||
..
|
||||
} => {
|
||||
warn!("Prompt dialog not implemented. Cancelled. {}", message);
|
||||
response_sender.send(Default::default())
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn show_context_menu(&self, title: Option<String>, items: Vec<String>) {
|
||||
|
@ -740,7 +761,7 @@ impl HostTrait for HostCallbacks {
|
|||
if load_status == LoadStatus::Complete {
|
||||
#[cfg(feature = "tracing-hitrace")]
|
||||
let _scope = hitrace::ScopedTrace::start_trace(&c"PageLoadEndedPrompt");
|
||||
self.prompt_alert("Page finished loading!".to_string(), true);
|
||||
self.show_alert("Page finished loading!".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -838,7 +859,7 @@ impl HostTrait for HostCallbacks {
|
|||
if let Some(bt) = backtrace {
|
||||
error!("Backtrace: {bt:?}")
|
||||
}
|
||||
self.prompt_alert("Servo crashed!".to_string(), true);
|
||||
self.prompt_alert(reason, true);
|
||||
self.show_alert("Servo crashed!".to_string());
|
||||
self.show_alert(reason);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue