@wcstack/pointer-lock 1.30.0 → 1.32.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
@@ -208,6 +208,10 @@ lock.dispose(); // document リスナーを外す
208
208
 
209
209
  Core の構造サーフェスは wcstack I/O ノード横断の規範です([async-io-node-guidelines §3.9](../../docs/async-io-node-guidelines.ja.md))。要素なしで signals に束縛するには [@wcstack/signals — Core を直接束縛する](../signals/README.ja.md#core-を直接束縛する要素なし) を参照。
210
210
 
211
+ ## アクセシビリティ
212
+
213
+ **WCAG 2.1.2 No Keyboard Trap(キーボードトラップなし)**: Esc でロックが必ず解除されることはブラウザが保証する — このキーを別用途に奪ってはならない。ただし、ユーザーが知らない保証付き脱出口は半分しか脱出口ではない: ロックが掛かる*前*に抜け方を伝え、アプリ内の出口(`exitPointerLock` コマンドを配線した可視のコントロール)も用意すること。ロック中の説明はポインタ操作なしで読める状態を保つ。
214
+
211
215
  ## ライセンス
212
216
 
213
217
  MIT
package/README.md CHANGED
@@ -211,6 +211,10 @@ lock.dispose(); // detach the document listener
211
211
 
212
212
  The structural Core surface is normative across wcstack IO nodes ([async-io-node-guidelines §3.9](../../docs/async-io-node-guidelines.md)); to bind it into signals with no element at all, see [@wcstack/signals — Binding a Core directly](../signals/README.md#binding-a-core-directly-no-element).
213
213
 
214
+ ## Accessibility
215
+
216
+ **WCAG 2.1.2 No Keyboard Trap**: the browser guarantees that Esc always releases the pointer lock — never repurpose or intercept that key. But a guaranteed escape hatch the user does not know about is only half an escape hatch: tell the user how to leave *before* the lock engages, and offer an in-app exit as well (a visible control wired to the `exitPointerLock` command). While locked, keep any instructions readable without pointer interaction.
217
+
214
218
  ## License
215
219
 
216
220
  MIT
package/dist/auto.min.js CHANGED
@@ -1,2 +1,2 @@
1
- const e={tagNames:{pointerLock:"wcs-pointer-lock"}},t="capability-missing",r="invalid-argument",n="not-allowed",s="pointer-lock-error";function i(e,i){const o=function(e){return"string"==typeof e?.message?e.message:String(e)}(e);if("capability-missing"===i)return{code:t,phase:"probe",recoverable:!1,message:o};if("invalid-argument"===i)return{code:r,phase:"start",recoverable:!1,message:o};const c=e?.name;return"NotAllowedError"===c||"TypeError"===c?{code:n,phase:"execute",recoverable:!0,message:o}:{code:s,phase:"execute",recoverable:!1,message:o}}class o extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"active",event:"wcs-pointer-lock:change",semantics:"state"},{name:"error",event:"wcs-pointer-lock:error",semantics:"state"},{name:"errorInfo",event:"wcs-pointer-lock:error-info-changed",semantics:"state"}],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:i(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}))}}function c(e,t){let r=Object.getPrototypeOf(e);for(;null!==r;){const e=Object.getOwnPropertyDescriptor(r,t);if(void 0!==e)return"function"==typeof e.get||"function"==typeof e.set;r=Object.getPrototypeOf(r)}return!1}class a 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":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(){!function(e){const t=e.constructor?.wcBindable,r=t?.inputs;if(void 0!==r)for(const t of r){const r=t.name;if(!Object.prototype.hasOwnProperty.call(e,r))continue;if(!c(e,r))continue;const n=e,s=n[r];delete n[r],n[r]=s}}(this),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}}}customElements.get(e.tagNames.pointerLock)||customElements.define(e.tagNames.pointerLock,a);
1
+ const e={tagNames:{pointerLock:"wcs-pointer-lock"}},t="capability-missing",r="invalid-argument",n="not-allowed",s="pointer-lock-error";function i(e,i){const o=function(e){return"string"==typeof e?.message?e.message:String(e)}(e);if("capability-missing"===i)return{code:t,phase:"probe",recoverable:!1,message:o};if("invalid-argument"===i)return{code:r,phase:"start",recoverable:!1,message:o};const c=e?.name;return"NotAllowedError"===c||"TypeError"===c?{code:n,phase:"execute",recoverable:!0,message:o}:{code:s,phase:"execute",recoverable:!1,message:o}}class o extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"active",event:"wcs-pointer-lock:change",semantics:"state"},{name:"error",event:"wcs-pointer-lock:error",semantics:"state"},{name:"errorInfo",event:"wcs-pointer-lock:error-info-changed",semantics:"state"}],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:i(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}))}}function c(e,t){let r=Object.getPrototypeOf(e);for(;null!==r;){const e=Object.getOwnPropertyDescriptor(r,t);if(void 0!==e)return"function"==typeof e.get||"function"==typeof e.set;r=Object.getPrototypeOf(r)}return!1}class a 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":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(){!function(e){const t=e.constructor?.wcBindable,r=t?.inputs;if(void 0!==r)for(const t of r){const r=t.name;if(!Object.prototype.hasOwnProperty.call(e,r))continue;if(!c(e,r))continue;const n=e,s=n[r];delete n[r],n[r]=s}}(this),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}}}var l;!function(t=customElements){t.get(e.tagNames.pointerLock)||t.define(e.tagNames.pointerLock,a)}(l);
2
2
  //# sourceMappingURL=auto.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auto.min.js","sources":["../src/config.ts","../src/core/pointerLockCapabilities.ts","../src/core/PointerLockCore.ts","../src/protocol/upgradeProperties.ts","../src/components/PointerLock.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\", semantics: \"state\" },\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\", semantics: \"state\" },\n { name: \"errorInfo\", event: \"wcs-pointer-lock:error-info-changed\", semantics: \"state\" },\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","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n for (const input of inputs) {\n const name = input.name;\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { PointerLockCore } from \"../core/PointerLockCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.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 // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\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"],"names":["config","tagNames","pointerLock","WCS_POINTER_LOCK_ERROR_CODE","derivePointerLockErrorInfo","error","kind","message","String","messageOf","code","phase","recoverable","name","PointerLockCore","EventTarget","static","protocol","version","properties","event","semantics","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","hasAccessorOnPrototype","Object","getPrototypeOf","descriptor","getOwnPropertyDescriptor","get","set","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","declaration","input","hasOwnProperty","call","record","upgradeProperties","_applyDisplayAndObserve","disconnectedCallback","attributeChangedCallback","isConnected","display","style","scope","getRootNode","_safeQuery","child","firstElementChild","selector","querySelector","customElements","define"],"mappings":"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"}
1
+ {"version":3,"file":"auto.min.js","sources":["../src/config.ts","../src/core/pointerLockCapabilities.ts","../src/core/PointerLockCore.ts","../src/protocol/upgradeProperties.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\", semantics: \"state\" },\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\", semantics: \"state\" },\n { name: \"errorInfo\", event: \"wcs-pointer-lock:error-info-changed\", semantics: \"state\" },\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","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n for (const input of inputs) {\n const name = input.name;\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { PointerLockCore } from \"../core/PointerLockCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.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 // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\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, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n","import { WcsPointerLock } from \"./components/PointerLock.js\";\nimport { config } from \"./config.js\";\n\n/**\n * Register this package's tags. Pass a scoped `CustomElementRegistry` to define\n * them for a single shadow tree -- scoped registries do not inherit the global\n * one, so a tree using one needs its own definitions.\n */\nexport function registerComponents(registry: CustomElementRegistry = customElements): void {\n if (!registry.get(config.tagNames.pointerLock)) {\n registry.define(config.tagNames.pointerLock, WcsPointerLock);\n }\n}\n"],"names":["config","tagNames","pointerLock","WCS_POINTER_LOCK_ERROR_CODE","derivePointerLockErrorInfo","error","kind","message","String","messageOf","code","phase","recoverable","name","PointerLockCore","EventTarget","static","protocol","version","properties","event","semantics","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","hasAccessorOnPrototype","Object","getPrototypeOf","descriptor","getOwnPropertyDescriptor","get","set","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","declaration","input","hasOwnProperty","call","record","upgradeProperties","_applyDisplayAndObserve","disconnectedCallback","attributeChangedCallback","isConnected","display","style","scope","getRootNode","_safeQuery","child","firstElementChild","selector","querySelector","registry","customElements","define","registerComponents"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -89,7 +89,7 @@ interface WcsPointerLockCoreValues {
89
89
  */
90
90
  type WcsPointerLockValues = WcsPointerLockCoreValues;
91
91
 
92
- declare function bootstrapPointerLock(userConfig?: IWritableConfig): void;
92
+ declare function bootstrapPointerLock(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void;
93
93
 
94
94
  declare function getConfig(): IConfig;
95
95
 
package/dist/index.esm.js CHANGED
@@ -592,17 +592,22 @@ class WcsPointerLock extends HTMLElement {
592
592
  }
593
593
  }
594
594
 
595
- function registerComponents() {
596
- if (!customElements.get(config.tagNames.pointerLock)) {
597
- customElements.define(config.tagNames.pointerLock, WcsPointerLock);
595
+ /**
596
+ * Register this package's tags. Pass a scoped `CustomElementRegistry` to define
597
+ * them for a single shadow tree -- scoped registries do not inherit the global
598
+ * one, so a tree using one needs its own definitions.
599
+ */
600
+ function registerComponents(registry = customElements) {
601
+ if (!registry.get(config.tagNames.pointerLock)) {
602
+ registry.define(config.tagNames.pointerLock, WcsPointerLock);
598
603
  }
599
604
  }
600
605
 
601
- function bootstrapPointerLock(userConfig) {
606
+ function bootstrapPointerLock(userConfig, registry) {
602
607
  if (userConfig) {
603
608
  setConfig(userConfig);
604
609
  }
605
- registerComponents();
610
+ registerComponents(registry);
606
611
  }
607
612
 
608
613
  export { PointerLockCore, WCS_POINTER_LOCK_ERROR_CODE, WcsPointerLock, bootstrapPointerLock, getConfig };
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/pointerLockCapabilities.ts","../src/core/PointerLockCore.ts","../src/protocol/upgradeProperties.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\", semantics: \"state\" },\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\", semantics: \"state\" },\n { name: \"errorInfo\", event: \"wcs-pointer-lock:error-info-changed\", semantics: \"state\" },\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","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n for (const input of inputs) {\n const name = input.name;\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { PointerLockCore } from \"../core/PointerLockCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.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 // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\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/protocol/upgradeProperties.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\", semantics: \"state\" },\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\", semantics: \"state\" },\n { name: \"errorInfo\", event: \"wcs-pointer-lock:error-info-changed\", semantics: \"state\" },\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","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n for (const input of inputs) {\n const name = input.name;\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { PointerLockCore } from \"../core/PointerLockCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.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 // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\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\n/**\n * Register this package's tags. Pass a scoped `CustomElementRegistry` to define\n * them for a single shadow tree -- scoped registries do not inherit the global\n * one, so a tree using one needs its own definitions.\n */\nexport function registerComponents(registry: CustomElementRegistry = customElements): void {\n if (!registry.get(config.tagNames.pointerLock)) {\n registry.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, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/pointer-lock",
3
- "version": "1.30.0",
3
+ "version": "1.32.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",