@ash-qw/dsh-theme-prts 2.6.1 → 2.7.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ash-qw/dsh-theme-prts",
3
- "version": "2.6.1",
3
+ "version": "2.7.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Unofficial Arknights P.R.T.S.-inspired UI theme for DeepSeek Harness Web and the official desktop client",
@@ -69,7 +69,7 @@
69
69
  },
70
70
  "engines": {
71
71
  "node": ">=20.9.0",
72
- "dsh": "0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.5"
72
+ "dsh": "0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.5 || 0.2.2-rc.1"
73
73
  },
74
74
  "devDependencies": {
75
75
  "@playwright/test": "1.55.1",
@@ -15,7 +15,7 @@ export function createCursorAdapter({document, window, assets}) {
15
15
  const root = document.documentElement
16
16
  let follower, img, point, moveFrame, timer, family, resting, pressed = false, phase
17
17
  let semantics, captureTarget, layerContext, stateObserver, watchedTarget, nativePicker
18
- let textContext, renderedX, renderedY
18
+ let textContext, renderedX, renderedY, nativeScrollbar=false
19
19
  let eventTarget, semanticTarget, semanticValue, pose, poseKind, dirty = true, hitDirty = true
20
20
  let suspended = false, visible = false, currentUrl, ready = false
21
21
  const staticPose=(rest,hotspot)=>({rest,hotspot})
@@ -78,7 +78,7 @@ export function createCursorAdapter({document, window, assets}) {
78
78
  play(family.release,()=>{stop();sync()})
79
79
  }
80
80
  function sync() {
81
- if (!follower || !ready || !point || nativePicker || suspended || document.hidden || document.pointerLockElement) return hide()
81
+ if (!follower || !ready || !point || nativePicker || nativeScrollbar || suspended || document.hidden || document.pointerLockElement) return hide()
82
82
  const hit=hitDirty || !eventTarget?.isConnected ? document.elementFromPoint(point.x,point.y) : eventTarget
83
83
  eventTarget=hit;hitDirty=false
84
84
  if(!hit || hit.closest('iframe'))return hide()
@@ -138,6 +138,7 @@ export function createCursorAdapter({document, window, assets}) {
138
138
  function flush() { moveFrame=undefined;sync() }
139
139
  function move(event) {
140
140
  if(event.pointerType!=='mouse')return
141
+ if(nativeScrollbar){if(event.buttons)return;nativeScrollbar=false}
141
142
  resumePicker(event)
142
143
  if(suspended && !event.buttons)suspended=false
143
144
  const unchanged=point?.x===event.clientX && point?.y===event.clientY && eventTarget===event.target
@@ -146,9 +147,34 @@ export function createCursorAdapter({document, window, assets}) {
146
147
  if(pressed && !(event.buttons&1)){stop();draw(resting)}
147
148
  if(!unchanged || dirty)if(moveFrame===undefined)moveFrame=window.requestAnimationFrame(flush)
148
149
  }
150
+ // Native scrollbar drags stop delivering mouse coordinates to the page.
151
+ // Measure only on press; never add geometry reads to ordinary movement.
152
+ function onScrollbar(event){
153
+ const el=event.target
154
+ if(!(el instanceof window.HTMLElement))return false
155
+ if(el===root || el===document.body){
156
+ if(event.clientX>=root.clientWidth && window.innerWidth>root.clientWidth)return true
157
+ if(event.clientY>=root.clientHeight && window.innerHeight>root.clientHeight)return true
158
+ }
159
+ if(el.offsetWidth<=el.clientWidth && el.offsetHeight<=el.clientHeight)return false
160
+ const style=window.getComputedStyle(el),rect=el.getBoundingClientRect()
161
+ if(!el.offsetWidth || !el.offsetHeight)return false
162
+ const x=(event.clientX-rect.left)*el.offsetWidth/rect.width
163
+ const y=(event.clientY-rect.top)*el.offsetHeight/rect.height
164
+ const left=parseFloat(style.borderLeftWidth)||0,right=parseFloat(style.borderRightWidth)||0
165
+ const top=parseFloat(style.borderTopWidth)||0,bottom=parseFloat(style.borderBottomWidth)||0
166
+ const inside=x>=left && x<el.offsetWidth-right && y>=top && y<el.offsetHeight-bottom
167
+ if(!inside)return false
168
+ const vertical=el.scrollHeight>el.clientHeight && /^(auto|scroll)$/.test(style.overflowY)
169
+ && el.offsetWidth-el.clientWidth-left-right>0 && (x<el.clientLeft || x>=el.clientLeft+el.clientWidth)
170
+ const horizontal=el.scrollWidth>el.clientWidth && /^(auto|scroll)$/.test(style.overflowX)
171
+ && el.offsetHeight-el.clientHeight-top-bottom>0 && y>=el.clientTop+el.clientHeight
172
+ return vertical || horizontal
173
+ }
149
174
  function down(event) {
150
175
  if(event.pointerType!=='mouse'){reset();return}
151
176
  if(event.button!==0||event.isPrimary===false)return
177
+ if(onScrollbar(event)){reset();nativeScrollbar=true;return}
152
178
  const picker=event.target.closest?.('select,input[type="file"],input[type="color"]')
153
179
  if(picker){nativePicker=picker;reset();return}
154
180
  nativePicker=undefined
@@ -177,6 +203,7 @@ export function createCursorAdapter({document, window, assets}) {
177
203
  }
178
204
  function over(event) {
179
205
  if(event.pointerType!=='mouse')return
206
+ if(nativeScrollbar){if(event.buttons)return;nativeScrollbar=false}
180
207
  resumePicker(event)
181
208
  if(moveFrame!==undefined)window.cancelAnimationFrame(moveFrame)
182
209
  moveFrame=undefined
@@ -185,6 +212,7 @@ export function createCursorAdapter({document, window, assets}) {
185
212
  sync()
186
213
  }
187
214
  function up(event) {
215
+ if(nativeScrollbar && event.pointerType==='mouse' && event.button===0){nativeScrollbar=false;move(event);return}
188
216
  if(event.pointerType!=='mouse'||event.button!==0||!pressed)return
189
217
  pressed=false;dirty=true
190
218
  if(reduced()){stop();draw(resting);return}
@@ -192,7 +220,7 @@ export function createCursorAdapter({document, window, assets}) {
192
220
  }
193
221
  function reset() {
194
222
  if(moveFrame!==undefined)window.cancelAnimationFrame(moveFrame)
195
- moveFrame=undefined;point=undefined;eventTarget=undefined;hitDirty=true;captureTarget=undefined;hide()
223
+ moveFrame=undefined;point=undefined;eventTarget=undefined;hitDirty=true;captureTarget=undefined;nativeScrollbar=false;hide()
196
224
  }
197
225
  function blur(event){if(event.target===window)reset()}
198
226
  function leave(event){if(!event.relatedTarget || event.relatedTarget.closest?.('iframe'))reset()}
@@ -241,7 +241,8 @@ export function normalizePreferences(value) {
241
241
  cornerColor: colorOr(input.cornerColor, DEFAULT_PREFERENCES.cornerColor),
242
242
  cornerColorLight: colorOr(input.cornerColorLight, colorOr(input.cornerColor, DEFAULT_PREFERENCES.cornerColor)),
243
243
  cornerCustomColorLight: colorOr(input.cornerCustomColorLight, colorOr(input.cornerCustomColor, DEFAULT_PREFERENCES.cornerCustomColor)),
244
- cursor: ['system', 'prts-follower'].includes(input.cursor) ? input.cursor : DEFAULT_PREFERENCES.cursor,
244
+ // The follower experiment is paused; stored/imported values fall back to native PRTS.
245
+ cursor: input.cursor === 'system' ? 'system' : DEFAULT_PREFERENCES.cursor,
245
246
  conversationParticleDensity: enumOr(legacyDensities.conversation, PARTICLE_DENSITIES, particlePreset.conversationParticleDensity),
246
247
  heroParticleDensity: enumOr(legacyDensities.hero, PARTICLE_DENSITIES, particlePreset.heroParticleDensity),
247
248
  particleTraversalSpeed: particleTraversalSpeedOr(
@@ -52,7 +52,10 @@ export function resolveRc7Regions(document, report = () => {}) {
52
52
  return null
53
53
  }
54
54
 
55
- const frame = closestCommonContainer(root, [sidebar, center, auxiliary])
55
+ const centerColumn = center.parentElement?.parentElement === auxiliary.parentElement
56
+ ? center.parentElement
57
+ : center
58
+ const frame = closestCommonContainer(root, [sidebar, centerColumn, auxiliary])
56
59
  if (!frame) {
57
60
  report('common layout container is unavailable')
58
61
  return null
@@ -62,7 +65,7 @@ export function resolveRc7Regions(document, report = () => {}) {
62
65
  root,
63
66
  frame,
64
67
  sidebar,
65
- center,
68
+ center: centerColumn,
66
69
  auxiliary,
67
70
  sidebarSlot,
68
71
  centerSlot,
@@ -21,7 +21,7 @@ const CURSOR_DESCRIPTIONS = {
21
21
  }
22
22
 
23
23
  const COMMON_CONTROLS = [
24
- ['cursor', '光标模式', [['system', '系统光标'], ['prts', 'PRTS 原生光标'], ['prts-follower', 'PRTS 跟随光标(实验)']]],
24
+ ['cursor', '光标模式', [['system', '系统光标'], ['prts', 'PRTS 原生光标']]],
25
25
  ['railDefaultHidden', '默认隐藏导航栏', [['false', '关闭'], ['true', '开启']]],
26
26
  ['motion', '动态效果', []],
27
27
  ['sessionFlow', '当前会话流线', [['false', '关闭'], ['true', '开启']]],