mirror of
https://github.com/servo/servo.git
synced 2025-10-10 05:20:19 +01:00
This change adds a new `WebView` API `evaluate_javascript()`, which allows embedders to execute JavaScript code and wait for a reply asynchronously. Ongoing script execution is tracked by a libservo `JavaScriptEvaluator` struct, which maps an id to the callback passed to the `evaluate_javascript()` method. The id is used to track the script and its execution through the other parts of Servo. Testing: This changes includes `WebView` unit tests. --------- Signed-off-by: Narfinger <Narfinger@users.noreply.github.com> Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
65 lines
2.1 KiB
Rust
65 lines
2.1 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use base::id::WebViewId;
|
|
use constellation_traits::EmbedderToConstellationMessage;
|
|
use embedder_traits::{JSValue, JavaScriptEvaluationError, JavaScriptEvaluationId};
|
|
|
|
use crate::ConstellationProxy;
|
|
|
|
struct PendingEvaluation {
|
|
callback: Box<dyn FnOnce(Result<JSValue, JavaScriptEvaluationError>)>,
|
|
}
|
|
|
|
pub(crate) struct JavaScriptEvaluator {
|
|
current_id: JavaScriptEvaluationId,
|
|
constellation_proxy: ConstellationProxy,
|
|
pending_evaluations: HashMap<JavaScriptEvaluationId, PendingEvaluation>,
|
|
}
|
|
|
|
impl JavaScriptEvaluator {
|
|
pub(crate) fn new(constellation_proxy: ConstellationProxy) -> Self {
|
|
Self {
|
|
current_id: JavaScriptEvaluationId(0),
|
|
constellation_proxy,
|
|
pending_evaluations: Default::default(),
|
|
}
|
|
}
|
|
|
|
fn generate_id(&mut self) -> JavaScriptEvaluationId {
|
|
let next_id = JavaScriptEvaluationId(self.current_id.0 + 1);
|
|
std::mem::replace(&mut self.current_id, next_id)
|
|
}
|
|
|
|
pub(crate) fn evaluate(
|
|
&mut self,
|
|
webview_id: WebViewId,
|
|
script: String,
|
|
callback: Box<dyn FnOnce(Result<JSValue, JavaScriptEvaluationError>)>,
|
|
) {
|
|
let evaluation_id = self.generate_id();
|
|
self.constellation_proxy
|
|
.send(EmbedderToConstellationMessage::EvaluateJavaScript(
|
|
webview_id,
|
|
evaluation_id,
|
|
script,
|
|
));
|
|
self.pending_evaluations
|
|
.insert(evaluation_id, PendingEvaluation { callback });
|
|
}
|
|
|
|
pub(crate) fn finish_evaluation(
|
|
&mut self,
|
|
evaluation_id: JavaScriptEvaluationId,
|
|
result: Result<JSValue, JavaScriptEvaluationError>,
|
|
) {
|
|
(self
|
|
.pending_evaluations
|
|
.remove(&evaluation_id)
|
|
.expect("Received request to finish unknown JavaScript evaluation.")
|
|
.callback)(result)
|
|
}
|
|
}
|