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