devtools/actors/inspector/
accessibility.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! The Accessibility actor is responsible for the Accessibility tab in the DevTools page. Right
6//! now it is a placeholder for future functionality.
7
8use malloc_size_of_derive::MallocSizeOf;
9use serde::Serialize;
10use serde_json::{Map, Value};
11
12use crate::StreamId;
13use crate::actor::{Actor, ActorError, ActorRegistry};
14use crate::protocol::ClientRequest;
15
16#[derive(Serialize)]
17struct BootstrapState {
18    enabled: bool,
19}
20
21#[derive(Serialize)]
22struct BootstrapReply {
23    from: String,
24    state: BootstrapState,
25}
26
27#[derive(Serialize)]
28struct GetSimulatorReply {
29    from: String,
30    simulator: ActorMsg,
31}
32
33#[derive(Serialize)]
34#[serde(rename_all = "camelCase")]
35struct AccessibilityTraits {
36    tabbing_order: bool,
37}
38
39#[derive(Serialize)]
40struct GetTraitsReply {
41    from: String,
42    traits: AccessibilityTraits,
43}
44
45#[derive(Serialize)]
46struct ActorMsg {
47    actor: String,
48}
49
50#[derive(Serialize)]
51struct GetWalkerReply {
52    from: String,
53    walker: ActorMsg,
54}
55
56#[derive(MallocSizeOf)]
57pub(crate) struct AccessibilityActor {
58    name: String,
59}
60
61impl Actor for AccessibilityActor {
62    fn name(&self) -> String {
63        self.name.clone()
64    }
65
66    /// The accesibility actor can handle the following messages:
67    ///
68    /// - `bootstrap`: It is required but it doesn't do anything yet
69    ///
70    /// - `getSimulator`: Returns a new Simulator actor
71    ///
72    /// - `getTraits`: Informs the DevTools client about the configuration of the accessibility actor
73    ///
74    /// - `getWalker`: Returns a new AccessibleWalker actor (not to be confused with the general
75    ///   inspector Walker actor)
76    fn handle_message(
77        &self,
78        request: ClientRequest,
79        registry: &ActorRegistry,
80        msg_type: &str,
81        _msg: &Map<String, Value>,
82        _id: StreamId,
83    ) -> Result<(), ActorError> {
84        match msg_type {
85            "bootstrap" => {
86                let msg = BootstrapReply {
87                    from: self.name(),
88                    state: BootstrapState { enabled: false },
89                };
90                request.reply_final(&msg)?
91            },
92            "getSimulator" => {
93                // TODO: Create actual simulator
94                let actor = registry.new_name::<SimulatorActor>();
95                registry.register(SimulatorActor {
96                    name: actor.clone(),
97                });
98                let msg = GetSimulatorReply {
99                    from: self.name(),
100                    simulator: ActorMsg { actor },
101                };
102                request.reply_final(&msg)?
103            },
104            "getTraits" => {
105                let msg = GetTraitsReply {
106                    from: self.name(),
107                    traits: AccessibilityTraits {
108                        tabbing_order: true,
109                    },
110                };
111                request.reply_final(&msg)?
112            },
113            "getWalker" => {
114                // TODO: Create actual accessible walker
115                let actor = registry.new_name::<AccessibleWalkerActor>();
116                registry.register(AccessibleWalkerActor {
117                    name: actor.clone(),
118                });
119                let msg = GetWalkerReply {
120                    from: self.name(),
121                    walker: ActorMsg { actor },
122                };
123                request.reply_final(&msg)?
124            },
125            _ => return Err(ActorError::UnrecognizedPacketType),
126        };
127        Ok(())
128    }
129}
130
131impl AccessibilityActor {
132    pub fn register(registry: &ActorRegistry) -> String {
133        let name = registry.new_name::<Self>();
134        let actor = Self { name: name.clone() };
135        registry.register::<Self>(actor);
136        name
137    }
138}
139
140#[derive(MallocSizeOf)]
141pub(crate) struct SimulatorActor {
142    name: String,
143}
144
145impl Actor for SimulatorActor {
146    fn name(&self) -> String {
147        self.name.clone()
148    }
149}
150
151#[derive(MallocSizeOf)]
152pub(crate) struct AccessibleWalkerActor {
153    name: String,
154}
155
156impl Actor for AccessibleWalkerActor {
157    fn name(&self) -> String {
158        self.name.clone()
159    }
160}