@wcstack/fullscreen 1.20.0 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +8 -6
- package/README.md +9 -7
- package/dist/index.d.ts +59 -10
- package/dist/index.esm.js +100 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
`@wcstack/state` と組み合わせると、`<wcs-fullscreen>` はパス契約で直接バインドできます:
|
|
9
9
|
|
|
10
10
|
- **入力サーフェス**: `target`(操作対象の要素。下記参照)
|
|
11
|
-
- **出力 state サーフェス**: `active`、`error`
|
|
11
|
+
- **出力 state サーフェス**: `active`、`error`、`errorInfo`
|
|
12
12
|
- **コマンド**: `requestFullscreen()`、`exitFullscreen()`
|
|
13
13
|
|
|
14
14
|
`@wcstack/fullscreen` は [CSBC](https://github.com/csbc-dev/arch/blob/main/README.md)(Core / Shell / Binding Contract)アーキテクチャに従います:
|
|
15
15
|
|
|
16
16
|
- **Core**(`FullscreenCore`)が Fullscreen API を操作し、`document` の `fullscreenchange` イベントを追従
|
|
17
17
|
- **Shell**(`<wcs-fullscreen target="...">`)が `target` を DOM 要素へ解決し、Core の state を DOM ライフサイクルに接続
|
|
18
|
-
- **Binding Contract**(`static wcBindable`)が観測可能な `active` プロパティと `requestFullscreen`/`exitFullscreen` コマンドを宣言
|
|
18
|
+
- **Binding Contract**(`static wcBindable`)が観測可能な `active` / `error` / `errorInfo` プロパティと `requestFullscreen`/`exitFullscreen` コマンドを宣言
|
|
19
19
|
|
|
20
20
|
## なぜ存在するか — 操作対象は「タグ自身」ではなく「参照先」
|
|
21
21
|
|
|
@@ -81,7 +81,8 @@ npm install @wcstack/fullscreen
|
|
|
81
81
|
| プロパティ | イベント | 説明 |
|
|
82
82
|
| ----------- | ------------------------ | ---- |
|
|
83
83
|
| `active` | `wcs-fullscreen:change` | `document.fullscreenElement` が**このインスタンスが解決したtarget**と一致している間 `true`、それ以外は `false`。 |
|
|
84
|
-
| `error` |
|
|
84
|
+
| `error` | `wcs-fullscreen:error` | 直近の失敗: rejectされたPromise(gesture外呼び出しなら `TypeError` 等)、プラットフォームAPI非対応なら `{ message: "Fullscreen API is not supported." }`、`target` が要素へ未解決なら `{ message: "Fullscreen target could not be resolved." }`。直近の呼び出しが成功済み・まだ何も失敗していない場合は `null`。 |
|
|
85
|
+
| `errorInfo` | `wcs-fullscreen:error-info-changed` | `error` から導出した serializable な失敗 taxonomy(`WcsIoErrorInfo`: 安定 `code` / `phase` / `recoverable`)、または `null`。additive で `error` の値の形は不変。 |
|
|
85
86
|
|
|
86
87
|
## コマンド
|
|
87
88
|
|
|
@@ -107,8 +108,9 @@ npm install @wcstack/fullscreen
|
|
|
107
108
|
|----------|----------------|
|
|
108
109
|
| `active` | `wcs-fullscreen:change` が `detail.active === true` で発火(`active: false` でクリア) |
|
|
109
110
|
|
|
110
|
-
`error`
|
|
111
|
-
|
|
111
|
+
`error` / `errorInfo` は observable(各自のイベントで `data-wcs` バインド可 — 上記
|
|
112
|
+
「観測可能プロパティ」参照)ですが、`:state()` には反映**しません**: 失敗オブジェクトは
|
|
113
|
+
boolean ステートではないため、boolean の `:state()` 反映で表現するものがありません。
|
|
112
114
|
|
|
113
115
|
```css
|
|
114
116
|
wcs-fullscreen:state(active) ~ .exit-hint { display: block; }
|
|
@@ -153,7 +155,7 @@ wcs-fullscreen:state(active) ~ .exit-hint { display: none; } /* デフォルト
|
|
|
153
155
|
- **ベンダープレフィックス。** 一部の古いSafariバージョンは `webkitRequestFullscreen` / `webkitExitFullscreen` / `webkitFullscreenElement` / `webkitfullscreenchange` のみを実装しています。Coreは標準名を優先的にプローブし、**呼び出しの都度**(非キャッシュ)レガシー名にフォールバックするため、両方とも透過的にサポートされます。
|
|
154
156
|
- **複数インスタンス。** `document.fullscreenElement` はdocument全体で単一の値です。異なるtargetを指す複数の `<wcs-fullscreen>` インスタンスが存在する場合、`target` が `document.fullscreenElement` と一致するインスタンスのみが `active: true` を報告し、他は正しく `false` を報告します。各インスタンスは内部で**自分自身が解決したtarget**を追跡しており、単純に「何かがfullscreenかどうか」をミラーしているわけではありません。ただし非対称な点に注意: `exitFullscreen()` はインスタンス単位にスコープされて**いません** — document全体に作用する `document.exitFullscreen()` を呼ぶため、どのインスタンスから呼んでも、現在fullscreenの要素(別インスタンスの `target` がfullscreen化した要素であっても)を解除します(silent no-opの判定も同様にdocument全体の「何かがfullscreenか」であり、「自分のtargetがfullscreenか」ではありません)。これはプラットフォームAPI自体の挙動をそのまま反映したものです。
|
|
155
157
|
- **`exitFullscreen()` は安全なno-op。** 何もfullscreenでない状態(またはAPI非対応)で呼び出してもエラーなくresolveします — 失敗しうる事前条件チェックではなく、べき等な「fullscreenでないことを保証する」コマンドとして扱われます。
|
|
156
|
-
- **`error`
|
|
158
|
+
- **`error` / `errorInfo` は observable(バインド可)。** 両者は専用イベント(`wcs-fullscreen:error` / `wcs-fullscreen:error-info-changed`)付きで `static wcBindable.properties` に宣言されているため、バインディング側が request/exit の失敗をリアクティブに観測できます(`data-wcs="error: fsError; errorInfo: fsErrorInfo"`)。もちろんコマンドの Promise settle 後に `element.error` / `element.errorInfo` を命令的に読み取ることもできます。`errorInfo` は `error` から導出した**additive** な serializable 失敗 taxonomy(`WcsIoErrorInfo`: `code` / `phase` / `recoverable`、`error` の値の形は不変)。API 非対応(`"…is not supported."`)→ `capability-missing`(phase `probe`)、`target` 未解決 → `invalid-argument`(phase `start`)、gesture 外拒否(`TypeError` / `NotAllowedError`)→ `not-allowed`(phase `execute`、`recoverable: true` — 実 gesture 内で再試行すれば成功しうる)、その他 → `fullscreen-error`(phase `execute`)。`errorInfo` は `error` と厳密に同期し(成功で `null` にクリア)、`WcsIoErrorInfo` 型と `WCS_FULLSCREEN_ERROR_CODE` 定数は export 済み。
|
|
157
159
|
- **`_gen` 世代ガード。** `dispose()` 後(または後続の呼び出しに追い越された後)にsettleした進行中の `requestFullscreen()`/`exitFullscreen()` 呼び出しは、破棄済みの状態を書き換えません。
|
|
158
160
|
- **SSR(`@wcstack/server`)。** `static hasConnectedCallbackPromise = true` を宣言し `connectedCallbackPromise` を公開しますが、`fullscreenchange` の購読が同期的なため、この promise は常に即座に settle します。
|
|
159
161
|
|
package/README.md
CHANGED
|
@@ -8,14 +8,14 @@ It is a **control node**: unlike most wcstack IO nodes (which act on themselves)
|
|
|
8
8
|
With `@wcstack/state`, `<wcs-fullscreen>` can be bound directly through path contracts:
|
|
9
9
|
|
|
10
10
|
- **input surface**: `target` (which element to operate on — see below)
|
|
11
|
-
- **output state surface**: `active`, `error`
|
|
11
|
+
- **output state surface**: `active`, `error`, `errorInfo`
|
|
12
12
|
- **commands**: `requestFullscreen()`, `exitFullscreen()`
|
|
13
13
|
|
|
14
14
|
`@wcstack/fullscreen` follows the [CSBC](https://github.com/csbc-dev/arch/blob/main/README.md) (Core / Shell / Binding Contract) architecture:
|
|
15
15
|
|
|
16
16
|
- **Core** (`FullscreenCore`) drives the Fullscreen API and tracks `document`'s `fullscreenchange` event
|
|
17
17
|
- **Shell** (`<wcs-fullscreen target="...">`) resolves `target` to a DOM element and connects Core state to DOM lifecycle
|
|
18
|
-
- **Binding Contract** (`static wcBindable`) declares the observable `active`
|
|
18
|
+
- **Binding Contract** (`static wcBindable`) declares the observable `active` / `error` / `errorInfo` properties and the `requestFullscreen`/`exitFullscreen` commands
|
|
19
19
|
|
|
20
20
|
## Why this exists — you operate on the *target*, not on the tag itself
|
|
21
21
|
|
|
@@ -81,7 +81,8 @@ Every bound state path must be declared up front — `isFullscreen: false` here;
|
|
|
81
81
|
| Property | Event | Description |
|
|
82
82
|
| --------- | ---------------------- | ------------ |
|
|
83
83
|
| `active` | `wcs-fullscreen:change` | `true` while `document.fullscreenElement` is *this instance's resolved target*; `false` otherwise. |
|
|
84
|
-
| `error` |
|
|
84
|
+
| `error` | `wcs-fullscreen:error` | The most recent failure: a rejected promise (e.g. a `TypeError` for a gesture-less call), `{ message: "Fullscreen API is not supported." }` when the platform API is missing, `{ message: "Fullscreen target could not be resolved." }` when `target` did not resolve to an element, or `null` if the last attempt succeeded / nothing has failed yet. |
|
|
85
|
+
| `errorInfo` | `wcs-fullscreen:error-info-changed` | Serializable failure taxonomy (`WcsIoErrorInfo`: stable `code` / `phase` / `recoverable`) derived from `error`, or `null`. Additive — the `error` value shape is unchanged. |
|
|
85
86
|
|
|
86
87
|
## Commands
|
|
87
88
|
|
|
@@ -107,9 +108,10 @@ so you can style it directly from CSS with the `:state()` pseudo-class — no
|
|
|
107
108
|
|-------|---------|
|
|
108
109
|
| `active` | `wcs-fullscreen:change` fires with `detail.active === true` (cleared when `active: false`) |
|
|
109
110
|
|
|
110
|
-
`error`
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
`error` / `errorInfo` are observable (`data-wcs` bindable via their own events —
|
|
112
|
+
see the Observable Properties table above), but they are **not** reflected onto
|
|
113
|
+
`:state()`: a failure object is not a boolean state, so there is nothing for the
|
|
114
|
+
boolean `:state()` reflection to represent.
|
|
113
115
|
|
|
114
116
|
```css
|
|
115
117
|
wcs-fullscreen:state(active) ~ .exit-hint { display: block; }
|
|
@@ -156,7 +158,7 @@ DevTools open; it is not a supported styling hook.
|
|
|
156
158
|
- **Vendor prefixes.** Some older Safari versions only implement `webkitRequestFullscreen` / `webkitExitFullscreen` / `webkitFullscreenElement` / `webkitfullscreenchange`. The Core probes the standard name first and falls back to the legacy name at *call time* (never cached), so both are supported transparently.
|
|
157
159
|
- **Multiple instances.** `document.fullscreenElement` is a single, document-wide value. If you have several `<wcs-fullscreen>` instances pointed at different targets, only the instance whose `target` matches `document.fullscreenElement` reports `active: true` — the others correctly report `false`. Each instance tracks *its own* resolved target internally; it does not simply mirror "is anything fullscreen". Note the asymmetry: `exitFullscreen()` is **not** scoped per instance — it calls the document-global `document.exitFullscreen()`, so invoking it on any instance exits whatever element is currently fullscreen, even one put there by another instance's `target` (its silent no-op check is likewise document-wide: "is anything fullscreen", not "is *my* target fullscreen"). This mirrors the platform API itself.
|
|
158
160
|
- **`exitFullscreen()` is a safe no-op.** Calling it when nothing is fullscreen (or when the API is unsupported) resolves without error — it is treated as an idempotent "make sure we're not fullscreen" command, not a failable precondition check.
|
|
159
|
-
- **`error`
|
|
161
|
+
- **`error` / `errorInfo` are observable (bindable).** Both are declared in `static wcBindable.properties` with their own events (`wcs-fullscreen:error` / `wcs-fullscreen:error-info-changed`), so a binding system can observe a request/exit failure reactively (`data-wcs="error: fsError; errorInfo: fsErrorInfo"`) — or you can still read `element.error` / `element.errorInfo` imperatively after a command's promise settles. `errorInfo` is the **additive** serializable failure taxonomy derived from `error`: a stable `WcsIoErrorInfo` (`code` / `phase` / `recoverable`) without changing the `error` value shape. A missing API (`"…is not supported."`) → `capability-missing` (phase `probe`); an unresolved `target` → `invalid-argument` (phase `start`); a gesture-less rejection (`TypeError` / `NotAllowedError`) → `not-allowed` (phase `execute`, `recoverable: true` — a retry from within a genuine user gesture may succeed); anything else → `fullscreen-error` (phase `execute`). `errorInfo` transitions exactly when `error` does (cleared to `null` on success); the `WcsIoErrorInfo` type and the `WCS_FULLSCREEN_ERROR_CODE` constants are exported.
|
|
160
162
|
- **`_gen` generation guard.** In-flight `requestFullscreen()`/`exitFullscreen()` calls that settle after `dispose()` (or after a superseding call) do not write to torn-down state.
|
|
161
163
|
- **SSR (`@wcstack/server`).** Declares `static hasConnectedCallbackPromise = true` and exposes `connectedCallbackPromise`, though since subscribing to `fullscreenchange` is synchronous this promise always settles immediately.
|
|
162
164
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/** operation error の phase(taxonomy)。 */
|
|
2
|
+
type WcsIoErrorPhase = "probe" | "start" | "execute" | "decode" | "commit" | "dispose";
|
|
3
|
+
/** serializable な error info(non-cloneable な cause とは分離。DevTools / remote へは info のみ)。 */
|
|
4
|
+
interface WcsIoErrorInfo {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
readonly phase: WcsIoErrorPhase;
|
|
7
|
+
readonly recoverable: boolean;
|
|
8
|
+
readonly capabilityId?: string;
|
|
9
|
+
readonly message: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
1
12
|
interface IWcBindableProperty {
|
|
2
13
|
readonly name: string;
|
|
3
14
|
readonly event: string;
|
|
@@ -13,7 +24,8 @@ interface IWcBindableCommand {
|
|
|
13
24
|
}
|
|
14
25
|
interface IWcBindable {
|
|
15
26
|
readonly protocol: "wc-bindable";
|
|
16
|
-
|
|
27
|
+
/** Integer protocol version. All versions >= 1 are core-compatible. */
|
|
28
|
+
readonly version: number;
|
|
17
29
|
readonly properties: readonly IWcBindableProperty[];
|
|
18
30
|
readonly inputs?: readonly IWcBindableInput[];
|
|
19
31
|
readonly commands?: readonly IWcBindableCommand[];
|
|
@@ -34,26 +46,27 @@ interface IWritableConfig {
|
|
|
34
46
|
|
|
35
47
|
/**
|
|
36
48
|
* Value types for FullscreenCore (headless) — the Core's readable value
|
|
37
|
-
* surface.
|
|
38
|
-
* `wcBindable.properties` with
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* (docs/fullscreen-tag-design.md §8, README
|
|
49
|
+
* surface. `active`, `error`, and `errorInfo` are all *observable* (declared in
|
|
50
|
+
* `wcBindable.properties` with change events: `wcs-fullscreen:change` /
|
|
51
|
+
* `:error` / `:error-info-changed`), so a wc-bindable binding core delivers a
|
|
52
|
+
* request/exit failure. `errorInfo` is the additive serializable failure
|
|
53
|
+
* taxonomy derived from `error` (docs/fullscreen-tag-design.md §8, README).
|
|
42
54
|
*
|
|
43
55
|
* @example
|
|
44
56
|
* ```typescript
|
|
45
57
|
* const core = new FullscreenCore();
|
|
46
|
-
* // bind() only ever delivers "active" — see the note above about "error".
|
|
47
58
|
* bind(core, (name: keyof WcsFullscreenCoreValues, value) => { ... });
|
|
48
59
|
* ```
|
|
49
60
|
*/
|
|
50
61
|
interface WcsFullscreenCoreValues {
|
|
51
62
|
active: boolean;
|
|
52
63
|
error: any;
|
|
64
|
+
/** Additive failure taxonomy derived from `error` (stable code / phase / recoverable). */
|
|
65
|
+
errorInfo: WcsIoErrorInfo | null;
|
|
53
66
|
}
|
|
54
67
|
/**
|
|
55
68
|
* Value types for the Shell (`<wcs-fullscreen target="...">`) — identical
|
|
56
|
-
* value surface to the Core (
|
|
69
|
+
* value surface to the Core (`active` / `error` / `errorInfo` all observable).
|
|
57
70
|
* The Shell adds the `target` input (attribute-mirrored) that resolves which
|
|
58
71
|
* element requestFullscreen()/exitFullscreen() operate on
|
|
59
72
|
* (docs/fullscreen-tag-design.md §1/§9).
|
|
@@ -84,6 +97,7 @@ declare class FullscreenCore extends EventTarget {
|
|
|
84
97
|
private _target;
|
|
85
98
|
private _active;
|
|
86
99
|
private _error;
|
|
100
|
+
private _errorInfo;
|
|
87
101
|
private _resolvedTarget;
|
|
88
102
|
private _gen;
|
|
89
103
|
private _subscribed;
|
|
@@ -92,6 +106,13 @@ declare class FullscreenCore extends EventTarget {
|
|
|
92
106
|
get ready(): Promise<void>;
|
|
93
107
|
get active(): boolean;
|
|
94
108
|
get error(): any;
|
|
109
|
+
/**
|
|
110
|
+
* The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /
|
|
111
|
+
* `recoverable`), or null. Additive wc-bindable property (event
|
|
112
|
+
* `wcs-fullscreen:error-info-changed`), derived from `error`; the existing
|
|
113
|
+
* `error` value shape is unchanged.
|
|
114
|
+
*/
|
|
115
|
+
get errorInfo(): WcsIoErrorInfo | null;
|
|
95
116
|
/**
|
|
96
117
|
* Update the resolved target without issuing a fullscreen request (e.g. the
|
|
97
118
|
* Shell re-resolves `target` on attribute change / connect). Re-evaluates
|
|
@@ -126,6 +147,7 @@ declare class FullscreenCore extends EventTarget {
|
|
|
126
147
|
private _applyActive;
|
|
127
148
|
private _setActive;
|
|
128
149
|
private _setError;
|
|
150
|
+
private _commitErrorInfo;
|
|
129
151
|
}
|
|
130
152
|
|
|
131
153
|
/**
|
|
@@ -165,6 +187,7 @@ declare class WcsFullscreen extends HTMLElement {
|
|
|
165
187
|
set target(value: string);
|
|
166
188
|
get active(): boolean;
|
|
167
189
|
get error(): any;
|
|
190
|
+
get errorInfo(): WcsIoErrorInfo | null;
|
|
168
191
|
/**
|
|
169
192
|
* Resolve `target` and request fullscreen on it. never-throw: an
|
|
170
193
|
* unresolvable target or an unsupported/rejected API call are both
|
|
@@ -180,5 +203,31 @@ declare class WcsFullscreen extends HTMLElement {
|
|
|
180
203
|
attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
|
|
181
204
|
}
|
|
182
205
|
|
|
183
|
-
|
|
184
|
-
|
|
206
|
+
/**
|
|
207
|
+
* fullscreenCapabilities.ts
|
|
208
|
+
*
|
|
209
|
+
* Fullscreen node 固有の error code(taxonomy)と derivation。汎用の error info 型は
|
|
210
|
+
* `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から
|
|
211
|
+
* import する。fullscreen は referenced element を操作するモニタ的ノードで競合 operation
|
|
212
|
+
* を持たないため lane は無く、error taxonomy(errorInfo)のみを採用する。
|
|
213
|
+
*
|
|
214
|
+
* `_setError` は合成 `{ message }`(target 未解決 / API 非対応)と caught 例外
|
|
215
|
+
* (`NotAllowedError` / `TypeError` = user gesture 外の requestFullscreen 拒否)を混在
|
|
216
|
+
* 受理する。呼出側が明示 `code` を渡して合成側を曖昧さ無く分類し、caught は `.name` で
|
|
217
|
+
* 分類する(storage / screen-orientation と同じ discriminator 方式)。
|
|
218
|
+
*/
|
|
219
|
+
|
|
220
|
+
/** 安定した fullscreen error code(taxonomy)。値は公開キーとして固定。 */
|
|
221
|
+
declare const WCS_FULLSCREEN_ERROR_CODE: {
|
|
222
|
+
/** Fullscreen API 非対応。 */
|
|
223
|
+
readonly CapabilityMissing: "capability-missing";
|
|
224
|
+
/** target selector が要素に解決しない等の入力不備。 */
|
|
225
|
+
readonly InvalidArgument: "invalid-argument";
|
|
226
|
+
/** `NotAllowedError` / `TypeError` — user gesture 外での要求拒否。 */
|
|
227
|
+
readonly NotAllowed: "not-allowed";
|
|
228
|
+
/** その他の caught 例外。 */
|
|
229
|
+
readonly FullscreenError: "fullscreen-error";
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
export { FullscreenCore, WCS_FULLSCREEN_ERROR_CODE, WcsFullscreen, bootstrapFullscreen, getConfig };
|
|
233
|
+
export type { IWritableConfig, IWritableTagNames, WcsFullscreenCoreValues, WcsFullscreenValues, WcsIoErrorInfo, WcsIoErrorPhase };
|
package/dist/index.esm.js
CHANGED
|
@@ -36,6 +36,56 @@ function setConfig(partialConfig) {
|
|
|
36
36
|
frozenConfig = null;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* fullscreenCapabilities.ts
|
|
41
|
+
*
|
|
42
|
+
* Fullscreen node 固有の error code(taxonomy)と derivation。汎用の error info 型は
|
|
43
|
+
* `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から
|
|
44
|
+
* import する。fullscreen は referenced element を操作するモニタ的ノードで競合 operation
|
|
45
|
+
* を持たないため lane は無く、error taxonomy(errorInfo)のみを採用する。
|
|
46
|
+
*
|
|
47
|
+
* `_setError` は合成 `{ message }`(target 未解決 / API 非対応)と caught 例外
|
|
48
|
+
* (`NotAllowedError` / `TypeError` = user gesture 外の requestFullscreen 拒否)を混在
|
|
49
|
+
* 受理する。呼出側が明示 `code` を渡して合成側を曖昧さ無く分類し、caught は `.name` で
|
|
50
|
+
* 分類する(storage / screen-orientation と同じ discriminator 方式)。
|
|
51
|
+
*/
|
|
52
|
+
/** 安定した fullscreen error code(taxonomy)。値は公開キーとして固定。 */
|
|
53
|
+
const WCS_FULLSCREEN_ERROR_CODE = {
|
|
54
|
+
/** Fullscreen API 非対応。 */
|
|
55
|
+
CapabilityMissing: "capability-missing",
|
|
56
|
+
/** target selector が要素に解決しない等の入力不備。 */
|
|
57
|
+
InvalidArgument: "invalid-argument",
|
|
58
|
+
/** `NotAllowedError` / `TypeError` — user gesture 外での要求拒否。 */
|
|
59
|
+
NotAllowed: "not-allowed",
|
|
60
|
+
/** その他の caught 例外。 */
|
|
61
|
+
FullscreenError: "fullscreen-error",
|
|
62
|
+
};
|
|
63
|
+
function messageOf(error) {
|
|
64
|
+
return typeof error?.message === "string"
|
|
65
|
+
? error.message
|
|
66
|
+
: String(error);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* fullscreen の失敗を serializable な error taxonomy に写す。`kind` は合成エラーの
|
|
70
|
+
* 呼出側が渡す明示 discriminator(`capability-missing` / `invalid-argument`)。未指定は
|
|
71
|
+
* caught 例外を意味し、`.name` で分類する。`NotAllowedError` / `TypeError` は user
|
|
72
|
+
* gesture 内で再試行すれば成功しうるため recoverable=true。
|
|
73
|
+
*/
|
|
74
|
+
function deriveFullscreenErrorInfo(error, kind) {
|
|
75
|
+
const message = messageOf(error);
|
|
76
|
+
if (kind === "capability-missing") {
|
|
77
|
+
return { code: WCS_FULLSCREEN_ERROR_CODE.CapabilityMissing, phase: "probe", recoverable: false, message };
|
|
78
|
+
}
|
|
79
|
+
if (kind === "invalid-argument") {
|
|
80
|
+
return { code: WCS_FULLSCREEN_ERROR_CODE.InvalidArgument, phase: "start", recoverable: false, message };
|
|
81
|
+
}
|
|
82
|
+
const name = error?.name;
|
|
83
|
+
if (name === "NotAllowedError" || name === "TypeError") {
|
|
84
|
+
return { code: WCS_FULLSCREEN_ERROR_CODE.NotAllowed, phase: "execute", recoverable: true, message };
|
|
85
|
+
}
|
|
86
|
+
return { code: WCS_FULLSCREEN_ERROR_CODE.FullscreenError, phase: "execute", recoverable: false, message };
|
|
87
|
+
}
|
|
88
|
+
|
|
39
89
|
/**
|
|
40
90
|
* Headless Fullscreen API primitive. Unlike most wcstack IO nodes, this Core
|
|
41
91
|
* does not operate on itself: it drives `requestFullscreen()` /
|
|
@@ -57,6 +107,14 @@ class FullscreenCore extends EventTarget {
|
|
|
57
107
|
version: 1,
|
|
58
108
|
properties: [
|
|
59
109
|
{ name: "active", event: "wcs-fullscreen:change", getter: (e) => e.detail.active },
|
|
110
|
+
// `error` / `errorInfo` are observable failure outputs. Historically `error`
|
|
111
|
+
// was an imperative getter with no event; both are now bindable (event-backed)
|
|
112
|
+
// so `data-wcs` / bind() can observe a request/exit failure. `errorInfo` is the
|
|
113
|
+
// additive serializable taxonomy (stable code / phase / recoverable) derived
|
|
114
|
+
// from `error`; the `error` value shape is unchanged. No lane — fullscreen
|
|
115
|
+
// drives a referenced element, not a competing operation.
|
|
116
|
+
{ name: "error", event: "wcs-fullscreen:error" },
|
|
117
|
+
{ name: "errorInfo", event: "wcs-fullscreen:error-info-changed" },
|
|
60
118
|
],
|
|
61
119
|
commands: [
|
|
62
120
|
{ name: "requestFullscreen", async: true },
|
|
@@ -70,6 +128,7 @@ class FullscreenCore extends EventTarget {
|
|
|
70
128
|
// machine like permission's 4-value surface — active/error are two
|
|
71
129
|
// orthogonal, independently-observable axes.
|
|
72
130
|
_error = null;
|
|
131
|
+
_errorInfo = null;
|
|
73
132
|
// The last Element this Core resolved via requestFullscreen()/setTarget().
|
|
74
133
|
// Compared against document.fullscreenElement on every fullscreenchange so
|
|
75
134
|
// each instance judges only its own target (§2.1). null means "no target
|
|
@@ -100,6 +159,15 @@ class FullscreenCore extends EventTarget {
|
|
|
100
159
|
get error() {
|
|
101
160
|
return this._error;
|
|
102
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /
|
|
164
|
+
* `recoverable`), or null. Additive wc-bindable property (event
|
|
165
|
+
* `wcs-fullscreen:error-info-changed`), derived from `error`; the existing
|
|
166
|
+
* `error` value shape is unchanged.
|
|
167
|
+
*/
|
|
168
|
+
get errorInfo() {
|
|
169
|
+
return this._errorInfo;
|
|
170
|
+
}
|
|
103
171
|
/**
|
|
104
172
|
* Update the resolved target without issuing a fullscreen request (e.g. the
|
|
105
173
|
* Shell re-resolves `target` on attribute change / connect). Re-evaluates
|
|
@@ -145,12 +213,12 @@ class FullscreenCore extends EventTarget {
|
|
|
145
213
|
// selector did not resolve to any element (missing/typo'd selector).
|
|
146
214
|
// Conflating the two previously misled users into thinking Fullscreen
|
|
147
215
|
// itself was unsupported when only their selector was wrong.
|
|
148
|
-
this._setError({ message: "Fullscreen target could not be resolved." });
|
|
216
|
+
this._setError({ message: "Fullscreen target could not be resolved." }, "invalid-argument");
|
|
149
217
|
return;
|
|
150
218
|
}
|
|
151
219
|
const fn = this._requestFullscreenFn(element);
|
|
152
220
|
if (!fn) {
|
|
153
|
-
this._setError({ message: "Fullscreen API is not supported." });
|
|
221
|
+
this._setError({ message: "Fullscreen API is not supported." }, "capability-missing");
|
|
154
222
|
return;
|
|
155
223
|
}
|
|
156
224
|
try {
|
|
@@ -251,8 +319,33 @@ class FullscreenCore extends EventTarget {
|
|
|
251
319
|
bubbles: true,
|
|
252
320
|
}));
|
|
253
321
|
}
|
|
254
|
-
|
|
322
|
+
// `kind` is an explicit taxonomy discriminator passed only from the synthetic
|
|
323
|
+
// error sites (unsupported / unresolved target); caught exceptions pass no kind
|
|
324
|
+
// and are classified by their `.name`. Both `error` and the additive `errorInfo`
|
|
325
|
+
// are now event-backed so a request/exit failure is observable via bind().
|
|
326
|
+
_setError(error, kind) {
|
|
327
|
+
// Same-value guard on reference: each failure builds a fresh object and the
|
|
328
|
+
// clear path passes the literal null, so this only suppresses redundant
|
|
329
|
+
// null→null (a successful request/exit clearing an already-null error).
|
|
330
|
+
if (this._error === error)
|
|
331
|
+
return;
|
|
255
332
|
this._error = error;
|
|
333
|
+
// Keep the additive errorInfo taxonomy in sync; fire it before the `error`
|
|
334
|
+
// event so an observer of both sees the classification first (io-node family).
|
|
335
|
+
this._commitErrorInfo(error === null ? null : deriveFullscreenErrorInfo(error, kind));
|
|
336
|
+
this._target.dispatchEvent(new CustomEvent("wcs-fullscreen:error", {
|
|
337
|
+
detail: error,
|
|
338
|
+
bubbles: true,
|
|
339
|
+
}));
|
|
340
|
+
}
|
|
341
|
+
// Called only from _setError (already reference-guarded), so errorInfo
|
|
342
|
+
// transitions exactly when error does — no separate guard needed here.
|
|
343
|
+
_commitErrorInfo(info) {
|
|
344
|
+
this._errorInfo = info;
|
|
345
|
+
this._target.dispatchEvent(new CustomEvent("wcs-fullscreen:error-info-changed", {
|
|
346
|
+
detail: info,
|
|
347
|
+
bubbles: true,
|
|
348
|
+
}));
|
|
256
349
|
}
|
|
257
350
|
}
|
|
258
351
|
|
|
@@ -366,6 +459,9 @@ class WcsFullscreen extends HTMLElement {
|
|
|
366
459
|
get error() {
|
|
367
460
|
return this._core.error;
|
|
368
461
|
}
|
|
462
|
+
get errorInfo() {
|
|
463
|
+
return this._core.errorInfo;
|
|
464
|
+
}
|
|
369
465
|
// --- Commands ---
|
|
370
466
|
/**
|
|
371
467
|
* Resolve `target` and request fullscreen on it. never-throw: an
|
|
@@ -441,5 +537,5 @@ function bootstrapFullscreen(userConfig) {
|
|
|
441
537
|
registerComponents();
|
|
442
538
|
}
|
|
443
539
|
|
|
444
|
-
export { FullscreenCore, WcsFullscreen, bootstrapFullscreen, getConfig };
|
|
540
|
+
export { FullscreenCore, WCS_FULLSCREEN_ERROR_CODE, WcsFullscreen, bootstrapFullscreen, getConfig };
|
|
445
541
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/FullscreenCore.ts","../src/components/Fullscreen.ts","../src/registerComponents.ts","../src/bootstrapFullscreen.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n fullscreen: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n fullscreen: \"wcs-fullscreen\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\n/**\n * Headless Fullscreen API primitive. Unlike most wcstack IO nodes, this Core\n * does not operate on itself: it drives `requestFullscreen()` /\n * `exitFullscreen()` on a *referenced* Element that the Shell resolves via its\n * `target` attribute (docs/fullscreen-tag-design.md §0). The Core only ever\n * receives already-resolved `Element`s from its callers — it has no opinion on\n * how `target` selectors are parsed.\n *\n * `document.fullscreenElement` is a single document-wide value, so this Core\n * always compares against the *last element it resolved* (via\n * `requestFullscreen()`/`setTarget()`), never against \"is the document\n * fullscreen at all\" — that comparison is what keeps multiple concurrent\n * `<wcs-fullscreen>` instances from all reporting the same `active` value\n * (docs/fullscreen-tag-design.md §2.1, MUST).\n */\nexport class FullscreenCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"active\", event: \"wcs-fullscreen:change\", getter: (e: Event) => (e as CustomEvent).detail.active },\n ],\n commands: [\n { name: \"requestFullscreen\", async: true },\n { name: \"exitFullscreen\", async: true },\n ],\n };\n\n private _target: EventTarget;\n private _active: boolean = false;\n // Single error slot (§8): null means \"no recent failure\". Fullscreen's\n // gesture-rejection failure is a one-shot event, not a persistent state\n // machine like permission's 4-value surface — active/error are two\n // orthogonal, independently-observable axes.\n private _error: any = null;\n\n // The last Element this Core resolved via requestFullscreen()/setTarget().\n // Compared against document.fullscreenElement on every fullscreenchange so\n // each instance judges only its own target (§2.1). null means \"no target\n // resolved yet\" — active must stay false in that case.\n private _resolvedTarget: Element | null = null;\n\n // Generation guard (§6): Core-scoped (one per Core, not per-target),\n // mirroring fetch/upload. document.fullscreenElement is a single\n // document-wide slot, so at most one in-flight request/exit is meaningful\n // per Core at a time.\n private _gen = 0;\n\n // True once observe() has attached the document-level fullscreenchange\n // listener. Guards observe() so a redundant call does not double-subscribe;\n // dispose() resets it so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // SSR (§10): 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 * Update the resolved target without issuing a fullscreen request (e.g. the\n * Shell re-resolves `target` on attribute change / connect). Re-evaluates\n * `active` against the current `document.fullscreenElement` so the state\n * stays correct even if the target changed while already fullscreen.\n */\n setTarget(element: Element | null): void {\n this._resolvedTarget = element;\n this._applyActive();\n }\n\n // Lifecycle (§10/§3.5). Idempotent: a second observe() while already\n // subscribed is a no-op (no double listener). Synchronous overall (no probe\n // to await), so the returned promise is only for API uniformity with other\n // IO nodes.\n observe(): Promise<void> {\n if (!this._subscribed) {\n this._subscribed = true;\n document.addEventListener(this._fullscreenChangeEventName(), this._onFullscreenChange);\n }\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n if (this._subscribed) {\n this._subscribed = false;\n document.removeEventListener(this._fullscreenChangeEventName(), this._onFullscreenChange);\n }\n }\n\n /**\n * Request fullscreen on `element`. never-throw (§3/§6): a missing API or a\n * rejected promise (e.g. a `TypeError` from a call outside a user\n * gesture, per the WHATWG Fullscreen spec's transient-activation check) is\n * caught and surfaced via `error`, never thrown. The caller\n * (Shell) is responsible for resolving `target` and for ensuring this is\n * invoked from within an actual user gesture — this Core cannot manufacture\n * one (docs/fullscreen-tag-design.md §3).\n */\n async requestFullscreen(element: Element | null): Promise<void> {\n const gen = ++this._gen;\n this._resolvedTarget = element;\n if (!element) {\n // Distinct from \"API is not supported\" (below): the Shell's `target`\n // selector did not resolve to any element (missing/typo'd selector).\n // Conflating the two previously misled users into thinking Fullscreen\n // itself was unsupported when only their selector was wrong.\n this._setError({ message: \"Fullscreen target could not be resolved.\" });\n return;\n }\n const fn = this._requestFullscreenFn(element);\n if (!fn) {\n this._setError({ message: \"Fullscreen API is not supported.\" });\n return;\n }\n try {\n await fn.call(element);\n if (gen !== this._gen) return; // stale: dispose()/superseding call ran\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 fullscreen. Silent no-op (§7) when nothing is currently fullscreen or\n * the API is unsupported — both are treated as \"already achieved the exit\n * intent\", not as errors, keeping repeated calls safe and never-throw.\n */\n async exitFullscreen(): Promise<void> {\n // no-op checks come BEFORE the generation bump: a call that does nothing\n // must not supersede an in-flight requestFullscreen() — bumping first\n // would make the pending request's settle handling stale and silently\n // swallow its error/active updates.\n if (this._fullscreenElement() === null) return; // already not fullscreen: silent no-op\n const fn = this._exitFullscreenFn();\n if (!fn) return; // unsupported: silent no-op (semantically already \"not fullscreen\")\n const gen = ++this._gen;\n try {\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 // --- API resolution layer (§4): call-time, never cached. Lets tests\n // install/remove the standard/legacy APIs freely and lets an unsupported\n // environment be detected correctly on every call. ---\n\n private _requestFullscreenFn(el: Element): (() => Promise<void>) | undefined {\n return this._elementFullscreenFn(el, \"requestFullscreen\")\n ?? this._elementFullscreenFn(el, \"webkitRequestFullscreen\");\n }\n\n // Resolve a fullscreen method for `el` WITHOUT a naive `el[name]` lookup.\n // A plain lookup walks the whole prototype chain — and <wcs-fullscreen>\n // itself declares a `requestFullscreen()` *command* method, so when the\n // resolved target is the Shell element (target=\"self\", or target omitted\n // with no children), the naive lookup would find the Shell's own command\n // instead of the platform API and recurse infinitely (stack overflow).\n // Instead: check the element's own properties (how tests install stubs —\n // happy-dom has no Fullscreen API — and how a deliberate per-element\n // monkey-patch would appear), then jump straight to Element.prototype,\n // where the platform defines the real methods. Both the standard and the\n // legacy webkit name go through this same resolution for symmetry.\n private _elementFullscreenFn(el: Element, name: string): (() => Promise<void>) | undefined {\n if (Object.prototype.hasOwnProperty.call(el, name)) {\n return (el as any)[name];\n }\n return (Element.prototype as any)[name];\n }\n\n private _exitFullscreenFn(): (() => Promise<void>) | undefined {\n const d = document as any;\n return d.exitFullscreen?.bind(document) ?? d.webkitExitFullscreen?.bind(document);\n }\n\n private _fullscreenElement(): Element | null {\n const d = document as any;\n return d.fullscreenElement ?? d.webkitFullscreenElement ?? null;\n }\n\n private _fullscreenChangeEventName(): string {\n return \"onfullscreenchange\" in document ? \"fullscreenchange\" : \"webkitfullscreenchange\";\n }\n\n // --- Internal ---\n\n private _onFullscreenChange = (): void => {\n this._applyActive();\n };\n\n // Re-derive `active` by comparing document.fullscreenElement (incl. legacy\n // fallback) against *this instance's* resolved target (§2/§2.1/§5). A null\n // resolved target always yields active=false — there is nothing for this\n // instance to claim as \"mine\".\n private _applyActive(): void {\n const next = this._resolvedTarget !== null && this._fullscreenElement() === this._resolvedTarget;\n this._setActive(next);\n }\n\n private _setActive(v: boolean): void {\n if (this._active === v) return; // same-value guard (§3.3 MUST)\n this._active = v;\n this._target.dispatchEvent(new CustomEvent(\"wcs-fullscreen:change\", {\n detail: { active: v },\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n this._error = error;\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { FullscreenCore } from \"../core/FullscreenCore.js\";\n\n/**\n * `<wcs-fullscreen target=\"...\">` — declarative Fullscreen API control.\n *\n * Like `intersection`/`resize`, this Shell operates on a *referenced* element,\n * not itself (docs/fullscreen-tag-design.md §0): `target` resolves which\n * element `requestFullscreen()`/`exitFullscreen()` are invoked on, using the\n * exact same 3-mode resolution as `<wcs-intersect>`\n * (docs/fullscreen-tag-design.md §1):\n *\n * | `target` | operates on | display | use case |\n * |-----------------|-------------------------|-------------|--------------------------|\n * | omitted | first element child | `contents` | wrap a gallery image/video |\n * | `\"#hero\"` / sel | the matched element | `none` | point at a distant node |\n * | `\"self\"` | the element itself | `block` | fullscreen the wrapper |\n *\n * `requestFullscreen()` requires an active user gesture — this element cannot\n * manufacture one. Invoke the command from within a real click handler\n * (typically via the command-token protocol: this element subscribes with\n * `command.requestFullscreen: $command.<token>`, and a button emits the\n * token from its own click handler, e.g. `onclick: $command.<token>`).\n */\nexport class WcsFullscreen extends HTMLElement {\n // SSR (§10): the fullscreenchange subscription is established synchronously\n // on connect, but the Shell still exposes connectedCallbackPromise so the\n // state binder can await it uniformly across all IO nodes before\n // snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static observedAttributes = [\"target\"];\n\n static wcBindable: IWcBindable = {\n ...FullscreenCore.wcBindable,\n inputs: [{ name: \"target\", attribute: \"target\" }],\n // Core の commands をそのまま継承(単一情報源)。network/intersection と同型。\n commands: FullscreenCore.wcBindable.commands,\n };\n\n private _core: FullscreenCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new FullscreenCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-fullscreen:change\": (d) => ({ active: d?.active === true }),\n });\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.1): 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 get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n // --- Core delegated getters ---\n\n get active(): boolean {\n return this._core.active;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n // --- Commands ---\n\n /**\n * Resolve `target` and request fullscreen on it. never-throw: an\n * unresolvable target or an unsupported/rejected API call are both\n * surfaced via `error`, never thrown (docs/fullscreen-tag-design.md §3/§6).\n */\n async requestFullscreen(): Promise<void> {\n const { element } = this._resolveTarget();\n await this._core.requestFullscreen(element);\n }\n\n async exitFullscreen(): Promise<void> {\n await this._core.exitFullscreen();\n }\n\n // --- Internal ---\n\n // Copied verbatim from <wcs-intersect> (Intersect.ts _resolveTarget/_safeQuery,\n // docs/fullscreen-tag-design.md §1): identical 3-mode resolution, only the\n // \"what to do with the resolved element\" step differs.\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 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 private _reresolve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n this._core.setTarget(element);\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this._reresolve();\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n if (!this.isConnected) return;\n this._reresolve();\n }\n}\n","import { WcsFullscreen } from \"./components/Fullscreen.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.fullscreen)) {\n customElements.define(config.tagNames.fullscreen, WcsFullscreen);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapFullscreen(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/fullscreenCapabilities.ts","../src/core/FullscreenCore.ts","../src/components/Fullscreen.ts","../src/registerComponents.ts","../src/bootstrapFullscreen.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n fullscreen: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n fullscreen: \"wcs-fullscreen\",\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 * fullscreenCapabilities.ts\n *\n * Fullscreen node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。fullscreen は referenced element を操作するモニタ的ノードで競合 operation\n * を持たないため lane は無く、error taxonomy(errorInfo)のみを採用する。\n *\n * `_setError` は合成 `{ message }`(target 未解決 / API 非対応)と caught 例外\n * (`NotAllowedError` / `TypeError` = user gesture 外の requestFullscreen 拒否)を混在\n * 受理する。呼出側が明示 `code` を渡して合成側を曖昧さ無く分類し、caught は `.name` で\n * 分類する(storage / screen-orientation と同じ discriminator 方式)。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 明示 code discriminator(合成エラーの呼出側が渡す)。 */\nexport type FullscreenErrorKind = \"capability-missing\" | \"invalid-argument\";\n\n/** 安定した fullscreen error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_FULLSCREEN_ERROR_CODE = {\n /** Fullscreen API 非対応。 */\n CapabilityMissing: \"capability-missing\",\n /** target selector が要素に解決しない等の入力不備。 */\n InvalidArgument: \"invalid-argument\",\n /** `NotAllowedError` / `TypeError` — user gesture 外での要求拒否。 */\n NotAllowed: \"not-allowed\",\n /** その他の caught 例外。 */\n FullscreenError: \"fullscreen-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 * fullscreen の失敗を serializable な error taxonomy に写す。`kind` は合成エラーの\n * 呼出側が渡す明示 discriminator(`capability-missing` / `invalid-argument`)。未指定は\n * caught 例外を意味し、`.name` で分類する。`NotAllowedError` / `TypeError` は user\n * gesture 内で再試行すれば成功しうるため recoverable=true。\n */\nexport function deriveFullscreenErrorInfo(error: unknown, kind?: FullscreenErrorKind): WcsIoErrorInfo {\n const message = messageOf(error);\n if (kind === \"capability-missing\") {\n return { code: WCS_FULLSCREEN_ERROR_CODE.CapabilityMissing, phase: \"probe\", recoverable: false, message };\n }\n if (kind === \"invalid-argument\") {\n return { code: WCS_FULLSCREEN_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_FULLSCREEN_ERROR_CODE.NotAllowed, phase: \"execute\", recoverable: true, message };\n }\n return { code: WCS_FULLSCREEN_ERROR_CODE.FullscreenError, phase: \"execute\", recoverable: false, message };\n}\n","import { IWcBindable } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { deriveFullscreenErrorInfo, FullscreenErrorKind } from \"./fullscreenCapabilities.js\";\n\n/**\n * Headless Fullscreen API primitive. Unlike most wcstack IO nodes, this Core\n * does not operate on itself: it drives `requestFullscreen()` /\n * `exitFullscreen()` on a *referenced* Element that the Shell resolves via its\n * `target` attribute (docs/fullscreen-tag-design.md §0). The Core only ever\n * receives already-resolved `Element`s from its callers — it has no opinion on\n * how `target` selectors are parsed.\n *\n * `document.fullscreenElement` is a single document-wide value, so this Core\n * always compares against the *last element it resolved* (via\n * `requestFullscreen()`/`setTarget()`), never against \"is the document\n * fullscreen at all\" — that comparison is what keeps multiple concurrent\n * `<wcs-fullscreen>` instances from all reporting the same `active` value\n * (docs/fullscreen-tag-design.md §2.1, MUST).\n */\nexport class FullscreenCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"active\", event: \"wcs-fullscreen:change\", getter: (e: Event) => (e as CustomEvent).detail.active },\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 — fullscreen\n // drives a referenced element, not a competing operation.\n { name: \"error\", event: \"wcs-fullscreen:error\" },\n { name: \"errorInfo\", event: \"wcs-fullscreen:error-info-changed\" },\n ],\n commands: [\n { name: \"requestFullscreen\", async: true },\n { name: \"exitFullscreen\", async: true },\n ],\n };\n\n private _target: EventTarget;\n private _active: boolean = false;\n // Single error slot (§8): null means \"no recent failure\". Fullscreen's\n // gesture-rejection failure is a one-shot event, not a persistent state\n // machine like permission's 4-value surface — active/error are two\n // orthogonal, independently-observable axes.\n private _error: any = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n\n // The last Element this Core resolved via requestFullscreen()/setTarget().\n // Compared against document.fullscreenElement on every fullscreenchange so\n // each instance judges only its own target (§2.1). null means \"no target\n // resolved yet\" — active must stay false in that case.\n private _resolvedTarget: Element | null = null;\n\n // Generation guard (§6): Core-scoped (one per Core, not per-target),\n // mirroring fetch/upload. document.fullscreenElement is a single\n // document-wide slot, so at most one in-flight request/exit is meaningful\n // per Core at a time.\n private _gen = 0;\n\n // True once observe() has attached the document-level fullscreenchange\n // listener. Guards observe() so a redundant call does not double-subscribe;\n // dispose() resets it so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // SSR (§10): 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-fullscreen: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 /**\n * Update the resolved target without issuing a fullscreen request (e.g. the\n * Shell re-resolves `target` on attribute change / connect). Re-evaluates\n * `active` against the current `document.fullscreenElement` so the state\n * stays correct even if the target changed while already fullscreen.\n */\n setTarget(element: Element | null): void {\n this._resolvedTarget = element;\n this._applyActive();\n }\n\n // Lifecycle (§10/§3.5). Idempotent: a second observe() while already\n // subscribed is a no-op (no double listener). Synchronous overall (no probe\n // to await), so the returned promise is only for API uniformity with other\n // IO nodes.\n observe(): Promise<void> {\n if (!this._subscribed) {\n this._subscribed = true;\n document.addEventListener(this._fullscreenChangeEventName(), this._onFullscreenChange);\n }\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n if (this._subscribed) {\n this._subscribed = false;\n document.removeEventListener(this._fullscreenChangeEventName(), this._onFullscreenChange);\n }\n }\n\n /**\n * Request fullscreen on `element`. never-throw (§3/§6): a missing API or a\n * rejected promise (e.g. a `TypeError` from a call outside a user\n * gesture, per the WHATWG Fullscreen spec's transient-activation check) is\n * caught and surfaced via `error`, never thrown. The caller\n * (Shell) is responsible for resolving `target` and for ensuring this is\n * invoked from within an actual user gesture — this Core cannot manufacture\n * one (docs/fullscreen-tag-design.md §3).\n */\n async requestFullscreen(element: Element | null): Promise<void> {\n const gen = ++this._gen;\n this._resolvedTarget = element;\n if (!element) {\n // Distinct from \"API is not supported\" (below): the Shell's `target`\n // selector did not resolve to any element (missing/typo'd selector).\n // Conflating the two previously misled users into thinking Fullscreen\n // itself was unsupported when only their selector was wrong.\n this._setError({ message: \"Fullscreen target could not be resolved.\" }, \"invalid-argument\");\n return;\n }\n const fn = this._requestFullscreenFn(element);\n if (!fn) {\n this._setError({ message: \"Fullscreen API is not supported.\" }, \"capability-missing\");\n return;\n }\n try {\n await fn.call(element);\n if (gen !== this._gen) return; // stale: dispose()/superseding call ran\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 fullscreen. Silent no-op (§7) when nothing is currently fullscreen or\n * the API is unsupported — both are treated as \"already achieved the exit\n * intent\", not as errors, keeping repeated calls safe and never-throw.\n */\n async exitFullscreen(): Promise<void> {\n // no-op checks come BEFORE the generation bump: a call that does nothing\n // must not supersede an in-flight requestFullscreen() — bumping first\n // would make the pending request's settle handling stale and silently\n // swallow its error/active updates.\n if (this._fullscreenElement() === null) return; // already not fullscreen: silent no-op\n const fn = this._exitFullscreenFn();\n if (!fn) return; // unsupported: silent no-op (semantically already \"not fullscreen\")\n const gen = ++this._gen;\n try {\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 // --- API resolution layer (§4): call-time, never cached. Lets tests\n // install/remove the standard/legacy APIs freely and lets an unsupported\n // environment be detected correctly on every call. ---\n\n private _requestFullscreenFn(el: Element): (() => Promise<void>) | undefined {\n return this._elementFullscreenFn(el, \"requestFullscreen\")\n ?? this._elementFullscreenFn(el, \"webkitRequestFullscreen\");\n }\n\n // Resolve a fullscreen method for `el` WITHOUT a naive `el[name]` lookup.\n // A plain lookup walks the whole prototype chain — and <wcs-fullscreen>\n // itself declares a `requestFullscreen()` *command* method, so when the\n // resolved target is the Shell element (target=\"self\", or target omitted\n // with no children), the naive lookup would find the Shell's own command\n // instead of the platform API and recurse infinitely (stack overflow).\n // Instead: check the element's own properties (how tests install stubs —\n // happy-dom has no Fullscreen API — and how a deliberate per-element\n // monkey-patch would appear), then jump straight to Element.prototype,\n // where the platform defines the real methods. Both the standard and the\n // legacy webkit name go through this same resolution for symmetry.\n private _elementFullscreenFn(el: Element, name: string): (() => Promise<void>) | undefined {\n if (Object.prototype.hasOwnProperty.call(el, name)) {\n return (el as any)[name];\n }\n return (Element.prototype as any)[name];\n }\n\n private _exitFullscreenFn(): (() => Promise<void>) | undefined {\n const d = document as any;\n return d.exitFullscreen?.bind(document) ?? d.webkitExitFullscreen?.bind(document);\n }\n\n private _fullscreenElement(): Element | null {\n const d = document as any;\n return d.fullscreenElement ?? d.webkitFullscreenElement ?? null;\n }\n\n private _fullscreenChangeEventName(): string {\n return \"onfullscreenchange\" in document ? \"fullscreenchange\" : \"webkitfullscreenchange\";\n }\n\n // --- Internal ---\n\n private _onFullscreenChange = (): void => {\n this._applyActive();\n };\n\n // Re-derive `active` by comparing document.fullscreenElement (incl. legacy\n // fallback) against *this instance's* resolved target (§2/§2.1/§5). A null\n // resolved target always yields active=false — there is nothing for this\n // instance to claim as \"mine\".\n private _applyActive(): void {\n const next = this._resolvedTarget !== null && this._fullscreenElement() === this._resolvedTarget;\n this._setActive(next);\n }\n\n private _setActive(v: boolean): void {\n if (this._active === v) return; // same-value guard (§3.3 MUST)\n this._active = v;\n this._target.dispatchEvent(new CustomEvent(\"wcs-fullscreen:change\", {\n detail: { active: 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?: FullscreenErrorKind): 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 : deriveFullscreenErrorInfo(error, kind));\n this._target.dispatchEvent(new CustomEvent(\"wcs-fullscreen: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-fullscreen:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { FullscreenCore } from \"../core/FullscreenCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\n\n/**\n * `<wcs-fullscreen target=\"...\">` — declarative Fullscreen API control.\n *\n * Like `intersection`/`resize`, this Shell operates on a *referenced* element,\n * not itself (docs/fullscreen-tag-design.md §0): `target` resolves which\n * element `requestFullscreen()`/`exitFullscreen()` are invoked on, using the\n * exact same 3-mode resolution as `<wcs-intersect>`\n * (docs/fullscreen-tag-design.md §1):\n *\n * | `target` | operates on | display | use case |\n * |-----------------|-------------------------|-------------|--------------------------|\n * | omitted | first element child | `contents` | wrap a gallery image/video |\n * | `\"#hero\"` / sel | the matched element | `none` | point at a distant node |\n * | `\"self\"` | the element itself | `block` | fullscreen the wrapper |\n *\n * `requestFullscreen()` requires an active user gesture — this element cannot\n * manufacture one. Invoke the command from within a real click handler\n * (typically via the command-token protocol: this element subscribes with\n * `command.requestFullscreen: $command.<token>`, and a button emits the\n * token from its own click handler, e.g. `onclick: $command.<token>`).\n */\nexport class WcsFullscreen extends HTMLElement {\n // SSR (§10): the fullscreenchange subscription is established synchronously\n // on connect, but the Shell still exposes connectedCallbackPromise so the\n // state binder can await it uniformly across all IO nodes before\n // snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static observedAttributes = [\"target\"];\n\n static wcBindable: IWcBindable = {\n ...FullscreenCore.wcBindable,\n inputs: [{ name: \"target\", attribute: \"target\" }],\n // Core の commands をそのまま継承(単一情報源)。network/intersection と同型。\n commands: FullscreenCore.wcBindable.commands,\n };\n\n private _core: FullscreenCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new FullscreenCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-fullscreen:change\": (d) => ({ active: d?.active === true }),\n });\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.1): 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 get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\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 fullscreen on it. never-throw: an\n * unresolvable target or an unsupported/rejected API call are both\n * surfaced via `error`, never thrown (docs/fullscreen-tag-design.md §3/§6).\n */\n async requestFullscreen(): Promise<void> {\n const { element } = this._resolveTarget();\n await this._core.requestFullscreen(element);\n }\n\n async exitFullscreen(): Promise<void> {\n await this._core.exitFullscreen();\n }\n\n // --- Internal ---\n\n // Copied verbatim from <wcs-intersect> (Intersect.ts _resolveTarget/_safeQuery,\n // docs/fullscreen-tag-design.md §1): identical 3-mode resolution, only the\n // \"what to do with the resolved element\" step differs.\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 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 private _reresolve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n this._core.setTarget(element);\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this._reresolve();\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n if (!this.isConnected) return;\n this._reresolve();\n }\n}\n","import { WcsFullscreen } from \"./components/Fullscreen.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.fullscreen)) {\n customElements.define(config.tagNames.fullscreen, WcsFullscreen);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapFullscreen(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.esm.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e={tagNames:{fullscreen:"wcs-fullscreen"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const
|
|
1
|
+
const e={tagNames:{fullscreen:"wcs-fullscreen"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const r of Object.keys(e))t(e[r]);return e}function r(e){if(null===e||"object"!=typeof e)return e;const t={};for(const s of Object.keys(e))t[s]=r(e[s]);return t}let s=null;const n=e;function l(){return s||(s=t(r(e))),s}const i={CapabilityMissing:"capability-missing",InvalidArgument:"invalid-argument",NotAllowed:"not-allowed",FullscreenError:"fullscreen-error"};function c(e,t){const r=function(e){return"string"==typeof e?.message?e.message:String(e)}(e);if("capability-missing"===t)return{code:i.CapabilityMissing,phase:"probe",recoverable:!1,message:r};if("invalid-argument"===t)return{code:i.InvalidArgument,phase:"start",recoverable:!1,message:r};const s=e?.name;return"NotAllowedError"===s||"TypeError"===s?{code:i.NotAllowed,phase:"execute",recoverable:!0,message:r}:{code:i.FullscreenError,phase:"execute",recoverable:!1,message:r}}class a extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"active",event:"wcs-fullscreen:change",getter:e=>e.detail.active},{name:"error",event:"wcs-fullscreen:error"},{name:"errorInfo",event:"wcs-fullscreen:error-info-changed"}],commands:[{name:"requestFullscreen",async:!0},{name:"exitFullscreen",async:!0}]};_target;_active=!1;_error=null;_errorInfo=null;_resolvedTarget=null;_gen=0;_subscribed=!1;_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}setTarget(e){this._resolvedTarget=e,this._applyActive()}observe(){return this._subscribed||(this._subscribed=!0,document.addEventListener(this._fullscreenChangeEventName(),this._onFullscreenChange)),this._ready}dispose(){this._gen++,this._subscribed&&(this._subscribed=!1,document.removeEventListener(this._fullscreenChangeEventName(),this._onFullscreenChange))}async requestFullscreen(e){const t=++this._gen;if(this._resolvedTarget=e,!e)return void this._setError({message:"Fullscreen target could not be resolved."},"invalid-argument");const r=this._requestFullscreenFn(e);if(r)try{if(await r.call(e),t!==this._gen)return;this._setError(null),this._applyActive()}catch(e){if(t!==this._gen)return;this._setError(e)}else this._setError({message:"Fullscreen API is not supported."},"capability-missing")}async exitFullscreen(){if(null===this._fullscreenElement())return;const e=this._exitFullscreenFn();if(!e)return;const t=++this._gen;try{if(await e(),t!==this._gen)return;this._setError(null),this._applyActive()}catch(e){if(t!==this._gen)return;this._setError(e)}}_requestFullscreenFn(e){return this._elementFullscreenFn(e,"requestFullscreen")??this._elementFullscreenFn(e,"webkitRequestFullscreen")}_elementFullscreenFn(e,t){return Object.prototype.hasOwnProperty.call(e,t)?e[t]:Element.prototype[t]}_exitFullscreenFn(){const e=document;return e.exitFullscreen?.bind(document)??e.webkitExitFullscreen?.bind(document)}_fullscreenElement(){const e=document;return e.fullscreenElement??e.webkitFullscreenElement??null}_fullscreenChangeEventName(){return"onfullscreenchange"in document?"fullscreenchange":"webkitfullscreenchange"}_onFullscreenChange=()=>{this._applyActive()};_applyActive(){const e=null!==this._resolvedTarget&&this._fullscreenElement()===this._resolvedTarget;this._setActive(e)}_setActive(e){this._active!==e&&(this._active=e,this._target.dispatchEvent(new CustomEvent("wcs-fullscreen:change",{detail:{active:e},bubbles:!0})))}_setError(e,t){this._error!==e&&(this._error=e,this._commitErrorInfo(null===e?null:c(e,t)),this._target.dispatchEvent(new CustomEvent("wcs-fullscreen:error",{detail:e,bubbles:!0})))}_commitErrorInfo(e){this._errorInfo=e,this._target.dispatchEvent(new CustomEvent("wcs-fullscreen:error-info-changed",{detail:e,bubbles:!0}))}}class o extends HTMLElement{static hasConnectedCallbackPromise=!0;static observedAttributes=["target"];static wcBindable={...a.wcBindable,inputs:[{name:"target",attribute:"target"}],commands:a.wcBindable.commands};_core;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new a(this),this._internals=this._initInternals(),this._wireStates({"wcs-fullscreen:change":e=>({active:!0===e?.active})})}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,s]of Object.entries(e))this.addEventListener(r,e=>{const r=this.hasAttribute("debug-states");for(const[n,l]of Object.entries(s(e.detail))){try{l?t.add(n):t.delete(n)}catch{}r&&this.toggleAttribute(`data-wcs-state-${n}`,l)}})}get connectedCallbackPromise(){return this._connectedCallbackPromise}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 requestFullscreen(){const{element:e}=this._resolveTarget();await this._core.requestFullscreen(e)}async exitFullscreen(){await this._core.exitFullscreen()}_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}}_reresolve(){const{element:e,display:t}=this._resolveTarget();this.style.display=t,this._core.setTarget(e)}connectedCallback(){this._reresolve(),this._connectedCallbackPromise=this._core.observe()}disconnectedCallback(){this._core.dispose()}attributeChangedCallback(e,t,r){t!==r&&this.isConnected&&this._reresolve()}}function u(t){var r;t&&((r=t).tagNames&&Object.assign(e.tagNames,r.tagNames),s=null),customElements.get(n.tagNames.fullscreen)||customElements.define(n.tagNames.fullscreen,o)}export{a as FullscreenCore,i as WCS_FULLSCREEN_ERROR_CODE,o as WcsFullscreen,u as bootstrapFullscreen,l as getConfig};
|
|
2
2
|
//# sourceMappingURL=index.esm.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/core/FullscreenCore.ts","../src/components/Fullscreen.ts","../src/bootstrapFullscreen.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n fullscreen: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n fullscreen: \"wcs-fullscreen\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\n/**\n * Headless Fullscreen API primitive. Unlike most wcstack IO nodes, this Core\n * does not operate on itself: it drives `requestFullscreen()` /\n * `exitFullscreen()` on a *referenced* Element that the Shell resolves via its\n * `target` attribute (docs/fullscreen-tag-design.md §0). The Core only ever\n * receives already-resolved `Element`s from its callers — it has no opinion on\n * how `target` selectors are parsed.\n *\n * `document.fullscreenElement` is a single document-wide value, so this Core\n * always compares against the *last element it resolved* (via\n * `requestFullscreen()`/`setTarget()`), never against \"is the document\n * fullscreen at all\" — that comparison is what keeps multiple concurrent\n * `<wcs-fullscreen>` instances from all reporting the same `active` value\n * (docs/fullscreen-tag-design.md §2.1, MUST).\n */\nexport class FullscreenCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"active\", event: \"wcs-fullscreen:change\", getter: (e: Event) => (e as CustomEvent).detail.active },\n ],\n commands: [\n { name: \"requestFullscreen\", async: true },\n { name: \"exitFullscreen\", async: true },\n ],\n };\n\n private _target: EventTarget;\n private _active: boolean = false;\n // Single error slot (§8): null means \"no recent failure\". Fullscreen's\n // gesture-rejection failure is a one-shot event, not a persistent state\n // machine like permission's 4-value surface — active/error are two\n // orthogonal, independently-observable axes.\n private _error: any = null;\n\n // The last Element this Core resolved via requestFullscreen()/setTarget().\n // Compared against document.fullscreenElement on every fullscreenchange so\n // each instance judges only its own target (§2.1). null means \"no target\n // resolved yet\" — active must stay false in that case.\n private _resolvedTarget: Element | null = null;\n\n // Generation guard (§6): Core-scoped (one per Core, not per-target),\n // mirroring fetch/upload. document.fullscreenElement is a single\n // document-wide slot, so at most one in-flight request/exit is meaningful\n // per Core at a time.\n private _gen = 0;\n\n // True once observe() has attached the document-level fullscreenchange\n // listener. Guards observe() so a redundant call does not double-subscribe;\n // dispose() resets it so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // SSR (§10): 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 * Update the resolved target without issuing a fullscreen request (e.g. the\n * Shell re-resolves `target` on attribute change / connect). Re-evaluates\n * `active` against the current `document.fullscreenElement` so the state\n * stays correct even if the target changed while already fullscreen.\n */\n setTarget(element: Element | null): void {\n this._resolvedTarget = element;\n this._applyActive();\n }\n\n // Lifecycle (§10/§3.5). Idempotent: a second observe() while already\n // subscribed is a no-op (no double listener). Synchronous overall (no probe\n // to await), so the returned promise is only for API uniformity with other\n // IO nodes.\n observe(): Promise<void> {\n if (!this._subscribed) {\n this._subscribed = true;\n document.addEventListener(this._fullscreenChangeEventName(), this._onFullscreenChange);\n }\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n if (this._subscribed) {\n this._subscribed = false;\n document.removeEventListener(this._fullscreenChangeEventName(), this._onFullscreenChange);\n }\n }\n\n /**\n * Request fullscreen on `element`. never-throw (§3/§6): a missing API or a\n * rejected promise (e.g. a `TypeError` from a call outside a user\n * gesture, per the WHATWG Fullscreen spec's transient-activation check) is\n * caught and surfaced via `error`, never thrown. The caller\n * (Shell) is responsible for resolving `target` and for ensuring this is\n * invoked from within an actual user gesture — this Core cannot manufacture\n * one (docs/fullscreen-tag-design.md §3).\n */\n async requestFullscreen(element: Element | null): Promise<void> {\n const gen = ++this._gen;\n this._resolvedTarget = element;\n if (!element) {\n // Distinct from \"API is not supported\" (below): the Shell's `target`\n // selector did not resolve to any element (missing/typo'd selector).\n // Conflating the two previously misled users into thinking Fullscreen\n // itself was unsupported when only their selector was wrong.\n this._setError({ message: \"Fullscreen target could not be resolved.\" });\n return;\n }\n const fn = this._requestFullscreenFn(element);\n if (!fn) {\n this._setError({ message: \"Fullscreen API is not supported.\" });\n return;\n }\n try {\n await fn.call(element);\n if (gen !== this._gen) return; // stale: dispose()/superseding call ran\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 fullscreen. Silent no-op (§7) when nothing is currently fullscreen or\n * the API is unsupported — both are treated as \"already achieved the exit\n * intent\", not as errors, keeping repeated calls safe and never-throw.\n */\n async exitFullscreen(): Promise<void> {\n // no-op checks come BEFORE the generation bump: a call that does nothing\n // must not supersede an in-flight requestFullscreen() — bumping first\n // would make the pending request's settle handling stale and silently\n // swallow its error/active updates.\n if (this._fullscreenElement() === null) return; // already not fullscreen: silent no-op\n const fn = this._exitFullscreenFn();\n if (!fn) return; // unsupported: silent no-op (semantically already \"not fullscreen\")\n const gen = ++this._gen;\n try {\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 // --- API resolution layer (§4): call-time, never cached. Lets tests\n // install/remove the standard/legacy APIs freely and lets an unsupported\n // environment be detected correctly on every call. ---\n\n private _requestFullscreenFn(el: Element): (() => Promise<void>) | undefined {\n return this._elementFullscreenFn(el, \"requestFullscreen\")\n ?? this._elementFullscreenFn(el, \"webkitRequestFullscreen\");\n }\n\n // Resolve a fullscreen method for `el` WITHOUT a naive `el[name]` lookup.\n // A plain lookup walks the whole prototype chain — and <wcs-fullscreen>\n // itself declares a `requestFullscreen()` *command* method, so when the\n // resolved target is the Shell element (target=\"self\", or target omitted\n // with no children), the naive lookup would find the Shell's own command\n // instead of the platform API and recurse infinitely (stack overflow).\n // Instead: check the element's own properties (how tests install stubs —\n // happy-dom has no Fullscreen API — and how a deliberate per-element\n // monkey-patch would appear), then jump straight to Element.prototype,\n // where the platform defines the real methods. Both the standard and the\n // legacy webkit name go through this same resolution for symmetry.\n private _elementFullscreenFn(el: Element, name: string): (() => Promise<void>) | undefined {\n if (Object.prototype.hasOwnProperty.call(el, name)) {\n return (el as any)[name];\n }\n return (Element.prototype as any)[name];\n }\n\n private _exitFullscreenFn(): (() => Promise<void>) | undefined {\n const d = document as any;\n return d.exitFullscreen?.bind(document) ?? d.webkitExitFullscreen?.bind(document);\n }\n\n private _fullscreenElement(): Element | null {\n const d = document as any;\n return d.fullscreenElement ?? d.webkitFullscreenElement ?? null;\n }\n\n private _fullscreenChangeEventName(): string {\n return \"onfullscreenchange\" in document ? \"fullscreenchange\" : \"webkitfullscreenchange\";\n }\n\n // --- Internal ---\n\n private _onFullscreenChange = (): void => {\n this._applyActive();\n };\n\n // Re-derive `active` by comparing document.fullscreenElement (incl. legacy\n // fallback) against *this instance's* resolved target (§2/§2.1/§5). A null\n // resolved target always yields active=false — there is nothing for this\n // instance to claim as \"mine\".\n private _applyActive(): void {\n const next = this._resolvedTarget !== null && this._fullscreenElement() === this._resolvedTarget;\n this._setActive(next);\n }\n\n private _setActive(v: boolean): void {\n if (this._active === v) return; // same-value guard (§3.3 MUST)\n this._active = v;\n this._target.dispatchEvent(new CustomEvent(\"wcs-fullscreen:change\", {\n detail: { active: v },\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n this._error = error;\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { FullscreenCore } from \"../core/FullscreenCore.js\";\n\n/**\n * `<wcs-fullscreen target=\"...\">` — declarative Fullscreen API control.\n *\n * Like `intersection`/`resize`, this Shell operates on a *referenced* element,\n * not itself (docs/fullscreen-tag-design.md §0): `target` resolves which\n * element `requestFullscreen()`/`exitFullscreen()` are invoked on, using the\n * exact same 3-mode resolution as `<wcs-intersect>`\n * (docs/fullscreen-tag-design.md §1):\n *\n * | `target` | operates on | display | use case |\n * |-----------------|-------------------------|-------------|--------------------------|\n * | omitted | first element child | `contents` | wrap a gallery image/video |\n * | `\"#hero\"` / sel | the matched element | `none` | point at a distant node |\n * | `\"self\"` | the element itself | `block` | fullscreen the wrapper |\n *\n * `requestFullscreen()` requires an active user gesture — this element cannot\n * manufacture one. Invoke the command from within a real click handler\n * (typically via the command-token protocol: this element subscribes with\n * `command.requestFullscreen: $command.<token>`, and a button emits the\n * token from its own click handler, e.g. `onclick: $command.<token>`).\n */\nexport class WcsFullscreen extends HTMLElement {\n // SSR (§10): the fullscreenchange subscription is established synchronously\n // on connect, but the Shell still exposes connectedCallbackPromise so the\n // state binder can await it uniformly across all IO nodes before\n // snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static observedAttributes = [\"target\"];\n\n static wcBindable: IWcBindable = {\n ...FullscreenCore.wcBindable,\n inputs: [{ name: \"target\", attribute: \"target\" }],\n // Core の commands をそのまま継承(単一情報源)。network/intersection と同型。\n commands: FullscreenCore.wcBindable.commands,\n };\n\n private _core: FullscreenCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new FullscreenCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-fullscreen:change\": (d) => ({ active: d?.active === true }),\n });\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.1): 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 get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get target(): string {\n return this.getAttribute(\"target\") ?? \"\";\n }\n\n set target(value: string) {\n this.setAttribute(\"target\", value);\n }\n\n // --- Core delegated getters ---\n\n get active(): boolean {\n return this._core.active;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n // --- Commands ---\n\n /**\n * Resolve `target` and request fullscreen on it. never-throw: an\n * unresolvable target or an unsupported/rejected API call are both\n * surfaced via `error`, never thrown (docs/fullscreen-tag-design.md §3/§6).\n */\n async requestFullscreen(): Promise<void> {\n const { element } = this._resolveTarget();\n await this._core.requestFullscreen(element);\n }\n\n async exitFullscreen(): Promise<void> {\n await this._core.exitFullscreen();\n }\n\n // --- Internal ---\n\n // Copied verbatim from <wcs-intersect> (Intersect.ts _resolveTarget/_safeQuery,\n // docs/fullscreen-tag-design.md §1): identical 3-mode resolution, only the\n // \"what to do with the resolved element\" step differs.\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 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 private _reresolve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n this._core.setTarget(element);\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this._reresolve();\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n if (!this.isConnected) return;\n this._reresolve();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapFullscreen(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsFullscreen } from \"./components/Fullscreen.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.fullscreen)) {\n customElements.define(config.tagNames.fullscreen, WcsFullscreen);\n }\n}\n"],"names":["_config","tagNames","fullscreen","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","FullscreenCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","active","commands","async","_target","_active","_error","_resolvedTarget","_gen","_subscribed","_ready","Promise","resolve","constructor","target","super","this","ready","error","setTarget","element","_applyActive","observe","document","addEventListener","_fullscreenChangeEventName","_onFullscreenChange","dispose","removeEventListener","requestFullscreen","gen","_setError","message","fn","_requestFullscreenFn","call","exitFullscreen","_fullscreenElement","_exitFullscreenFn","el","_elementFullscreenFn","prototype","hasOwnProperty","Element","d","bind","webkitExitFullscreen","fullscreenElement","webkitFullscreenElement","next","_setActive","v","dispatchEvent","CustomEvent","bubbles","WcsFullscreen","HTMLElement","wcBindable","inputs","attribute","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","connectedCallbackPromise","getAttribute","value","setAttribute","_resolveTarget","display","scope","getRootNode","_safeQuery","child","firstElementChild","selector","querySelector","_reresolve","style","connectedCallback","disconnectedCallback","attributeChangedCallback","_name","oldValue","newValue","isConnected","bootstrapFullscreen","userConfig","partialConfig","assign","customElements","get","define"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/core/fullscreenCapabilities.ts","../src/core/FullscreenCore.ts","../src/components/Fullscreen.ts","../src/bootstrapFullscreen.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n fullscreen: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n fullscreen: \"wcs-fullscreen\",\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 * fullscreenCapabilities.ts\n *\n * Fullscreen node 固有の error code(taxonomy)と derivation。汎用の error info 型は\n * `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)から\n * import する。fullscreen は referenced element を操作するモニタ的ノードで競合 operation\n * を持たないため lane は無く、error taxonomy(errorInfo)のみを採用する。\n *\n * `_setError` は合成 `{ message }`(target 未解決 / API 非対応)と caught 例外\n * (`NotAllowedError` / `TypeError` = user gesture 外の requestFullscreen 拒否)を混在\n * 受理する。呼出側が明示 `code` を渡して合成側を曖昧さ無く分類し、caught は `.name` で\n * 分類する(storage / screen-orientation と同じ discriminator 方式)。\n */\n\nimport type { WcsIoErrorInfo } from \"./platformCapability.js\";\n\n/** 明示 code discriminator(合成エラーの呼出側が渡す)。 */\nexport type FullscreenErrorKind = \"capability-missing\" | \"invalid-argument\";\n\n/** 安定した fullscreen error code(taxonomy)。値は公開キーとして固定。 */\nexport const WCS_FULLSCREEN_ERROR_CODE = {\n /** Fullscreen API 非対応。 */\n CapabilityMissing: \"capability-missing\",\n /** target selector が要素に解決しない等の入力不備。 */\n InvalidArgument: \"invalid-argument\",\n /** `NotAllowedError` / `TypeError` — user gesture 外での要求拒否。 */\n NotAllowed: \"not-allowed\",\n /** その他の caught 例外。 */\n FullscreenError: \"fullscreen-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 * fullscreen の失敗を serializable な error taxonomy に写す。`kind` は合成エラーの\n * 呼出側が渡す明示 discriminator(`capability-missing` / `invalid-argument`)。未指定は\n * caught 例外を意味し、`.name` で分類する。`NotAllowedError` / `TypeError` は user\n * gesture 内で再試行すれば成功しうるため recoverable=true。\n */\nexport function deriveFullscreenErrorInfo(error: unknown, kind?: FullscreenErrorKind): WcsIoErrorInfo {\n const message = messageOf(error);\n if (kind === \"capability-missing\") {\n return { code: WCS_FULLSCREEN_ERROR_CODE.CapabilityMissing, phase: \"probe\", recoverable: false, message };\n }\n if (kind === \"invalid-argument\") {\n return { code: WCS_FULLSCREEN_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_FULLSCREEN_ERROR_CODE.NotAllowed, phase: \"execute\", recoverable: true, message };\n }\n return { code: WCS_FULLSCREEN_ERROR_CODE.FullscreenError, phase: \"execute\", recoverable: false, message };\n}\n","import { IWcBindable } from \"../types.js\";\nimport { WcsIoErrorInfo } from \"./platformCapability.js\";\nimport { deriveFullscreenErrorInfo, FullscreenErrorKind } from \"./fullscreenCapabilities.js\";\n\n/**\n * Headless Fullscreen API primitive. Unlike most wcstack IO nodes, this Core\n * does not operate on itself: it drives `requestFullscreen()` /\n * `exitFullscreen()` on a *referenced* Element that the Shell resolves via its\n * `target` attribute (docs/fullscreen-tag-design.md §0). The Core only ever\n * receives already-resolved `Element`s from its callers — it has no opinion on\n * how `target` selectors are parsed.\n *\n * `document.fullscreenElement` is a single document-wide value, so this Core\n * always compares against the *last element it resolved* (via\n * `requestFullscreen()`/`setTarget()`), never against \"is the document\n * fullscreen at all\" — that comparison is what keeps multiple concurrent\n * `<wcs-fullscreen>` instances from all reporting the same `active` value\n * (docs/fullscreen-tag-design.md §2.1, MUST).\n */\nexport class FullscreenCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"active\", event: \"wcs-fullscreen:change\", getter: (e: Event) => (e as CustomEvent).detail.active },\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 — fullscreen\n // drives a referenced element, not a competing operation.\n { name: \"error\", event: \"wcs-fullscreen:error\" },\n { name: \"errorInfo\", event: \"wcs-fullscreen:error-info-changed\" },\n ],\n commands: [\n { name: \"requestFullscreen\", async: true },\n { name: \"exitFullscreen\", async: true },\n ],\n };\n\n private _target: EventTarget;\n private _active: boolean = false;\n // Single error slot (§8): null means \"no recent failure\". Fullscreen's\n // gesture-rejection failure is a one-shot event, not a persistent state\n // machine like permission's 4-value surface — active/error are two\n // orthogonal, independently-observable axes.\n private _error: any = null;\n private _errorInfo: WcsIoErrorInfo | null = null;\n\n // The last Element this Core resolved via requestFullscreen()/setTarget().\n // Compared against document.fullscreenElement on every fullscreenchange so\n // each instance judges only its own target (§2.1). null means \"no target\n // resolved yet\" — active must stay false in that case.\n private _resolvedTarget: Element | null = null;\n\n // Generation guard (§6): Core-scoped (one per Core, not per-target),\n // mirroring fetch/upload. document.fullscreenElement is a single\n // document-wide slot, so at most one in-flight request/exit is meaningful\n // per Core at a time.\n private _gen = 0;\n\n // True once observe() has attached the document-level fullscreenchange\n // listener. Guards observe() so a redundant call does not double-subscribe;\n // dispose() resets it so a later observe() resumes cleanly.\n private _subscribed = false;\n\n // SSR (§10): 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-fullscreen: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 /**\n * Update the resolved target without issuing a fullscreen request (e.g. the\n * Shell re-resolves `target` on attribute change / connect). Re-evaluates\n * `active` against the current `document.fullscreenElement` so the state\n * stays correct even if the target changed while already fullscreen.\n */\n setTarget(element: Element | null): void {\n this._resolvedTarget = element;\n this._applyActive();\n }\n\n // Lifecycle (§10/§3.5). Idempotent: a second observe() while already\n // subscribed is a no-op (no double listener). Synchronous overall (no probe\n // to await), so the returned promise is only for API uniformity with other\n // IO nodes.\n observe(): Promise<void> {\n if (!this._subscribed) {\n this._subscribed = true;\n document.addEventListener(this._fullscreenChangeEventName(), this._onFullscreenChange);\n }\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n if (this._subscribed) {\n this._subscribed = false;\n document.removeEventListener(this._fullscreenChangeEventName(), this._onFullscreenChange);\n }\n }\n\n /**\n * Request fullscreen on `element`. never-throw (§3/§6): a missing API or a\n * rejected promise (e.g. a `TypeError` from a call outside a user\n * gesture, per the WHATWG Fullscreen spec's transient-activation check) is\n * caught and surfaced via `error`, never thrown. The caller\n * (Shell) is responsible for resolving `target` and for ensuring this is\n * invoked from within an actual user gesture — this Core cannot manufacture\n * one (docs/fullscreen-tag-design.md §3).\n */\n async requestFullscreen(element: Element | null): Promise<void> {\n const gen = ++this._gen;\n this._resolvedTarget = element;\n if (!element) {\n // Distinct from \"API is not supported\" (below): the Shell's `target`\n // selector did not resolve to any element (missing/typo'd selector).\n // Conflating the two previously misled users into thinking Fullscreen\n // itself was unsupported when only their selector was wrong.\n this._setError({ message: \"Fullscreen target could not be resolved.\" }, \"invalid-argument\");\n return;\n }\n const fn = this._requestFullscreenFn(element);\n if (!fn) {\n this._setError({ message: \"Fullscreen API is not supported.\" }, \"capability-missing\");\n return;\n }\n try {\n await fn.call(element);\n if (gen !== this._gen) return; // stale: dispose()/superseding call ran\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 fullscreen. Silent no-op (§7) when nothing is currently fullscreen or\n * the API is unsupported — both are treated as \"already achieved the exit\n * intent\", not as errors, keeping repeated calls safe and never-throw.\n */\n async exitFullscreen(): Promise<void> {\n // no-op checks come BEFORE the generation bump: a call that does nothing\n // must not supersede an in-flight requestFullscreen() — bumping first\n // would make the pending request's settle handling stale and silently\n // swallow its error/active updates.\n if (this._fullscreenElement() === null) return; // already not fullscreen: silent no-op\n const fn = this._exitFullscreenFn();\n if (!fn) return; // unsupported: silent no-op (semantically already \"not fullscreen\")\n const gen = ++this._gen;\n try {\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 // --- API resolution layer (§4): call-time, never cached. Lets tests\n // install/remove the standard/legacy APIs freely and lets an unsupported\n // environment be detected correctly on every call. ---\n\n private _requestFullscreenFn(el: Element): (() => Promise<void>) | undefined {\n return this._elementFullscreenFn(el, \"requestFullscreen\")\n ?? this._elementFullscreenFn(el, \"webkitRequestFullscreen\");\n }\n\n // Resolve a fullscreen method for `el` WITHOUT a naive `el[name]` lookup.\n // A plain lookup walks the whole prototype chain — and <wcs-fullscreen>\n // itself declares a `requestFullscreen()` *command* method, so when the\n // resolved target is the Shell element (target=\"self\", or target omitted\n // with no children), the naive lookup would find the Shell's own command\n // instead of the platform API and recurse infinitely (stack overflow).\n // Instead: check the element's own properties (how tests install stubs —\n // happy-dom has no Fullscreen API — and how a deliberate per-element\n // monkey-patch would appear), then jump straight to Element.prototype,\n // where the platform defines the real methods. Both the standard and the\n // legacy webkit name go through this same resolution for symmetry.\n private _elementFullscreenFn(el: Element, name: string): (() => Promise<void>) | undefined {\n if (Object.prototype.hasOwnProperty.call(el, name)) {\n return (el as any)[name];\n }\n return (Element.prototype as any)[name];\n }\n\n private _exitFullscreenFn(): (() => Promise<void>) | undefined {\n const d = document as any;\n return d.exitFullscreen?.bind(document) ?? d.webkitExitFullscreen?.bind(document);\n }\n\n private _fullscreenElement(): Element | null {\n const d = document as any;\n return d.fullscreenElement ?? d.webkitFullscreenElement ?? null;\n }\n\n private _fullscreenChangeEventName(): string {\n return \"onfullscreenchange\" in document ? \"fullscreenchange\" : \"webkitfullscreenchange\";\n }\n\n // --- Internal ---\n\n private _onFullscreenChange = (): void => {\n this._applyActive();\n };\n\n // Re-derive `active` by comparing document.fullscreenElement (incl. legacy\n // fallback) against *this instance's* resolved target (§2/§2.1/§5). A null\n // resolved target always yields active=false — there is nothing for this\n // instance to claim as \"mine\".\n private _applyActive(): void {\n const next = this._resolvedTarget !== null && this._fullscreenElement() === this._resolvedTarget;\n this._setActive(next);\n }\n\n private _setActive(v: boolean): void {\n if (this._active === v) return; // same-value guard (§3.3 MUST)\n this._active = v;\n this._target.dispatchEvent(new CustomEvent(\"wcs-fullscreen:change\", {\n detail: { active: 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?: FullscreenErrorKind): 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 : deriveFullscreenErrorInfo(error, kind));\n this._target.dispatchEvent(new CustomEvent(\"wcs-fullscreen: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-fullscreen:error-info-changed\", {\n detail: info,\n bubbles: true,\n }));\n }\n}\n","import { IWcBindable } from \"../types.js\";\nimport { FullscreenCore } from \"../core/FullscreenCore.js\";\nimport { WcsIoErrorInfo } from \"../core/platformCapability.js\";\n\n/**\n * `<wcs-fullscreen target=\"...\">` — declarative Fullscreen API control.\n *\n * Like `intersection`/`resize`, this Shell operates on a *referenced* element,\n * not itself (docs/fullscreen-tag-design.md §0): `target` resolves which\n * element `requestFullscreen()`/`exitFullscreen()` are invoked on, using the\n * exact same 3-mode resolution as `<wcs-intersect>`\n * (docs/fullscreen-tag-design.md §1):\n *\n * | `target` | operates on | display | use case |\n * |-----------------|-------------------------|-------------|--------------------------|\n * | omitted | first element child | `contents` | wrap a gallery image/video |\n * | `\"#hero\"` / sel | the matched element | `none` | point at a distant node |\n * | `\"self\"` | the element itself | `block` | fullscreen the wrapper |\n *\n * `requestFullscreen()` requires an active user gesture — this element cannot\n * manufacture one. Invoke the command from within a real click handler\n * (typically via the command-token protocol: this element subscribes with\n * `command.requestFullscreen: $command.<token>`, and a button emits the\n * token from its own click handler, e.g. `onclick: $command.<token>`).\n */\nexport class WcsFullscreen extends HTMLElement {\n // SSR (§10): the fullscreenchange subscription is established synchronously\n // on connect, but the Shell still exposes connectedCallbackPromise so the\n // state binder can await it uniformly across all IO nodes before\n // snapshotting.\n static hasConnectedCallbackPromise = true;\n\n static observedAttributes = [\"target\"];\n\n static wcBindable: IWcBindable = {\n ...FullscreenCore.wcBindable,\n inputs: [{ name: \"target\", attribute: \"target\" }],\n // Core の commands をそのまま継承(単一情報源)。network/intersection と同型。\n commands: FullscreenCore.wcBindable.commands,\n };\n\n private _core: FullscreenCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new FullscreenCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-fullscreen:change\": (d) => ({ active: d?.active === true }),\n });\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.1): 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 get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\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 fullscreen on it. never-throw: an\n * unresolvable target or an unsupported/rejected API call are both\n * surfaced via `error`, never thrown (docs/fullscreen-tag-design.md §3/§6).\n */\n async requestFullscreen(): Promise<void> {\n const { element } = this._resolveTarget();\n await this._core.requestFullscreen(element);\n }\n\n async exitFullscreen(): Promise<void> {\n await this._core.exitFullscreen();\n }\n\n // --- Internal ---\n\n // Copied verbatim from <wcs-intersect> (Intersect.ts _resolveTarget/_safeQuery,\n // docs/fullscreen-tag-design.md §1): identical 3-mode resolution, only the\n // \"what to do with the resolved element\" step differs.\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 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 private _reresolve(): void {\n const { element, display } = this._resolveTarget();\n this.style.display = display;\n this._core.setTarget(element);\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n this._reresolve();\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n\n attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n if (!this.isConnected) return;\n this._reresolve();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapFullscreen(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsFullscreen } from \"./components/Fullscreen.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.fullscreen)) {\n customElements.define(config.tagNames.fullscreen, WcsFullscreen);\n }\n}\n"],"names":["_config","tagNames","fullscreen","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","WCS_FULLSCREEN_ERROR_CODE","CapabilityMissing","InvalidArgument","NotAllowed","FullscreenError","deriveFullscreenErrorInfo","error","kind","message","String","messageOf","code","phase","recoverable","name","FullscreenCore","EventTarget","static","protocol","version","properties","event","getter","e","detail","active","commands","async","_target","_active","_error","_errorInfo","_resolvedTarget","_gen","_subscribed","_ready","Promise","resolve","constructor","target","super","this","ready","errorInfo","setTarget","element","_applyActive","observe","document","addEventListener","_fullscreenChangeEventName","_onFullscreenChange","dispose","removeEventListener","requestFullscreen","gen","_setError","fn","_requestFullscreenFn","call","exitFullscreen","_fullscreenElement","_exitFullscreenFn","el","_elementFullscreenFn","prototype","hasOwnProperty","Element","d","bind","webkitExitFullscreen","fullscreenElement","webkitFullscreenElement","next","_setActive","v","dispatchEvent","CustomEvent","bubbles","_commitErrorInfo","info","WcsFullscreen","HTMLElement","wcBindable","inputs","attribute","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","connectedCallbackPromise","getAttribute","value","setAttribute","_resolveTarget","display","scope","getRootNode","_safeQuery","child","firstElementChild","selector","querySelector","_reresolve","style","connectedCallback","disconnectedCallback","attributeChangedCallback","_name","oldValue","newValue","isConnected","bootstrapFullscreen","userConfig","partialConfig","assign","customElements","get","define"],"mappings":"AAQA,MAAMA,EAA2B,CAC/BC,SAAU,CACRC,WAAY,mBAIhB,SAASC,EAAcC,GACrB,GAAY,OAARA,GAA+B,iBAARA,EAAkB,OAAOA,EACpDC,OAAOC,OAAOF,GACd,IAAK,MAAMG,KAAOF,OAAOG,KAAKJ,GAC5BD,EAAYC,EAAgCG,IAE9C,OAAOH,CACT,CAEA,SAASK,EAAaL,GACpB,GAAY,OAARA,GAA+B,iBAARA,EAAkB,OAAOA,EACpD,MAAMM,EAAiC,CAAA,EACvC,IAAK,MAAMH,KAAOF,OAAOG,KAAKJ,GAC5BM,EAAMH,GAAOE,EAAWL,EAAgCG,IAE1D,OAAOG,CACT,CAEA,IAAIC,EAA+B,KAE5B,MAAMC,EAAkBZ,WAEfa,IAId,OAHKF,IACHA,EAAeR,EAAWM,EAAUT,KAE/BW,CACT,CCrBO,MAAMG,EAA4B,CAEvCC,kBAAmB,qBAEnBC,gBAAiB,mBAEjBC,WAAY,cAEZC,gBAAiB,oBAeb,SAAUC,EAA0BC,EAAgBC,GACxD,MAAMC,EAbR,SAAmBF,GACjB,MAAmE,iBAApDA,GAAwCE,QAClDF,EAA8BE,QAC/BC,OAAOH,EACb,CASkBI,CAAUJ,GAC1B,GAAa,uBAATC,EACF,MAAO,CAAEI,KAAMX,EAA0BC,kBAAmBW,MAAO,QAASC,aAAa,EAAOL,WAElG,GAAa,qBAATD,EACF,MAAO,CAAEI,KAAMX,EAA0BE,gBAAiBU,MAAO,QAASC,aAAa,EAAOL,WAEhG,MAAMM,EAAQR,GAAqCQ,KACnD,MAAa,oBAATA,GAAuC,cAATA,EACzB,CAAEH,KAAMX,EAA0BG,WAAYS,MAAO,UAAWC,aAAa,EAAML,WAErF,CAAEG,KAAMX,EAA0BI,gBAAiBQ,MAAO,UAAWC,aAAa,EAAOL,UAClG,CCrCM,MAAOO,UAAuBC,YAClCC,kBAAiC,CAC/BC,SAAU,cACVC,QAAS,EACTC,WAAY,CACV,CAAEN,KAAM,SAAUO,MAAO,wBAAyBC,OAASC,GAAcA,EAAkBC,OAAOC,QAOlG,CAAEX,KAAM,QAASO,MAAO,wBACxB,CAAEP,KAAM,YAAaO,MAAO,sCAE9BK,SAAU,CACR,CAAEZ,KAAM,oBAAqBa,OAAO,GACpC,CAAEb,KAAM,iBAAkBa,OAAO,KAI7BC,QACAC,SAAmB,EAKnBC,OAAc,KACdC,WAAoC,KAMpCC,gBAAkC,KAMlCC,KAAO,EAKPC,aAAc,EAIdC,OAAwBC,QAAQC,UAExC,WAAAC,CAAYC,GACVC,QACAC,KAAKb,QAAUW,GAAUE,IAC3B,CAEA,SAAIC,GACF,OAAOD,KAAKN,MACd,CAEA,UAAIV,GACF,OAAOgB,KAAKZ,OACd,CAEA,SAAIvB,GACF,OAAOmC,KAAKX,MACd,CAQA,aAAIa,GACF,OAAOF,KAAKV,UACd,CAQA,SAAAa,CAAUC,GACRJ,KAAKT,gBAAkBa,EACvBJ,KAAKK,cACP,CAMA,OAAAC,GAKE,OAJKN,KAAKP,cACRO,KAAKP,aAAc,EACnBc,SAASC,iBAAiBR,KAAKS,6BAA8BT,KAAKU,sBAE7DV,KAAKN,MACd,CAEA,OAAAiB,GACEX,KAAKR,OACDQ,KAAKP,cACPO,KAAKP,aAAc,EACnBc,SAASK,oBAAoBZ,KAAKS,6BAA8BT,KAAKU,qBAEzE,CAWA,uBAAMG,CAAkBT,GACtB,MAAMU,IAAQd,KAAKR,KAEnB,GADAQ,KAAKT,gBAAkBa,GAClBA,EAMH,YADAJ,KAAKe,UAAU,CAAEhD,QAAS,4CAA8C,oBAG1E,MAAMiD,EAAKhB,KAAKiB,qBAAqBb,GACrC,GAAKY,EAIL,IAEE,SADMA,EAAGE,KAAKd,GACVU,IAAQd,KAAKR,KAAM,OACvBQ,KAAKe,UAAU,MACff,KAAKK,cACP,CAAE,MAAOvB,GACP,GAAIgC,IAAQd,KAAKR,KAAM,OACvBQ,KAAKe,UAAUjC,EACjB,MAXEkB,KAAKe,UAAU,CAAEhD,QAAS,oCAAsC,qBAYpE,CAOA,oBAAMoD,GAKJ,GAAkC,OAA9BnB,KAAKoB,qBAA+B,OACxC,MAAMJ,EAAKhB,KAAKqB,oBAChB,IAAKL,EAAI,OACT,MAAMF,IAAQd,KAAKR,KACnB,IAEE,SADMwB,IACFF,IAAQd,KAAKR,KAAM,OACvBQ,KAAKe,UAAU,MACff,KAAKK,cACP,CAAE,MAAOvB,GACP,GAAIgC,IAAQd,KAAKR,KAAM,OACvBQ,KAAKe,UAAUjC,EACjB,CACF,CAMQ,oBAAAmC,CAAqBK,GAC3B,OAAOtB,KAAKuB,qBAAqBD,EAAI,sBAChCtB,KAAKuB,qBAAqBD,EAAI,0BACrC,CAaQ,oBAAAC,CAAqBD,EAAajD,GACxC,OAAIvB,OAAO0E,UAAUC,eAAeP,KAAKI,EAAIjD,GACnCiD,EAAWjD,GAEbqD,QAAQF,UAAkBnD,EACpC,CAEQ,iBAAAgD,GACN,MAAMM,EAAIpB,SACV,OAAOoB,EAAER,gBAAgBS,KAAKrB,WAAaoB,EAAEE,sBAAsBD,KAAKrB,SAC1E,CAEQ,kBAAAa,GACN,MAAMO,EAAIpB,SACV,OAAOoB,EAAEG,mBAAqBH,EAAEI,yBAA2B,IAC7D,CAEQ,0BAAAtB,GACN,MAAO,uBAAwBF,SAAW,mBAAqB,wBACjE,CAIQG,oBAAsB,KAC5BV,KAAKK,gBAOC,YAAAA,GACN,MAAM2B,EAAgC,OAAzBhC,KAAKT,iBAA4BS,KAAKoB,uBAAyBpB,KAAKT,gBACjFS,KAAKiC,WAAWD,EAClB,CAEQ,UAAAC,CAAWC,GACblC,KAAKZ,UAAY8C,IACrBlC,KAAKZ,QAAU8C,EACflC,KAAKb,QAAQgD,cAAc,IAAIC,YAAY,wBAAyB,CAClErD,OAAQ,CAAEC,OAAQkD,GAClBG,SAAS,KAEb,CAMQ,SAAAtB,CAAUlD,EAAYC,GAIxBkC,KAAKX,SAAWxB,IACpBmC,KAAKX,OAASxB,EAGdmC,KAAKsC,iBAA2B,OAAVzE,EAAiB,KAAOD,EAA0BC,EAAOC,IAC/EkC,KAAKb,QAAQgD,cAAc,IAAIC,YAAY,uBAAwB,CACjErD,OAAQlB,EACRwE,SAAS,KAEb,CAIQ,gBAAAC,CAAiBC,GACvBvC,KAAKV,WAAaiD,EAClBvC,KAAKb,QAAQgD,cAAc,IAAIC,YAAY,oCAAqC,CAC9ErD,OAAQwD,EACRF,SAAS,IAEb,EChQI,MAAOG,UAAsBC,YAKjCjE,oCAAqC,EAErCA,0BAA4B,CAAC,UAE7BA,kBAAiC,IAC5BF,EAAeoE,WAClBC,OAAQ,CAAC,CAAEtE,KAAM,SAAUuE,UAAW,WAEtC3D,SAAUX,EAAeoE,WAAWzD,UAG9B4D,MACAC,0BAA2CnD,QAAQC,UACnDmD,WAAsC,KAE9C,WAAAlD,GACEE,QACAC,KAAK6C,MAAQ,IAAIvE,EAAe0B,MAChCA,KAAK+C,WAAa/C,KAAKgD,iBACvBhD,KAAKiD,YAAY,CACf,wBAA0BtB,KAAS3C,QAAsB,IAAd2C,GAAG3C,UAElD,CAMA,eAAIkE,GACF,OAAOlD,KAAK+C,WAAa,IAAI/C,KAAK+C,WAAWI,QAAU,EACzD,CAEQ,cAAAH,GAMN,IACE,GAAoC,mBAAzBhD,KAAKoD,gBAAgC,OAAO,KACvD,MAAMC,EAAYrD,KAAKoD,kBAGvB,OAFAC,EAAUF,OAAOG,IAAI,aACrBD,EAAUF,OAAOI,OAAO,aACjBF,CACT,CAAE,MACA,OAAO,IACT,CACF,CAEQ,WAAAJ,CAAYO,GAClB,GAAwB,OAApBxD,KAAK+C,WAAqB,OAC9B,MAAMI,EAASnD,KAAK+C,WAAWI,OAC/B,IAAK,MAAOvE,EAAO6E,KAAa3G,OAAO4G,QAAQF,GAC7CxD,KAAKQ,iBAAiB5B,EAAQE,IAC5B,MAAM6E,EAAQ3D,KAAK4D,aAAa,gBAChC,IAAK,MAAOvF,EAAMwF,KAAO/G,OAAO4G,QAAQD,EAAU3E,EAAkBC,SAAU,CAC5E,IACM8E,EAAMV,EAAOG,IAAIjF,GAAgB8E,EAAOI,OAAOlF,EACrD,CAAE,MAA0B,CACxBsF,GAAO3D,KAAK8D,gBAAgB,kBAAkBzF,IAAQwF,EAC5D,GAGN,CAEA,4BAAIE,GACF,OAAO/D,KAAK8C,yBACd,CAIA,UAAIhD,GACF,OAAOE,KAAKgE,aAAa,WAAa,EACxC,CAEA,UAAIlE,CAAOmE,GACTjE,KAAKkE,aAAa,SAAUD,EAC9B,CAIA,UAAIjF,GACF,OAAOgB,KAAK6C,MAAM7D,MACpB,CAEA,SAAInB,GACF,OAAOmC,KAAK6C,MAAMhF,KACpB,CAEA,aAAIqC,GACF,OAAOF,KAAK6C,MAAM3C,SACpB,CASA,uBAAMW,GACJ,MAAMT,QAAEA,GAAYJ,KAAKmE,uBACnBnE,KAAK6C,MAAMhC,kBAAkBT,EACrC,CAEA,oBAAMe,SACEnB,KAAK6C,MAAM1B,gBACnB,CAOQ,cAAAgD,GACN,MAAMrE,EAASE,KAAKF,OACpB,GAAe,SAAXA,EACF,MAAO,CAAEM,QAASJ,KAAMoE,QAAS,SAEnC,GAAe,KAAXtE,EAAe,CACjB,MAAMuE,EAAQrE,KAAKsE,cACnB,MAAO,CAAElE,QAASJ,KAAKuE,WAAWF,EAAOvE,GAASsE,QAAS,OAC7D,CACA,MAAMI,EAAQxE,KAAKyE,kBACnB,OAAID,EACK,CAAEpE,QAASoE,EAAOJ,QAAS,YAE7B,CAAEhE,QAASJ,KAAMoE,QAAS,QACnC,CAEQ,UAAAG,CAAWF,EAA8BK,GAC/C,IACE,OAAOL,EAAMM,cAAcD,EAC7B,CAAE,MACA,OAAO,IACT,CACF,CAEQ,UAAAE,GACN,MAAMxE,QAAEA,EAAOgE,QAAEA,GAAYpE,KAAKmE,iBAClCnE,KAAK6E,MAAMT,QAAUA,EACrBpE,KAAK6C,MAAM1C,UAAUC,EACvB,CAIA,iBAAA0E,GACE9E,KAAK4E,aACL5E,KAAK8C,0BAA4B9C,KAAK6C,MAAMvC,SAC9C,CAEA,oBAAAyE,GACE/E,KAAK6C,MAAMlC,SACb,CAEA,wBAAAqE,CAAyBC,EAAeC,EAAyBC,GAC3DD,IAAaC,GACZnF,KAAKoF,aACVpF,KAAK4E,YACP,ECzLI,SAAUS,EAAoBC,GJuC9B,IAAoBC,EItCpBD,KJsCoBC,EIrCZD,GJsCM5I,UAChBI,OAAO0I,OAAO/I,EAAQC,SAAU6I,EAAc7I,UAEhDU,EAAe,MK3CVqI,eAAeC,IAAIrI,EAAOX,SAASC,aACtC8I,eAAeE,OAAOtI,EAAOX,SAASC,WAAY6F,EDItD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wcstack/fullscreen",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"description": "Declarative Fullscreen API component for Web Components. Framework-agnostic requestFullscreen()/exitFullscreen() control via wc-bindable-protocol.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.esm.js",
|