dsh-claude-style 0.2.2 → 0.2.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.3] - 2026-09-19
4
+
5
+ ### Fixed
6
+ - 修复账户抽屉弹层打开期间镜像被持续改写导致 hover / 点击失效的问题:宿主在会话流式输出、用量统计刷新等场景下高频重渲染 footer 条目,弹层同步每帧重写镜像内容并在顺序变化时搬动节点——悬停状态的元素被替换/挪走后浏览器不再视为 :hover,点击落在 pointerdown 与 pointerup 之间的新节点上会被吞掉,唯一不受影响的是从不被同步触碰的设置按钮。现改为:弹层打开期间镜像 DOM 完全静止(侧栏侧的真实条目隐藏仍实时生效),打开前做最后一次同步刷新内容与顺序;点击目标在点击瞬间从实时 footer DOM 重解析兜底,宿主重渲染导致旧目标节点脱离文档时仍能命中正确控件。
7
+
3
8
  ## [0.2.2] - 2026-09-19
4
9
 
5
10
  ### Added
package/README.en.md CHANGED
@@ -39,12 +39,13 @@ Install: double-click the `.ttf` on Windows → *Install*; on macOS import via *
39
39
 
40
40
  ## Install
41
41
 
42
- > Tested on dsh 0.1.5-rc.2 · not yet published to npm — install from GitHub
42
+ > Tested on dsh 0.1.5-rc.2
43
43
 
44
44
  1. Install via terminal
45
45
 
46
46
  ```bash
47
- dsh plugin --profile web add Nwflower/dsh-claude-style # GitHub source
47
+ dsh plugin --profile web add dsh-claude-style # npm package (recommended)
48
+ dsh plugin --profile web add Nwflower/dsh-claude-style # GitHub source
48
49
  ```
49
50
 
50
51
  2. Install via [Plugin Marketplace](https://github.com/dsh-market/dsh-market)
package/README.md CHANGED
@@ -39,12 +39,13 @@
39
39
 
40
40
  ## 安装
41
41
 
42
- > 已在 dsh 0.1.5-rc.2 上测试 · 暂未发布 npm —— 请从 GitHub 源安装
42
+ > 已在 dsh 0.1.5-rc.2 上测试
43
43
 
44
44
  1. 通过终端安装
45
45
 
46
46
  ```bash
47
- dsh plugin --profile web add Nwflower/dsh-claude-style # GitHub
47
+ dsh plugin --profile web add dsh-claude-style # npm 包(推荐)
48
+ dsh plugin --profile web add Nwflower/dsh-claude-style # GitHub 源
48
49
  ```
49
50
 
50
51
  2. 通过[插件市场](https://github.com/dsh-market/dsh-market)安装
package/lib/client.js CHANGED
@@ -2680,6 +2680,13 @@ window.__ModuleLoader__.load({
2680
2680
  clearTimeout(popoverTimer)
2681
2681
  popoverTimer = null
2682
2682
  }
2683
+ // Mirrors are frozen while the popover is open (syncPopoverItems
2684
+ // bails), so reconcile them here — before the reveal — to show fresh
2685
+ // content/order and bind click targets for the upcoming interaction.
2686
+ try {
2687
+ var footArea = document.querySelector('[class*="footArea"]')
2688
+ if (footArea) syncPopoverItems(footArea)
2689
+ } catch (error) { /* opening must never fail because of a mirror sync */ }
2683
2690
  accountPopover.setAttribute('data-open', 'true')
2684
2691
  accountBtn.setAttribute('data-open', 'true')
2685
2692
  accountBtn.setAttribute('aria-expanded', 'true')
@@ -2766,6 +2773,15 @@ window.__ModuleLoader__.load({
2766
2773
  var footerActions = footArea.querySelector('[class*="footerActions"]')
2767
2774
  var footerEntries = syncFooterActionVisibility(footerActions)
2768
2775
 
2776
+ // While the popover is open, its mirrors must stay completely static:
2777
+ // a content rewrite, reorder, or embedded-clone replacement under the
2778
+ // pointer cancels the browser's :hover state and can swallow the click
2779
+ // between pointerdown and pointerup. Sync runs only while closed;
2780
+ // openPopover runs one final pass right before the reveal — and the
2781
+ // sidebar-side redirection above stays live, so a newly mounted entry
2782
+ // keeps being hidden even with the popover open.
2783
+ if (accountPopover && accountPopover.getAttribute('data-open') === 'true') return
2784
+
2769
2785
  var existingActionItems = popoverBody.querySelectorAll('[data-action-index], [data-embed-index]')
2770
2786
  for (var ea = 0; ea < existingActionItems.length; ea++) {
2771
2787
  var staleIdx = parseInt(existingActionItems[ea].getAttribute('data-action-index') || existingActionItems[ea].getAttribute('data-embed-index'), 10)
@@ -2775,7 +2791,8 @@ window.__ModuleLoader__.load({
2775
2791
  }
2776
2792
 
2777
2793
  for (var f = 0; f < footerEntries.length; f++) {
2778
- (function (entry, idx) {
2794
+ try {
2795
+ (function (entry, idx) {
2779
2796
  var trigger = findFooterTrigger(entry)
2780
2797
  var hasContent = (entry.textContent || '').trim() !== '' ||
2781
2798
  entry.querySelector('svg, img, canvas') !== null
@@ -2817,11 +2834,26 @@ window.__ModuleLoader__.load({
2817
2834
  item.addEventListener('click', function (e) {
2818
2835
  e.stopPropagation()
2819
2836
  closePopover()
2820
- // The activator is rebound on every sync pass
2837
+ // The activator is rebound on every (closed-state) sync pass
2821
2838
  // (`item.__dshActivator`), never captured at creation — the
2822
2839
  // host re-sorts list slots by `order` on each render, so the
2823
2840
  // entry behind an index changes over time.
2824
2841
  var live = item.__dshActivator
2842
+ if (!live || typeof live.click !== 'function') {
2843
+ // Safety net: re-resolve the current trigger for this index
2844
+ // from the live footer DOM. Covers the rare case where the
2845
+ // stored node was detached by a host re-render while the
2846
+ // popover was open.
2847
+ try {
2848
+ var fa = document.querySelector('[class*="footArea"]')
2849
+ var actions = fa ? fa.querySelector('[class*="footerActions"]') : null
2850
+ var liveEntries = actions ? footerEntriesOf(actions) : []
2851
+ var liveEntry = liveEntries[idx] || null
2852
+ live = liveEntry ? findFooterTrigger(liveEntry) : null
2853
+ } catch (error) {
2854
+ live = null
2855
+ }
2856
+ }
2825
2857
  if (live && typeof live.click === 'function') live.click()
2826
2858
  })
2827
2859
  popoverBody.insertBefore(item, settingsItem)
@@ -2841,7 +2873,12 @@ window.__ModuleLoader__.load({
2841
2873
  // Rebind the click target to the entry currently behind this
2842
2874
  // index. Done on every pass, for new and reused items alike.
2843
2875
  item.__dshActivator = activator
2844
- })(footerEntries[f], f)
2876
+ })(footerEntries[f], f)
2877
+ } catch (err) {
2878
+ // A single broken entry must not abort the rest of the mirror
2879
+ // sync (which would leave later items without a rebound
2880
+ // activator or un-ordered).
2881
+ }
2845
2882
  }
2846
2883
 
2847
2884
  // The host re-sorts list-slot outlets by `order` on every render
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-claude-style",
3
3
  "description": "Claude Code Desktop theme for DeepSeek Harness (dsh) web GUI — visual & interaction overhaul",
4
- "version": "0.2.2",
4
+ "version": "0.2.3",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "scripts": {