xterm-input-panel 1.2.0 → 1.2.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.
@@ -96,23 +96,135 @@ function terminalPage(): ShortcutPage {
96
96
  cols: GRID_COLS,
97
97
  rows: GRID_ROWS,
98
98
  items: [
99
- { id: 'ctrl-w', label: 'Kill Word', subLabel: 'Ctrl+W', col: 3, row: ROW_Q, cols: 2, action: { type: 'send', data: '\x17' } },
100
- { id: 'ctrl-r', label: 'History Search', subLabel: 'Ctrl+R', col: 5, row: ROW_Q, cols: 2, action: { type: 'send', data: '\x12' } },
101
- { id: 'ctrl-u', label: 'Kill Left', subLabel: 'Ctrl+U', col: 8, row: ROW_Q, cols: 2, action: { type: 'send', data: '\x15' } },
102
-
103
- { id: 'ctrl-a', label: 'Line Start', subLabel: 'Ctrl+A', col: 2, row: ROW_A, cols: 2, action: { type: 'send', data: '\x01' } },
104
- { id: 'ctrl-d', label: 'EOF', subLabel: 'Ctrl+D', col: 4, row: ROW_A, cols: 2, action: { type: 'send', data: '\x04' } },
105
- { id: 'ctrl-f', label: 'Char Right', subLabel: 'Ctrl+F', col: 6, row: ROW_A, cols: 2, action: { type: 'send', data: '\x06' } },
106
- { id: 'ctrl-k', label: 'Kill Right', subLabel: 'Ctrl+K', col: 9, row: ROW_A, cols: 2, action: { type: 'send', data: '\x0b' } },
107
- { id: 'ctrl-l', label: 'Clear', subLabel: 'Ctrl+L', col: 11, row: ROW_A, cols: 2, action: { type: 'send', data: '\x0c' } },
108
-
109
- { id: 'ctrl-z', label: 'Suspend', subLabel: 'Ctrl+Z', col: 3, row: ROW_Z, cols: 2, action: { type: 'send', data: '\x1a' } },
110
- { id: 'ctrl-c', label: 'Interrupt', subLabel: 'Ctrl+C', col: 5, row: ROW_Z, cols: 2, action: { type: 'send', data: '\x03' } },
111
- { id: 'ctrl-v', label: 'Literal', subLabel: 'Ctrl+V', col: 7, row: ROW_Z, cols: 2, action: { type: 'send', data: '\x16' } },
112
- { id: 'ctrl-y', label: 'Yank', subLabel: 'Ctrl+Y', col: 9, row: ROW_Z, cols: 2, action: { type: 'send', data: '\x19' } },
113
-
114
- { id: 'alt-b', label: 'Prev Word', subLabel: 'Alt+B', col: 6, row: ROW_BOTTOM, cols: 2, action: { type: 'send', data: '\x1bb' } },
115
- { id: 'alt-f', label: 'Next Word', subLabel: 'Alt+F', col: 8, row: ROW_BOTTOM, cols: 2, action: { type: 'send', data: '\x1bf' } },
99
+ {
100
+ id: 'ctrl-w',
101
+ label: 'Kill Word',
102
+ subLabel: 'Ctrl+W',
103
+ col: 3,
104
+ row: ROW_Q,
105
+ cols: 2,
106
+ action: { type: 'send', data: '\x17' },
107
+ },
108
+ {
109
+ id: 'ctrl-r',
110
+ label: 'History Search',
111
+ subLabel: 'Ctrl+R',
112
+ col: 5,
113
+ row: ROW_Q,
114
+ cols: 2,
115
+ action: { type: 'send', data: '\x12' },
116
+ },
117
+ {
118
+ id: 'ctrl-u',
119
+ label: 'Kill Left',
120
+ subLabel: 'Ctrl+U',
121
+ col: 8,
122
+ row: ROW_Q,
123
+ cols: 2,
124
+ action: { type: 'send', data: '\x15' },
125
+ },
126
+
127
+ {
128
+ id: 'ctrl-a',
129
+ label: 'Line Start',
130
+ subLabel: 'Ctrl+A',
131
+ col: 2,
132
+ row: ROW_A,
133
+ cols: 2,
134
+ action: { type: 'send', data: '\x01' },
135
+ },
136
+ {
137
+ id: 'ctrl-d',
138
+ label: 'EOF',
139
+ subLabel: 'Ctrl+D',
140
+ col: 4,
141
+ row: ROW_A,
142
+ cols: 2,
143
+ action: { type: 'send', data: '\x04' },
144
+ },
145
+ {
146
+ id: 'ctrl-f',
147
+ label: 'Char Right',
148
+ subLabel: 'Ctrl+F',
149
+ col: 6,
150
+ row: ROW_A,
151
+ cols: 2,
152
+ action: { type: 'send', data: '\x06' },
153
+ },
154
+ {
155
+ id: 'ctrl-k',
156
+ label: 'Kill Right',
157
+ subLabel: 'Ctrl+K',
158
+ col: 9,
159
+ row: ROW_A,
160
+ cols: 2,
161
+ action: { type: 'send', data: '\x0b' },
162
+ },
163
+ {
164
+ id: 'ctrl-l',
165
+ label: 'Clear',
166
+ subLabel: 'Ctrl+L',
167
+ col: 11,
168
+ row: ROW_A,
169
+ cols: 2,
170
+ action: { type: 'send', data: '\x0c' },
171
+ },
172
+
173
+ {
174
+ id: 'ctrl-z',
175
+ label: 'Suspend',
176
+ subLabel: 'Ctrl+Z',
177
+ col: 3,
178
+ row: ROW_Z,
179
+ cols: 2,
180
+ action: { type: 'send', data: '\x1a' },
181
+ },
182
+ {
183
+ id: 'ctrl-c',
184
+ label: 'Interrupt',
185
+ subLabel: 'Ctrl+C',
186
+ col: 5,
187
+ row: ROW_Z,
188
+ cols: 2,
189
+ action: { type: 'send', data: '\x03' },
190
+ },
191
+ {
192
+ id: 'ctrl-v',
193
+ label: 'Literal',
194
+ subLabel: 'Ctrl+V',
195
+ col: 7,
196
+ row: ROW_Z,
197
+ cols: 2,
198
+ action: { type: 'send', data: '\x16' },
199
+ },
200
+ {
201
+ id: 'ctrl-y',
202
+ label: 'Yank',
203
+ subLabel: 'Ctrl+Y',
204
+ col: 9,
205
+ row: ROW_Z,
206
+ cols: 2,
207
+ action: { type: 'send', data: '\x19' },
208
+ },
209
+
210
+ {
211
+ id: 'alt-b',
212
+ label: 'Prev Word',
213
+ subLabel: 'Alt+B',
214
+ col: 6,
215
+ row: ROW_BOTTOM,
216
+ cols: 2,
217
+ action: { type: 'send', data: '\x1bb' },
218
+ },
219
+ {
220
+ id: 'alt-f',
221
+ label: 'Next Word',
222
+ subLabel: 'Alt+F',
223
+ col: 8,
224
+ row: ROW_BOTTOM,
225
+ cols: 2,
226
+ action: { type: 'send', data: '\x1bf' },
227
+ },
116
228
  ],
117
229
  }
118
230
  }
@@ -125,20 +237,116 @@ function claudePage(): ShortcutPage {
125
237
  cols: GRID_COLS,
126
238
  rows: GRID_ROWS,
127
239
  items: [
128
- { id: 'claude-commands', label: '/ Commands', subLabel: '/', col: 1, row: ROW_TOP, cols: 2, action: { type: 'text', text: '/' } },
129
- { id: 'claude-shell', label: '! Shell', subLabel: '!', col: 3, row: ROW_TOP, cols: 2, action: { type: 'text', text: '!' } },
130
- { id: 'claude-files', label: '@ Paths', subLabel: '@', col: 5, row: ROW_TOP, cols: 2, action: { type: 'text', text: '@' } },
131
- { id: 'claude-newline', label: 'Newline', subLabel: '\\ + Enter', col: 8, row: ROW_TOP, cols: 3, action: { type: 'text', text: '\\\n' } },
132
- { id: 'claude-edit-last', label: 'Edit Previous', subLabel: 'Esc Esc', col: 11, row: ROW_TOP, cols: 3, action: { type: 'send', data: '\x1b\x1b' } },
133
-
134
- { id: 'claude-editor', label: 'External Editor', subLabel: 'Ctrl+G', col: 2, row: ROW_A, cols: 3, action: { type: 'send', data: '\x07' } },
135
- { id: 'claude-reverse-search', label: 'History Search', subLabel: 'Ctrl+R', col: 5, row: ROW_A, cols: 3, action: { type: 'send', data: '\x12' } },
136
- { id: 'claude-bg', label: 'Background Task', subLabel: 'Ctrl+B', col: 8, row: ROW_A, cols: 3, action: { type: 'send', data: '\x02' } },
137
- { id: 'claude-task-list', label: 'Task List', subLabel: 'Ctrl+T', col: 11, row: ROW_A, cols: 3, action: { type: 'send', data: '\x14' } },
138
-
139
- { id: 'claude-change-mode', label: 'Change Mode', subLabel: 'Shift+Tab', col: 1, row: ROW_BOTTOM, cols: 3, action: { type: 'send', data: '\x1b[Z' } },
140
- { id: 'claude-cancel', label: 'Cancel', subLabel: 'Ctrl+C', col: 4, row: ROW_BOTTOM, cols: 3, action: { type: 'send', data: '\x03' } },
141
- { id: 'claude-exit', label: 'Exit', subLabel: 'Ctrl+D', col: 7, row: ROW_BOTTOM, cols: 3, action: { type: 'send', data: '\x04' } },
240
+ {
241
+ id: 'claude-commands',
242
+ label: '/ Commands',
243
+ subLabel: '/',
244
+ col: 1,
245
+ row: ROW_TOP,
246
+ cols: 2,
247
+ action: { type: 'text', text: '/' },
248
+ },
249
+ {
250
+ id: 'claude-shell',
251
+ label: '! Shell',
252
+ subLabel: '!',
253
+ col: 3,
254
+ row: ROW_TOP,
255
+ cols: 2,
256
+ action: { type: 'text', text: '!' },
257
+ },
258
+ {
259
+ id: 'claude-files',
260
+ label: '@ Paths',
261
+ subLabel: '@',
262
+ col: 5,
263
+ row: ROW_TOP,
264
+ cols: 2,
265
+ action: { type: 'text', text: '@' },
266
+ },
267
+ {
268
+ id: 'claude-newline',
269
+ label: 'Newline',
270
+ subLabel: '\\ + Enter',
271
+ col: 8,
272
+ row: ROW_TOP,
273
+ cols: 3,
274
+ action: { type: 'text', text: '\\\n' },
275
+ },
276
+ {
277
+ id: 'claude-edit-last',
278
+ label: 'Edit Previous',
279
+ subLabel: 'Esc Esc',
280
+ col: 11,
281
+ row: ROW_TOP,
282
+ cols: 3,
283
+ action: { type: 'send', data: '\x1b\x1b' },
284
+ },
285
+
286
+ {
287
+ id: 'claude-editor',
288
+ label: 'External Editor',
289
+ subLabel: 'Ctrl+G',
290
+ col: 2,
291
+ row: ROW_A,
292
+ cols: 3,
293
+ action: { type: 'send', data: '\x07' },
294
+ },
295
+ {
296
+ id: 'claude-reverse-search',
297
+ label: 'History Search',
298
+ subLabel: 'Ctrl+R',
299
+ col: 5,
300
+ row: ROW_A,
301
+ cols: 3,
302
+ action: { type: 'send', data: '\x12' },
303
+ },
304
+ {
305
+ id: 'claude-bg',
306
+ label: 'Background Task',
307
+ subLabel: 'Ctrl+B',
308
+ col: 8,
309
+ row: ROW_A,
310
+ cols: 3,
311
+ action: { type: 'send', data: '\x02' },
312
+ },
313
+ {
314
+ id: 'claude-task-list',
315
+ label: 'Task List',
316
+ subLabel: 'Ctrl+T',
317
+ col: 11,
318
+ row: ROW_A,
319
+ cols: 3,
320
+ action: { type: 'send', data: '\x14' },
321
+ },
322
+
323
+ {
324
+ id: 'claude-change-mode',
325
+ label: 'Change Mode',
326
+ subLabel: 'Shift+Tab',
327
+ col: 1,
328
+ row: ROW_BOTTOM,
329
+ cols: 3,
330
+ action: { type: 'send', data: '\x1b[Z' },
331
+ },
332
+ {
333
+ id: 'claude-cancel',
334
+ label: 'Cancel',
335
+ subLabel: 'Ctrl+C',
336
+ col: 4,
337
+ row: ROW_BOTTOM,
338
+ cols: 3,
339
+ action: { type: 'send', data: '\x03' },
340
+ },
341
+ {
342
+ id: 'claude-exit',
343
+ label: 'Exit',
344
+ subLabel: 'Ctrl+D',
345
+ col: 7,
346
+ row: ROW_BOTTOM,
347
+ cols: 3,
348
+ action: { type: 'send', data: '\x04' },
349
+ },
142
350
  ],
143
351
  }
144
352
  }
@@ -151,20 +359,108 @@ function codexPage(platform: HostPlatform): ShortcutPage {
151
359
  cols: GRID_COLS,
152
360
  rows: GRID_ROWS,
153
361
  items: [
154
- { id: 'codex-commands', label: '/ Commands', subLabel: '/', col: 1, row: ROW_TOP, cols: 2, action: { type: 'text', text: '/' } },
155
- { id: 'codex-shell', label: '! Shell', subLabel: '!', col: 3, row: ROW_TOP, cols: 2, action: { type: 'text', text: '!' } },
156
- { id: 'codex-files', label: '@ Paths', subLabel: '@', col: 5, row: ROW_TOP, cols: 2, action: { type: 'text', text: '@' } },
157
- { id: 'codex-newline', label: 'Newline', subLabel: 'Shift+Enter', col: 8, row: ROW_TOP, cols: 3, action: { type: 'send', data: '\n' } },
158
- { id: 'codex-queue', label: 'Queue Message', subLabel: 'Tab', col: 11, row: ROW_TOP, cols: 3, action: { type: 'send', data: '\t' } },
362
+ {
363
+ id: 'codex-commands',
364
+ label: '/ Commands',
365
+ subLabel: '/',
366
+ col: 1,
367
+ row: ROW_TOP,
368
+ cols: 2,
369
+ action: { type: 'text', text: '/' },
370
+ },
371
+ {
372
+ id: 'codex-shell',
373
+ label: '! Shell',
374
+ subLabel: '!',
375
+ col: 3,
376
+ row: ROW_TOP,
377
+ cols: 2,
378
+ action: { type: 'text', text: '!' },
379
+ },
380
+ {
381
+ id: 'codex-files',
382
+ label: '@ Paths',
383
+ subLabel: '@',
384
+ col: 5,
385
+ row: ROW_TOP,
386
+ cols: 2,
387
+ action: { type: 'text', text: '@' },
388
+ },
389
+ {
390
+ id: 'codex-newline',
391
+ label: 'Newline',
392
+ subLabel: 'Shift+Enter',
393
+ col: 8,
394
+ row: ROW_TOP,
395
+ cols: 3,
396
+ action: { type: 'send', data: '\n' },
397
+ },
398
+ {
399
+ id: 'codex-queue',
400
+ label: 'Queue Message',
401
+ subLabel: 'Tab',
402
+ col: 11,
403
+ row: ROW_TOP,
404
+ cols: 3,
405
+ action: { type: 'send', data: '\t' },
406
+ },
159
407
 
160
- { id: 'codex-editor', label: 'External Editor', subLabel: 'Ctrl+G', col: 4, row: ROW_A, cols: 3, action: { type: 'send', data: '\x07' } },
161
- { id: 'codex-edit-last', label: 'Edit Previous', subLabel: 'Esc Esc', col: 7, row: ROW_A, cols: 3, action: { type: 'send', data: '\x1b\x1b' } },
162
- { id: 'codex-transcript', label: 'Transcript', subLabel: 'Ctrl+T', col: 10, row: ROW_A, cols: 3, action: { type: 'send', data: '\x14' } },
408
+ {
409
+ id: 'codex-editor',
410
+ label: 'External Editor',
411
+ subLabel: 'Ctrl+G',
412
+ col: 4,
413
+ row: ROW_A,
414
+ cols: 3,
415
+ action: { type: 'send', data: '\x07' },
416
+ },
417
+ {
418
+ id: 'codex-edit-last',
419
+ label: 'Edit Previous',
420
+ subLabel: 'Esc Esc',
421
+ col: 7,
422
+ row: ROW_A,
423
+ cols: 3,
424
+ action: { type: 'send', data: '\x1b\x1b' },
425
+ },
426
+ {
427
+ id: 'codex-transcript',
428
+ label: 'Transcript',
429
+ subLabel: 'Ctrl+T',
430
+ col: 10,
431
+ row: ROW_A,
432
+ cols: 3,
433
+ action: { type: 'send', data: '\x14' },
434
+ },
163
435
 
164
- { id: 'codex-paste-image', label: 'Paste Image', subLabel: codexPasteImageLabel(platform), col: 6, row: ROW_Z, cols: 3, action: { type: 'send', data: '\x16' } },
436
+ {
437
+ id: 'codex-paste-image',
438
+ label: 'Paste Image',
439
+ subLabel: codexPasteImageLabel(platform),
440
+ col: 6,
441
+ row: ROW_Z,
442
+ cols: 3,
443
+ action: { type: 'send', data: '\x16' },
444
+ },
165
445
 
166
- { id: 'codex-change-mode', label: 'Change Mode', subLabel: 'Shift+Tab', col: 1, row: ROW_BOTTOM, cols: 3, action: { type: 'send', data: '\x1b[Z' } },
167
- { id: 'codex-exit', label: 'Exit', subLabel: 'Ctrl+C', col: 4, row: ROW_BOTTOM, cols: 3, action: { type: 'send', data: '\x03' } },
446
+ {
447
+ id: 'codex-change-mode',
448
+ label: 'Change Mode',
449
+ subLabel: 'Shift+Tab',
450
+ col: 1,
451
+ row: ROW_BOTTOM,
452
+ cols: 3,
453
+ action: { type: 'send', data: '\x1b[Z' },
454
+ },
455
+ {
456
+ id: 'codex-exit',
457
+ label: 'Exit',
458
+ subLabel: 'Ctrl+C',
459
+ col: 4,
460
+ row: ROW_BOTTOM,
461
+ cols: 3,
462
+ action: { type: 'send', data: '\x03' },
463
+ },
168
464
  ],
169
465
  }
170
466
  }
@@ -177,28 +473,102 @@ function geminiPage(): ShortcutPage {
177
473
  cols: GRID_COLS,
178
474
  rows: GRID_ROWS,
179
475
  items: [
180
- { id: 'gemini-shell-mode', label: 'Shell Mode', subLabel: '!', col: 1, row: ROW_TOP, cols: 2, action: { type: 'text', text: '!' } },
181
- { id: 'gemini-shortcuts-panel', label: 'Shortcuts', subLabel: '?', col: 3, row: ROW_TOP, cols: 2, action: { type: 'text', text: '?' } },
182
- { id: 'gemini-editor', label: 'External Editor', subLabel: 'Ctrl+X', col: 5, row: ROW_TOP, cols: 3, action: { type: 'send', data: '\x18' } },
183
- { id: 'gemini-reverse-search', label: 'Reverse Search', subLabel: 'Ctrl+R', col: 8, row: ROW_TOP, cols: 3, action: { type: 'send', data: '\x12' } },
184
- { id: 'gemini-edit-last', label: 'Edit Previous', subLabel: 'Esc Esc', col: 11, row: ROW_TOP, cols: 3, action: { type: 'send', data: '\x1b\x1b' } },
185
-
186
- { id: 'gemini-ide-context', label: 'IDE Context', subLabel: 'Ctrl+G', col: 4, row: ROW_A, cols: 3, action: { type: 'send', data: '\x07' } },
187
- { id: 'gemini-todo-list', label: 'TODO List', subLabel: 'Ctrl+T', col: 7, row: ROW_A, cols: 3, action: { type: 'send', data: '\x14' } },
188
- { id: 'gemini-change-mode', label: 'Change Mode', subLabel: 'Shift+Tab', col: 10, row: ROW_A, cols: 3, action: { type: 'send', data: '\x1b[Z' } },
189
-
190
- { id: 'gemini-cancel', label: 'Cancel', subLabel: 'Ctrl+C', col: 4, row: ROW_BOTTOM, cols: 3, action: { type: 'send', data: '\x03' } },
191
- { id: 'gemini-exit', label: 'Exit Empty', subLabel: 'Ctrl+D', col: 7, row: ROW_BOTTOM, cols: 3, action: { type: 'send', data: '\x04' } },
476
+ {
477
+ id: 'gemini-shell-mode',
478
+ label: 'Shell Mode',
479
+ subLabel: '!',
480
+ col: 1,
481
+ row: ROW_TOP,
482
+ cols: 2,
483
+ action: { type: 'text', text: '!' },
484
+ },
485
+ {
486
+ id: 'gemini-shortcuts-panel',
487
+ label: 'Shortcuts',
488
+ subLabel: '?',
489
+ col: 3,
490
+ row: ROW_TOP,
491
+ cols: 2,
492
+ action: { type: 'text', text: '?' },
493
+ },
494
+ {
495
+ id: 'gemini-editor',
496
+ label: 'External Editor',
497
+ subLabel: 'Ctrl+X',
498
+ col: 5,
499
+ row: ROW_TOP,
500
+ cols: 3,
501
+ action: { type: 'send', data: '\x18' },
502
+ },
503
+ {
504
+ id: 'gemini-reverse-search',
505
+ label: 'Reverse Search',
506
+ subLabel: 'Ctrl+R',
507
+ col: 8,
508
+ row: ROW_TOP,
509
+ cols: 3,
510
+ action: { type: 'send', data: '\x12' },
511
+ },
512
+ {
513
+ id: 'gemini-edit-last',
514
+ label: 'Edit Previous',
515
+ subLabel: 'Esc Esc',
516
+ col: 11,
517
+ row: ROW_TOP,
518
+ cols: 3,
519
+ action: { type: 'send', data: '\x1b\x1b' },
520
+ },
521
+
522
+ {
523
+ id: 'gemini-ide-context',
524
+ label: 'IDE Context',
525
+ subLabel: 'Ctrl+G',
526
+ col: 4,
527
+ row: ROW_A,
528
+ cols: 3,
529
+ action: { type: 'send', data: '\x07' },
530
+ },
531
+ {
532
+ id: 'gemini-todo-list',
533
+ label: 'TODO List',
534
+ subLabel: 'Ctrl+T',
535
+ col: 7,
536
+ row: ROW_A,
537
+ cols: 3,
538
+ action: { type: 'send', data: '\x14' },
539
+ },
540
+ {
541
+ id: 'gemini-change-mode',
542
+ label: 'Change Mode',
543
+ subLabel: 'Shift+Tab',
544
+ col: 10,
545
+ row: ROW_A,
546
+ cols: 3,
547
+ action: { type: 'send', data: '\x1b[Z' },
548
+ },
549
+
550
+ {
551
+ id: 'gemini-cancel',
552
+ label: 'Cancel',
553
+ subLabel: 'Ctrl+C',
554
+ col: 4,
555
+ row: ROW_BOTTOM,
556
+ cols: 3,
557
+ action: { type: 'send', data: '\x03' },
558
+ },
559
+ {
560
+ id: 'gemini-exit',
561
+ label: 'Exit Empty',
562
+ subLabel: 'Ctrl+D',
563
+ col: 7,
564
+ row: ROW_BOTTOM,
565
+ cols: 3,
566
+ action: { type: 'send', data: '\x04' },
567
+ },
192
568
  ],
193
569
  }
194
570
  }
195
571
 
196
572
  export function buildShortcutPages(platform: HostPlatform): ShortcutPage[] {
197
- return [
198
- systemPage(platform),
199
- terminalPage(),
200
- claudePage(),
201
- codexPage(platform),
202
- geminiPage(),
203
- ]
573
+ return [systemPage(platform), terminalPage(), claudePage(), codexPage(platform), geminiPage()]
204
574
  }
@@ -1,9 +1,22 @@
1
- import { LitElement, css, html } from 'lit'
2
- import { Application, CanvasTextMetrics, Container, FederatedPointerEvent, Graphics, Text, TextStyle } from 'pixi.js'
1
+ import { css, html, LitElement } from 'lit'
3
2
  import { createElement, SquareSlash, SquareTerminal } from 'lucide'
4
- import { resolvePixiTheme, onThemeChange, type PixiTheme } from './pixi-theme.js'
5
- import { buildShortcutPages, type ShortcutAction, type ShortcutItem, type ShortcutPage } from './shortcut-pages.js'
3
+ import {
4
+ Application,
5
+ CanvasTextMetrics,
6
+ Container,
7
+ FederatedPointerEvent,
8
+ Graphics,
9
+ Text,
10
+ TextStyle,
11
+ } from 'pixi.js'
12
+ import { onThemeChange, resolvePixiTheme, type PixiTheme } from './pixi-theme.js'
6
13
  import { detectHostPlatform, type PlatformMode } from './platform.js'
14
+ import {
15
+ buildShortcutPages,
16
+ type ShortcutAction,
17
+ type ShortcutItem,
18
+ type ShortcutPage,
19
+ } from './shortcut-pages.js'
7
20
 
8
21
  const GRID_GAP = 8
9
22
  const GRID_PADDING = 10
@@ -66,7 +79,10 @@ export class ShortcutTab extends LitElement {
66
79
  justify-content: center;
67
80
  padding: 0;
68
81
  cursor: pointer;
69
- transition: border-color 0.15s, color 0.15s, background 0.15s;
82
+ transition:
83
+ border-color 0.15s,
84
+ color 0.15s,
85
+ background 0.15s;
70
86
  }
71
87
 
72
88
  .page-btn:hover {
@@ -247,9 +263,7 @@ export class ShortcutTab extends LitElement {
247
263
  gfx.clear()
248
264
  gfx.roundRect(0, 0, width, height, CARD_RADIUS)
249
265
  gfx.fill({
250
- color: pressed
251
- ? this._theme.keyPressed
252
- : this._theme.keyNormal,
266
+ color: pressed ? this._theme.keyPressed : this._theme.keyNormal,
253
267
  })
254
268
  gfx.stroke({
255
269
  color: pressed ? this._theme.accent : this._theme.surfaceBorder,
@@ -409,7 +423,7 @@ export class ShortcutTab extends LitElement {
409
423
  detail: { data },
410
424
  bubbles: true,
411
425
  composed: true,
412
- }),
426
+ })
413
427
  )
414
428
  }
415
429
 
@@ -443,7 +457,12 @@ export class ShortcutTab extends LitElement {
443
457
  document.execCommand('selectAll')
444
458
  }
445
459
 
446
- private _dpadData(event: FederatedPointerEvent, width: number, height: number, container: Container): string {
460
+ private _dpadData(
461
+ event: FederatedPointerEvent,
462
+ width: number,
463
+ height: number,
464
+ container: Container
465
+ ): string {
447
466
  const local = container.toLocal(event.global)
448
467
  const dx = local.x - width / 2
449
468
  const dy = local.y - height / 2
@@ -463,7 +482,7 @@ export class ShortcutTab extends LitElement {
463
482
  event: FederatedPointerEvent,
464
483
  width: number,
465
484
  height: number,
466
- container: Container,
485
+ container: Container
467
486
  ) {
468
487
  if (item.kind === 'dpad') {
469
488
  this._send(this._dpadData(event, width, height, container))
@@ -518,19 +537,21 @@ export class ShortcutTab extends LitElement {
518
537
  return html`
519
538
  <div class="layout">
520
539
  <div class="pages">
521
- ${pages.map((page) => html`
522
- <button
523
- type="button"
524
- class="page-btn"
525
- title=${page.title}
526
- aria-label=${page.title}
527
- ?data-active=${page.id === activePage.id}
528
- @click=${() => this._setActivePage(page.id)}
529
- >
530
- ${this._renderPageIcon(page.id)}
531
- <span class="sr-only">${page.title}</span>
532
- </button>
533
- `)}
540
+ ${pages.map(
541
+ (page) => html`
542
+ <button
543
+ type="button"
544
+ class="page-btn"
545
+ title=${page.title}
546
+ aria-label=${page.title}
547
+ ?data-active=${page.id === activePage.id}
548
+ @click=${() => this._setActivePage(page.id)}
549
+ >
550
+ ${this._renderPageIcon(page.id)}
551
+ <span class="sr-only">${page.title}</span>
552
+ </button>
553
+ `
554
+ )}
534
555
  </div>
535
556
  <div class="canvas-wrap">
536
557
  <div class="pixi-host"></div>
@@ -0,0 +1,22 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { getSessionScopedStorageKey } from './storage-namespace'
3
+
4
+ describe('storage namespace helpers', () => {
5
+ it('scopes hosted version entries by session', () => {
6
+ expect(
7
+ getSessionScopedStorageKey('xtermInputPanelState', {
8
+ pathname: '/versions/v2.1/index.html',
9
+ search: '?session=session-a',
10
+ })
11
+ ).toBe('hosted-session:session-a:xtermInputPanelState')
12
+ })
13
+
14
+ it('keeps non-hosted keys unchanged', () => {
15
+ expect(
16
+ getSessionScopedStorageKey('xtermInputPanelState', {
17
+ pathname: '/dashboard',
18
+ search: '?session=session-a',
19
+ })
20
+ ).toBe('xtermInputPanelState')
21
+ })
22
+ })
@@ -0,0 +1,17 @@
1
+ const HOSTED_VERSION_PATH_RE = /^\/versions\/[^/]+(?:\/|$)/
2
+
3
+ function getHostedSessionId(locationLike: Pick<Location, 'pathname' | 'search'>): string | null {
4
+ if (!HOSTED_VERSION_PATH_RE.test(locationLike.pathname)) {
5
+ return null
6
+ }
7
+ const value = new URLSearchParams(locationLike.search).get('session')?.trim()
8
+ return value ? value : null
9
+ }
10
+
11
+ export function getSessionScopedStorageKey(
12
+ baseKey: string,
13
+ locationLike: Pick<Location, 'pathname' | 'search'> = window.location
14
+ ): string {
15
+ const sessionId = getHostedSessionId(locationLike)
16
+ return sessionId ? `hosted-session:${sessionId}:${baseKey}` : baseKey
17
+ }