@nativedesktop/react 0.4.0 → 0.4.2
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/dist/index.js +316 -93
- package/dist/packages/react/src/generated/intrinsics.d.ts +12 -1
- package/dist/packages/react/src/generated/rpc.d.ts +60 -2
- package/dist/packages/react/src/generated/schema-meta.d.ts +6 -1
- package/dist/packages/react/src/index.d.ts +2 -2
- package/dist/packages/react/src/webview.d.ts +34 -0
- package/dist/runtime/ndp.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -87,57 +87,81 @@ class BinaryUnsupportedValue extends Error {
|
|
|
87
87
|
var textEncoder = new TextEncoder;
|
|
88
88
|
|
|
89
89
|
class ByteWriter {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
buf;
|
|
91
|
+
view;
|
|
92
|
+
cap;
|
|
93
93
|
len = 0;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
constructor(capacity) {
|
|
95
|
+
this.buf = new Uint8Array(capacity);
|
|
96
|
+
this.view = new DataView(this.buf.buffer);
|
|
97
|
+
this.cap = capacity;
|
|
98
|
+
}
|
|
99
|
+
grow(n) {
|
|
100
|
+
let cap = this.cap * 2;
|
|
98
101
|
while (cap < this.len + n)
|
|
99
102
|
cap *= 2;
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
this.
|
|
103
|
-
this.
|
|
104
|
-
this.
|
|
103
|
+
const next = new Uint8Array(cap);
|
|
104
|
+
next.set(this.buf.subarray(0, this.len));
|
|
105
|
+
this.buf = next;
|
|
106
|
+
this.view = new DataView(next.buffer);
|
|
107
|
+
this.cap = cap;
|
|
105
108
|
}
|
|
106
109
|
u8(v) {
|
|
107
|
-
this.
|
|
110
|
+
if (this.len + 1 > this.cap)
|
|
111
|
+
this.grow(1);
|
|
108
112
|
this.buf[this.len++] = v & 255;
|
|
109
113
|
}
|
|
110
114
|
u16(v) {
|
|
111
|
-
this.
|
|
115
|
+
if (this.len + 2 > this.cap)
|
|
116
|
+
this.grow(2);
|
|
112
117
|
this.view.setUint16(this.len, v, true);
|
|
113
118
|
this.len += 2;
|
|
114
119
|
}
|
|
115
120
|
u32(v) {
|
|
116
|
-
this.
|
|
121
|
+
if (this.len + 4 > this.cap)
|
|
122
|
+
this.grow(4);
|
|
117
123
|
this.view.setUint32(this.len, v >>> 0, true);
|
|
118
124
|
this.len += 4;
|
|
119
125
|
}
|
|
120
126
|
i64(v) {
|
|
121
|
-
this.
|
|
127
|
+
if (this.len + 8 > this.cap)
|
|
128
|
+
this.grow(8);
|
|
122
129
|
this.view.setBigInt64(this.len, BigInt(v), true);
|
|
123
130
|
this.len += 8;
|
|
124
131
|
}
|
|
125
132
|
f64(v) {
|
|
126
|
-
this.
|
|
133
|
+
if (this.len + 8 > this.cap)
|
|
134
|
+
this.grow(8);
|
|
127
135
|
this.view.setFloat64(this.len, v, true);
|
|
128
136
|
this.len += 8;
|
|
129
137
|
}
|
|
130
|
-
bytes(b) {
|
|
131
|
-
this.ensure(b.length);
|
|
132
|
-
this.buf.set(b, this.len);
|
|
133
|
-
this.len += b.length;
|
|
134
|
-
}
|
|
135
138
|
lenString(s) {
|
|
136
|
-
|
|
139
|
+
const n = s.length;
|
|
140
|
+
if (this.len + 4 + n * 3 > this.cap)
|
|
141
|
+
this.grow(4 + n * 3);
|
|
137
142
|
const lenPos = this.len;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
143
|
+
let p = lenPos + 4;
|
|
144
|
+
let ascii = true;
|
|
145
|
+
for (let i = 0;i < n; i++) {
|
|
146
|
+
const c = s.charCodeAt(i);
|
|
147
|
+
if (c > 127) {
|
|
148
|
+
ascii = false;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
this.buf[p++] = c;
|
|
152
|
+
}
|
|
153
|
+
if (!ascii) {
|
|
154
|
+
const { written } = textEncoder.encodeInto(s, this.buf.subarray(lenPos + 4));
|
|
155
|
+
p = lenPos + 4 + written;
|
|
156
|
+
}
|
|
157
|
+
this.view.setUint32(lenPos, p - lenPos - 4, true);
|
|
158
|
+
this.len = p;
|
|
159
|
+
}
|
|
160
|
+
patchU16(pos, v) {
|
|
161
|
+
this.view.setUint16(pos, v, true);
|
|
162
|
+
}
|
|
163
|
+
patchU32(pos, v) {
|
|
164
|
+
this.view.setUint32(pos, v >>> 0, true);
|
|
141
165
|
}
|
|
142
166
|
slice() {
|
|
143
167
|
return this.buf.slice(0, this.len);
|
|
@@ -155,93 +179,103 @@ function encodeCommitBatchBinary(batch) {
|
|
|
155
179
|
index.set(s, i);
|
|
156
180
|
return i;
|
|
157
181
|
};
|
|
158
|
-
|
|
182
|
+
let lastKey = "";
|
|
183
|
+
let lastKeyRef = 0;
|
|
184
|
+
const internKey = (k) => {
|
|
185
|
+
if (k === lastKey)
|
|
186
|
+
return lastKeyRef;
|
|
187
|
+
lastKey = k;
|
|
188
|
+
lastKeyRef = intern(k);
|
|
189
|
+
return lastKeyRef;
|
|
190
|
+
};
|
|
191
|
+
const out = new ByteWriter(32 * batch.ops.length + 4096);
|
|
192
|
+
out.u8(78);
|
|
193
|
+
out.u8(1);
|
|
194
|
+
for (let i = 0;i < 6; i++)
|
|
195
|
+
out.u8(0);
|
|
196
|
+
out.i64(batch.commitId);
|
|
197
|
+
out.u32(batch.generation);
|
|
198
|
+
out.u32(batch.ops.length);
|
|
199
|
+
const stringTableOffsetPos = out.len;
|
|
200
|
+
out.u32(0);
|
|
159
201
|
const writeProps = (props) => {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
202
|
+
const countPos = out.len;
|
|
203
|
+
out.u16(0);
|
|
204
|
+
let count = 0;
|
|
205
|
+
for (const k in props) {
|
|
206
|
+
count++;
|
|
207
|
+
out.u32(internKey(k));
|
|
164
208
|
const v = props[k];
|
|
165
209
|
if (v === null || v === undefined) {
|
|
166
|
-
|
|
210
|
+
out.u8(0);
|
|
167
211
|
} else if (typeof v === "boolean") {
|
|
168
|
-
|
|
169
|
-
|
|
212
|
+
out.u8(1);
|
|
213
|
+
out.u8(v ? 1 : 0);
|
|
170
214
|
} else if (typeof v === "number") {
|
|
171
215
|
if (Number.isInteger(v)) {
|
|
172
|
-
|
|
173
|
-
|
|
216
|
+
out.u8(2);
|
|
217
|
+
out.i64(v);
|
|
174
218
|
} else {
|
|
175
|
-
|
|
176
|
-
|
|
219
|
+
out.u8(3);
|
|
220
|
+
out.f64(v);
|
|
177
221
|
}
|
|
178
222
|
} else if (typeof v === "string") {
|
|
179
|
-
|
|
180
|
-
|
|
223
|
+
out.u8(4);
|
|
224
|
+
out.u32(intern(v));
|
|
181
225
|
} else {
|
|
182
226
|
throw new BinaryUnsupportedValue(k, v);
|
|
183
227
|
}
|
|
184
228
|
}
|
|
229
|
+
out.patchU16(countPos, count);
|
|
185
230
|
};
|
|
186
231
|
for (const op of batch.ops) {
|
|
187
232
|
switch (op.op) {
|
|
188
233
|
case "create": {
|
|
189
|
-
|
|
190
|
-
|
|
234
|
+
out.u8(1);
|
|
235
|
+
out.u32(op.id);
|
|
191
236
|
const wt = WIDGET_TYPE[op.widget];
|
|
192
237
|
if (wt === undefined)
|
|
193
238
|
throw new Error(`ndp-binary: unknown widget "${op.widget}"`);
|
|
194
|
-
|
|
239
|
+
out.u16(wt);
|
|
195
240
|
writeProps(op.props);
|
|
196
241
|
break;
|
|
197
242
|
}
|
|
198
243
|
case "append":
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
244
|
+
out.u8(2);
|
|
245
|
+
out.u32(op.parent);
|
|
246
|
+
out.u32(op.child);
|
|
202
247
|
break;
|
|
203
248
|
case "insertBefore":
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
249
|
+
out.u8(3);
|
|
250
|
+
out.u32(op.parent);
|
|
251
|
+
out.u32(op.child);
|
|
252
|
+
out.u32(op.before ?? 0);
|
|
208
253
|
break;
|
|
209
254
|
case "remove":
|
|
210
|
-
|
|
211
|
-
|
|
255
|
+
out.u8(4);
|
|
256
|
+
out.u32(op.id);
|
|
212
257
|
break;
|
|
213
258
|
case "setText":
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
259
|
+
out.u8(5);
|
|
260
|
+
out.u32(op.id);
|
|
261
|
+
out.u32(intern(op.text));
|
|
217
262
|
break;
|
|
218
263
|
case "update":
|
|
219
|
-
|
|
220
|
-
|
|
264
|
+
out.u8(6);
|
|
265
|
+
out.u32(op.id);
|
|
221
266
|
writeProps(op.props);
|
|
222
267
|
break;
|
|
223
268
|
case "hide":
|
|
224
|
-
|
|
225
|
-
|
|
269
|
+
out.u8(7);
|
|
270
|
+
out.u32(op.id);
|
|
226
271
|
break;
|
|
227
272
|
case "unhide":
|
|
228
|
-
|
|
229
|
-
|
|
273
|
+
out.u8(8);
|
|
274
|
+
out.u32(op.id);
|
|
230
275
|
break;
|
|
231
276
|
}
|
|
232
277
|
}
|
|
233
|
-
|
|
234
|
-
const stringTableOffset = 28 + opBytes.length;
|
|
235
|
-
const out = new ByteWriter;
|
|
236
|
-
out.u8(78);
|
|
237
|
-
out.u8(1);
|
|
238
|
-
for (let i = 0;i < 6; i++)
|
|
239
|
-
out.u8(0);
|
|
240
|
-
out.i64(batch.commitId);
|
|
241
|
-
out.u32(batch.generation);
|
|
242
|
-
out.u32(batch.ops.length);
|
|
243
|
-
out.u32(stringTableOffset);
|
|
244
|
-
out.bytes(opBytes);
|
|
278
|
+
out.patchU32(stringTableOffsetPos, out.len);
|
|
245
279
|
out.u32(strings.length);
|
|
246
280
|
for (const s of strings)
|
|
247
281
|
out.lenString(s);
|
|
@@ -253,10 +287,15 @@ var NDP_VERSION = 1;
|
|
|
253
287
|
|
|
254
288
|
// ../../runtime/ndp.ts
|
|
255
289
|
var TRACE = process.env.NDP_TRACE === "1";
|
|
290
|
+
var textDecoder = new TextDecoder;
|
|
291
|
+
var textEncoder2 = new TextEncoder;
|
|
256
292
|
|
|
257
293
|
class Ndp {
|
|
258
294
|
socket;
|
|
259
|
-
inbox = new Uint8Array(
|
|
295
|
+
inbox = new Uint8Array(64 * 1024);
|
|
296
|
+
inboxView = new DataView(this.inbox.buffer);
|
|
297
|
+
inboxHead = 0;
|
|
298
|
+
inboxTail = 0;
|
|
260
299
|
eventCb = null;
|
|
261
300
|
helloAckResolve = null;
|
|
262
301
|
outbox = [];
|
|
@@ -321,22 +360,52 @@ class Ndp {
|
|
|
321
360
|
}
|
|
322
361
|
}
|
|
323
362
|
}
|
|
363
|
+
reserveInbox(extra) {
|
|
364
|
+
const pending = this.inboxTail - this.inboxHead;
|
|
365
|
+
if (this.inboxTail + extra <= this.inbox.length)
|
|
366
|
+
return;
|
|
367
|
+
if (pending + extra <= this.inbox.length) {
|
|
368
|
+
this.compactInbox();
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
let cap = this.inbox.length * 2;
|
|
372
|
+
while (cap < pending + extra)
|
|
373
|
+
cap *= 2;
|
|
374
|
+
const next = new Uint8Array(cap);
|
|
375
|
+
next.set(this.inbox.subarray(this.inboxHead, this.inboxTail));
|
|
376
|
+
this.inbox = next;
|
|
377
|
+
this.inboxView = new DataView(next.buffer);
|
|
378
|
+
this.inboxHead = 0;
|
|
379
|
+
this.inboxTail = pending;
|
|
380
|
+
}
|
|
381
|
+
compactInbox() {
|
|
382
|
+
if (this.inboxHead === 0)
|
|
383
|
+
return;
|
|
384
|
+
this.inbox.copyWithin(0, this.inboxHead, this.inboxTail);
|
|
385
|
+
this.inboxTail -= this.inboxHead;
|
|
386
|
+
this.inboxHead = 0;
|
|
387
|
+
}
|
|
324
388
|
onData(chunk) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
this.
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const len = view.getUint32(0, true);
|
|
332
|
-
if (this.inbox.length < 4 + len)
|
|
389
|
+
this.reserveInbox(chunk.length);
|
|
390
|
+
this.inbox.set(chunk, this.inboxTail);
|
|
391
|
+
this.inboxTail += chunk.length;
|
|
392
|
+
while (this.inboxTail - this.inboxHead >= 4) {
|
|
393
|
+
const len = this.inboxView.getUint32(this.inboxHead, true);
|
|
394
|
+
if (this.inboxTail - this.inboxHead < 4 + len)
|
|
333
395
|
break;
|
|
334
|
-
const
|
|
335
|
-
|
|
396
|
+
const start = this.inboxHead + 4;
|
|
397
|
+
const json = textDecoder.decode(this.inbox.subarray(start, start + len));
|
|
398
|
+
this.inboxHead = start + len;
|
|
336
399
|
if (TRACE)
|
|
337
400
|
console.error("<< " + json);
|
|
338
401
|
this.dispatch(JSON.parse(json));
|
|
339
402
|
}
|
|
403
|
+
if (this.inboxHead === this.inboxTail) {
|
|
404
|
+
this.inboxHead = 0;
|
|
405
|
+
this.inboxTail = 0;
|
|
406
|
+
} else if (this.inboxHead * 2 >= this.inbox.length) {
|
|
407
|
+
this.compactInbox();
|
|
408
|
+
}
|
|
340
409
|
}
|
|
341
410
|
dispatch(msg) {
|
|
342
411
|
if (msg.type === "helloAck") {
|
|
@@ -366,12 +435,12 @@ class Ndp {
|
|
|
366
435
|
}
|
|
367
436
|
}
|
|
368
437
|
send(obj) {
|
|
369
|
-
const json =
|
|
438
|
+
const json = textEncoder2.encode(JSON.stringify(obj));
|
|
370
439
|
const frame = new Uint8Array(4 + json.length);
|
|
371
440
|
new DataView(frame.buffer).setUint32(0, json.length, true);
|
|
372
441
|
frame.set(json, 4);
|
|
373
442
|
if (TRACE)
|
|
374
|
-
console.error(">> " +
|
|
443
|
+
console.error(">> " + textDecoder.decode(json));
|
|
375
444
|
const wasEmpty = this.outbox.length === 0;
|
|
376
445
|
this.outbox.push(frame);
|
|
377
446
|
if (wasEmpty)
|
|
@@ -524,7 +593,7 @@ var widgetEvents = {
|
|
|
524
593
|
tabview: [{ name: "selectionChanged", handler: "onSelectionChanged", payload: "index" }, { name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }],
|
|
525
594
|
grid: [{ name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }],
|
|
526
595
|
listview: [{ name: "rowActivated", handler: "onRowActivated", payload: "index" }, { name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }],
|
|
527
|
-
webview: [{ name: "navigate", handler: "onNavigate", payload: "text" }, { name: "titleChanged", handler: "onTitleChanged", payload: "text" }, { name: "loadingChanged", handler: "onLoadingChanged", payload: "checked" }, { name: "backAvailable", handler: "onBackAvailable", payload: "checked" }, { name: "forwardAvailable", handler: "onForwardAvailable", payload: "checked" }, { name: "loadProgress", handler: "onLoadProgress", payload: "value" }, { name: "loadFailed", handler: "onLoadFailed", payload: "data" }, { name: "newWindow", handler: "onNewWindow", payload: "text" }, { name: "downloadRequested", handler: "onDownloadRequested", payload: "data" }, { name: "javaScriptResult", handler: "onJavaScriptResult", payload: "data" }, { name: "scriptMessage", handler: "onScriptMessage", payload: "data" }, { name: "schemeRequest", handler: "onSchemeRequest", payload: "data" }, { name: "cookiesResult", handler: "onCookiesResult", payload: "data" }, { name: "cookiesChanged", handler: "onCookiesChanged", payload: "data" }, { name: "faviconChanged", handler: "onFaviconChanged", payload: "data" }, { name: "findResult", handler: "onFindResult", payload: "data" }, { name: "securityChanged", handler: "onSecurityChanged", payload: "data" }, { name: "linkHover", handler: "onLinkHover", payload: "text" }, { name: "contextMenu", handler: "onContextMenu", payload: "data" }, { name: "contextMenuItemClicked", handler: "onContextMenuItemClicked", payload: "data" }, { name: "sessionSaved", handler: "onSessionSaved", payload: "data" }, { name: "audioStateChanged", handler: "onAudioStateChanged", payload: "data" }, { name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }],
|
|
596
|
+
webview: [{ name: "navigate", handler: "onNavigate", payload: "text" }, { name: "titleChanged", handler: "onTitleChanged", payload: "text" }, { name: "loadingChanged", handler: "onLoadingChanged", payload: "checked" }, { name: "backAvailable", handler: "onBackAvailable", payload: "checked" }, { name: "forwardAvailable", handler: "onForwardAvailable", payload: "checked" }, { name: "loadProgress", handler: "onLoadProgress", payload: "value" }, { name: "loadFailed", handler: "onLoadFailed", payload: "data" }, { name: "newWindow", handler: "onNewWindow", payload: "text" }, { name: "downloadRequested", handler: "onDownloadRequested", payload: "data" }, { name: "javaScriptResult", handler: "onJavaScriptResult", payload: "data" }, { name: "scriptMessage", handler: "onScriptMessage", payload: "data" }, { name: "schemeRequest", handler: "onSchemeRequest", payload: "data" }, { name: "cookiesResult", handler: "onCookiesResult", payload: "data" }, { name: "cookiesChanged", handler: "onCookiesChanged", payload: "data" }, { name: "faviconChanged", handler: "onFaviconChanged", payload: "data" }, { name: "findResult", handler: "onFindResult", payload: "data" }, { name: "securityChanged", handler: "onSecurityChanged", payload: "data" }, { name: "linkHover", handler: "onLinkHover", payload: "text" }, { name: "contextMenu", handler: "onContextMenu", payload: "data" }, { name: "contextMenuItemClicked", handler: "onContextMenuItemClicked", payload: "data" }, { name: "sessionSaved", handler: "onSessionSaved", payload: "data" }, { name: "audioStateChanged", handler: "onAudioStateChanged", payload: "data" }, { name: "extensionsList", handler: "onExtensionsList", payload: "data" }, { name: "extensionActions", handler: "onExtensionActions", payload: "data" }, { name: "chromeDialog", handler: "onChromeDialog", payload: "data" }, { name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }],
|
|
528
597
|
nativeview: [{ name: "nativeEvent", handler: "onNativeEvent", payload: "data" }, { name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }],
|
|
529
598
|
splitview: [{ name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }],
|
|
530
599
|
headerbar: [{ name: "back", handler: "onBack", payload: "none" }, { name: "forward", handler: "onForward", payload: "none" }, { name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }],
|
|
@@ -578,6 +647,9 @@ var widgetEvents = {
|
|
|
578
647
|
chart: [{ name: "pointSelected", handler: "onPointSelected", payload: "data" }, { name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }],
|
|
579
648
|
codeeditor: [{ name: "changed", handler: "onChange", payload: "text" }, { name: "cursorMoved", handler: "onCursorMoved", payload: "data" }, { name: "diagnosticClicked", handler: "onDiagnosticClicked", payload: "data" }, { name: "dragStarted", handler: "onDragStarted", payload: "text" }, { name: "dragEnded", handler: "onDragEnded", payload: "none" }, { name: "dragOver", handler: "onDragOver", payload: "dragPoint" }, { name: "dropped", handler: "onDropped", payload: "dragPoint" }]
|
|
580
649
|
};
|
|
650
|
+
var widgetRefProps = {
|
|
651
|
+
popover: { anchorRef: "anchor" }
|
|
652
|
+
};
|
|
581
653
|
var handlerPropNames = {
|
|
582
654
|
window: ["onAlertResult", "onOpenFileResult", "onSaveFileResult", "onNewTabRequested", "onClosed", "onFocused", "onSizeChanged", "onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
583
655
|
box: ["onHoverChanged", "onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
@@ -597,7 +669,7 @@ var handlerPropNames = {
|
|
|
597
669
|
tabview: ["onSelectionChanged", "onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
598
670
|
grid: ["onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
599
671
|
listview: ["onRowActivated", "onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
600
|
-
webview: ["onNavigate", "onTitleChanged", "onLoadingChanged", "onBackAvailable", "onForwardAvailable", "onLoadProgress", "onLoadFailed", "onNewWindow", "onDownloadRequested", "onJavaScriptResult", "onScriptMessage", "onSchemeRequest", "onCookiesResult", "onCookiesChanged", "onFaviconChanged", "onFindResult", "onSecurityChanged", "onLinkHover", "onContextMenu", "onContextMenuItemClicked", "onSessionSaved", "onAudioStateChanged", "onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
672
|
+
webview: ["onNavigate", "onTitleChanged", "onLoadingChanged", "onBackAvailable", "onForwardAvailable", "onLoadProgress", "onLoadFailed", "onNewWindow", "onDownloadRequested", "onJavaScriptResult", "onScriptMessage", "onSchemeRequest", "onCookiesResult", "onCookiesChanged", "onFaviconChanged", "onFindResult", "onSecurityChanged", "onLinkHover", "onContextMenu", "onContextMenuItemClicked", "onSessionSaved", "onAudioStateChanged", "onExtensionsList", "onExtensionActions", "onChromeDialog", "onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
601
673
|
nativeview: ["onNativeEvent", "onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
602
674
|
splitview: ["onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
603
675
|
headerbar: ["onBack", "onForward", "onDragStarted", "onDragEnded", "onDragOver", "onDropped"],
|
|
@@ -670,7 +742,7 @@ var widgetCommands = {
|
|
|
670
742
|
tabview: [],
|
|
671
743
|
grid: [],
|
|
672
744
|
listview: [],
|
|
673
|
-
webview: ["goBack", "goForward", "reload", "stop", "executeJavaScript", "setZoom", "setUserAgent", "openDevTools", "addUserScript", "removeUserScript", "clearUserScripts", "registerScriptMessage", "unregisterScriptMessage", "respondScheme", "getCookies", "setCookie", "deleteCookie", "findStart", "findNext", "findPrevious", "findStop", "saveSession", "restoreSession", "setMuted", "setContextMenuItems", "focus"],
|
|
745
|
+
webview: ["goBack", "goForward", "reload", "stop", "executeJavaScript", "setZoom", "setUserAgent", "openDevTools", "addUserScript", "removeUserScript", "clearUserScripts", "registerScriptMessage", "unregisterScriptMessage", "respondScheme", "getCookies", "setCookie", "deleteCookie", "findStart", "findNext", "findPrevious", "findStop", "saveSession", "restoreSession", "setMuted", "setContextMenuItems", "listExtensions", "listExtensionActions", "installExtension", "uninstallExtension", "setExtensionEnabled", "focus"],
|
|
674
746
|
nativeview: [],
|
|
675
747
|
splitview: [],
|
|
676
748
|
headerbar: [],
|
|
@@ -1114,6 +1186,7 @@ function emitCreateIfNew(inst) {
|
|
|
1114
1186
|
if (inst.type === "label" && text !== undefined)
|
|
1115
1187
|
props.text = text;
|
|
1116
1188
|
delete props.children;
|
|
1189
|
+
resolveRefProps(inst, props);
|
|
1117
1190
|
for (const h of handlerPropNames[inst.type] ?? [])
|
|
1118
1191
|
delete props[h];
|
|
1119
1192
|
activeBatch.push({ op: "create", id: inst.id, widget: intrinsicToName[inst.type], props });
|
|
@@ -1123,6 +1196,89 @@ function emitCreateIfNew(inst) {
|
|
|
1123
1196
|
activeBatch.push({ op: "append", parent: inst.id, child: child.id });
|
|
1124
1197
|
}
|
|
1125
1198
|
}
|
|
1199
|
+
var lastRefIds = new WeakMap;
|
|
1200
|
+
function refId(v) {
|
|
1201
|
+
const id = v?.current?.id;
|
|
1202
|
+
return typeof id === "number" ? id : undefined;
|
|
1203
|
+
}
|
|
1204
|
+
function resolveRefProps(inst, props) {
|
|
1205
|
+
const refs = widgetRefProps[inst.type];
|
|
1206
|
+
if (!refs)
|
|
1207
|
+
return;
|
|
1208
|
+
const sent = {};
|
|
1209
|
+
for (const [refName, wireName] of Object.entries(refs)) {
|
|
1210
|
+
if (!(refName in props))
|
|
1211
|
+
continue;
|
|
1212
|
+
const id = refId(props[refName]);
|
|
1213
|
+
delete props[refName];
|
|
1214
|
+
if (id === undefined)
|
|
1215
|
+
continue;
|
|
1216
|
+
props[wireName] = id;
|
|
1217
|
+
sent[wireName] = id;
|
|
1218
|
+
}
|
|
1219
|
+
lastRefIds.set(inst, sent);
|
|
1220
|
+
}
|
|
1221
|
+
function diffRefProps(inst, props, changed) {
|
|
1222
|
+
const refs = widgetRefProps[inst.type];
|
|
1223
|
+
if (!refs)
|
|
1224
|
+
return;
|
|
1225
|
+
let sent = lastRefIds.get(inst);
|
|
1226
|
+
if (!sent) {
|
|
1227
|
+
sent = {};
|
|
1228
|
+
lastRefIds.set(inst, sent);
|
|
1229
|
+
}
|
|
1230
|
+
for (const [refName, wireName] of Object.entries(refs)) {
|
|
1231
|
+
if (wireName in props)
|
|
1232
|
+
continue;
|
|
1233
|
+
const id = refName in props ? refId(props[refName]) : undefined;
|
|
1234
|
+
if (id === sent[wireName])
|
|
1235
|
+
continue;
|
|
1236
|
+
if (id === undefined) {
|
|
1237
|
+
changed[wireName] = null;
|
|
1238
|
+
delete sent[wireName];
|
|
1239
|
+
continue;
|
|
1240
|
+
}
|
|
1241
|
+
changed[wireName] = id;
|
|
1242
|
+
sent[wireName] = id;
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
var PROP_COMPARE_DEPTH = 4;
|
|
1246
|
+
function isPlainObject(v) {
|
|
1247
|
+
if (typeof v !== "object" || v === null)
|
|
1248
|
+
return false;
|
|
1249
|
+
const proto = Object.getPrototypeOf(v);
|
|
1250
|
+
return proto === Object.prototype || proto === null;
|
|
1251
|
+
}
|
|
1252
|
+
function propsEqual(a, b, depth = 0) {
|
|
1253
|
+
if (Object.is(a, b))
|
|
1254
|
+
return true;
|
|
1255
|
+
if (depth >= PROP_COMPARE_DEPTH)
|
|
1256
|
+
return false;
|
|
1257
|
+
if (Array.isArray(a)) {
|
|
1258
|
+
if (!Array.isArray(b) || a.length !== b.length)
|
|
1259
|
+
return false;
|
|
1260
|
+
for (let i = 0;i < a.length; i++)
|
|
1261
|
+
if (!propsEqual(a[i], b[i], depth + 1))
|
|
1262
|
+
return false;
|
|
1263
|
+
return true;
|
|
1264
|
+
}
|
|
1265
|
+
if (!isPlainObject(a) || !isPlainObject(b))
|
|
1266
|
+
return false;
|
|
1267
|
+
const keys = Object.keys(a);
|
|
1268
|
+
if (keys.length !== Object.keys(b).length)
|
|
1269
|
+
return false;
|
|
1270
|
+
for (const k of keys) {
|
|
1271
|
+
if (!Object.prototype.hasOwnProperty.call(b, k))
|
|
1272
|
+
return false;
|
|
1273
|
+
if (!propsEqual(a[k], b[k], depth + 1))
|
|
1274
|
+
return false;
|
|
1275
|
+
}
|
|
1276
|
+
return true;
|
|
1277
|
+
}
|
|
1278
|
+
var REMOVAL_VALUE = {
|
|
1279
|
+
style: Object.freeze({}),
|
|
1280
|
+
cssClasses: Object.freeze([])
|
|
1281
|
+
};
|
|
1126
1282
|
function setPriorityFor(kind) {
|
|
1127
1283
|
currentUpdatePriority = kind === "discrete" ? DiscreteEventPriority : kind === "continuous" ? ContinuousEventPriority : DefaultEventPriority;
|
|
1128
1284
|
}
|
|
@@ -1201,15 +1357,21 @@ var hostConfig = {
|
|
|
1201
1357
|
activeBatch.push({ op: "setText", id: inst.id, text: t });
|
|
1202
1358
|
}
|
|
1203
1359
|
const skip = handlerPropNames[type] ?? [];
|
|
1360
|
+
const refs = widgetRefProps[type];
|
|
1361
|
+
const wire = (k) => k !== "children" && !skip.includes(k) && !(type === "label" && k === "text") && !(refs !== undefined && (k in refs));
|
|
1204
1362
|
const changed = {};
|
|
1205
1363
|
for (const k of Object.keys(newProps)) {
|
|
1206
|
-
if (
|
|
1207
|
-
continue;
|
|
1208
|
-
if (type === "label" && k === "text")
|
|
1364
|
+
if (!wire(k))
|
|
1209
1365
|
continue;
|
|
1210
|
-
if (newProps[k]
|
|
1366
|
+
if (!propsEqual(newProps[k], oldProps[k]))
|
|
1211
1367
|
changed[k] = newProps[k];
|
|
1212
1368
|
}
|
|
1369
|
+
for (const k of Object.keys(oldProps)) {
|
|
1370
|
+
if (k in newProps || !wire(k))
|
|
1371
|
+
continue;
|
|
1372
|
+
changed[k] = REMOVAL_VALUE[k] ?? null;
|
|
1373
|
+
}
|
|
1374
|
+
diffRefProps(inst, newProps, changed);
|
|
1213
1375
|
if (Object.keys(changed).length)
|
|
1214
1376
|
activeBatch.push({ op: "update", id: inst.id, props: changed });
|
|
1215
1377
|
inst.props = newProps;
|
|
@@ -1770,6 +1932,8 @@ function makeRef(instance) {
|
|
|
1770
1932
|
var pendingEvals = new Map;
|
|
1771
1933
|
var pendingCookies = new Map;
|
|
1772
1934
|
var pendingSessions = new Map;
|
|
1935
|
+
var pendingExtensions = new Map;
|
|
1936
|
+
var pendingActions = new Map;
|
|
1773
1937
|
var seq2 = 0;
|
|
1774
1938
|
function nextId(prefix) {
|
|
1775
1939
|
return `${prefix}${++seq2}`;
|
|
@@ -1825,6 +1989,58 @@ function onSessionSaved(e) {
|
|
|
1825
1989
|
pendingSessions.delete(result.id);
|
|
1826
1990
|
call2.resolve(result.state ?? "");
|
|
1827
1991
|
}
|
|
1992
|
+
function listExtensions(node) {
|
|
1993
|
+
const id = nextId("ext");
|
|
1994
|
+
return new Promise((resolve2, reject2) => {
|
|
1995
|
+
pendingExtensions.set(id, { resolve: resolve2, reject: reject2 });
|
|
1996
|
+
sendCommand(node, "listExtensions", { id });
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
function onExtensionsList(e) {
|
|
2000
|
+
const result = e.data;
|
|
2001
|
+
const call2 = pendingExtensions.get(result.id);
|
|
2002
|
+
if (!call2)
|
|
2003
|
+
return;
|
|
2004
|
+
pendingExtensions.delete(result.id);
|
|
2005
|
+
if (result.ok)
|
|
2006
|
+
call2.resolve(result.extensions ?? []);
|
|
2007
|
+
else
|
|
2008
|
+
call2.reject(new Error(result.error ?? "listExtensions failed"));
|
|
2009
|
+
}
|
|
2010
|
+
function installExtension(node, path) {
|
|
2011
|
+
return extensionMutation(node, "installExtension", { path });
|
|
2012
|
+
}
|
|
2013
|
+
function uninstallExtension(node, extensionId) {
|
|
2014
|
+
return extensionMutation(node, "uninstallExtension", { extensionId });
|
|
2015
|
+
}
|
|
2016
|
+
function setExtensionEnabled(node, extensionId, enabled) {
|
|
2017
|
+
return extensionMutation(node, "setExtensionEnabled", { extensionId, enabled });
|
|
2018
|
+
}
|
|
2019
|
+
function extensionMutation(node, command, args) {
|
|
2020
|
+
const id = nextId("ext");
|
|
2021
|
+
return new Promise((resolve2, reject2) => {
|
|
2022
|
+
pendingExtensions.set(id, { resolve: resolve2, reject: reject2 });
|
|
2023
|
+
sendCommand(node, command, { id, ...args });
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
2026
|
+
function listExtensionActions(node) {
|
|
2027
|
+
const id = nextId("ext");
|
|
2028
|
+
return new Promise((resolve2, reject2) => {
|
|
2029
|
+
pendingActions.set(id, { resolve: resolve2, reject: reject2 });
|
|
2030
|
+
sendCommand(node, "listExtensionActions", { id });
|
|
2031
|
+
});
|
|
2032
|
+
}
|
|
2033
|
+
function onExtensionActions(e) {
|
|
2034
|
+
const result = e.data;
|
|
2035
|
+
const call2 = pendingActions.get(result.id);
|
|
2036
|
+
if (!call2)
|
|
2037
|
+
return;
|
|
2038
|
+
pendingActions.delete(result.id);
|
|
2039
|
+
if (result.ok)
|
|
2040
|
+
call2.resolve(result.actions ?? []);
|
|
2041
|
+
else
|
|
2042
|
+
call2.reject(new Error(result.error ?? "listExtensionActions failed"));
|
|
2043
|
+
}
|
|
1828
2044
|
function setContextMenuItems(node, items) {
|
|
1829
2045
|
sendCommand(node, "setContextMenuItems", { items });
|
|
1830
2046
|
}
|
|
@@ -2194,6 +2410,7 @@ export {
|
|
|
2194
2410
|
useContext,
|
|
2195
2411
|
useCallback,
|
|
2196
2412
|
use,
|
|
2413
|
+
uninstallExtension,
|
|
2197
2414
|
system,
|
|
2198
2415
|
startTransition,
|
|
2199
2416
|
showToast,
|
|
@@ -2201,6 +2418,7 @@ export {
|
|
|
2201
2418
|
showAlert,
|
|
2202
2419
|
showAbout,
|
|
2203
2420
|
setUnhandledErrorPolicy,
|
|
2421
|
+
setExtensionEnabled,
|
|
2204
2422
|
setContextMenuItems,
|
|
2205
2423
|
sendNativeCommand,
|
|
2206
2424
|
sendCommand,
|
|
@@ -2221,11 +2439,16 @@ export {
|
|
|
2221
2439
|
onSaveFileResult,
|
|
2222
2440
|
onOpenFileResult,
|
|
2223
2441
|
onJavaScriptResult,
|
|
2442
|
+
onExtensionsList,
|
|
2443
|
+
onExtensionActions,
|
|
2224
2444
|
onCookiesResult,
|
|
2225
2445
|
onAlertResult,
|
|
2226
2446
|
notifications,
|
|
2227
2447
|
moveNode,
|
|
2228
2448
|
memo,
|
|
2449
|
+
listExtensions,
|
|
2450
|
+
listExtensionActions,
|
|
2451
|
+
installExtension,
|
|
2229
2452
|
hasWidget,
|
|
2230
2453
|
hasCommand,
|
|
2231
2454
|
getCookies,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReactNode, Ref } from "react";
|
|
1
|
+
import type { ReactNode, Ref, RefObject } from "react";
|
|
2
2
|
export { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
3
3
|
export type WidgetName = "Window" | "Box" | "Label" | "Button" | "TextInput" | "TextArea" | "Checkbox" | "Radio" | "Select" | "Slider" | "ProgressBar" | "Image" | "ScrollView" | "Separator" | "Spinner" | "TabView" | "Grid" | "ListView" | "WebView" | "NativeView" | "SplitView" | "HeaderBar" | "ToolbarView" | "SearchInput" | "SourceList" | "SourceTree" | "Menubar" | "Menu" | "MenuItem" | "SettingsGroup" | "Row" | "SwitchRow" | "Clamp" | "Overlay" | "Switch" | "ToggleButton" | "SegmentedControl" | "NumberInput" | "LinkButton" | "LevelIndicator" | "ColorPicker" | "Banner" | "MenuButton" | "SplitButton" | "Popover" | "Expander" | "StatusPage" | "ToastOverlay" | "DatePicker" | "Table" | "TreeView" | "FontPicker" | "Video" | "TrayItem" | "ShareButton" | "Terminal" | "Paned" | "CommandPalette" | "Avatar" | "Badge" | "Tag" | "Kbd" | "ComboBox" | "Breadcrumb" | "Dialog" | "Sheet" | "RichText" | "ProgressCircle" | "Skeleton" | "Chart" | "CodeEditor";
|
|
4
4
|
export type WidgetType = "window" | "box" | "label" | "button" | "textinput" | "textarea" | "checkbox" | "radio" | "select" | "slider" | "progressbar" | "image" | "scrollview" | "separator" | "spinner" | "tabview" | "grid" | "listview" | "webview" | "nativeview" | "splitview" | "headerbar" | "toolbarview" | "searchinput" | "sourcelist" | "sourcetree" | "menubar" | "menu" | "menuitem" | "settingsgroup" | "row" | "switchrow" | "clamp" | "overlay" | "switch" | "togglebutton" | "segmentedcontrol" | "numberinput" | "linkbutton" | "levelindicator" | "colorpicker" | "banner" | "menubutton" | "splitbutton" | "popover" | "expander" | "statuspage" | "toastoverlay" | "datepicker" | "table" | "treeview" | "fontpicker" | "video" | "trayitem" | "sharebutton" | "terminal" | "paned" | "commandpalette" | "avatar" | "badge" | "tag" | "kbd" | "combobox" | "breadcrumb" | "dialog" | "sheet" | "richtext" | "progresscircle" | "skeleton" | "chart" | "codeeditor";
|
|
@@ -992,6 +992,15 @@ export declare namespace JSX {
|
|
|
992
992
|
onAudioStateChanged?: (e: {
|
|
993
993
|
data: unknown;
|
|
994
994
|
}) => void;
|
|
995
|
+
onExtensionsList?: (e: {
|
|
996
|
+
data: unknown;
|
|
997
|
+
}) => void;
|
|
998
|
+
onExtensionActions?: (e: {
|
|
999
|
+
data: unknown;
|
|
1000
|
+
}) => void;
|
|
1001
|
+
onChromeDialog?: (e: {
|
|
1002
|
+
data: unknown;
|
|
1003
|
+
}) => void;
|
|
995
1004
|
onDragStarted?: (e: {
|
|
996
1005
|
text: string;
|
|
997
1006
|
}) => void;
|
|
@@ -2118,6 +2127,8 @@ export declare namespace JSX {
|
|
|
2118
2127
|
children?: ReactNode;
|
|
2119
2128
|
};
|
|
2120
2129
|
popover: {
|
|
2130
|
+
anchor?: number;
|
|
2131
|
+
anchorRef?: RefObject<NdNodeRef | null>;
|
|
2121
2132
|
open?: boolean;
|
|
2122
2133
|
position?: "top" | "bottom" | "left" | "right";
|
|
2123
2134
|
enabled?: boolean;
|
|
@@ -14,7 +14,7 @@ export interface RowJson {
|
|
|
14
14
|
id: string | null;
|
|
15
15
|
subtitle: string | null;
|
|
16
16
|
}
|
|
17
|
-
/** One tree-snapshot node. itemCount is ListView's row count (M5c-D4), null for every widget that isn't data-driven; rows is SourceList's ordered row data, null for every widget that isn't row-driven. role/enabled/focused/value are the accessibility-tree fields (M16): role is the widget's schema-declared automation role (null when the type declares none); enabled/focused/value come from a live per-node backend probe and default to true/false/null on backends without the probe. */
|
|
17
|
+
/** One tree-snapshot node. itemCount is ListView's row count (M5c-D4), null for every widget that isn't data-driven; rows is SourceList's ordered row data, null for every widget that isn't row-driven. role/enabled/focused/value are the accessibility-tree fields (M16): role is the widget's schema-declared automation role (null when the type declares none); enabled/focused/value come from a live per-node backend probe and default to true/false/null on backends without the probe. checked/selected/expanded/placeholder/label/options come from the same probe and are null on every node the field does not apply to (a Label has no checked state), so a locator can ask isChecked/isSelected/isExpanded of any node without first knowing its kind. */
|
|
18
18
|
export interface JsonNode {
|
|
19
19
|
ref: number;
|
|
20
20
|
type: string;
|
|
@@ -29,6 +29,12 @@ export interface JsonNode {
|
|
|
29
29
|
enabled: boolean;
|
|
30
30
|
focused: boolean;
|
|
31
31
|
value: unknown | null;
|
|
32
|
+
checked: boolean | null;
|
|
33
|
+
selected: boolean | null;
|
|
34
|
+
expanded: boolean | null;
|
|
35
|
+
placeholder: string | null;
|
|
36
|
+
label: string | null;
|
|
37
|
+
options: string[] | null;
|
|
32
38
|
}
|
|
33
39
|
export interface GetTreeResult {
|
|
34
40
|
coordinateSpace: string;
|
|
@@ -82,7 +88,7 @@ export interface ResolveResult {
|
|
|
82
88
|
refs: number[];
|
|
83
89
|
count: number;
|
|
84
90
|
}
|
|
85
|
-
/** key/main/visible/title come from the live windowState probe on the Window node's handle; tabGroup is the create-time prop (null for plain windows). */
|
|
91
|
+
/** key/main/visible/title come from the live windowState probe on the Window node's handle; tabGroup is the create-time prop (null for plain windows). geometry is the window's frame in the same logical, top-left-origin units node Geometry uses (w/h are width/height), null on a backend whose probe does not report it. */
|
|
86
92
|
export interface WindowInfo {
|
|
87
93
|
ref: number;
|
|
88
94
|
title: string | null;
|
|
@@ -90,6 +96,7 @@ export interface WindowInfo {
|
|
|
90
96
|
main: boolean;
|
|
91
97
|
visible: boolean;
|
|
92
98
|
tabGroup: string | null;
|
|
99
|
+
geometry: Geometry | null;
|
|
93
100
|
}
|
|
94
101
|
export interface WindowsResult {
|
|
95
102
|
windows: WindowInfo[];
|
|
@@ -109,6 +116,14 @@ export interface DragResult {
|
|
|
109
116
|
export interface KeysResult {
|
|
110
117
|
dispatched: boolean;
|
|
111
118
|
}
|
|
119
|
+
export interface FocusResult {
|
|
120
|
+
ok: boolean;
|
|
121
|
+
}
|
|
122
|
+
/** scrolled is false when the target has no scrollable ancestor (nothing to do), which is a success, not an error. */
|
|
123
|
+
export interface ScrollIntoViewResult {
|
|
124
|
+
ok: boolean;
|
|
125
|
+
scrolled: boolean;
|
|
126
|
+
}
|
|
112
127
|
/** Live page state read off the engine on the UI thread (WebKitGTK's uri/title/is-loading/can-go-back/can-go-forward, WKWebView's url/title/isLoading/canGoBack/canGoForward) — no page JavaScript, no app cooperation. url/title are null before the first commit. */
|
|
113
128
|
export interface WebViewInfo {
|
|
114
129
|
ref: number;
|
|
@@ -187,6 +202,33 @@ export interface HoverParams {
|
|
|
187
202
|
testId?: string;
|
|
188
203
|
window?: number;
|
|
189
204
|
}
|
|
205
|
+
/** Moves keyboard focus to the target, the same path the widget-level `focus` command takes (first responder on macOS, gtk_widget_grab_focus on GTK), so a following `keys`/`type` lands there. Target by exactly one of ref / testId. After it returns, waitFor {testId, state: "focused"} holds. */
|
|
206
|
+
export interface FocusParams {
|
|
207
|
+
ref?: number;
|
|
208
|
+
testId?: string;
|
|
209
|
+
window?: number;
|
|
210
|
+
}
|
|
211
|
+
/** Scrolls the target's nearest scrollable ancestor until the target is inside the viewport, so an off-screen node becomes actionable. A target with no scrollable ancestor answers {ok: true, scrolled: false} rather than an error. Target by exactly one of ref / testId. */
|
|
212
|
+
export interface ScrollIntoViewParams {
|
|
213
|
+
ref?: number;
|
|
214
|
+
testId?: string;
|
|
215
|
+
window?: number;
|
|
216
|
+
}
|
|
217
|
+
/** In-process render of ONE node's widget to a PNG, same result shape as screenshot. The image is the node's own surface, so its pixel dimensions come from the same handle Geometry measures rather than from the whole window at an unknown backing scale. `path` is an absolute path; absent, the host writes beside the automation socket and answers where. Target by exactly one of ref / testId. */
|
|
218
|
+
export interface SnapshotNodeParams {
|
|
219
|
+
ref?: number;
|
|
220
|
+
testId?: string;
|
|
221
|
+
window?: number;
|
|
222
|
+
path?: string;
|
|
223
|
+
}
|
|
224
|
+
/** Moves and/or resizes a window; omitted components keep their current value. Coordinates are logical points with a top-left origin, matching WindowInfo.geometry. `window` names a Window node ref (default: the root window). Answers that window's updated WindowInfo. GTK sizes the window but cannot position it (client-side placement is not a Wayland capability), so x/y are ignored there. */
|
|
225
|
+
export interface SetWindowFrameParams {
|
|
226
|
+
window?: number;
|
|
227
|
+
x?: number;
|
|
228
|
+
y?: number;
|
|
229
|
+
width?: number;
|
|
230
|
+
height?: number;
|
|
231
|
+
}
|
|
190
232
|
/** Resolves a testID to the single ACTIONABLE instance. Candidates are ranked: actionable (the checkActionable predicate passes) before not; then key/front window before background. `refs` is every match in tree order, `ref` the winner (null when none is actionable and `actionable` is true). */
|
|
191
233
|
export interface ResolveParams {
|
|
192
234
|
testId: string;
|
|
@@ -276,6 +318,22 @@ export interface RpcMethods {
|
|
|
276
318
|
params: HoverParams;
|
|
277
319
|
result: ClickResult;
|
|
278
320
|
};
|
|
321
|
+
focus: {
|
|
322
|
+
params: FocusParams;
|
|
323
|
+
result: FocusResult;
|
|
324
|
+
};
|
|
325
|
+
scrollIntoView: {
|
|
326
|
+
params: ScrollIntoViewParams;
|
|
327
|
+
result: ScrollIntoViewResult;
|
|
328
|
+
};
|
|
329
|
+
snapshotNode: {
|
|
330
|
+
params: SnapshotNodeParams;
|
|
331
|
+
result: ScreenshotResult;
|
|
332
|
+
};
|
|
333
|
+
setWindowFrame: {
|
|
334
|
+
params: SetWindowFrameParams;
|
|
335
|
+
result: WindowInfo;
|
|
336
|
+
};
|
|
279
337
|
resolve: {
|
|
280
338
|
params: ResolveParams;
|
|
281
339
|
result: ResolveResult;
|
|
@@ -11,6 +11,11 @@ export interface WidgetEvent {
|
|
|
11
11
|
payload: "none" | "text" | "checked" | "value" | "index" | "indexes" | "data" | "position" | "dragPoint";
|
|
12
12
|
}
|
|
13
13
|
export declare const widgetEvents: Record<string, WidgetEvent[]>;
|
|
14
|
+
/** JSX ref-prop name -> the wire prop that carries the target's node id
|
|
15
|
+
* (schema `refProp`). The reconciler reads `.current.id` off the ref and
|
|
16
|
+
* sends the number, so an app never handles a node id itself; only the
|
|
17
|
+
* widgets listed here have one. */
|
|
18
|
+
export declare const widgetRefProps: Record<string, Record<string, string>>;
|
|
14
19
|
export declare const handlerPropNames: Record<string, string[]>;
|
|
15
20
|
/** Imperative commands each widget accepts via the widgetCommand NDP frame
|
|
16
21
|
* (M14) — the runtime validation table behind sendCommand(). */
|
|
@@ -24,7 +29,7 @@ export type WidgetCommandNames = {
|
|
|
24
29
|
"checkbox": "focus";
|
|
25
30
|
"radio": "focus";
|
|
26
31
|
"select": "focus";
|
|
27
|
-
"webview": "goBack" | "goForward" | "reload" | "stop" | "executeJavaScript" | "setZoom" | "setUserAgent" | "openDevTools" | "addUserScript" | "removeUserScript" | "clearUserScripts" | "registerScriptMessage" | "unregisterScriptMessage" | "respondScheme" | "getCookies" | "setCookie" | "deleteCookie" | "findStart" | "findNext" | "findPrevious" | "findStop" | "saveSession" | "restoreSession" | "setMuted" | "setContextMenuItems" | "focus";
|
|
32
|
+
"webview": "goBack" | "goForward" | "reload" | "stop" | "executeJavaScript" | "setZoom" | "setUserAgent" | "openDevTools" | "addUserScript" | "removeUserScript" | "clearUserScripts" | "registerScriptMessage" | "unregisterScriptMessage" | "respondScheme" | "getCookies" | "setCookie" | "deleteCookie" | "findStart" | "findNext" | "findPrevious" | "findStop" | "saveSession" | "restoreSession" | "setMuted" | "setContextMenuItems" | "listExtensions" | "listExtensionActions" | "installExtension" | "uninstallExtension" | "setExtensionEnabled" | "focus";
|
|
28
33
|
"searchinput": "focus";
|
|
29
34
|
"switch": "focus";
|
|
30
35
|
"numberinput": "focus";
|
|
@@ -7,8 +7,8 @@ export type { SpacingScale } from "./metrics.ts";
|
|
|
7
7
|
export { getAppDataDir, ensureAppDataDir } from "./paths.ts";
|
|
8
8
|
export { defineNativeComponent } from "./native-component.ts";
|
|
9
9
|
export type { NativeComponentOptions, NativeComponentProps, NativeComponentRef } from "./native-component.ts";
|
|
10
|
-
export { executeJavaScript, onJavaScriptResult, getCookies, onCookiesResult, saveSession, onSessionSaved, setContextMenuItems, } from "./webview.ts";
|
|
11
|
-
export type { Cookie, ContextMenuContext, ContextMenuItem, ContextMenuItemClick } from "./webview.ts";
|
|
10
|
+
export { executeJavaScript, onJavaScriptResult, getCookies, onCookiesResult, saveSession, onSessionSaved, setContextMenuItems, listExtensions, onExtensionsList, listExtensionActions, onExtensionActions, installExtension, uninstallExtension, setExtensionEnabled, } from "./webview.ts";
|
|
11
|
+
export type { Cookie, ContextMenuContext, ContextMenuItem, ContextMenuItemClick, ExtensionAction, InstalledExtension, } from "./webview.ts";
|
|
12
12
|
export { showAlert, openFile, saveFile, showAbout, showTabOverview, onAlertResult, onOpenFileResult, onSaveFileResult, } from "./dialogs.ts";
|
|
13
13
|
export type { DialogButton, ShowAlertOptions, AlertResult, OpenFileOptions as WindowOpenFileOptions, OpenFileResult as WindowOpenFileResult, SaveFileOptions as WindowSaveFileOptions, SaveFileResult as WindowSaveFileResult, ShowAboutOptions, } from "./dialogs.ts";
|
|
14
14
|
export { showToast, dismissToast, onToastButtonClicked, onToastDismissed } from "./toast.ts";
|
|
@@ -22,6 +22,40 @@ export declare function saveSession(node: NdNodeRef<"webview">): Promise<string>
|
|
|
22
22
|
export declare function onSessionSaved(e: {
|
|
23
23
|
data: unknown;
|
|
24
24
|
}): void;
|
|
25
|
+
export interface InstalledExtension {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
version: string;
|
|
29
|
+
enabled: boolean;
|
|
30
|
+
/** A `data:` URI, ready for an `<image>` src. Empty when the extension has no icon. */
|
|
31
|
+
iconUrl: string;
|
|
32
|
+
/** `chrome-extension://…` options page, or "" when the extension declares none. */
|
|
33
|
+
optionsUrl: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function listExtensions(node: NdNodeRef<"webview">): Promise<InstalledExtension[]>;
|
|
36
|
+
export declare function onExtensionsList(e: {
|
|
37
|
+
data: unknown;
|
|
38
|
+
}): void;
|
|
39
|
+
export declare function installExtension(node: NdNodeRef<"webview">, path: string): Promise<InstalledExtension[]>;
|
|
40
|
+
export declare function uninstallExtension(node: NdNodeRef<"webview">, extensionId: string): Promise<InstalledExtension[]>;
|
|
41
|
+
export declare function setExtensionEnabled(node: NdNodeRef<"webview">, extensionId: string, enabled: boolean): Promise<InstalledExtension[]>;
|
|
42
|
+
export interface ExtensionAction {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
/** `action.default_title`, falling back to the extension's name. */
|
|
47
|
+
title: string;
|
|
48
|
+
/** `chrome-extension://…` icon from `action.default_icon`, or the registry icon. */
|
|
49
|
+
iconUrl: string;
|
|
50
|
+
/** `chrome-extension://…` popup page, or "" for an action that fires `onClicked`. */
|
|
51
|
+
popupUrl: string;
|
|
52
|
+
/** Always "": Chromium answers `chrome.action.getBadgeText` to the extension alone. */
|
|
53
|
+
badgeText: string;
|
|
54
|
+
}
|
|
55
|
+
export declare function listExtensionActions(node: NdNodeRef<"webview">): Promise<ExtensionAction[]>;
|
|
56
|
+
export declare function onExtensionActions(e: {
|
|
57
|
+
data: unknown;
|
|
58
|
+
}): void;
|
|
25
59
|
export type ContextMenuContext = "all" | "page" | "link" | "image" | "selection" | "editable";
|
|
26
60
|
export interface ContextMenuItem {
|
|
27
61
|
id?: string;
|
package/dist/runtime/ndp.d.ts
CHANGED
|
@@ -2,6 +2,9 @@ import type { Runtime, Op, CommitBatch, EventMsg } from "../packages/react/src/g
|
|
|
2
2
|
export declare class Ndp {
|
|
3
3
|
private socket;
|
|
4
4
|
private inbox;
|
|
5
|
+
private inboxView;
|
|
6
|
+
private inboxHead;
|
|
7
|
+
private inboxTail;
|
|
5
8
|
private eventCb;
|
|
6
9
|
private helloAckResolve;
|
|
7
10
|
private outbox;
|
|
@@ -22,6 +25,8 @@ export declare class Ndp {
|
|
|
22
25
|
get hostCommands(): Set<string> | null;
|
|
23
26
|
static connect(): Promise<Ndp>;
|
|
24
27
|
private pump;
|
|
28
|
+
private reserveInbox;
|
|
29
|
+
private compactInbox;
|
|
25
30
|
private onData;
|
|
26
31
|
private dispatch;
|
|
27
32
|
private send;
|