@wcstack/pointer-lock 1.19.1 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -8,14 +8,14 @@
8
8
  `@wcstack/state` と組み合わせると、`<wcs-pointer-lock>` はパス契約で直接バインドできます:
9
9
 
10
10
  - **入力サーフェス**: `target`
11
- - **出力 state サーフェス**: `active`、`error`
11
+ - **出力 state サーフェス**: `active`、`error`、`errorInfo`
12
12
  - **コマンド**: `requestPointerLock`、`exitPointerLock`
13
13
 
14
14
  `@wcstack/pointer-lock` は [CSBC](https://github.com/csbc-dev/arch/blob/main/README.md)(Core / Shell / Binding Contract)アーキテクチャに従います:
15
15
 
16
16
  - **Core**(`PointerLockCore`)が `Element.requestPointerLock()` / `document.exitPointerLock()` / `document.pointerLockElement` をラップし、`document`単位で発火する `pointerlockchange` イベントを自身が解決した target と自己判定でフィルタする
17
17
  - **Shell**(`<wcs-pointer-lock target="...">`)がDOMから「どの要素を操作するか」を解決し、display とライフサイクルを管理
18
- - **Binding Contract**(`static wcBindable`)が観測可能な `active` プロパティと `requestPointerLock`/`exitPointerLock` コマンドを宣言
18
+ - **Binding Contract**(`static wcBindable`)が観測可能な `active` / `error` / `errorInfo` プロパティと `requestPointerLock`/`exitPointerLock` コマンドを宣言
19
19
 
20
20
  ## 用途が限定的なノード — 使う前に必ず読んでください
21
21
 
@@ -81,11 +81,26 @@ npm install @wcstack/pointer-lock
81
81
 
82
82
  ## 観測可能プロパティ(出力)
83
83
 
84
- | プロパティ | イベント | 説明 |
85
- | ---------- | ---------------------------- | ------------ |
86
- | `active` | `wcs-pointer-lock:change` | `document.pointerLockElement` がこのインスタンスの解決済み target と一致していれば `true`、それ以外は `false`。 |
84
+ | プロパティ | イベント | 説明 |
85
+ | ----------- | -------------------------------------- | ------------ |
86
+ | `active` | `wcs-pointer-lock:change` | `document.pointerLockElement` がこのインスタンスの解決済み target と一致していれば `true`、それ以外は `false`。 |
87
+ | `error` | `wcs-pointer-lock:error` | 直近の失敗、または `null`。次のいずれか: rejectされたPromise(gesture外呼び出しなら`NotAllowedError`等)、プラットフォームAPI非対応なら`{ message: "Pointer Lock API is not supported." }`、`target`が要素へ未解決なら`{ message: "Pointer Lock target could not be resolved." }`。直近の呼び出しが成功済み・まだ何も失敗していない場合は`null`。 |
88
+ | `errorInfo` | `wcs-pointer-lock:error-info-changed` | `error` から導出される追加のシリアライズ可能な失敗タクソノミ `{ code, phase, recoverable, message }`、または `null`。下記参照。 |
87
89
 
88
- `error`(後述コマンド参照)は単純な getter として公開され、`wcBindable` property ではありません コマンド呼び出しの副作用としてのみ変化します(`@wcstack/fullscreen` と同型)。直近の失敗は次のいずれか: rejectされたPromise(gesture外呼び出しなら`NotAllowedError`等)、プラットフォームAPI非対応なら`{ message: "Pointer Lock API is not supported." }`、`target`が要素へ未解決なら`{ message: "Pointer Lock target could not be resolved." }`。直近の呼び出しが成功済み・まだ何も失敗していない場合は`null`。
90
+ `error` `errorInfo` **どちらも観測可能な event-backed `wcBindable` property** です。(`error` はかつて独自イベントを持たない命令的 getter でしたが、現在はそうではありません。)wc-bindable バインディングコアが request/exit の失敗をリアクティブに配信するようになったため、コマンドが settle するたびに `element.error` をポーリングするのではなく `data-wcs` / `bind()` でバインドできます。`error` **値の形状は不変** で、`errorInfo` は追加のシリアライズ可能な分類です。
91
+
92
+ ### `errorInfo` タクソノミ
93
+
94
+ `errorInfo` は各失敗を安定した `{ code, phase, recoverable, message }` に写します:
95
+
96
+ | `code` | `phase` | `recoverable` | 条件 |
97
+ | -------------------- | --------- | ------------- | ----- |
98
+ | `capability-missing` | `probe` | `false` | Pointer Lock API 非対応(標準名・レガシー名のどちらも存在しない) |
99
+ | `invalid-argument` | `start` | `false` | `target` が要素へ未解決 |
100
+ | `not-allowed` | `execute` | `true` | `NotAllowedError` / `TypeError` — user gesture 外での呼び出し。実際の gesture 内で再試行すれば成功しうる |
101
+ | `pointer-lock-error` | `execute` | `false` | その他の caught 例外 |
102
+
103
+ 安定した `code` 値は `WCS_POINTER_LOCK_ERROR_CODE` として export されます。共有の `WcsIoErrorInfo` / `WcsIoErrorPhase` 型も本パッケージから再 export されます。
89
104
 
90
105
  ## コマンド
91
106
 
@@ -117,8 +132,10 @@ wcs-pointer-lock:state(active) ~ .crosshair { display: none; } /* デフォル
117
132
  ```
118
133
 
119
134
  属性やクラスと異なり `:state()` は要素の外部から書き込めないため、この出力ステートが
120
- 入力と混同される心配がありません。`error` はあえて反映していません 上記「観測可能プロパティ」参照。
121
- 単純な getter として公開されるのみで、`wcBindable` property ではありません。
135
+ 入力と混同される心配がありません。`error` / `errorInfo` は `:state()` には**反映していません**。
136
+ これらは観測可能な `wcBindable` property ですが(上記「観測可能プロパティ」参照)、失敗オブジェクトは
137
+ 真偽値の CSS ステートではないため、`:state()` に配線されるのは `active` のみです。
138
+ `error` / `errorInfo` は `data-wcs` / `bind()` で観測してください。
122
139
 
123
140
  **対応ブラウザ**(新構文 `:state(x)`): Chrome/Edge 125+、Safari 17.4+、Firefox 126+。
124
141
  非対応の環境ではステートが一切 set されないだけです — `:state()` セレクタがマッチしなく
package/README.md CHANGED
@@ -8,14 +8,14 @@ It is an **async primitive node** that turns the Pointer Lock API's lock state i
8
8
  With `@wcstack/state`, `<wcs-pointer-lock>` can be bound directly through path contracts:
9
9
 
10
10
  - **input surface**: `target`
11
- - **output state surface**: `active`, `error`
11
+ - **output state surface**: `active`, `error`, `errorInfo`
12
12
  - **commands**: `requestPointerLock`, `exitPointerLock`
13
13
 
14
14
  `@wcstack/pointer-lock` follows the [CSBC](https://github.com/csbc-dev/arch/blob/main/README.md) (Core / Shell / Binding Contract) architecture:
15
15
 
16
16
  - **Core** (`PointerLockCore`) wraps `Element.requestPointerLock()` / `document.exitPointerLock()` / `document.pointerLockElement`, self-filtering the `document`-scoped `pointerlockchange` event against its own resolved target
17
17
  - **Shell** (`<wcs-pointer-lock target="...">`) resolves *which* element to operate on from the DOM, manages display and lifecycle
18
- - **Binding Contract** (`static wcBindable`) declares the observable `active` property and the `requestPointerLock`/`exitPointerLock` commands
18
+ - **Binding Contract** (`static wcBindable`) declares the observable `active` / `error` / `errorInfo` properties and the `requestPointerLock`/`exitPointerLock` commands
19
19
 
20
20
  ## A narrow-purpose node — read this before reaching for it
21
21
 
@@ -81,11 +81,26 @@ Every bound state path must be declared up front — `locked: false` here; bindi
81
81
 
82
82
  ## Observable Properties (outputs)
83
83
 
84
- | Property | Event | Description |
85
- | ---------- | ---------------------------- | ------------ |
86
- | `active` | `wcs-pointer-lock:change` | `true` when `document.pointerLockElement` is this instance's resolved target, `false` otherwise. |
84
+ | Property | Event | Description |
85
+ | ----------- | -------------------------------------- | ------------ |
86
+ | `active` | `wcs-pointer-lock:change` | `true` when `document.pointerLockElement` is this instance's resolved target, `false` otherwise. |
87
+ | `error` | `wcs-pointer-lock:error` | The most recent failure, or `null`. One of: a rejected promise (e.g. `NotAllowedError` for a gesture-less call), `{ message: "Pointer Lock API is not supported." }` when the platform API is missing, `{ message: "Pointer Lock target could not be resolved." }` when `target` did not resolve to an element, or `null` if the last attempt succeeded / nothing has failed yet. |
88
+ | `errorInfo` | `wcs-pointer-lock:error-info-changed` | Additive serializable failure taxonomy derived from `error` — `{ code, phase, recoverable, message }` — or `null`. See below. |
87
89
 
88
- `error` (see Commands below) is exposed as a plain getter, not as a `wcBindable` property it only changes as a side effect of a command call, mirroring `@wcstack/fullscreen`. The most recent failure is one of: a rejected promise (e.g. `NotAllowedError` for a gesture-less call), `{ message: "Pointer Lock API is not supported." }` when the platform API is missing, `{ message: "Pointer Lock target could not be resolved." }` when `target` did not resolve to an element, or `null` if the last attempt succeeded / nothing has failed yet.
90
+ `error` and `errorInfo` are **both observable, event-backed `wcBindable` properties**. (`error` was historically an imperative getter with no event of its own that is no longer the case.) A wc-bindable binding core now delivers a request/exit failure reactively, so you can bind it with `data-wcs` / `bind()` rather than polling `element.error` after each command settles. The `error` **value shape is unchanged**; `errorInfo` is the additive serializable classification.
91
+
92
+ ### `errorInfo` taxonomy
93
+
94
+ `errorInfo` maps each failure to a stable `{ code, phase, recoverable, message }`:
95
+
96
+ | `code` | `phase` | `recoverable` | when |
97
+ | -------------------- | --------- | ------------- | ----- |
98
+ | `capability-missing` | `probe` | `false` | Pointer Lock API is unsupported (neither standard nor legacy name present) |
99
+ | `invalid-argument` | `start` | `false` | `target` did not resolve to an element |
100
+ | `not-allowed` | `execute` | `true` | `NotAllowedError` / `TypeError` — called outside a user gesture; retrying inside a real gesture can succeed |
101
+ | `pointer-lock-error` | `execute` | `false` | any other caught exception |
102
+
103
+ The stable `code` values are exported as `WCS_POINTER_LOCK_ERROR_CODE`; the shared `WcsIoErrorInfo` / `WcsIoErrorPhase` types are re-exported from this package.
89
104
 
90
105
  ## Commands
91
106
 
@@ -118,8 +133,10 @@ wcs-pointer-lock:state(active) ~ .crosshair { display: none; } /* default */
118
133
 
119
134
  Unlike attributes or classes, `:state()` cannot be written from outside the
120
135
  element, so there is no risk of confusing this output state with an input.
121
- `error` is intentionally not reflected see "Observable Properties" above;
122
- it is exposed only as a plain getter, not a `wcBindable` property.
136
+ `error` / `errorInfo` are **not** reflected onto `:state()`: they are observable
137
+ `wcBindable` properties (see "Observable Properties" above), but a failure object
138
+ is not a boolean CSS state, so only `active` is wired to `:state()`. Observe
139
+ `error` / `errorInfo` via `data-wcs` / `bind()` instead.
123
140
 
124
141
  **Browser support** (`:state(x)` syntax): Chrome/Edge 125+, Safari 17.4+,
125
142
  Firefox 126+. In older browsers the states are simply never set — `:state()`
package/dist/index.d.ts CHANGED
@@ -1,3 +1,14 @@
1
+ /** operation error の phase(taxonomy)。 */
2
+ type WcsIoErrorPhase = "probe" | "start" | "execute" | "decode" | "commit" | "dispose";
3
+ /** serializable な error info(non-cloneable な cause とは分離。DevTools / remote へは info のみ)。 */
4
+ interface WcsIoErrorInfo {
5
+ readonly code: string;
6
+ readonly phase: WcsIoErrorPhase;
7
+ readonly recoverable: boolean;
8
+ readonly capabilityId?: string;
9
+ readonly message: string;
10
+ }
11
+
1
12
  interface IWcBindableProperty {
2
13
  readonly name: string;
3
14
  readonly event: string;
@@ -13,7 +24,8 @@ interface IWcBindableCommand {
13
24
  }
14
25
  interface IWcBindable {
15
26
  readonly protocol: "wc-bindable";
16
- readonly version: 1;
27
+ /** Integer protocol version. All versions >= 1 are core-compatible. */
28
+ readonly version: number;
17
29
  readonly properties: readonly IWcBindableProperty[];
18
30
  readonly inputs?: readonly IWcBindableInput[];
19
31
  readonly commands?: readonly IWcBindableCommand[];
@@ -34,26 +46,27 @@ interface IWritableConfig {
34
46
 
35
47
  /**
36
48
  * Value types for PointerLockCore (headless) — the Core's readable value
37
- * surface. Note that only `active` is *observable* (declared in
38
- * `wcBindable.properties` with a change event); `error` is an
39
- * imperative-read-only getter with no event of its own — a wc-bindable
40
- * binding core will never deliver it, so read it after a command settles
41
- * (docs/pointer-lock-tag-design.md §2, docs/fullscreen-tag-design.md §8).
49
+ * surface. `active`, `error`, and `errorInfo` are all *observable* (declared in
50
+ * `wcBindable.properties` with change events: `wcs-pointer-lock:change` /
51
+ * `:error` / `:error-info-changed`), so a wc-bindable binding core delivers a
52
+ * request/exit failure. `errorInfo` is the additive serializable failure
53
+ * taxonomy derived from `error` (docs/pointer-lock-tag-design.md §2, README).
42
54
  *
43
55
  * @example
44
56
  * ```typescript
45
57
  * const core = new PointerLockCore();
46
- * // bind() only ever delivers "active" — see the note above about "error".
47
58
  * bind(core, (name: keyof WcsPointerLockCoreValues, value) => { ... });
48
59
  * ```
49
60
  */
50
61
  interface WcsPointerLockCoreValues {
51
62
  active: boolean;
52
63
  error: any;
64
+ /** Additive failure taxonomy derived from `error` (stable code / phase / recoverable). */
65
+ errorInfo: WcsIoErrorInfo | null;
53
66
  }
54
67
  /**
55
68
  * Value types for the Shell (`<wcs-pointer-lock>`) — identical value surface
56
- * to the Core (same caveat: only `active` is observable). The Shell
69
+ * to the Core (`active` / `error` / `errorInfo` all observable). The Shell
57
70
  * additionally accepts a `target` attribute
58
71
  * (see docs/pointer-lock-tag-design.md / docs/fullscreen-tag-design.md §1).
59
72
  */
@@ -97,6 +110,7 @@ declare class PointerLockCore extends EventTarget {
97
110
  private _target;
98
111
  private _active;
99
112
  private _error;
113
+ private _errorInfo;
100
114
  private _resolvedTarget;
101
115
  private _subscribed;
102
116
  private _gen;
@@ -105,6 +119,13 @@ declare class PointerLockCore extends EventTarget {
105
119
  get ready(): Promise<void>;
106
120
  get active(): boolean;
107
121
  get error(): any;
122
+ /**
123
+ * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /
124
+ * `recoverable`), or null. Additive wc-bindable property (event
125
+ * `wcs-pointer-lock:error-info-changed`), derived from `error`; the existing
126
+ * `error` value shape is unchanged.
127
+ */
128
+ get errorInfo(): WcsIoErrorInfo | null;
108
129
  observe(target: Element | null): Promise<void>;
109
130
  dispose(): void;
110
131
  /**
@@ -138,6 +159,7 @@ declare class PointerLockCore extends EventTarget {
138
159
  private _applyActive;
139
160
  private _setActive;
140
161
  private _setError;
162
+ private _commitErrorInfo;
141
163
  }
142
164
 
143
165
  /**
@@ -182,6 +204,7 @@ declare class WcsPointerLock extends HTMLElement {
182
204
  set target(value: string);
183
205
  get active(): boolean;
184
206
  get error(): any;
207
+ get errorInfo(): WcsIoErrorInfo | null;
185
208
  /**
186
209
  * Resolve `target` and request pointer lock on it. Requires a user-gesture
187
210
  * context. never-throw: an unresolvable target or an unsupported/rejected
@@ -202,5 +225,31 @@ declare class WcsPointerLock extends HTMLElement {
202
225
  private _safeQuery;
203
226
  }
204
227
 
205
- export { PointerLockCore, WcsPointerLock, bootstrapPointerLock, getConfig };
206
- export type { IWritableConfig, IWritableTagNames, WcsPointerLockCoreValues, WcsPointerLockValues };
228
+ /**
229
+ * pointerLockCapabilities.ts
230
+ *
231
+ * Pointer Lock node 固有の error code(taxonomy)と derivation。汎用の error info 型は
232
+ * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から
233
+ * import する。pointer-lock は referenced element を操作するモニタ的ノードで競合 operation
234
+ * を持たないため lane は無く、error taxonomy(errorInfo)のみを採用する。
235
+ *
236
+ * `_setError` は合成 `{ message }`(target 未解決 / API 非対応)と caught 例外
237
+ * (`NotAllowedError` / `TypeError` = user gesture 外の requestPointerLock 拒否)を混在
238
+ * 受理する。呼出側が明示 `kind` を渡して合成側を曖昧さ無く分類し、caught は `.name` で
239
+ * 分類する(fullscreen と同じ discriminator 方式)。
240
+ */
241
+
242
+ /** 安定した pointer-lock error code(taxonomy)。値は公開キーとして固定。 */
243
+ declare const WCS_POINTER_LOCK_ERROR_CODE: {
244
+ /** Pointer Lock API 非対応。 */
245
+ readonly CapabilityMissing: "capability-missing";
246
+ /** target selector が要素に解決しない等の入力不備。 */
247
+ readonly InvalidArgument: "invalid-argument";
248
+ /** `NotAllowedError` / `TypeError` — user gesture 外での要求拒否。 */
249
+ readonly NotAllowed: "not-allowed";
250
+ /** その他の caught 例外。 */
251
+ readonly PointerLockError: "pointer-lock-error";
252
+ };
253
+
254
+ export { PointerLockCore, WCS_POINTER_LOCK_ERROR_CODE, WcsPointerLock, bootstrapPointerLock, getConfig };
255
+ export type { IWritableConfig, IWritableTagNames, WcsIoErrorInfo, WcsIoErrorPhase, WcsPointerLockCoreValues, WcsPointerLockValues };
package/dist/index.esm.js CHANGED
@@ -36,6 +36,56 @@ function setConfig(partialConfig) {
36
36
  frozenConfig = null;
37
37
  }
38
38
 
39
+ /**
40
+ * pointerLockCapabilities.ts
41
+ *
42
+ * Pointer Lock node 固有の error code(taxonomy)と derivation。汎用の error info 型は
43
+ * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から
44
+ * import する。pointer-lock は referenced element を操作するモニタ的ノードで競合 operation
45
+ * を持たないため lane は無く、error taxonomy(errorInfo)のみを採用する。
46
+ *
47
+ * `_setError` は合成 `{ message }`(target 未解決 / API 非対応)と caught 例外
48
+ * (`NotAllowedError` / `TypeError` = user gesture 外の requestPointerLock 拒否)を混在
49
+ * 受理する。呼出側が明示 `kind` を渡して合成側を曖昧さ無く分類し、caught は `.name` で
50
+ * 分類する(fullscreen と同じ discriminator 方式)。
51
+ */
52
+ /** 安定した pointer-lock error code(taxonomy)。値は公開キーとして固定。 */
53
+ const WCS_POINTER_LOCK_ERROR_CODE = {
54
+ /** Pointer Lock API 非対応。 */
55
+ CapabilityMissing: "capability-missing",
56
+ /** target selector が要素に解決しない等の入力不備。 */
57
+ InvalidArgument: "invalid-argument",
58
+ /** `NotAllowedError` / `TypeError` — user gesture 外での要求拒否。 */
59
+ NotAllowed: "not-allowed",
60
+ /** その他の caught 例外。 */
61
+ PointerLockError: "pointer-lock-error",
62
+ };
63
+ function messageOf(error) {
64
+ return typeof error?.message === "string"
65
+ ? error.message
66
+ : String(error);
67
+ }
68
+ /**
69
+ * pointer-lock の失敗を serializable な error taxonomy に写す。`kind` は合成エラーの
70
+ * 呼出側が渡す明示 discriminator(`capability-missing` / `invalid-argument`)。未指定は
71
+ * caught 例外を意味し、`.name` で分類する。`NotAllowedError` / `TypeError` は user
72
+ * gesture 内で再試行すれば成功しうるため recoverable=true。
73
+ */
74
+ function derivePointerLockErrorInfo(error, kind) {
75
+ const message = messageOf(error);
76
+ if (kind === "capability-missing") {
77
+ return { code: WCS_POINTER_LOCK_ERROR_CODE.CapabilityMissing, phase: "probe", recoverable: false, message };
78
+ }
79
+ if (kind === "invalid-argument") {
80
+ return { code: WCS_POINTER_LOCK_ERROR_CODE.InvalidArgument, phase: "start", recoverable: false, message };
81
+ }
82
+ const name = error?.name;
83
+ if (name === "NotAllowedError" || name === "TypeError") {
84
+ return { code: WCS_POINTER_LOCK_ERROR_CODE.NotAllowed, phase: "execute", recoverable: true, message };
85
+ }
86
+ return { code: WCS_POINTER_LOCK_ERROR_CODE.PointerLockError, phase: "execute", recoverable: false, message };
87
+ }
88
+
39
89
  /**
40
90
  * Headless Pointer Lock primitive. A thin, framework-agnostic wrapper around
41
91
  * the Pointer Lock API (`Element.requestPointerLock()` /
@@ -74,6 +124,14 @@ class PointerLockCore extends EventTarget {
74
124
  // FullscreenCore's `{ active }`-shaped detail + getter.
75
125
  properties: [
76
126
  { name: "active", event: "wcs-pointer-lock:change" },
127
+ // `error` / `errorInfo` are observable failure outputs. Historically `error`
128
+ // was an imperative getter with no event; both are now bindable (event-backed)
129
+ // so `data-wcs` / bind() can observe a request/exit failure. `errorInfo` is the
130
+ // additive serializable taxonomy (stable code / phase / recoverable) derived
131
+ // from `error`; the `error` value shape is unchanged. No lane — pointer-lock
132
+ // drives a referenced element, not a competing operation.
133
+ { name: "error", event: "wcs-pointer-lock:error" },
134
+ { name: "errorInfo", event: "wcs-pointer-lock:error-info-changed" },
77
135
  ],
78
136
  commands: [
79
137
  { name: "requestPointerLock", async: true },
@@ -85,6 +143,7 @@ class PointerLockCore extends EventTarget {
85
143
  _target;
86
144
  _active = false;
87
145
  _error = null;
146
+ _errorInfo = null;
88
147
  // The element this instance last resolved requestPointerLock()/observe()
89
148
  // against, kept so the document-scoped `pointerlockchange` handler can
90
149
  // self-filter under multiple concurrent instances (docs/fullscreen-tag-design.md
@@ -115,6 +174,15 @@ class PointerLockCore extends EventTarget {
115
174
  get error() {
116
175
  return this._error;
117
176
  }
177
+ /**
178
+ * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /
179
+ * `recoverable`), or null. Additive wc-bindable property (event
180
+ * `wcs-pointer-lock:error-info-changed`), derived from `error`; the existing
181
+ * `error` value shape is unchanged.
182
+ */
183
+ get errorInfo() {
184
+ return this._errorInfo;
185
+ }
118
186
  // Lifecycle (§3.5). Idempotent: a second observe() while already subscribed
119
187
  // updates the tracked resolved target without re-subscribing to `document`.
120
188
  observe(target) {
@@ -149,7 +217,7 @@ class PointerLockCore extends EventTarget {
149
217
  const gen = ++this._gen;
150
218
  this._resolvedTarget = element;
151
219
  if (!element) {
152
- this._setError({ message: "Pointer Lock target could not be resolved." });
220
+ this._setError({ message: "Pointer Lock target could not be resolved." }, "invalid-argument");
153
221
  return;
154
222
  }
155
223
  const fn = this._requestPointerLockFn(element);
@@ -158,7 +226,7 @@ class PointerLockCore extends EventTarget {
158
226
  // cannot have run yet, so no staleness check is needed here (matches
159
227
  // the reference `requestFullscreen()` implementation,
160
228
  // docs/fullscreen-tag-design.md §6).
161
- this._setError({ message: "Pointer Lock API is not supported." });
229
+ this._setError({ message: "Pointer Lock API is not supported." }, "capability-missing");
162
230
  return;
163
231
  }
164
232
  try {
@@ -269,8 +337,33 @@ class PointerLockCore extends EventTarget {
269
337
  bubbles: true,
270
338
  }));
271
339
  }
272
- _setError(e) {
273
- this._error = e;
340
+ // `kind` is an explicit taxonomy discriminator passed only from the synthetic
341
+ // error sites (unsupported / unresolved target); caught exceptions pass no kind
342
+ // and are classified by their `.name`. Both `error` and the additive `errorInfo`
343
+ // are now event-backed so a request/exit failure is observable via bind().
344
+ _setError(error, kind) {
345
+ // Same-value guard on reference: each failure builds a fresh object and the
346
+ // clear path passes the literal null, so this only suppresses redundant
347
+ // null→null (a successful request/exit clearing an already-null error).
348
+ if (this._error === error)
349
+ return;
350
+ this._error = error;
351
+ // Keep the additive errorInfo taxonomy in sync; fire it before the `error`
352
+ // event so an observer of both sees the classification first (io-node family).
353
+ this._commitErrorInfo(error === null ? null : derivePointerLockErrorInfo(error, kind));
354
+ this._target.dispatchEvent(new CustomEvent("wcs-pointer-lock:error", {
355
+ detail: error,
356
+ bubbles: true,
357
+ }));
358
+ }
359
+ // Called only from _setError (already reference-guarded), so errorInfo
360
+ // transitions exactly when error does — no separate guard needed here.
361
+ _commitErrorInfo(info) {
362
+ this._errorInfo = info;
363
+ this._target.dispatchEvent(new CustomEvent("wcs-pointer-lock:error-info-changed", {
364
+ detail: info,
365
+ bubbles: true,
366
+ }));
274
367
  }
275
368
  }
276
369
 
@@ -388,6 +481,9 @@ class WcsPointerLock extends HTMLElement {
388
481
  get error() {
389
482
  return this._core.error;
390
483
  }
484
+ get errorInfo() {
485
+ return this._core.errorInfo;
486
+ }
391
487
  // --- Commands ---
392
488
  /**
393
489
  * Resolve `target` and request pointer lock on it. Requires a user-gesture
@@ -465,5 +561,5 @@ function bootstrapPointerLock(userConfig) {
465
561
  registerComponents();
466
562
  }
467
563
 
468
- export { PointerLockCore, WcsPointerLock, bootstrapPointerLock, getConfig };
564
+ export { PointerLockCore, WCS_POINTER_LOCK_ERROR_CODE, WcsPointerLock, bootstrapPointerLock, getConfig };
469
565
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/PointerLockCore.ts","../src/components/PointerLock.ts","../src/registerComponents.ts","../src/bootstrapPointerLock.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n pointerLock: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n pointerLock: \"wcs-pointer-lock\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\n/**\n * Headless Pointer Lock primitive. A thin, framework-agnostic wrapper around\n * the Pointer Lock API (`Element.requestPointerLock()` /\n * `document.exitPointerLock()` / `document.pointerLockElement` / the\n * `document`-scoped `pointerlockchange` event) exposed through the\n * wc-bindable protocol.\n *\n * This Core follows the same basic pattern as `FullscreenCore`\n * (docs/fullscreen-tag-design.md, referenced by docs/pointer-lock-tag-design.md\n * §1): target resolution happens in the Shell, `pointerlockchange` is\n * subscribed on `document` (not on the target element) and each instance\n * self-filters by comparing `document.pointerLockElement` against its own\n * resolved target, API resolution is call-time (never cached) and probes the\n * standard name before the legacy (`webkit`-prefixed) name, and a single\n * Core-level `_gen` generation guard protects the asynchronous\n * `requestPointerLock()` call from stale resolution after dispose().\n *\n * Key difference from Fullscreen (docs/pointer-lock-tag-design.md §2):\n * `exitPointerLock()` is a *synchronous* platform API (it returns `void`, not\n * a `Promise`), so the Core's `exitPointerLock()` command is synchronous too\n * and carries no `_gen` guard of its own — it is wrapped in `try/catch` only\n * as a defensive measure (never-throw), not because it can go stale.\n *\n * Scope note (docs/pointer-lock-tag-design.md §3): `movementX`/`movementY`\n * are intentionally NOT exposed by this Core (v1 scope). They are\n * high-frequency `mousemove` data unsuited to the same-value-guarded\n * declarative `properties` surface; see the design doc for the rationale and\n * the planned `debounce`/`throttle`-based opt-in for a future version.\n */\nexport class PointerLockCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n // `active`'s CustomEvent detail is the bare boolean value itself — no\n // getter needed (docs/pointer-lock-tag-design.md §2). This differs from\n // FullscreenCore's `{ active }`-shaped detail + getter.\n properties: [\n { name: \"active\", event: \"wcs-pointer-lock:change\" },\n ],\n commands: [\n { name: \"requestPointerLock\", async: true },\n // Synchronous platform API (document.exitPointerLock() returns void) —\n // no `async` flag (docs/pointer-lock-tag-design.md §2).\n { name: \"exitPointerLock\" },\n ],\n };\n\n private _target: EventTarget;\n private _active = false;\n private _error: any = null;\n\n // The element this instance last resolved requestPointerLock()/observe()\n // against, kept so the document-scoped `pointerlockchange` handler can\n // self-filter under multiple concurrent instances (docs/fullscreen-tag-design.md\n // §2.1, inherited verbatim by pointer-lock per docs/pointer-lock-tag-design.md §1).\n private _resolvedTarget: Element | null = null;\n\n // True once observe() has attached the live `document` listener. Guards\n // observe() so a redundant call does not re-subscribe; dispose() resets it\n // so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // Core-level generation guard (§3.4 of the guidelines / §6 of\n // fullscreen-tag-design.md): only requestPointerLock() is asynchronous and\n // needs it. exitPointerLock() is synchronous and has no stale-resolution\n // race to guard against.\n private _gen = 0;\n\n // SSR (§3.8): no asynchronous probe to await — observe() completes\n // synchronously, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get active(): boolean {\n return this._active;\n }\n\n get error(): any {\n return this._error;\n }\n\n // Lifecycle (§3.5). Idempotent: a second observe() while already subscribed\n // updates the tracked resolved target without re-subscribing to `document`.\n observe(target: Element | null): Promise<void> {\n this._resolvedTarget = target;\n if (!this._subscribed) {\n this._subscribed = true;\n document.addEventListener(this._pointerLockChangeEventName(), this._onChange);\n }\n this._applyActive();\n return this._ready;\n }\n\n dispose(): void {\n this._gen++; // invalidate any in-flight requestPointerLock() resolution\n if (this._subscribed) {\n this._subscribed = false;\n document.removeEventListener(this._pointerLockChangeEventName(), this._onChange);\n }\n this._resolvedTarget = null;\n }\n\n /**\n * Request pointer lock on `element`. Never-throw: a missing API or a\n * rejected promise (e.g. called outside a user-gesture context —\n * `NotAllowedError`, docs/fullscreen-tag-design.md §3) is captured into\n * `error` rather than propagated. `element` may be `null` when the Shell's\n * `target` selector did not resolve (docs/pointer-lock-tag-design.md §1\n * defers error representation to FullscreenCore verbatim — this null-target\n * case mirrors `FullscreenCore.requestFullscreen(null)`,\n * docs/fullscreen-tag-design.md §6): distinct from \"API is not supported\"\n * below, so a typo'd selector doesn't masquerade as an unsupported platform.\n */\n async requestPointerLock(element: Element | null): Promise<void> {\n const gen = ++this._gen;\n this._resolvedTarget = element;\n if (!element) {\n this._setError({ message: \"Pointer Lock target could not be resolved.\" });\n return;\n }\n const fn = this._requestPointerLockFn(element);\n if (!fn) {\n // Resolved synchronously in the same tick as the call — dispose()\n // cannot have run yet, so no staleness check is needed here (matches\n // the reference `requestFullscreen()` implementation,\n // docs/fullscreen-tag-design.md §6).\n this._setError({ message: \"Pointer Lock API is not supported.\" });\n return;\n }\n try {\n // fn is already bound to `element` by _requestPointerLockFn().\n await fn();\n if (gen !== this._gen) return; // stale\n this._setError(null);\n this._applyActive();\n } catch (e: any) {\n if (gen !== this._gen) return; // stale\n this._setError(e);\n }\n }\n\n /**\n * Exit pointer lock. Synchronous platform API (docs/pointer-lock-tag-design.md\n * §2) — returns `void`, not a `Promise`. Silent no-op when nothing is\n * currently locked or the API is unsupported (mirrors\n * `FullscreenCore.exitFullscreen()`'s no-op contract,\n * docs/fullscreen-tag-design.md §7). Wrapped in try/catch defensively: even\n * though the platform API is synchronous and documented as not throwing in\n * this case, a synchronous throw from a non-conformant/fake implementation\n * must never escape (never-throw).\n */\n exitPointerLock(): void {\n try {\n if (this._pointerLockElement() === null) return; // already unlocked: silent no-op\n const fn = this._exitPointerLockFn();\n if (!fn) return; // unsupported: silent no-op (semantically already \"not locked\")\n fn();\n this._setError(null);\n this._applyActive();\n } catch (e: any) {\n this._setError(e);\n }\n }\n\n // --- API resolution (call-time, never cached — §3.7) ---\n\n // Resolved from `Element.prototype` rather than `el.requestPointerLock`\n // directly: when `target=\"self\"`, `el` is the `<wcs-pointer-lock>` Shell\n // itself, whose own class declares an instance method also named\n // `requestPointerLock()` (the wcBindable command). Reading the property off\n // the instance would pick up that Shell method instead of the native\n // platform API and recurse infinitely (Shell.requestPointerLock() ->\n // Core.requestPointerLock() -> resolves \"el.requestPointerLock\" -> the same\n // Shell method again). Going through `Element.prototype` sidesteps the name\n // collision — note this does NOT pick up an override on a subclass's own\n // prototype (e.g. `WcsPointerLock.prototype`); it deliberately jumps\n // straight to the platform-defined layer. Both the standard and legacy name\n // are resolved the same way, for symmetry — matching FullscreenCore's\n // `_elementFullscreenFn` (docs/fullscreen-tag-design.md §4) ONLY in that one\n // respect. Unlike that Core, this one does not check `el`'s own properties\n // first: there is no test-stub/per-element monkey-patch path to accommodate\n // here (mocks.ts installs the fakes directly on `Element.prototype`), so it\n // goes straight there for both names.\n private _requestPointerLockFn(el: Element): (() => Promise<void>) | undefined {\n const proto = Element.prototype as any;\n const standard = proto.requestPointerLock;\n if (typeof standard === \"function\") return standard.bind(el);\n const legacy = proto.webkitRequestPointerLock;\n return typeof legacy === \"function\" ? legacy.bind(el) : undefined;\n }\n\n private _exitPointerLockFn(): (() => void) | undefined {\n const d = document as any;\n return d.exitPointerLock?.bind(document) ?? d.webkitExitPointerLock?.bind(document);\n }\n\n private _pointerLockElement(): Element | null {\n const d = document as any;\n return d.pointerLockElement ?? d.webkitPointerLockElement ?? null;\n }\n\n // NOTE (test-environment caveat, not a production concern): happy-dom\n // always implements `document.onpointerlockchange` (as `null`) regardless\n // of which fake API surface a test installs, so `\"onpointerlockchange\" in\n // document` can never observably be `false` under this test runner and the\n // `webkitpointerlockchange` branch below cannot be driven through\n // `observe()` in a unit test. The branch is still correct and required for\n // real legacy WebKit builds that lack `onpointerlockchange` entirely — kept\n // as documented, deliberate, untestable-in-this-harness code per\n // docs/pointer-lock-tag-design.md.\n /* v8 ignore next 3 */\n private _pointerLockChangeEventName(): string {\n return \"onpointerlockchange\" in document ? \"pointerlockchange\" : \"webkitpointerlockchange\";\n }\n\n private _onChange = (): void => {\n this._applyActive();\n };\n\n // Self-filter (docs/fullscreen-tag-design.md §2.1): compares against this\n // instance's own resolved target, not merely \"is *something* locked\" — so\n // multiple concurrent instances each report the correct `active` value.\n private _applyActive(): void {\n const next = this._resolvedTarget !== null && this._pointerLockElement() === this._resolvedTarget;\n this._setActive(next);\n }\n\n // Same-value guard (MUST, §3.3 of the guidelines). detail itself is the\n // bare boolean value (no getter needed) per docs/pointer-lock-tag-design.md\n // §2 — unlike FullscreenCore's `{ active }`-shaped detail + getter.\n private _setActive(v: boolean): void {\n if (this._active === v) return;\n this._active = v;\n this._target.dispatchEvent(new CustomEvent(\"wcs-pointer-lock:change\", {\n detail: v,\n bubbles: true,\n }));\n }\n\n private _setError(e: any): void {\n this._error = e;\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { PointerLockCore } from \"../core/PointerLockCore.js\";\n\n/**\n * `<wcs-pointer-lock target=\"...\">` — declarative Pointer Lock API control.\n *\n * Like `<wcs-fullscreen>` (docs/fullscreen-tag-design.md §0), this Shell does\n * not lock itself — it operates on a *referenced* element via the `target`\n * attribute, using the same 3-mode resolution rule as `intersection`\n * (`_resolveTarget()`/`_safeQuery()`, copied verbatim per\n * docs/pointer-lock-tag-design.md §1 / docs/fullscreen-tag-design.md §1):\n *\n * | `target` | operates on | display |\n * |-----------------|-------------------------|-------------|\n * | omitted | first element child | `contents` |\n * | `\"#selector\"` | the matched element | `none` |\n * | `\"self\"` | the element itself | `block` |\n *\n * `requestPointerLock()` requires a user-gesture context (docs/fullscreen-tag-design.md\n * §3) — the primary activation path is the command-token protocol\n * (`command.requestPointerLock: $command.<token>` on `<wcs-pointer-lock>`,\n * emitted by a button's `onclick: $command.<token>`), not an\n * autoTrigger attribute (none is provided in v1,\n * docs/pointer-lock-tag-design.md §4).\n *\n * `movementX`/`movementY` are intentionally out of scope for v1\n * (docs/pointer-lock-tag-design.md §3) — do not add them without revisiting\n * the design doc.\n */\nexport class WcsPointerLock extends HTMLElement {\n // SSR (§4.4): the Core subscribes synchronously on connect, but the Shell\n // still exposes connectedCallbackPromise so the state binder can await it\n // uniformly across all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static observedAttributes = [\"target\"];\n\n static wcBindable: IWcBindable = {\n ...PointerLockCore.wcBindable,\n inputs: [{ name: \"target\", attribute: \"target\" }],\n // Core の commands をそのまま継承(単一情報源)。network/intersection と同型。\n commands: PointerLockCore.wcBindable.commands,\n };\n\n private _core: PointerLockCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new PointerLockCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-pointer-lock:change\": (d) => ({ active: d === true }),\n });\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (docs/custom-state-reflection-design.md §3.6): attachInternals\n // is absent in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n // --- Core delegated getters ---\n\n get active(): boolean {\n return this._core.active;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n // --- Commands ---\n\n /**\n * Resolve `target` and request pointer lock on it. Requires a user-gesture\n * context. never-throw: an unresolvable target or an unsupported/rejected\n * API call are both surfaced via `error`, never thrown (mirrors\n * `<wcs-fullscreen>`'s `requestFullscreen()`, docs/fullscreen-tag-design.md\n * §3/§6 — the Shell passes the (possibly `null`) resolved element straight\n * through and lets the Core set `error`, rather than silently no-op'ing\n * here).\n */\n async requestPointerLock(): Promise<void> {\n const { element } = this._resolveTarget();\n await this._core.requestPointerLock(element);\n }\n\n /** Exit pointer lock. Synchronous command — silent no-op if nothing is locked. */\n exitPointerLock(): void {\n this._core.exitPointerLock();\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this._applyDisplayAndObserve();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n\n attributeChangedCallback(name: string): void {\n if (name === \"target\" && this.isConnected) {\n this._applyDisplayAndObserve();\n }\n }\n\n // --- Internal ---\n\n private _applyDisplayAndObserve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n this._connectedCallbackPromise = this._core.observe(element);\n }\n\n // Copied verbatim from packages/intersection/src/components/Intersect.ts\n // (§1 of docs/pointer-lock-tag-design.md / docs/fullscreen-tag-design.md).\n private _resolveTarget(): { element: Element | null; display: string } {\n const target = this.target;\n if (target === \"self\") {\n return { element: this, display: \"block\" };\n }\n if (target !== \"\") {\n const scope = this.getRootNode() as Document | ShadowRoot;\n return { element: this._safeQuery(scope, target), display: \"none\" };\n }\n const child = this.firstElementChild;\n if (child) {\n return { element: child, display: \"contents\" };\n }\n return { element: this, display: \"block\" };\n }\n\n // Copied verbatim from packages/intersection/src/components/Intersect.ts.\n private _safeQuery(scope: Document | ShadowRoot, selector: string): Element | null {\n try {\n return scope.querySelector(selector);\n } catch {\n return null;\n }\n }\n}\n","import { WcsPointerLock } from \"./components/PointerLock.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.pointerLock)) {\n customElements.define(config.tagNames.pointerLock, WcsPointerLock);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapPointerLock(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/pointerLockCapabilities.ts","../src/core/PointerLockCore.ts","../src/components/PointerLock.ts","../src/registerComponents.ts","../src/bootstrapPointerLock.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n pointerLock: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n pointerLock: \"wcs-pointer-lock\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","/**\n * pointerLockCapabilities.ts\n *\n * Pointer Lock node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。pointer-lock は referenced element を操作するモニタ的ノードで競合 operation\n * を持たないため lane は無く、error taxonomy(errorInfo)のみを採用する。\n *\n * `_setError` は合成 `{ message }`(target 未解決 / API 非対応)と caught 例外\n * (`NotAllowedError` / `TypeError` = user gesture 外の requestPointerLock 拒否)を混在\n * 受理する。呼出側が明示 `kind` を渡して合成側を曖昧さ無く分類し、caught は `.name` で\n * 分類する(fullscreen と同じ discriminator 方式)。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 明示 kind discriminator(合成エラーの呼出側が渡す)。 */\nexport type PointerLockErrorKind = \"capability-missing\" | \"invalid-argument\";\n\n/** 安定した pointer-lock error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_POINTER_LOCK_ERROR_CODE = {\n /** Pointer Lock API 非対応。 */\n CapabilityMissing: \"capability-missing\",\n /** target selector が要素に解決しない等の入力不備。 */\n InvalidArgument: \"invalid-argument\",\n /** `NotAllowedError` / `TypeError` — user gesture 外での要求拒否。 */\n NotAllowed: \"not-allowed\",\n /** その他の caught 例外。 */\n PointerLockError: \"pointer-lock-error\",\n} as const;\n\nfunction messageOf(error: unknown): string {\n return typeof (error as { message?: unknown } | null)?.message === \"string\"\n ? (error as { message: string }).message\n : String(error);\n}\n\n/**\n * pointer-lock の失敗を serializable な error taxonomy に写す。`kind` は合成エラーの\n * 呼出側が渡す明示 discriminator(`capability-missing` / `invalid-argument`)。未指定は\n * caught 例外を意味し、`.name` で分類する。`NotAllowedError` / `TypeError` は user\n * gesture 内で再試行すれば成功しうるため recoverable=true。\n */\nexport function derivePointerLockErrorInfo(error: unknown, kind?: PointerLockErrorKind): WcsIoErrorInfo {\n const message = messageOf(error);\n if (kind === \"capability-missing\") {\n return { code: WCS_POINTER_LOCK_ERROR_CODE.CapabilityMissing, phase: \"probe\", recoverable: false, message };\n }\n if (kind === \"invalid-argument\") {\n return { code: WCS_POINTER_LOCK_ERROR_CODE.InvalidArgument, phase: \"start\", recoverable: false, message };\n }\n const name = (error as { name?: unknown } | null)?.name;\n if (name === \"NotAllowedError\" || name === \"TypeError\") {\n return { code: WCS_POINTER_LOCK_ERROR_CODE.NotAllowed, phase: \"execute\", recoverable: true, message };\n }\n return { code: WCS_POINTER_LOCK_ERROR_CODE.PointerLockError, phase: \"execute\", recoverable: false, message };\n}\n","import { IWcBindable } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { derivePointerLockErrorInfo, PointerLockErrorKind } from \"./pointerLockCapabilities.js\";\n\n/**\n * Headless Pointer Lock primitive. A thin, framework-agnostic wrapper around\n * the Pointer Lock API (`Element.requestPointerLock()` /\n * `document.exitPointerLock()` / `document.pointerLockElement` / the\n * `document`-scoped `pointerlockchange` event) exposed through the\n * wc-bindable protocol.\n *\n * This Core follows the same basic pattern as `FullscreenCore`\n * (docs/fullscreen-tag-design.md, referenced by docs/pointer-lock-tag-design.md\n * §1): target resolution happens in the Shell, `pointerlockchange` is\n * subscribed on `document` (not on the target element) and each instance\n * self-filters by comparing `document.pointerLockElement` against its own\n * resolved target, API resolution is call-time (never cached) and probes the\n * standard name before the legacy (`webkit`-prefixed) name, and a single\n * Core-level `_gen` generation guard protects the asynchronous\n * `requestPointerLock()` call from stale resolution after dispose().\n *\n * Key difference from Fullscreen (docs/pointer-lock-tag-design.md §2):\n * `exitPointerLock()` is a *synchronous* platform API (it returns `void`, not\n * a `Promise`), so the Core's `exitPointerLock()` command is synchronous too\n * and carries no `_gen` guard of its own — it is wrapped in `try/catch` only\n * as a defensive measure (never-throw), not because it can go stale.\n *\n * Scope note (docs/pointer-lock-tag-design.md §3): `movementX`/`movementY`\n * are intentionally NOT exposed by this Core (v1 scope). They are\n * high-frequency `mousemove` data unsuited to the same-value-guarded\n * declarative `properties` surface; see the design doc for the rationale and\n * the planned `debounce`/`throttle`-based opt-in for a future version.\n */\nexport class PointerLockCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n // `active`'s CustomEvent detail is the bare boolean value itself — no\n // getter needed (docs/pointer-lock-tag-design.md §2). This differs from\n // FullscreenCore's `{ active }`-shaped detail + getter.\n properties: [\n { name: \"active\", event: \"wcs-pointer-lock:change\" },\n // `error` / `errorInfo` are observable failure outputs. Historically `error`\n // was an imperative getter with no event; both are now bindable (event-backed)\n // so `data-wcs` / bind() can observe a request/exit failure. `errorInfo` is the\n // additive serializable taxonomy (stable code / phase / recoverable) derived\n // from `error`; the `error` value shape is unchanged. No lane — pointer-lock\n // drives a referenced element, not a competing operation.\n { name: \"error\", event: \"wcs-pointer-lock:error\" },\n { name: \"errorInfo\", event: \"wcs-pointer-lock:error-info-changed\" },\n ],\n commands: [\n { name: \"requestPointerLock\", async: true },\n // Synchronous platform API (document.exitPointerLock() returns void) —\n // no `async` flag (docs/pointer-lock-tag-design.md §2).\n { name: \"exitPointerLock\" },\n ],\n };\n\n private _target: EventTarget;\n private _active = false;\n private _error: any = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n\n // The element this instance last resolved requestPointerLock()/observe()\n // against, kept so the document-scoped `pointerlockchange` handler can\n // self-filter under multiple concurrent instances (docs/fullscreen-tag-design.md\n // §2.1, inherited verbatim by pointer-lock per docs/pointer-lock-tag-design.md §1).\n private _resolvedTarget: Element | null = null;\n\n // True once observe() has attached the live `document` listener. Guards\n // observe() so a redundant call does not re-subscribe; dispose() resets it\n // so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // Core-level generation guard (§3.4 of the guidelines / §6 of\n // fullscreen-tag-design.md): only requestPointerLock() is asynchronous and\n // needs it. exitPointerLock() is synchronous and has no stale-resolution\n // race to guard against.\n private _gen = 0;\n\n // SSR (§3.8): no asynchronous probe to await — observe() completes\n // synchronously, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get active(): boolean {\n return this._active;\n }\n\n get error(): any {\n return this._error;\n }\n\n /**\n * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /\n * `recoverable`), or null. Additive wc-bindable property (event\n * `wcs-pointer-lock:error-info-changed`), derived from `error`; the existing\n * `error` value shape is unchanged.\n */\n get errorInfo(): WcsIoErrorInfo | null {\n return this._errorInfo;\n }\n\n // Lifecycle (§3.5). Idempotent: a second observe() while already subscribed\n // updates the tracked resolved target without re-subscribing to `document`.\n observe(target: Element | null): Promise<void> {\n this._resolvedTarget = target;\n if (!this._subscribed) {\n this._subscribed = true;\n document.addEventListener(this._pointerLockChangeEventName(), this._onChange);\n }\n this._applyActive();\n return this._ready;\n }\n\n dispose(): void {\n this._gen++; // invalidate any in-flight requestPointerLock() resolution\n if (this._subscribed) {\n this._subscribed = false;\n document.removeEventListener(this._pointerLockChangeEventName(), this._onChange);\n }\n this._resolvedTarget = null;\n }\n\n /**\n * Request pointer lock on `element`. Never-throw: a missing API or a\n * rejected promise (e.g. called outside a user-gesture context —\n * `NotAllowedError`, docs/fullscreen-tag-design.md §3) is captured into\n * `error` rather than propagated. `element` may be `null` when the Shell's\n * `target` selector did not resolve (docs/pointer-lock-tag-design.md §1\n * defers error representation to FullscreenCore verbatim — this null-target\n * case mirrors `FullscreenCore.requestFullscreen(null)`,\n * docs/fullscreen-tag-design.md §6): distinct from \"API is not supported\"\n * below, so a typo'd selector doesn't masquerade as an unsupported platform.\n */\n async requestPointerLock(element: Element | null): Promise<void> {\n const gen = ++this._gen;\n this._resolvedTarget = element;\n if (!element) {\n this._setError({ message: \"Pointer Lock target could not be resolved.\" }, \"invalid-argument\");\n return;\n }\n const fn = this._requestPointerLockFn(element);\n if (!fn) {\n // Resolved synchronously in the same tick as the call — dispose()\n // cannot have run yet, so no staleness check is needed here (matches\n // the reference `requestFullscreen()` implementation,\n // docs/fullscreen-tag-design.md §6).\n this._setError({ message: \"Pointer Lock API is not supported.\" }, \"capability-missing\");\n return;\n }\n try {\n // fn is already bound to `element` by _requestPointerLockFn().\n await fn();\n if (gen !== this._gen) return; // stale\n this._setError(null);\n this._applyActive();\n } catch (e: any) {\n if (gen !== this._gen) return; // stale\n this._setError(e);\n }\n }\n\n /**\n * Exit pointer lock. Synchronous platform API (docs/pointer-lock-tag-design.md\n * §2) — returns `void`, not a `Promise`. Silent no-op when nothing is\n * currently locked or the API is unsupported (mirrors\n * `FullscreenCore.exitFullscreen()`'s no-op contract,\n * docs/fullscreen-tag-design.md §7). Wrapped in try/catch defensively: even\n * though the platform API is synchronous and documented as not throwing in\n * this case, a synchronous throw from a non-conformant/fake implementation\n * must never escape (never-throw).\n */\n exitPointerLock(): void {\n try {\n if (this._pointerLockElement() === null) return; // already unlocked: silent no-op\n const fn = this._exitPointerLockFn();\n if (!fn) return; // unsupported: silent no-op (semantically already \"not locked\")\n fn();\n this._setError(null);\n this._applyActive();\n } catch (e: any) {\n this._setError(e);\n }\n }\n\n // --- API resolution (call-time, never cached — §3.7) ---\n\n // Resolved from `Element.prototype` rather than `el.requestPointerLock`\n // directly: when `target=\"self\"`, `el` is the `<wcs-pointer-lock>` Shell\n // itself, whose own class declares an instance method also named\n // `requestPointerLock()` (the wcBindable command). Reading the property off\n // the instance would pick up that Shell method instead of the native\n // platform API and recurse infinitely (Shell.requestPointerLock() ->\n // Core.requestPointerLock() -> resolves \"el.requestPointerLock\" -> the same\n // Shell method again). Going through `Element.prototype` sidesteps the name\n // collision — note this does NOT pick up an override on a subclass's own\n // prototype (e.g. `WcsPointerLock.prototype`); it deliberately jumps\n // straight to the platform-defined layer. Both the standard and legacy name\n // are resolved the same way, for symmetry — matching FullscreenCore's\n // `_elementFullscreenFn` (docs/fullscreen-tag-design.md §4) ONLY in that one\n // respect. Unlike that Core, this one does not check `el`'s own properties\n // first: there is no test-stub/per-element monkey-patch path to accommodate\n // here (mocks.ts installs the fakes directly on `Element.prototype`), so it\n // goes straight there for both names.\n private _requestPointerLockFn(el: Element): (() => Promise<void>) | undefined {\n const proto = Element.prototype as any;\n const standard = proto.requestPointerLock;\n if (typeof standard === \"function\") return standard.bind(el);\n const legacy = proto.webkitRequestPointerLock;\n return typeof legacy === \"function\" ? legacy.bind(el) : undefined;\n }\n\n private _exitPointerLockFn(): (() => void) | undefined {\n const d = document as any;\n return d.exitPointerLock?.bind(document) ?? d.webkitExitPointerLock?.bind(document);\n }\n\n private _pointerLockElement(): Element | null {\n const d = document as any;\n return d.pointerLockElement ?? d.webkitPointerLockElement ?? null;\n }\n\n // NOTE (test-environment caveat, not a production concern): happy-dom\n // always implements `document.onpointerlockchange` (as `null`) regardless\n // of which fake API surface a test installs, so `\"onpointerlockchange\" in\n // document` can never observably be `false` under this test runner and the\n // `webkitpointerlockchange` branch below cannot be driven through\n // `observe()` in a unit test. The branch is still correct and required for\n // real legacy WebKit builds that lack `onpointerlockchange` entirely — kept\n // as documented, deliberate, untestable-in-this-harness code per\n // docs/pointer-lock-tag-design.md.\n /* v8 ignore next 3 */\n private _pointerLockChangeEventName(): string {\n return \"onpointerlockchange\" in document ? \"pointerlockchange\" : \"webkitpointerlockchange\";\n }\n\n private _onChange = (): void => {\n this._applyActive();\n };\n\n // Self-filter (docs/fullscreen-tag-design.md §2.1): compares against this\n // instance's own resolved target, not merely \"is *something* locked\" — so\n // multiple concurrent instances each report the correct `active` value.\n private _applyActive(): void {\n const next = this._resolvedTarget !== null && this._pointerLockElement() === this._resolvedTarget;\n this._setActive(next);\n }\n\n // Same-value guard (MUST, §3.3 of the guidelines). detail itself is the\n // bare boolean value (no getter needed) per docs/pointer-lock-tag-design.md\n // §2 — unlike FullscreenCore's `{ active }`-shaped detail + getter.\n private _setActive(v: boolean): void {\n if (this._active === v) return;\n this._active = v;\n this._target.dispatchEvent(new CustomEvent(\"wcs-pointer-lock:change\", {\n detail: v,\n bubbles: true,\n }));\n }\n\n // `kind` is an explicit taxonomy discriminator passed only from the synthetic\n // error sites (unsupported / unresolved target); caught exceptions pass no kind\n // and are classified by their `.name`. Both `error` and the additive `errorInfo`\n // are now event-backed so a request/exit failure is observable via bind().\n private _setError(error: any, kind?: PointerLockErrorKind): void {\n // Same-value guard on reference: each failure builds a fresh object and the\n // clear path passes the literal null, so this only suppresses redundant\n // null→null (a successful request/exit clearing an already-null error).\n if (this._error === error) return;\n this._error = error;\n // Keep the additive errorInfo taxonomy in sync; fire it before the `error`\n // event so an observer of both sees the classification first (io-node family).\n this._commitErrorInfo(error === null ? null : derivePointerLockErrorInfo(error, kind));\n this._target.dispatchEvent(new CustomEvent(\"wcs-pointer-lock:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // Called only from _setError (already reference-guarded), so errorInfo\n // transitions exactly when error does — no separate guard needed here.\n private _commitErrorInfo(info: WcsIoErrorInfo | null): void {\n this._errorInfo = info;\n this._target.dispatchEvent(new CustomEvent(\"wcs-pointer-lock:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { PointerLockCore } from \"../core/PointerLockCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\n\n/**\n * `<wcs-pointer-lock target=\"...\">` — declarative Pointer Lock API control.\n *\n * Like `<wcs-fullscreen>` (docs/fullscreen-tag-design.md §0), this Shell does\n * not lock itself — it operates on a *referenced* element via the `target`\n * attribute, using the same 3-mode resolution rule as `intersection`\n * (`_resolveTarget()`/`_safeQuery()`, copied verbatim per\n * docs/pointer-lock-tag-design.md §1 / docs/fullscreen-tag-design.md §1):\n *\n * | `target` | operates on | display |\n * |-----------------|-------------------------|-------------|\n * | omitted | first element child | `contents` |\n * | `\"#selector\"` | the matched element | `none` |\n * | `\"self\"` | the element itself | `block` |\n *\n * `requestPointerLock()` requires a user-gesture context (docs/fullscreen-tag-design.md\n * §3) — the primary activation path is the command-token protocol\n * (`command.requestPointerLock: $command.<token>` on `<wcs-pointer-lock>`,\n * emitted by a button's `onclick: $command.<token>`), not an\n * autoTrigger attribute (none is provided in v1,\n * docs/pointer-lock-tag-design.md §4).\n *\n * `movementX`/`movementY` are intentionally out of scope for v1\n * (docs/pointer-lock-tag-design.md §3) — do not add them without revisiting\n * the design doc.\n */\nexport class WcsPointerLock extends HTMLElement {\n // SSR (§4.4): the Core subscribes synchronously on connect, but the Shell\n // still exposes connectedCallbackPromise so the state binder can await it\n // uniformly across all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static observedAttributes = [\"target\"];\n\n static wcBindable: IWcBindable = {\n ...PointerLockCore.wcBindable,\n inputs: [{ name: \"target\", attribute: \"target\" }],\n // Core の commands をそのまま継承(単一情報源)。network/intersection と同型。\n commands: PointerLockCore.wcBindable.commands,\n };\n\n private _core: PointerLockCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new PointerLockCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-pointer-lock:change\": (d) => ({ active: d === true }),\n });\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (docs/custom-state-reflection-design.md §3.6): attachInternals\n // is absent in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n // --- Core delegated getters ---\n\n get active(): boolean {\n return this._core.active;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get errorInfo(): WcsIoErrorInfo | null {\n return this._core.errorInfo;\n }\n\n // --- Commands ---\n\n /**\n * Resolve `target` and request pointer lock on it. Requires a user-gesture\n * context. never-throw: an unresolvable target or an unsupported/rejected\n * API call are both surfaced via `error`, never thrown (mirrors\n * `<wcs-fullscreen>`'s `requestFullscreen()`, docs/fullscreen-tag-design.md\n * §3/§6 — the Shell passes the (possibly `null`) resolved element straight\n * through and lets the Core set `error`, rather than silently no-op'ing\n * here).\n */\n async requestPointerLock(): Promise<void> {\n const { element } = this._resolveTarget();\n await this._core.requestPointerLock(element);\n }\n\n /** Exit pointer lock. Synchronous command — silent no-op if nothing is locked. */\n exitPointerLock(): void {\n this._core.exitPointerLock();\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this._applyDisplayAndObserve();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n\n attributeChangedCallback(name: string): void {\n if (name === \"target\" && this.isConnected) {\n this._applyDisplayAndObserve();\n }\n }\n\n // --- Internal ---\n\n private _applyDisplayAndObserve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n this._connectedCallbackPromise = this._core.observe(element);\n }\n\n // Copied verbatim from packages/intersection/src/components/Intersect.ts\n // (§1 of docs/pointer-lock-tag-design.md / docs/fullscreen-tag-design.md).\n private _resolveTarget(): { element: Element | null; display: string } {\n const target = this.target;\n if (target === \"self\") {\n return { element: this, display: \"block\" };\n }\n if (target !== \"\") {\n const scope = this.getRootNode() as Document | ShadowRoot;\n return { element: this._safeQuery(scope, target), display: \"none\" };\n }\n const child = this.firstElementChild;\n if (child) {\n return { element: child, display: \"contents\" };\n }\n return { element: this, display: \"block\" };\n }\n\n // Copied verbatim from packages/intersection/src/components/Intersect.ts.\n private _safeQuery(scope: Document | ShadowRoot, selector: string): Element | null {\n try {\n return scope.querySelector(selector);\n } catch {\n return null;\n }\n }\n}\n","import { WcsPointerLock } from \"./components/PointerLock.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.pointerLock)) {\n customElements.define(config.tagNames.pointerLock, WcsPointerLock);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapPointerLock(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const t={tagNames:{pointerLock:"wcs-pointer-lock"}};function e(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const r of Object.keys(t))e(t[r]);return t}function r(t){if(null===t||"object"!=typeof t)return t;const e={};for(const n of Object.keys(t))e[n]=r(t[n]);return e}let n=null;const s=t;function i(){return n||(n=e(r(t))),n}class o extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"active",event:"wcs-pointer-lock:change"}],commands:[{name:"requestPointerLock",async:!0},{name:"exitPointerLock"}]};_target;_active=!1;_error=null;_resolvedTarget=null;_subscribed=!1;_gen=0;_ready=Promise.resolve();constructor(t){super(),this._target=t??this}get ready(){return this._ready}get active(){return this._active}get error(){return this._error}observe(t){return this._resolvedTarget=t,this._subscribed||(this._subscribed=!0,document.addEventListener(this._pointerLockChangeEventName(),this._onChange)),this._applyActive(),this._ready}dispose(){this._gen++,this._subscribed&&(this._subscribed=!1,document.removeEventListener(this._pointerLockChangeEventName(),this._onChange)),this._resolvedTarget=null}async requestPointerLock(t){const e=++this._gen;if(this._resolvedTarget=t,!t)return void this._setError({message:"Pointer Lock target could not be resolved."});const r=this._requestPointerLockFn(t);if(r)try{if(await r(),e!==this._gen)return;this._setError(null),this._applyActive()}catch(t){if(e!==this._gen)return;this._setError(t)}else this._setError({message:"Pointer Lock API is not supported."})}exitPointerLock(){try{if(null===this._pointerLockElement())return;const t=this._exitPointerLockFn();if(!t)return;t(),this._setError(null),this._applyActive()}catch(t){this._setError(t)}}_requestPointerLockFn(t){const e=Element.prototype,r=e.requestPointerLock;if("function"==typeof r)return r.bind(t);const n=e.webkitRequestPointerLock;return"function"==typeof n?n.bind(t):void 0}_exitPointerLockFn(){const t=document;return t.exitPointerLock?.bind(document)??t.webkitExitPointerLock?.bind(document)}_pointerLockElement(){const t=document;return t.pointerLockElement??t.webkitPointerLockElement??null}_pointerLockChangeEventName(){return"onpointerlockchange"in document?"pointerlockchange":"webkitpointerlockchange"}_onChange=()=>{this._applyActive()};_applyActive(){const t=null!==this._resolvedTarget&&this._pointerLockElement()===this._resolvedTarget;this._setActive(t)}_setActive(t){this._active!==t&&(this._active=t,this._target.dispatchEvent(new CustomEvent("wcs-pointer-lock:change",{detail:t,bubbles:!0})))}_setError(t){this._error=t}}class c extends HTMLElement{static hasConnectedCallbackPromise=!0;static observedAttributes=["target"];static wcBindable={...o.wcBindable,inputs:[{name:"target",attribute:"target"}],commands:o.wcBindable.commands};_core;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new o(this),this._internals=this._initInternals(),this._wireStates({"wcs-pointer-lock:change":t=>({active:!0===t})})}get connectedCallbackPromise(){return this._connectedCallbackPromise}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const t=this.attachInternals();return t.states.add("wcs-probe"),t.states.delete("wcs-probe"),t}catch{return null}}_wireStates(t){if(null===this._internals)return;const e=this._internals.states;for(const[r,n]of Object.entries(t))this.addEventListener(r,t=>{const r=this.hasAttribute("debug-states");for(const[s,i]of Object.entries(n(t.detail))){try{i?e.add(s):e.delete(s)}catch{}r&&this.toggleAttribute(`data-wcs-state-${s}`,i)}})}get target(){return this.getAttribute("target")??""}set target(t){this.setAttribute("target",t)}get active(){return this._core.active}get error(){return this._core.error}async requestPointerLock(){const{element:t}=this._resolveTarget();await this._core.requestPointerLock(t)}exitPointerLock(){this._core.exitPointerLock()}connectedCallback(){this._applyDisplayAndObserve()}disconnectedCallback(){this._core.dispose()}attributeChangedCallback(t){"target"===t&&this.isConnected&&this._applyDisplayAndObserve()}_applyDisplayAndObserve(){const{element:t,display:e}=this._resolveTarget();this.style.display=e,this._connectedCallbackPromise=this._core.observe(t)}_resolveTarget(){const t=this.target;if("self"===t)return{element:this,display:"block"};if(""!==t){const e=this.getRootNode();return{element:this._safeQuery(e,t),display:"none"}}const e=this.firstElementChild;return e?{element:e,display:"contents"}:{element:this,display:"block"}}_safeQuery(t,e){try{return t.querySelector(e)}catch{return null}}}function a(e){var r;e&&((r=e).tagNames&&Object.assign(t.tagNames,r.tagNames),n=null),customElements.get(s.tagNames.pointerLock)||customElements.define(s.tagNames.pointerLock,c)}export{o as PointerLockCore,c as WcsPointerLock,a as bootstrapPointerLock,i as getConfig};
1
+ const e={tagNames:{pointerLock:"wcs-pointer-lock"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const r of Object.keys(e))t(e[r]);return e}function r(e){if(null===e||"object"!=typeof e)return e;const t={};for(const n of Object.keys(e))t[n]=r(e[n]);return t}let n=null;const s=e;function i(){return n||(n=t(r(e))),n}const o={CapabilityMissing:"capability-missing",InvalidArgument:"invalid-argument",NotAllowed:"not-allowed",PointerLockError:"pointer-lock-error"};function c(e,t){const r=function(e){return"string"==typeof e?.message?e.message:String(e)}(e);if("capability-missing"===t)return{code:o.CapabilityMissing,phase:"probe",recoverable:!1,message:r};if("invalid-argument"===t)return{code:o.InvalidArgument,phase:"start",recoverable:!1,message:r};const n=e?.name;return"NotAllowedError"===n||"TypeError"===n?{code:o.NotAllowed,phase:"execute",recoverable:!0,message:r}:{code:o.PointerLockError,phase:"execute",recoverable:!1,message:r}}class a extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"active",event:"wcs-pointer-lock:change"},{name:"error",event:"wcs-pointer-lock:error"},{name:"errorInfo",event:"wcs-pointer-lock:error-info-changed"}],commands:[{name:"requestPointerLock",async:!0},{name:"exitPointerLock"}]};_target;_active=!1;_error=null;_errorInfo=null;_resolvedTarget=null;_subscribed=!1;_gen=0;_ready=Promise.resolve();constructor(e){super(),this._target=e??this}get ready(){return this._ready}get active(){return this._active}get error(){return this._error}get errorInfo(){return this._errorInfo}observe(e){return this._resolvedTarget=e,this._subscribed||(this._subscribed=!0,document.addEventListener(this._pointerLockChangeEventName(),this._onChange)),this._applyActive(),this._ready}dispose(){this._gen++,this._subscribed&&(this._subscribed=!1,document.removeEventListener(this._pointerLockChangeEventName(),this._onChange)),this._resolvedTarget=null}async requestPointerLock(e){const t=++this._gen;if(this._resolvedTarget=e,!e)return void this._setError({message:"Pointer Lock target could not be resolved."},"invalid-argument");const r=this._requestPointerLockFn(e);if(r)try{if(await r(),t!==this._gen)return;this._setError(null),this._applyActive()}catch(e){if(t!==this._gen)return;this._setError(e)}else this._setError({message:"Pointer Lock API is not supported."},"capability-missing")}exitPointerLock(){try{if(null===this._pointerLockElement())return;const e=this._exitPointerLockFn();if(!e)return;e(),this._setError(null),this._applyActive()}catch(e){this._setError(e)}}_requestPointerLockFn(e){const t=Element.prototype,r=t.requestPointerLock;if("function"==typeof r)return r.bind(e);const n=t.webkitRequestPointerLock;return"function"==typeof n?n.bind(e):void 0}_exitPointerLockFn(){const e=document;return e.exitPointerLock?.bind(document)??e.webkitExitPointerLock?.bind(document)}_pointerLockElement(){const e=document;return e.pointerLockElement??e.webkitPointerLockElement??null}_pointerLockChangeEventName(){return"onpointerlockchange"in document?"pointerlockchange":"webkitpointerlockchange"}_onChange=()=>{this._applyActive()};_applyActive(){const e=null!==this._resolvedTarget&&this._pointerLockElement()===this._resolvedTarget;this._setActive(e)}_setActive(e){this._active!==e&&(this._active=e,this._target.dispatchEvent(new CustomEvent("wcs-pointer-lock:change",{detail:e,bubbles:!0})))}_setError(e,t){this._error!==e&&(this._error=e,this._commitErrorInfo(null===e?null:c(e,t)),this._target.dispatchEvent(new CustomEvent("wcs-pointer-lock:error",{detail:e,bubbles:!0})))}_commitErrorInfo(e){this._errorInfo=e,this._target.dispatchEvent(new CustomEvent("wcs-pointer-lock:error-info-changed",{detail:e,bubbles:!0}))}}class l extends HTMLElement{static hasConnectedCallbackPromise=!0;static observedAttributes=["target"];static wcBindable={...a.wcBindable,inputs:[{name:"target",attribute:"target"}],commands:a.wcBindable.commands};_core;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new a(this),this._internals=this._initInternals(),this._wireStates({"wcs-pointer-lock:change":e=>({active:!0===e})})}get connectedCallbackPromise(){return this._connectedCallbackPromise}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const e=this.attachInternals();return e.states.add("wcs-probe"),e.states.delete("wcs-probe"),e}catch{return null}}_wireStates(e){if(null===this._internals)return;const t=this._internals.states;for(const[r,n]of Object.entries(e))this.addEventListener(r,e=>{const r=this.hasAttribute("debug-states");for(const[s,i]of Object.entries(n(e.detail))){try{i?t.add(s):t.delete(s)}catch{}r&&this.toggleAttribute(`data-wcs-state-${s}`,i)}})}get target(){return this.getAttribute("target")??""}set target(e){this.setAttribute("target",e)}get active(){return this._core.active}get error(){return this._core.error}get errorInfo(){return this._core.errorInfo}async requestPointerLock(){const{element:e}=this._resolveTarget();await this._core.requestPointerLock(e)}exitPointerLock(){this._core.exitPointerLock()}connectedCallback(){this._applyDisplayAndObserve()}disconnectedCallback(){this._core.dispose()}attributeChangedCallback(e){"target"===e&&this.isConnected&&this._applyDisplayAndObserve()}_applyDisplayAndObserve(){const{element:e,display:t}=this._resolveTarget();this.style.display=t,this._connectedCallbackPromise=this._core.observe(e)}_resolveTarget(){const e=this.target;if("self"===e)return{element:this,display:"block"};if(""!==e){const t=this.getRootNode();return{element:this._safeQuery(t,e),display:"none"}}const t=this.firstElementChild;return t?{element:t,display:"contents"}:{element:this,display:"block"}}_safeQuery(e,t){try{return e.querySelector(t)}catch{return null}}}function u(t){var r;t&&((r=t).tagNames&&Object.assign(e.tagNames,r.tagNames),n=null),customElements.get(s.tagNames.pointerLock)||customElements.define(s.tagNames.pointerLock,l)}export{a as PointerLockCore,o as WCS_POINTER_LOCK_ERROR_CODE,l as WcsPointerLock,u as bootstrapPointerLock,i as getConfig};
2
2
  //# sourceMappingURL=index.esm.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/core/PointerLockCore.ts","../src/components/PointerLock.ts","../src/bootstrapPointerLock.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n pointerLock: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n pointerLock: \"wcs-pointer-lock\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\n/**\n * Headless Pointer Lock primitive. A thin, framework-agnostic wrapper around\n * the Pointer Lock API (`Element.requestPointerLock()` /\n * `document.exitPointerLock()` / `document.pointerLockElement` / the\n * `document`-scoped `pointerlockchange` event) exposed through the\n * wc-bindable protocol.\n *\n * This Core follows the same basic pattern as `FullscreenCore`\n * (docs/fullscreen-tag-design.md, referenced by docs/pointer-lock-tag-design.md\n * §1): target resolution happens in the Shell, `pointerlockchange` is\n * subscribed on `document` (not on the target element) and each instance\n * self-filters by comparing `document.pointerLockElement` against its own\n * resolved target, API resolution is call-time (never cached) and probes the\n * standard name before the legacy (`webkit`-prefixed) name, and a single\n * Core-level `_gen` generation guard protects the asynchronous\n * `requestPointerLock()` call from stale resolution after dispose().\n *\n * Key difference from Fullscreen (docs/pointer-lock-tag-design.md §2):\n * `exitPointerLock()` is a *synchronous* platform API (it returns `void`, not\n * a `Promise`), so the Core's `exitPointerLock()` command is synchronous too\n * and carries no `_gen` guard of its own — it is wrapped in `try/catch` only\n * as a defensive measure (never-throw), not because it can go stale.\n *\n * Scope note (docs/pointer-lock-tag-design.md §3): `movementX`/`movementY`\n * are intentionally NOT exposed by this Core (v1 scope). They are\n * high-frequency `mousemove` data unsuited to the same-value-guarded\n * declarative `properties` surface; see the design doc for the rationale and\n * the planned `debounce`/`throttle`-based opt-in for a future version.\n */\nexport class PointerLockCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n // `active`'s CustomEvent detail is the bare boolean value itself — no\n // getter needed (docs/pointer-lock-tag-design.md §2). This differs from\n // FullscreenCore's `{ active }`-shaped detail + getter.\n properties: [\n { name: \"active\", event: \"wcs-pointer-lock:change\" },\n ],\n commands: [\n { name: \"requestPointerLock\", async: true },\n // Synchronous platform API (document.exitPointerLock() returns void) —\n // no `async` flag (docs/pointer-lock-tag-design.md §2).\n { name: \"exitPointerLock\" },\n ],\n };\n\n private _target: EventTarget;\n private _active = false;\n private _error: any = null;\n\n // The element this instance last resolved requestPointerLock()/observe()\n // against, kept so the document-scoped `pointerlockchange` handler can\n // self-filter under multiple concurrent instances (docs/fullscreen-tag-design.md\n // §2.1, inherited verbatim by pointer-lock per docs/pointer-lock-tag-design.md §1).\n private _resolvedTarget: Element | null = null;\n\n // True once observe() has attached the live `document` listener. Guards\n // observe() so a redundant call does not re-subscribe; dispose() resets it\n // so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // Core-level generation guard (§3.4 of the guidelines / §6 of\n // fullscreen-tag-design.md): only requestPointerLock() is asynchronous and\n // needs it. exitPointerLock() is synchronous and has no stale-resolution\n // race to guard against.\n private _gen = 0;\n\n // SSR (§3.8): no asynchronous probe to await — observe() completes\n // synchronously, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get active(): boolean {\n return this._active;\n }\n\n get error(): any {\n return this._error;\n }\n\n // Lifecycle (§3.5). Idempotent: a second observe() while already subscribed\n // updates the tracked resolved target without re-subscribing to `document`.\n observe(target: Element | null): Promise<void> {\n this._resolvedTarget = target;\n if (!this._subscribed) {\n this._subscribed = true;\n document.addEventListener(this._pointerLockChangeEventName(), this._onChange);\n }\n this._applyActive();\n return this._ready;\n }\n\n dispose(): void {\n this._gen++; // invalidate any in-flight requestPointerLock() resolution\n if (this._subscribed) {\n this._subscribed = false;\n document.removeEventListener(this._pointerLockChangeEventName(), this._onChange);\n }\n this._resolvedTarget = null;\n }\n\n /**\n * Request pointer lock on `element`. Never-throw: a missing API or a\n * rejected promise (e.g. called outside a user-gesture context —\n * `NotAllowedError`, docs/fullscreen-tag-design.md §3) is captured into\n * `error` rather than propagated. `element` may be `null` when the Shell's\n * `target` selector did not resolve (docs/pointer-lock-tag-design.md §1\n * defers error representation to FullscreenCore verbatim — this null-target\n * case mirrors `FullscreenCore.requestFullscreen(null)`,\n * docs/fullscreen-tag-design.md §6): distinct from \"API is not supported\"\n * below, so a typo'd selector doesn't masquerade as an unsupported platform.\n */\n async requestPointerLock(element: Element | null): Promise<void> {\n const gen = ++this._gen;\n this._resolvedTarget = element;\n if (!element) {\n this._setError({ message: \"Pointer Lock target could not be resolved.\" });\n return;\n }\n const fn = this._requestPointerLockFn(element);\n if (!fn) {\n // Resolved synchronously in the same tick as the call — dispose()\n // cannot have run yet, so no staleness check is needed here (matches\n // the reference `requestFullscreen()` implementation,\n // docs/fullscreen-tag-design.md §6).\n this._setError({ message: \"Pointer Lock API is not supported.\" });\n return;\n }\n try {\n // fn is already bound to `element` by _requestPointerLockFn().\n await fn();\n if (gen !== this._gen) return; // stale\n this._setError(null);\n this._applyActive();\n } catch (e: any) {\n if (gen !== this._gen) return; // stale\n this._setError(e);\n }\n }\n\n /**\n * Exit pointer lock. Synchronous platform API (docs/pointer-lock-tag-design.md\n * §2) — returns `void`, not a `Promise`. Silent no-op when nothing is\n * currently locked or the API is unsupported (mirrors\n * `FullscreenCore.exitFullscreen()`'s no-op contract,\n * docs/fullscreen-tag-design.md §7). Wrapped in try/catch defensively: even\n * though the platform API is synchronous and documented as not throwing in\n * this case, a synchronous throw from a non-conformant/fake implementation\n * must never escape (never-throw).\n */\n exitPointerLock(): void {\n try {\n if (this._pointerLockElement() === null) return; // already unlocked: silent no-op\n const fn = this._exitPointerLockFn();\n if (!fn) return; // unsupported: silent no-op (semantically already \"not locked\")\n fn();\n this._setError(null);\n this._applyActive();\n } catch (e: any) {\n this._setError(e);\n }\n }\n\n // --- API resolution (call-time, never cached — §3.7) ---\n\n // Resolved from `Element.prototype` rather than `el.requestPointerLock`\n // directly: when `target=\"self\"`, `el` is the `<wcs-pointer-lock>` Shell\n // itself, whose own class declares an instance method also named\n // `requestPointerLock()` (the wcBindable command). Reading the property off\n // the instance would pick up that Shell method instead of the native\n // platform API and recurse infinitely (Shell.requestPointerLock() ->\n // Core.requestPointerLock() -> resolves \"el.requestPointerLock\" -> the same\n // Shell method again). Going through `Element.prototype` sidesteps the name\n // collision — note this does NOT pick up an override on a subclass's own\n // prototype (e.g. `WcsPointerLock.prototype`); it deliberately jumps\n // straight to the platform-defined layer. Both the standard and legacy name\n // are resolved the same way, for symmetry — matching FullscreenCore's\n // `_elementFullscreenFn` (docs/fullscreen-tag-design.md §4) ONLY in that one\n // respect. Unlike that Core, this one does not check `el`'s own properties\n // first: there is no test-stub/per-element monkey-patch path to accommodate\n // here (mocks.ts installs the fakes directly on `Element.prototype`), so it\n // goes straight there for both names.\n private _requestPointerLockFn(el: Element): (() => Promise<void>) | undefined {\n const proto = Element.prototype as any;\n const standard = proto.requestPointerLock;\n if (typeof standard === \"function\") return standard.bind(el);\n const legacy = proto.webkitRequestPointerLock;\n return typeof legacy === \"function\" ? legacy.bind(el) : undefined;\n }\n\n private _exitPointerLockFn(): (() => void) | undefined {\n const d = document as any;\n return d.exitPointerLock?.bind(document) ?? d.webkitExitPointerLock?.bind(document);\n }\n\n private _pointerLockElement(): Element | null {\n const d = document as any;\n return d.pointerLockElement ?? d.webkitPointerLockElement ?? null;\n }\n\n // NOTE (test-environment caveat, not a production concern): happy-dom\n // always implements `document.onpointerlockchange` (as `null`) regardless\n // of which fake API surface a test installs, so `\"onpointerlockchange\" in\n // document` can never observably be `false` under this test runner and the\n // `webkitpointerlockchange` branch below cannot be driven through\n // `observe()` in a unit test. The branch is still correct and required for\n // real legacy WebKit builds that lack `onpointerlockchange` entirely — kept\n // as documented, deliberate, untestable-in-this-harness code per\n // docs/pointer-lock-tag-design.md.\n /* v8 ignore next 3 */\n private _pointerLockChangeEventName(): string {\n return \"onpointerlockchange\" in document ? \"pointerlockchange\" : \"webkitpointerlockchange\";\n }\n\n private _onChange = (): void => {\n this._applyActive();\n };\n\n // Self-filter (docs/fullscreen-tag-design.md §2.1): compares against this\n // instance's own resolved target, not merely \"is *something* locked\" — so\n // multiple concurrent instances each report the correct `active` value.\n private _applyActive(): void {\n const next = this._resolvedTarget !== null && this._pointerLockElement() === this._resolvedTarget;\n this._setActive(next);\n }\n\n // Same-value guard (MUST, §3.3 of the guidelines). detail itself is the\n // bare boolean value (no getter needed) per docs/pointer-lock-tag-design.md\n // §2 — unlike FullscreenCore's `{ active }`-shaped detail + getter.\n private _setActive(v: boolean): void {\n if (this._active === v) return;\n this._active = v;\n this._target.dispatchEvent(new CustomEvent(\"wcs-pointer-lock:change\", {\n detail: v,\n bubbles: true,\n }));\n }\n\n private _setError(e: any): void {\n this._error = e;\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { PointerLockCore } from \"../core/PointerLockCore.js\";\n\n/**\n * `<wcs-pointer-lock target=\"...\">` — declarative Pointer Lock API control.\n *\n * Like `<wcs-fullscreen>` (docs/fullscreen-tag-design.md §0), this Shell does\n * not lock itself — it operates on a *referenced* element via the `target`\n * attribute, using the same 3-mode resolution rule as `intersection`\n * (`_resolveTarget()`/`_safeQuery()`, copied verbatim per\n * docs/pointer-lock-tag-design.md §1 / docs/fullscreen-tag-design.md §1):\n *\n * | `target` | operates on | display |\n * |-----------------|-------------------------|-------------|\n * | omitted | first element child | `contents` |\n * | `\"#selector\"` | the matched element | `none` |\n * | `\"self\"` | the element itself | `block` |\n *\n * `requestPointerLock()` requires a user-gesture context (docs/fullscreen-tag-design.md\n * §3) — the primary activation path is the command-token protocol\n * (`command.requestPointerLock: $command.<token>` on `<wcs-pointer-lock>`,\n * emitted by a button's `onclick: $command.<token>`), not an\n * autoTrigger attribute (none is provided in v1,\n * docs/pointer-lock-tag-design.md §4).\n *\n * `movementX`/`movementY` are intentionally out of scope for v1\n * (docs/pointer-lock-tag-design.md §3) — do not add them without revisiting\n * the design doc.\n */\nexport class WcsPointerLock extends HTMLElement {\n // SSR (§4.4): the Core subscribes synchronously on connect, but the Shell\n // still exposes connectedCallbackPromise so the state binder can await it\n // uniformly across all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static observedAttributes = [\"target\"];\n\n static wcBindable: IWcBindable = {\n ...PointerLockCore.wcBindable,\n inputs: [{ name: \"target\", attribute: \"target\" }],\n // Core の commands をそのまま継承(単一情報源)。network/intersection と同型。\n commands: PointerLockCore.wcBindable.commands,\n };\n\n private _core: PointerLockCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new PointerLockCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-pointer-lock:change\": (d) => ({ active: d === true }),\n });\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (docs/custom-state-reflection-design.md §3.6): attachInternals\n // is absent in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n // --- Core delegated getters ---\n\n get active(): boolean {\n return this._core.active;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n // --- Commands ---\n\n /**\n * Resolve `target` and request pointer lock on it. Requires a user-gesture\n * context. never-throw: an unresolvable target or an unsupported/rejected\n * API call are both surfaced via `error`, never thrown (mirrors\n * `<wcs-fullscreen>`'s `requestFullscreen()`, docs/fullscreen-tag-design.md\n * §3/§6 — the Shell passes the (possibly `null`) resolved element straight\n * through and lets the Core set `error`, rather than silently no-op'ing\n * here).\n */\n async requestPointerLock(): Promise<void> {\n const { element } = this._resolveTarget();\n await this._core.requestPointerLock(element);\n }\n\n /** Exit pointer lock. Synchronous command — silent no-op if nothing is locked. */\n exitPointerLock(): void {\n this._core.exitPointerLock();\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this._applyDisplayAndObserve();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n\n attributeChangedCallback(name: string): void {\n if (name === \"target\" && this.isConnected) {\n this._applyDisplayAndObserve();\n }\n }\n\n // --- Internal ---\n\n private _applyDisplayAndObserve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n this._connectedCallbackPromise = this._core.observe(element);\n }\n\n // Copied verbatim from packages/intersection/src/components/Intersect.ts\n // (§1 of docs/pointer-lock-tag-design.md / docs/fullscreen-tag-design.md).\n private _resolveTarget(): { element: Element | null; display: string } {\n const target = this.target;\n if (target === \"self\") {\n return { element: this, display: \"block\" };\n }\n if (target !== \"\") {\n const scope = this.getRootNode() as Document | ShadowRoot;\n return { element: this._safeQuery(scope, target), display: \"none\" };\n }\n const child = this.firstElementChild;\n if (child) {\n return { element: child, display: \"contents\" };\n }\n return { element: this, display: \"block\" };\n }\n\n // Copied verbatim from packages/intersection/src/components/Intersect.ts.\n private _safeQuery(scope: Document | ShadowRoot, selector: string): Element | null {\n try {\n return scope.querySelector(selector);\n } catch {\n return null;\n }\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapPointerLock(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsPointerLock } from \"./components/PointerLock.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.pointerLock)) {\n customElements.define(config.tagNames.pointerLock, WcsPointerLock);\n }\n}\n"],"names":["_config","tagNames","pointerLock","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","PointerLockCore","EventTarget","static","protocol","version","properties","name","event","commands","async","_target","_active","_error","_resolvedTarget","_subscribed","_gen","_ready","Promise","resolve","constructor","target","super","this","ready","active","error","observe","document","addEventListener","_pointerLockChangeEventName","_onChange","_applyActive","dispose","removeEventListener","requestPointerLock","element","gen","_setError","message","fn","_requestPointerLockFn","e","exitPointerLock","_pointerLockElement","_exitPointerLockFn","el","proto","Element","prototype","standard","bind","legacy","webkitRequestPointerLock","undefined","d","webkitExitPointerLock","pointerLockElement","webkitPointerLockElement","next","_setActive","v","dispatchEvent","CustomEvent","detail","bubbles","WcsPointerLock","HTMLElement","wcBindable","inputs","attribute","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","connectedCallbackPromise","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","getAttribute","value","setAttribute","_resolveTarget","connectedCallback","_applyDisplayAndObserve","disconnectedCallback","attributeChangedCallback","isConnected","display","style","scope","getRootNode","_safeQuery","child","firstElementChild","selector","querySelector","bootstrapPointerLock","userConfig","partialConfig","assign","customElements","get","define"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/core/pointerLockCapabilities.ts","../src/core/PointerLockCore.ts","../src/components/PointerLock.ts","../src/bootstrapPointerLock.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n pointerLock: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n pointerLock: \"wcs-pointer-lock\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","/**\n * pointerLockCapabilities.ts\n *\n * Pointer Lock node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。pointer-lock は referenced element を操作するモニタ的ノードで競合 operation\n * を持たないため lane は無く、error taxonomy(errorInfo)のみを採用する。\n *\n * `_setError` は合成 `{ message }`(target 未解決 / API 非対応)と caught 例外\n * (`NotAllowedError` / `TypeError` = user gesture 外の requestPointerLock 拒否)を混在\n * 受理する。呼出側が明示 `kind` を渡して合成側を曖昧さ無く分類し、caught は `.name` で\n * 分類する(fullscreen と同じ discriminator 方式)。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 明示 kind discriminator(合成エラーの呼出側が渡す)。 */\nexport type PointerLockErrorKind = \"capability-missing\" | \"invalid-argument\";\n\n/** 安定した pointer-lock error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_POINTER_LOCK_ERROR_CODE = {\n /** Pointer Lock API 非対応。 */\n CapabilityMissing: \"capability-missing\",\n /** target selector が要素に解決しない等の入力不備。 */\n InvalidArgument: \"invalid-argument\",\n /** `NotAllowedError` / `TypeError` — user gesture 外での要求拒否。 */\n NotAllowed: \"not-allowed\",\n /** その他の caught 例外。 */\n PointerLockError: \"pointer-lock-error\",\n} as const;\n\nfunction messageOf(error: unknown): string {\n return typeof (error as { message?: unknown } | null)?.message === \"string\"\n ? (error as { message: string }).message\n : String(error);\n}\n\n/**\n * pointer-lock の失敗を serializable な error taxonomy に写す。`kind` は合成エラーの\n * 呼出側が渡す明示 discriminator(`capability-missing` / `invalid-argument`)。未指定は\n * caught 例外を意味し、`.name` で分類する。`NotAllowedError` / `TypeError` は user\n * gesture 内で再試行すれば成功しうるため recoverable=true。\n */\nexport function derivePointerLockErrorInfo(error: unknown, kind?: PointerLockErrorKind): WcsIoErrorInfo {\n const message = messageOf(error);\n if (kind === \"capability-missing\") {\n return { code: WCS_POINTER_LOCK_ERROR_CODE.CapabilityMissing, phase: \"probe\", recoverable: false, message };\n }\n if (kind === \"invalid-argument\") {\n return { code: WCS_POINTER_LOCK_ERROR_CODE.InvalidArgument, phase: \"start\", recoverable: false, message };\n }\n const name = (error as { name?: unknown } | null)?.name;\n if (name === \"NotAllowedError\" || name === \"TypeError\") {\n return { code: WCS_POINTER_LOCK_ERROR_CODE.NotAllowed, phase: \"execute\", recoverable: true, message };\n }\n return { code: WCS_POINTER_LOCK_ERROR_CODE.PointerLockError, phase: \"execute\", recoverable: false, message };\n}\n","import { IWcBindable } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { derivePointerLockErrorInfo, PointerLockErrorKind } from \"./pointerLockCapabilities.js\";\n\n/**\n * Headless Pointer Lock primitive. A thin, framework-agnostic wrapper around\n * the Pointer Lock API (`Element.requestPointerLock()` /\n * `document.exitPointerLock()` / `document.pointerLockElement` / the\n * `document`-scoped `pointerlockchange` event) exposed through the\n * wc-bindable protocol.\n *\n * This Core follows the same basic pattern as `FullscreenCore`\n * (docs/fullscreen-tag-design.md, referenced by docs/pointer-lock-tag-design.md\n * §1): target resolution happens in the Shell, `pointerlockchange` is\n * subscribed on `document` (not on the target element) and each instance\n * self-filters by comparing `document.pointerLockElement` against its own\n * resolved target, API resolution is call-time (never cached) and probes the\n * standard name before the legacy (`webkit`-prefixed) name, and a single\n * Core-level `_gen` generation guard protects the asynchronous\n * `requestPointerLock()` call from stale resolution after dispose().\n *\n * Key difference from Fullscreen (docs/pointer-lock-tag-design.md §2):\n * `exitPointerLock()` is a *synchronous* platform API (it returns `void`, not\n * a `Promise`), so the Core's `exitPointerLock()` command is synchronous too\n * and carries no `_gen` guard of its own — it is wrapped in `try/catch` only\n * as a defensive measure (never-throw), not because it can go stale.\n *\n * Scope note (docs/pointer-lock-tag-design.md §3): `movementX`/`movementY`\n * are intentionally NOT exposed by this Core (v1 scope). They are\n * high-frequency `mousemove` data unsuited to the same-value-guarded\n * declarative `properties` surface; see the design doc for the rationale and\n * the planned `debounce`/`throttle`-based opt-in for a future version.\n */\nexport class PointerLockCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n // `active`'s CustomEvent detail is the bare boolean value itself — no\n // getter needed (docs/pointer-lock-tag-design.md §2). This differs from\n // FullscreenCore's `{ active }`-shaped detail + getter.\n properties: [\n { name: \"active\", event: \"wcs-pointer-lock:change\" },\n // `error` / `errorInfo` are observable failure outputs. Historically `error`\n // was an imperative getter with no event; both are now bindable (event-backed)\n // so `data-wcs` / bind() can observe a request/exit failure. `errorInfo` is the\n // additive serializable taxonomy (stable code / phase / recoverable) derived\n // from `error`; the `error` value shape is unchanged. No lane — pointer-lock\n // drives a referenced element, not a competing operation.\n { name: \"error\", event: \"wcs-pointer-lock:error\" },\n { name: \"errorInfo\", event: \"wcs-pointer-lock:error-info-changed\" },\n ],\n commands: [\n { name: \"requestPointerLock\", async: true },\n // Synchronous platform API (document.exitPointerLock() returns void) —\n // no `async` flag (docs/pointer-lock-tag-design.md §2).\n { name: \"exitPointerLock\" },\n ],\n };\n\n private _target: EventTarget;\n private _active = false;\n private _error: any = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n\n // The element this instance last resolved requestPointerLock()/observe()\n // against, kept so the document-scoped `pointerlockchange` handler can\n // self-filter under multiple concurrent instances (docs/fullscreen-tag-design.md\n // §2.1, inherited verbatim by pointer-lock per docs/pointer-lock-tag-design.md §1).\n private _resolvedTarget: Element | null = null;\n\n // True once observe() has attached the live `document` listener. Guards\n // observe() so a redundant call does not re-subscribe; dispose() resets it\n // so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // Core-level generation guard (§3.4 of the guidelines / §6 of\n // fullscreen-tag-design.md): only requestPointerLock() is asynchronous and\n // needs it. exitPointerLock() is synchronous and has no stale-resolution\n // race to guard against.\n private _gen = 0;\n\n // SSR (§3.8): no asynchronous probe to await — observe() completes\n // synchronously, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n get active(): boolean {\n return this._active;\n }\n\n get error(): any {\n return this._error;\n }\n\n /**\n * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /\n * `recoverable`), or null. Additive wc-bindable property (event\n * `wcs-pointer-lock:error-info-changed`), derived from `error`; the existing\n * `error` value shape is unchanged.\n */\n get errorInfo(): WcsIoErrorInfo | null {\n return this._errorInfo;\n }\n\n // Lifecycle (§3.5). Idempotent: a second observe() while already subscribed\n // updates the tracked resolved target without re-subscribing to `document`.\n observe(target: Element | null): Promise<void> {\n this._resolvedTarget = target;\n if (!this._subscribed) {\n this._subscribed = true;\n document.addEventListener(this._pointerLockChangeEventName(), this._onChange);\n }\n this._applyActive();\n return this._ready;\n }\n\n dispose(): void {\n this._gen++; // invalidate any in-flight requestPointerLock() resolution\n if (this._subscribed) {\n this._subscribed = false;\n document.removeEventListener(this._pointerLockChangeEventName(), this._onChange);\n }\n this._resolvedTarget = null;\n }\n\n /**\n * Request pointer lock on `element`. Never-throw: a missing API or a\n * rejected promise (e.g. called outside a user-gesture context —\n * `NotAllowedError`, docs/fullscreen-tag-design.md §3) is captured into\n * `error` rather than propagated. `element` may be `null` when the Shell's\n * `target` selector did not resolve (docs/pointer-lock-tag-design.md §1\n * defers error representation to FullscreenCore verbatim — this null-target\n * case mirrors `FullscreenCore.requestFullscreen(null)`,\n * docs/fullscreen-tag-design.md §6): distinct from \"API is not supported\"\n * below, so a typo'd selector doesn't masquerade as an unsupported platform.\n */\n async requestPointerLock(element: Element | null): Promise<void> {\n const gen = ++this._gen;\n this._resolvedTarget = element;\n if (!element) {\n this._setError({ message: \"Pointer Lock target could not be resolved.\" }, \"invalid-argument\");\n return;\n }\n const fn = this._requestPointerLockFn(element);\n if (!fn) {\n // Resolved synchronously in the same tick as the call — dispose()\n // cannot have run yet, so no staleness check is needed here (matches\n // the reference `requestFullscreen()` implementation,\n // docs/fullscreen-tag-design.md §6).\n this._setError({ message: \"Pointer Lock API is not supported.\" }, \"capability-missing\");\n return;\n }\n try {\n // fn is already bound to `element` by _requestPointerLockFn().\n await fn();\n if (gen !== this._gen) return; // stale\n this._setError(null);\n this._applyActive();\n } catch (e: any) {\n if (gen !== this._gen) return; // stale\n this._setError(e);\n }\n }\n\n /**\n * Exit pointer lock. Synchronous platform API (docs/pointer-lock-tag-design.md\n * §2) — returns `void`, not a `Promise`. Silent no-op when nothing is\n * currently locked or the API is unsupported (mirrors\n * `FullscreenCore.exitFullscreen()`'s no-op contract,\n * docs/fullscreen-tag-design.md §7). Wrapped in try/catch defensively: even\n * though the platform API is synchronous and documented as not throwing in\n * this case, a synchronous throw from a non-conformant/fake implementation\n * must never escape (never-throw).\n */\n exitPointerLock(): void {\n try {\n if (this._pointerLockElement() === null) return; // already unlocked: silent no-op\n const fn = this._exitPointerLockFn();\n if (!fn) return; // unsupported: silent no-op (semantically already \"not locked\")\n fn();\n this._setError(null);\n this._applyActive();\n } catch (e: any) {\n this._setError(e);\n }\n }\n\n // --- API resolution (call-time, never cached — §3.7) ---\n\n // Resolved from `Element.prototype` rather than `el.requestPointerLock`\n // directly: when `target=\"self\"`, `el` is the `<wcs-pointer-lock>` Shell\n // itself, whose own class declares an instance method also named\n // `requestPointerLock()` (the wcBindable command). Reading the property off\n // the instance would pick up that Shell method instead of the native\n // platform API and recurse infinitely (Shell.requestPointerLock() ->\n // Core.requestPointerLock() -> resolves \"el.requestPointerLock\" -> the same\n // Shell method again). Going through `Element.prototype` sidesteps the name\n // collision — note this does NOT pick up an override on a subclass's own\n // prototype (e.g. `WcsPointerLock.prototype`); it deliberately jumps\n // straight to the platform-defined layer. Both the standard and legacy name\n // are resolved the same way, for symmetry — matching FullscreenCore's\n // `_elementFullscreenFn` (docs/fullscreen-tag-design.md §4) ONLY in that one\n // respect. Unlike that Core, this one does not check `el`'s own properties\n // first: there is no test-stub/per-element monkey-patch path to accommodate\n // here (mocks.ts installs the fakes directly on `Element.prototype`), so it\n // goes straight there for both names.\n private _requestPointerLockFn(el: Element): (() => Promise<void>) | undefined {\n const proto = Element.prototype as any;\n const standard = proto.requestPointerLock;\n if (typeof standard === \"function\") return standard.bind(el);\n const legacy = proto.webkitRequestPointerLock;\n return typeof legacy === \"function\" ? legacy.bind(el) : undefined;\n }\n\n private _exitPointerLockFn(): (() => void) | undefined {\n const d = document as any;\n return d.exitPointerLock?.bind(document) ?? d.webkitExitPointerLock?.bind(document);\n }\n\n private _pointerLockElement(): Element | null {\n const d = document as any;\n return d.pointerLockElement ?? d.webkitPointerLockElement ?? null;\n }\n\n // NOTE (test-environment caveat, not a production concern): happy-dom\n // always implements `document.onpointerlockchange` (as `null`) regardless\n // of which fake API surface a test installs, so `\"onpointerlockchange\" in\n // document` can never observably be `false` under this test runner and the\n // `webkitpointerlockchange` branch below cannot be driven through\n // `observe()` in a unit test. The branch is still correct and required for\n // real legacy WebKit builds that lack `onpointerlockchange` entirely — kept\n // as documented, deliberate, untestable-in-this-harness code per\n // docs/pointer-lock-tag-design.md.\n /* v8 ignore next 3 */\n private _pointerLockChangeEventName(): string {\n return \"onpointerlockchange\" in document ? \"pointerlockchange\" : \"webkitpointerlockchange\";\n }\n\n private _onChange = (): void => {\n this._applyActive();\n };\n\n // Self-filter (docs/fullscreen-tag-design.md §2.1): compares against this\n // instance's own resolved target, not merely \"is *something* locked\" — so\n // multiple concurrent instances each report the correct `active` value.\n private _applyActive(): void {\n const next = this._resolvedTarget !== null && this._pointerLockElement() === this._resolvedTarget;\n this._setActive(next);\n }\n\n // Same-value guard (MUST, §3.3 of the guidelines). detail itself is the\n // bare boolean value (no getter needed) per docs/pointer-lock-tag-design.md\n // §2 — unlike FullscreenCore's `{ active }`-shaped detail + getter.\n private _setActive(v: boolean): void {\n if (this._active === v) return;\n this._active = v;\n this._target.dispatchEvent(new CustomEvent(\"wcs-pointer-lock:change\", {\n detail: v,\n bubbles: true,\n }));\n }\n\n // `kind` is an explicit taxonomy discriminator passed only from the synthetic\n // error sites (unsupported / unresolved target); caught exceptions pass no kind\n // and are classified by their `.name`. Both `error` and the additive `errorInfo`\n // are now event-backed so a request/exit failure is observable via bind().\n private _setError(error: any, kind?: PointerLockErrorKind): void {\n // Same-value guard on reference: each failure builds a fresh object and the\n // clear path passes the literal null, so this only suppresses redundant\n // null→null (a successful request/exit clearing an already-null error).\n if (this._error === error) return;\n this._error = error;\n // Keep the additive errorInfo taxonomy in sync; fire it before the `error`\n // event so an observer of both sees the classification first (io-node family).\n this._commitErrorInfo(error === null ? null : derivePointerLockErrorInfo(error, kind));\n this._target.dispatchEvent(new CustomEvent(\"wcs-pointer-lock:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n // Called only from _setError (already reference-guarded), so errorInfo\n // transitions exactly when error does — no separate guard needed here.\n private _commitErrorInfo(info: WcsIoErrorInfo | null): void {\n this._errorInfo = info;\n this._target.dispatchEvent(new CustomEvent(\"wcs-pointer-lock:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { PointerLockCore } from \"../core/PointerLockCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\n\n/**\n * `<wcs-pointer-lock target=\"...\">` — declarative Pointer Lock API control.\n *\n * Like `<wcs-fullscreen>` (docs/fullscreen-tag-design.md §0), this Shell does\n * not lock itself — it operates on a *referenced* element via the `target`\n * attribute, using the same 3-mode resolution rule as `intersection`\n * (`_resolveTarget()`/`_safeQuery()`, copied verbatim per\n * docs/pointer-lock-tag-design.md §1 / docs/fullscreen-tag-design.md §1):\n *\n * | `target` | operates on | display |\n * |-----------------|-------------------------|-------------|\n * | omitted | first element child | `contents` |\n * | `\"#selector\"` | the matched element | `none` |\n * | `\"self\"` | the element itself | `block` |\n *\n * `requestPointerLock()` requires a user-gesture context (docs/fullscreen-tag-design.md\n * §3) — the primary activation path is the command-token protocol\n * (`command.requestPointerLock: $command.<token>` on `<wcs-pointer-lock>`,\n * emitted by a button's `onclick: $command.<token>`), not an\n * autoTrigger attribute (none is provided in v1,\n * docs/pointer-lock-tag-design.md §4).\n *\n * `movementX`/`movementY` are intentionally out of scope for v1\n * (docs/pointer-lock-tag-design.md §3) — do not add them without revisiting\n * the design doc.\n */\nexport class WcsPointerLock extends HTMLElement {\n // SSR (§4.4): the Core subscribes synchronously on connect, but the Shell\n // still exposes connectedCallbackPromise so the state binder can await it\n // uniformly across all IO nodes before snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static observedAttributes = [\"target\"];\n\n static wcBindable: IWcBindable = {\n ...PointerLockCore.wcBindable,\n inputs: [{ name: \"target\", attribute: \"target\" }],\n // Core の commands をそのまま継承(単一情報源)。network/intersection と同型。\n commands: PointerLockCore.wcBindable.commands,\n };\n\n private _core: PointerLockCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new PointerLockCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-pointer-lock:change\": (d) => ({ active: d === true }),\n });\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (docs/custom-state-reflection-design.md §3.6): attachInternals\n // is absent in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n // --- Core delegated getters ---\n\n get active(): boolean {\n return this._core.active;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get errorInfo(): WcsIoErrorInfo | null {\n return this._core.errorInfo;\n }\n\n // --- Commands ---\n\n /**\n * Resolve `target` and request pointer lock on it. Requires a user-gesture\n * context. never-throw: an unresolvable target or an unsupported/rejected\n * API call are both surfaced via `error`, never thrown (mirrors\n * `<wcs-fullscreen>`'s `requestFullscreen()`, docs/fullscreen-tag-design.md\n * §3/§6 — the Shell passes the (possibly `null`) resolved element straight\n * through and lets the Core set `error`, rather than silently no-op'ing\n * here).\n */\n async requestPointerLock(): Promise<void> {\n const { element } = this._resolveTarget();\n await this._core.requestPointerLock(element);\n }\n\n /** Exit pointer lock. Synchronous command — silent no-op if nothing is locked. */\n exitPointerLock(): void {\n this._core.exitPointerLock();\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this._applyDisplayAndObserve();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n\n attributeChangedCallback(name: string): void {\n if (name === \"target\" && this.isConnected) {\n this._applyDisplayAndObserve();\n }\n }\n\n // --- Internal ---\n\n private _applyDisplayAndObserve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n this._connectedCallbackPromise = this._core.observe(element);\n }\n\n // Copied verbatim from packages/intersection/src/components/Intersect.ts\n // (§1 of docs/pointer-lock-tag-design.md / docs/fullscreen-tag-design.md).\n private _resolveTarget(): { element: Element | null; display: string } {\n const target = this.target;\n if (target === \"self\") {\n return { element: this, display: \"block\" };\n }\n if (target !== \"\") {\n const scope = this.getRootNode() as Document | ShadowRoot;\n return { element: this._safeQuery(scope, target), display: \"none\" };\n }\n const child = this.firstElementChild;\n if (child) {\n return { element: child, display: \"contents\" };\n }\n return { element: this, display: \"block\" };\n }\n\n // Copied verbatim from packages/intersection/src/components/Intersect.ts.\n private _safeQuery(scope: Document | ShadowRoot, selector: string): Element | null {\n try {\n return scope.querySelector(selector);\n } catch {\n return null;\n }\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapPointerLock(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsPointerLock } from \"./components/PointerLock.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.pointerLock)) {\n customElements.define(config.tagNames.pointerLock, WcsPointerLock);\n }\n}\n"],"names":["_config","tagNames","pointerLock","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","WCS_POINTER_LOCK_ERROR_CODE","CapabilityMissing","InvalidArgument","NotAllowed","PointerLockError","derivePointerLockErrorInfo","error","kind","message","String","messageOf","code","phase","recoverable","name","PointerLockCore","EventTarget","static","protocol","version","properties","event","commands","async","_target","_active","_error","_errorInfo","_resolvedTarget","_subscribed","_gen","_ready","Promise","resolve","constructor","target","super","this","ready","active","errorInfo","observe","document","addEventListener","_pointerLockChangeEventName","_onChange","_applyActive","dispose","removeEventListener","requestPointerLock","element","gen","_setError","fn","_requestPointerLockFn","e","exitPointerLock","_pointerLockElement","_exitPointerLockFn","el","proto","Element","prototype","standard","bind","legacy","webkitRequestPointerLock","undefined","d","webkitExitPointerLock","pointerLockElement","webkitPointerLockElement","next","_setActive","v","dispatchEvent","CustomEvent","detail","bubbles","_commitErrorInfo","info","WcsPointerLock","HTMLElement","wcBindable","inputs","attribute","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","connectedCallbackPromise","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","getAttribute","value","setAttribute","_resolveTarget","connectedCallback","_applyDisplayAndObserve","disconnectedCallback","attributeChangedCallback","isConnected","display","style","scope","getRootNode","_safeQuery","child","firstElementChild","selector","querySelector","bootstrapPointerLock","userConfig","partialConfig","assign","customElements","get","define"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/pointer-lock",
3
- "version": "1.19.1",
3
+ "version": "1.21.0",
4
4
  "description": "Declarative Pointer Lock component for Web Components. Framework-agnostic Pointer Lock API control via wc-bindable-protocol.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",