slint-ui 1.9.0-nightly.2024100103 → 1.9.0-nightly.2024100207

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Cargo.toml CHANGED
@@ -41,10 +41,10 @@ accessibility = ["slint-interpreter/accessibility"]
41
41
  [dependencies]
42
42
  napi = { version = "2.14.0", default-features = false, features = ["napi8"] }
43
43
  napi-derive = "2.14.0"
44
- i-slint-compiler = { features = ["default"] , git = "https://github.com/slint-ui/slint", rev = "f041075e76b61b95df3cff8c430776cb032e20fb", version = "=1.9.0", default-features = false }
45
- i-slint-core = { features = ["default"] , git = "https://github.com/slint-ui/slint", rev = "f041075e76b61b95df3cff8c430776cb032e20fb", version = "=1.9.0", default-features = false }
46
- i-slint-backend-selector = { git = "https://github.com/slint-ui/slint", rev = "f041075e76b61b95df3cff8c430776cb032e20fb", version = "=1.9.0", default-features = false }
47
- slint-interpreter = { default-features = false , features = ["display-diagnostics", "internal", "compat-1-2"] , git = "https://github.com/slint-ui/slint", rev = "f041075e76b61b95df3cff8c430776cb032e20fb", version = "=1.9.0"}
44
+ i-slint-compiler = { features = ["default"] , git = "https://github.com/slint-ui/slint", rev = "34fc24e4e0df464056cd79972dcfaa24b2dbb9f4", version = "=1.9.0", default-features = false }
45
+ i-slint-core = { features = ["default"] , git = "https://github.com/slint-ui/slint", rev = "34fc24e4e0df464056cd79972dcfaa24b2dbb9f4", version = "=1.9.0", default-features = false }
46
+ i-slint-backend-selector = { git = "https://github.com/slint-ui/slint", rev = "34fc24e4e0df464056cd79972dcfaa24b2dbb9f4", version = "=1.9.0", default-features = false }
47
+ slint-interpreter = { default-features = false , features = ["display-diagnostics", "internal", "compat-1-2"] , git = "https://github.com/slint-ui/slint", rev = "34fc24e4e0df464056cd79972dcfaa24b2dbb9f4", version = "=1.9.0"}
48
48
  spin_on = { version = "0.1" }
49
49
  css-color-parser2 = { version = "1.0.1" }
50
50
  itertools = { version = "0.13" }
package/README.md CHANGED
@@ -193,6 +193,7 @@ The types used for properties in .slint design markup each translate to specific
193
193
  | `angle` | `Number` | The angle in degrees |
194
194
  | structure | `Object` | Structures are mapped to JavaScript objects where each structure field is a property. |
195
195
  | array | `Array` or any implementation of Model | |
196
+ | enumeration | `String` | The value of an enum |
196
197
 
197
198
  ### Arrays and Models
198
199
 
package/biome.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
3
3
  "extends": ["../../biome.json"],
4
4
  "formatter": {
5
- "ignore": ["*/rust-module.d.ts"]
5
+ "ignore": ["rust-module.d.ts", "rust-module.cjs", "dist/"]
6
6
  },
7
7
  "linter": {
8
- "ignore": ["rust-module.d.ts", "rust-module.cjs"],
8
+ "ignore": ["rust-module.d.ts", "rust-module.cjs", "dist/"],
9
9
  "rules": {
10
10
  "complexity": {
11
11
  "useArrowFunction": "off",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slint-ui",
3
- "version": "1.9.0-nightly.2024100103",
3
+ "version": "1.9.0-nightly.2024100207",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "homepage": "https://github.com/slint-ui/slint",
@@ -22,9 +22,11 @@
22
22
  "devDependencies": {
23
23
  "@ava/typescript": "^4.1.0",
24
24
  "@biomejs/biome": "1.8.3",
25
+ "@types/capture-console": "^1.0.5",
25
26
  "@types/node": "^20.8.6",
26
27
  "@types/node-fetch": "^2.6.7",
27
28
  "ava": "^5.3.0",
29
+ "capture-console": "^1.0.2",
28
30
  "jimp": "^0.22.8",
29
31
  "ts-node": "^10.9.1",
30
32
  "typedoc": "^0.25.2",
@@ -65,10 +67,10 @@
65
67
  "@napi-rs/cli": "^2.16.5"
66
68
  },
67
69
  "optionalDependencies": {
68
- "@slint-ui/slint-ui-binary-linux-x64-gnu": "1.9.0-nightly.2024100103",
69
- "@slint-ui/slint-ui-binary-darwin-x64": "1.9.0-nightly.2024100103",
70
- "@slint-ui/slint-ui-binary-darwin-arm64": "1.9.0-nightly.2024100103",
71
- "@slint-ui/slint-ui-binary-win32-x64-msvc": "1.9.0-nightly.2024100103",
72
- "@slint-ui/slint-ui-binary-win32-ia32-msvc": "1.9.0-nightly.2024100103"
70
+ "@slint-ui/slint-ui-binary-linux-x64-gnu": "1.9.0-nightly.2024100207",
71
+ "@slint-ui/slint-ui-binary-darwin-x64": "1.9.0-nightly.2024100207",
72
+ "@slint-ui/slint-ui-binary-darwin-arm64": "1.9.0-nightly.2024100207",
73
+ "@slint-ui/slint-ui-binary-win32-x64-msvc": "1.9.0-nightly.2024100207",
74
+ "@slint-ui/slint-ui-binary-win32-ia32-msvc": "1.9.0-nightly.2024100207"
73
75
  }
74
76
  }
@@ -137,21 +137,39 @@ impl JsComponentInstance {
137
137
  self.inner
138
138
  .set_callback(callback_name.as_str(), {
139
139
  let return_type = return_type.clone();
140
+ let callback_name = callback_name.clone();
140
141
 
141
142
  move |args| {
142
- let callback: JsFunction = function_ref.get().unwrap();
143
- let result = callback
143
+ let Ok(callback) = function_ref.get::<JsFunction>() else {
144
+ eprintln!("Node.js: cannot get reference of callback {} because it has the wrong type", callback_name);
145
+ return Value::Void;
146
+ };
147
+
148
+ let result = match callback
144
149
  .call(
145
150
  None,
146
151
  args.iter()
147
152
  .map(|v| super::value::to_js_unknown(&env, v).unwrap())
148
153
  .collect::<Vec<JsUnknown>>()
149
- .as_ref(),
150
- )
151
- .unwrap();
154
+ .as_ref()
155
+ ) {
156
+ Ok(result) => result,
157
+ Err(err) => {
158
+ crate::console_err!(env, "Node.js: Invoking callback '{callback_name}' failed: {err}");
159
+ return Value::Void;
160
+ }
161
+ };
152
162
 
153
163
  if let Some(return_type) = &return_type {
154
- super::to_value(&env, result, return_type).unwrap()
164
+ if let Ok(value) = super::to_value(&env, result, return_type) {
165
+ return value;
166
+ } else {
167
+ eprintln!(
168
+ "Node.js: cannot convert return type of callback {}",
169
+ callback_name
170
+ );
171
+ return slint_interpreter::default_value_for_type(return_type);
172
+ }
155
173
  } else {
156
174
  Value::Void
157
175
  }
@@ -192,21 +210,43 @@ impl JsComponentInstance {
192
210
  self.inner
193
211
  .set_global_callback(global_name.as_str(), callback_name.as_str(), {
194
212
  let return_type = return_type.clone();
213
+ let global_name = global_name.clone();
214
+ let callback_name = callback_name.clone();
195
215
 
196
216
  move |args| {
197
- let callback: JsFunction = function_ref.get().unwrap();
198
- let result = callback
217
+ let Ok(callback) = function_ref.get::<JsFunction>() else {
218
+ eprintln!(
219
+ "Node.js: cannot get reference of callback {} of global {} because it has the wrong type",
220
+ callback_name, global_name
221
+ );
222
+ return Value::Void;
223
+ };
224
+
225
+ let result = match callback
199
226
  .call(
200
227
  None,
201
228
  args.iter()
202
229
  .map(|v| super::value::to_js_unknown(&env, v).unwrap())
203
230
  .collect::<Vec<JsUnknown>>()
204
- .as_ref(),
205
- )
206
- .unwrap();
231
+ .as_ref()
232
+ ) {
233
+ Ok(result) => result,
234
+ Err(err) => {
235
+ crate::console_err!(env, "Node.js: Invoking global callback '{callback_name}' failed: {err}");
236
+ return Value::Void;
237
+ }
238
+ };
207
239
 
208
240
  if let Some(return_type) = &return_type {
209
- super::to_value(&env, result, return_type).unwrap()
241
+ if let Ok(value) = super::to_value(&env, result, return_type) {
242
+ return value;
243
+ } else {
244
+ eprintln!(
245
+ "Node.js: cannot convert return type of callback {}",
246
+ callback_name
247
+ );
248
+ return slint_interpreter::default_value_for_type(return_type);
249
+ }
210
250
  } else {
211
251
  Value::Void
212
252
  }
@@ -78,6 +78,7 @@ pub fn to_js_unknown(env: &Env, value: &Value) -> Result<JsUnknown> {
78
78
  model_wrapper.into_js(env)
79
79
  }
80
80
  }
81
+ Value::EnumerationValue(_, value) => env.create_string(value).map(|v| v.into_unknown()),
81
82
  _ => env.get_undefined().map(|v| v.into_unknown()),
82
83
  }
83
84
  }
@@ -239,7 +240,14 @@ pub fn to_value(env: &Env, unknown: JsUnknown, typ: &Type) -> Result<Value> {
239
240
  let mut vec = vec![];
240
241
 
241
242
  for i in 0..array.len() {
242
- vec.push(to_value(env, array.get(i)?.unwrap(), a)?);
243
+ vec.push(to_value(
244
+ env,
245
+ array.get(i)?.ok_or(napi::Error::from_reason(format!(
246
+ "Cannot access array element at index {}",
247
+ i
248
+ )))?,
249
+ a,
250
+ )?);
243
251
  }
244
252
  Ok(Value::Model(ModelRc::new(SharedVectorModel::from(SharedVector::from_slice(
245
253
  &vec,
@@ -250,7 +258,19 @@ pub fn to_value(env: &Env, unknown: JsUnknown, typ: &Type) -> Result<Value> {
250
258
  Ok(Value::Model(rust_model))
251
259
  }
252
260
  }
253
- Type::Enumeration(_) => todo!(),
261
+ Type::Enumeration(e) => {
262
+ let js_string: JsString = unknown.try_into()?;
263
+ let value: String = js_string.into_utf8()?.as_str()?.into();
264
+
265
+ if !e.values.contains(&value) {
266
+ return Err(napi::Error::from_reason(format!(
267
+ "{value} is not a value of enum {}",
268
+ e.name
269
+ )));
270
+ }
271
+
272
+ Ok(Value::EnumerationValue(e.name.clone(), value))
273
+ }
254
274
  Type::Invalid
255
275
  | Type::Model
256
276
  | Type::Void
package/rust/lib.rs CHANGED
@@ -7,7 +7,7 @@ pub use interpreter::*;
7
7
  mod types;
8
8
  pub use types::*;
9
9
 
10
- use napi::{Env, JsFunction};
10
+ use napi::{Env, JsFunction, JsObject};
11
11
 
12
12
  #[macro_use]
13
13
  extern crate napi_derive;
@@ -54,7 +54,10 @@ pub fn invoke_from_event_loop(env: Env, callback: JsFunction) -> napi::Result<na
54
54
  let function_ref = send_wrapper::SendWrapper::new(function_ref);
55
55
  i_slint_core::api::invoke_from_event_loop(move || {
56
56
  let function_ref = function_ref.take();
57
- let callback: JsFunction = function_ref.get().unwrap();
57
+ let Ok(callback) = function_ref.get::<JsFunction>() else {
58
+ eprintln!("Node.js: JavaScript invoke_from_event_loop threw an exception");
59
+ return;
60
+ };
58
61
  callback.call_without_args(None).ok();
59
62
  })
60
63
  .map_err(|e| napi::Error::from_reason(e.to_string()))
@@ -82,3 +85,38 @@ pub fn init_testing() {
82
85
  #[cfg(feature = "testing")]
83
86
  i_slint_backend_testing::init_integration_test_with_mock_time();
84
87
  }
88
+
89
+ pub fn print_to_console(env: Env, function: &str, arguments: core::fmt::Arguments) {
90
+ let Ok(global) = env.get_global() else {
91
+ eprintln!("Unable to obtain global object");
92
+ return;
93
+ };
94
+
95
+ let Ok(console_object) = global
96
+ .get_named_property::<JsObject>("console")
97
+ .and_then(|console| console.coerce_to_object())
98
+ else {
99
+ eprintln!("Unable to obtain console object for logging");
100
+ return;
101
+ };
102
+
103
+ let Ok(Some(log_fn)) = console_object.get::<&str, JsFunction>(function) else {
104
+ eprintln!("Unable to obtain console.{function}");
105
+ return;
106
+ };
107
+
108
+ let message = arguments.to_string();
109
+ let Ok(js_message) = env.create_string(&message) else {
110
+ eprintln!("Unable to provide log message to JS env");
111
+ return;
112
+ };
113
+
114
+ if let Err(err) = log_fn.call(None, &vec![js_message.into_unknown()]) {
115
+ eprintln!("Unable to invoke console.{function}: {err}");
116
+ }
117
+ }
118
+
119
+ #[macro_export]
120
+ macro_rules! console_err {
121
+ ($env:expr, $($t:tt)*) => ($crate::print_to_console($env, "error", format_args!($($t)*)))
122
+ }
@@ -90,7 +90,10 @@ impl Model for JsModel {
90
90
  type Data = slint_interpreter::Value;
91
91
 
92
92
  fn row_count(&self) -> usize {
93
- let model: Object = self.js_impl.get().unwrap();
93
+ let Ok(model) = self.js_impl.get::<Object>() else {
94
+ eprintln!("Node.js: JavaScript Model<T>'s rowCount threw an exception");
95
+ return 0;
96
+ };
94
97
 
95
98
  let Ok(row_count_property) = model.get::<&str, JsFunction>("rowCount") else {
96
99
  eprintln!("Node.js: JavaScript Model<T> implementation is missing rowCount property");
@@ -121,7 +124,11 @@ impl Model for JsModel {
121
124
  }
122
125
 
123
126
  fn row_data(&self, row: usize) -> Option<Self::Data> {
124
- let model: Object = self.js_impl.get().unwrap();
127
+ let Ok(model) = self.js_impl.get::<Object>() else {
128
+ eprintln!("Node.js: JavaScript Model<T>'s rowData threw an exception");
129
+ return None;
130
+ };
131
+
125
132
  let Ok(row_data_property) = model.get::<&str, JsFunction>("rowData") else {
126
133
  eprintln!("Node.js: JavaScript Model<T> implementation is missing rowData property");
127
134
  return None;
@@ -152,7 +159,10 @@ impl Model for JsModel {
152
159
  }
153
160
 
154
161
  fn set_row_data(&self, row: usize, data: Self::Data) {
155
- let model: Object = self.js_impl.get().unwrap();
162
+ let Ok(model) = self.js_impl.get::<Object>() else {
163
+ eprintln!("Node.js: JavaScript Model<T>'s setRowData threw an exception");
164
+ return;
165
+ };
156
166
 
157
167
  let Ok(set_row_data_property) = model.get::<&str, JsFunction>("setRowData") else {
158
168
  eprintln!("Node.js: JavaScript Model<T> implementation is missing setRowData property");