@aipanel/dsh-client 1.2.7 → 1.2.8
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/lib/client.js +80 -11
- package/package.json +8 -5
package/lib/client.js
CHANGED
|
@@ -285,7 +285,7 @@ function registerDiagnosticsView(ctx) {
|
|
|
285
285
|
|
|
286
286
|
// dsh-client/src/client/index.ts
|
|
287
287
|
var SELECTION_STORAGE_KEY = "dsh.bridge.selection";
|
|
288
|
-
var inject = ["slots"];
|
|
288
|
+
var inject = ["slots", "sessions", "inputTriggers", "conversation"];
|
|
289
289
|
var SESSION_READY_EVENT = "aipanel:session-ready";
|
|
290
290
|
var INSERT_ELEMENT_EVENT = "aipanel:insert-element";
|
|
291
291
|
var SESSION_SETTLE_MS = 400;
|
|
@@ -447,12 +447,46 @@ function apply(ctx) {
|
|
|
447
447
|
let start = snapshot.draft.length;
|
|
448
448
|
let end = snapshot.draft.length;
|
|
449
449
|
try {
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
450
|
+
const composer = document.querySelector(
|
|
451
|
+
'[role="textbox"][contenteditable="true"], textarea[data-phase]'
|
|
452
|
+
);
|
|
453
|
+
if (composer) {
|
|
454
|
+
if (composer.isContentEditable) {
|
|
455
|
+
const draftInComposer = (composer.innerText ?? "").replace(/\n$/, "");
|
|
456
|
+
if (draftInComposer === snapshot.draft) {
|
|
457
|
+
const sel = window.getSelection();
|
|
458
|
+
if (sel && sel.rangeCount > 0 && sel.anchorNode && sel.focusNode && composer.contains(sel.anchorNode) && composer.contains(sel.focusNode)) {
|
|
459
|
+
const textNodes = [];
|
|
460
|
+
const walker = document.createTreeWalker(composer, NodeFilter.SHOW_TEXT);
|
|
461
|
+
let n = walker.nextNode();
|
|
462
|
+
while (n) {
|
|
463
|
+
textNodes.push(n);
|
|
464
|
+
n = walker.nextNode();
|
|
465
|
+
}
|
|
466
|
+
const posOf = (node, off) => {
|
|
467
|
+
const idx = textNodes.indexOf(node);
|
|
468
|
+
if (idx < 0) return null;
|
|
469
|
+
let acc = 0;
|
|
470
|
+
for (let i = 0; i < idx; i++) acc += textNodes[i].data.length;
|
|
471
|
+
return acc + Math.min(off, textNodes[idx].data.length);
|
|
472
|
+
};
|
|
473
|
+
const s = posOf(sel.anchorNode, sel.anchorOffset);
|
|
474
|
+
const e = posOf(sel.focusNode, sel.focusOffset);
|
|
475
|
+
if (s !== null && e !== null) {
|
|
476
|
+
start = Math.min(Math.max(s, 0), snapshot.draft.length);
|
|
477
|
+
end = Math.min(Math.max(e, start), snapshot.draft.length);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
} else {
|
|
482
|
+
const ta = composer;
|
|
483
|
+
if (ta.value === snapshot.draft) {
|
|
484
|
+
const s = ta.selectionStart ?? snapshot.draft.length;
|
|
485
|
+
const e = ta.selectionEnd ?? s;
|
|
486
|
+
start = Math.min(s, snapshot.draft.length);
|
|
487
|
+
end = Math.min(e, snapshot.draft.length);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
456
490
|
}
|
|
457
491
|
} catch {
|
|
458
492
|
}
|
|
@@ -479,11 +513,46 @@ function apply(ctx) {
|
|
|
479
513
|
input.insertReference(reference, { start, end, draftRev: rev });
|
|
480
514
|
requestAnimationFrame(() => {
|
|
481
515
|
try {
|
|
482
|
-
const el = document.querySelector(
|
|
516
|
+
const el = document.querySelector(
|
|
517
|
+
'[role="textbox"][contenteditable="true"], textarea[data-phase]'
|
|
518
|
+
);
|
|
483
519
|
if (!el) return;
|
|
484
|
-
const caret =
|
|
485
|
-
el.
|
|
486
|
-
|
|
520
|
+
const caret = start + insertedLen + leadingSpace;
|
|
521
|
+
if (el.isContentEditable) {
|
|
522
|
+
const textNodes = [];
|
|
523
|
+
const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
|
524
|
+
let n = walker.nextNode();
|
|
525
|
+
while (n) {
|
|
526
|
+
textNodes.push(n);
|
|
527
|
+
n = walker.nextNode();
|
|
528
|
+
}
|
|
529
|
+
let target = textNodes[textNodes.length - 1] ?? null;
|
|
530
|
+
let off = target ? target.data.length : 0;
|
|
531
|
+
let remaining = Math.max(0, caret);
|
|
532
|
+
if (target) {
|
|
533
|
+
for (const t of textNodes) {
|
|
534
|
+
if (remaining <= t.data.length) {
|
|
535
|
+
target = t;
|
|
536
|
+
off = remaining;
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
remaining -= t.data.length;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
if (target) {
|
|
543
|
+
const range = document.createRange();
|
|
544
|
+
range.setStart(target, Math.min(off, target.data.length));
|
|
545
|
+
range.collapse(true);
|
|
546
|
+
const sel = window.getSelection();
|
|
547
|
+
sel?.removeAllRanges();
|
|
548
|
+
sel?.addRange(range);
|
|
549
|
+
}
|
|
550
|
+
el.focus();
|
|
551
|
+
} else {
|
|
552
|
+
const ta = el;
|
|
553
|
+
ta.focus();
|
|
554
|
+
ta.setSelectionRange(Math.min(caret, ta.value.length), Math.min(caret, ta.value.length));
|
|
555
|
+
}
|
|
487
556
|
} catch {
|
|
488
557
|
}
|
|
489
558
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aipanel/dsh-client",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AIPanel 浏览器侧插件(dsh web Web Client):注册 @aipanel 文件引用 source,选中元素以 file chip 高亮插入并可供模型解析。",
|
|
6
6
|
"publishConfig": {
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"lib"
|
|
12
12
|
],
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
15
|
-
"@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.
|
|
16
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.
|
|
14
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
15
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.2-rc.1",
|
|
16
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-rc.1",
|
|
17
17
|
"@types/react": "^18.3.0",
|
|
18
18
|
"esbuild": "^0.25.0",
|
|
19
19
|
"react": "^18.3.0"
|
|
@@ -27,7 +27,10 @@
|
|
|
27
27
|
"client": {
|
|
28
28
|
"platform": "web",
|
|
29
29
|
"inject": [
|
|
30
|
-
"slots"
|
|
30
|
+
"slots",
|
|
31
|
+
"sessions",
|
|
32
|
+
"inputTriggers",
|
|
33
|
+
"conversation"
|
|
31
34
|
]
|
|
32
35
|
}
|
|
33
36
|
},
|