slint-ui 1.9.0-nightly.2024100903 → 1.9.0-nightly.2024101016
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 +4 -4
- package/README.md +73 -4
- package/cover.md +70 -0
- package/dist/index.d.ts +20 -2
- package/dist/index.js +72 -16
- package/package.json +6 -6
- package/rust/interpreter/component_compiler.rs +70 -1
- package/rust/lib.rs +8 -0
- package/rust-module.cjs +2 -1
- package/rust-module.d.ts +3 -0
- package/typescript/index.ts +271 -222
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 = "
|
|
45
|
-
i-slint-core = { features = ["default"] , git = "https://github.com/slint-ui/slint", rev = "
|
|
46
|
-
i-slint-backend-selector = { git = "https://github.com/slint-ui/slint", rev = "
|
|
47
|
-
slint-interpreter = { default-features = false , features = ["display-diagnostics", "internal", "compat-1-2"] , git = "https://github.com/slint-ui/slint", rev = "
|
|
44
|
+
i-slint-compiler = { features = ["default"] , git = "https://github.com/slint-ui/slint", rev = "ccf5f04087c5d920c80e7e706230e99a12b9e9ef", version = "=1.9.0", default-features = false }
|
|
45
|
+
i-slint-core = { features = ["default", "gettext-rs"] , git = "https://github.com/slint-ui/slint", rev = "ccf5f04087c5d920c80e7e706230e99a12b9e9ef", version = "=1.9.0", default-features = false }
|
|
46
|
+
i-slint-backend-selector = { git = "https://github.com/slint-ui/slint", rev = "ccf5f04087c5d920c80e7e706230e99a12b9e9ef", 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 = "ccf5f04087c5d920c80e7e706230e99a12b9e9ef", 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
|
@@ -57,7 +57,7 @@ Combining these two steps leads us to the obligatory "Hello World" example:
|
|
|
57
57
|
|
|
58
58
|
```js
|
|
59
59
|
import * as slint from "slint-ui";
|
|
60
|
-
let ui = slint.loadFile(".ui/main.slint");
|
|
60
|
+
let ui = slint.loadFile(new URL(".ui/main.slint", import.meta.url));
|
|
61
61
|
let main = new ui.Main();
|
|
62
62
|
main.run();
|
|
63
63
|
```
|
|
@@ -94,7 +94,7 @@ an object which allow to initialize the value of public properties or callbacks.
|
|
|
94
94
|
import * as slint from "slint-ui";
|
|
95
95
|
// In this example, the main.slint file exports a module which
|
|
96
96
|
// has a counter property and a clicked callback
|
|
97
|
-
let ui = slint.loadFile("ui/main.slint");
|
|
97
|
+
let ui = slint.loadFile(new URL("ui/main.slint", import.meta.url));
|
|
98
98
|
let component = new ui.MainWindow({
|
|
99
99
|
counter: 42,
|
|
100
100
|
clicked: function() { console.log("hello"); }
|
|
@@ -135,7 +135,7 @@ The callbacks in Slint are exposed as properties in JavaScript and that can be c
|
|
|
135
135
|
```js
|
|
136
136
|
import * as slint from "slint-ui";
|
|
137
137
|
|
|
138
|
-
let ui = slint.loadFile("ui/my-component.slint");
|
|
138
|
+
let ui = slint.loadFile(new URL("ui/my-component.slint", import.meta.url));
|
|
139
139
|
let component = new ui.MyComponent();
|
|
140
140
|
|
|
141
141
|
// connect to a callback
|
|
@@ -168,7 +168,7 @@ If the function is marked `public`, it can also be called from JavaScript.
|
|
|
168
168
|
```js
|
|
169
169
|
import * as slint from "slint-ui";
|
|
170
170
|
|
|
171
|
-
let ui = slint.loadFile("ui/my-component.slint");
|
|
171
|
+
let ui = slint.loadFile(new URL("ui/my-component.slint", import.meta.url));
|
|
172
172
|
let component = new ui.MyComponent();
|
|
173
173
|
|
|
174
174
|
// call a public function
|
|
@@ -273,3 +273,72 @@ model.push(4); // this works
|
|
|
273
273
|
// does NOT work, getting the model does not return the right object
|
|
274
274
|
// component.model.push(5);
|
|
275
275
|
```
|
|
276
|
+
|
|
277
|
+
### structs
|
|
278
|
+
|
|
279
|
+
An exported struct can be created either by defing of an object literal or by using the new keyword.
|
|
280
|
+
|
|
281
|
+
**`my-component.slint`**
|
|
282
|
+
|
|
283
|
+
```slint
|
|
284
|
+
export struct Person {
|
|
285
|
+
name: string,
|
|
286
|
+
age: int
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export component MyComponent inherits Window {
|
|
290
|
+
in-out property <Person> person;
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**`main.js`**
|
|
295
|
+
|
|
296
|
+
```js
|
|
297
|
+
|
|
298
|
+
import * as slint from "slint-ui";
|
|
299
|
+
|
|
300
|
+
let ui = slint.loadFile(new URL("my-component.slint", import.meta.url));
|
|
301
|
+
let component = new ui.MyComponent();
|
|
302
|
+
|
|
303
|
+
// object literal
|
|
304
|
+
component.person = { name: "Peter", age: 22 };
|
|
305
|
+
|
|
306
|
+
// new keyword (sets property values to default e.g. '' for string)
|
|
307
|
+
component.person = new ui.Person();
|
|
308
|
+
|
|
309
|
+
// new keyword with parameters
|
|
310
|
+
component.person = new ui.Person({ name: "Tim", age: 30 });
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### enums
|
|
314
|
+
|
|
315
|
+
A value of an exported enum can be set as string or by usign the value from the exported enum.
|
|
316
|
+
|
|
317
|
+
**`my-component.slint`**
|
|
318
|
+
|
|
319
|
+
```slint
|
|
320
|
+
export enum Position {
|
|
321
|
+
top,
|
|
322
|
+
bottom
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export component MyComponent inherits Window {
|
|
326
|
+
in-out property <Position> position;
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**`main.js`**
|
|
331
|
+
|
|
332
|
+
```js
|
|
333
|
+
|
|
334
|
+
import * as slint from "slint-ui";
|
|
335
|
+
|
|
336
|
+
let ui = slint.loadFile(new URL("my-component.slint", import.meta.url));
|
|
337
|
+
let component = new ui.MyComponent();
|
|
338
|
+
|
|
339
|
+
// set enum value as string
|
|
340
|
+
component.position = "top";
|
|
341
|
+
|
|
342
|
+
// use the value of the enum
|
|
343
|
+
component.position = ui.Position.bottom;
|
|
344
|
+
```
|
package/cover.md
CHANGED
|
@@ -271,6 +271,75 @@ component.model = component.model.concat(4);
|
|
|
271
271
|
|
|
272
272
|
Another option is to set an object that implements the {@link Model} interface.
|
|
273
273
|
|
|
274
|
+
### structs
|
|
275
|
+
|
|
276
|
+
An exported struct can be created either by defing of an object literal or by using the new keyword.
|
|
277
|
+
|
|
278
|
+
**`my-component.slint`**
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
export struct Person {
|
|
282
|
+
name: string,
|
|
283
|
+
age: int
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export component MyComponent inherits Window {
|
|
287
|
+
in-out property <Person> person;
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**`main.js`**
|
|
292
|
+
|
|
293
|
+
```js
|
|
294
|
+
|
|
295
|
+
import * as slint from "slint-ui";
|
|
296
|
+
|
|
297
|
+
let ui = slint.loadFile("my-component.slint");
|
|
298
|
+
let component = new ui.MyComponent();
|
|
299
|
+
|
|
300
|
+
// object literal
|
|
301
|
+
component.person = { name: "Peter", age: 22 };
|
|
302
|
+
|
|
303
|
+
// new keyword (sets property values to default e.g. '' for string)
|
|
304
|
+
component.person = new ui.Person();
|
|
305
|
+
|
|
306
|
+
// new keyword with parameters
|
|
307
|
+
component.person = new ui.Person({ name: "Tim", age: 30 });
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### enums
|
|
311
|
+
|
|
312
|
+
A value of an exported enum can be set as string or by usign the value from the exported enum.
|
|
313
|
+
|
|
314
|
+
**`my-component.slint`**
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
export enum Position {
|
|
318
|
+
top,
|
|
319
|
+
bottom
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export component MyComponent inherits Window {
|
|
323
|
+
in-out property <Position> position;
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**`main.js`**
|
|
328
|
+
|
|
329
|
+
```js
|
|
330
|
+
|
|
331
|
+
import * as slint from "slint-ui";
|
|
332
|
+
|
|
333
|
+
let ui = slint.loadFile("my-component.slint");
|
|
334
|
+
let component = new ui.MyComponent();
|
|
335
|
+
|
|
336
|
+
// set enum value as string
|
|
337
|
+
component.position = "top";
|
|
338
|
+
|
|
339
|
+
// use the value of the enum
|
|
340
|
+
component.position = ui.Position.bottom;
|
|
341
|
+
```
|
|
342
|
+
|
|
274
343
|
### Globals
|
|
275
344
|
|
|
276
345
|
You can declare [globally available singletons](../slint/src/language/syntax/globals) in your
|
|
@@ -302,3 +371,4 @@ component.Logic.to_upper_case = (str) => {
|
|
|
302
371
|
|
|
303
372
|
**Note**: Global singletons are instantiated once per component. When declaring multiple components for `export` to JavaScript,
|
|
304
373
|
each instance will have their own instance of associated globals singletons.
|
|
374
|
+
|
package/dist/index.d.ts
CHANGED
|
@@ -194,7 +194,7 @@ export interface LoadFileOptions {
|
|
|
194
194
|
* main.greeting = "Hello friends";
|
|
195
195
|
* ```
|
|
196
196
|
*
|
|
197
|
-
* @param filePath The path to the file to load
|
|
197
|
+
* @param filePath The path to the file to load as `string` or `URL`. Relative paths are resolved against the process' current working directory.
|
|
198
198
|
* @param options An optional {@link LoadFileOptions} to configure additional Slint compilation settings,
|
|
199
199
|
* such as include search paths, library imports, or the widget style.
|
|
200
200
|
* @returns Returns an object that is immutable and provides a constructor function for each exported Window component found in the `.slint` file.
|
|
@@ -203,7 +203,7 @@ export interface LoadFileOptions {
|
|
|
203
203
|
* For further information on the available properties, refer to [Instantiating A Component](../index.html#md:instantiating-a-component).
|
|
204
204
|
* @throws {@link CompileError} if errors occur during compilation.
|
|
205
205
|
*/
|
|
206
|
-
export declare function loadFile(filePath: string, options?: LoadFileOptions): Object;
|
|
206
|
+
export declare function loadFile(filePath: string | URL, options?: LoadFileOptions): Object;
|
|
207
207
|
/**
|
|
208
208
|
* Loads the given Slint source code and returns an object that contains a functions to construct the exported
|
|
209
209
|
* components of the Slint source code.
|
|
@@ -404,6 +404,24 @@ export declare namespace private_api {
|
|
|
404
404
|
rowData(row: number): U | undefined;
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
|
+
/**
|
|
408
|
+
* Initialize translations.
|
|
409
|
+
*
|
|
410
|
+
* Call this with the path where translations are located. This function internally calls the [bindtextdomain](https://man7.org/linux/man-pages/man3/bindtextdomain.3.html) function from gettext.
|
|
411
|
+
*
|
|
412
|
+
* Translations are expected to be found at <path>/<locale>/LC_MESSAGES/<domain>.mo, where path is the directory passed as an argument to this function, locale is a locale name (e.g., en, en_GB, fr), and domain is the package name.
|
|
413
|
+
*
|
|
414
|
+
* @param domain defines the domain name e.g. name of the package.
|
|
415
|
+
* @param path specifies the directory as `string` or as `URL` in which gettext should search for translations.
|
|
416
|
+
*
|
|
417
|
+
* For example, assuming this is in a package called example and the default locale is configured to be French, it will load translations at runtime from ``/path/to/example/translations/fr/LC_MESSAGES/example.mo`.
|
|
418
|
+
*
|
|
419
|
+
* ```js
|
|
420
|
+
* import * as slint from "slint-ui";
|
|
421
|
+
* slint.initTranslations("example", new URL("translations/", import.meta.url));
|
|
422
|
+
* ````
|
|
423
|
+
*/
|
|
424
|
+
export declare function initTranslations(domain: string, path: string | URL): void;
|
|
407
425
|
/**
|
|
408
426
|
* @hidden
|
|
409
427
|
*/
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
3
3
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.private_api = exports.quitEventLoop = exports.runEventLoop = exports.loadSource = exports.loadFile = exports.CompileError = exports.ArrayModel = exports.Model = exports.Brush = exports.RgbaColor = exports.DiagnosticLevel = exports.Diagnostic = void 0;
|
|
5
|
+
exports.initTranslations = exports.private_api = exports.quitEventLoop = exports.runEventLoop = exports.loadSource = exports.loadFile = exports.CompileError = exports.ArrayModel = exports.Model = exports.Brush = exports.RgbaColor = exports.DiagnosticLevel = exports.Diagnostic = void 0;
|
|
6
6
|
const napi = require("../rust-module.cjs");
|
|
7
7
|
var rust_module_cjs_1 = require("../rust-module.cjs");
|
|
8
8
|
Object.defineProperty(exports, "Diagnostic", { enumerable: true, get: function () { return rust_module_cjs_1.Diagnostic; } });
|
|
@@ -72,6 +72,9 @@ class CompileError extends Error {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
exports.CompileError = CompileError;
|
|
75
|
+
function translateName(key) {
|
|
76
|
+
return key.replace(/-/g, "_");
|
|
77
|
+
}
|
|
75
78
|
function loadSlint(loadData) {
|
|
76
79
|
const { filePath, options } = loadData.fileData;
|
|
77
80
|
const compiler = new napi.ComponentCompiler();
|
|
@@ -101,14 +104,44 @@ function loadSlint(loadData) {
|
|
|
101
104
|
}
|
|
102
105
|
}
|
|
103
106
|
const slint_module = Object.create({});
|
|
107
|
+
// generate structs
|
|
108
|
+
const structs = compiler.structs;
|
|
109
|
+
for (const key in compiler.structs) {
|
|
110
|
+
Object.defineProperty(slint_module, translateName(key), {
|
|
111
|
+
value: function (properties) {
|
|
112
|
+
const defaultObject = structs[key];
|
|
113
|
+
const newObject = Object.create({});
|
|
114
|
+
for (const propertyKey in defaultObject) {
|
|
115
|
+
const propertyName = translateName(propertyKey);
|
|
116
|
+
const propertyValue = properties !== undefined &&
|
|
117
|
+
Object.hasOwn(properties, propertyName)
|
|
118
|
+
? properties[propertyName]
|
|
119
|
+
: defaultObject[propertyKey];
|
|
120
|
+
Object.defineProperty(newObject, propertyName, {
|
|
121
|
+
value: propertyValue,
|
|
122
|
+
writable: true,
|
|
123
|
+
enumerable: true,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return Object.seal(newObject);
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// generate enums
|
|
131
|
+
const enums = compiler.enums;
|
|
132
|
+
for (const key in enums) {
|
|
133
|
+
Object.defineProperty(slint_module, translateName(key), {
|
|
134
|
+
value: Object.seal(enums[key]),
|
|
135
|
+
enumerable: true,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
104
138
|
Object.keys(definitions).forEach((key) => {
|
|
105
139
|
const definition = definitions[key];
|
|
106
|
-
Object.defineProperty(slint_module, definition.name
|
|
140
|
+
Object.defineProperty(slint_module, translateName(definition.name), {
|
|
107
141
|
value: function (properties) {
|
|
108
142
|
const instance = definition.create();
|
|
109
143
|
if (instance == null) {
|
|
110
|
-
throw Error("Could not create a component handle for" +
|
|
111
|
-
filePath);
|
|
144
|
+
throw Error("Could not create a component handle for" + filePath);
|
|
112
145
|
}
|
|
113
146
|
for (var key in properties) {
|
|
114
147
|
const value = properties[key];
|
|
@@ -121,7 +154,7 @@ function loadSlint(loadData) {
|
|
|
121
154
|
}
|
|
122
155
|
const componentHandle = new Component(instance);
|
|
123
156
|
instance.definition().properties.forEach((prop) => {
|
|
124
|
-
const propName = prop.name
|
|
157
|
+
const propName = translateName(prop.name);
|
|
125
158
|
if (componentHandle[propName] !== undefined) {
|
|
126
159
|
console.warn("Duplicated property name " + propName);
|
|
127
160
|
}
|
|
@@ -138,12 +171,12 @@ function loadSlint(loadData) {
|
|
|
138
171
|
}
|
|
139
172
|
});
|
|
140
173
|
instance.definition().callbacks.forEach((cb) => {
|
|
141
|
-
const callbackName = cb
|
|
174
|
+
const callbackName = translateName(cb);
|
|
142
175
|
if (componentHandle[callbackName] !== undefined) {
|
|
143
176
|
console.warn("Duplicated callback name " + callbackName);
|
|
144
177
|
}
|
|
145
178
|
else {
|
|
146
|
-
Object.defineProperty(componentHandle, cb
|
|
179
|
+
Object.defineProperty(componentHandle, translateName(cb), {
|
|
147
180
|
get() {
|
|
148
181
|
return function () {
|
|
149
182
|
return instance.invoke(cb, Array.from(arguments));
|
|
@@ -157,12 +190,12 @@ function loadSlint(loadData) {
|
|
|
157
190
|
}
|
|
158
191
|
});
|
|
159
192
|
instance.definition().functions.forEach((cb) => {
|
|
160
|
-
const functionName = cb
|
|
193
|
+
const functionName = translateName(cb);
|
|
161
194
|
if (componentHandle[functionName] !== undefined) {
|
|
162
195
|
console.warn("Duplicated function name " + functionName);
|
|
163
196
|
}
|
|
164
197
|
else {
|
|
165
|
-
Object.defineProperty(componentHandle, cb
|
|
198
|
+
Object.defineProperty(componentHandle, translateName(cb), {
|
|
166
199
|
get() {
|
|
167
200
|
return function () {
|
|
168
201
|
return instance.invoke(cb, Array.from(arguments));
|
|
@@ -183,7 +216,7 @@ function loadSlint(loadData) {
|
|
|
183
216
|
.definition()
|
|
184
217
|
.globalProperties(globalName)
|
|
185
218
|
.forEach((prop) => {
|
|
186
|
-
const propName = prop.name
|
|
219
|
+
const propName = translateName(prop.name);
|
|
187
220
|
if (globalObject[propName] !== undefined) {
|
|
188
221
|
console.warn("Duplicated property name " +
|
|
189
222
|
propName +
|
|
@@ -206,7 +239,7 @@ function loadSlint(loadData) {
|
|
|
206
239
|
.definition()
|
|
207
240
|
.globalCallbacks(globalName)
|
|
208
241
|
.forEach((cb) => {
|
|
209
|
-
const callbackName = cb
|
|
242
|
+
const callbackName = translateName(cb);
|
|
210
243
|
if (globalObject[callbackName] !== undefined) {
|
|
211
244
|
console.warn("Duplicated property name " +
|
|
212
245
|
cb +
|
|
@@ -214,7 +247,7 @@ function loadSlint(loadData) {
|
|
|
214
247
|
global);
|
|
215
248
|
}
|
|
216
249
|
else {
|
|
217
|
-
Object.defineProperty(globalObject, cb
|
|
250
|
+
Object.defineProperty(globalObject, translateName(cb), {
|
|
218
251
|
get() {
|
|
219
252
|
return function () {
|
|
220
253
|
return instance.invokeGlobal(globalName, cb, Array.from(arguments));
|
|
@@ -231,7 +264,7 @@ function loadSlint(loadData) {
|
|
|
231
264
|
.definition()
|
|
232
265
|
.globalFunctions(globalName)
|
|
233
266
|
.forEach((cb) => {
|
|
234
|
-
const functionName = cb
|
|
267
|
+
const functionName = translateName(cb);
|
|
235
268
|
if (globalObject[functionName] !== undefined) {
|
|
236
269
|
console.warn("Duplicated function name " +
|
|
237
270
|
cb +
|
|
@@ -239,7 +272,7 @@ function loadSlint(loadData) {
|
|
|
239
272
|
global);
|
|
240
273
|
}
|
|
241
274
|
else {
|
|
242
|
-
Object.defineProperty(globalObject, cb
|
|
275
|
+
Object.defineProperty(globalObject, translateName(cb), {
|
|
243
276
|
get() {
|
|
244
277
|
return function () {
|
|
245
278
|
return instance.invokeGlobal(globalName, cb, Array.from(arguments));
|
|
@@ -286,7 +319,7 @@ function loadSlint(loadData) {
|
|
|
286
319
|
* main.greeting = "Hello friends";
|
|
287
320
|
* ```
|
|
288
321
|
*
|
|
289
|
-
* @param filePath The path to the file to load
|
|
322
|
+
* @param filePath The path to the file to load as `string` or `URL`. Relative paths are resolved against the process' current working directory.
|
|
290
323
|
* @param options An optional {@link LoadFileOptions} to configure additional Slint compilation settings,
|
|
291
324
|
* such as include search paths, library imports, or the widget style.
|
|
292
325
|
* @returns Returns an object that is immutable and provides a constructor function for each exported Window component found in the `.slint` file.
|
|
@@ -296,8 +329,9 @@ function loadSlint(loadData) {
|
|
|
296
329
|
* @throws {@link CompileError} if errors occur during compilation.
|
|
297
330
|
*/
|
|
298
331
|
function loadFile(filePath, options) {
|
|
332
|
+
const pathname = filePath instanceof URL ? filePath.pathname : filePath;
|
|
299
333
|
return loadSlint({
|
|
300
|
-
fileData: { filePath, options },
|
|
334
|
+
fileData: { filePath: pathname, options },
|
|
301
335
|
from: "file",
|
|
302
336
|
});
|
|
303
337
|
}
|
|
@@ -570,6 +604,28 @@ var private_api;
|
|
|
570
604
|
}
|
|
571
605
|
private_api.MapModel = MapModel;
|
|
572
606
|
})(private_api || (exports.private_api = private_api = {}));
|
|
607
|
+
/**
|
|
608
|
+
* Initialize translations.
|
|
609
|
+
*
|
|
610
|
+
* Call this with the path where translations are located. This function internally calls the [bindtextdomain](https://man7.org/linux/man-pages/man3/bindtextdomain.3.html) function from gettext.
|
|
611
|
+
*
|
|
612
|
+
* Translations are expected to be found at <path>/<locale>/LC_MESSAGES/<domain>.mo, where path is the directory passed as an argument to this function, locale is a locale name (e.g., en, en_GB, fr), and domain is the package name.
|
|
613
|
+
*
|
|
614
|
+
* @param domain defines the domain name e.g. name of the package.
|
|
615
|
+
* @param path specifies the directory as `string` or as `URL` in which gettext should search for translations.
|
|
616
|
+
*
|
|
617
|
+
* For example, assuming this is in a package called example and the default locale is configured to be French, it will load translations at runtime from ``/path/to/example/translations/fr/LC_MESSAGES/example.mo`.
|
|
618
|
+
*
|
|
619
|
+
* ```js
|
|
620
|
+
* import * as slint from "slint-ui";
|
|
621
|
+
* slint.initTranslations("example", new URL("translations/", import.meta.url));
|
|
622
|
+
* ````
|
|
623
|
+
*/
|
|
624
|
+
function initTranslations(domain, path) {
|
|
625
|
+
const pathname = path instanceof URL ? path.pathname : path;
|
|
626
|
+
napi.initTranslations(domain, pathname);
|
|
627
|
+
}
|
|
628
|
+
exports.initTranslations = initTranslations;
|
|
573
629
|
/**
|
|
574
630
|
* @hidden
|
|
575
631
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slint-ui",
|
|
3
|
-
"version": "1.9.0-nightly.
|
|
3
|
+
"version": "1.9.0-nightly.2024101016",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"homepage": "https://github.com/slint-ui/slint",
|
|
@@ -67,10 +67,10 @@
|
|
|
67
67
|
"@napi-rs/cli": "2.16.5"
|
|
68
68
|
},
|
|
69
69
|
"optionalDependencies": {
|
|
70
|
-
"@slint-ui/slint-ui-binary-linux-x64-gnu": "1.9.0-nightly.
|
|
71
|
-
"@slint-ui/slint-ui-binary-darwin-x64": "1.9.0-nightly.
|
|
72
|
-
"@slint-ui/slint-ui-binary-darwin-arm64": "1.9.0-nightly.
|
|
73
|
-
"@slint-ui/slint-ui-binary-win32-x64-msvc": "1.9.0-nightly.
|
|
74
|
-
"@slint-ui/slint-ui-binary-win32-ia32-msvc": "1.9.0-nightly.
|
|
70
|
+
"@slint-ui/slint-ui-binary-linux-x64-gnu": "1.9.0-nightly.2024101016",
|
|
71
|
+
"@slint-ui/slint-ui-binary-darwin-x64": "1.9.0-nightly.2024101016",
|
|
72
|
+
"@slint-ui/slint-ui-binary-darwin-arm64": "1.9.0-nightly.2024101016",
|
|
73
|
+
"@slint-ui/slint-ui-binary-win32-x64-msvc": "1.9.0-nightly.2024101016",
|
|
74
|
+
"@slint-ui/slint-ui-binary-win32-ia32-msvc": "1.9.0-nightly.2024101016"
|
|
75
75
|
}
|
|
76
76
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
2
2
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
|
3
3
|
|
|
4
|
+
use crate::to_js_unknown;
|
|
5
|
+
|
|
4
6
|
use super::JsComponentDefinition;
|
|
5
7
|
use super::JsDiagnostic;
|
|
8
|
+
use i_slint_compiler::langtype::Type;
|
|
6
9
|
use itertools::Itertools;
|
|
10
|
+
use napi::Env;
|
|
11
|
+
use napi::JsUnknown;
|
|
7
12
|
use slint_interpreter::Compiler;
|
|
13
|
+
use slint_interpreter::Value;
|
|
8
14
|
use std::collections::HashMap;
|
|
9
15
|
use std::path::PathBuf;
|
|
10
16
|
|
|
@@ -13,6 +19,7 @@ use std::path::PathBuf;
|
|
|
13
19
|
#[napi(js_name = "ComponentCompiler")]
|
|
14
20
|
pub struct JsComponentCompiler {
|
|
15
21
|
internal: Compiler,
|
|
22
|
+
structs_and_enums: Vec<Type>,
|
|
16
23
|
diagnostics: Vec<slint_interpreter::Diagnostic>,
|
|
17
24
|
}
|
|
18
25
|
|
|
@@ -44,7 +51,7 @@ impl JsComponentCompiler {
|
|
|
44
51
|
|
|
45
52
|
compiler.set_include_paths(include_paths);
|
|
46
53
|
compiler.set_library_paths(library_paths);
|
|
47
|
-
Self { internal: compiler, diagnostics: vec![] }
|
|
54
|
+
Self { internal: compiler, diagnostics: vec![], structs_and_enums: vec![] }
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
#[napi(setter)]
|
|
@@ -99,12 +106,72 @@ impl JsComponentCompiler {
|
|
|
99
106
|
self.diagnostics.iter().map(|d| JsDiagnostic::from(d.clone())).collect()
|
|
100
107
|
}
|
|
101
108
|
|
|
109
|
+
#[napi(getter)]
|
|
110
|
+
pub fn structs(&self, env: Env) -> HashMap<String, JsUnknown> {
|
|
111
|
+
fn convert_type(env: &Env, ty: &Type) -> Option<(String, JsUnknown)> {
|
|
112
|
+
match ty {
|
|
113
|
+
Type::Struct { fields, name: Some(name), node: Some(_), .. } => {
|
|
114
|
+
let struct_instance = to_js_unknown(
|
|
115
|
+
env,
|
|
116
|
+
&Value::Struct(slint_interpreter::Struct::from_iter(fields.iter().map(
|
|
117
|
+
|(name, field_type)| {
|
|
118
|
+
(
|
|
119
|
+
name.to_string(),
|
|
120
|
+
slint_interpreter::default_value_for_type(field_type),
|
|
121
|
+
)
|
|
122
|
+
},
|
|
123
|
+
))),
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
return Some((name.to_string(), struct_instance.ok()?));
|
|
127
|
+
}
|
|
128
|
+
_ => return None,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
self.structs_and_enums
|
|
133
|
+
.iter()
|
|
134
|
+
.filter_map(|ty| convert_type(&env, ty))
|
|
135
|
+
.into_iter()
|
|
136
|
+
.collect::<HashMap<String, JsUnknown>>()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#[napi(getter)]
|
|
140
|
+
pub fn enums(&self, env: Env) -> HashMap<String, JsUnknown> {
|
|
141
|
+
fn convert_type(env: &Env, ty: &Type) -> Option<(String, JsUnknown)> {
|
|
142
|
+
match ty {
|
|
143
|
+
Type::Enumeration(en) => {
|
|
144
|
+
let mut o = env.create_object().ok()?;
|
|
145
|
+
|
|
146
|
+
for value in en.values.iter() {
|
|
147
|
+
let value = value.replace('-', "_");
|
|
148
|
+
o.set_property(
|
|
149
|
+
env.create_string(&value).ok()?,
|
|
150
|
+
env.create_string(&value).ok()?.into_unknown(),
|
|
151
|
+
)
|
|
152
|
+
.ok()?;
|
|
153
|
+
}
|
|
154
|
+
return Some((en.name.clone(), o.into_unknown()));
|
|
155
|
+
}
|
|
156
|
+
_ => return None,
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
self.structs_and_enums
|
|
161
|
+
.iter()
|
|
162
|
+
.filter_map(|ty| convert_type(&env, ty))
|
|
163
|
+
.into_iter()
|
|
164
|
+
.collect::<HashMap<String, JsUnknown>>()
|
|
165
|
+
}
|
|
166
|
+
|
|
102
167
|
/// Compile a .slint file into a ComponentDefinition
|
|
103
168
|
///
|
|
104
169
|
/// Returns the compiled `ComponentDefinition` if there were no errors.
|
|
105
170
|
#[napi]
|
|
106
171
|
pub fn build_from_path(&mut self, path: String) -> HashMap<String, JsComponentDefinition> {
|
|
107
172
|
let r = spin_on::spin_on(self.internal.build_from_path(PathBuf::from(path)));
|
|
173
|
+
self.structs_and_enums =
|
|
174
|
+
r.structs_and_enums(i_slint_core::InternalToken {}).cloned().collect::<Vec<_>>();
|
|
108
175
|
self.diagnostics = r.diagnostics().collect();
|
|
109
176
|
r.components().map(|c| (c.name().to_owned(), c.into())).collect()
|
|
110
177
|
}
|
|
@@ -118,6 +185,8 @@ impl JsComponentCompiler {
|
|
|
118
185
|
) -> HashMap<String, JsComponentDefinition> {
|
|
119
186
|
let r = spin_on::spin_on(self.internal.build_from_source(source_code, PathBuf::from(path)));
|
|
120
187
|
self.diagnostics = r.diagnostics().collect();
|
|
188
|
+
self.structs_and_enums =
|
|
189
|
+
r.structs_and_enums(i_slint_core::InternalToken {}).cloned().collect::<Vec<_>>();
|
|
121
190
|
r.components().map(|c| (c.name().to_owned(), c.into())).collect()
|
|
122
191
|
}
|
|
123
192
|
}
|
package/rust/lib.rs
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
|
3
3
|
|
|
4
4
|
mod interpreter;
|
|
5
|
+
use std::path::PathBuf;
|
|
6
|
+
|
|
5
7
|
pub use interpreter::*;
|
|
6
8
|
|
|
7
9
|
mod types;
|
|
@@ -86,6 +88,12 @@ pub fn init_testing() {
|
|
|
86
88
|
i_slint_backend_testing::init_integration_test_with_mock_time();
|
|
87
89
|
}
|
|
88
90
|
|
|
91
|
+
#[napi]
|
|
92
|
+
pub fn init_translations(domain: String, dir_name: String) -> napi::Result<()> {
|
|
93
|
+
i_slint_core::translations::gettext_bindtextdomain(domain.as_str(), PathBuf::from(dir_name))
|
|
94
|
+
.map_err(|e| napi::Error::from_reason(e.to_string()))
|
|
95
|
+
}
|
|
96
|
+
|
|
89
97
|
pub fn print_to_console(env: Env, function: &str, arguments: core::fmt::Arguments) {
|
|
90
98
|
let Ok(global) = env.get_global() else {
|
|
91
99
|
eprintln!("Unable to obtain global object");
|
package/rust-module.cjs
CHANGED
|
@@ -252,7 +252,7 @@ if (!nativeBinding) {
|
|
|
252
252
|
throw new Error(`Failed to load native binding`)
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
const { DiagnosticLevel, ComponentCompiler, ComponentDefinition, ComponentInstance, ValueType, Property, Window, SlintRgbaColor, SlintBrush, SlintImageData, SharedModelNotify, jsModelNotifyNew, jsModelNotifyRowDataChanged, jsModelNotifyRowAdded, jsModelNotifyRowRemoved, jsModelNotifyReset, ReadOnlyRustModel, ModelIterator, SlintPoint, SlintSize, mockElapsedTime, getMockedTime, ProcessEventsResult, processEvents, invokeFromEventLoop, setQuitOnLastWindowClosed, initTesting } = nativeBinding
|
|
255
|
+
const { DiagnosticLevel, ComponentCompiler, ComponentDefinition, ComponentInstance, ValueType, Property, Window, SlintRgbaColor, SlintBrush, SlintImageData, SharedModelNotify, jsModelNotifyNew, jsModelNotifyRowDataChanged, jsModelNotifyRowAdded, jsModelNotifyRowRemoved, jsModelNotifyReset, ReadOnlyRustModel, ModelIterator, SlintPoint, SlintSize, mockElapsedTime, getMockedTime, ProcessEventsResult, processEvents, invokeFromEventLoop, setQuitOnLastWindowClosed, initTesting, initTranslations } = nativeBinding
|
|
256
256
|
|
|
257
257
|
module.exports.DiagnosticLevel = DiagnosticLevel
|
|
258
258
|
module.exports.ComponentCompiler = ComponentCompiler
|
|
@@ -281,3 +281,4 @@ module.exports.processEvents = processEvents
|
|
|
281
281
|
module.exports.invokeFromEventLoop = invokeFromEventLoop
|
|
282
282
|
module.exports.setQuitOnLastWindowClosed = setQuitOnLastWindowClosed
|
|
283
283
|
module.exports.initTesting = initTesting
|
|
284
|
+
module.exports.initTranslations = initTranslations
|
package/rust-module.d.ts
CHANGED
|
@@ -83,6 +83,7 @@ export declare function processEvents(): ProcessEventsResult
|
|
|
83
83
|
export declare function invokeFromEventLoop(callback: (...args: any[]) => any): void
|
|
84
84
|
export declare function setQuitOnLastWindowClosed(quitOnLastWindowClosed: boolean): void
|
|
85
85
|
export declare function initTesting(): void
|
|
86
|
+
export declare function initTranslations(domain: string, dirName: string): void
|
|
86
87
|
export type JsComponentCompiler = ComponentCompiler
|
|
87
88
|
/**
|
|
88
89
|
* ComponentCompiler is the entry point to the Slint interpreter that can be used
|
|
@@ -98,6 +99,8 @@ export class ComponentCompiler {
|
|
|
98
99
|
set style(style: string)
|
|
99
100
|
get style(): string | null
|
|
100
101
|
get diagnostics(): Array<Diagnostic>
|
|
102
|
+
get structs(): Record<string, unknown>
|
|
103
|
+
get enums(): Record<string, unknown>
|
|
101
104
|
/**
|
|
102
105
|
* Compile a .slint file into a ComponentDefinition
|
|
103
106
|
*
|
package/typescript/index.ts
CHANGED
|
@@ -266,6 +266,10 @@ type LoadData =
|
|
|
266
266
|
from: "source";
|
|
267
267
|
};
|
|
268
268
|
|
|
269
|
+
function translateName(key: string): string {
|
|
270
|
+
return key.replace(/-/g, "_");
|
|
271
|
+
}
|
|
272
|
+
|
|
269
273
|
function loadSlint(loadData: LoadData): Object {
|
|
270
274
|
const { filePath, options } = loadData.fileData;
|
|
271
275
|
|
|
@@ -309,252 +313,271 @@ function loadSlint(loadData: LoadData): Object {
|
|
|
309
313
|
|
|
310
314
|
const slint_module = Object.create({});
|
|
311
315
|
|
|
316
|
+
// generate structs
|
|
317
|
+
const structs = compiler.structs;
|
|
318
|
+
|
|
319
|
+
for (const key in compiler.structs) {
|
|
320
|
+
Object.defineProperty(slint_module, translateName(key), {
|
|
321
|
+
value: function (properties: any) {
|
|
322
|
+
const defaultObject = structs[key];
|
|
323
|
+
const newObject = Object.create({});
|
|
324
|
+
|
|
325
|
+
for (const propertyKey in defaultObject) {
|
|
326
|
+
const propertyName = translateName(propertyKey);
|
|
327
|
+
const propertyValue =
|
|
328
|
+
properties !== undefined &&
|
|
329
|
+
Object.hasOwn(properties, propertyName)
|
|
330
|
+
? properties[propertyName]
|
|
331
|
+
: defaultObject[propertyKey];
|
|
332
|
+
|
|
333
|
+
Object.defineProperty(newObject, propertyName, {
|
|
334
|
+
value: propertyValue,
|
|
335
|
+
writable: true,
|
|
336
|
+
enumerable: true,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return Object.seal(newObject);
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// generate enums
|
|
346
|
+
const enums = compiler.enums;
|
|
347
|
+
|
|
348
|
+
for (const key in enums) {
|
|
349
|
+
Object.defineProperty(slint_module, translateName(key), {
|
|
350
|
+
value: Object.seal(enums[key]),
|
|
351
|
+
enumerable: true,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
|
|
312
355
|
Object.keys(definitions).forEach((key) => {
|
|
313
356
|
const definition = definitions[key];
|
|
314
357
|
|
|
315
|
-
Object.defineProperty(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
"Could not create a component handle for" +
|
|
325
|
-
filePath,
|
|
326
|
-
);
|
|
327
|
-
}
|
|
358
|
+
Object.defineProperty(slint_module, translateName(definition.name), {
|
|
359
|
+
value: function (properties: any) {
|
|
360
|
+
const instance = definition.create();
|
|
361
|
+
|
|
362
|
+
if (instance == null) {
|
|
363
|
+
throw Error(
|
|
364
|
+
"Could not create a component handle for" + filePath,
|
|
365
|
+
);
|
|
366
|
+
}
|
|
328
367
|
|
|
329
|
-
|
|
330
|
-
|
|
368
|
+
for (var key in properties) {
|
|
369
|
+
const value = properties[key];
|
|
331
370
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
371
|
+
if (value instanceof Function) {
|
|
372
|
+
instance.setCallback(key, value);
|
|
373
|
+
} else {
|
|
374
|
+
instance.setProperty(key, properties[key]);
|
|
337
375
|
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const componentHandle = new Component(instance!);
|
|
379
|
+
instance!.definition().properties.forEach((prop) => {
|
|
380
|
+
const propName = translateName(prop.name);
|
|
381
|
+
|
|
382
|
+
if (componentHandle[propName] !== undefined) {
|
|
383
|
+
console.warn("Duplicated property name " + propName);
|
|
384
|
+
} else {
|
|
385
|
+
Object.defineProperty(componentHandle, propName, {
|
|
386
|
+
get() {
|
|
387
|
+
return instance!.getProperty(prop.name);
|
|
388
|
+
},
|
|
389
|
+
set(value) {
|
|
390
|
+
instance!.setProperty(prop.name, value);
|
|
391
|
+
},
|
|
392
|
+
enumerable: true,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
});
|
|
338
396
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const propName = prop.name.replace(/-/g, "_");
|
|
397
|
+
instance!.definition().callbacks.forEach((cb) => {
|
|
398
|
+
const callbackName = translateName(cb);
|
|
342
399
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
400
|
+
if (componentHandle[callbackName] !== undefined) {
|
|
401
|
+
console.warn(
|
|
402
|
+
"Duplicated callback name " + callbackName,
|
|
403
|
+
);
|
|
404
|
+
} else {
|
|
405
|
+
Object.defineProperty(
|
|
406
|
+
componentHandle,
|
|
407
|
+
translateName(cb),
|
|
408
|
+
{
|
|
349
409
|
get() {
|
|
350
|
-
return
|
|
410
|
+
return function () {
|
|
411
|
+
return instance!.invoke(
|
|
412
|
+
cb,
|
|
413
|
+
Array.from(arguments),
|
|
414
|
+
);
|
|
415
|
+
};
|
|
351
416
|
},
|
|
352
|
-
set(
|
|
353
|
-
instance!.
|
|
417
|
+
set(callback) {
|
|
418
|
+
instance!.setCallback(cb, callback);
|
|
354
419
|
},
|
|
355
420
|
enumerable: true,
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
}
|
|
421
|
+
},
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
});
|
|
359
425
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (componentHandle[callbackName] !== undefined) {
|
|
364
|
-
console.warn(
|
|
365
|
-
"Duplicated callback name " + callbackName,
|
|
366
|
-
);
|
|
367
|
-
} else {
|
|
368
|
-
Object.defineProperty(
|
|
369
|
-
componentHandle,
|
|
370
|
-
cb.replace(/-/g, "_"),
|
|
371
|
-
{
|
|
372
|
-
get() {
|
|
373
|
-
return function () {
|
|
374
|
-
return instance!.invoke(
|
|
375
|
-
cb,
|
|
376
|
-
Array.from(arguments),
|
|
377
|
-
);
|
|
378
|
-
};
|
|
379
|
-
},
|
|
380
|
-
set(callback) {
|
|
381
|
-
instance!.setCallback(cb, callback);
|
|
382
|
-
},
|
|
383
|
-
enumerable: true,
|
|
384
|
-
},
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
});
|
|
426
|
+
instance!.definition().functions.forEach((cb) => {
|
|
427
|
+
const functionName = translateName(cb);
|
|
388
428
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
Array.from(arguments),
|
|
406
|
-
);
|
|
407
|
-
};
|
|
408
|
-
},
|
|
409
|
-
enumerable: true,
|
|
429
|
+
if (componentHandle[functionName] !== undefined) {
|
|
430
|
+
console.warn(
|
|
431
|
+
"Duplicated function name " + functionName,
|
|
432
|
+
);
|
|
433
|
+
} else {
|
|
434
|
+
Object.defineProperty(
|
|
435
|
+
componentHandle,
|
|
436
|
+
translateName(cb),
|
|
437
|
+
{
|
|
438
|
+
get() {
|
|
439
|
+
return function () {
|
|
440
|
+
return instance!.invoke(
|
|
441
|
+
cb,
|
|
442
|
+
Array.from(arguments),
|
|
443
|
+
);
|
|
444
|
+
};
|
|
410
445
|
},
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
446
|
+
enumerable: true,
|
|
447
|
+
},
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
// globals
|
|
453
|
+
instance!.definition().globals.forEach((globalName) => {
|
|
454
|
+
if (componentHandle[globalName] !== undefined) {
|
|
455
|
+
console.warn("Duplicated property name " + globalName);
|
|
456
|
+
} else {
|
|
457
|
+
const globalObject = Object.create({});
|
|
458
|
+
|
|
459
|
+
instance!
|
|
460
|
+
.definition()
|
|
461
|
+
.globalProperties(globalName)
|
|
462
|
+
.forEach((prop) => {
|
|
463
|
+
const propName = translateName(prop.name);
|
|
464
|
+
|
|
465
|
+
if (globalObject[propName] !== undefined) {
|
|
466
|
+
console.warn(
|
|
467
|
+
"Duplicated property name " +
|
|
468
|
+
propName +
|
|
469
|
+
" on global " +
|
|
470
|
+
global,
|
|
431
471
|
);
|
|
472
|
+
} else {
|
|
473
|
+
Object.defineProperty(
|
|
474
|
+
globalObject,
|
|
475
|
+
propName,
|
|
476
|
+
{
|
|
477
|
+
get() {
|
|
478
|
+
return instance!.getGlobalProperty(
|
|
479
|
+
globalName,
|
|
480
|
+
prop.name,
|
|
481
|
+
);
|
|
482
|
+
},
|
|
483
|
+
set(value) {
|
|
484
|
+
instance!.setGlobalProperty(
|
|
485
|
+
globalName,
|
|
486
|
+
prop.name,
|
|
487
|
+
value,
|
|
488
|
+
);
|
|
489
|
+
},
|
|
490
|
+
enumerable: true,
|
|
491
|
+
},
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
});
|
|
432
495
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
496
|
+
instance!
|
|
497
|
+
.definition()
|
|
498
|
+
.globalCallbacks(globalName)
|
|
499
|
+
.forEach((cb) => {
|
|
500
|
+
const callbackName = translateName(cb);
|
|
501
|
+
|
|
502
|
+
if (globalObject[callbackName] !== undefined) {
|
|
503
|
+
console.warn(
|
|
504
|
+
"Duplicated property name " +
|
|
505
|
+
cb +
|
|
506
|
+
" on global " +
|
|
507
|
+
global,
|
|
508
|
+
);
|
|
509
|
+
} else {
|
|
510
|
+
Object.defineProperty(
|
|
511
|
+
globalObject,
|
|
512
|
+
translateName(cb),
|
|
513
|
+
{
|
|
514
|
+
get() {
|
|
515
|
+
return function () {
|
|
516
|
+
return instance!.invokeGlobal(
|
|
453
517
|
globalName,
|
|
454
|
-
|
|
455
|
-
|
|
518
|
+
cb,
|
|
519
|
+
Array.from(arguments),
|
|
456
520
|
);
|
|
457
|
-
}
|
|
458
|
-
enumerable: true,
|
|
521
|
+
};
|
|
459
522
|
},
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
cb
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
},
|
|
495
|
-
set(callback) {
|
|
496
|
-
instance!.setGlobalCallback(
|
|
523
|
+
set(callback) {
|
|
524
|
+
instance!.setGlobalCallback(
|
|
525
|
+
globalName,
|
|
526
|
+
cb,
|
|
527
|
+
callback,
|
|
528
|
+
);
|
|
529
|
+
},
|
|
530
|
+
enumerable: true,
|
|
531
|
+
},
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
instance!
|
|
537
|
+
.definition()
|
|
538
|
+
.globalFunctions(globalName)
|
|
539
|
+
.forEach((cb) => {
|
|
540
|
+
const functionName = translateName(cb);
|
|
541
|
+
|
|
542
|
+
if (globalObject[functionName] !== undefined) {
|
|
543
|
+
console.warn(
|
|
544
|
+
"Duplicated function name " +
|
|
545
|
+
cb +
|
|
546
|
+
" on global " +
|
|
547
|
+
global,
|
|
548
|
+
);
|
|
549
|
+
} else {
|
|
550
|
+
Object.defineProperty(
|
|
551
|
+
globalObject,
|
|
552
|
+
translateName(cb),
|
|
553
|
+
{
|
|
554
|
+
get() {
|
|
555
|
+
return function () {
|
|
556
|
+
return instance!.invokeGlobal(
|
|
497
557
|
globalName,
|
|
498
558
|
cb,
|
|
499
|
-
|
|
559
|
+
Array.from(arguments),
|
|
500
560
|
);
|
|
501
|
-
}
|
|
502
|
-
enumerable: true,
|
|
561
|
+
};
|
|
503
562
|
},
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
instance!
|
|
509
|
-
.definition()
|
|
510
|
-
.globalFunctions(globalName)
|
|
511
|
-
.forEach((cb) => {
|
|
512
|
-
const functionName = cb.replace(/-/g, "_");
|
|
513
|
-
|
|
514
|
-
if (
|
|
515
|
-
globalObject[functionName] !== undefined
|
|
516
|
-
) {
|
|
517
|
-
console.warn(
|
|
518
|
-
"Duplicated function name " +
|
|
519
|
-
cb +
|
|
520
|
-
" on global " +
|
|
521
|
-
global,
|
|
522
|
-
);
|
|
523
|
-
} else {
|
|
524
|
-
Object.defineProperty(
|
|
525
|
-
globalObject,
|
|
526
|
-
cb.replace(/-/g, "_"),
|
|
527
|
-
{
|
|
528
|
-
get() {
|
|
529
|
-
return function () {
|
|
530
|
-
return instance!.invokeGlobal(
|
|
531
|
-
globalName,
|
|
532
|
-
cb,
|
|
533
|
-
Array.from(
|
|
534
|
-
arguments,
|
|
535
|
-
),
|
|
536
|
-
);
|
|
537
|
-
};
|
|
538
|
-
},
|
|
539
|
-
enumerable: true,
|
|
540
|
-
},
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
Object.defineProperty(componentHandle, globalName, {
|
|
546
|
-
get() {
|
|
547
|
-
return globalObject;
|
|
548
|
-
},
|
|
549
|
-
enumerable: true,
|
|
563
|
+
enumerable: true,
|
|
564
|
+
},
|
|
565
|
+
);
|
|
566
|
+
}
|
|
550
567
|
});
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
568
|
|
|
554
|
-
|
|
555
|
-
|
|
569
|
+
Object.defineProperty(componentHandle, globalName, {
|
|
570
|
+
get() {
|
|
571
|
+
return globalObject;
|
|
572
|
+
},
|
|
573
|
+
enumerable: true,
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
return Object.seal(componentHandle);
|
|
556
579
|
},
|
|
557
|
-
);
|
|
580
|
+
});
|
|
558
581
|
});
|
|
559
582
|
return Object.seal(slint_module);
|
|
560
583
|
}
|
|
@@ -582,7 +605,7 @@ function loadSlint(loadData: LoadData): Object {
|
|
|
582
605
|
* main.greeting = "Hello friends";
|
|
583
606
|
* ```
|
|
584
607
|
*
|
|
585
|
-
* @param filePath The path to the file to load
|
|
608
|
+
* @param filePath The path to the file to load as `string` or `URL`. Relative paths are resolved against the process' current working directory.
|
|
586
609
|
* @param options An optional {@link LoadFileOptions} to configure additional Slint compilation settings,
|
|
587
610
|
* such as include search paths, library imports, or the widget style.
|
|
588
611
|
* @returns Returns an object that is immutable and provides a constructor function for each exported Window component found in the `.slint` file.
|
|
@@ -591,9 +614,13 @@ function loadSlint(loadData: LoadData): Object {
|
|
|
591
614
|
* For further information on the available properties, refer to [Instantiating A Component](../index.html#md:instantiating-a-component).
|
|
592
615
|
* @throws {@link CompileError} if errors occur during compilation.
|
|
593
616
|
*/
|
|
594
|
-
export function loadFile(
|
|
617
|
+
export function loadFile(
|
|
618
|
+
filePath: string | URL,
|
|
619
|
+
options?: LoadFileOptions,
|
|
620
|
+
): Object {
|
|
621
|
+
const pathname = filePath instanceof URL ? filePath.pathname : filePath;
|
|
595
622
|
return loadSlint({
|
|
596
|
-
fileData: { filePath, options },
|
|
623
|
+
fileData: { filePath: pathname, options },
|
|
597
624
|
from: "file",
|
|
598
625
|
});
|
|
599
626
|
}
|
|
@@ -895,6 +922,28 @@ export namespace private_api {
|
|
|
895
922
|
}
|
|
896
923
|
}
|
|
897
924
|
|
|
925
|
+
/**
|
|
926
|
+
* Initialize translations.
|
|
927
|
+
*
|
|
928
|
+
* Call this with the path where translations are located. This function internally calls the [bindtextdomain](https://man7.org/linux/man-pages/man3/bindtextdomain.3.html) function from gettext.
|
|
929
|
+
*
|
|
930
|
+
* Translations are expected to be found at <path>/<locale>/LC_MESSAGES/<domain>.mo, where path is the directory passed as an argument to this function, locale is a locale name (e.g., en, en_GB, fr), and domain is the package name.
|
|
931
|
+
*
|
|
932
|
+
* @param domain defines the domain name e.g. name of the package.
|
|
933
|
+
* @param path specifies the directory as `string` or as `URL` in which gettext should search for translations.
|
|
934
|
+
*
|
|
935
|
+
* For example, assuming this is in a package called example and the default locale is configured to be French, it will load translations at runtime from ``/path/to/example/translations/fr/LC_MESSAGES/example.mo`.
|
|
936
|
+
*
|
|
937
|
+
* ```js
|
|
938
|
+
* import * as slint from "slint-ui";
|
|
939
|
+
* slint.initTranslations("example", new URL("translations/", import.meta.url));
|
|
940
|
+
* ````
|
|
941
|
+
*/
|
|
942
|
+
export function initTranslations(domain: string, path: string | URL) {
|
|
943
|
+
const pathname = path instanceof URL ? path.pathname : path;
|
|
944
|
+
napi.initTranslations(domain, pathname);
|
|
945
|
+
}
|
|
946
|
+
|
|
898
947
|
/**
|
|
899
948
|
* @hidden
|
|
900
949
|
*/
|