dsh-skin-galactic-opera 0.1.3 → 0.1.5
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 +26 -0
- package/lib/client.js +125 -88
- package/package.json +12 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this package will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.1.5 - 2026-08-28
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Scanner target now double-flashes at the clicked page position projected into the bottom-left scanner disk.
|
|
10
|
+
- Package metadata for repository, homepage, and issue reporting.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Optimizes telemetry rescan scheduling by ignoring skin-owned DOM mutations and reusing valid cached telemetry sources.
|
|
15
|
+
- Replaces the scanner target's continuous sweep polling with click-triggered pings.
|
|
16
|
+
- Caches the reduced-motion media query and tightens plugin-specific global state class names.
|
|
17
|
+
- Expands JavaScript syntax checks to include both client and host entries and runs them before publishing.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Improves contenteditable detection, including empty and plaintext-only contenteditable controls.
|
|
22
|
+
- Prevents hidden telemetry source elements from intercepting pointer events.
|
|
23
|
+
- Narrows scrollbar styling to avoid a global universal selector.
|
|
24
|
+
|
|
25
|
+
## 0.1.4 - 2026-08-28
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Restores the top-right satellite's original 0.1.2 elliptical orbit behavior by excluding satellite and orbit animations from typing low-distraction pause rules.
|
|
30
|
+
|
|
5
31
|
## 0.1.3 - 2026-08-27
|
|
6
32
|
|
|
7
33
|
### Added
|
package/lib/client.js
CHANGED
|
@@ -79,6 +79,7 @@ body.dsh-skin-galactic-opera {
|
|
|
79
79
|
radial-gradient(circle at 62% 83%, rgba(255, 71, 120, 0.20), transparent 34rem),
|
|
80
80
|
radial-gradient(circle at 32% 74%, rgba(102, 255, 199, 0.10), transparent 28rem),
|
|
81
81
|
linear-gradient(180deg, #02030a 0%, #03040b 44%, #080b1c 100%) !important;
|
|
82
|
+
scrollbar-color: rgba(125, 227, 255, 0.42) rgba(5, 7, 17, 0.40);
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
body.dsh-skin-galactic-opera::before,
|
|
@@ -139,35 +140,36 @@ body.dsh-skin-galactic-opera #root::before {
|
|
|
139
140
|
will-change: transform;
|
|
140
141
|
}
|
|
141
142
|
|
|
142
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active::before,
|
|
143
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active::after,
|
|
144
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active #root::before {
|
|
143
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active::before,
|
|
144
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active::after,
|
|
145
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active #root::before {
|
|
145
146
|
animation-play-state: paused !important;
|
|
146
147
|
}
|
|
147
148
|
|
|
148
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active::before {
|
|
149
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active::before {
|
|
149
150
|
opacity: 0.28;
|
|
150
151
|
}
|
|
151
152
|
|
|
152
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active::after {
|
|
153
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active::after {
|
|
153
154
|
opacity: 0.12;
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active #root::before {
|
|
157
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active #root::before {
|
|
157
158
|
opacity: 0.10;
|
|
158
159
|
transform: none;
|
|
159
160
|
will-change: auto;
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active .dsh-skin-galactic-opera-decor {
|
|
163
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active .dsh-skin-galactic-opera-decor {
|
|
163
164
|
opacity: 0.28;
|
|
164
165
|
}
|
|
165
166
|
|
|
166
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active :is(.dsh-skin-nebula-core, .dsh-skin-energy, .dsh-skin-comet, .dsh-skin-starfighter, .dsh-skin-mission-crawl, .dsh-skin-scanner, .dsh-skin-
|
|
167
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active :is(.dsh-skin-nebula-core, .dsh-skin-energy, .dsh-skin-comet, .dsh-skin-starfighter, .dsh-skin-mission-crawl, .dsh-skin-scanner, .dsh-skin-route-map),
|
|
168
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active .dsh-skin-scanner::after {
|
|
167
169
|
animation-play-state: paused !important;
|
|
168
170
|
}
|
|
169
171
|
|
|
170
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active :is(.dsh-skin-nebula-core, .dsh-skin-energy, .dsh-skin-comet, .dsh-skin-starfighter, .dsh-skin-mission-crawl) {
|
|
172
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active :is(.dsh-skin-nebula-core, .dsh-skin-energy, .dsh-skin-comet, .dsh-skin-starfighter, .dsh-skin-mission-crawl) {
|
|
171
173
|
opacity: 0.08 !important;
|
|
172
174
|
}
|
|
173
175
|
|
|
@@ -217,8 +219,8 @@ body.dsh-skin-galactic-opera .dsh-skin-galactic-opera-decor::before {
|
|
|
217
219
|
filter: blur(0.2px);
|
|
218
220
|
}
|
|
219
221
|
|
|
220
|
-
body.dsh-skin-galactic-opera.dsh-skin-hyperspace .dsh-skin-galactic-opera-decor::before {
|
|
221
|
-
animation: dsh-skin-hyperspace-burst 880ms cubic-bezier(.16,.8,.25,1) both;
|
|
222
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-hyperspace .dsh-skin-galactic-opera-decor::before {
|
|
223
|
+
animation: dsh-skin-galactic-opera-hyperspace-burst 880ms cubic-bezier(.16,.8,.25,1) both;
|
|
222
224
|
}
|
|
223
225
|
|
|
224
226
|
body.dsh-skin-galactic-opera .dsh-skin-galactic-opera-decor span {
|
|
@@ -446,7 +448,7 @@ body.dsh-skin-galactic-opera .dsh-skin-scanner-target {
|
|
|
446
448
|
transition: opacity 120ms ease-out, transform 120ms ease-out, box-shadow 120ms ease-out;
|
|
447
449
|
}
|
|
448
450
|
|
|
449
|
-
body.dsh-skin-galactic-opera .dsh-skin-scanner-target[data-
|
|
451
|
+
body.dsh-skin-galactic-opera .dsh-skin-scanner-target[data-ping="true"] {
|
|
450
452
|
opacity: 1;
|
|
451
453
|
transform: translate(-50%, -50%) scale(1.18);
|
|
452
454
|
box-shadow:
|
|
@@ -454,7 +456,7 @@ body.dsh-skin-galactic-opera .dsh-skin-scanner-target[data-lit="true"] {
|
|
|
454
456
|
0 0 14px rgba(255,207,92,0.96),
|
|
455
457
|
0 0 30px rgba(125,227,255,0.68),
|
|
456
458
|
0 0 54px rgba(255,71,120,0.28);
|
|
457
|
-
animation: dsh-skin-scanner-target-ping
|
|
459
|
+
animation: dsh-skin-scanner-target-double-ping 640ms ease-out both;
|
|
458
460
|
}
|
|
459
461
|
|
|
460
462
|
body.dsh-skin-galactic-opera .dsh-skin-route-map {
|
|
@@ -646,9 +648,9 @@ body.dsh-skin-galactic-opera :is(pre, code, textarea, input, select, [class*="me
|
|
|
646
648
|
inset 0 0 20px rgba(255, 207, 92, 0.035) !important;
|
|
647
649
|
}
|
|
648
650
|
|
|
649
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active :is(textarea, input, [contenteditable="
|
|
650
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active :is(textarea, input, [contenteditable="
|
|
651
|
-
body.dsh-skin-galactic-opera.dsh-skin-input-active :is(textarea, input, [contenteditable="
|
|
651
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active :is(textarea, input, [contenteditable]:not([contenteditable="false"])):hover,
|
|
652
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active :is(textarea, input, [contenteditable]:not([contenteditable="false"])):focus,
|
|
653
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active :is(textarea, input, [contenteditable]:not([contenteditable="false"])):focus-within {
|
|
652
654
|
outline: none !important;
|
|
653
655
|
box-shadow: none !important;
|
|
654
656
|
}
|
|
@@ -658,12 +660,9 @@ body.dsh-skin-galactic-opera ::selection {
|
|
|
658
660
|
background: rgba(255, 207, 92, 0.86);
|
|
659
661
|
}
|
|
660
662
|
|
|
661
|
-
body.dsh-skin-galactic-opera * {
|
|
662
|
-
scrollbar-color: rgba(125, 227, 255, 0.42) rgba(5, 7, 17, 0.40);
|
|
663
|
-
}
|
|
664
|
-
|
|
665
663
|
body.dsh-skin-galactic-opera .dsh-skin-telemetry-source-hidden {
|
|
666
664
|
opacity: 0 !important;
|
|
665
|
+
pointer-events: none !important;
|
|
667
666
|
}
|
|
668
667
|
|
|
669
668
|
body.dsh-skin-galactic-opera .dsh-skin-telemetry-panel[hidden] {
|
|
@@ -907,9 +906,11 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
907
906
|
50% { opacity: 1; transform: rotate(7deg) scaleX(1); }
|
|
908
907
|
}
|
|
909
908
|
|
|
910
|
-
@keyframes dsh-skin-scanner-target-ping {
|
|
911
|
-
0%, 100% { transform: translate(-50%, -50%) scale(0.
|
|
912
|
-
|
|
909
|
+
@keyframes dsh-skin-scanner-target-double-ping {
|
|
910
|
+
0%, 100% { transform: translate(-50%, -50%) scale(0.72); opacity: 0.04; }
|
|
911
|
+
12%, 42% { transform: translate(-50%, -50%) scale(1.24); opacity: 1; }
|
|
912
|
+
27%, 57% { transform: translate(-50%, -50%) scale(0.86); opacity: 0.34; }
|
|
913
|
+
72% { transform: translate(-50%, -50%) scale(1.12); opacity: 0.82; }
|
|
913
914
|
}
|
|
914
915
|
|
|
915
916
|
@keyframes dsh-skin-click-pulse {
|
|
@@ -918,7 +919,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
918
919
|
100% { opacity: 0; width: 132px; height: 132px; filter: brightness(0.8); }
|
|
919
920
|
}
|
|
920
921
|
|
|
921
|
-
@keyframes dsh-skin-hyperspace-burst {
|
|
922
|
+
@keyframes dsh-skin-galactic-opera-hyperspace-burst {
|
|
922
923
|
0% { opacity: 0; transform: scale(0.32) rotate(0deg); }
|
|
923
924
|
15% { opacity: 0.9; }
|
|
924
925
|
100% { opacity: 0; transform: scale(1.45) rotate(10deg); }
|
|
@@ -1043,20 +1044,43 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1043
1044
|
return decor;
|
|
1044
1045
|
}
|
|
1045
1046
|
|
|
1047
|
+
const EDITABLE_CONTENT_SELECTOR = `[contenteditable]:not([contenteditable="false"])`;
|
|
1048
|
+
let reducedMotionQuery;
|
|
1049
|
+
let reducedMotionMatches = false;
|
|
1050
|
+
let reducedMotionListener;
|
|
1051
|
+
|
|
1046
1052
|
function isReducedMotion() {
|
|
1047
|
-
|
|
1053
|
+
if (typeof matchMedia === "undefined") return false;
|
|
1054
|
+
if (reducedMotionQuery === undefined) {
|
|
1055
|
+
reducedMotionQuery = matchMedia("(prefers-reduced-motion: reduce)");
|
|
1056
|
+
reducedMotionMatches = reducedMotionQuery.matches;
|
|
1057
|
+
reducedMotionListener = (event) => { reducedMotionMatches = event.matches; };
|
|
1058
|
+
if (typeof reducedMotionQuery.addEventListener === "function") reducedMotionQuery.addEventListener("change", reducedMotionListener);
|
|
1059
|
+
else if (typeof reducedMotionQuery.addListener === "function") reducedMotionQuery.addListener(reducedMotionListener);
|
|
1060
|
+
}
|
|
1061
|
+
return reducedMotionMatches;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
function disposeReducedMotionCache() {
|
|
1065
|
+
if (reducedMotionQuery !== undefined && reducedMotionListener !== undefined) {
|
|
1066
|
+
if (typeof reducedMotionQuery.removeEventListener === "function") reducedMotionQuery.removeEventListener("change", reducedMotionListener);
|
|
1067
|
+
else if (typeof reducedMotionQuery.removeListener === "function") reducedMotionQuery.removeListener(reducedMotionListener);
|
|
1068
|
+
}
|
|
1069
|
+
reducedMotionQuery = undefined;
|
|
1070
|
+
reducedMotionMatches = false;
|
|
1071
|
+
reducedMotionListener = undefined;
|
|
1048
1072
|
}
|
|
1049
1073
|
|
|
1050
1074
|
function isEditableTarget(target) {
|
|
1051
1075
|
if (!(target instanceof Element)) return false;
|
|
1052
1076
|
const tag = target.tagName.toLowerCase();
|
|
1053
|
-
return tag === "input" || tag === "textarea" || tag === "select" || target.closest(
|
|
1077
|
+
return tag === "input" || tag === "textarea" || tag === "select" || target.closest(EDITABLE_CONTENT_SELECTOR) !== null;
|
|
1054
1078
|
}
|
|
1055
1079
|
|
|
1056
1080
|
function isInstructionInputTarget(target) {
|
|
1057
1081
|
if (!(target instanceof Element)) return false;
|
|
1058
1082
|
const tag = target.tagName.toLowerCase();
|
|
1059
|
-
return tag === "textarea" || target.closest(
|
|
1083
|
+
return tag === "textarea" || target.closest(EDITABLE_CONTENT_SELECTOR) !== null;
|
|
1060
1084
|
}
|
|
1061
1085
|
|
|
1062
1086
|
function isLikelySendButton(target) {
|
|
@@ -1064,7 +1088,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1064
1088
|
const button = target.closest("button");
|
|
1065
1089
|
if (!(button instanceof HTMLButtonElement)) return false;
|
|
1066
1090
|
const form = button.closest("form");
|
|
1067
|
-
if (form !== null && form.querySelector(
|
|
1091
|
+
if (form !== null && form.querySelector(`textarea, ${EDITABLE_CONTENT_SELECTOR}`) !== null && button.type === "submit") return true;
|
|
1068
1092
|
const label = `${button.getAttribute("aria-label") ?? ""} ${button.getAttribute("title") ?? ""} ${button.textContent ?? ""}`.toLowerCase();
|
|
1069
1093
|
return /send|submit|发送|提交|送出|传送/.test(label);
|
|
1070
1094
|
}
|
|
@@ -1072,17 +1096,15 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1072
1096
|
function installInteractions(decor) {
|
|
1073
1097
|
if (typeof document === "undefined" || typeof window === "undefined" || decor === undefined) return () => {};
|
|
1074
1098
|
let frame = 0;
|
|
1075
|
-
let sweepFrame = 0;
|
|
1076
|
-
let sweepTimer = 0;
|
|
1077
1099
|
let latestX = window.innerWidth / 2;
|
|
1078
1100
|
let latestY = window.innerHeight / 2;
|
|
1079
|
-
let targetAngle = 0;
|
|
1080
1101
|
let pulseIndex = 0;
|
|
1081
1102
|
let hyperspaceTimer;
|
|
1082
1103
|
let inputFocusTimer;
|
|
1104
|
+
let scannerPingTimer;
|
|
1083
1105
|
let lastHyperspaceAt = 0;
|
|
1106
|
+
const scanner = decor.querySelector(".dsh-skin-scanner");
|
|
1084
1107
|
const scannerTarget = decor.querySelector(".dsh-skin-scanner-target");
|
|
1085
|
-
const scannerStartedAt = performance.now();
|
|
1086
1108
|
const pulseColors = ["rgba(125,227,255,0.94)", "rgba(255,207,92,0.92)", "rgba(255,71,120,0.88)"];
|
|
1087
1109
|
const updatePointer = () => {
|
|
1088
1110
|
frame = 0;
|
|
@@ -1090,30 +1112,42 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1090
1112
|
const ny = (latestY / Math.max(1, window.innerHeight) - 0.5) * 2;
|
|
1091
1113
|
document.body.style.setProperty("--dsh-skin-parallax-x", `${Math.round(nx * -10)}px`);
|
|
1092
1114
|
document.body.style.setProperty("--dsh-skin-parallax-y", `${Math.round(ny * -8)}px`);
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1115
|
+
};
|
|
1116
|
+
const pingScannerAt = (clientX, clientY) => {
|
|
1117
|
+
if (!(scanner instanceof HTMLElement) || !(scannerTarget instanceof HTMLElement)) return;
|
|
1118
|
+
const rect = scanner.getBoundingClientRect();
|
|
1119
|
+
const scannerCenterX = rect.left + rect.width / 2;
|
|
1120
|
+
const scannerCenterY = rect.top + rect.height / 2;
|
|
1121
|
+
const viewportCenterX = window.innerWidth / 2;
|
|
1122
|
+
const viewportCenterY = window.innerHeight / 2;
|
|
1123
|
+
const dx = clientX - viewportCenterX;
|
|
1124
|
+
const dy = clientY - viewportCenterY;
|
|
1125
|
+
const distance = Math.hypot(dx, dy);
|
|
1126
|
+
const farthestX = dx >= 0 ? window.innerWidth - viewportCenterX : viewportCenterX;
|
|
1127
|
+
const farthestY = dy >= 0 ? window.innerHeight - viewportCenterY : viewportCenterY;
|
|
1128
|
+
const maxDistance = Math.max(1, Math.hypot(farthestX, farthestY));
|
|
1129
|
+
const scannerRadius = Math.max(10, Math.min(rect.width, rect.height) * 0.38);
|
|
1130
|
+
const projectedRadius = Math.min(1, distance / maxDistance) * scannerRadius;
|
|
1131
|
+
const angle = Math.atan2(dy, dx);
|
|
1132
|
+
document.body.style.setProperty("--dsh-skin-scanner-dot-x", `${Math.round(scannerCenterX + Math.cos(angle) * projectedRadius)}px`);
|
|
1133
|
+
document.body.style.setProperty("--dsh-skin-scanner-dot-y", `${Math.round(scannerCenterY + Math.sin(angle) * projectedRadius)}px`);
|
|
1134
|
+
scannerTarget.removeAttribute("data-ping");
|
|
1135
|
+
// Force the double-flash animation to restart on repeated clicks at the same point.
|
|
1136
|
+
void scannerTarget.offsetWidth;
|
|
1137
|
+
scannerTarget.dataset.ping = "true";
|
|
1138
|
+
window.clearTimeout(scannerPingTimer);
|
|
1139
|
+
scannerPingTimer = window.setTimeout(() => {
|
|
1140
|
+
scannerTarget.removeAttribute("data-ping");
|
|
1141
|
+
}, 700);
|
|
1108
1142
|
};
|
|
1109
1143
|
const isTypingActive = () => document.activeElement instanceof Element && isEditableTarget(document.activeElement);
|
|
1110
1144
|
const setInputActive = (active) => {
|
|
1111
1145
|
window.clearTimeout(inputFocusTimer);
|
|
1112
1146
|
if (active) {
|
|
1113
|
-
document.body.classList.add("dsh-skin-input-active");
|
|
1147
|
+
document.body.classList.add("dsh-skin-galactic-opera-input-active");
|
|
1114
1148
|
} else {
|
|
1115
1149
|
inputFocusTimer = window.setTimeout(() => {
|
|
1116
|
-
document.body.classList.remove("dsh-skin-input-active");
|
|
1150
|
+
document.body.classList.remove("dsh-skin-galactic-opera-input-active");
|
|
1117
1151
|
}, 160);
|
|
1118
1152
|
}
|
|
1119
1153
|
};
|
|
@@ -1128,10 +1162,10 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1128
1162
|
const now = performance.now();
|
|
1129
1163
|
if (now - lastHyperspaceAt < 1200) return;
|
|
1130
1164
|
lastHyperspaceAt = now;
|
|
1131
|
-
document.body.classList.add("dsh-skin-hyperspace");
|
|
1165
|
+
document.body.classList.add("dsh-skin-galactic-opera-hyperspace");
|
|
1132
1166
|
window.clearTimeout(hyperspaceTimer);
|
|
1133
1167
|
hyperspaceTimer = window.setTimeout(() => {
|
|
1134
|
-
document.body.classList.remove("dsh-skin-hyperspace");
|
|
1168
|
+
document.body.classList.remove("dsh-skin-galactic-opera-hyperspace");
|
|
1135
1169
|
}, 900);
|
|
1136
1170
|
};
|
|
1137
1171
|
const onPointerDown = (event) => {
|
|
@@ -1146,6 +1180,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1146
1180
|
const remove = () => { pulse.remove(); };
|
|
1147
1181
|
pulse.addEventListener("animationend", remove, { once: true });
|
|
1148
1182
|
window.setTimeout(remove, 900);
|
|
1183
|
+
pingScannerAt(event.clientX, event.clientY);
|
|
1149
1184
|
if (isLikelySendButton(event.target)) window.setTimeout(triggerHyperspace, 40);
|
|
1150
1185
|
};
|
|
1151
1186
|
const onKeyDown = (event) => {
|
|
@@ -1160,26 +1195,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1160
1195
|
const onFocusOut = (event) => {
|
|
1161
1196
|
if (isEditableTarget(event.target)) setInputActive(false);
|
|
1162
1197
|
};
|
|
1163
|
-
const sweepLoop = () => {
|
|
1164
|
-
sweepFrame = 0;
|
|
1165
|
-
sweepTimer = 0;
|
|
1166
|
-
const typing = isTypingActive();
|
|
1167
|
-
if (scannerTarget instanceof HTMLElement) {
|
|
1168
|
-
if (isReducedMotion() || typing) {
|
|
1169
|
-
scannerTarget.removeAttribute("data-lit");
|
|
1170
|
-
} else {
|
|
1171
|
-
// The scanner disk rotates once every 7s. Offset roughly matches the bright conic wedge.
|
|
1172
|
-
const sweepAngle = (((performance.now() - scannerStartedAt) % 7000) / 7000 * 360 + 18) % 360;
|
|
1173
|
-
const delta = Math.abs(((sweepAngle - targetAngle + 540) % 360) - 180);
|
|
1174
|
-
if (delta < 10) scannerTarget.dataset.lit = "true";
|
|
1175
|
-
else scannerTarget.removeAttribute("data-lit");
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
if (typing) sweepTimer = window.setTimeout(sweepLoop, 300);
|
|
1179
|
-
else sweepFrame = requestAnimationFrame(sweepLoop);
|
|
1180
|
-
};
|
|
1181
1198
|
updatePointer();
|
|
1182
|
-
sweepFrame = requestAnimationFrame(sweepLoop);
|
|
1183
1199
|
document.addEventListener("pointermove", onPointerMove, { passive: true });
|
|
1184
1200
|
document.addEventListener("pointerdown", onPointerDown, { passive: true });
|
|
1185
1201
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -1193,13 +1209,12 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1193
1209
|
document.removeEventListener("focusin", onFocusIn);
|
|
1194
1210
|
document.removeEventListener("focusout", onFocusOut);
|
|
1195
1211
|
window.clearTimeout(inputFocusTimer);
|
|
1196
|
-
document.body.classList.remove("dsh-skin-input-active");
|
|
1212
|
+
document.body.classList.remove("dsh-skin-galactic-opera-input-active");
|
|
1197
1213
|
if (frame !== 0) cancelAnimationFrame(frame);
|
|
1198
|
-
if (
|
|
1199
|
-
|
|
1200
|
-
if (scannerTarget instanceof HTMLElement) scannerTarget.removeAttribute("data-lit");
|
|
1214
|
+
if (scannerTarget instanceof HTMLElement) scannerTarget.removeAttribute("data-ping");
|
|
1215
|
+
window.clearTimeout(scannerPingTimer);
|
|
1201
1216
|
window.clearTimeout(hyperspaceTimer);
|
|
1202
|
-
document.body.classList.remove("dsh-skin-hyperspace");
|
|
1217
|
+
document.body.classList.remove("dsh-skin-galactic-opera-hyperspace");
|
|
1203
1218
|
document.body.style.removeProperty("--dsh-skin-parallax-x");
|
|
1204
1219
|
document.body.style.removeProperty("--dsh-skin-parallax-y");
|
|
1205
1220
|
document.body.style.removeProperty("--dsh-skin-scanner-dot-x");
|
|
@@ -1210,8 +1225,8 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1210
1225
|
function installTelemetryPanel() {
|
|
1211
1226
|
if (typeof document === "undefined" || typeof window === "undefined") return () => {};
|
|
1212
1227
|
const telemetryPattern = /(?:\d[\d.,KkMm%/]*\s*轮\s*[·•]?\s*\d[\d.,KkMm%/]*\s*步)|(?:\d[\d.,KkMm%/]*\s*(?:rounds?|turns?)\s*[·•]?\s*\d[\d.,KkMm%/]*\s*steps?)|LLM\b|工具调用|(?:首\s*)?(?:token|tokens|tok|toks)\s*平均|(?:token|tokens|tok|toks)\/s|缓存命中|缓存|cache\b|cached\b|输入|输出|prompt\b|completion\b/i;
|
|
1213
|
-
const skipSelector = `#${DECOR_ID}, style, script, textarea, input, select, button, [role=button], [aria-haspopup],
|
|
1214
|
-
const editableDescendantSelector =
|
|
1228
|
+
const skipSelector = `#${DECOR_ID}, style, script, textarea, input, select, button, [role=button], [aria-haspopup], ${EDITABLE_CONTENT_SELECTOR}, [role=dialog], [role=menu], [role=listbox], [role=tooltip], [popover], .dsh-skin-pulse, .dsh-skin-telemetry-panel`;
|
|
1229
|
+
const editableDescendantSelector = `textarea, input, select, ${EDITABLE_CONTENT_SELECTOR}`;
|
|
1215
1230
|
let currentSources = new Set();
|
|
1216
1231
|
let lastText = "";
|
|
1217
1232
|
let frame = 0;
|
|
@@ -1233,9 +1248,17 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1233
1248
|
toggle.className = "dsh-skin-telemetry-toggle";
|
|
1234
1249
|
toggle.hidden = true;
|
|
1235
1250
|
document.body.append(panel, toggle);
|
|
1251
|
+
const skinMutationSelector = `#${DECOR_ID}, .dsh-skin-pulse, .dsh-skin-telemetry-panel, .dsh-skin-telemetry-toggle`;
|
|
1236
1252
|
const isSkippable = (element) => element.closest(skipSelector) !== null;
|
|
1237
1253
|
const hasEditableDescendant = (element) => element.querySelector(editableDescendantSelector) !== null;
|
|
1238
1254
|
const getTelemetryText = (element) => (element.innerText || element.textContent || "").replace(/\s+/g, " ").trim();
|
|
1255
|
+
const getMutationElement = (node) => node instanceof Element ? node : node.parentElement;
|
|
1256
|
+
const isSkinOwnedNode = (node) => getMutationElement(node)?.closest(skinMutationSelector) !== null;
|
|
1257
|
+
const isSkinOwnedMutation = (mutation) => {
|
|
1258
|
+
if (isSkinOwnedNode(mutation.target)) return true;
|
|
1259
|
+
const touched = [...mutation.addedNodes, ...mutation.removedNodes];
|
|
1260
|
+
return touched.length > 0 && touched.every(isSkinOwnedNode);
|
|
1261
|
+
};
|
|
1239
1262
|
const scoreCandidate = (element) => {
|
|
1240
1263
|
if (!(element instanceof HTMLElement) || isSkippable(element) || hasEditableDescendant(element)) return 0;
|
|
1241
1264
|
const rect = element.getBoundingClientRect();
|
|
@@ -1252,7 +1275,6 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1252
1275
|
if (/调用|消耗|上下文|usage|context|缓存|命中|输入|输出/i.test(text)) score += 2;
|
|
1253
1276
|
if (/轮次|轮|步骤|步数|步|steps?|rounds?|turns?/i.test(text)) score += 2;
|
|
1254
1277
|
if (/[·•|;;]/.test(text)) score += 2;
|
|
1255
|
-
if (/button|input|textarea|select/i.test(element.tagName)) score -= 4;
|
|
1256
1278
|
return score;
|
|
1257
1279
|
};
|
|
1258
1280
|
const chooseTelemetryElements = () => {
|
|
@@ -1380,29 +1402,40 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1380
1402
|
event.stopPropagation();
|
|
1381
1403
|
setCollapsed(!collapsed);
|
|
1382
1404
|
});
|
|
1383
|
-
const renderPanel = (
|
|
1384
|
-
const rows = splitTelemetryRows(
|
|
1405
|
+
const renderPanel = (telemetryText) => {
|
|
1406
|
+
const rows = splitTelemetryRows(telemetryText);
|
|
1385
1407
|
panel.hidden = rows.length === 0;
|
|
1386
1408
|
toggle.hidden = rows.length === 0;
|
|
1387
|
-
content.replaceChildren(...rows.map((
|
|
1409
|
+
content.replaceChildren(...rows.map((rowText) => {
|
|
1388
1410
|
const row = document.createElement("div");
|
|
1389
1411
|
row.className = "dsh-skin-telemetry-row";
|
|
1390
1412
|
const metric = document.createElement("span");
|
|
1391
1413
|
metric.className = "dsh-skin-telemetry-value dsh-skin-telemetry-value-full";
|
|
1392
|
-
metric.textContent =
|
|
1414
|
+
metric.textContent = rowText;
|
|
1393
1415
|
row.append(metric);
|
|
1394
1416
|
return row;
|
|
1395
1417
|
}));
|
|
1396
1418
|
};
|
|
1397
1419
|
const isTelemetryPaused = () => document.activeElement instanceof Element && isInstructionInputTarget(document.activeElement);
|
|
1420
|
+
const getSourcesText = (sources) => [...sources].map(getTelemetryText).filter(Boolean).join(" | ");
|
|
1421
|
+
const areCachedSourcesUsable = () => {
|
|
1422
|
+
if (currentSources.size === 0) return false;
|
|
1423
|
+
const sources = [...currentSources];
|
|
1424
|
+
if (!sources.every((source) => source.isConnected && scoreCandidate(source) > 0)) return false;
|
|
1425
|
+
return splitTelemetryRows(getSourcesText(currentSources)).length > 0;
|
|
1426
|
+
};
|
|
1398
1427
|
const update = () => {
|
|
1399
1428
|
frame = 0;
|
|
1400
1429
|
if (isTelemetryPaused()) return;
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1430
|
+
let nextSources = currentSources;
|
|
1431
|
+
let text = getSourcesText(nextSources);
|
|
1432
|
+
if (!areCachedSourcesUsable()) {
|
|
1433
|
+
nextSources = new Set(chooseTelemetryElements());
|
|
1434
|
+
text = getSourcesText(nextSources);
|
|
1435
|
+
for (const source of currentSources) if (!nextSources.has(source)) source.classList.remove("dsh-skin-telemetry-source-hidden");
|
|
1436
|
+
for (const source of nextSources) if (!currentSources.has(source)) source.classList.add("dsh-skin-telemetry-source-hidden");
|
|
1437
|
+
currentSources = nextSources;
|
|
1438
|
+
}
|
|
1406
1439
|
if (text === lastText) return;
|
|
1407
1440
|
lastText = text;
|
|
1408
1441
|
renderPanel(text);
|
|
@@ -1421,7 +1454,10 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1421
1454
|
const onTelemetryFocusOut = (event) => {
|
|
1422
1455
|
if (isInstructionInputTarget(event.target)) window.setTimeout(schedule, 240);
|
|
1423
1456
|
};
|
|
1424
|
-
const observer = typeof MutationObserver === "undefined" ? undefined : new MutationObserver(
|
|
1457
|
+
const observer = typeof MutationObserver === "undefined" ? undefined : new MutationObserver((mutations) => {
|
|
1458
|
+
if (mutations.every(isSkinOwnedMutation)) return;
|
|
1459
|
+
schedule();
|
|
1460
|
+
});
|
|
1425
1461
|
schedule();
|
|
1426
1462
|
observer?.observe(document.body, { childList: true, subtree: true, characterData: true });
|
|
1427
1463
|
window.addEventListener("resize", schedule, { passive: true });
|
|
@@ -1451,6 +1487,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1451
1487
|
return () => {
|
|
1452
1488
|
disposeTelemetryPanel();
|
|
1453
1489
|
disposeInteractions();
|
|
1490
|
+
disposeReducedMotionCache();
|
|
1454
1491
|
if (typeof document !== "undefined") document.body.classList.remove("dsh-skin-galactic-opera");
|
|
1455
1492
|
decor?.remove();
|
|
1456
1493
|
style?.remove();
|
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-skin-galactic-opera",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Unofficial cinematic space-opera dark skin bundle for the DSH Web GUI.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/xmnathan/dsh-skin-galactic-opera.git"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/xmnathan/dsh-skin-galactic-opera#readme",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/xmnathan/dsh-skin-galactic-opera/issues"
|
|
12
|
+
},
|
|
5
13
|
"type": "module",
|
|
6
14
|
"main": "lib/index.js",
|
|
7
15
|
"exports": {
|
|
@@ -19,8 +27,9 @@
|
|
|
19
27
|
"CHANGELOG.md"
|
|
20
28
|
],
|
|
21
29
|
"scripts": {
|
|
22
|
-
"check": "node --check lib/client.js",
|
|
23
|
-
"pack:dry": "npm pack --dry-run"
|
|
30
|
+
"check": "node --check lib/client.js && node --check lib/index.js",
|
|
31
|
+
"pack:dry": "npm pack --dry-run",
|
|
32
|
+
"prepublishOnly": "npm run check"
|
|
24
33
|
},
|
|
25
34
|
"keywords": [
|
|
26
35
|
"dsh",
|