@supermousejs/core 2.5.0-beta.1 → 2.5.0-beta.2
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 +7 -0
- package/dist/index.d.ts +44 -11
- package/dist/index.mjs +230 -142
- package/dist/index.umd.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @supermousejs/core
|
|
2
2
|
|
|
3
|
+
## 2.5.0-beta.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ff288b4: Fixed Logic Plugins not have effect from wrong ordering of target overwrite
|
|
8
|
+
- 18b57de: Fixed CSS stylesheets being destroyed erroneously from a lack of a primary owner and plugins being activated all at once by the `States` plugin when re-entering previously exited scope
|
|
9
|
+
|
|
3
10
|
## 2.5.0-beta.1
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -91,6 +91,11 @@ export declare interface MouseState {
|
|
|
91
91
|
shape: ShapeState | null;
|
|
92
92
|
/** Centralized store for hover metadata from data attributes and rules. */
|
|
93
93
|
interaction: InteractionState;
|
|
94
|
+
/** The currently active scope's identity, or null when none is active. */
|
|
95
|
+
scope: {
|
|
96
|
+
name: string | undefined;
|
|
97
|
+
container: HTMLElement;
|
|
98
|
+
} | null;
|
|
94
99
|
}
|
|
95
100
|
|
|
96
101
|
declare type ResolvedOptions = SupermouseOptions & Required<Pick<SupermouseOptions, "smoothness" | "enableTouch" | "autoDisableOnMobile" | "cursor" | "hideOnLeave" | "autoStart" | "container" | "dataPrefix" | "zIndex" | "inheritDataAttributes">>;
|
|
@@ -119,6 +124,12 @@ export declare interface ScopeConfig {
|
|
|
119
124
|
cursorPolicy?: CursorPolicyInput;
|
|
120
125
|
/** Plugins installed when this scope activates. */
|
|
121
126
|
plugins?: SupermousePlugin[];
|
|
127
|
+
/**
|
|
128
|
+
* Rules evaluated against hovered elements inside this scope. If omitted,
|
|
129
|
+
* the scope inherits the primary scope's rules. If provided, the scope
|
|
130
|
+
* uses only its own rules.
|
|
131
|
+
*/
|
|
132
|
+
rules?: Record<string, RuleDefinition>;
|
|
122
133
|
/**
|
|
123
134
|
* Whether data attributes and rules on ancestors cascade to the hovered
|
|
124
135
|
* element. Inherits from top-level if omitted.
|
|
@@ -132,8 +143,14 @@ export declare interface ScopeConfig {
|
|
|
132
143
|
export declare interface ScopeHandle {
|
|
133
144
|
readonly name: string | undefined;
|
|
134
145
|
readonly container: HTMLElement;
|
|
146
|
+
readonly disabled: boolean;
|
|
135
147
|
remove(): void;
|
|
136
148
|
setCursor(mode: CursorMode): void;
|
|
149
|
+
disable(): void;
|
|
150
|
+
enable(): void;
|
|
151
|
+
use(plugin: SupermousePlugin): ScopeHandle;
|
|
152
|
+
removePlugin(name: string): void;
|
|
153
|
+
getPlugin(name: string): SupermousePlugin | undefined;
|
|
137
154
|
}
|
|
138
155
|
|
|
139
156
|
export declare interface ShapeState {
|
|
@@ -151,7 +168,10 @@ export declare class Supermouse {
|
|
|
151
168
|
private _activeScope;
|
|
152
169
|
private _installingScope;
|
|
153
170
|
private scopeByContainer;
|
|
171
|
+
private scopeByName;
|
|
172
|
+
private scopeHandles;
|
|
154
173
|
private input;
|
|
174
|
+
private styleOwner;
|
|
155
175
|
private rafId;
|
|
156
176
|
private lastTime;
|
|
157
177
|
private visibilityAbortController;
|
|
@@ -163,6 +183,7 @@ export declare class Supermouse {
|
|
|
163
183
|
get isRunning(): boolean;
|
|
164
184
|
use(plugin: SupermousePlugin): this;
|
|
165
185
|
getPlugin(name: string): SupermousePlugin | undefined;
|
|
186
|
+
getScope(name: string): ScopeHandle | undefined;
|
|
166
187
|
enablePlugin(name: string): void;
|
|
167
188
|
disablePlugin(name: string): void;
|
|
168
189
|
togglePlugin(name: string): void;
|
|
@@ -178,13 +199,24 @@ export declare class Supermouse {
|
|
|
178
199
|
destroy(): void;
|
|
179
200
|
private _running;
|
|
180
201
|
private createScope;
|
|
202
|
+
private buildScopeHandle;
|
|
181
203
|
private removeScope;
|
|
182
204
|
private setScopeCursor;
|
|
205
|
+
private disableScope;
|
|
206
|
+
private enableScope;
|
|
207
|
+
private findScopeAbove;
|
|
183
208
|
private installPlugins;
|
|
184
209
|
private installPlugin;
|
|
210
|
+
private removePluginFromScope;
|
|
185
211
|
private handleActiveScopeChange;
|
|
186
|
-
private activatePlugin;
|
|
187
212
|
private deactivatePlugin;
|
|
213
|
+
/**
|
|
214
|
+
* Runs the deactivation lifecycle for a plugin whose owning scope just
|
|
215
|
+
* became inactive. Does NOT flip `plugin.isEnabled`, so user intent
|
|
216
|
+
* (e.g. States disabling a plugin) survives the scope round-trip.
|
|
217
|
+
*/
|
|
218
|
+
private scopeDeactivatePlugin;
|
|
219
|
+
private scopeActivatePlugin;
|
|
188
220
|
private rebuildStylesheet;
|
|
189
221
|
private runPluginSafe;
|
|
190
222
|
private cleanupCrashedPlugins;
|
|
@@ -196,21 +228,22 @@ export declare class Supermouse {
|
|
|
196
228
|
private bindVisibilityHandling;
|
|
197
229
|
private startLoop;
|
|
198
230
|
/**
|
|
199
|
-
* @deprecated
|
|
200
|
-
*
|
|
201
|
-
* plugins and runtime extension; it mutates the active scope's selector set.
|
|
202
|
-
*/
|
|
203
|
-
registerHoverTarget(selector: string): void;
|
|
204
|
-
/**
|
|
205
|
-
* @deprecated Read from the active scope instead. Exposed for tests and
|
|
206
|
-
* debugging only.
|
|
231
|
+
* @deprecated Read from the active scope instead.
|
|
232
|
+
* Exposed for tests and debugging.
|
|
207
233
|
*/
|
|
208
234
|
get hoverSelectors(): Set<string>;
|
|
209
235
|
/**
|
|
210
|
-
* @deprecated Read from the active scope instead.
|
|
211
|
-
* debugging
|
|
236
|
+
* @deprecated Read from the active scope instead.
|
|
237
|
+
* Exposed for tests and debugging.
|
|
212
238
|
*/
|
|
213
239
|
get plugins(): SupermousePlugin[];
|
|
240
|
+
/**
|
|
241
|
+
* Adds one or more hover selectors to the current scope. Intended for
|
|
242
|
+
* raw-object plugins during `install`. Plugins written with `definePlugin`
|
|
243
|
+
* should use the `selector` option instead, and consumers setting up a
|
|
244
|
+
* scope should prefer the `hoverSelectors` option at construction.
|
|
245
|
+
*/
|
|
246
|
+
registerHoverTarget(selector: string): void;
|
|
214
247
|
}
|
|
215
248
|
|
|
216
249
|
export declare type SupermouseInstance = Supermouse;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const x = {
|
|
2
2
|
rules: [
|
|
3
3
|
{ selector: "input", native: !0, hide: !0 },
|
|
4
4
|
{ selector: "textarea", native: !0, hide: !0 },
|
|
@@ -10,31 +10,31 @@ const w = {
|
|
|
10
10
|
{ selector: "[tabindex]", native: !1, hide: !0 }
|
|
11
11
|
]
|
|
12
12
|
};
|
|
13
|
-
function
|
|
14
|
-
if (!i) return
|
|
13
|
+
function _(i) {
|
|
14
|
+
if (!i) return x;
|
|
15
15
|
if ("rules" in i) return i;
|
|
16
16
|
const t = [], e = new Set(i.native ?? []), s = new Set(i.hide ?? []), n = /* @__PURE__ */ new Set([...e, ...s]);
|
|
17
|
-
for (const
|
|
17
|
+
for (const o of n)
|
|
18
18
|
t.push({
|
|
19
|
-
selector:
|
|
20
|
-
native: e.has(
|
|
21
|
-
hide: s.has(
|
|
19
|
+
selector: o,
|
|
20
|
+
native: e.has(o),
|
|
21
|
+
hide: s.has(o)
|
|
22
22
|
});
|
|
23
23
|
return { rules: t };
|
|
24
24
|
}
|
|
25
|
-
function
|
|
25
|
+
function A(i) {
|
|
26
26
|
const t = [], e = [];
|
|
27
27
|
for (const s of i.rules)
|
|
28
28
|
s.native !== !1 && t.push(s.selector), s.hide !== !1 && e.push(s.selector);
|
|
29
29
|
return { native: t, hide: e };
|
|
30
30
|
}
|
|
31
|
-
let
|
|
32
|
-
class
|
|
31
|
+
let D = 0;
|
|
32
|
+
class O {
|
|
33
33
|
constructor(t, e) {
|
|
34
34
|
if (this.container = t, !t || !(t instanceof HTMLElement))
|
|
35
35
|
throw new Error(`[Supermouse] Invalid container: ${t}. Must be an HTMLElement.`);
|
|
36
36
|
t.isConnected;
|
|
37
|
-
const s =
|
|
37
|
+
const s = D++;
|
|
38
38
|
this.scopeClass = `supermouse-scope-${s}`, this.hideClass = `supermouse-hide-${s}`;
|
|
39
39
|
const n = t === document.body;
|
|
40
40
|
if (this.element = document.createElement("div"), Object.assign(this.element.style, {
|
|
@@ -45,8 +45,8 @@ class A {
|
|
|
45
45
|
opacity: "1",
|
|
46
46
|
transition: "opacity 0.15s ease"
|
|
47
47
|
}), !n) {
|
|
48
|
-
const
|
|
49
|
-
this.originalContainerPosition =
|
|
48
|
+
const o = window.getComputedStyle(t);
|
|
49
|
+
this.originalContainerPosition = o.position, o.position === "static" && (t.style.position = "relative");
|
|
50
50
|
}
|
|
51
51
|
this.originalContainerCursor = t.style.cursor, t.appendChild(this.element), t.classList.add("supermouse-scope", this.scopeClass);
|
|
52
52
|
}
|
|
@@ -78,11 +78,11 @@ class A {
|
|
|
78
78
|
this.element.remove(), this.container.style.cursor = this.originalContainerCursor, this.container.classList.remove("supermouse-scope", this.scopeClass, this.hideClass), this.container !== document.body && this.originalContainerPosition === "static" && (this.container.style.position = "");
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
class
|
|
81
|
+
class L {
|
|
82
82
|
constructor(t, e) {
|
|
83
|
-
this.config = t, this.name = t.name, this.cursorMode = t.cursor ?? e.cursor, this.hoverSelectors = new Set(t.hoverSelectors ?? e.hoverSelectors), this.inheritDataAttributes = t.inheritDataAttributes ?? e.inheritDataAttributes;
|
|
84
|
-
const s = t.cursorPolicy ?
|
|
85
|
-
this.nativeSelectors = n.native, this.hideSelectors = n.hide, this.stage = new
|
|
83
|
+
this.config = t, this.name = t.name, this.cursorMode = t.cursor ?? e.cursor, this.hoverSelectors = new Set(t.hoverSelectors ?? e.hoverSelectors), this.inheritDataAttributes = t.inheritDataAttributes ?? e.inheritDataAttributes, this.ruleEntries = t.rules ? Object.entries(t.rules) : e.ruleEntries;
|
|
84
|
+
const s = t.cursorPolicy ? _(t.cursorPolicy) : e.cursorPolicy, n = A(s);
|
|
85
|
+
this.nativeSelectors = n.native, this.hideSelectors = n.hide, this.stage = new O(t.container, t.zIndex ?? e.zIndex);
|
|
86
86
|
}
|
|
87
87
|
config;
|
|
88
88
|
stage;
|
|
@@ -91,8 +91,10 @@ class I {
|
|
|
91
91
|
nativeSelectors;
|
|
92
92
|
hideSelectors;
|
|
93
93
|
inheritDataAttributes;
|
|
94
|
+
ruleEntries;
|
|
94
95
|
name;
|
|
95
96
|
cursorMode;
|
|
97
|
+
disabled = !1;
|
|
96
98
|
contains(t) {
|
|
97
99
|
return this.stage.containerElement.contains(t);
|
|
98
100
|
}
|
|
@@ -105,7 +107,6 @@ class I {
|
|
|
105
107
|
get nativeSelectorString() {
|
|
106
108
|
return this.nativeSelectors.join(", ");
|
|
107
109
|
}
|
|
108
|
-
/** Build the CSS rules this scope contributes to the shared stylesheet. */
|
|
109
110
|
buildRules() {
|
|
110
111
|
const t = this.stage.getRulePrefix(), e = this.stage.getExclusion(), s = [
|
|
111
112
|
`${t}${e} { cursor: none !important; }`,
|
|
@@ -120,7 +121,7 @@ class I {
|
|
|
120
121
|
), s;
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
|
-
const f = { x: -100, y: -100 },
|
|
124
|
+
const f = { x: -100, y: -100 }, I = /* @__PURE__ */ new Set([
|
|
124
125
|
"default",
|
|
125
126
|
"auto",
|
|
126
127
|
"pointer",
|
|
@@ -128,55 +129,55 @@ const f = { x: -100, y: -100 }, R = /* @__PURE__ */ new Set([
|
|
|
128
129
|
"inherit",
|
|
129
130
|
"grab",
|
|
130
131
|
"grabbing"
|
|
131
|
-
]),
|
|
132
|
+
]), R = [
|
|
132
133
|
"a",
|
|
133
134
|
"button",
|
|
134
135
|
"input",
|
|
135
136
|
"textarea",
|
|
136
137
|
"[data-hover]",
|
|
137
138
|
"[data-cursor]"
|
|
138
|
-
], u = /* @__PURE__ */ new Map(),
|
|
139
|
-
let v = null, g = !1, m = !1,
|
|
140
|
-
function
|
|
139
|
+
], u = /* @__PURE__ */ new Map(), M = /* @__PURE__ */ new Map();
|
|
140
|
+
let v = null, g = !1, m = !1, C = 0;
|
|
141
|
+
function E(i) {
|
|
141
142
|
const t = i.getBoundingClientRect();
|
|
142
143
|
return { left: t.left, top: t.top, width: t.width, height: t.height };
|
|
143
144
|
}
|
|
144
|
-
function
|
|
145
|
-
u.set(i,
|
|
146
|
-
const t =
|
|
145
|
+
function T(i) {
|
|
146
|
+
u.set(i, E(i));
|
|
147
|
+
const t = M.get(i);
|
|
147
148
|
if (t) for (const e of t) e();
|
|
148
149
|
}
|
|
149
|
-
function
|
|
150
|
-
for (const i of u.keys())
|
|
150
|
+
function b() {
|
|
151
|
+
for (const i of u.keys()) T(i);
|
|
151
152
|
}
|
|
152
|
-
function
|
|
153
|
+
function $() {
|
|
153
154
|
v || typeof ResizeObserver > "u" || (v = new ResizeObserver((i) => {
|
|
154
155
|
for (const t of i) {
|
|
155
156
|
const e = t.target;
|
|
156
|
-
u.has(e) &&
|
|
157
|
+
u.has(e) && T(e);
|
|
157
158
|
}
|
|
158
159
|
}));
|
|
159
160
|
}
|
|
160
|
-
function
|
|
161
|
-
typeof window > "u" || (g || (window.addEventListener("scroll",
|
|
161
|
+
function B() {
|
|
162
|
+
typeof window > "u" || (g || (window.addEventListener("scroll", b, { passive: !0, capture: !0 }), g = !0), m || (window.addEventListener("resize", b, { passive: !0 }), m = !0));
|
|
162
163
|
}
|
|
163
|
-
function
|
|
164
|
-
return
|
|
165
|
-
|
|
164
|
+
function H(i, t) {
|
|
165
|
+
return C++, u.has(i) || (u.set(i, E(i)), $(), v?.observe(i), B()), () => {
|
|
166
|
+
C--, C === 0 && (v?.disconnect(), v = null, u.clear(), M.clear(), g && (window.removeEventListener("scroll", b, { capture: !0 }), g = !1), m && (window.removeEventListener("resize", b), m = !1));
|
|
166
167
|
};
|
|
167
168
|
}
|
|
168
|
-
function
|
|
169
|
+
function N(i) {
|
|
169
170
|
let t = u.get(i);
|
|
170
|
-
return t || (t =
|
|
171
|
+
return t || (t = E(i), u.set(i, t)), t;
|
|
171
172
|
}
|
|
172
|
-
function
|
|
173
|
+
function z(i, t, e) {
|
|
173
174
|
if (i === document.body) return { x: t, y: e };
|
|
174
|
-
const s =
|
|
175
|
+
const s = N(i);
|
|
175
176
|
return { x: t - s.left, y: e - s.top };
|
|
176
177
|
}
|
|
177
|
-
class
|
|
178
|
+
class k {
|
|
178
179
|
constructor(t, e, s, n) {
|
|
179
|
-
this.state = t, this.options = e, this.onEnableChange = s, this.onActiveScopeChange = n, this.dataPrefix = e.dataPrefix ?? "supermouse", this.normalizedDataPrefix = this.dataPrefix.toLowerCase(), this.ignoreAttribute = `data-${this.dataPrefix}-ignore`, this.
|
|
180
|
+
this.state = t, this.options = e, this.onEnableChange = s, this.onActiveScopeChange = n, this.dataPrefix = e.dataPrefix ?? "supermouse", this.normalizedDataPrefix = this.dataPrefix.toLowerCase(), this.ignoreAttribute = `data-${this.dataPrefix}-ignore`, this.checkDeviceCapability(), this.checkMotionPreference(), this.bindEvents();
|
|
180
181
|
}
|
|
181
182
|
state;
|
|
182
183
|
options;
|
|
@@ -193,7 +194,6 @@ class B {
|
|
|
193
194
|
nativeTarget = null;
|
|
194
195
|
currentTarget = null;
|
|
195
196
|
lastParsedTarget = null;
|
|
196
|
-
ruleEntries;
|
|
197
197
|
releaseViewport = null;
|
|
198
198
|
hasSeenPointer = !1;
|
|
199
199
|
isEnabled = !0;
|
|
@@ -206,19 +206,19 @@ class B {
|
|
|
206
206
|
for (const e of t) this.scopeByContainer.set(e.container, e);
|
|
207
207
|
}
|
|
208
208
|
setActiveScope(t) {
|
|
209
|
-
t !== this.activeScope && (this.activeScope = t, this.releaseViewport?.(), this.releaseViewport = t && t.container !== document.body ?
|
|
209
|
+
t !== this.activeScope && (this.activeScope = t, this.lastParsedTarget = null, this.cachedChain = [], this.releaseViewport?.(), this.releaseViewport = t && t.container !== document.body ? H(t.container) : null, this.hasSeenPointer && (this.applyPointerToState(), this.state.target.x = this.state.smooth.x = this.state.pointer.x, this.state.target.y = this.state.smooth.y = this.state.pointer.y), this.onActiveScopeChange(t));
|
|
210
210
|
}
|
|
211
211
|
findScope(t) {
|
|
212
212
|
let e = t;
|
|
213
213
|
for (; e; ) {
|
|
214
214
|
const s = this.scopeByContainer.get(e);
|
|
215
|
-
if (s) return s;
|
|
215
|
+
if (s && !s.disabled) return s;
|
|
216
216
|
e = e.parentElement;
|
|
217
217
|
}
|
|
218
218
|
return null;
|
|
219
219
|
}
|
|
220
220
|
applyPointerToState() {
|
|
221
|
-
const t = this.activeScope?.container ?? document.body, e =
|
|
221
|
+
const t = this.activeScope?.container ?? document.body, e = z(t, this.viewportX, this.viewportY);
|
|
222
222
|
this.state.pointer.x = e.x, this.state.pointer.y = e.y;
|
|
223
223
|
}
|
|
224
224
|
checkDeviceCapability() {
|
|
@@ -239,42 +239,43 @@ class B {
|
|
|
239
239
|
this.isEnabled = t, this.onEnableChange(t);
|
|
240
240
|
}
|
|
241
241
|
parseDOMInteraction(t) {
|
|
242
|
-
|
|
242
|
+
if (!this.activeScope) return;
|
|
243
|
+
const e = this.activeScope.container, s = this.activeScope.inheritDataAttributes, n = this.normalizedDataPrefix, o = this.activeScope.ruleEntries;
|
|
243
244
|
if (t !== this.lastParsedTarget) {
|
|
244
245
|
this.lastParsedTarget = t, this.cachedChain = [];
|
|
245
|
-
let
|
|
246
|
-
for (;
|
|
247
|
-
const
|
|
248
|
-
for (const [a,
|
|
249
|
-
this.matchesSelector(
|
|
250
|
-
if (this.cachedChain.push({ element:
|
|
251
|
-
const c =
|
|
246
|
+
let r = t;
|
|
247
|
+
for (; r; ) {
|
|
248
|
+
const p = [];
|
|
249
|
+
for (const [a, l] of o)
|
|
250
|
+
this.matchesSelector(r, a) && p.push({ selector: a, rules: l });
|
|
251
|
+
if (this.cachedChain.push({ element: r, matchedRules: p }), !s || r === e) break;
|
|
252
|
+
const c = r.parentElement;
|
|
252
253
|
if (!c || !e.contains(c)) break;
|
|
253
|
-
|
|
254
|
+
r = c;
|
|
254
255
|
}
|
|
255
256
|
}
|
|
256
|
-
const
|
|
257
|
-
for (const { element:
|
|
257
|
+
const h = {};
|
|
258
|
+
for (const { element: r, matchedRules: p } of this.cachedChain) {
|
|
258
259
|
const c = {};
|
|
259
|
-
for (const { rules: a } of
|
|
260
|
+
for (const { rules: a } of p)
|
|
260
261
|
try {
|
|
261
|
-
const
|
|
262
|
-
if (!
|
|
263
|
-
for (const [
|
|
264
|
-
c[
|
|
262
|
+
const l = typeof a == "function" ? a(r) : a;
|
|
263
|
+
if (!l || typeof l != "object") continue;
|
|
264
|
+
for (const [S, d] of Object.entries(l))
|
|
265
|
+
c[S] = typeof d == "function" ? d(r) : d;
|
|
265
266
|
} catch {
|
|
266
267
|
}
|
|
267
|
-
for (const a in
|
|
268
|
+
for (const a in r.dataset) {
|
|
268
269
|
if (!a.toLowerCase().startsWith(n)) continue;
|
|
269
|
-
const
|
|
270
|
-
if (!
|
|
271
|
-
const
|
|
272
|
-
c[
|
|
270
|
+
const l = a.slice(n.length);
|
|
271
|
+
if (!l) continue;
|
|
272
|
+
const S = l[0].toLowerCase() + l.slice(1), d = r.dataset[a];
|
|
273
|
+
c[S] = d == null || d === "" ? !0 : d;
|
|
273
274
|
}
|
|
274
|
-
for (const [a,
|
|
275
|
-
a in
|
|
275
|
+
for (const [a, l] of Object.entries(c))
|
|
276
|
+
a in h || (h[a] = l);
|
|
276
277
|
}
|
|
277
|
-
this.state.interaction =
|
|
278
|
+
this.state.interaction = h;
|
|
278
279
|
}
|
|
279
280
|
matchesSelector(t, e) {
|
|
280
281
|
try {
|
|
@@ -310,7 +311,7 @@ class B {
|
|
|
310
311
|
this.state.isNative = !0, this.nativeTarget = e;
|
|
311
312
|
return;
|
|
312
313
|
}
|
|
313
|
-
(e.isContentEditable || !
|
|
314
|
+
(e.isContentEditable || !I.has(this.resolveComputedCursor(e))) && (this.state.isNative = !0, this.nativeTarget = e);
|
|
314
315
|
}
|
|
315
316
|
};
|
|
316
317
|
handleMouseOut = (t) => {
|
|
@@ -332,34 +333,39 @@ class B {
|
|
|
332
333
|
this.abortController.abort(), this.releaseViewport?.(), this.cachedChain = [];
|
|
333
334
|
}
|
|
334
335
|
}
|
|
335
|
-
let
|
|
336
|
-
|
|
337
|
-
|
|
336
|
+
let V = 0;
|
|
337
|
+
const y = /* @__PURE__ */ new Map();
|
|
338
|
+
function F() {
|
|
339
|
+
return V++;
|
|
338
340
|
}
|
|
339
|
-
function
|
|
340
|
-
|
|
341
|
-
`))
|
|
341
|
+
function j(i, t) {
|
|
342
|
+
let e = y.get(i);
|
|
343
|
+
e || (e = document.createElement("style"), e.id = `supermouse-styles-${i}`, document.head.appendChild(e), y.set(i, e)), e.textContent = t.join(`
|
|
344
|
+
`);
|
|
342
345
|
}
|
|
343
|
-
function
|
|
344
|
-
|
|
346
|
+
function Q(i) {
|
|
347
|
+
y.get(i)?.remove(), y.delete(i);
|
|
345
348
|
}
|
|
346
|
-
const
|
|
347
|
-
function
|
|
349
|
+
const P = "2.5.0-beta.2";
|
|
350
|
+
function U(i, t, e) {
|
|
348
351
|
return i + (t - i) * e;
|
|
349
352
|
}
|
|
350
|
-
function
|
|
351
|
-
return
|
|
353
|
+
function w(i, t, e, s) {
|
|
354
|
+
return U(i, t, 1 - Math.exp(-e * s));
|
|
352
355
|
}
|
|
353
|
-
class
|
|
354
|
-
static version =
|
|
355
|
-
version =
|
|
356
|
+
class Y {
|
|
357
|
+
static version = P;
|
|
358
|
+
version = P;
|
|
356
359
|
state;
|
|
357
360
|
options;
|
|
358
361
|
_scopes = [];
|
|
359
362
|
_activeScope = null;
|
|
360
363
|
_installingScope = null;
|
|
361
364
|
scopeByContainer = /* @__PURE__ */ new Map();
|
|
365
|
+
scopeByName = /* @__PURE__ */ new Map();
|
|
366
|
+
scopeHandles = /* @__PURE__ */ new Map();
|
|
362
367
|
input;
|
|
368
|
+
styleOwner;
|
|
363
369
|
rafId = 0;
|
|
364
370
|
lastTime = 0;
|
|
365
371
|
visibilityAbortController = new AbortController();
|
|
@@ -377,7 +383,7 @@ class Q {
|
|
|
377
383
|
zIndex: 9999,
|
|
378
384
|
inheritDataAttributes: !0,
|
|
379
385
|
...t
|
|
380
|
-
}, this.state = {
|
|
386
|
+
}, this.styleOwner = F(), this.state = {
|
|
381
387
|
pointer: { ...f },
|
|
382
388
|
target: { ...f },
|
|
383
389
|
smooth: { ...f },
|
|
@@ -392,7 +398,8 @@ class Q {
|
|
|
392
398
|
reducedMotion: !1,
|
|
393
399
|
hasReceivedInput: !1,
|
|
394
400
|
shape: null,
|
|
395
|
-
interaction: {}
|
|
401
|
+
interaction: {},
|
|
402
|
+
scope: null
|
|
396
403
|
};
|
|
397
404
|
const e = this.createScope({
|
|
398
405
|
container: this.options.container,
|
|
@@ -400,9 +407,10 @@ class Q {
|
|
|
400
407
|
hoverSelectors: this.options.hoverSelectors,
|
|
401
408
|
cursorPolicy: this.options.cursorPolicy,
|
|
402
409
|
plugins: this.options.plugins,
|
|
410
|
+
rules: this.options.rules,
|
|
403
411
|
zIndex: this.options.zIndex
|
|
404
412
|
});
|
|
405
|
-
if (this.input = new
|
|
413
|
+
if (this.input = new k(
|
|
406
414
|
this.state,
|
|
407
415
|
this.options,
|
|
408
416
|
(s) => {
|
|
@@ -435,9 +443,16 @@ class Q {
|
|
|
435
443
|
if (s) return s;
|
|
436
444
|
}
|
|
437
445
|
}
|
|
446
|
+
getScope(t) {
|
|
447
|
+
const e = this.scopeByName.get(t);
|
|
448
|
+
return e ? this.scopeHandles.get(e) : void 0;
|
|
449
|
+
}
|
|
438
450
|
enablePlugin(t) {
|
|
439
451
|
const e = this.getPlugin(t);
|
|
440
|
-
e
|
|
452
|
+
if (!e || e.isEnabled !== !1) return;
|
|
453
|
+
e.isEnabled = !0;
|
|
454
|
+
const s = this._activeScope;
|
|
455
|
+
s && !s.disabled && s.plugins.includes(e) && this.scopeActivatePlugin(e);
|
|
441
456
|
}
|
|
442
457
|
disablePlugin(t) {
|
|
443
458
|
const e = this.getPlugin(t);
|
|
@@ -452,12 +467,7 @@ class Q {
|
|
|
452
467
|
}
|
|
453
468
|
addScope(t) {
|
|
454
469
|
const e = this.createScope(t);
|
|
455
|
-
return this.input.setScopes(this._scopes), this.installPlugins(e), this.rebuildStylesheet(),
|
|
456
|
-
name: e.name,
|
|
457
|
-
container: e.container,
|
|
458
|
-
remove: () => this.removeScope(e),
|
|
459
|
-
setCursor: (s) => this.setScopeCursor(e, s)
|
|
460
|
-
};
|
|
470
|
+
return this.input.setScopes(this._scopes), this.installPlugins(e), this.rebuildStylesheet(), this.scopeHandles.get(e);
|
|
461
471
|
}
|
|
462
472
|
enable() {
|
|
463
473
|
this.input.isEnabled = !0, this.input.hasSeenPointer && (this.state.target.x = this.state.smooth.x = this.state.pointer.x, this.state.target.y = this.state.smooth.y = this.state.pointer.y, this.resetMotion(), this.state.hasReceivedInput = !0), this._activeScope && this._activeScope.stage.setNativeCursor(this.resolveCursorState());
|
|
@@ -484,19 +494,42 @@ class Q {
|
|
|
484
494
|
}
|
|
485
495
|
t.stage.destroy();
|
|
486
496
|
}
|
|
487
|
-
this._scopes = [], this.scopeByContainer.clear(), this._activeScope = null,
|
|
497
|
+
this._scopes = [], this.scopeByContainer.clear(), this.scopeByName.clear(), this.scopeHandles.clear(), this._activeScope = null, this.state.scope = null, Q(this.styleOwner);
|
|
488
498
|
}
|
|
489
499
|
// ─── Internal ───
|
|
490
500
|
_running = !1;
|
|
491
501
|
createScope(t) {
|
|
492
|
-
|
|
502
|
+
this.scopeByContainer.has(t.container);
|
|
503
|
+
const e = new L(t, {
|
|
493
504
|
cursor: this.options.cursor,
|
|
494
|
-
hoverSelectors: this.options.hoverSelectors ??
|
|
495
|
-
cursorPolicy: this.options.cursorPolicy ?
|
|
505
|
+
hoverSelectors: this.options.hoverSelectors ?? R,
|
|
506
|
+
cursorPolicy: this.options.cursorPolicy ? _(this.options.cursorPolicy) : x,
|
|
496
507
|
zIndex: this.options.zIndex,
|
|
497
|
-
inheritDataAttributes: this.options.inheritDataAttributes
|
|
508
|
+
inheritDataAttributes: this.options.inheritDataAttributes,
|
|
509
|
+
ruleEntries: this.options.rules ? Object.entries(this.options.rules) : []
|
|
498
510
|
});
|
|
499
|
-
return this._scopes.push(e), this.scopeByContainer.set(e.container, e), e;
|
|
511
|
+
return this._scopes.push(e), this.scopeByContainer.set(e.container, e), e.name && this.scopeByName.set(e.name, e), this.scopeHandles.set(e, this.buildScopeHandle(e)), e;
|
|
512
|
+
}
|
|
513
|
+
buildScopeHandle(t) {
|
|
514
|
+
const e = {
|
|
515
|
+
get name() {
|
|
516
|
+
return t.name;
|
|
517
|
+
},
|
|
518
|
+
get container() {
|
|
519
|
+
return t.container;
|
|
520
|
+
},
|
|
521
|
+
get disabled() {
|
|
522
|
+
return t.disabled;
|
|
523
|
+
},
|
|
524
|
+
remove: () => this.removeScope(t),
|
|
525
|
+
setCursor: (s) => this.setScopeCursor(t, s),
|
|
526
|
+
disable: () => this.disableScope(t),
|
|
527
|
+
enable: () => this.enableScope(t),
|
|
528
|
+
use: (s) => (this.installPlugin(t, s), e),
|
|
529
|
+
removePlugin: (s) => this.removePluginFromScope(t, s),
|
|
530
|
+
getPlugin: (s) => t.plugins.find((n) => n.name === s)
|
|
531
|
+
};
|
|
532
|
+
return e;
|
|
500
533
|
}
|
|
501
534
|
removeScope(t) {
|
|
502
535
|
const e = this._scopes.indexOf(t);
|
|
@@ -506,12 +539,34 @@ class Q {
|
|
|
506
539
|
s.destroy?.(this);
|
|
507
540
|
} catch {
|
|
508
541
|
}
|
|
509
|
-
t.plugins.length = 0, t.stage.destroy(), this._scopes.splice(e, 1), this.scopeByContainer.delete(t.container), this.
|
|
542
|
+
if (t.plugins.length = 0, t.stage.destroy(), this._scopes.splice(e, 1), this.scopeByContainer.delete(t.container), t.name && this.scopeByName.delete(t.name), this.scopeHandles.delete(t), this.input.setScopes(this._scopes), this._activeScope === t) {
|
|
543
|
+
const s = this.findScopeAbove(t.container.parentElement) ?? this._scopes.find((n) => !n.disabled) ?? null;
|
|
544
|
+
this.input.setActiveScope(s);
|
|
545
|
+
}
|
|
546
|
+
this.rebuildStylesheet();
|
|
510
547
|
}
|
|
511
548
|
}
|
|
512
549
|
setScopeCursor(t, e) {
|
|
513
550
|
t.cursorMode = e, t === this._activeScope && (this.state.cursorMode = e);
|
|
514
551
|
}
|
|
552
|
+
disableScope(t) {
|
|
553
|
+
if (!t.disabled && (t.disabled = !0, this._activeScope === t)) {
|
|
554
|
+
const e = this.findScopeAbove(t.container.parentElement) ?? this._scopes.find((s) => !s.disabled) ?? null;
|
|
555
|
+
this.input.setActiveScope(e);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
enableScope(t) {
|
|
559
|
+
t.disabled = !1;
|
|
560
|
+
}
|
|
561
|
+
findScopeAbove(t) {
|
|
562
|
+
let e = t;
|
|
563
|
+
for (; e; ) {
|
|
564
|
+
const s = this.scopeByContainer.get(e);
|
|
565
|
+
if (s && !s.disabled) return s;
|
|
566
|
+
e = e.parentElement;
|
|
567
|
+
}
|
|
568
|
+
return null;
|
|
569
|
+
}
|
|
515
570
|
installPlugins(t) {
|
|
516
571
|
if (t.config.plugins)
|
|
517
572
|
for (const e of t.config.plugins) this.installPlugin(t, e);
|
|
@@ -525,23 +580,39 @@ class Q {
|
|
|
525
580
|
this._installingScope = null;
|
|
526
581
|
return;
|
|
527
582
|
}
|
|
528
|
-
this._installingScope = null, t.plugins.push(e), t.plugins.sort((s, n) => (s.priority ?? 0) - (n.priority ?? 0)), t !== this._activeScope
|
|
583
|
+
this._installingScope = null, t.plugins.push(e), t.plugins.sort((s, n) => (s.priority ?? 0) - (n.priority ?? 0)), (t !== this._activeScope || t.disabled) && e.element && (e.element.style.display = "none");
|
|
529
584
|
}
|
|
530
585
|
}
|
|
586
|
+
removePluginFromScope(t, e) {
|
|
587
|
+
const s = t.plugins.findIndex((r) => r.name === e);
|
|
588
|
+
if (s === -1) return;
|
|
589
|
+
const n = t.plugins[s];
|
|
590
|
+
t.plugins.splice(s, 1);
|
|
591
|
+
const o = () => {
|
|
592
|
+
try {
|
|
593
|
+
n.onDisable?.(this), n.destroy?.(this);
|
|
594
|
+
} catch {
|
|
595
|
+
}
|
|
596
|
+
n.element?.remove();
|
|
597
|
+
}, h = n.onBeforeDisable?.(this);
|
|
598
|
+
h && typeof h.then == "function" ? Promise.resolve(h).then(o).catch((r) => {
|
|
599
|
+
o();
|
|
600
|
+
}) : o();
|
|
601
|
+
}
|
|
531
602
|
handleActiveScopeChange(t) {
|
|
532
603
|
const e = this._activeScope;
|
|
533
604
|
if (e !== t) {
|
|
534
605
|
if (e)
|
|
535
|
-
for (const s of e.plugins)
|
|
606
|
+
for (const s of e.plugins)
|
|
607
|
+
s.isEnabled !== !1 && this.scopeDeactivatePlugin(s);
|
|
536
608
|
if (this._activeScope = t, t) {
|
|
537
|
-
this.state.cursorMode = t.cursorMode;
|
|
538
|
-
for (const s of t.plugins)
|
|
539
|
-
|
|
609
|
+
this.state.cursorMode = t.cursorMode, this.state.scope = { name: t.name, container: t.container };
|
|
610
|
+
for (const s of t.plugins)
|
|
611
|
+
s.isEnabled !== !1 && this.scopeActivatePlugin(s);
|
|
612
|
+
} else
|
|
613
|
+
this.state.scope = null;
|
|
540
614
|
}
|
|
541
615
|
}
|
|
542
|
-
activatePlugin(t) {
|
|
543
|
-
t.isEnabled === !1 && (t.isEnabled = !0, t.element && (t.element.style.display = ""), t.onEnable?.(this));
|
|
544
|
-
}
|
|
545
616
|
deactivatePlugin(t) {
|
|
546
617
|
if (t.isEnabled === !1) return;
|
|
547
618
|
t.isEnabled = !1;
|
|
@@ -552,10 +623,26 @@ class Q {
|
|
|
552
623
|
e();
|
|
553
624
|
}) : e();
|
|
554
625
|
}
|
|
626
|
+
/**
|
|
627
|
+
* Runs the deactivation lifecycle for a plugin whose owning scope just
|
|
628
|
+
* became inactive. Does NOT flip `plugin.isEnabled`, so user intent
|
|
629
|
+
* (e.g. States disabling a plugin) survives the scope round-trip.
|
|
630
|
+
*/
|
|
631
|
+
scopeDeactivatePlugin(t) {
|
|
632
|
+
const e = () => {
|
|
633
|
+
t.element && (t.element.style.display = "none"), t.onDisable?.(this);
|
|
634
|
+
}, s = t.onBeforeDisable?.(this);
|
|
635
|
+
s && typeof s.then == "function" ? Promise.resolve(s).then(e).catch((n) => {
|
|
636
|
+
e();
|
|
637
|
+
}) : e();
|
|
638
|
+
}
|
|
639
|
+
scopeActivatePlugin(t) {
|
|
640
|
+
t.element && (t.element.style.display = ""), t.onEnable?.(this);
|
|
641
|
+
}
|
|
555
642
|
rebuildStylesheet() {
|
|
556
643
|
const t = [];
|
|
557
644
|
for (const e of this._scopes) t.push(...e.buildRules());
|
|
558
|
-
|
|
645
|
+
j(this.styleOwner, t);
|
|
559
646
|
}
|
|
560
647
|
runPluginSafe(t, e) {
|
|
561
648
|
if (t.isEnabled !== !1)
|
|
@@ -597,18 +684,18 @@ class Q {
|
|
|
597
684
|
const e = t - this.lastTime, s = Math.min(e / 1e3, 0.1);
|
|
598
685
|
this.lastTime = t;
|
|
599
686
|
const n = this.input.getCurrentTarget();
|
|
600
|
-
n && !n.isConnected ? this.input.clearHover() : n && this.input.parseDOMInteraction(n);
|
|
601
|
-
const
|
|
602
|
-
if (
|
|
603
|
-
|
|
604
|
-
for (let
|
|
605
|
-
this.runPluginSafe(
|
|
687
|
+
n && !n.isConnected ? this.input.clearHover() : n && this.input.parseDOMInteraction(n), this.input.isEnabled && this.state.hasReceivedInput && (this.state.target.x = this.state.pointer.x, this.state.target.y = this.state.pointer.y);
|
|
688
|
+
const o = this._activeScope;
|
|
689
|
+
if (o) {
|
|
690
|
+
o.stage.setVisibility(this.resolveStageVisibility()), this.input.isEnabled && o.stage.setNativeCursor(this.resolveCursorState());
|
|
691
|
+
for (let h = 0; h < o.plugins.length; h++)
|
|
692
|
+
this.runPluginSafe(o.plugins[h], e);
|
|
606
693
|
}
|
|
607
|
-
if (this.cleanupCrashedPlugins(), this.input.isEnabled
|
|
608
|
-
const
|
|
609
|
-
this.state.smooth.x =
|
|
610
|
-
const { x:
|
|
611
|
-
(Math.abs(
|
|
694
|
+
if (this.cleanupCrashedPlugins(), this.input.isEnabled) {
|
|
695
|
+
const h = this.state.reducedMotion ? 1e3 : 1 / this.options.smoothness * 2, r = this.state.smooth.x, p = this.state.smooth.y;
|
|
696
|
+
this.state.smooth.x = w(this.state.smooth.x, this.state.target.x, h, s), this.state.smooth.y = w(this.state.smooth.y, this.state.target.y, h, s), this.state.displacement.x = this.state.target.x - this.state.smooth.x, this.state.displacement.y = this.state.target.y - this.state.smooth.y, s > 0 ? (this.state.velocity.x = (this.state.smooth.x - r) / s, this.state.velocity.y = (this.state.smooth.y - p) / s) : (this.state.velocity.x = 0, this.state.velocity.y = 0);
|
|
697
|
+
const { x: c, y: a } = this.state.velocity;
|
|
698
|
+
(Math.abs(c) > 0.1 || Math.abs(a) > 0.1) && (this.state.angle = Math.atan2(a, c) * (180 / Math.PI));
|
|
612
699
|
}
|
|
613
700
|
}
|
|
614
701
|
tick = (t) => {
|
|
@@ -627,37 +714,38 @@ class Q {
|
|
|
627
714
|
this._running || (this._running = !0, !document.hidden && (this.lastTime = performance.now(), this.rafId = requestAnimationFrame(this.tick)));
|
|
628
715
|
}
|
|
629
716
|
/**
|
|
630
|
-
* @deprecated
|
|
631
|
-
*
|
|
632
|
-
* plugins and runtime extension; it mutates the active scope's selector set.
|
|
633
|
-
*/
|
|
634
|
-
registerHoverTarget(t) {
|
|
635
|
-
const e = this._installingScope ?? this._activeScope ?? this._scopes[0];
|
|
636
|
-
if (e)
|
|
637
|
-
for (const s of t.split(",")) {
|
|
638
|
-
const n = s.trim();
|
|
639
|
-
n && e.hoverSelectors.add(n);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
/**
|
|
643
|
-
* @deprecated Read from the active scope instead. Exposed for tests and
|
|
644
|
-
* debugging only.
|
|
717
|
+
* @deprecated Read from the active scope instead.
|
|
718
|
+
* Exposed for tests and debugging.
|
|
645
719
|
*/
|
|
646
720
|
get hoverSelectors() {
|
|
647
721
|
const t = this._activeScope ?? this._scopes[0];
|
|
648
722
|
return t ? t.hoverSelectors : /* @__PURE__ */ new Set();
|
|
649
723
|
}
|
|
650
724
|
/**
|
|
651
|
-
* @deprecated Read from the active scope instead.
|
|
652
|
-
* debugging
|
|
725
|
+
* @deprecated Read from the active scope instead.
|
|
726
|
+
* Exposed for tests and debugging.
|
|
653
727
|
*/
|
|
654
728
|
get plugins() {
|
|
655
729
|
const t = this._activeScope ?? this._scopes[0];
|
|
656
730
|
return t ? t.plugins : [];
|
|
657
731
|
}
|
|
732
|
+
/**
|
|
733
|
+
* Adds one or more hover selectors to the current scope. Intended for
|
|
734
|
+
* raw-object plugins during `install`. Plugins written with `definePlugin`
|
|
735
|
+
* should use the `selector` option instead, and consumers setting up a
|
|
736
|
+
* scope should prefer the `hoverSelectors` option at construction.
|
|
737
|
+
*/
|
|
738
|
+
registerHoverTarget(t) {
|
|
739
|
+
const e = this._installingScope ?? this._activeScope ?? this._scopes[0];
|
|
740
|
+
if (e)
|
|
741
|
+
for (const s of t.split(",")) {
|
|
742
|
+
const n = s.trim();
|
|
743
|
+
n && e.hoverSelectors.add(n);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
658
746
|
}
|
|
659
747
|
export {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
748
|
+
x as DEFAULT_CURSOR_POLICY,
|
|
749
|
+
R as DEFAULT_HOVER_SELECTORS,
|
|
750
|
+
Y as Supermouse
|
|
663
751
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(l,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(l=typeof globalThis<"u"?globalThis:l||self,p(l.SupermouseCore={}))})(this,(function(l){"use strict";const p={rules:[{selector:"input",native:!0,hide:!0},{selector:"textarea",native:!0,hide:!0},{selector:"select",native:!0,hide:!0},{selector:"[contenteditable]",native:!0,hide:!0},{selector:"a",native:!1,hide:!0},{selector:"button",native:!1,hide:!0},{selector:'[role="button"]',native:!1,hide:!0},{selector:"[tabindex]",native:!1,hide:!0}]};function w(i){if(!i)return p;if("rules"in i)return i;const t=[],e=new Set(i.native??[]),s=new Set(i.hide??[]),n=new Set([...e,...s]);for(const r of n)t.push({selector:r,native:e.has(r),hide:s.has(r)});return{rules:t}}function A(i){const t=[],e=[];for(const s of i.rules)s.native!==!1&&t.push(s.selector),s.hide!==!1&&e.push(s.selector);return{native:t,hide:e}}let R=0;class O{constructor(t,e){if(this.container=t,!t||!(t instanceof HTMLElement))throw new Error(`[Supermouse] Invalid container: ${t}. Must be an HTMLElement.`);t.isConnected;const s=R++;this.scopeClass=`supermouse-scope-${s}`,this.hideClass=`supermouse-hide-${s}`;const n=t===document.body;if(this.element=document.createElement("div"),Object.assign(this.element.style,{position:n?"fixed":"absolute",inset:"0px",pointerEvents:"none",zIndex:String(e),opacity:"1",transition:"opacity 0.15s ease"}),!n){const r=window.getComputedStyle(t);this.originalContainerPosition=r.position,r.position==="static"&&(t.style.position="relative")}this.originalContainerCursor=t.style.cursor,t.appendChild(this.element),t.classList.add("supermouse-scope",this.scopeClass)}container;element;scopeClass;hideClass;currentCursorState=null;originalContainerPosition="";originalContainerCursor="";get containerElement(){return this.container}getRulePrefix(){return`.${this.scopeClass}.${this.hideClass}`}getExclusion(){return`:not(.${this.scopeClass} .supermouse-scope):not(.${this.scopeClass} .supermouse-scope *)`}setVisibility(t){this.element.style.opacity=t?"1":"0"}setNativeCursor(t){t!==this.currentCursorState&&(this.currentCursorState=t,this.container.classList.toggle(this.hideClass,t==="none"),t==="none"?this.container.style.cursor="none":this.container===document.body?this.container.style.cursor=this.originalContainerCursor:this.container.style.cursor=this.originalContainerCursor||"auto")}destroy(){this.element.remove(),this.container.style.cursor=this.originalContainerCursor,this.container.classList.remove("supermouse-scope",this.scopeClass,this.hideClass),this.container!==document.body&&this.originalContainerPosition==="static"&&(this.container.style.position="")}}class I{constructor(t,e){this.config=t,this.name=t.name,this.cursorMode=t.cursor??e.cursor,this.hoverSelectors=new Set(t.hoverSelectors??e.hoverSelectors),this.inheritDataAttributes=t.inheritDataAttributes??e.inheritDataAttributes;const s=t.cursorPolicy?w(t.cursorPolicy):e.cursorPolicy,n=A(s);this.nativeSelectors=n.native,this.hideSelectors=n.hide,this.stage=new O(t.container,t.zIndex??e.zIndex)}config;stage;hoverSelectors;plugins=[];nativeSelectors;hideSelectors;inheritDataAttributes;name;cursorMode;contains(t){return this.stage.containerElement.contains(t)}get container(){return this.stage.containerElement}get hoverSelectorString(){return Array.from(this.hoverSelectors).join(", ")}get nativeSelectorString(){return this.nativeSelectors.join(", ")}buildRules(){const t=this.stage.getRulePrefix(),e=this.stage.getExclusion(),s=[`${t}${e} { cursor: none !important; }`,`${t} *${e} { cursor: none !important; }`];for(const n of this.hideSelectors)s.push(`${t} ${n}${e} { cursor: none !important; }`);return s.push(`${t} label${e} { cursor: none !important; }`),s.push(`${t} select${e} { cursor: none !important; }`),s.push(`${t} input[type="range"]${e}::-webkit-slider-thumb { cursor: none !important; }`),s.push(`${t} input[type="range"]${e}::-moz-range-thumb { cursor: none !important; }`),s}}const v={x:-100,y:-100},D=new Set(["default","auto","pointer","none","inherit","grab","grabbing"]),x=["a","button","input","textarea","[data-hover]","[data-cursor]"],u=new Map,_=new Map;let m=null,y=!1,S=!1,C=0;function E(i){const t=i.getBoundingClientRect();return{left:t.left,top:t.top,width:t.width,height:t.height}}function T(i){u.set(i,E(i));const t=_.get(i);if(t)for(const e of t)e()}function b(){for(const i of u.keys())T(i)}function $(){m||typeof ResizeObserver>"u"||(m=new ResizeObserver(i=>{for(const t of i){const e=t.target;u.has(e)&&T(e)}}))}function z(){typeof window>"u"||(y||(window.addEventListener("scroll",b,{passive:!0,capture:!0}),y=!0),S||(window.addEventListener("resize",b,{passive:!0}),S=!0))}function k(i,t){return C++,u.has(i)||(u.set(i,E(i)),$(),m?.observe(i),z()),()=>{C--,C===0&&(m?.disconnect(),m=null,u.clear(),_.clear(),y&&(window.removeEventListener("scroll",b,{capture:!0}),y=!1),S&&(window.removeEventListener("resize",b),S=!1))}}function N(i){let t=u.get(i);return t||(t=E(i),u.set(i,t)),t}function H(i,t,e){if(i===document.body)return{x:t,y:e};const s=N(i);return{x:t-s.left,y:e-s.top}}class V{constructor(t,e,s,n){this.state=t,this.options=e,this.onEnableChange=s,this.onActiveScopeChange=n,this.dataPrefix=e.dataPrefix??"supermouse",this.normalizedDataPrefix=this.dataPrefix.toLowerCase(),this.ignoreAttribute=`data-${this.dataPrefix}-ignore`,this.ruleEntries=e.rules?Object.entries(e.rules):[],this.checkDeviceCapability(),this.checkMotionPreference(),this.bindEvents()}state;options;onEnableChange;onActiveScopeChange;abortController=new AbortController;mediaQueryList;motionQuery;dataPrefix;normalizedDataPrefix;ignoreAttribute;activeScope=null;scopeByContainer=new Map;nativeTarget=null;currentTarget=null;lastParsedTarget=null;ruleEntries;releaseViewport=null;hasSeenPointer=!1;isEnabled=!0;viewportX=0;viewportY=0;cachedChain=[];setScopes(t){this.scopeByContainer.clear();for(const e of t)this.scopeByContainer.set(e.container,e)}setActiveScope(t){t!==this.activeScope&&(this.activeScope=t,this.releaseViewport?.(),this.releaseViewport=t&&t.container!==document.body?k(t.container):null,this.hasSeenPointer&&(this.applyPointerToState(),this.state.target.x=this.state.smooth.x=this.state.pointer.x,this.state.target.y=this.state.smooth.y=this.state.pointer.y),this.onActiveScopeChange(t))}findScope(t){let e=t;for(;e;){const s=this.scopeByContainer.get(e);if(s)return s;e=e.parentElement}return null}applyPointerToState(){const t=this.activeScope?.container??document.body,e=H(t,this.viewportX,this.viewportY);this.state.pointer.x=e.x,this.state.pointer.y=e.y}checkDeviceCapability(){this.options.autoDisableOnMobile&&(this.mediaQueryList=window.matchMedia("(pointer: fine)"),this.updateEnabledState(this.mediaQueryList.matches),this.mediaQueryList.addEventListener("change",t=>this.updateEnabledState(t.matches),{signal:this.abortController.signal}))}checkMotionPreference(){this.motionQuery=window.matchMedia("(prefers-reduced-motion: reduce)"),this.state.reducedMotion=this.motionQuery.matches,this.motionQuery.addEventListener("change",t=>{this.state.reducedMotion=t.matches},{signal:this.abortController.signal})}updateEnabledState(t){this.isEnabled=t,this.onEnableChange(t)}parseDOMInteraction(t){const e=this.activeScope?.container??document.body,s=this.activeScope?.inheritDataAttributes??!0,n=this.normalizedDataPrefix;if(t!==this.lastParsedTarget){this.lastParsedTarget=t,this.cachedChain=[];let o=t;for(;o;){const g=[];for(const[a,h]of this.ruleEntries)this.matchesSelector(o,a)&&g.push({selector:a,rules:h});if(this.cachedChain.push({element:o,matchedRules:g}),!s||o===e)break;const c=o.parentElement;if(!c||!e.contains(c))break;o=c}}const r={};for(const{element:o,matchedRules:g}of this.cachedChain){const c={};for(const{rules:a}of g)try{const h=typeof a=="function"?a(o):a;if(!h||typeof h!="object")continue;for(const[P,f]of Object.entries(h))c[P]=typeof f=="function"?f(o):f}catch{}for(const a in o.dataset){if(!a.toLowerCase().startsWith(n))continue;const h=a.slice(n.length);if(!h)continue;const P=h[0].toLowerCase()+h.slice(1),f=o.dataset[a];c[P]=f==null||f===""?!0:f}for(const[a,h]of Object.entries(c))a in r||(r[a]=h)}this.state.interaction=r}matchesSelector(t,e){try{return t.matches(e)}catch{return!1}}resolveComputedCursor(t){return window.getComputedStyle(t).cursor}handleMove=t=>{this.options.autoDisableOnMobile&&t.pointerType==="touch"&&!this.options.enableTouch||(this.viewportX=t.clientX,this.viewportY=t.clientY,this.hasSeenPointer=!0,this.applyPointerToState(),this.isEnabled&&(this.state.hasReceivedInput||(this.state.hasReceivedInput=!0,this.state.target.x=this.state.smooth.x=this.state.pointer.x,this.state.target.y=this.state.smooth.y=this.state.pointer.y)))};handleDown=()=>{this.isEnabled&&(this.state.isDown=!0)};handleUp=()=>{this.isEnabled&&(this.state.isDown=!1)};handleMouseOver=t=>{if(!this.isEnabled)return;const e=t.target,s=this.findScope(e);if(s&&s!==this.activeScope&&this.setActiveScope(s),!this.activeScope)return;if(this.state.cursorMode==="auto"&&e.closest(`[${this.ignoreAttribute}]`)){this.clearHover(),this.state.isNative=!0,this.nativeTarget=e;return}this.state.isNative=!1,this.nativeTarget=null,this.currentTarget=e,this.parseDOMInteraction(e);const n=e.closest(this.activeScope.hoverSelectorString);if(n&&(this.state.isHover=!0,this.state.hoverTarget=n),this.state.cursorMode==="auto"){if(this.matchesSelector(e,this.activeScope.nativeSelectorString)){this.state.isNative=!0,this.nativeTarget=e;return}(e.isContentEditable||!D.has(this.resolveComputedCursor(e)))&&(this.state.isNative=!0,this.nativeTarget=e)}};handleMouseOut=t=>{if(!this.isEnabled)return;const e=t.target,s=t.relatedTarget;(e===this.state.hoverTarget||e.contains(this.state.hoverTarget))&&(!s||!this.state.hoverTarget?.contains(s))&&(this.state.isHover=!1,this.state.hoverTarget=null),this.nativeTarget&&(e===this.nativeTarget||e.contains(this.nativeTarget))&&(!s||!this.nativeTarget.contains(s))&&(this.state.isNative=!1,this.nativeTarget=null),e===this.currentTarget&&(this.currentTarget=null,this.lastParsedTarget=null,this.cachedChain=[]),!s&&this.options.hideOnLeave&&(this.state.hasReceivedInput=!1,this.state.pointer={...v})};clearHover(){this.state.isHover=!1,this.state.hoverTarget=null,this.state.isNative=!1,this.nativeTarget=null,this.state.interaction={},this.currentTarget=null,this.lastParsedTarget=null,this.cachedChain=[]}getCurrentTarget(){return this.currentTarget}bindEvents(){const{signal:t}=this.abortController;window.addEventListener("pointermove",this.handleMove,{passive:!0,signal:t}),window.addEventListener("pointerdown",this.handleDown,{passive:!0,signal:t}),window.addEventListener("pointerup",this.handleUp,{signal:t}),document.addEventListener("mouseover",this.handleMouseOver,{signal:t}),document.addEventListener("mouseout",this.handleMouseOut,{signal:t})}destroy(){this.abortController.abort(),this.releaseViewport?.(),this.cachedChain=[]}}let d=null;function B(){d||typeof document>"u"||(d=document.createElement("style"),d.id="supermouse-styles",document.head.appendChild(d))}function F(i){B(),d&&(d.textContent=i.join(`
|
|
2
|
-
`))}function U(){d?.remove(),d=null}const M="2.5.0-beta.1";function j(i,t,e){return i+(t-i)*e}function L(i,t,e,s){return j(i,t,1-Math.exp(-e*s))}class Q{static version=M;version=M;state;options;_scopes=[];_activeScope=null;_installingScope=null;scopeByContainer=new Map;input;rafId=0;lastTime=0;visibilityAbortController=new AbortController;crashedPlugins=[];constructor(t={}){this.options={smoothness:.15,enableTouch:!1,autoDisableOnMobile:!0,cursor:"auto",hideOnLeave:!0,autoStart:!0,container:document.body,dataPrefix:"supermouse",zIndex:9999,inheritDataAttributes:!0,...t},this.state={pointer:{...v},target:{...v},smooth:{...v},velocity:{x:0,y:0},displacement:{x:0,y:0},angle:0,isDown:!1,isHover:!1,isNative:!1,cursorMode:this.options.cursor,hoverTarget:null,reducedMotion:!1,hasReceivedInput:!1,shape:null,interaction:{}};const e=this.createScope({container:this.options.container,cursor:this.options.cursor,hoverSelectors:this.options.hoverSelectors,cursorPolicy:this.options.cursorPolicy,plugins:this.options.plugins,zIndex:this.options.zIndex});if(this.input=new V(this.state,this.options,s=>{s||this.reset()},s=>this.handleActiveScopeChange(s)),this.input.setScopes(this._scopes),this.input.setActiveScope(e),this.installPlugins(e),this.options.scopes)for(const s of this.options.scopes)this.addScope(s);this.rebuildStylesheet(),this.bindVisibilityHandling(),this.options.autoStart&&this.startLoop()}get container(){return(this._activeScope??this._scopes[0]).container}get stage(){return(this._installingScope??this._activeScope??this._scopes[0]).stage.element}get isEnabled(){return this.input.isEnabled}get isRunning(){return this._running}use(t){return this.installPlugin(this._scopes[0],t),this}getPlugin(t){for(const e of this._scopes){const s=e.plugins.find(n=>n.name===t);if(s)return s}}enablePlugin(t){const e=this.getPlugin(t);e&&e.isEnabled===!1&&(e.isEnabled=!0,e.element&&(e.element.style.display=""),e.onEnable?.(this))}disablePlugin(t){const e=this.getPlugin(t);e&&e.isEnabled!==!1&&this.deactivatePlugin(e)}togglePlugin(t){const e=this.getPlugin(t);e&&(e.isEnabled===!1?this.enablePlugin(t):this.disablePlugin(t))}setCursor(t){this._activeScope&&(this._activeScope.cursorMode=t,this.state.cursorMode=t)}addScope(t){const e=this.createScope(t);return this.input.setScopes(this._scopes),this.installPlugins(e),this.rebuildStylesheet(),{name:e.name,container:e.container,remove:()=>this.removeScope(e),setCursor:s=>this.setScopeCursor(e,s)}}enable(){this.input.isEnabled=!0,this.input.hasSeenPointer&&(this.state.target.x=this.state.smooth.x=this.state.pointer.x,this.state.target.y=this.state.smooth.y=this.state.pointer.y,this.resetMotion(),this.state.hasReceivedInput=!0),this._activeScope&&this._activeScope.stage.setNativeCursor(this.resolveCursorState())}disable(t){this.input.isEnabled=!1,this._activeScope&&(this._activeScope.stage.setNativeCursor("auto"),this._activeScope.stage.setVisibility(!1)),t?.reset&&this.reset()}reset(){this.state.target={...v},this.state.smooth={...v},this.resetMotion(),this.state.angle=0,this.state.hasReceivedInput=!1,this.state.shape=null,this.state.interaction={}}start(){this.startLoop()}step(t){this.update(t)}destroy(){this._running=!1,cancelAnimationFrame(this.rafId),this.visibilityAbortController.abort(),this.input.destroy();for(const t of this._scopes){for(const e of t.plugins)try{e.destroy?.(this)}catch{}t.stage.destroy()}this._scopes=[],this.scopeByContainer.clear(),this._activeScope=null,U()}_running=!1;createScope(t){const e=new I(t,{cursor:this.options.cursor,hoverSelectors:this.options.hoverSelectors??x,cursorPolicy:this.options.cursorPolicy?w(this.options.cursorPolicy):p,zIndex:this.options.zIndex,inheritDataAttributes:this.options.inheritDataAttributes});return this._scopes.push(e),this.scopeByContainer.set(e.container,e),e}removeScope(t){const e=this._scopes.indexOf(t);if(e!==-1){for(const s of t.plugins)try{s.destroy?.(this)}catch{}t.plugins.length=0,t.stage.destroy(),this._scopes.splice(e,1),this.scopeByContainer.delete(t.container),this.input.setScopes(this._scopes),this._activeScope===t&&this.input.setActiveScope(this._scopes[0]??null),this.rebuildStylesheet()}}setScopeCursor(t,e){t.cursorMode=e,t===this._activeScope&&(this.state.cursorMode=e)}installPlugins(t){if(t.config.plugins)for(const e of t.config.plugins)this.installPlugin(t,e)}installPlugin(t,e){if(!t.plugins.some(s=>s.name===e.name)){e.isEnabled??=!0,this._installingScope=t;try{e.install?.(this)}catch{this._installingScope=null;return}this._installingScope=null,t.plugins.push(e),t.plugins.sort((s,n)=>(s.priority??0)-(n.priority??0)),t!==this._activeScope&&(e.isEnabled=!1,e.element&&(e.element.style.display="none"))}}handleActiveScopeChange(t){const e=this._activeScope;if(e!==t){if(e)for(const s of e.plugins)this.deactivatePlugin(s);if(this._activeScope=t,t){this.state.cursorMode=t.cursorMode;for(const s of t.plugins)this.activatePlugin(s)}}}activatePlugin(t){t.isEnabled===!1&&(t.isEnabled=!0,t.element&&(t.element.style.display=""),t.onEnable?.(this))}deactivatePlugin(t){if(t.isEnabled===!1)return;t.isEnabled=!1;const e=()=>{t.element&&(t.element.style.display="none"),t.onDisable?.(this)},s=t.onBeforeDisable?.(this);s&&typeof s.then=="function"?Promise.resolve(s).then(e).catch(n=>{e()}):e()}rebuildStylesheet(){const t=[];for(const e of this._scopes)t.push(...e.buildRules());F(t)}runPluginSafe(t,e){if(t.isEnabled!==!1)try{t.update?.(this,e)}catch{t.isEnabled=!1,this.crashedPlugins.push(t)}}cleanupCrashedPlugins(){if(this.crashedPlugins.length!==0){for(const t of this.crashedPlugins){for(const e of this._scopes){const s=e.plugins.indexOf(t);if(s!==-1){e.plugins.splice(s,1);break}}try{t.onDisable?.(this),t.destroy?.(this)}catch{}t.element?.remove()}this.crashedPlugins=[]}}resolveStageVisibility(){return this.state.cursorMode==="native"?!1:this.state.cursorMode==="custom"||this.state.cursorMode==="both"?this.input.isEnabled&&this.state.hasReceivedInput:this.input.isEnabled&&!this.state.isNative&&this.state.hasReceivedInput}resolveCursorState(){return!this.input.isEnabled||this.state.cursorMode==="native"||this.state.cursorMode==="both"?"auto":this.state.cursorMode==="custom"?"none":this.state.isNative||!this.state.hasReceivedInput?"auto":"none"}resetMotion(){this.state.velocity={x:0,y:0},this.state.displacement={x:0,y:0}}update(t){const e=t-this.lastTime,s=Math.min(e/1e3,.1);this.lastTime=t;const n=this.input.getCurrentTarget();n&&!n.isConnected?this.input.clearHover():n&&this.input.parseDOMInteraction(n);const r=this._activeScope;if(r){r.stage.setVisibility(this.resolveStageVisibility()),this.input.isEnabled&&r.stage.setNativeCursor(this.resolveCursorState());for(let o=0;o<r.plugins.length;o++)this.runPluginSafe(r.plugins[o],e)}if(this.cleanupCrashedPlugins(),this.input.isEnabled&&this.state.hasReceivedInput&&(this.state.target.x=this.state.pointer.x,this.state.target.y=this.state.pointer.y),this.input.isEnabled){const o=this.state.reducedMotion?1e3:1/this.options.smoothness*2,g=this.state.smooth.x,c=this.state.smooth.y;this.state.smooth.x=L(this.state.smooth.x,this.state.target.x,o,s),this.state.smooth.y=L(this.state.smooth.y,this.state.target.y,o,s),this.state.displacement.x=this.state.target.x-this.state.smooth.x,this.state.displacement.y=this.state.target.y-this.state.smooth.y,s>0?(this.state.velocity.x=(this.state.smooth.x-g)/s,this.state.velocity.y=(this.state.smooth.y-c)/s):(this.state.velocity.x=0,this.state.velocity.y=0);const{x:a,y:h}=this.state.velocity;(Math.abs(a)>.1||Math.abs(h)>.1)&&(this.state.angle=Math.atan2(h,a)*(180/Math.PI))}}tick=t=>{this.update(t),this._running&&(this.rafId=requestAnimationFrame(this.tick))};bindVisibilityHandling(){document.addEventListener("visibilitychange",()=>{this._running&&(document.hidden?cancelAnimationFrame(this.rafId):(this.lastTime=performance.now(),this.rafId=requestAnimationFrame(this.tick)))},{signal:this.visibilityAbortController.signal})}startLoop(){this._running||(this._running=!0,!document.hidden&&(this.lastTime=performance.now(),this.rafId=requestAnimationFrame(this.tick)))}registerHoverTarget(t){const e=this._installingScope??this._activeScope??this._scopes[0];if(e)for(const s of t.split(",")){const n=s.trim();n&&e.hoverSelectors.add(n)}}get hoverSelectors(){const t=this._activeScope??this._scopes[0];return t?t.hoverSelectors:new Set}get plugins(){const t=this._activeScope??this._scopes[0];return t?t.plugins:[]}}l.DEFAULT_CURSOR_POLICY=p,l.DEFAULT_HOVER_SELECTORS=x,l.Supermouse=Q,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(u,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(u=typeof globalThis<"u"?globalThis:u||self,p(u.SupermouseCore={}))})(this,(function(u){"use strict";const p={rules:[{selector:"input",native:!0,hide:!0},{selector:"textarea",native:!0,hide:!0},{selector:"select",native:!0,hide:!0},{selector:"[contenteditable]",native:!0,hide:!0},{selector:"a",native:!1,hide:!0},{selector:"button",native:!1,hide:!0},{selector:'[role="button"]',native:!1,hide:!0},{selector:"[tabindex]",native:!1,hide:!0}]};function x(i){if(!i)return p;if("rules"in i)return i;const t=[],e=new Set(i.native??[]),s=new Set(i.hide??[]),n=new Set([...e,...s]);for(const o of n)t.push({selector:o,native:e.has(o),hide:s.has(o)});return{rules:t}}function L(i){const t=[],e=[];for(const s of i.rules)s.native!==!1&&t.push(s.selector),s.hide!==!1&&e.push(s.selector);return{native:t,hide:e}}let D=0;class I{constructor(t,e){if(this.container=t,!t||!(t instanceof HTMLElement))throw new Error(`[Supermouse] Invalid container: ${t}. Must be an HTMLElement.`);t.isConnected;const s=D++;this.scopeClass=`supermouse-scope-${s}`,this.hideClass=`supermouse-hide-${s}`;const n=t===document.body;if(this.element=document.createElement("div"),Object.assign(this.element.style,{position:n?"fixed":"absolute",inset:"0px",pointerEvents:"none",zIndex:String(e),opacity:"1",transition:"opacity 0.15s ease"}),!n){const o=window.getComputedStyle(t);this.originalContainerPosition=o.position,o.position==="static"&&(t.style.position="relative")}this.originalContainerCursor=t.style.cursor,t.appendChild(this.element),t.classList.add("supermouse-scope",this.scopeClass)}container;element;scopeClass;hideClass;currentCursorState=null;originalContainerPosition="";originalContainerCursor="";get containerElement(){return this.container}getRulePrefix(){return`.${this.scopeClass}.${this.hideClass}`}getExclusion(){return`:not(.${this.scopeClass} .supermouse-scope):not(.${this.scopeClass} .supermouse-scope *)`}setVisibility(t){this.element.style.opacity=t?"1":"0"}setNativeCursor(t){t!==this.currentCursorState&&(this.currentCursorState=t,this.container.classList.toggle(this.hideClass,t==="none"),t==="none"?this.container.style.cursor="none":this.container===document.body?this.container.style.cursor=this.originalContainerCursor:this.container.style.cursor=this.originalContainerCursor||"auto")}destroy(){this.element.remove(),this.container.style.cursor=this.originalContainerCursor,this.container.classList.remove("supermouse-scope",this.scopeClass,this.hideClass),this.container!==document.body&&this.originalContainerPosition==="static"&&(this.container.style.position="")}}class R{constructor(t,e){this.config=t,this.name=t.name,this.cursorMode=t.cursor??e.cursor,this.hoverSelectors=new Set(t.hoverSelectors??e.hoverSelectors),this.inheritDataAttributes=t.inheritDataAttributes??e.inheritDataAttributes,this.ruleEntries=t.rules?Object.entries(t.rules):e.ruleEntries;const s=t.cursorPolicy?x(t.cursorPolicy):e.cursorPolicy,n=L(s);this.nativeSelectors=n.native,this.hideSelectors=n.hide,this.stage=new I(t.container,t.zIndex??e.zIndex)}config;stage;hoverSelectors;plugins=[];nativeSelectors;hideSelectors;inheritDataAttributes;ruleEntries;name;cursorMode;disabled=!1;contains(t){return this.stage.containerElement.contains(t)}get container(){return this.stage.containerElement}get hoverSelectorString(){return Array.from(this.hoverSelectors).join(", ")}get nativeSelectorString(){return this.nativeSelectors.join(", ")}buildRules(){const t=this.stage.getRulePrefix(),e=this.stage.getExclusion(),s=[`${t}${e} { cursor: none !important; }`,`${t} *${e} { cursor: none !important; }`];for(const n of this.hideSelectors)s.push(`${t} ${n}${e} { cursor: none !important; }`);return s.push(`${t} label${e} { cursor: none !important; }`),s.push(`${t} select${e} { cursor: none !important; }`),s.push(`${t} input[type="range"]${e}::-webkit-slider-thumb { cursor: none !important; }`),s.push(`${t} input[type="range"]${e}::-moz-range-thumb { cursor: none !important; }`),s}}const v={x:-100,y:-100},$=new Set(["default","auto","pointer","none","inherit","grab","grabbing"]),_=["a","button","input","textarea","[data-hover]","[data-cursor]"],d=new Map,M=new Map;let m=null,b=!1,y=!1,E=0;function P(i){const t=i.getBoundingClientRect();return{left:t.left,top:t.top,width:t.width,height:t.height}}function T(i){d.set(i,P(i));const t=M.get(i);if(t)for(const e of t)e()}function S(){for(const i of d.keys())T(i)}function B(){m||typeof ResizeObserver>"u"||(m=new ResizeObserver(i=>{for(const t of i){const e=t.target;d.has(e)&&T(e)}}))}function H(){typeof window>"u"||(b||(window.addEventListener("scroll",S,{passive:!0,capture:!0}),b=!0),y||(window.addEventListener("resize",S,{passive:!0}),y=!0))}function N(i,t){return E++,d.has(i)||(d.set(i,P(i)),B(),m?.observe(i),H()),()=>{E--,E===0&&(m?.disconnect(),m=null,d.clear(),M.clear(),b&&(window.removeEventListener("scroll",S,{capture:!0}),b=!1),y&&(window.removeEventListener("resize",S),y=!1))}}function z(i){let t=d.get(i);return t||(t=P(i),d.set(i,t)),t}function k(i,t,e){if(i===document.body)return{x:t,y:e};const s=z(i);return{x:t-s.left,y:e-s.top}}class V{constructor(t,e,s,n){this.state=t,this.options=e,this.onEnableChange=s,this.onActiveScopeChange=n,this.dataPrefix=e.dataPrefix??"supermouse",this.normalizedDataPrefix=this.dataPrefix.toLowerCase(),this.ignoreAttribute=`data-${this.dataPrefix}-ignore`,this.checkDeviceCapability(),this.checkMotionPreference(),this.bindEvents()}state;options;onEnableChange;onActiveScopeChange;abortController=new AbortController;mediaQueryList;motionQuery;dataPrefix;normalizedDataPrefix;ignoreAttribute;activeScope=null;scopeByContainer=new Map;nativeTarget=null;currentTarget=null;lastParsedTarget=null;releaseViewport=null;hasSeenPointer=!1;isEnabled=!0;viewportX=0;viewportY=0;cachedChain=[];setScopes(t){this.scopeByContainer.clear();for(const e of t)this.scopeByContainer.set(e.container,e)}setActiveScope(t){t!==this.activeScope&&(this.activeScope=t,this.lastParsedTarget=null,this.cachedChain=[],this.releaseViewport?.(),this.releaseViewport=t&&t.container!==document.body?N(t.container):null,this.hasSeenPointer&&(this.applyPointerToState(),this.state.target.x=this.state.smooth.x=this.state.pointer.x,this.state.target.y=this.state.smooth.y=this.state.pointer.y),this.onActiveScopeChange(t))}findScope(t){let e=t;for(;e;){const s=this.scopeByContainer.get(e);if(s&&!s.disabled)return s;e=e.parentElement}return null}applyPointerToState(){const t=this.activeScope?.container??document.body,e=k(t,this.viewportX,this.viewportY);this.state.pointer.x=e.x,this.state.pointer.y=e.y}checkDeviceCapability(){this.options.autoDisableOnMobile&&(this.mediaQueryList=window.matchMedia("(pointer: fine)"),this.updateEnabledState(this.mediaQueryList.matches),this.mediaQueryList.addEventListener("change",t=>this.updateEnabledState(t.matches),{signal:this.abortController.signal}))}checkMotionPreference(){this.motionQuery=window.matchMedia("(prefers-reduced-motion: reduce)"),this.state.reducedMotion=this.motionQuery.matches,this.motionQuery.addEventListener("change",t=>{this.state.reducedMotion=t.matches},{signal:this.abortController.signal})}updateEnabledState(t){this.isEnabled=t,this.onEnableChange(t)}parseDOMInteraction(t){if(!this.activeScope)return;const e=this.activeScope.container,s=this.activeScope.inheritDataAttributes,n=this.normalizedDataPrefix,o=this.activeScope.ruleEntries;if(t!==this.lastParsedTarget){this.lastParsedTarget=t,this.cachedChain=[];let r=t;for(;r;){const g=[];for(const[a,l]of o)this.matchesSelector(r,a)&&g.push({selector:a,rules:l});if(this.cachedChain.push({element:r,matchedRules:g}),!s||r===e)break;const c=r.parentElement;if(!c||!e.contains(c))break;r=c}}const h={};for(const{element:r,matchedRules:g}of this.cachedChain){const c={};for(const{rules:a}of g)try{const l=typeof a=="function"?a(r):a;if(!l||typeof l!="object")continue;for(const[w,f]of Object.entries(l))c[w]=typeof f=="function"?f(r):f}catch{}for(const a in r.dataset){if(!a.toLowerCase().startsWith(n))continue;const l=a.slice(n.length);if(!l)continue;const w=l[0].toLowerCase()+l.slice(1),f=r.dataset[a];c[w]=f==null||f===""?!0:f}for(const[a,l]of Object.entries(c))a in h||(h[a]=l)}this.state.interaction=h}matchesSelector(t,e){try{return t.matches(e)}catch{return!1}}resolveComputedCursor(t){return window.getComputedStyle(t).cursor}handleMove=t=>{this.options.autoDisableOnMobile&&t.pointerType==="touch"&&!this.options.enableTouch||(this.viewportX=t.clientX,this.viewportY=t.clientY,this.hasSeenPointer=!0,this.applyPointerToState(),this.isEnabled&&(this.state.hasReceivedInput||(this.state.hasReceivedInput=!0,this.state.target.x=this.state.smooth.x=this.state.pointer.x,this.state.target.y=this.state.smooth.y=this.state.pointer.y)))};handleDown=()=>{this.isEnabled&&(this.state.isDown=!0)};handleUp=()=>{this.isEnabled&&(this.state.isDown=!1)};handleMouseOver=t=>{if(!this.isEnabled)return;const e=t.target,s=this.findScope(e);if(s&&s!==this.activeScope&&this.setActiveScope(s),!this.activeScope)return;if(this.state.cursorMode==="auto"&&e.closest(`[${this.ignoreAttribute}]`)){this.clearHover(),this.state.isNative=!0,this.nativeTarget=e;return}this.state.isNative=!1,this.nativeTarget=null,this.currentTarget=e,this.parseDOMInteraction(e);const n=e.closest(this.activeScope.hoverSelectorString);if(n&&(this.state.isHover=!0,this.state.hoverTarget=n),this.state.cursorMode==="auto"){if(this.matchesSelector(e,this.activeScope.nativeSelectorString)){this.state.isNative=!0,this.nativeTarget=e;return}(e.isContentEditable||!$.has(this.resolveComputedCursor(e)))&&(this.state.isNative=!0,this.nativeTarget=e)}};handleMouseOut=t=>{if(!this.isEnabled)return;const e=t.target,s=t.relatedTarget;(e===this.state.hoverTarget||e.contains(this.state.hoverTarget))&&(!s||!this.state.hoverTarget?.contains(s))&&(this.state.isHover=!1,this.state.hoverTarget=null),this.nativeTarget&&(e===this.nativeTarget||e.contains(this.nativeTarget))&&(!s||!this.nativeTarget.contains(s))&&(this.state.isNative=!1,this.nativeTarget=null),e===this.currentTarget&&(this.currentTarget=null,this.lastParsedTarget=null,this.cachedChain=[]),!s&&this.options.hideOnLeave&&(this.state.hasReceivedInput=!1,this.state.pointer={...v})};clearHover(){this.state.isHover=!1,this.state.hoverTarget=null,this.state.isNative=!1,this.nativeTarget=null,this.state.interaction={},this.currentTarget=null,this.lastParsedTarget=null,this.cachedChain=[]}getCurrentTarget(){return this.currentTarget}bindEvents(){const{signal:t}=this.abortController;window.addEventListener("pointermove",this.handleMove,{passive:!0,signal:t}),window.addEventListener("pointerdown",this.handleDown,{passive:!0,signal:t}),window.addEventListener("pointerup",this.handleUp,{signal:t}),document.addEventListener("mouseover",this.handleMouseOver,{signal:t}),document.addEventListener("mouseout",this.handleMouseOut,{signal:t})}destroy(){this.abortController.abort(),this.releaseViewport?.(),this.cachedChain=[]}}let F=0;const C=new Map;function j(){return F++}function U(i,t){let e=C.get(i);e||(e=document.createElement("style"),e.id=`supermouse-styles-${i}`,document.head.appendChild(e),C.set(i,e)),e.textContent=t.join(`
|
|
2
|
+
`)}function Q(i){C.get(i)?.remove(),C.delete(i)}const A="2.5.0-beta.2";function Y(i,t,e){return i+(t-i)*e}function O(i,t,e,s){return Y(i,t,1-Math.exp(-e*s))}class q{static version=A;version=A;state;options;_scopes=[];_activeScope=null;_installingScope=null;scopeByContainer=new Map;scopeByName=new Map;scopeHandles=new Map;input;styleOwner;rafId=0;lastTime=0;visibilityAbortController=new AbortController;crashedPlugins=[];constructor(t={}){this.options={smoothness:.15,enableTouch:!1,autoDisableOnMobile:!0,cursor:"auto",hideOnLeave:!0,autoStart:!0,container:document.body,dataPrefix:"supermouse",zIndex:9999,inheritDataAttributes:!0,...t},this.styleOwner=j(),this.state={pointer:{...v},target:{...v},smooth:{...v},velocity:{x:0,y:0},displacement:{x:0,y:0},angle:0,isDown:!1,isHover:!1,isNative:!1,cursorMode:this.options.cursor,hoverTarget:null,reducedMotion:!1,hasReceivedInput:!1,shape:null,interaction:{},scope:null};const e=this.createScope({container:this.options.container,cursor:this.options.cursor,hoverSelectors:this.options.hoverSelectors,cursorPolicy:this.options.cursorPolicy,plugins:this.options.plugins,rules:this.options.rules,zIndex:this.options.zIndex});if(this.input=new V(this.state,this.options,s=>{s||this.reset()},s=>this.handleActiveScopeChange(s)),this.input.setScopes(this._scopes),this.input.setActiveScope(e),this.installPlugins(e),this.options.scopes)for(const s of this.options.scopes)this.addScope(s);this.rebuildStylesheet(),this.bindVisibilityHandling(),this.options.autoStart&&this.startLoop()}get container(){return(this._activeScope??this._scopes[0]).container}get stage(){return(this._installingScope??this._activeScope??this._scopes[0]).stage.element}get isEnabled(){return this.input.isEnabled}get isRunning(){return this._running}use(t){return this.installPlugin(this._scopes[0],t),this}getPlugin(t){for(const e of this._scopes){const s=e.plugins.find(n=>n.name===t);if(s)return s}}getScope(t){const e=this.scopeByName.get(t);return e?this.scopeHandles.get(e):void 0}enablePlugin(t){const e=this.getPlugin(t);if(!e||e.isEnabled!==!1)return;e.isEnabled=!0;const s=this._activeScope;s&&!s.disabled&&s.plugins.includes(e)&&this.scopeActivatePlugin(e)}disablePlugin(t){const e=this.getPlugin(t);e&&e.isEnabled!==!1&&this.deactivatePlugin(e)}togglePlugin(t){const e=this.getPlugin(t);e&&(e.isEnabled===!1?this.enablePlugin(t):this.disablePlugin(t))}setCursor(t){this._activeScope&&(this._activeScope.cursorMode=t,this.state.cursorMode=t)}addScope(t){const e=this.createScope(t);return this.input.setScopes(this._scopes),this.installPlugins(e),this.rebuildStylesheet(),this.scopeHandles.get(e)}enable(){this.input.isEnabled=!0,this.input.hasSeenPointer&&(this.state.target.x=this.state.smooth.x=this.state.pointer.x,this.state.target.y=this.state.smooth.y=this.state.pointer.y,this.resetMotion(),this.state.hasReceivedInput=!0),this._activeScope&&this._activeScope.stage.setNativeCursor(this.resolveCursorState())}disable(t){this.input.isEnabled=!1,this._activeScope&&(this._activeScope.stage.setNativeCursor("auto"),this._activeScope.stage.setVisibility(!1)),t?.reset&&this.reset()}reset(){this.state.target={...v},this.state.smooth={...v},this.resetMotion(),this.state.angle=0,this.state.hasReceivedInput=!1,this.state.shape=null,this.state.interaction={}}start(){this.startLoop()}step(t){this.update(t)}destroy(){this._running=!1,cancelAnimationFrame(this.rafId),this.visibilityAbortController.abort(),this.input.destroy();for(const t of this._scopes){for(const e of t.plugins)try{e.destroy?.(this)}catch{}t.stage.destroy()}this._scopes=[],this.scopeByContainer.clear(),this.scopeByName.clear(),this.scopeHandles.clear(),this._activeScope=null,this.state.scope=null,Q(this.styleOwner)}_running=!1;createScope(t){this.scopeByContainer.has(t.container);const e=new R(t,{cursor:this.options.cursor,hoverSelectors:this.options.hoverSelectors??_,cursorPolicy:this.options.cursorPolicy?x(this.options.cursorPolicy):p,zIndex:this.options.zIndex,inheritDataAttributes:this.options.inheritDataAttributes,ruleEntries:this.options.rules?Object.entries(this.options.rules):[]});return this._scopes.push(e),this.scopeByContainer.set(e.container,e),e.name&&this.scopeByName.set(e.name,e),this.scopeHandles.set(e,this.buildScopeHandle(e)),e}buildScopeHandle(t){const e={get name(){return t.name},get container(){return t.container},get disabled(){return t.disabled},remove:()=>this.removeScope(t),setCursor:s=>this.setScopeCursor(t,s),disable:()=>this.disableScope(t),enable:()=>this.enableScope(t),use:s=>(this.installPlugin(t,s),e),removePlugin:s=>this.removePluginFromScope(t,s),getPlugin:s=>t.plugins.find(n=>n.name===s)};return e}removeScope(t){const e=this._scopes.indexOf(t);if(e!==-1){for(const s of t.plugins)try{s.destroy?.(this)}catch{}if(t.plugins.length=0,t.stage.destroy(),this._scopes.splice(e,1),this.scopeByContainer.delete(t.container),t.name&&this.scopeByName.delete(t.name),this.scopeHandles.delete(t),this.input.setScopes(this._scopes),this._activeScope===t){const s=this.findScopeAbove(t.container.parentElement)??this._scopes.find(n=>!n.disabled)??null;this.input.setActiveScope(s)}this.rebuildStylesheet()}}setScopeCursor(t,e){t.cursorMode=e,t===this._activeScope&&(this.state.cursorMode=e)}disableScope(t){if(!t.disabled&&(t.disabled=!0,this._activeScope===t)){const e=this.findScopeAbove(t.container.parentElement)??this._scopes.find(s=>!s.disabled)??null;this.input.setActiveScope(e)}}enableScope(t){t.disabled=!1}findScopeAbove(t){let e=t;for(;e;){const s=this.scopeByContainer.get(e);if(s&&!s.disabled)return s;e=e.parentElement}return null}installPlugins(t){if(t.config.plugins)for(const e of t.config.plugins)this.installPlugin(t,e)}installPlugin(t,e){if(!t.plugins.some(s=>s.name===e.name)){e.isEnabled??=!0,this._installingScope=t;try{e.install?.(this)}catch{this._installingScope=null;return}this._installingScope=null,t.plugins.push(e),t.plugins.sort((s,n)=>(s.priority??0)-(n.priority??0)),(t!==this._activeScope||t.disabled)&&e.element&&(e.element.style.display="none")}}removePluginFromScope(t,e){const s=t.plugins.findIndex(r=>r.name===e);if(s===-1)return;const n=t.plugins[s];t.plugins.splice(s,1);const o=()=>{try{n.onDisable?.(this),n.destroy?.(this)}catch{}n.element?.remove()},h=n.onBeforeDisable?.(this);h&&typeof h.then=="function"?Promise.resolve(h).then(o).catch(r=>{o()}):o()}handleActiveScopeChange(t){const e=this._activeScope;if(e!==t){if(e)for(const s of e.plugins)s.isEnabled!==!1&&this.scopeDeactivatePlugin(s);if(this._activeScope=t,t){this.state.cursorMode=t.cursorMode,this.state.scope={name:t.name,container:t.container};for(const s of t.plugins)s.isEnabled!==!1&&this.scopeActivatePlugin(s)}else this.state.scope=null}}deactivatePlugin(t){if(t.isEnabled===!1)return;t.isEnabled=!1;const e=()=>{t.element&&(t.element.style.display="none"),t.onDisable?.(this)},s=t.onBeforeDisable?.(this);s&&typeof s.then=="function"?Promise.resolve(s).then(e).catch(n=>{e()}):e()}scopeDeactivatePlugin(t){const e=()=>{t.element&&(t.element.style.display="none"),t.onDisable?.(this)},s=t.onBeforeDisable?.(this);s&&typeof s.then=="function"?Promise.resolve(s).then(e).catch(n=>{e()}):e()}scopeActivatePlugin(t){t.element&&(t.element.style.display=""),t.onEnable?.(this)}rebuildStylesheet(){const t=[];for(const e of this._scopes)t.push(...e.buildRules());U(this.styleOwner,t)}runPluginSafe(t,e){if(t.isEnabled!==!1)try{t.update?.(this,e)}catch{t.isEnabled=!1,this.crashedPlugins.push(t)}}cleanupCrashedPlugins(){if(this.crashedPlugins.length!==0){for(const t of this.crashedPlugins){for(const e of this._scopes){const s=e.plugins.indexOf(t);if(s!==-1){e.plugins.splice(s,1);break}}try{t.onDisable?.(this),t.destroy?.(this)}catch{}t.element?.remove()}this.crashedPlugins=[]}}resolveStageVisibility(){return this.state.cursorMode==="native"?!1:this.state.cursorMode==="custom"||this.state.cursorMode==="both"?this.input.isEnabled&&this.state.hasReceivedInput:this.input.isEnabled&&!this.state.isNative&&this.state.hasReceivedInput}resolveCursorState(){return!this.input.isEnabled||this.state.cursorMode==="native"||this.state.cursorMode==="both"?"auto":this.state.cursorMode==="custom"?"none":this.state.isNative||!this.state.hasReceivedInput?"auto":"none"}resetMotion(){this.state.velocity={x:0,y:0},this.state.displacement={x:0,y:0}}update(t){const e=t-this.lastTime,s=Math.min(e/1e3,.1);this.lastTime=t;const n=this.input.getCurrentTarget();n&&!n.isConnected?this.input.clearHover():n&&this.input.parseDOMInteraction(n),this.input.isEnabled&&this.state.hasReceivedInput&&(this.state.target.x=this.state.pointer.x,this.state.target.y=this.state.pointer.y);const o=this._activeScope;if(o){o.stage.setVisibility(this.resolveStageVisibility()),this.input.isEnabled&&o.stage.setNativeCursor(this.resolveCursorState());for(let h=0;h<o.plugins.length;h++)this.runPluginSafe(o.plugins[h],e)}if(this.cleanupCrashedPlugins(),this.input.isEnabled){const h=this.state.reducedMotion?1e3:1/this.options.smoothness*2,r=this.state.smooth.x,g=this.state.smooth.y;this.state.smooth.x=O(this.state.smooth.x,this.state.target.x,h,s),this.state.smooth.y=O(this.state.smooth.y,this.state.target.y,h,s),this.state.displacement.x=this.state.target.x-this.state.smooth.x,this.state.displacement.y=this.state.target.y-this.state.smooth.y,s>0?(this.state.velocity.x=(this.state.smooth.x-r)/s,this.state.velocity.y=(this.state.smooth.y-g)/s):(this.state.velocity.x=0,this.state.velocity.y=0);const{x:c,y:a}=this.state.velocity;(Math.abs(c)>.1||Math.abs(a)>.1)&&(this.state.angle=Math.atan2(a,c)*(180/Math.PI))}}tick=t=>{this.update(t),this._running&&(this.rafId=requestAnimationFrame(this.tick))};bindVisibilityHandling(){document.addEventListener("visibilitychange",()=>{this._running&&(document.hidden?cancelAnimationFrame(this.rafId):(this.lastTime=performance.now(),this.rafId=requestAnimationFrame(this.tick)))},{signal:this.visibilityAbortController.signal})}startLoop(){this._running||(this._running=!0,!document.hidden&&(this.lastTime=performance.now(),this.rafId=requestAnimationFrame(this.tick)))}get hoverSelectors(){const t=this._activeScope??this._scopes[0];return t?t.hoverSelectors:new Set}get plugins(){const t=this._activeScope??this._scopes[0];return t?t.plugins:[]}registerHoverTarget(t){const e=this._installingScope??this._activeScope??this._scopes[0];if(e)for(const s of t.split(",")){const n=s.trim();n&&e.hoverSelectors.add(n)}}}u.DEFAULT_CURSOR_POLICY=p,u.DEFAULT_HOVER_SELECTORS=_,u.Supermouse=q,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})}));
|