servo/
javascript_evaluator.rs1use base::id::WebViewId;
6use constellation_traits::EmbedderToConstellationMessage;
7use embedder_traits::{JSValue, JavaScriptEvaluationError, JavaScriptEvaluationId};
8use rustc_hash::FxHashMap;
9
10use crate::ConstellationProxy;
11
12struct PendingEvaluation {
13 callback: Box<dyn FnOnce(Result<JSValue, JavaScriptEvaluationError>)>,
14}
15
16pub(crate) struct JavaScriptEvaluator {
17 current_id: JavaScriptEvaluationId,
18 constellation_proxy: ConstellationProxy,
19 pending_evaluations: FxHashMap<JavaScriptEvaluationId, PendingEvaluation>,
20}
21
22impl JavaScriptEvaluator {
23 pub(crate) fn new(constellation_proxy: ConstellationProxy) -> Self {
24 Self {
25 current_id: JavaScriptEvaluationId(0),
26 constellation_proxy,
27 pending_evaluations: Default::default(),
28 }
29 }
30
31 fn generate_id(&mut self) -> JavaScriptEvaluationId {
32 let next_id = JavaScriptEvaluationId(self.current_id.0 + 1);
33 std::mem::replace(&mut self.current_id, next_id)
34 }
35
36 pub(crate) fn evaluate(
37 &mut self,
38 webview_id: WebViewId,
39 script: String,
40 callback: Box<dyn FnOnce(Result<JSValue, JavaScriptEvaluationError>)>,
41 ) {
42 let evaluation_id = self.generate_id();
43 self.constellation_proxy
44 .send(EmbedderToConstellationMessage::EvaluateJavaScript(
45 webview_id,
46 evaluation_id,
47 script,
48 ));
49 self.pending_evaluations
50 .insert(evaluation_id, PendingEvaluation { callback });
51 }
52
53 pub(crate) fn finish_evaluation(
54 &mut self,
55 evaluation_id: JavaScriptEvaluationId,
56 result: Result<JSValue, JavaScriptEvaluationError>,
57 ) {
58 (self
59 .pending_evaluations
60 .remove(&evaluation_id)
61 .expect("Received request to finish unknown JavaScript evaluation.")
62 .callback)(result)
63 }
64}