1use crate::{DomId, JsJson, JsJsonObjectBuilder};
2
3use super::{api::CallbackId, StaticString};
4
5#[derive(Clone, Debug)]
6pub enum DriverDomCommand {
7 CreateNode {
8 id: DomId,
9 name: StaticString,
10 },
11 CreateText {
12 id: DomId,
13 value: String,
14 },
15 UpdateText {
16 id: DomId,
17 value: String,
18 },
19 SetAttr {
20 id: DomId,
21 name: StaticString,
22 value: String,
23 },
24 RemoveAttr {
25 id: DomId,
26 name: StaticString,
27 },
28 RemoveNode {
29 id: DomId,
30 },
31 RemoveText {
32 id: DomId,
33 },
34 InsertBefore {
35 parent: DomId,
36 child: DomId,
37 ref_id: Option<DomId>,
38 },
39 InsertCss {
40 selector: Option<String>,
41 value: String,
42 },
43
44 CreateComment {
45 id: DomId,
46 value: String,
47 },
48 RemoveComment {
49 id: DomId,
50 },
51 CallbackAdd {
52 id: DomId,
53 event_name: String,
54 callback_id: CallbackId,
55 },
56 CallbackRemove {
57 id: DomId,
58 event_name: String,
59 callback_id: CallbackId,
60 },
61}
62
63impl DriverDomCommand {
64 fn is_event(&self) -> bool {
65 matches!(
66 self,
67 Self::RemoveNode { .. } | Self::RemoveText { .. } | Self::RemoveComment { .. }
68 )
69 }
70
71 pub fn into_string(self) -> JsJson {
72 match self {
73 Self::CreateNode { id, name } => JsJsonObjectBuilder::default()
74 .insert("type", "create_node")
75 .insert("id", id.to_u64())
76 .insert("name", name.as_str())
77 .get(),
78 Self::CreateText { id, value } => JsJsonObjectBuilder::default()
79 .insert("type", "create_text")
80 .insert("id", id.to_u64())
81 .insert("value", value)
82 .get(),
83 Self::UpdateText { id, value } => JsJsonObjectBuilder::default()
84 .insert("type", "update_text")
85 .insert("id", id.to_u64())
86 .insert("value", value)
87 .get(),
88 Self::SetAttr { id, name, value } => JsJsonObjectBuilder::default()
89 .insert("type", "set_attr")
90 .insert("id", id.to_u64())
91 .insert("name", name.as_str())
92 .insert("value", value)
93 .get(),
94 Self::RemoveAttr { id, name } => JsJsonObjectBuilder::default()
95 .insert("type", "remove_attr")
96 .insert("id", id.to_u64())
97 .insert("name", name.as_str())
98 .get(),
99 Self::RemoveNode { id } => JsJsonObjectBuilder::default()
100 .insert("type", "remove_node")
101 .insert("id", id.to_u64())
102 .get(),
103 Self::RemoveText { id } => JsJsonObjectBuilder::default()
104 .insert("type", "remove_text")
105 .insert("id", id.to_u64())
106 .get(),
107
108 Self::CreateComment { id, value } => JsJsonObjectBuilder::default()
109 .insert("type", "create_comment")
110 .insert("id", id.to_u64())
111 .insert("value", value)
112 .get(),
113 Self::RemoveComment { id } => JsJsonObjectBuilder::default()
114 .insert("type", "remove_comment")
115 .insert("id", id.to_u64())
116 .get(),
117
118 Self::InsertBefore {
119 parent,
120 child,
121 ref_id,
122 } => JsJsonObjectBuilder::default()
123 .insert("type", "insert_before")
124 .insert("parent", parent.to_u64())
125 .insert("child", child.to_u64())
126 .insert("ref_id", ref_id.map(|value| value.to_u64()))
127 .get(),
128 Self::InsertCss { selector, value } => JsJsonObjectBuilder::default()
129 .insert("type", "insert_css")
130 .insert("selector", selector)
131 .insert("value", value)
132 .get(),
133 Self::CallbackAdd {
134 id,
135 event_name,
136 callback_id,
137 } => JsJsonObjectBuilder::default()
138 .insert("type", "callback_add")
139 .insert("id", id.to_u64())
140 .insert("event_name", event_name)
141 .insert("callback_id", callback_id.as_u64())
142 .get(),
143 Self::CallbackRemove {
144 id,
145 event_name,
146 callback_id,
147 } => JsJsonObjectBuilder::default()
148 .insert("type", "callback_remove")
149 .insert("id", id.to_u64())
150 .insert("event_name", event_name)
151 .insert("callback_id", callback_id.as_u64())
152 .get(),
153 }
154 }
155}
156
157pub fn sort_commands(list: Vec<DriverDomCommand>) -> Vec<DriverDomCommand> {
158 let mut dom = Vec::new();
159 let mut events = Vec::new();
160
161 for command in list {
162 if command.is_event() {
163 events.push(command);
164 } else {
165 dom.push(command);
166 }
167 }
168
169 dom.extend(events);
170
171 dom
172}