Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ jobs:
matrix:
include:
- node: 22
host-ref: dsh-v0.1.1-rc.2
host-ref: dsh-v0.1.2-rc.1
- node: 24
host-ref: dsh-v0.1.2-alpha.1
host-ref: dsh-v0.1.3-alpha.1
runs-on: ubuntu-latest
timeout-minutes: 40
steps:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
PRERELEASE: ${{ github.event.release.prerelease }}
HOST_REF: ${{ github.event.release.prerelease && 'dsh-v0.1.2-alpha.1' || 'dsh-v0.1.1-rc.2' }}
HOST_REF: ${{ github.event.release.prerelease && 'dsh-v0.1.3-alpha.1' || 'dsh-v0.1.2-rc.1' }}

steps:
# actions/checkout@v4
Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:
fi

if [ "$PRERELEASE" = "true" ]; then
echo "npm_tag=next" >> "$GITHUB_OUTPUT"
echo "npm_tag=preview" >> "$GITHUB_OUTPUT"
else
echo "npm_tag=latest" >> "$GITHUB_OUTPUT"
# Never move the public `latest` dist-tag backwards: DSH Desktop
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## [Unreleased]

## [1.4.8] - 2026-09-05
### 兼容性
- 适配 DSH 0.1.2-rc.1 和 0.1.3-alpha.1:保存或编辑批注后聚焦可编辑输入区,并将光标放到草稿末尾,支持继续输入和直接回车发送。
- CI 与发布验收分别固定到上述官方 rc 和 alpha 标签。

## [1.4.7] - 2026-09-04
### 修复
- **设置页不再被批注高亮遮挡(issue #44)**:设置弹窗打开时隐藏会话选区高亮层,避免插件的页面级浮层跨越宿主侧栏层叠环境。
Expand Down
14 changes: 9 additions & 5 deletions client.js
Original file line number Diff line number Diff line change
Expand Up @@ -1507,12 +1507,16 @@ window.__ModuleLoader__.load({
// 会强制滚动页面(视觉上"卡一下");延迟一帧让卡片关闭动画先完成,
// 焦点回归更平滑。
function focusComposer() {
var ta = document.querySelector('[data-composer-card] textarea')
if (!(ta instanceof HTMLTextAreaElement) || ta.disabled) return
var input = document.querySelector('[data-composer-card] [data-composer-input]')
if (!(input instanceof HTMLElement) || !input.isContentEditable) return
requestAnimationFrame(function () {
if (!ta.isConnected) return
ta.focus({ preventScroll: true })
ta.setSelectionRange(ta.value.length, ta.value.length)
if (!input.isConnected) return
input.focus({ preventScroll: true })
var selection = window.getSelection()
if (selection !== null) {
selection.selectAllChildren(input)
selection.collapseToEnd()
}
})
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@changfenhuang/dsh-annotation",
"version": "1.4.7",
"version": "1.4.8",
"type": "module",
"description": "DSH Web selection-annotation plugin: select assistant text, annotate (optional), and press Enter to send the annotation block with your message — the model replies to each annotation by number, with hoverable chips in the reply.",
"main": "lib/index.js",
Expand Down
26 changes: 26 additions & 0 deletions test/enter-policy.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,32 @@ test('新版可编辑输入区按 Enter 会进入批注拼稿(issue #41)', (
assert.doesNotMatch(fn[0], /HTMLTextAreaElement/)
})

test('保存批注后聚焦新版输入区,并把光标放在草稿末尾', () => {
const fn = source.match(/function focusComposer\(\) \{[\s\S]*?\n \}/)
assert.ok(fn, 'client.js should define focusComposer')
const calls = []
class HTMLElement {}
const input = Object.assign(new HTMLElement(), {
isContentEditable: true, isConnected: true,
focus: options => calls.push(['focus', options]),
})
const selection = {
selectAllChildren: element => calls.push(['select', element]),
collapseToEnd: () => calls.push(['end']),
}
const focusComposer = Function('document', 'window', 'HTMLElement', 'HTMLTextAreaElement', 'requestAnimationFrame',
`return (${fn[0]})`)(
{ querySelector: selector => selector === '[data-composer-card] [data-composer-input]' ? input : null },
{ getSelection: () => selection }, HTMLElement, class HTMLTextAreaElement {}, callback => callback(),
)
focusComposer()
assert.deepEqual(calls, [['focus', { preventScroll: true }], ['select', input], ['end']])
calls.length = 0
input.isConnected = false
focusComposer()
assert.deepEqual(calls, [])
})

test('发送按钮在 pointerdown 阶段先拼稿,空草稿按钮则由插件直接提交', () => {
const fn = source.match(/function onSendPointerDown\(e\) \{[\s\S]*?\n \}/)
assert.ok(fn, 'client.js should define onSendPointerDown')
Expand Down
Loading