haori-bootstrap 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Haori.js Bootstrap は、Haori.js 向けの Bootstrap ベース UI 拡張ライブラリです。
4
4
 
5
- Version: 0.2.0
5
+ Version: 0.3.0
6
6
 
7
7
  ## 概要
8
8
 
@@ -13,7 +13,7 @@ Version: 0.2.0
13
13
  - 対応 Bootstrap バージョン: 5.3.x
14
14
  - 配布形式: ESM と IIFE
15
15
 
16
- npm パッケージ名は `haori-js-bootstrap` から `haori-bootstrap` へ変更しました。既存利用者は新しい package 名へ移行してください。GitHub リポジトリ名は変更していません。
16
+ npm パッケージ名は `haori-js-bootstrap` から `haori-bootstrap` へ変更し、旧 package は deprecated にしました。既存利用者は新しい package 名へ移行してください。GitHub リポジトリ名は変更していません。
17
17
 
18
18
  Haori.js の dialog、confirm、toast、openDialog、closeDialog、addErrorMessage、clearMessages などの UI 系静的メソッドを Bootstrap ベース実装へ差し替えつつ、既存の Procedure 連携を維持します。
19
19
 
@@ -41,9 +41,9 @@ npm install haori-bootstrap
41
41
  rel="stylesheet"
42
42
  href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
43
43
  />
44
- <script src="https://cdn.jsdelivr.net/npm/haori@0.1.2/dist/haori.iife.js"></script>
44
+ <script src="https://cdn.jsdelivr.net/npm/haori@0.1.5/dist/haori.iife.js"></script>
45
45
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
46
- <script src="https://cdn.jsdelivr.net/npm/haori-bootstrap@0.2.0/dist/haori-bootstrap.iife.js"></script>
46
+ <script src="https://cdn.jsdelivr.net/npm/haori-bootstrap@0.3.0/dist/haori-bootstrap.iife.js"></script>
47
47
  ```
48
48
 
49
49
  IIFE 版は、window.Haori と window.bootstrap が利用可能な場合に自動で有効化されます。
@@ -63,6 +63,7 @@ import { install } from 'haori-bootstrap';
63
63
 
64
64
  install({
65
65
  fallbackToNative: true,
66
+ runtime: 'demo',
66
67
  });
67
68
  ```
68
69
 
@@ -77,7 +78,7 @@ install({
77
78
  | closeDialog(element) | 任意要素の非表示 | Promise<void> |
78
79
  | addErrorMessage(target, message) | 管理対象エラーメッセージの追加 | Promise<void> |
79
80
  | clearMessages(parentOrTarget) | 管理対象メッセージのみ削除 | Promise<void> |
80
- | install(options) | Bootstrap 対応 Haori を再適用し設定を上書き | void |
81
+ | install(options) | Bootstrap 対応 Haori を再適用し、runtime を含めて設定を上書き | void |
81
82
  | uninstall() | 元の Haori 実装を復元 | void |
82
83
 
83
84
  ## Procedure 連携例
@@ -130,16 +131,16 @@ push 後に、そのタグから GitHub Release を published にします。公
130
131
  次回 patch リリースの例:
131
132
 
132
133
  ```bash
133
- # version が 0.2.1 になる
134
+ # version が 0.3.1 になる
134
135
  npm version patch
135
136
  git push origin main --follow-tags
136
137
  ```
137
138
 
138
- その後、push 済みタグの GitHub Release を作成して published にします。例として次回は `0.2.1` タグになります。
139
+ その後、push 済みタグの GitHub Release を作成して published にします。例として次回は `0.3.1` タグになります。
139
140
 
140
141
  自動公開:
141
142
 
142
- - `npm version patch` で、src/index.ts の公開用 `version` 定数も package.json と同期されます。
143
+ - `npm version patch` で、src/index.ts の公開用 `version` 定数、README の例、CDN デモ、Playwright の CDN 確認も package.json と同期されます。
143
144
  - publish-on-release.yml がパッケージを build し、npm publish を実行します。
144
145
  - release-archive.yml が dist/ を build し、dist.zip を同じ GitHub Release へ添付します。
145
146
 
@@ -150,12 +151,12 @@ git push origin main --follow-tags
150
151
  - npm アカウントで 2FA を有効化している場合は、write 操作用の bypass 2FA を有効にした token を使います。
151
152
  - `NPM_TOKEN` の作成に、パッケージの事前公開は不要です。
152
153
 
153
- 名称変更後の初回 `0.2.0` 公開の例:
154
+ 名称変更後の初回 `0.3.0` 公開の例:
154
155
 
155
156
  ```bash
156
157
  git push origin main
157
- git tag 0.2.0
158
- git push origin 0.2.0
158
+ git tag 0.3.0
159
+ git push origin 0.3.0
159
160
  ```
160
161
 
161
162
  初回公開チェックリスト:
@@ -170,6 +171,7 @@ git push origin 0.2.0
170
171
 
171
172
  - English README: [README.md](README.md)
172
173
  - 初期設計書: [doc/Haori.js Bootstrap初期設計書.md](doc/Haori.js Bootstrap初期設計書.md)
174
+ - ブラウザデモ時の Procedure 挙動提案: [doc/ブラウザデモ時Procedure挙動仕様提案.md](doc/%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%83%87%E3%83%A2%E6%99%82Procedure%E6%8C%99%E5%8B%95%E4%BB%95%E6%A7%98%E6%8F%90%E6%A1%88.md)
173
175
  - 変更履歴: [CHANGELOG.md](CHANGELOG.md)
174
176
 
175
177
  ## 補足
@@ -178,3 +180,4 @@ git push origin 0.2.0
178
180
  - Haori.js は前提依存として扱い、本ライブラリへ同梱しません。
179
181
  - CDN でブラウザ直読み込みする場合の配布物は dist/haori-bootstrap.iife.js です。
180
182
  - npm 公開時のエントリは dist/haori-bootstrap.js、型定義は dist/index.d.ts です。
183
+ - ブラウザデモ時の通信正規化は上記の提案書で検討しており、現時点の公開 API には含めていません。
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Haori.js Bootstrap is a Bootstrap-based UI extension library for Haori.js.
4
4
 
5
- Version: 0.2.0
5
+ Version: 0.3.0
6
6
 
7
7
  ## Overview
8
8
 
@@ -13,7 +13,7 @@ Version: 0.2.0
13
13
  - Supported Bootstrap version: 5.3.x
14
14
  - Distributed formats: ESM and IIFE
15
15
 
16
- The npm package has been renamed from `haori-js-bootstrap` to `haori-bootstrap`. Existing installations should migrate to the new package name. The GitHub repository name remains unchanged.
16
+ The npm package has been renamed from `haori-js-bootstrap` to `haori-bootstrap`, and the previous package is now deprecated. Existing installations should migrate to the new package name. The GitHub repository name remains unchanged.
17
17
 
18
18
  The library replaces Haori.js static UI methods such as dialog, confirm, toast, openDialog, closeDialog, addErrorMessage, and clearMessages with Bootstrap-based behavior while keeping existing Procedure integration intact.
19
19
 
@@ -41,9 +41,9 @@ Load dependencies in this order for browser direct loading:
41
41
  rel="stylesheet"
42
42
  href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
43
43
  />
44
- <script src="https://cdn.jsdelivr.net/npm/haori@0.1.2/dist/haori.iife.js"></script>
44
+ <script src="https://cdn.jsdelivr.net/npm/haori@0.1.5/dist/haori.iife.js"></script>
45
45
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
46
- <script src="https://cdn.jsdelivr.net/npm/haori-bootstrap@0.2.0/dist/haori-bootstrap.iife.js"></script>
46
+ <script src="https://cdn.jsdelivr.net/npm/haori-bootstrap@0.3.0/dist/haori-bootstrap.iife.js"></script>
47
47
  ```
48
48
 
49
49
  The IIFE build auto-enables when both window.Haori and window.bootstrap are available.
@@ -63,6 +63,7 @@ import { install } from 'haori-bootstrap';
63
63
 
64
64
  install({
65
65
  fallbackToNative: true,
66
+ runtime: 'demo',
66
67
  });
67
68
  ```
68
69
 
@@ -77,7 +78,7 @@ install({
77
78
  | closeDialog(element) | Close an arbitrary dialog element | Promise<void> |
78
79
  | addErrorMessage(target, message) | Append managed error messages | Promise<void> |
79
80
  | clearMessages(parentOrTarget) | Remove only managed messages | Promise<void> |
80
- | install(options) | Re-apply Bootstrap-backed Haori with overridden options | void |
81
+ | install(options) | Re-apply Bootstrap-backed Haori with overridden options, including runtime | void |
81
82
  | uninstall() | Restore the original Haori implementation | void |
82
83
 
83
84
  ## Procedure Integration Example
@@ -127,19 +128,19 @@ git push origin main --follow-tags
127
128
 
128
129
  After pushing, publish a GitHub Release from the generated version tag. The release workflow then publishes the package and uploads `dist.zip` automatically.
129
130
 
130
- Example next patch release after `0.2.0`:
131
+ Example next patch release after `0.3.0`:
131
132
 
132
133
  ```bash
133
- # version becomes 0.2.1
134
+ # version becomes 0.3.1
134
135
  npm version patch
135
136
  git push origin main --follow-tags
136
137
  ```
137
138
 
138
- Create and publish the GitHub Release for the pushed tag such as `0.2.1`.
139
+ Create and publish the GitHub Release for the pushed tag such as `0.3.1`.
139
140
 
140
141
  Release automation:
141
142
 
142
- - `npm version patch` also keeps the exported `version` constant in src/index.ts in sync.
143
+ - `npm version patch` also keeps the exported `version` constant, README examples, CDN demo, and Playwright CDN checks in sync.
143
144
  - publish-on-release.yml builds the package and runs npm publish.
144
145
  - release-archive.yml builds dist/ and uploads dist.zip to the same GitHub Release.
145
146
 
@@ -150,12 +151,12 @@ First release only:
150
151
  - If npm account 2FA is enabled, create the token with bypass 2FA for write actions.
151
152
  - The package does not need to be published already to create `NPM_TOKEN`.
152
153
 
153
- Example for the first `0.2.0` release after the package rename:
154
+ Example for the first `0.3.0` release after the package rename:
154
155
 
155
156
  ```bash
156
157
  git push origin main
157
- git tag 0.2.0
158
- git push origin 0.2.0
158
+ git tag 0.3.0
159
+ git push origin 0.3.0
159
160
  ```
160
161
 
161
162
  First release checklist:
@@ -170,6 +171,7 @@ First release checklist:
170
171
 
171
172
  - Japanese README: [README.ja.md](README.ja.md)
172
173
  - Initial design: [doc/Haori.js Bootstrap初期設計書.md](doc/Haori.js Bootstrap初期設計書.md)
174
+ - Browser demo procedure proposal: [doc/ブラウザデモ時Procedure挙動仕様提案.md](doc/%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%83%87%E3%83%A2%E6%99%82Procedure%E6%8C%99%E5%8B%95%E4%BB%95%E6%A7%98%E6%8F%90%E6%A1%88.md)
173
175
  - Changelog: [CHANGELOG.md](CHANGELOG.md)
174
176
 
175
177
  ## Notes
@@ -178,3 +180,4 @@ First release checklist:
178
180
  - Haori.js is treated as a prerequisite and is not bundled into this package.
179
181
  - Browser direct loading for CDN consumers uses dist/haori-bootstrap.iife.js.
180
182
  - The published npm entry is dist/haori-bootstrap.js with types at dist/index.d.ts.
183
+ - Browser demo transport normalization is discussed in the proposal document above and is not part of the current public API.
@@ -1,3 +1,3 @@
1
- var HaoriBootstrap=(function(m){"use strict";function P(e){return typeof e=="function"}function _(e){return P(e?.Modal)?e?.Modal:void 0}function x(e){return P(e?.Toast)?e?.Toast:void 0}function E(e){return!!_(e)}function Y(e){return!!x(e)}function C(e,t,o){const n=_(o);if(n)return typeof n.getOrCreateInstance=="function"?n.getOrCreateInstance(e,t):new n(e,t)}function Z(e,t){const o=x(t);if(o)return typeof o.getOrCreateInstance=="function"?o.getOrCreateInstance(e):new o(e)}const ee="data-haori-bootstrap-dialog",v="data-haori-bootstrap-action";function D(){return{backdrop:"static"}}function R(e,t){if(t.dialogContainerSelector){const o=e.querySelector(t.dialogContainerSelector);if(o)return o}return e.body}function q(e,t,o){const n=e.createElement("div");n.className="modal fade",n.tabIndex=-1,n.setAttribute(ee,"true"),n.setAttribute("aria-hidden","true");const r=e.createElement("div");r.className="modal-dialog modal-dialog-centered";const i=e.createElement("div");i.className="modal-content";const u=e.createElement("div");u.className="modal-body";const a=e.createElement("p");a.className="mb-0",a.style.whiteSpace="pre-line",a.textContent=t,u.appendChild(a);const s=e.createElement("div");if(s.className="modal-footer",o){const f=e.createElement("button");f.type="button",f.className="btn btn-secondary",f.setAttribute(v,"cancel"),f.textContent="Cancel",s.appendChild(f)}const c=e.createElement("button");return c.type="button",c.className="btn btn-primary",c.setAttribute(v,"ok"),c.textContent="OK",s.appendChild(c),i.append(u,s),r.appendChild(i),n.appendChild(r),n}function te(e,t){const o=globalThis.document,n=q(o,e,!1);R(o,t).appendChild(n);const r=C(n,D(),t.bootstrap);return r?new Promise((i,u)=>{const a=()=>{n.removeEventListener("hidden.bs.modal",s),n.remove(),r.dispose?.(),i()},s=()=>{a()};n.querySelector(`[${v}="ok"]`)?.addEventListener("click",()=>{r.hide()},{once:!0}),n.addEventListener("hidden.bs.modal",s,{once:!0});try{r.show()}catch(f){n.removeEventListener("hidden.bs.modal",s),n.remove(),r.dispose?.(),u(f)}}):(n.remove(),Promise.reject(new Error("Bootstrap Modal is unavailable.")))}function oe(e,t){const o=globalThis.document,n=q(o,e,!0);R(o,t).appendChild(n);const r=C(n,D(),t.bootstrap);return r?new Promise((i,u)=>{let a=!1;const s=()=>{n.removeEventListener("hidden.bs.modal",c),n.remove(),r.dispose?.(),i(a)},c=()=>{s()},f=n.querySelector(`[${v}="ok"]`),ke=n.querySelector(`[${v}="cancel"]`);f?.addEventListener("click",()=>{a=!0,r.hide()},{once:!0}),ke?.addEventListener("click",()=>{a=!1,r.hide()},{once:!0}),n.addEventListener("hidden.bs.modal",c,{once:!0});try{r.show()}catch(Be){n.removeEventListener("hidden.bs.modal",c),n.remove(),r.dispose?.(),u(Be)}}):(n.remove(),Promise.reject(new Error("Bootstrap Modal is unavailable.")))}const T="data-haori-bootstrap-owned",p="data-haori-bootstrap-message-container",h="data-haori-bootstrap-invalid-target";function M(e){return e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")}function g(e){return e instanceof HTMLInputElement&&e.type==="radio"}function I(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function N(e){return Array.from(e.children).find(t=>t instanceof HTMLElement&&t.getAttribute(p)==="true")}function ne(e,t){const o=e.createElement("div");return o.setAttribute(T,"true"),o.textContent=t,o}function re(e){return N(e)}function S(e){if(e.name){const t=e.form??e.ownerDocument,o=typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(e.name):e.name.replace(/(["\\])/g,"\\$1"),n=Array.from(t.querySelectorAll(`input[type="radio"][name="${o}"]`));if(n.length>0)return n}return[e]}function ie(e){const[t,...o]=e;if(!t)return;let n=t;for(;n;){if(o.every(r=>n?.contains(r)))return n;n=n.parentElement}}function $(e){const o=S(e).map(n=>n.closest(".form-check")).filter(n=>n instanceof HTMLElement);if(o.length>1){const n=ie(o);if(n&&!o.includes(n))return n}return k(e)}function k(e){const t=e.closest(".form-check");return t instanceof HTMLElement?t:void 0}function U(e){const t=e.nextElementSibling;if(t instanceof HTMLElement&&t.getAttribute(p)==="true")return t;const o=document.createElement("div");return o.className="invalid-feedback d-block",o.setAttribute(T,"true"),o.setAttribute(p,"true"),e.insertAdjacentElement("afterend",o),o}function ae(e){const t=g(e)?$(e):k(e);if(!t)return U(e);const o=N(t);if(o)return o;const n=document.createElement("div");return n.className="invalid-feedback d-block",n.setAttribute(T,"true"),n.setAttribute(p,"true"),t.appendChild(n),n}function se(e){const t=re(e);if(t)return t;const o=document.createElement("div");return o.className="alert alert-danger",o.setAttribute("role","alert"),o.setAttribute(T,"true"),o.setAttribute(p,"true"),e.insertAdjacentElement("afterbegin",o),o}function B(e){e.getAttribute(h)==="true"&&(e.classList.remove("is-invalid"),e.removeAttribute(h))}function ce(e){(g(e)?S(e):[e]).forEach(o=>{o.classList.add("is-invalid"),o.setAttribute(h,"true")})}function le(e){(g(e)?S(e):[e]).forEach(o=>{B(o)})}function ue(e,t){return(M(e)?ae(e):I(e)?U(e):se(e)).appendChild(ne(document,t)),M(e)?ce(e):I(e)&&(e.classList.add("is-invalid"),e.setAttribute(h,"true")),Promise.resolve()}function de(e){if(M(e)){const n=g(e)?$(e):k(e);(n?N(n):void 0)?.remove(),le(e)}else if(I(e)){const n=e.nextElementSibling;n instanceof HTMLElement&&n.getAttribute(p)==="true"&&n.remove(),B(e)}return e.querySelectorAll(`[${p}="true"]`).forEach(n=>{n.remove()}),e.querySelectorAll(`[${h}="true"]`).forEach(n=>{B(n)}),Promise.resolve()}function z(e){e.classList.contains("modal")||e.classList.add("modal"),e.tabIndex<0&&(e.tabIndex=-1),e.hasAttribute("aria-hidden")||e.setAttribute("aria-hidden","true")}function fe(e,t){z(e);const o=C(e,void 0,t.bootstrap);return o?(o.show(),Promise.resolve()):Promise.reject(new Error("Bootstrap Modal is unavailable."))}function me(e,t){z(e);const o=C(e,void 0,t.bootstrap);return o?(o.hide(),Promise.resolve()):Promise.reject(new Error("Bootstrap Modal is unavailable."))}const W="data-haori-bootstrap-toast-container",pe="data-haori-bootstrap-toast",be="data-haori-bootstrap-toast-accent";function ve(e){switch(e){case"warning":return{accentClassName:"bg-warning"};case"error":return{accentClassName:"bg-danger"};default:return{accentClassName:"bg-info"}}}function he(e,t){if(t.toastContainerSelector){const o=e.querySelector(t.toastContainerSelector);if(o)return o}return e.body}function Ee(e,t){const o=he(e,t),n=o.querySelector(`[${W}="true"]`);if(n)return n;const r=e.createElement("div");return r.className="toast-container position-fixed bottom-0 end-0 p-3",r.setAttribute(W,"true"),o.appendChild(r),r}function Ce(e,t,o){const n=globalThis.document,r=ve(t),i=n.createElement("div");i.className="toast border bg-body text-body shadow-sm",i.setAttribute("role","status"),i.setAttribute("aria-live","polite"),i.setAttribute("aria-atomic","true"),i.setAttribute(pe,"true");const u=n.createElement("div");u.className="d-flex align-items-stretch";const a=n.createElement("div");a.className=`flex-shrink-0 rounded-start ${r.accentClassName}`,a.style.width="0.375rem",a.setAttribute(be,"true");const s=n.createElement("div");s.className="toast-body",s.style.whiteSpace="pre-line",s.textContent=e,u.appendChild(a),u.appendChild(s),i.appendChild(u),Ee(n,o).appendChild(i);const c=Z(i,o.bootstrap);if(!c)return i.remove(),Promise.reject(new Error("Bootstrap Toast is unavailable."));i.addEventListener("hidden.bs.toast",()=>{i.remove(),c.dispose?.()},{once:!0});try{return c.show(),Promise.resolve()}catch(f){return i.remove(),c.dispose?.(),Promise.reject(f)}}let l={options:{fallbackToNative:!0}};function b(e){return e.replace(/\\n/g,`
2
- `)}function O(){return globalThis.window}function H(e){return Promise.resolve(e).then(()=>{})}function A(e){const t=l.originalHaori?.[e];return typeof t=="function"?t:void 0}function w(e){console.warn(`[haori-bootstrap] ${e} skipped because Bootstrap support is unavailable.`)}function F(e){const t=b(e),o=A("dialog");if(o)return H(o(t));const n=O();return l.options.fallbackToNative&&typeof n?.alert=="function"?(n.alert(t),Promise.resolve()):(w("dialog"),Promise.resolve())}function G(e){const t=b(e),o=A("confirm");if(o)return Promise.resolve(o(t)).then(r=>!!r);const n=O();return l.options.fallbackToNative&&typeof n?.confirm=="function"?Promise.resolve(n.confirm(t)):(w("confirm"),Promise.resolve(!1))}function j(e,t){const o=b(e),n=A("toast");return n?H(n(o,t)):(w("toast"),Promise.resolve())}function y(e,t){const o=A(e);return o?H(o(t)):(w(e),Promise.resolve())}function Te(e){l=e}class K{static dialog(t){const o=b(t);return E(l.options.bootstrap)?te(o,l.options).catch(()=>F(o)):F(o)}static confirm(t){const o=b(t);return E(l.options.bootstrap)?oe(o,l.options).catch(()=>G(o)):G(o)}static toast(t,o){const n=b(t);return Y(l.options.bootstrap)?Ce(n,o,l.options).catch(()=>j(n,o)):j(n,o)}static openDialog(t){return E(l.options.bootstrap)?fe(t,l.options).catch(()=>y("openDialog",t)):y("openDialog",t)}static closeDialog(t){return E(l.options.bootstrap)?me(t,l.options).catch(()=>y("closeDialog",t)):y("closeDialog",t)}static addErrorMessage(t,o){return ue(t,o)}static clearMessages(t){return de(t)}}const V={fallbackToNative:!0},d={installed:!1,options:V};function L(){return globalThis.window}function ge(e,t){return{bootstrap:e.bootstrap??t?.bootstrap,fallbackToNative:e.fallbackToNative??V.fallbackToNative,toastContainerSelector:e.toastContainerSelector,dialogContainerSelector:e.dialogContainerSelector}}function J(e=L()){return!!(e?.Haori&&e.bootstrap)}function Q(e={}){const t=L();if(!t?.Haori)throw new Error("window.Haori is required before calling install().");d.originalHaori||(d.originalHaori=t.Haori),d.options=ge(e,t),Te({originalHaori:d.originalHaori,options:d.options}),t.Haori=K,d.installed=!0}function Ae(){const e=L();!e||!d.originalHaori||(e.Haori=d.originalHaori,d.installed=!1,d.originalHaori=void 0)}function we(){return d.installed}const X="__haoriJsBootstrapAutoEnabled__";function ye(){return globalThis.window}function Me(e){return!!e[X]}function Ie(e){e[X]=!0}function Ne(){const e=ye();if(!(!e||Me(e))){if(!J(e)){console.warn("[haori-bootstrap] Auto-enable skipped because window.Haori or window.bootstrap is missing.");return}try{Q({bootstrap:e.bootstrap}),Ie(e)}catch(t){console.warn("[haori-bootstrap] Auto-enable failed.",t)}}}Ne();const Se="0.2.0";return m.BootstrapHaori=K,m.hasAutoEnablePrerequisites=J,m.install=Q,m.isInstalled=we,m.uninstall=Ae,m.version=Se,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"}),m})({});
1
+ var HaoriBootstrap=(function(m){"use strict";function P(e){return typeof e=="function"}function R(e){return P(e?.Modal)?e?.Modal:void 0}function _(e){return P(e?.Toast)?e?.Toast:void 0}function E(e){return!!R(e)}function Y(e){return!!_(e)}function C(e,t,o){const n=R(o);if(n)return typeof n.getOrCreateInstance=="function"?n.getOrCreateInstance(e,t):new n(e,t)}function Z(e,t){const o=_(t);if(o)return typeof o.getOrCreateInstance=="function"?o.getOrCreateInstance(e):new o(e)}const ee="data-haori-bootstrap-dialog",v="data-haori-bootstrap-action";function x(){return{backdrop:"static"}}function D(e,t){if(t.dialogContainerSelector){const o=e.querySelector(t.dialogContainerSelector);if(o)return o}return e.body}function q(e,t,o){const n=e.createElement("div");n.className="modal fade",n.tabIndex=-1,n.setAttribute(ee,"true"),n.setAttribute("aria-hidden","true");const r=e.createElement("div");r.className="modal-dialog modal-dialog-centered";const i=e.createElement("div");i.className="modal-content";const d=e.createElement("div");d.className="modal-body";const a=e.createElement("p");a.className="mb-0",a.style.whiteSpace="pre-line",a.textContent=t,d.appendChild(a);const s=e.createElement("div");if(s.className="modal-footer",o){const f=e.createElement("button");f.type="button",f.className="btn btn-secondary",f.setAttribute(v,"cancel"),f.textContent="Cancel",s.appendChild(f)}const c=e.createElement("button");return c.type="button",c.className="btn btn-primary",c.setAttribute(v,"ok"),c.textContent="OK",s.appendChild(c),i.append(d,s),r.appendChild(i),n.appendChild(r),n}function te(e,t){const o=globalThis.document,n=q(o,e,!1);D(o,t).appendChild(n);const r=C(n,x(),t.bootstrap);return r?new Promise((i,d)=>{const a=()=>{n.removeEventListener("hidden.bs.modal",s),n.remove(),r.dispose?.(),i()},s=()=>{a()};n.querySelector(`[${v}="ok"]`)?.addEventListener("click",()=>{r.hide()},{once:!0}),n.addEventListener("hidden.bs.modal",s,{once:!0});try{r.show()}catch(f){n.removeEventListener("hidden.bs.modal",s),n.remove(),r.dispose?.(),d(f)}}):(n.remove(),Promise.reject(new Error("Bootstrap Modal is unavailable.")))}function oe(e,t){const o=globalThis.document,n=q(o,e,!0);D(o,t).appendChild(n);const r=C(n,x(),t.bootstrap);return r?new Promise((i,d)=>{let a=!1;const s=()=>{n.removeEventListener("hidden.bs.modal",c),n.remove(),r.dispose?.(),i(a)},c=()=>{s()},f=n.querySelector(`[${v}="ok"]`),ke=n.querySelector(`[${v}="cancel"]`);f?.addEventListener("click",()=>{a=!0,r.hide()},{once:!0}),ke?.addEventListener("click",()=>{a=!1,r.hide()},{once:!0}),n.addEventListener("hidden.bs.modal",c,{once:!0});try{r.show()}catch(He){n.removeEventListener("hidden.bs.modal",c),n.remove(),r.dispose?.(),d(He)}}):(n.remove(),Promise.reject(new Error("Bootstrap Modal is unavailable.")))}const T="data-haori-bootstrap-owned",p="data-haori-bootstrap-message-container",h="data-haori-bootstrap-invalid-target";function M(e){return e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")}function g(e){return e instanceof HTMLInputElement&&e.type==="radio"}function I(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function N(e){return Array.from(e.children).find(t=>t instanceof HTMLElement&&t.getAttribute(p)==="true")}function ne(e,t){const o=e.createElement("div");return o.setAttribute(T,"true"),o.textContent=t,o}function re(e){return N(e)}function S(e){if(e.name){const t=e.form??e.ownerDocument,o=typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(e.name):e.name.replace(/(["\\])/g,"\\$1"),n=Array.from(t.querySelectorAll(`input[type="radio"][name="${o}"]`));if(n.length>0)return n}return[e]}function ie(e){const[t,...o]=e;if(!t)return;let n=t;for(;n;){if(o.every(r=>n?.contains(r)))return n;n=n.parentElement}}function $(e){const o=S(e).map(n=>n.closest(".form-check")).filter(n=>n instanceof HTMLElement);if(o.length>1){const n=ie(o);if(n&&!o.includes(n))return n}return k(e)}function k(e){const t=e.closest(".form-check");return t instanceof HTMLElement?t:void 0}function U(e){const t=e.nextElementSibling;if(t instanceof HTMLElement&&t.getAttribute(p)==="true")return t;const o=document.createElement("div");return o.className="invalid-feedback d-block",o.setAttribute(T,"true"),o.setAttribute(p,"true"),e.insertAdjacentElement("afterend",o),o}function ae(e){const t=g(e)?$(e):k(e);if(!t)return U(e);const o=N(t);if(o)return o;const n=document.createElement("div");return n.className="invalid-feedback d-block",n.setAttribute(T,"true"),n.setAttribute(p,"true"),t.appendChild(n),n}function se(e){const t=re(e);if(t)return t;const o=document.createElement("div");return o.className="alert alert-danger",o.setAttribute("role","alert"),o.setAttribute(T,"true"),o.setAttribute(p,"true"),e.insertAdjacentElement("afterbegin",o),o}function H(e){e.getAttribute(h)==="true"&&(e.classList.remove("is-invalid"),e.removeAttribute(h))}function ce(e){(g(e)?S(e):[e]).forEach(o=>{o.classList.add("is-invalid"),o.setAttribute(h,"true")})}function le(e){(g(e)?S(e):[e]).forEach(o=>{H(o)})}function ue(e,t){return(M(e)?ae(e):I(e)?U(e):se(e)).appendChild(ne(document,t)),M(e)?ce(e):I(e)&&(e.classList.add("is-invalid"),e.setAttribute(h,"true")),Promise.resolve()}function de(e){if(M(e)){const n=g(e)?$(e):k(e);(n?N(n):void 0)?.remove(),le(e)}else if(I(e)){const n=e.nextElementSibling;n instanceof HTMLElement&&n.getAttribute(p)==="true"&&n.remove(),H(e)}return e.querySelectorAll(`[${p}="true"]`).forEach(n=>{n.remove()}),e.querySelectorAll(`[${h}="true"]`).forEach(n=>{H(n)}),Promise.resolve()}function z(e){e.classList.contains("modal")||e.classList.add("modal"),e.tabIndex<0&&(e.tabIndex=-1),e.hasAttribute("aria-hidden")||e.setAttribute("aria-hidden","true")}function fe(e,t){z(e);const o=C(e,void 0,t.bootstrap);return o?(o.show(),Promise.resolve()):Promise.reject(new Error("Bootstrap Modal is unavailable."))}function me(e,t){z(e);const o=C(e,void 0,t.bootstrap);return o?(o.hide(),Promise.resolve()):Promise.reject(new Error("Bootstrap Modal is unavailable."))}const O="data-haori-bootstrap-toast-container",pe="data-haori-bootstrap-toast",be="data-haori-bootstrap-toast-accent";function ve(e){switch(e){case"warning":return{accentClassName:"bg-warning"};case"error":return{accentClassName:"bg-danger"};default:return{accentClassName:"bg-info"}}}function he(e,t){if(t.toastContainerSelector){const o=e.querySelector(t.toastContainerSelector);if(o)return o}return e.body}function Ee(e,t){const o=he(e,t),n=o.querySelector(`[${O}="true"]`);if(n)return n;const r=e.createElement("div");return r.className="toast-container position-fixed bottom-0 end-0 p-3",r.setAttribute(O,"true"),o.appendChild(r),r}function Ce(e,t,o){const n=globalThis.document,r=ve(t),i=n.createElement("div");i.className="toast border bg-body text-body shadow-sm",i.setAttribute("role","status"),i.setAttribute("aria-live","polite"),i.setAttribute("aria-atomic","true"),i.setAttribute(pe,"true");const d=n.createElement("div");d.className="d-flex align-items-stretch";const a=n.createElement("div");a.className=`flex-shrink-0 rounded-start ${r.accentClassName}`,a.style.width="0.375rem",a.setAttribute(be,"true");const s=n.createElement("div");s.className="toast-body",s.style.whiteSpace="pre-line",s.textContent=e,d.appendChild(a),d.appendChild(s),i.appendChild(d),Ee(n,o).appendChild(i);const c=Z(i,o.bootstrap);if(!c)return i.remove(),Promise.reject(new Error("Bootstrap Toast is unavailable."));i.addEventListener("hidden.bs.toast",()=>{i.remove(),c.dispose?.()},{once:!0});try{return c.show(),Promise.resolve()}catch(f){return i.remove(),c.dispose?.(),Promise.reject(f)}}let l={options:{fallbackToNative:!0}};function b(e){return e.replace(/\\n/g,`
2
+ `)}function W(){return globalThis.window}function B(e){return Promise.resolve(e).then(()=>{})}function A(e){const t=l.originalHaori?.[e];return typeof t=="function"?t:void 0}function w(e){console.warn(`[haori-bootstrap] ${e} skipped because Bootstrap support is unavailable.`)}function F(e){const t=b(e),o=A("dialog");if(o)return B(o(t));const n=W();return l.options.fallbackToNative&&typeof n?.alert=="function"?(n.alert(t),Promise.resolve()):(w("dialog"),Promise.resolve())}function G(e){const t=b(e),o=A("confirm");if(o)return Promise.resolve(o(t)).then(r=>!!r);const n=W();return l.options.fallbackToNative&&typeof n?.confirm=="function"?Promise.resolve(n.confirm(t)):(w("confirm"),Promise.resolve(!1))}function j(e,t){const o=b(e),n=A("toast");return n?B(n(o,t)):(w("toast"),Promise.resolve())}function y(e,t){const o=A(e);return o?B(o(t)):(w(e),Promise.resolve())}function Te(e){l=e}class K{static dialog(t){const o=b(t);return E(l.options.bootstrap)?te(o,l.options).catch(()=>F(o)):F(o)}static confirm(t){const o=b(t);return E(l.options.bootstrap)?oe(o,l.options).catch(()=>G(o)):G(o)}static toast(t,o){const n=b(t);return Y(l.options.bootstrap)?Ce(n,o,l.options).catch(()=>j(n,o)):j(n,o)}static openDialog(t){return E(l.options.bootstrap)?fe(t,l.options).catch(()=>y("openDialog",t)):y("openDialog",t)}static closeDialog(t){return E(l.options.bootstrap)?me(t,l.options).catch(()=>y("closeDialog",t)):y("closeDialog",t)}static addErrorMessage(t,o){return ue(t,o)}static clearMessages(t){return de(t)}}const V={fallbackToNative:!0},u={installed:!1,options:V};function L(){return globalThis.window}function ge(e,t){return{bootstrap:e.bootstrap??t?.bootstrap,fallbackToNative:e.fallbackToNative??V.fallbackToNative,runtime:e.runtime??u.options.runtime??t?.Haori?.runtime,toastContainerSelector:e.toastContainerSelector,dialogContainerSelector:e.dialogContainerSelector}}function J(e=L()){return!!(e?.Haori&&e.bootstrap)}function Q(e={}){const t=L();if(!t?.Haori)throw new Error("window.Haori is required before calling install().");u.originalHaori||(u.originalHaori=t.Haori),u.options=ge(e,t),u.options.runtime&&typeof t.Haori.setRuntime=="function"&&t.Haori.setRuntime(u.options.runtime),Te({originalHaori:u.originalHaori,options:u.options}),t.Haori=K,u.installed=!0}function Ae(){const e=L();!e||!u.originalHaori||(e.Haori=u.originalHaori,u.installed=!1,u.originalHaori=void 0)}function we(){return u.installed}const X="__haoriJsBootstrapAutoEnabled__";function ye(){return globalThis.window}function Me(e){return!!e[X]}function Ie(e){e[X]=!0}function Ne(){const e=ye();if(!(!e||Me(e))){if(!J(e)){console.warn("[haori-bootstrap] Auto-enable skipped because window.Haori or window.bootstrap is missing.");return}try{Q({bootstrap:e.bootstrap}),Ie(e)}catch(t){console.warn("[haori-bootstrap] Auto-enable failed.",t)}}}Ne();const Se="0.3.0";return m.BootstrapHaori=K,m.hasAutoEnablePrerequisites=J,m.install=Q,m.isInstalled=we,m.uninstall=Ae,m.version=Se,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"}),m})({});
3
3
  //# sourceMappingURL=haori-bootstrap.iife.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"haori-bootstrap.iife.js","sources":["../src/bootstrap_resolver.ts","../src/dialog.ts","../src/message.ts","../src/modal.ts","../src/toast.ts","../src/bootstrap_haori.ts","../src/install.ts","../src/browser.ts","../src/index.ts"],"sourcesContent":["import type {\n BootstrapModalConstructor,\n BootstrapModalInstance,\n BootstrapModalOptions,\n BootstrapNamespace,\n BootstrapToastConstructor,\n BootstrapToastInstance,\n} from './types';\n\n/**\n * 値がコンストラクター関数かどうかを判定する。\n *\n * @param value 判定対象の値。\n * @return コンストラクター関数なら true。\n */\nfunction isConstructor<T>(value: unknown): value is new (...args: readonly unknown[]) => T {\n return typeof value === 'function';\n}\n\n/**\n * Bootstrap の Modal コンストラクターを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return Modal コンストラクター。見つからない場合は undefined。\n */\nexport function resolveModalConstructor(\n bootstrap?: BootstrapNamespace,\n): BootstrapModalConstructor | undefined {\n return isConstructor<BootstrapModalInstance>(bootstrap?.Modal)\n ? (bootstrap?.Modal as BootstrapModalConstructor)\n : undefined;\n}\n\n/**\n * Bootstrap の Toast コンストラクターを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return Toast コンストラクター。見つからない場合は undefined。\n */\nexport function resolveToastConstructor(\n bootstrap?: BootstrapNamespace,\n): BootstrapToastConstructor | undefined {\n return isConstructor<BootstrapToastInstance>(bootstrap?.Toast)\n ? (bootstrap?.Toast as BootstrapToastConstructor)\n : undefined;\n}\n\n/**\n * Modal が利用可能かどうかを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return 利用可能なら true。\n */\nexport function hasModalSupport(bootstrap?: BootstrapNamespace): boolean {\n return Boolean(resolveModalConstructor(bootstrap));\n}\n\n/**\n * Toast が利用可能かどうかを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return 利用可能なら true。\n */\nexport function hasToastSupport(bootstrap?: BootstrapNamespace): boolean {\n return Boolean(resolveToastConstructor(bootstrap));\n}\n\n/**\n * Modal インスタンスを取得または生成する。\n *\n * @param element 対象要素。\n * @param bootstrap Bootstrap 名前空間。\n * @return Modal インスタンス。生成できない場合は undefined。\n */\nexport function createModalInstance(\n element: HTMLElement,\n options?: BootstrapModalOptions,\n bootstrap?: BootstrapNamespace,\n): BootstrapModalInstance | undefined {\n const modalConstructor = resolveModalConstructor(bootstrap);\n if (!modalConstructor) {\n return undefined;\n }\n\n if (typeof modalConstructor.getOrCreateInstance === 'function') {\n return modalConstructor.getOrCreateInstance(element, options);\n }\n\n return new modalConstructor(element, options);\n}\n\n/**\n * Toast インスタンスを取得または生成する。\n *\n * @param element 対象要素。\n * @param bootstrap Bootstrap 名前空間。\n * @return Toast インスタンス。生成できない場合は undefined。\n */\nexport function createToastInstance(\n element: HTMLElement,\n bootstrap?: BootstrapNamespace,\n): BootstrapToastInstance | undefined {\n const toastConstructor = resolveToastConstructor(bootstrap);\n if (!toastConstructor) {\n return undefined;\n }\n\n if (typeof toastConstructor.getOrCreateInstance === 'function') {\n return toastConstructor.getOrCreateInstance(element);\n }\n\n return new toastConstructor(element);\n}\n","import { createModalInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\nconst DIALOG_CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-dialog';\nconst ACTION_ATTRIBUTE = 'data-haori-bootstrap-action';\n\n/**\n * dialog 系 modal の既定オプションを返す。\n *\n * @return Bootstrap Modal の生成オプション。\n */\nfunction createDialogModalOptions() {\n return {\n backdrop: 'static' as const,\n };\n}\n\n/**\n * dialog を挿入する親要素を解決する。\n *\n * @param documentObject 検索に使用する document。\n * @param options 解決済み導入設定。\n * @return 挿入先の要素。\n */\nfunction resolveDialogContainer(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n if (options.dialogContainerSelector) {\n const resolvedElement = documentObject.querySelector<HTMLElement>(\n options.dialogContainerSelector,\n );\n if (resolvedElement) {\n return resolvedElement;\n }\n }\n\n return documentObject.body;\n}\n\n/**\n * dialog または confirm 用の modal 要素を組み立てる。\n *\n * @param documentObject 生成に使用する document。\n * @param message 表示するメッセージ。\n * @param isConfirm confirm 用かどうか。\n * @return 生成した modal 要素。\n */\nfunction createModalShell(documentObject: Document, message: string, isConfirm: boolean): HTMLDivElement {\n const modalElement = documentObject.createElement('div');\n modalElement.className = 'modal fade';\n modalElement.tabIndex = -1;\n modalElement.setAttribute(DIALOG_CONTAINER_ATTRIBUTE, 'true');\n modalElement.setAttribute('aria-hidden', 'true');\n\n const dialogElement = documentObject.createElement('div');\n dialogElement.className = 'modal-dialog modal-dialog-centered';\n\n const contentElement = documentObject.createElement('div');\n contentElement.className = 'modal-content';\n\n const bodyElement = documentObject.createElement('div');\n bodyElement.className = 'modal-body';\n\n const messageElement = documentObject.createElement('p');\n messageElement.className = 'mb-0';\n messageElement.style.whiteSpace = 'pre-line';\n messageElement.textContent = message;\n bodyElement.appendChild(messageElement);\n\n const footerElement = documentObject.createElement('div');\n footerElement.className = 'modal-footer';\n\n if (isConfirm) {\n const cancelButton = documentObject.createElement('button');\n cancelButton.type = 'button';\n cancelButton.className = 'btn btn-secondary';\n cancelButton.setAttribute(ACTION_ATTRIBUTE, 'cancel');\n cancelButton.textContent = 'Cancel';\n footerElement.appendChild(cancelButton);\n }\n\n const okButton = documentObject.createElement('button');\n okButton.type = 'button';\n okButton.className = 'btn btn-primary';\n okButton.setAttribute(ACTION_ATTRIBUTE, 'ok');\n okButton.textContent = 'OK';\n footerElement.appendChild(okButton);\n\n contentElement.append(bodyElement, footerElement);\n dialogElement.appendChild(contentElement);\n modalElement.appendChild(dialogElement);\n return modalElement;\n}\n\n/**\n * 情報表示用の Bootstrap Modal を表示する。\n *\n * @param message 表示するメッセージ。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function showDialog(message: string, options: ResolvedInstallOptions): Promise<void> {\n const documentObject = globalThis.document;\n const modalElement = createModalShell(documentObject, message, false);\n resolveDialogContainer(documentObject, options).appendChild(modalElement);\n\n const modalInstance = createModalInstance(\n modalElement,\n createDialogModalOptions(),\n options.bootstrap,\n );\n if (!modalInstance) {\n modalElement.remove();\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n return new Promise<void>((resolve, reject) => {\n const finalize = (): void => {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n resolve();\n };\n\n const handleHidden = (): void => {\n finalize();\n };\n\n const okButton = modalElement.querySelector<HTMLButtonElement>(`[${ACTION_ATTRIBUTE}=\"ok\"]`);\n okButton?.addEventListener(\n 'click',\n () => {\n modalInstance.hide();\n },\n { once: true },\n );\n\n modalElement.addEventListener('hidden.bs.modal', handleHidden, { once: true });\n\n try {\n modalInstance.show();\n } catch (error) {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n reject(error);\n }\n });\n}\n\n/**\n * 確認用の Bootstrap Modal を表示する。\n *\n * @param message 表示するメッセージ。\n * @param options 解決済み導入設定。\n * @return OK のみ true を返す Promise。\n */\nexport function showConfirm(\n message: string,\n options: ResolvedInstallOptions,\n): Promise<boolean> {\n const documentObject = globalThis.document;\n const modalElement = createModalShell(documentObject, message, true);\n resolveDialogContainer(documentObject, options).appendChild(modalElement);\n\n const modalInstance = createModalInstance(\n modalElement,\n createDialogModalOptions(),\n options.bootstrap,\n );\n if (!modalInstance) {\n modalElement.remove();\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n return new Promise<boolean>((resolve, reject) => {\n let confirmed = false;\n\n const finalize = (): void => {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n resolve(confirmed);\n };\n\n const handleHidden = (): void => {\n finalize();\n };\n\n const okButton = modalElement.querySelector<HTMLButtonElement>(`[${ACTION_ATTRIBUTE}=\"ok\"]`);\n const cancelButton = modalElement.querySelector<HTMLButtonElement>(\n `[${ACTION_ATTRIBUTE}=\"cancel\"]`,\n );\n\n okButton?.addEventListener(\n 'click',\n () => {\n confirmed = true;\n modalInstance.hide();\n },\n { once: true },\n );\n cancelButton?.addEventListener(\n 'click',\n () => {\n confirmed = false;\n modalInstance.hide();\n },\n { once: true },\n );\n\n modalElement.addEventListener('hidden.bs.modal', handleHidden, { once: true });\n\n try {\n modalInstance.show();\n } catch (error) {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n reject(error);\n }\n });\n}\n","const OWNED_ATTRIBUTE = 'data-haori-bootstrap-owned';\nconst CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-message-container';\nconst INVALID_TARGET_ATTRIBUTE = 'data-haori-bootstrap-invalid-target';\n\n/**\n * 対象要素が checkbox または radio かどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return checkbox または radio の input 要素なら true。\n */\nfunction isChoiceInput(target: HTMLElement): target is HTMLInputElement {\n return (\n target instanceof HTMLInputElement &&\n (target.type === 'checkbox' || target.type === 'radio')\n );\n}\n\n/**\n * 対象要素が radio input かどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return radio の input 要素なら true。\n */\nfunction isRadioInput(target: HTMLElement): target is HTMLInputElement {\n return target instanceof HTMLInputElement && target.type === 'radio';\n}\n\n/**\n * 対象要素が通常の invalid-feedback を直後に付与するフィールドかどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return 入力系フィールドなら true。\n */\nfunction isFieldTarget(\n target: HTMLElement,\n): target is HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement {\n return (\n target instanceof HTMLInputElement ||\n target instanceof HTMLSelectElement ||\n target instanceof HTMLTextAreaElement\n );\n}\n\n/**\n * 子要素から管理対象のメッセージコンテナを取得する。\n *\n * @param target 検索対象の要素。\n * @return 管理対象コンテナ。見つからない場合は undefined。\n */\nfunction getDirectOwnedContainer(target: HTMLElement): HTMLElement | undefined {\n return Array.from(target.children).find(\n (element): element is HTMLElement =>\n element instanceof HTMLElement && element.getAttribute(CONTAINER_ATTRIBUTE) === 'true',\n );\n}\n\n/**\n * 管理対象のメッセージ要素を生成する。\n *\n * @param documentObject 生成に使用する document。\n * @param message 表示するメッセージ。\n * @return 生成したメッセージ要素。\n */\nfunction createMessageItem(documentObject: Document, message: string): HTMLDivElement {\n const messageElement = documentObject.createElement('div');\n messageElement.setAttribute(OWNED_ATTRIBUTE, 'true');\n messageElement.textContent = message;\n return messageElement;\n}\n\n/**\n * block container 配下の既存メッセージコンテナを取得する。\n *\n * @param target 検索対象の要素。\n * @return 既存コンテナ。見つからない場合は undefined。\n */\nfunction getOwnedDirectChild(target: HTMLElement): HTMLElement | undefined {\n return getDirectOwnedContainer(target);\n}\n\n/**\n * 指定した radio と同じグループに属する radio 要素一覧を取得する。\n *\n * @param target 基準となる radio 要素。\n * @return 同じグループに属する radio 要素一覧。\n */\nfunction getRadioGroupTargets(target: HTMLInputElement): HTMLInputElement[] {\n if (target.name) {\n const rootNode = target.form ?? target.ownerDocument;\n const escapedName = typeof CSS !== 'undefined' && typeof CSS.escape === 'function'\n ? CSS.escape(target.name)\n : target.name.replace(/([\"\\\\])/g, '\\\\$1');\n const groupTargets = Array.from(\n rootNode.querySelectorAll<HTMLInputElement>(`input[type=\"radio\"][name=\"${escapedName}\"]`),\n );\n if (groupTargets.length > 0) {\n return groupTargets;\n }\n }\n\n return [target];\n}\n\n/**\n * 複数要素の最も近い共通祖先要素を返す。\n *\n * @param elements 判定対象の要素一覧。\n * @return 共通祖先要素。見つからない場合は undefined。\n */\nfunction findCommonAncestor(elements: readonly HTMLElement[]): HTMLElement | undefined {\n const [firstElement, ...restElements] = elements;\n if (!firstElement) {\n return undefined;\n }\n\n let candidate: HTMLElement | null = firstElement;\n while (candidate) {\n if (restElements.every((element) => candidate?.contains(element))) {\n return candidate;\n }\n candidate = candidate.parentElement;\n }\n\n return undefined;\n}\n\n/**\n * radio group のメッセージ挿入先を解決する。\n *\n * @param target 対象の radio 要素。\n * @return 挿入先の要素。見つからない場合は undefined。\n */\nfunction resolveRadioMessageHost(target: HTMLInputElement): HTMLElement | undefined {\n const groupTargets = getRadioGroupTargets(target);\n const wrappers = groupTargets\n .map((element) => element.closest('.form-check'))\n .filter((element): element is HTMLElement => element instanceof HTMLElement);\n\n if (wrappers.length > 1) {\n const commonAncestor = findCommonAncestor(wrappers);\n if (commonAncestor && !wrappers.includes(commonAncestor)) {\n return commonAncestor;\n }\n }\n\n return resolveChoiceMessageHost(target);\n}\n\n/**\n * checkbox と radio のメッセージ挿入先を解決する。\n *\n * @param target 対象の input 要素。\n * @return 挿入先の form-check 要素。見つからない場合は undefined。\n */\nfunction resolveChoiceMessageHost(target: HTMLInputElement): HTMLElement | undefined {\n const closestFormCheck = target.closest('.form-check');\n return closestFormCheck instanceof HTMLElement ? closestFormCheck : undefined;\n}\n\n/**\n * 通常フィールドの直後に invalid-feedback コンテナを取得または生成する。\n *\n * @param target 対象の要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureFieldContainer(target: HTMLElement): HTMLElement {\n const nextElement = target.nextElementSibling;\n if (\n nextElement instanceof HTMLElement &&\n nextElement.getAttribute(CONTAINER_ATTRIBUTE) === 'true'\n ) {\n return nextElement;\n }\n\n const container = document.createElement('div');\n container.className = 'invalid-feedback d-block';\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n target.insertAdjacentElement('afterend', container);\n return container;\n}\n\n/**\n * checkbox と radio 用に form-check 末尾の invalid-feedback を取得または生成する。\n *\n * @param target 対象の input 要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureChoiceContainer(target: HTMLInputElement): HTMLElement {\n const hostElement = isRadioInput(target)\n ? resolveRadioMessageHost(target)\n : resolveChoiceMessageHost(target);\n if (!hostElement) {\n return ensureFieldContainer(target);\n }\n\n const existingContainer = getDirectOwnedContainer(hostElement);\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = 'invalid-feedback d-block';\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n hostElement.appendChild(container);\n return container;\n}\n\n/**\n * container target の先頭に alert コンテナを取得または生成する。\n *\n * @param target 対象の要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureBlockContainer(target: HTMLElement): HTMLElement {\n const existingContainer = getOwnedDirectChild(target);\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = 'alert alert-danger';\n container.setAttribute('role', 'alert');\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n target.insertAdjacentElement('afterbegin', container);\n return container;\n}\n\n/**\n * このライブラリが付けた is-invalid 状態だけを外す。\n *\n * @param target 状態を解除する要素。\n * @return 戻り値はない。\n */\nfunction removeOwnedInvalidState(target: HTMLElement): void {\n if (target.getAttribute(INVALID_TARGET_ATTRIBUTE) !== 'true') {\n return;\n }\n\n target.classList.remove('is-invalid');\n target.removeAttribute(INVALID_TARGET_ATTRIBUTE);\n}\n\n/**\n * choice input に対して、このライブラリが付けた invalid 状態を付与する。\n *\n * @param target 対象の input 要素。\n * @return 戻り値はない。\n */\nfunction markChoiceInvalidState(target: HTMLInputElement): void {\n const targets = isRadioInput(target) ? getRadioGroupTargets(target) : [target];\n targets.forEach((element) => {\n element.classList.add('is-invalid');\n element.setAttribute(INVALID_TARGET_ATTRIBUTE, 'true');\n });\n}\n\n/**\n * choice input に対して、このライブラリが付けた invalid 状態を解除する。\n *\n * @param target 対象の input 要素。\n * @return 戻り値はない。\n */\nfunction clearChoiceInvalidState(target: HTMLInputElement): void {\n const targets = isRadioInput(target) ? getRadioGroupTargets(target) : [target];\n targets.forEach((element) => {\n removeOwnedInvalidState(element);\n });\n}\n\n/**\n * 管理対象のエラーメッセージを追加する。\n *\n * @param target 追加先の要素。\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\nexport function addManagedErrorMessage(target: HTMLElement, message: string): Promise<void> {\n const container = isChoiceInput(target)\n ? ensureChoiceContainer(target)\n : isFieldTarget(target)\n ? ensureFieldContainer(target)\n : ensureBlockContainer(target);\n container.appendChild(createMessageItem(document, message));\n\n if (isChoiceInput(target)) {\n markChoiceInvalidState(target);\n } else if (isFieldTarget(target)) {\n target.classList.add('is-invalid');\n target.setAttribute(INVALID_TARGET_ATTRIBUTE, 'true');\n }\n\n return Promise.resolve();\n}\n\n/**\n * 管理対象のメッセージを削除する。\n *\n * @param parentOrTarget 削除対象の親要素または対象要素。\n * @return 完了時に解決される Promise。\n */\nexport function clearManagedMessages(parentOrTarget: HTMLElement): Promise<void> {\n if (isChoiceInput(parentOrTarget)) {\n const hostElement = isRadioInput(parentOrTarget)\n ? resolveRadioMessageHost(parentOrTarget)\n : resolveChoiceMessageHost(parentOrTarget);\n const ownedContainer = hostElement ? getDirectOwnedContainer(hostElement) : undefined;\n ownedContainer?.remove();\n clearChoiceInvalidState(parentOrTarget);\n } else if (isFieldTarget(parentOrTarget)) {\n const nextElement = parentOrTarget.nextElementSibling;\n if (\n nextElement instanceof HTMLElement &&\n nextElement.getAttribute(CONTAINER_ATTRIBUTE) === 'true'\n ) {\n nextElement.remove();\n }\n removeOwnedInvalidState(parentOrTarget);\n }\n\n const ownedContainers = parentOrTarget.querySelectorAll<HTMLElement>(\n `[${CONTAINER_ATTRIBUTE}=\"true\"]`,\n );\n ownedContainers.forEach((element) => {\n element.remove();\n });\n\n const invalidTargets = parentOrTarget.querySelectorAll<HTMLElement>(\n `[${INVALID_TARGET_ATTRIBUTE}=\"true\"]`,\n );\n invalidTargets.forEach((element) => {\n removeOwnedInvalidState(element);\n });\n\n return Promise.resolve();\n}\n","import { createModalInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\n/**\n * 既存要素を Bootstrap Modal として扱える最低限の属性へ整える。\n *\n * @param element 整形対象の要素。\n * @return 戻り値はない。\n */\nfunction prepareModalElement(element: HTMLElement): void {\n if (!element.classList.contains('modal')) {\n element.classList.add('modal');\n }\n\n if (element.tabIndex < 0) {\n element.tabIndex = -1;\n }\n\n if (!element.hasAttribute('aria-hidden')) {\n element.setAttribute('aria-hidden', 'true');\n }\n}\n\n/**\n * 任意要素を Bootstrap Modal として開く。\n *\n * @param element 開く対象の要素。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function openDialogElement(\n element: HTMLElement,\n options: ResolvedInstallOptions,\n): Promise<void> {\n prepareModalElement(element);\n const modalInstance = createModalInstance(element, undefined, options.bootstrap);\n if (!modalInstance) {\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n modalInstance.show();\n return Promise.resolve();\n}\n\n/**\n * 任意要素を Bootstrap Modal として閉じる。\n *\n * @param element 閉じる対象の要素。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function closeDialogElement(\n element: HTMLElement,\n options: ResolvedInstallOptions,\n): Promise<void> {\n prepareModalElement(element);\n const modalInstance = createModalInstance(element, undefined, options.bootstrap);\n if (!modalInstance) {\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n modalInstance.hide();\n return Promise.resolve();\n}\n","import { createToastInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\nconst TOAST_CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-toast-container';\nconst TOAST_ATTRIBUTE = 'data-haori-bootstrap-toast';\nconst TOAST_ACCENT_ATTRIBUTE = 'data-haori-bootstrap-toast-accent';\n\ninterface ToastAppearance {\n accentClassName: string;\n}\n\n/**\n * 通知レベルを toast 表示用の見た目へ変換する。\n *\n * @param level 通知レベル。\n * @return 対応する見た目定義。\n */\nfunction resolveToastAppearance(level?: string): ToastAppearance {\n switch (level) {\n case 'warning':\n return { accentClassName: 'bg-warning' };\n case 'error':\n return { accentClassName: 'bg-danger' };\n default:\n return { accentClassName: 'bg-info' };\n }\n}\n\n/**\n * toast コンテナを配置する親要素を解決する。\n *\n * @param documentObject 検索に使用する document。\n * @param options 解決済み導入設定。\n * @return 配置先の要素。\n */\nfunction resolveToastRoot(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n if (options.toastContainerSelector) {\n const resolvedElement = documentObject.querySelector<HTMLElement>(options.toastContainerSelector);\n if (resolvedElement) {\n return resolvedElement;\n }\n }\n\n return documentObject.body;\n}\n\n/**\n * toast コンテナを取得または生成する。\n *\n * @param documentObject 生成に使用する document。\n * @param options 解決済み導入設定。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureToastContainer(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n const rootElement = resolveToastRoot(documentObject, options);\n const existingContainer = rootElement.querySelector<HTMLElement>(\n `[${TOAST_CONTAINER_ATTRIBUTE}=\"true\"]`,\n );\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = documentObject.createElement('div');\n container.className = 'toast-container position-fixed bottom-0 end-0 p-3';\n container.setAttribute(TOAST_CONTAINER_ATTRIBUTE, 'true');\n rootElement.appendChild(container);\n return container;\n}\n\n/**\n * Bootstrap Toast を表示する。\n *\n * @param message 表示するメッセージ。\n * @param level 通知レベル。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function showToast(\n message: string,\n level: string | undefined,\n options: ResolvedInstallOptions,\n): Promise<void> {\n const documentObject = globalThis.document;\n const appearance = resolveToastAppearance(level);\n const toastElement = documentObject.createElement('div');\n toastElement.className = 'toast border bg-body text-body shadow-sm';\n toastElement.setAttribute('role', 'status');\n toastElement.setAttribute('aria-live', 'polite');\n toastElement.setAttribute('aria-atomic', 'true');\n toastElement.setAttribute(TOAST_ATTRIBUTE, 'true');\n\n const bodyWrapper = documentObject.createElement('div');\n bodyWrapper.className = 'd-flex align-items-stretch';\n\n const accentElement = documentObject.createElement('div');\n accentElement.className = `flex-shrink-0 rounded-start ${appearance.accentClassName}`;\n accentElement.style.width = '0.375rem';\n accentElement.setAttribute(TOAST_ACCENT_ATTRIBUTE, 'true');\n\n const bodyElement = documentObject.createElement('div');\n bodyElement.className = 'toast-body';\n bodyElement.style.whiteSpace = 'pre-line';\n bodyElement.textContent = message;\n\n bodyWrapper.appendChild(accentElement);\n bodyWrapper.appendChild(bodyElement);\n toastElement.appendChild(bodyWrapper);\n ensureToastContainer(documentObject, options).appendChild(toastElement);\n\n const toastInstance = createToastInstance(toastElement, options.bootstrap);\n if (!toastInstance) {\n toastElement.remove();\n return Promise.reject(new Error('Bootstrap Toast is unavailable.'));\n }\n\n toastElement.addEventListener(\n 'hidden.bs.toast',\n () => {\n toastElement.remove();\n toastInstance.dispose?.();\n },\n { once: true },\n );\n\n try {\n toastInstance.show();\n return Promise.resolve();\n } catch (error) {\n toastElement.remove();\n toastInstance.dispose?.();\n return Promise.reject(error);\n }\n}\n","import { hasModalSupport, hasToastSupport } from './bootstrap_resolver';\nimport { showConfirm, showDialog } from './dialog';\nimport { addManagedErrorMessage, clearManagedMessages } from './message';\nimport { closeDialogElement, openDialogElement } from './modal';\nimport { showToast } from './toast';\nimport type { HaoriGlobalObject, ResolvedInstallOptions } from './types';\n\n/**\n * BootstrapHaori が利用する内部コンテキスト。\n */\nexport interface BootstrapHaoriContext {\n /** 差し替え前の Haori 実装。 */\n originalHaori?: HaoriGlobalObject;\n /** 解決済みの導入設定。 */\n options: ResolvedInstallOptions;\n}\n\nconst defaultContext: BootstrapHaoriContext = {\n options: {\n fallbackToNative: true,\n },\n};\n\nlet context = defaultContext;\n\n/**\n * 表示用 message 中のエスケープ済み改行を実際の改行へ正規化する。\n *\n * @param message 正規化対象のメッセージ。\n * @return 正規化後のメッセージ。\n */\nfunction normalizeMessageText(message: string): string {\n return message.replace(/\\\\n/g, '\\n');\n}\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): Window | undefined {\n const scope = globalThis as typeof globalThis & { window?: Window };\n return scope.window;\n}\n\n/**\n * 値を Promise<void> 契約へ正規化する。\n *\n * @param value 正規化対象の値。\n * @return 完了時に解決される Promise。\n */\nfunction toPromiseVoid(value: Promise<void> | void | unknown): Promise<void> {\n return Promise.resolve(value).then(() => undefined);\n}\n\n/**\n * 元の Haori 実装から対象メソッドを取得する。\n *\n * @param methodName 取得対象のメソッド名。\n * @return 対象メソッド。見つからない場合は undefined。\n */\nfunction getOriginalMethod(\n methodName: keyof HaoriGlobalObject,\n): ((...args: readonly unknown[]) => unknown) | undefined {\n const method = context.originalHaori?.[methodName];\n return typeof method === 'function'\n ? (method as (...args: readonly unknown[]) => unknown)\n : undefined;\n}\n\n/**\n * no-op に正規化したことを警告する。\n *\n * @param apiName 利用できなかった API 名。\n * @return 戻り値はない。\n */\nfunction warnNoop(apiName: string): void {\n console.warn(`[haori-bootstrap] ${apiName} skipped because Bootstrap support is unavailable.`);\n}\n\n/**\n * dialog の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackDialog(message: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('dialog');\n if (originalMethod) {\n return toPromiseVoid(originalMethod(normalizedMessage));\n }\n\n const browserWindow = getBrowserWindow();\n if (context.options.fallbackToNative && typeof browserWindow?.alert === 'function') {\n browserWindow.alert(normalizedMessage);\n return Promise.resolve();\n }\n\n warnNoop('dialog');\n return Promise.resolve();\n}\n\n/**\n * confirm の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @return 確認結果を返す Promise。\n */\nfunction fallbackConfirm(message: string): Promise<boolean> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('confirm');\n if (originalMethod) {\n return Promise.resolve(originalMethod(normalizedMessage) as Promise<boolean> | boolean).then(\n (value) => Boolean(value),\n );\n }\n\n const browserWindow = getBrowserWindow();\n if (context.options.fallbackToNative && typeof browserWindow?.confirm === 'function') {\n return Promise.resolve(browserWindow.confirm(normalizedMessage));\n }\n\n warnNoop('confirm');\n return Promise.resolve(false);\n}\n\n/**\n * toast の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @param level 通知レベル。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackToast(message: string, level?: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('toast');\n if (originalMethod) {\n return toPromiseVoid(originalMethod(normalizedMessage, level));\n }\n\n warnNoop('toast');\n return Promise.resolve();\n}\n\n/**\n * openDialog または closeDialog の fallback 経路を処理する。\n *\n * @param methodName 呼び出す API 名。\n * @param element 対象要素。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackModal(methodName: 'openDialog' | 'closeDialog', element: HTMLElement): Promise<void> {\n const originalMethod = getOriginalMethod(methodName);\n if (originalMethod) {\n return toPromiseVoid(originalMethod(element));\n }\n\n warnNoop(methodName);\n return Promise.resolve();\n}\n\n/**\n * BootstrapHaori が参照する内部状態を更新する。\n *\n * @param nextContext 差し替え先が参照する内部コンテキスト。\n * @return 戻り値はない。\n */\nexport function setBootstrapHaoriContext(nextContext: BootstrapHaoriContext): void {\n context = nextContext;\n}\n\n/**\n * Haori の UI 系静的メソッドを差し替える最小ファサード。\n */\nexport class BootstrapHaori {\n /**\n * 情報表示ダイアログを表示する。\n *\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\n public static dialog(message: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasModalSupport(context.options.bootstrap)) {\n return showDialog(normalizedMessage, context.options).catch(() => fallbackDialog(normalizedMessage));\n }\n\n return fallbackDialog(normalizedMessage);\n }\n\n /**\n * 確認ダイアログを表示する。\n *\n * @param message 表示するメッセージ。\n * @return OK のみ true を返す Promise。\n */\n public static confirm(message: string): Promise<boolean> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasModalSupport(context.options.bootstrap)) {\n return showConfirm(normalizedMessage, context.options).catch(() => fallbackConfirm(normalizedMessage));\n }\n\n return fallbackConfirm(normalizedMessage);\n }\n\n /**\n * トースト通知を表示する。\n *\n * @param message 表示するメッセージ。\n * @param level 通知レベル。\n * @return 完了時に解決される Promise。\n */\n public static toast(message: string, level?: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasToastSupport(context.options.bootstrap)) {\n return showToast(normalizedMessage, level, context.options).catch(() =>\n fallbackToast(normalizedMessage, level),\n );\n }\n\n return fallbackToast(normalizedMessage, level);\n }\n\n /**\n * 任意のダイアログ要素を開く。\n *\n * @param element 開く対象の要素。\n * @return 完了時に解決される Promise。\n */\n public static openDialog(element: HTMLElement): Promise<void> {\n if (hasModalSupport(context.options.bootstrap)) {\n return openDialogElement(element, context.options).catch(() =>\n fallbackModal('openDialog', element),\n );\n }\n\n return fallbackModal('openDialog', element);\n }\n\n /**\n * 任意のダイアログ要素を閉じる。\n *\n * @param element 閉じる対象の要素。\n * @return 完了時に解決される Promise。\n */\n public static closeDialog(element: HTMLElement): Promise<void> {\n if (hasModalSupport(context.options.bootstrap)) {\n return closeDialogElement(element, context.options).catch(() =>\n fallbackModal('closeDialog', element),\n );\n }\n\n return fallbackModal('closeDialog', element);\n }\n\n /**\n * 管理対象のエラーメッセージを追加する。\n *\n * @param target 追加先の要素。\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\n public static addErrorMessage(target: HTMLElement, message: string): Promise<void> {\n return addManagedErrorMessage(target, message);\n }\n\n /**\n * 管理対象のメッセージを削除する。\n *\n * @param parentOrTarget 削除対象の親要素または対象要素。\n * @return 完了時に解決される Promise。\n */\n public static clearMessages(parentOrTarget: HTMLElement): Promise<void> {\n return clearManagedMessages(parentOrTarget);\n }\n}\n","import { BootstrapHaori, setBootstrapHaoriContext } from './bootstrap_haori';\nimport type {\n BrowserWindow,\n HaoriGlobalObject,\n InstallOptions,\n ResolvedInstallOptions,\n} from './types';\n\nconst DEFAULT_INSTALL_OPTIONS: ResolvedInstallOptions = {\n fallbackToNative: true,\n};\n\nconst installState: {\n installed: boolean;\n originalHaori?: HaoriGlobalObject;\n options: ResolvedInstallOptions;\n} = {\n installed: false,\n options: DEFAULT_INSTALL_OPTIONS,\n};\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): BrowserWindow | undefined {\n const scope = globalThis as typeof globalThis & { window?: BrowserWindow };\n return scope.window;\n}\n\n/**\n * install に渡された設定を既定値込みで解決する。\n *\n * @param options 指定された導入設定。\n * @param browserWindow 現在の window。\n * @return 解決済みの導入設定。\n */\nfunction resolveInstallOptions(\n options: InstallOptions,\n browserWindow: BrowserWindow | undefined,\n): ResolvedInstallOptions {\n return {\n bootstrap: options.bootstrap ?? browserWindow?.bootstrap,\n fallbackToNative: options.fallbackToNative ?? DEFAULT_INSTALL_OPTIONS.fallbackToNative,\n toastContainerSelector: options.toastContainerSelector,\n dialogContainerSelector: options.dialogContainerSelector,\n };\n}\n\n/**\n * 自動有効化に必要な前提が揃っているかを返す。\n *\n * @param browserWindow 判定対象の window。\n * @return 自動有効化可能なら true。\n */\nexport function hasAutoEnablePrerequisites(\n browserWindow: BrowserWindow | undefined = getBrowserWindow(),\n): boolean {\n return Boolean(browserWindow?.Haori && browserWindow.bootstrap);\n}\n\n/**\n * Bootstrap 対応 Haori を再適用し、必要なら設定を上書きする。\n *\n * @param options 上書きする導入設定。\n * @return 戻り値はない。\n */\nexport function install(options: InstallOptions = {}): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow?.Haori) {\n throw new Error('window.Haori is required before calling install().');\n }\n\n if (!installState.originalHaori) {\n installState.originalHaori = browserWindow.Haori;\n }\n\n installState.options = resolveInstallOptions(options, browserWindow);\n setBootstrapHaoriContext({\n originalHaori: installState.originalHaori,\n options: installState.options,\n });\n browserWindow.Haori = BootstrapHaori as unknown as HaoriGlobalObject;\n installState.installed = true;\n}\n\n/**\n * 元の Haori 実装を復元する。\n *\n * @return 戻り値はない。\n */\nexport function uninstall(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow || !installState.originalHaori) {\n return;\n }\n\n browserWindow.Haori = installState.originalHaori;\n installState.installed = false;\n installState.originalHaori = undefined;\n}\n\n/**\n * 現在 BootstrapHaori が有効かどうかを返す。\n *\n * @return 有効なら true。\n */\nexport function isInstalled(): boolean {\n return installState.installed;\n}\n","import { hasAutoEnablePrerequisites, install } from './install';\nimport type { BrowserWindow } from './types';\n\nconst AUTO_ENABLE_MARKER = '__haoriJsBootstrapAutoEnabled__';\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): BrowserWindow | undefined {\n const scope = globalThis as typeof globalThis & { window?: BrowserWindow };\n return scope.window;\n}\n\n/**\n * 既に自動有効化済みかどうかを返す。\n *\n * @param browserWindow 判定対象の window。\n * @return 既に自動有効化済みなら true。\n */\nfunction wasAutoEnabled(browserWindow: BrowserWindow): boolean {\n return Boolean((browserWindow as unknown as Record<string, unknown>)[AUTO_ENABLE_MARKER]);\n}\n\n/**\n * 自動有効化済みの印を付ける。\n *\n * @param browserWindow 更新対象の window。\n * @return 戻り値はない。\n */\nfunction markAutoEnabled(browserWindow: BrowserWindow): void {\n (browserWindow as unknown as Record<string, unknown>)[AUTO_ENABLE_MARKER] = true;\n}\n\n/**\n * 前提が揃っていれば自動有効化を試行する。\n *\n * @return 戻り値はない。\n */\nfunction autoEnable(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow || wasAutoEnabled(browserWindow)) {\n return;\n }\n\n if (!hasAutoEnablePrerequisites(browserWindow)) {\n console.warn(\n '[haori-bootstrap] Auto-enable skipped because window.Haori or window.bootstrap is missing.',\n );\n return;\n }\n\n try {\n install({ bootstrap: browserWindow.bootstrap });\n markAutoEnabled(browserWindow);\n } catch (error) {\n console.warn('[haori-bootstrap] Auto-enable failed.', error);\n }\n}\n\nautoEnable();\n","import './browser';\n\nexport { BootstrapHaori } from './bootstrap_haori';\nexport { hasAutoEnablePrerequisites, install, isInstalled, uninstall } from './install';\nexport type {\n BootstrapNamespace,\n BrowserWindow,\n HaoriBootstrapGlobal,\n HaoriGlobalObject,\n InstallOptions,\n ResolvedInstallOptions,\n} from './types';\n\n/**\n * パッケージの公開版数。\n */\nexport const version = '0.2.0';\n"],"names":["isConstructor","value","resolveModalConstructor","bootstrap","resolveToastConstructor","hasModalSupport","hasToastSupport","createModalInstance","element","options","modalConstructor","createToastInstance","toastConstructor","DIALOG_CONTAINER_ATTRIBUTE","ACTION_ATTRIBUTE","createDialogModalOptions","resolveDialogContainer","documentObject","resolvedElement","createModalShell","message","isConfirm","modalElement","dialogElement","contentElement","bodyElement","messageElement","footerElement","cancelButton","okButton","showDialog","modalInstance","resolve","reject","finalize","handleHidden","error","showConfirm","confirmed","OWNED_ATTRIBUTE","CONTAINER_ATTRIBUTE","INVALID_TARGET_ATTRIBUTE","isChoiceInput","target","isRadioInput","isFieldTarget","getDirectOwnedContainer","createMessageItem","getOwnedDirectChild","getRadioGroupTargets","rootNode","escapedName","groupTargets","findCommonAncestor","elements","firstElement","restElements","candidate","resolveRadioMessageHost","wrappers","commonAncestor","resolveChoiceMessageHost","closestFormCheck","ensureFieldContainer","nextElement","container","ensureChoiceContainer","hostElement","existingContainer","ensureBlockContainer","removeOwnedInvalidState","markChoiceInvalidState","clearChoiceInvalidState","addManagedErrorMessage","clearManagedMessages","parentOrTarget","prepareModalElement","openDialogElement","closeDialogElement","TOAST_CONTAINER_ATTRIBUTE","TOAST_ATTRIBUTE","TOAST_ACCENT_ATTRIBUTE","resolveToastAppearance","level","resolveToastRoot","ensureToastContainer","rootElement","showToast","appearance","toastElement","bodyWrapper","accentElement","toastInstance","context","normalizeMessageText","getBrowserWindow","toPromiseVoid","getOriginalMethod","methodName","method","warnNoop","apiName","fallbackDialog","normalizedMessage","originalMethod","browserWindow","fallbackConfirm","fallbackToast","fallbackModal","setBootstrapHaoriContext","nextContext","BootstrapHaori","DEFAULT_INSTALL_OPTIONS","installState","resolveInstallOptions","hasAutoEnablePrerequisites","install","uninstall","isInstalled","AUTO_ENABLE_MARKER","wasAutoEnabled","markAutoEnabled","autoEnable","version"],"mappings":"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"}
1
+ {"version":3,"file":"haori-bootstrap.iife.js","sources":["../src/bootstrap_resolver.ts","../src/dialog.ts","../src/message.ts","../src/modal.ts","../src/toast.ts","../src/bootstrap_haori.ts","../src/install.ts","../src/browser.ts","../src/index.ts"],"sourcesContent":["import type {\n BootstrapModalConstructor,\n BootstrapModalInstance,\n BootstrapModalOptions,\n BootstrapNamespace,\n BootstrapToastConstructor,\n BootstrapToastInstance,\n} from './types';\n\n/**\n * 値がコンストラクター関数かどうかを判定する。\n *\n * @param value 判定対象の値。\n * @return コンストラクター関数なら true。\n */\nfunction isConstructor<T>(value: unknown): value is new (...args: readonly unknown[]) => T {\n return typeof value === 'function';\n}\n\n/**\n * Bootstrap の Modal コンストラクターを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return Modal コンストラクター。見つからない場合は undefined。\n */\nexport function resolveModalConstructor(\n bootstrap?: BootstrapNamespace,\n): BootstrapModalConstructor | undefined {\n return isConstructor<BootstrapModalInstance>(bootstrap?.Modal)\n ? (bootstrap?.Modal as BootstrapModalConstructor)\n : undefined;\n}\n\n/**\n * Bootstrap の Toast コンストラクターを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return Toast コンストラクター。見つからない場合は undefined。\n */\nexport function resolveToastConstructor(\n bootstrap?: BootstrapNamespace,\n): BootstrapToastConstructor | undefined {\n return isConstructor<BootstrapToastInstance>(bootstrap?.Toast)\n ? (bootstrap?.Toast as BootstrapToastConstructor)\n : undefined;\n}\n\n/**\n * Modal が利用可能かどうかを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return 利用可能なら true。\n */\nexport function hasModalSupport(bootstrap?: BootstrapNamespace): boolean {\n return Boolean(resolveModalConstructor(bootstrap));\n}\n\n/**\n * Toast が利用可能かどうかを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return 利用可能なら true。\n */\nexport function hasToastSupport(bootstrap?: BootstrapNamespace): boolean {\n return Boolean(resolveToastConstructor(bootstrap));\n}\n\n/**\n * Modal インスタンスを取得または生成する。\n *\n * @param element 対象要素。\n * @param bootstrap Bootstrap 名前空間。\n * @return Modal インスタンス。生成できない場合は undefined。\n */\nexport function createModalInstance(\n element: HTMLElement,\n options?: BootstrapModalOptions,\n bootstrap?: BootstrapNamespace,\n): BootstrapModalInstance | undefined {\n const modalConstructor = resolveModalConstructor(bootstrap);\n if (!modalConstructor) {\n return undefined;\n }\n\n if (typeof modalConstructor.getOrCreateInstance === 'function') {\n return modalConstructor.getOrCreateInstance(element, options);\n }\n\n return new modalConstructor(element, options);\n}\n\n/**\n * Toast インスタンスを取得または生成する。\n *\n * @param element 対象要素。\n * @param bootstrap Bootstrap 名前空間。\n * @return Toast インスタンス。生成できない場合は undefined。\n */\nexport function createToastInstance(\n element: HTMLElement,\n bootstrap?: BootstrapNamespace,\n): BootstrapToastInstance | undefined {\n const toastConstructor = resolveToastConstructor(bootstrap);\n if (!toastConstructor) {\n return undefined;\n }\n\n if (typeof toastConstructor.getOrCreateInstance === 'function') {\n return toastConstructor.getOrCreateInstance(element);\n }\n\n return new toastConstructor(element);\n}\n","import { createModalInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\nconst DIALOG_CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-dialog';\nconst ACTION_ATTRIBUTE = 'data-haori-bootstrap-action';\n\n/**\n * dialog 系 modal の既定オプションを返す。\n *\n * @return Bootstrap Modal の生成オプション。\n */\nfunction createDialogModalOptions() {\n return {\n backdrop: 'static' as const,\n };\n}\n\n/**\n * dialog を挿入する親要素を解決する。\n *\n * @param documentObject 検索に使用する document。\n * @param options 解決済み導入設定。\n * @return 挿入先の要素。\n */\nfunction resolveDialogContainer(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n if (options.dialogContainerSelector) {\n const resolvedElement = documentObject.querySelector<HTMLElement>(\n options.dialogContainerSelector,\n );\n if (resolvedElement) {\n return resolvedElement;\n }\n }\n\n return documentObject.body;\n}\n\n/**\n * dialog または confirm 用の modal 要素を組み立てる。\n *\n * @param documentObject 生成に使用する document。\n * @param message 表示するメッセージ。\n * @param isConfirm confirm 用かどうか。\n * @return 生成した modal 要素。\n */\nfunction createModalShell(documentObject: Document, message: string, isConfirm: boolean): HTMLDivElement {\n const modalElement = documentObject.createElement('div');\n modalElement.className = 'modal fade';\n modalElement.tabIndex = -1;\n modalElement.setAttribute(DIALOG_CONTAINER_ATTRIBUTE, 'true');\n modalElement.setAttribute('aria-hidden', 'true');\n\n const dialogElement = documentObject.createElement('div');\n dialogElement.className = 'modal-dialog modal-dialog-centered';\n\n const contentElement = documentObject.createElement('div');\n contentElement.className = 'modal-content';\n\n const bodyElement = documentObject.createElement('div');\n bodyElement.className = 'modal-body';\n\n const messageElement = documentObject.createElement('p');\n messageElement.className = 'mb-0';\n messageElement.style.whiteSpace = 'pre-line';\n messageElement.textContent = message;\n bodyElement.appendChild(messageElement);\n\n const footerElement = documentObject.createElement('div');\n footerElement.className = 'modal-footer';\n\n if (isConfirm) {\n const cancelButton = documentObject.createElement('button');\n cancelButton.type = 'button';\n cancelButton.className = 'btn btn-secondary';\n cancelButton.setAttribute(ACTION_ATTRIBUTE, 'cancel');\n cancelButton.textContent = 'Cancel';\n footerElement.appendChild(cancelButton);\n }\n\n const okButton = documentObject.createElement('button');\n okButton.type = 'button';\n okButton.className = 'btn btn-primary';\n okButton.setAttribute(ACTION_ATTRIBUTE, 'ok');\n okButton.textContent = 'OK';\n footerElement.appendChild(okButton);\n\n contentElement.append(bodyElement, footerElement);\n dialogElement.appendChild(contentElement);\n modalElement.appendChild(dialogElement);\n return modalElement;\n}\n\n/**\n * 情報表示用の Bootstrap Modal を表示する。\n *\n * @param message 表示するメッセージ。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function showDialog(message: string, options: ResolvedInstallOptions): Promise<void> {\n const documentObject = globalThis.document;\n const modalElement = createModalShell(documentObject, message, false);\n resolveDialogContainer(documentObject, options).appendChild(modalElement);\n\n const modalInstance = createModalInstance(\n modalElement,\n createDialogModalOptions(),\n options.bootstrap,\n );\n if (!modalInstance) {\n modalElement.remove();\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n return new Promise<void>((resolve, reject) => {\n const finalize = (): void => {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n resolve();\n };\n\n const handleHidden = (): void => {\n finalize();\n };\n\n const okButton = modalElement.querySelector<HTMLButtonElement>(`[${ACTION_ATTRIBUTE}=\"ok\"]`);\n okButton?.addEventListener(\n 'click',\n () => {\n modalInstance.hide();\n },\n { once: true },\n );\n\n modalElement.addEventListener('hidden.bs.modal', handleHidden, { once: true });\n\n try {\n modalInstance.show();\n } catch (error) {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n reject(error);\n }\n });\n}\n\n/**\n * 確認用の Bootstrap Modal を表示する。\n *\n * @param message 表示するメッセージ。\n * @param options 解決済み導入設定。\n * @return OK のみ true を返す Promise。\n */\nexport function showConfirm(\n message: string,\n options: ResolvedInstallOptions,\n): Promise<boolean> {\n const documentObject = globalThis.document;\n const modalElement = createModalShell(documentObject, message, true);\n resolveDialogContainer(documentObject, options).appendChild(modalElement);\n\n const modalInstance = createModalInstance(\n modalElement,\n createDialogModalOptions(),\n options.bootstrap,\n );\n if (!modalInstance) {\n modalElement.remove();\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n return new Promise<boolean>((resolve, reject) => {\n let confirmed = false;\n\n const finalize = (): void => {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n resolve(confirmed);\n };\n\n const handleHidden = (): void => {\n finalize();\n };\n\n const okButton = modalElement.querySelector<HTMLButtonElement>(`[${ACTION_ATTRIBUTE}=\"ok\"]`);\n const cancelButton = modalElement.querySelector<HTMLButtonElement>(\n `[${ACTION_ATTRIBUTE}=\"cancel\"]`,\n );\n\n okButton?.addEventListener(\n 'click',\n () => {\n confirmed = true;\n modalInstance.hide();\n },\n { once: true },\n );\n cancelButton?.addEventListener(\n 'click',\n () => {\n confirmed = false;\n modalInstance.hide();\n },\n { once: true },\n );\n\n modalElement.addEventListener('hidden.bs.modal', handleHidden, { once: true });\n\n try {\n modalInstance.show();\n } catch (error) {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n reject(error);\n }\n });\n}\n","const OWNED_ATTRIBUTE = 'data-haori-bootstrap-owned';\nconst CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-message-container';\nconst INVALID_TARGET_ATTRIBUTE = 'data-haori-bootstrap-invalid-target';\n\n/**\n * 対象要素が checkbox または radio かどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return checkbox または radio の input 要素なら true。\n */\nfunction isChoiceInput(target: HTMLElement): target is HTMLInputElement {\n return (\n target instanceof HTMLInputElement &&\n (target.type === 'checkbox' || target.type === 'radio')\n );\n}\n\n/**\n * 対象要素が radio input かどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return radio の input 要素なら true。\n */\nfunction isRadioInput(target: HTMLElement): target is HTMLInputElement {\n return target instanceof HTMLInputElement && target.type === 'radio';\n}\n\n/**\n * 対象要素が通常の invalid-feedback を直後に付与するフィールドかどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return 入力系フィールドなら true。\n */\nfunction isFieldTarget(\n target: HTMLElement,\n): target is HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement {\n return (\n target instanceof HTMLInputElement ||\n target instanceof HTMLSelectElement ||\n target instanceof HTMLTextAreaElement\n );\n}\n\n/**\n * 子要素から管理対象のメッセージコンテナを取得する。\n *\n * @param target 検索対象の要素。\n * @return 管理対象コンテナ。見つからない場合は undefined。\n */\nfunction getDirectOwnedContainer(target: HTMLElement): HTMLElement | undefined {\n return Array.from(target.children).find(\n (element): element is HTMLElement =>\n element instanceof HTMLElement && element.getAttribute(CONTAINER_ATTRIBUTE) === 'true',\n );\n}\n\n/**\n * 管理対象のメッセージ要素を生成する。\n *\n * @param documentObject 生成に使用する document。\n * @param message 表示するメッセージ。\n * @return 生成したメッセージ要素。\n */\nfunction createMessageItem(documentObject: Document, message: string): HTMLDivElement {\n const messageElement = documentObject.createElement('div');\n messageElement.setAttribute(OWNED_ATTRIBUTE, 'true');\n messageElement.textContent = message;\n return messageElement;\n}\n\n/**\n * block container 配下の既存メッセージコンテナを取得する。\n *\n * @param target 検索対象の要素。\n * @return 既存コンテナ。見つからない場合は undefined。\n */\nfunction getOwnedDirectChild(target: HTMLElement): HTMLElement | undefined {\n return getDirectOwnedContainer(target);\n}\n\n/**\n * 指定した radio と同じグループに属する radio 要素一覧を取得する。\n *\n * @param target 基準となる radio 要素。\n * @return 同じグループに属する radio 要素一覧。\n */\nfunction getRadioGroupTargets(target: HTMLInputElement): HTMLInputElement[] {\n if (target.name) {\n const rootNode = target.form ?? target.ownerDocument;\n const escapedName = typeof CSS !== 'undefined' && typeof CSS.escape === 'function'\n ? CSS.escape(target.name)\n : target.name.replace(/([\"\\\\])/g, '\\\\$1');\n const groupTargets = Array.from(\n rootNode.querySelectorAll<HTMLInputElement>(`input[type=\"radio\"][name=\"${escapedName}\"]`),\n );\n if (groupTargets.length > 0) {\n return groupTargets;\n }\n }\n\n return [target];\n}\n\n/**\n * 複数要素の最も近い共通祖先要素を返す。\n *\n * @param elements 判定対象の要素一覧。\n * @return 共通祖先要素。見つからない場合は undefined。\n */\nfunction findCommonAncestor(elements: readonly HTMLElement[]): HTMLElement | undefined {\n const [firstElement, ...restElements] = elements;\n if (!firstElement) {\n return undefined;\n }\n\n let candidate: HTMLElement | null = firstElement;\n while (candidate) {\n if (restElements.every((element) => candidate?.contains(element))) {\n return candidate;\n }\n candidate = candidate.parentElement;\n }\n\n return undefined;\n}\n\n/**\n * radio group のメッセージ挿入先を解決する。\n *\n * @param target 対象の radio 要素。\n * @return 挿入先の要素。見つからない場合は undefined。\n */\nfunction resolveRadioMessageHost(target: HTMLInputElement): HTMLElement | undefined {\n const groupTargets = getRadioGroupTargets(target);\n const wrappers = groupTargets\n .map((element) => element.closest('.form-check'))\n .filter((element): element is HTMLElement => element instanceof HTMLElement);\n\n if (wrappers.length > 1) {\n const commonAncestor = findCommonAncestor(wrappers);\n if (commonAncestor && !wrappers.includes(commonAncestor)) {\n return commonAncestor;\n }\n }\n\n return resolveChoiceMessageHost(target);\n}\n\n/**\n * checkbox と radio のメッセージ挿入先を解決する。\n *\n * @param target 対象の input 要素。\n * @return 挿入先の form-check 要素。見つからない場合は undefined。\n */\nfunction resolveChoiceMessageHost(target: HTMLInputElement): HTMLElement | undefined {\n const closestFormCheck = target.closest('.form-check');\n return closestFormCheck instanceof HTMLElement ? closestFormCheck : undefined;\n}\n\n/**\n * 通常フィールドの直後に invalid-feedback コンテナを取得または生成する。\n *\n * @param target 対象の要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureFieldContainer(target: HTMLElement): HTMLElement {\n const nextElement = target.nextElementSibling;\n if (\n nextElement instanceof HTMLElement &&\n nextElement.getAttribute(CONTAINER_ATTRIBUTE) === 'true'\n ) {\n return nextElement;\n }\n\n const container = document.createElement('div');\n container.className = 'invalid-feedback d-block';\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n target.insertAdjacentElement('afterend', container);\n return container;\n}\n\n/**\n * checkbox と radio 用に form-check 末尾の invalid-feedback を取得または生成する。\n *\n * @param target 対象の input 要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureChoiceContainer(target: HTMLInputElement): HTMLElement {\n const hostElement = isRadioInput(target)\n ? resolveRadioMessageHost(target)\n : resolveChoiceMessageHost(target);\n if (!hostElement) {\n return ensureFieldContainer(target);\n }\n\n const existingContainer = getDirectOwnedContainer(hostElement);\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = 'invalid-feedback d-block';\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n hostElement.appendChild(container);\n return container;\n}\n\n/**\n * container target の先頭に alert コンテナを取得または生成する。\n *\n * @param target 対象の要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureBlockContainer(target: HTMLElement): HTMLElement {\n const existingContainer = getOwnedDirectChild(target);\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = 'alert alert-danger';\n container.setAttribute('role', 'alert');\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n target.insertAdjacentElement('afterbegin', container);\n return container;\n}\n\n/**\n * このライブラリが付けた is-invalid 状態だけを外す。\n *\n * @param target 状態を解除する要素。\n * @return 戻り値はない。\n */\nfunction removeOwnedInvalidState(target: HTMLElement): void {\n if (target.getAttribute(INVALID_TARGET_ATTRIBUTE) !== 'true') {\n return;\n }\n\n target.classList.remove('is-invalid');\n target.removeAttribute(INVALID_TARGET_ATTRIBUTE);\n}\n\n/**\n * choice input に対して、このライブラリが付けた invalid 状態を付与する。\n *\n * @param target 対象の input 要素。\n * @return 戻り値はない。\n */\nfunction markChoiceInvalidState(target: HTMLInputElement): void {\n const targets = isRadioInput(target) ? getRadioGroupTargets(target) : [target];\n targets.forEach((element) => {\n element.classList.add('is-invalid');\n element.setAttribute(INVALID_TARGET_ATTRIBUTE, 'true');\n });\n}\n\n/**\n * choice input に対して、このライブラリが付けた invalid 状態を解除する。\n *\n * @param target 対象の input 要素。\n * @return 戻り値はない。\n */\nfunction clearChoiceInvalidState(target: HTMLInputElement): void {\n const targets = isRadioInput(target) ? getRadioGroupTargets(target) : [target];\n targets.forEach((element) => {\n removeOwnedInvalidState(element);\n });\n}\n\n/**\n * 管理対象のエラーメッセージを追加する。\n *\n * @param target 追加先の要素。\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\nexport function addManagedErrorMessage(target: HTMLElement, message: string): Promise<void> {\n const container = isChoiceInput(target)\n ? ensureChoiceContainer(target)\n : isFieldTarget(target)\n ? ensureFieldContainer(target)\n : ensureBlockContainer(target);\n container.appendChild(createMessageItem(document, message));\n\n if (isChoiceInput(target)) {\n markChoiceInvalidState(target);\n } else if (isFieldTarget(target)) {\n target.classList.add('is-invalid');\n target.setAttribute(INVALID_TARGET_ATTRIBUTE, 'true');\n }\n\n return Promise.resolve();\n}\n\n/**\n * 管理対象のメッセージを削除する。\n *\n * @param parentOrTarget 削除対象の親要素または対象要素。\n * @return 完了時に解決される Promise。\n */\nexport function clearManagedMessages(parentOrTarget: HTMLElement): Promise<void> {\n if (isChoiceInput(parentOrTarget)) {\n const hostElement = isRadioInput(parentOrTarget)\n ? resolveRadioMessageHost(parentOrTarget)\n : resolveChoiceMessageHost(parentOrTarget);\n const ownedContainer = hostElement ? getDirectOwnedContainer(hostElement) : undefined;\n ownedContainer?.remove();\n clearChoiceInvalidState(parentOrTarget);\n } else if (isFieldTarget(parentOrTarget)) {\n const nextElement = parentOrTarget.nextElementSibling;\n if (\n nextElement instanceof HTMLElement &&\n nextElement.getAttribute(CONTAINER_ATTRIBUTE) === 'true'\n ) {\n nextElement.remove();\n }\n removeOwnedInvalidState(parentOrTarget);\n }\n\n const ownedContainers = parentOrTarget.querySelectorAll<HTMLElement>(\n `[${CONTAINER_ATTRIBUTE}=\"true\"]`,\n );\n ownedContainers.forEach((element) => {\n element.remove();\n });\n\n const invalidTargets = parentOrTarget.querySelectorAll<HTMLElement>(\n `[${INVALID_TARGET_ATTRIBUTE}=\"true\"]`,\n );\n invalidTargets.forEach((element) => {\n removeOwnedInvalidState(element);\n });\n\n return Promise.resolve();\n}\n","import { createModalInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\n/**\n * 既存要素を Bootstrap Modal として扱える最低限の属性へ整える。\n *\n * @param element 整形対象の要素。\n * @return 戻り値はない。\n */\nfunction prepareModalElement(element: HTMLElement): void {\n if (!element.classList.contains('modal')) {\n element.classList.add('modal');\n }\n\n if (element.tabIndex < 0) {\n element.tabIndex = -1;\n }\n\n if (!element.hasAttribute('aria-hidden')) {\n element.setAttribute('aria-hidden', 'true');\n }\n}\n\n/**\n * 任意要素を Bootstrap Modal として開く。\n *\n * @param element 開く対象の要素。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function openDialogElement(\n element: HTMLElement,\n options: ResolvedInstallOptions,\n): Promise<void> {\n prepareModalElement(element);\n const modalInstance = createModalInstance(element, undefined, options.bootstrap);\n if (!modalInstance) {\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n modalInstance.show();\n return Promise.resolve();\n}\n\n/**\n * 任意要素を Bootstrap Modal として閉じる。\n *\n * @param element 閉じる対象の要素。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function closeDialogElement(\n element: HTMLElement,\n options: ResolvedInstallOptions,\n): Promise<void> {\n prepareModalElement(element);\n const modalInstance = createModalInstance(element, undefined, options.bootstrap);\n if (!modalInstance) {\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n modalInstance.hide();\n return Promise.resolve();\n}\n","import { createToastInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\nconst TOAST_CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-toast-container';\nconst TOAST_ATTRIBUTE = 'data-haori-bootstrap-toast';\nconst TOAST_ACCENT_ATTRIBUTE = 'data-haori-bootstrap-toast-accent';\n\ninterface ToastAppearance {\n accentClassName: string;\n}\n\n/**\n * 通知レベルを toast 表示用の見た目へ変換する。\n *\n * @param level 通知レベル。\n * @return 対応する見た目定義。\n */\nfunction resolveToastAppearance(level?: string): ToastAppearance {\n switch (level) {\n case 'warning':\n return { accentClassName: 'bg-warning' };\n case 'error':\n return { accentClassName: 'bg-danger' };\n default:\n return { accentClassName: 'bg-info' };\n }\n}\n\n/**\n * toast コンテナを配置する親要素を解決する。\n *\n * @param documentObject 検索に使用する document。\n * @param options 解決済み導入設定。\n * @return 配置先の要素。\n */\nfunction resolveToastRoot(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n if (options.toastContainerSelector) {\n const resolvedElement = documentObject.querySelector<HTMLElement>(options.toastContainerSelector);\n if (resolvedElement) {\n return resolvedElement;\n }\n }\n\n return documentObject.body;\n}\n\n/**\n * toast コンテナを取得または生成する。\n *\n * @param documentObject 生成に使用する document。\n * @param options 解決済み導入設定。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureToastContainer(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n const rootElement = resolveToastRoot(documentObject, options);\n const existingContainer = rootElement.querySelector<HTMLElement>(\n `[${TOAST_CONTAINER_ATTRIBUTE}=\"true\"]`,\n );\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = documentObject.createElement('div');\n container.className = 'toast-container position-fixed bottom-0 end-0 p-3';\n container.setAttribute(TOAST_CONTAINER_ATTRIBUTE, 'true');\n rootElement.appendChild(container);\n return container;\n}\n\n/**\n * Bootstrap Toast を表示する。\n *\n * @param message 表示するメッセージ。\n * @param level 通知レベル。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function showToast(\n message: string,\n level: string | undefined,\n options: ResolvedInstallOptions,\n): Promise<void> {\n const documentObject = globalThis.document;\n const appearance = resolveToastAppearance(level);\n const toastElement = documentObject.createElement('div');\n toastElement.className = 'toast border bg-body text-body shadow-sm';\n toastElement.setAttribute('role', 'status');\n toastElement.setAttribute('aria-live', 'polite');\n toastElement.setAttribute('aria-atomic', 'true');\n toastElement.setAttribute(TOAST_ATTRIBUTE, 'true');\n\n const bodyWrapper = documentObject.createElement('div');\n bodyWrapper.className = 'd-flex align-items-stretch';\n\n const accentElement = documentObject.createElement('div');\n accentElement.className = `flex-shrink-0 rounded-start ${appearance.accentClassName}`;\n accentElement.style.width = '0.375rem';\n accentElement.setAttribute(TOAST_ACCENT_ATTRIBUTE, 'true');\n\n const bodyElement = documentObject.createElement('div');\n bodyElement.className = 'toast-body';\n bodyElement.style.whiteSpace = 'pre-line';\n bodyElement.textContent = message;\n\n bodyWrapper.appendChild(accentElement);\n bodyWrapper.appendChild(bodyElement);\n toastElement.appendChild(bodyWrapper);\n ensureToastContainer(documentObject, options).appendChild(toastElement);\n\n const toastInstance = createToastInstance(toastElement, options.bootstrap);\n if (!toastInstance) {\n toastElement.remove();\n return Promise.reject(new Error('Bootstrap Toast is unavailable.'));\n }\n\n toastElement.addEventListener(\n 'hidden.bs.toast',\n () => {\n toastElement.remove();\n toastInstance.dispose?.();\n },\n { once: true },\n );\n\n try {\n toastInstance.show();\n return Promise.resolve();\n } catch (error) {\n toastElement.remove();\n toastInstance.dispose?.();\n return Promise.reject(error);\n }\n}\n","import { hasModalSupport, hasToastSupport } from './bootstrap_resolver';\nimport { showConfirm, showDialog } from './dialog';\nimport { addManagedErrorMessage, clearManagedMessages } from './message';\nimport { closeDialogElement, openDialogElement } from './modal';\nimport { showToast } from './toast';\nimport type { HaoriGlobalObject, ResolvedInstallOptions } from './types';\n\n/**\n * BootstrapHaori が利用する内部コンテキスト。\n */\nexport interface BootstrapHaoriContext {\n /** 差し替え前の Haori 実装。 */\n originalHaori?: HaoriGlobalObject;\n /** 解決済みの導入設定。 */\n options: ResolvedInstallOptions;\n}\n\nconst defaultContext: BootstrapHaoriContext = {\n options: {\n fallbackToNative: true,\n },\n};\n\nlet context = defaultContext;\n\n/**\n * 表示用 message 中のエスケープ済み改行を実際の改行へ正規化する。\n *\n * @param message 正規化対象のメッセージ。\n * @return 正規化後のメッセージ。\n */\nfunction normalizeMessageText(message: string): string {\n return message.replace(/\\\\n/g, '\\n');\n}\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): Window | undefined {\n const scope = globalThis as typeof globalThis & { window?: Window };\n return scope.window;\n}\n\n/**\n * 値を Promise<void> 契約へ正規化する。\n *\n * @param value 正規化対象の値。\n * @return 完了時に解決される Promise。\n */\nfunction toPromiseVoid(value: Promise<void> | void | unknown): Promise<void> {\n return Promise.resolve(value).then(() => undefined);\n}\n\n/**\n * 元の Haori 実装から対象メソッドを取得する。\n *\n * @param methodName 取得対象のメソッド名。\n * @return 対象メソッド。見つからない場合は undefined。\n */\nfunction getOriginalMethod(\n methodName: keyof HaoriGlobalObject,\n): ((...args: readonly unknown[]) => unknown) | undefined {\n const method = context.originalHaori?.[methodName];\n return typeof method === 'function'\n ? (method as (...args: readonly unknown[]) => unknown)\n : undefined;\n}\n\n/**\n * no-op に正規化したことを警告する。\n *\n * @param apiName 利用できなかった API 名。\n * @return 戻り値はない。\n */\nfunction warnNoop(apiName: string): void {\n console.warn(`[haori-bootstrap] ${apiName} skipped because Bootstrap support is unavailable.`);\n}\n\n/**\n * dialog の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackDialog(message: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('dialog');\n if (originalMethod) {\n return toPromiseVoid(originalMethod(normalizedMessage));\n }\n\n const browserWindow = getBrowserWindow();\n if (context.options.fallbackToNative && typeof browserWindow?.alert === 'function') {\n browserWindow.alert(normalizedMessage);\n return Promise.resolve();\n }\n\n warnNoop('dialog');\n return Promise.resolve();\n}\n\n/**\n * confirm の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @return 確認結果を返す Promise。\n */\nfunction fallbackConfirm(message: string): Promise<boolean> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('confirm');\n if (originalMethod) {\n return Promise.resolve(originalMethod(normalizedMessage) as Promise<boolean> | boolean).then(\n (value) => Boolean(value),\n );\n }\n\n const browserWindow = getBrowserWindow();\n if (context.options.fallbackToNative && typeof browserWindow?.confirm === 'function') {\n return Promise.resolve(browserWindow.confirm(normalizedMessage));\n }\n\n warnNoop('confirm');\n return Promise.resolve(false);\n}\n\n/**\n * toast の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @param level 通知レベル。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackToast(message: string, level?: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('toast');\n if (originalMethod) {\n return toPromiseVoid(originalMethod(normalizedMessage, level));\n }\n\n warnNoop('toast');\n return Promise.resolve();\n}\n\n/**\n * openDialog または closeDialog の fallback 経路を処理する。\n *\n * @param methodName 呼び出す API 名。\n * @param element 対象要素。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackModal(methodName: 'openDialog' | 'closeDialog', element: HTMLElement): Promise<void> {\n const originalMethod = getOriginalMethod(methodName);\n if (originalMethod) {\n return toPromiseVoid(originalMethod(element));\n }\n\n warnNoop(methodName);\n return Promise.resolve();\n}\n\n/**\n * BootstrapHaori が参照する内部状態を更新する。\n *\n * @param nextContext 差し替え先が参照する内部コンテキスト。\n * @return 戻り値はない。\n */\nexport function setBootstrapHaoriContext(nextContext: BootstrapHaoriContext): void {\n context = nextContext;\n}\n\n/**\n * Haori の UI 系静的メソッドを差し替える最小ファサード。\n */\nexport class BootstrapHaori {\n /**\n * 情報表示ダイアログを表示する。\n *\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\n public static dialog(message: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasModalSupport(context.options.bootstrap)) {\n return showDialog(normalizedMessage, context.options).catch(() => fallbackDialog(normalizedMessage));\n }\n\n return fallbackDialog(normalizedMessage);\n }\n\n /**\n * 確認ダイアログを表示する。\n *\n * @param message 表示するメッセージ。\n * @return OK のみ true を返す Promise。\n */\n public static confirm(message: string): Promise<boolean> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasModalSupport(context.options.bootstrap)) {\n return showConfirm(normalizedMessage, context.options).catch(() => fallbackConfirm(normalizedMessage));\n }\n\n return fallbackConfirm(normalizedMessage);\n }\n\n /**\n * トースト通知を表示する。\n *\n * @param message 表示するメッセージ。\n * @param level 通知レベル。\n * @return 完了時に解決される Promise。\n */\n public static toast(message: string, level?: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasToastSupport(context.options.bootstrap)) {\n return showToast(normalizedMessage, level, context.options).catch(() =>\n fallbackToast(normalizedMessage, level),\n );\n }\n\n return fallbackToast(normalizedMessage, level);\n }\n\n /**\n * 任意のダイアログ要素を開く。\n *\n * @param element 開く対象の要素。\n * @return 完了時に解決される Promise。\n */\n public static openDialog(element: HTMLElement): Promise<void> {\n if (hasModalSupport(context.options.bootstrap)) {\n return openDialogElement(element, context.options).catch(() =>\n fallbackModal('openDialog', element),\n );\n }\n\n return fallbackModal('openDialog', element);\n }\n\n /**\n * 任意のダイアログ要素を閉じる。\n *\n * @param element 閉じる対象の要素。\n * @return 完了時に解決される Promise。\n */\n public static closeDialog(element: HTMLElement): Promise<void> {\n if (hasModalSupport(context.options.bootstrap)) {\n return closeDialogElement(element, context.options).catch(() =>\n fallbackModal('closeDialog', element),\n );\n }\n\n return fallbackModal('closeDialog', element);\n }\n\n /**\n * 管理対象のエラーメッセージを追加する。\n *\n * @param target 追加先の要素。\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\n public static addErrorMessage(target: HTMLElement, message: string): Promise<void> {\n return addManagedErrorMessage(target, message);\n }\n\n /**\n * 管理対象のメッセージを削除する。\n *\n * @param parentOrTarget 削除対象の親要素または対象要素。\n * @return 完了時に解決される Promise。\n */\n public static clearMessages(parentOrTarget: HTMLElement): Promise<void> {\n return clearManagedMessages(parentOrTarget);\n }\n}\n","import { BootstrapHaori, setBootstrapHaoriContext } from './bootstrap_haori';\nimport type {\n BrowserWindow,\n HaoriGlobalObject,\n InstallOptions,\n ResolvedInstallOptions,\n} from './types';\n\nconst DEFAULT_INSTALL_OPTIONS: ResolvedInstallOptions = {\n fallbackToNative: true,\n};\n\nconst installState: {\n installed: boolean;\n originalHaori?: HaoriGlobalObject;\n options: ResolvedInstallOptions;\n} = {\n installed: false,\n options: DEFAULT_INSTALL_OPTIONS,\n};\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): BrowserWindow | undefined {\n const scope = globalThis as typeof globalThis & { window?: BrowserWindow };\n return scope.window;\n}\n\n/**\n * install に渡された設定を既定値込みで解決する。\n *\n * @param options 指定された導入設定。\n * @param browserWindow 現在の window。\n * @return 解決済みの導入設定。\n */\nfunction resolveInstallOptions(\n options: InstallOptions,\n browserWindow: BrowserWindow | undefined,\n): ResolvedInstallOptions {\n return {\n bootstrap: options.bootstrap ?? browserWindow?.bootstrap,\n fallbackToNative: options.fallbackToNative ?? DEFAULT_INSTALL_OPTIONS.fallbackToNative,\n runtime:\n options.runtime ?? installState.options.runtime ?? browserWindow?.Haori?.runtime,\n toastContainerSelector: options.toastContainerSelector,\n dialogContainerSelector: options.dialogContainerSelector,\n };\n}\n\n/**\n * 自動有効化に必要な前提が揃っているかを返す。\n *\n * @param browserWindow 判定対象の window。\n * @return 自動有効化可能なら true。\n */\nexport function hasAutoEnablePrerequisites(\n browserWindow: BrowserWindow | undefined = getBrowserWindow(),\n): boolean {\n return Boolean(browserWindow?.Haori && browserWindow.bootstrap);\n}\n\n/**\n * Bootstrap 対応 Haori を再適用し、必要なら設定を上書きする。\n *\n * @param options 上書きする導入設定。\n * @return 戻り値はない。\n */\nexport function install(options: InstallOptions = {}): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow?.Haori) {\n throw new Error('window.Haori is required before calling install().');\n }\n\n if (!installState.originalHaori) {\n installState.originalHaori = browserWindow.Haori;\n }\n\n installState.options = resolveInstallOptions(options, browserWindow);\n if (\n installState.options.runtime &&\n typeof browserWindow.Haori.setRuntime === 'function'\n ) {\n browserWindow.Haori.setRuntime(installState.options.runtime);\n }\n setBootstrapHaoriContext({\n originalHaori: installState.originalHaori,\n options: installState.options,\n });\n browserWindow.Haori = BootstrapHaori as unknown as HaoriGlobalObject;\n installState.installed = true;\n}\n\n/**\n * 元の Haori 実装を復元する。\n *\n * @return 戻り値はない。\n */\nexport function uninstall(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow || !installState.originalHaori) {\n return;\n }\n\n browserWindow.Haori = installState.originalHaori;\n installState.installed = false;\n installState.originalHaori = undefined;\n}\n\n/**\n * 現在 BootstrapHaori が有効かどうかを返す。\n *\n * @return 有効なら true。\n */\nexport function isInstalled(): boolean {\n return installState.installed;\n}\n","import { hasAutoEnablePrerequisites, install } from './install';\nimport type { BrowserWindow } from './types';\n\nconst AUTO_ENABLE_MARKER = '__haoriJsBootstrapAutoEnabled__';\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): BrowserWindow | undefined {\n const scope = globalThis as typeof globalThis & { window?: BrowserWindow };\n return scope.window;\n}\n\n/**\n * 既に自動有効化済みかどうかを返す。\n *\n * @param browserWindow 判定対象の window。\n * @return 既に自動有効化済みなら true。\n */\nfunction wasAutoEnabled(browserWindow: BrowserWindow): boolean {\n return Boolean((browserWindow as unknown as Record<string, unknown>)[AUTO_ENABLE_MARKER]);\n}\n\n/**\n * 自動有効化済みの印を付ける。\n *\n * @param browserWindow 更新対象の window。\n * @return 戻り値はない。\n */\nfunction markAutoEnabled(browserWindow: BrowserWindow): void {\n (browserWindow as unknown as Record<string, unknown>)[AUTO_ENABLE_MARKER] = true;\n}\n\n/**\n * 前提が揃っていれば自動有効化を試行する。\n *\n * @return 戻り値はない。\n */\nfunction autoEnable(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow || wasAutoEnabled(browserWindow)) {\n return;\n }\n\n if (!hasAutoEnablePrerequisites(browserWindow)) {\n console.warn(\n '[haori-bootstrap] Auto-enable skipped because window.Haori or window.bootstrap is missing.',\n );\n return;\n }\n\n try {\n install({ bootstrap: browserWindow.bootstrap });\n markAutoEnabled(browserWindow);\n } catch (error) {\n console.warn('[haori-bootstrap] Auto-enable failed.', error);\n }\n}\n\nautoEnable();\n","import './browser';\n\nexport { BootstrapHaori } from './bootstrap_haori';\nexport { hasAutoEnablePrerequisites, install, isInstalled, uninstall } from './install';\nexport type {\n BootstrapNamespace,\n BrowserWindow,\n HaoriBootstrapGlobal,\n HaoriGlobalObject,\n InstallOptions,\n ResolvedInstallOptions,\n} from './types';\n\n/**\n * パッケージの公開版数。\n */\nexport const version = '0.3.0';\n"],"names":["isConstructor","value","resolveModalConstructor","bootstrap","resolveToastConstructor","hasModalSupport","hasToastSupport","createModalInstance","element","options","modalConstructor","createToastInstance","toastConstructor","DIALOG_CONTAINER_ATTRIBUTE","ACTION_ATTRIBUTE","createDialogModalOptions","resolveDialogContainer","documentObject","resolvedElement","createModalShell","message","isConfirm","modalElement","dialogElement","contentElement","bodyElement","messageElement","footerElement","cancelButton","okButton","showDialog","modalInstance","resolve","reject","finalize","handleHidden","error","showConfirm","confirmed","OWNED_ATTRIBUTE","CONTAINER_ATTRIBUTE","INVALID_TARGET_ATTRIBUTE","isChoiceInput","target","isRadioInput","isFieldTarget","getDirectOwnedContainer","createMessageItem","getOwnedDirectChild","getRadioGroupTargets","rootNode","escapedName","groupTargets","findCommonAncestor","elements","firstElement","restElements","candidate","resolveRadioMessageHost","wrappers","commonAncestor","resolveChoiceMessageHost","closestFormCheck","ensureFieldContainer","nextElement","container","ensureChoiceContainer","hostElement","existingContainer","ensureBlockContainer","removeOwnedInvalidState","markChoiceInvalidState","clearChoiceInvalidState","addManagedErrorMessage","clearManagedMessages","parentOrTarget","prepareModalElement","openDialogElement","closeDialogElement","TOAST_CONTAINER_ATTRIBUTE","TOAST_ATTRIBUTE","TOAST_ACCENT_ATTRIBUTE","resolveToastAppearance","level","resolveToastRoot","ensureToastContainer","rootElement","showToast","appearance","toastElement","bodyWrapper","accentElement","toastInstance","context","normalizeMessageText","getBrowserWindow","toPromiseVoid","getOriginalMethod","methodName","method","warnNoop","apiName","fallbackDialog","normalizedMessage","originalMethod","browserWindow","fallbackConfirm","fallbackToast","fallbackModal","setBootstrapHaoriContext","nextContext","BootstrapHaori","DEFAULT_INSTALL_OPTIONS","installState","resolveInstallOptions","hasAutoEnablePrerequisites","install","uninstall","isInstalled","AUTO_ENABLE_MARKER","wasAutoEnabled","markAutoEnabled","autoEnable","version"],"mappings":"6CAeA,SAASA,EAAiBC,EAAiE,CACzF,OAAO,OAAOA,GAAU,UAC1B,CAQO,SAASC,EACdC,EACuC,CACvC,OAAOH,EAAsCG,GAAW,KAAK,EACxDA,GAAW,MACZ,MACN,CAQO,SAASC,EACdD,EACuC,CACvC,OAAOH,EAAsCG,GAAW,KAAK,EACxDA,GAAW,MACZ,MACN,CAQO,SAASE,EAAgBF,EAAyC,CACvE,MAAO,EAAQD,EAAwBC,CAAS,CAClD,CAQO,SAASG,EAAgBH,EAAyC,CACvE,MAAO,EAAQC,EAAwBD,CAAS,CAClD,CASO,SAASI,EACdC,EACAC,EACAN,EACoC,CACpC,MAAMO,EAAmBR,EAAwBC,CAAS,EAC1D,GAAKO,EAIL,OAAI,OAAOA,EAAiB,qBAAwB,WAC3CA,EAAiB,oBAAoBF,EAASC,CAAO,EAGvD,IAAIC,EAAiBF,EAASC,CAAO,CAC9C,CASO,SAASE,EACdH,EACAL,EACoC,CACpC,MAAMS,EAAmBR,EAAwBD,CAAS,EAC1D,GAAKS,EAIL,OAAI,OAAOA,EAAiB,qBAAwB,WAC3CA,EAAiB,oBAAoBJ,CAAO,EAG9C,IAAII,EAAiBJ,CAAO,CACrC,CC7GA,MAAMK,GAA6B,8BAC7BC,EAAmB,8BAOzB,SAASC,GAA2B,CAClC,MAAO,CACL,SAAU,QAAA,CAEd,CASA,SAASC,EAAuBC,EAA0BR,EAA8C,CACtG,GAAIA,EAAQ,wBAAyB,CACnC,MAAMS,EAAkBD,EAAe,cACrCR,EAAQ,uBAAA,EAEV,GAAIS,EACF,OAAOA,CAEX,CAEA,OAAOD,EAAe,IACxB,CAUA,SAASE,EAAiBF,EAA0BG,EAAiBC,EAAoC,CACvG,MAAMC,EAAeL,EAAe,cAAc,KAAK,EACvDK,EAAa,UAAY,aACzBA,EAAa,SAAW,GACxBA,EAAa,aAAaT,GAA4B,MAAM,EAC5DS,EAAa,aAAa,cAAe,MAAM,EAE/C,MAAMC,EAAgBN,EAAe,cAAc,KAAK,EACxDM,EAAc,UAAY,qCAE1B,MAAMC,EAAiBP,EAAe,cAAc,KAAK,EACzDO,EAAe,UAAY,gBAE3B,MAAMC,EAAcR,EAAe,cAAc,KAAK,EACtDQ,EAAY,UAAY,aAExB,MAAMC,EAAiBT,EAAe,cAAc,GAAG,EACvDS,EAAe,UAAY,OAC3BA,EAAe,MAAM,WAAa,WAClCA,EAAe,YAAcN,EAC7BK,EAAY,YAAYC,CAAc,EAEtC,MAAMC,EAAgBV,EAAe,cAAc,KAAK,EAGxD,GAFAU,EAAc,UAAY,eAEtBN,EAAW,CACb,MAAMO,EAAeX,EAAe,cAAc,QAAQ,EAC1DW,EAAa,KAAO,SACpBA,EAAa,UAAY,oBACzBA,EAAa,aAAad,EAAkB,QAAQ,EACpDc,EAAa,YAAc,SAC3BD,EAAc,YAAYC,CAAY,CACxC,CAEA,MAAMC,EAAWZ,EAAe,cAAc,QAAQ,EACtD,OAAAY,EAAS,KAAO,SAChBA,EAAS,UAAY,kBACrBA,EAAS,aAAaf,EAAkB,IAAI,EAC5Ce,EAAS,YAAc,KACvBF,EAAc,YAAYE,CAAQ,EAElCL,EAAe,OAAOC,EAAaE,CAAa,EAChDJ,EAAc,YAAYC,CAAc,EACxCF,EAAa,YAAYC,CAAa,EAC/BD,CACT,CASO,SAASQ,GAAWV,EAAiBX,EAAgD,CAC1F,MAAMQ,EAAiB,WAAW,SAC5BK,EAAeH,EAAiBF,EAAgBG,EAAS,EAAK,EACpEJ,EAAuBC,EAAgBR,CAAO,EAAE,YAAYa,CAAY,EAExE,MAAMS,EAAgBxB,EACpBe,EACAP,EAAA,EACAN,EAAQ,SAAA,EAEV,OAAKsB,EAKE,IAAI,QAAc,CAACC,EAASC,IAAW,CAC5C,MAAMC,EAAW,IAAY,CAC3BZ,EAAa,oBAAoB,kBAAmBa,CAAY,EAChEb,EAAa,OAAA,EACbS,EAAc,UAAA,EACdC,EAAA,CACF,EAEMG,EAAe,IAAY,CAC/BD,EAAA,CACF,EAEiBZ,EAAa,cAAiC,IAAIR,CAAgB,QAAQ,GACjF,iBACR,QACA,IAAM,CACJiB,EAAc,KAAA,CAChB,EACA,CAAE,KAAM,EAAA,CAAK,EAGfT,EAAa,iBAAiB,kBAAmBa,EAAc,CAAE,KAAM,GAAM,EAE7E,GAAI,CACFJ,EAAc,KAAA,CAChB,OAASK,EAAO,CACdd,EAAa,oBAAoB,kBAAmBa,CAAY,EAChEb,EAAa,OAAA,EACbS,EAAc,UAAA,EACdE,EAAOG,CAAK,CACd,CACF,CAAC,GAnCCd,EAAa,OAAA,EACN,QAAQ,OAAO,IAAI,MAAM,iCAAiC,CAAC,EAmCtE,CASO,SAASe,GACdjB,EACAX,EACkB,CAClB,MAAMQ,EAAiB,WAAW,SAC5BK,EAAeH,EAAiBF,EAAgBG,EAAS,EAAI,EACnEJ,EAAuBC,EAAgBR,CAAO,EAAE,YAAYa,CAAY,EAExE,MAAMS,EAAgBxB,EACpBe,EACAP,EAAA,EACAN,EAAQ,SAAA,EAEV,OAAKsB,EAKE,IAAI,QAAiB,CAACC,EAASC,IAAW,CAC/C,IAAIK,EAAY,GAEhB,MAAMJ,EAAW,IAAY,CAC3BZ,EAAa,oBAAoB,kBAAmBa,CAAY,EAChEb,EAAa,OAAA,EACbS,EAAc,UAAA,EACdC,EAAQM,CAAS,CACnB,EAEMH,EAAe,IAAY,CAC/BD,EAAA,CACF,EAEML,EAAWP,EAAa,cAAiC,IAAIR,CAAgB,QAAQ,EACrFc,GAAeN,EAAa,cAChC,IAAIR,CAAgB,YAAA,EAGtBe,GAAU,iBACR,QACA,IAAM,CACJS,EAAY,GACZP,EAAc,KAAA,CAChB,EACA,CAAE,KAAM,EAAA,CAAK,EAEfH,IAAc,iBACZ,QACA,IAAM,CACJU,EAAY,GACZP,EAAc,KAAA,CAChB,EACA,CAAE,KAAM,EAAA,CAAK,EAGfT,EAAa,iBAAiB,kBAAmBa,EAAc,CAAE,KAAM,GAAM,EAE7E,GAAI,CACFJ,EAAc,KAAA,CAChB,OAASK,GAAO,CACdd,EAAa,oBAAoB,kBAAmBa,CAAY,EAChEb,EAAa,OAAA,EACbS,EAAc,UAAA,EACdE,EAAOG,EAAK,CACd,CACF,CAAC,GAlDCd,EAAa,OAAA,EACN,QAAQ,OAAO,IAAI,MAAM,iCAAiC,CAAC,EAkDtE,CC5NA,MAAMiB,EAAkB,6BAClBC,EAAsB,yCACtBC,EAA2B,sCAQjC,SAASC,EAAcC,EAAiD,CACtE,OACEA,aAAkB,mBACjBA,EAAO,OAAS,YAAcA,EAAO,OAAS,QAEnD,CAQA,SAASC,EAAaD,EAAiD,CACrE,OAAOA,aAAkB,kBAAoBA,EAAO,OAAS,OAC/D,CAQA,SAASE,EACPF,EACsE,CACtE,OACEA,aAAkB,kBAClBA,aAAkB,mBAClBA,aAAkB,mBAEtB,CAQA,SAASG,EAAwBH,EAA8C,CAC7E,OAAO,MAAM,KAAKA,EAAO,QAAQ,EAAE,KAChCnC,GACCA,aAAmB,aAAeA,EAAQ,aAAagC,CAAmB,IAAM,MAAA,CAEtF,CASA,SAASO,GAAkB9B,EAA0BG,EAAiC,CACpF,MAAMM,EAAiBT,EAAe,cAAc,KAAK,EACzD,OAAAS,EAAe,aAAaa,EAAiB,MAAM,EACnDb,EAAe,YAAcN,EACtBM,CACT,CAQA,SAASsB,GAAoBL,EAA8C,CACzE,OAAOG,EAAwBH,CAAM,CACvC,CAQA,SAASM,EAAqBN,EAA8C,CAC1E,GAAIA,EAAO,KAAM,CACf,MAAMO,EAAWP,EAAO,MAAQA,EAAO,cACjCQ,EAAc,OAAO,IAAQ,KAAe,OAAO,IAAI,QAAW,WACpE,IAAI,OAAOR,EAAO,IAAI,EACtBA,EAAO,KAAK,QAAQ,WAAY,MAAM,EACpCS,EAAe,MAAM,KACzBF,EAAS,iBAAmC,6BAA6BC,CAAW,IAAI,CAAA,EAE1F,GAAIC,EAAa,OAAS,EACxB,OAAOA,CAEX,CAEA,MAAO,CAACT,CAAM,CAChB,CAQA,SAASU,GAAmBC,EAA2D,CACrF,KAAM,CAACC,EAAc,GAAGC,CAAY,EAAIF,EACxC,GAAI,CAACC,EACH,OAGF,IAAIE,EAAgCF,EACpC,KAAOE,GAAW,CAChB,GAAID,EAAa,MAAOhD,GAAYiD,GAAW,SAASjD,CAAO,CAAC,EAC9D,OAAOiD,EAETA,EAAYA,EAAU,aACxB,CAGF,CAQA,SAASC,EAAwBf,EAAmD,CAElF,MAAMgB,EADeV,EAAqBN,CAAM,EAE7C,IAAKnC,GAAYA,EAAQ,QAAQ,aAAa,CAAC,EAC/C,OAAQA,GAAoCA,aAAmB,WAAW,EAE7E,GAAImD,EAAS,OAAS,EAAG,CACvB,MAAMC,EAAiBP,GAAmBM,CAAQ,EAClD,GAAIC,GAAkB,CAACD,EAAS,SAASC,CAAc,EACrD,OAAOA,CAEX,CAEA,OAAOC,EAAyBlB,CAAM,CACxC,CAQA,SAASkB,EAAyBlB,EAAmD,CACnF,MAAMmB,EAAmBnB,EAAO,QAAQ,aAAa,EACrD,OAAOmB,aAA4B,YAAcA,EAAmB,MACtE,CAQA,SAASC,EAAqBpB,EAAkC,CAC9D,MAAMqB,EAAcrB,EAAO,mBAC3B,GACEqB,aAAuB,aACvBA,EAAY,aAAaxB,CAAmB,IAAM,OAElD,OAAOwB,EAGT,MAAMC,EAAY,SAAS,cAAc,KAAK,EAC9C,OAAAA,EAAU,UAAY,2BACtBA,EAAU,aAAa1B,EAAiB,MAAM,EAC9C0B,EAAU,aAAazB,EAAqB,MAAM,EAClDG,EAAO,sBAAsB,WAAYsB,CAAS,EAC3CA,CACT,CAQA,SAASC,GAAsBvB,EAAuC,CACpE,MAAMwB,EAAcvB,EAAaD,CAAM,EACnCe,EAAwBf,CAAM,EAC9BkB,EAAyBlB,CAAM,EACnC,GAAI,CAACwB,EACH,OAAOJ,EAAqBpB,CAAM,EAGpC,MAAMyB,EAAoBtB,EAAwBqB,CAAW,EAC7D,GAAIC,EACF,OAAOA,EAGT,MAAMH,EAAY,SAAS,cAAc,KAAK,EAC9C,OAAAA,EAAU,UAAY,2BACtBA,EAAU,aAAa1B,EAAiB,MAAM,EAC9C0B,EAAU,aAAazB,EAAqB,MAAM,EAClD2B,EAAY,YAAYF,CAAS,EAC1BA,CACT,CAQA,SAASI,GAAqB1B,EAAkC,CAC9D,MAAMyB,EAAoBpB,GAAoBL,CAAM,EACpD,GAAIyB,EACF,OAAOA,EAGT,MAAMH,EAAY,SAAS,cAAc,KAAK,EAC9C,OAAAA,EAAU,UAAY,qBACtBA,EAAU,aAAa,OAAQ,OAAO,EACtCA,EAAU,aAAa1B,EAAiB,MAAM,EAC9C0B,EAAU,aAAazB,EAAqB,MAAM,EAClDG,EAAO,sBAAsB,aAAcsB,CAAS,EAC7CA,CACT,CAQA,SAASK,EAAwB3B,EAA2B,CACtDA,EAAO,aAAaF,CAAwB,IAAM,SAItDE,EAAO,UAAU,OAAO,YAAY,EACpCA,EAAO,gBAAgBF,CAAwB,EACjD,CAQA,SAAS8B,GAAuB5B,EAAgC,EAC9CC,EAAaD,CAAM,EAAIM,EAAqBN,CAAM,EAAI,CAACA,CAAM,GACrE,QAASnC,GAAY,CAC3BA,EAAQ,UAAU,IAAI,YAAY,EAClCA,EAAQ,aAAaiC,EAA0B,MAAM,CACvD,CAAC,CACH,CAQA,SAAS+B,GAAwB7B,EAAgC,EAC/CC,EAAaD,CAAM,EAAIM,EAAqBN,CAAM,EAAI,CAACA,CAAM,GACrE,QAASnC,GAAY,CAC3B8D,EAAwB9D,CAAO,CACjC,CAAC,CACH,CASO,SAASiE,GAAuB9B,EAAqBvB,EAAgC,CAM1F,OALkBsB,EAAcC,CAAM,EAClCuB,GAAsBvB,CAAM,EAC5BE,EAAcF,CAAM,EAClBoB,EAAqBpB,CAAM,EAC3B0B,GAAqB1B,CAAM,GACvB,YAAYI,GAAkB,SAAU3B,CAAO,CAAC,EAEtDsB,EAAcC,CAAM,EACtB4B,GAAuB5B,CAAM,EACpBE,EAAcF,CAAM,IAC7BA,EAAO,UAAU,IAAI,YAAY,EACjCA,EAAO,aAAaF,EAA0B,MAAM,GAG/C,QAAQ,QAAA,CACjB,CAQO,SAASiC,GAAqBC,EAA4C,CAC/E,GAAIjC,EAAciC,CAAc,EAAG,CACjC,MAAMR,EAAcvB,EAAa+B,CAAc,EAC3CjB,EAAwBiB,CAAc,EACtCd,EAAyBc,CAAc,GACpBR,EAAcrB,EAAwBqB,CAAW,EAAI,SAC5D,OAAA,EAChBK,GAAwBG,CAAc,CACxC,SAAW9B,EAAc8B,CAAc,EAAG,CACxC,MAAMX,EAAcW,EAAe,mBAEjCX,aAAuB,aACvBA,EAAY,aAAaxB,CAAmB,IAAM,QAElDwB,EAAY,OAAA,EAEdM,EAAwBK,CAAc,CACxC,CAKA,OAHwBA,EAAe,iBACrC,IAAInC,CAAmB,UAAA,EAET,QAAShC,GAAY,CACnCA,EAAQ,OAAA,CACV,CAAC,EAEsBmE,EAAe,iBACpC,IAAIlC,CAAwB,UAAA,EAEf,QAASjC,GAAY,CAClC8D,EAAwB9D,CAAO,CACjC,CAAC,EAEM,QAAQ,QAAA,CACjB,CCxUA,SAASoE,EAAoBpE,EAA4B,CAClDA,EAAQ,UAAU,SAAS,OAAO,GACrCA,EAAQ,UAAU,IAAI,OAAO,EAG3BA,EAAQ,SAAW,IACrBA,EAAQ,SAAW,IAGhBA,EAAQ,aAAa,aAAa,GACrCA,EAAQ,aAAa,cAAe,MAAM,CAE9C,CASO,SAASqE,GACdrE,EACAC,EACe,CACfmE,EAAoBpE,CAAO,EAC3B,MAAMuB,EAAgBxB,EAAoBC,EAAS,OAAWC,EAAQ,SAAS,EAC/E,OAAKsB,GAILA,EAAc,KAAA,EACP,QAAQ,QAAA,GAJN,QAAQ,OAAO,IAAI,MAAM,iCAAiC,CAAC,CAKtE,CASO,SAAS+C,GACdtE,EACAC,EACe,CACfmE,EAAoBpE,CAAO,EAC3B,MAAMuB,EAAgBxB,EAAoBC,EAAS,OAAWC,EAAQ,SAAS,EAC/E,OAAKsB,GAILA,EAAc,KAAA,EACP,QAAQ,QAAA,GAJN,QAAQ,OAAO,IAAI,MAAM,iCAAiC,CAAC,CAKtE,CC5DA,MAAMgD,EAA4B,uCAC5BC,GAAkB,6BAClBC,GAAyB,oCAY/B,SAASC,GAAuBC,EAAiC,CAC/D,OAAQA,EAAA,CACN,IAAK,UACH,MAAO,CAAE,gBAAiB,YAAA,EAC5B,IAAK,QACH,MAAO,CAAE,gBAAiB,WAAA,EAC5B,QACE,MAAO,CAAE,gBAAiB,SAAA,CAAU,CAE1C,CASA,SAASC,GAAiBnE,EAA0BR,EAA8C,CAChG,GAAIA,EAAQ,uBAAwB,CAClC,MAAMS,EAAkBD,EAAe,cAA2BR,EAAQ,sBAAsB,EAChG,GAAIS,EACF,OAAOA,CAEX,CAEA,OAAOD,EAAe,IACxB,CASA,SAASoE,GAAqBpE,EAA0BR,EAA8C,CACpG,MAAM6E,EAAcF,GAAiBnE,EAAgBR,CAAO,EACtD2D,EAAoBkB,EAAY,cACpC,IAAIP,CAAyB,UAAA,EAE/B,GAAIX,EACF,OAAOA,EAGT,MAAMH,EAAYhD,EAAe,cAAc,KAAK,EACpD,OAAAgD,EAAU,UAAY,oDACtBA,EAAU,aAAac,EAA2B,MAAM,EACxDO,EAAY,YAAYrB,CAAS,EAC1BA,CACT,CAUO,SAASsB,GACdnE,EACA+D,EACA1E,EACe,CACf,MAAMQ,EAAiB,WAAW,SAC5BuE,EAAaN,GAAuBC,CAAK,EACzCM,EAAexE,EAAe,cAAc,KAAK,EACvDwE,EAAa,UAAY,2CACzBA,EAAa,aAAa,OAAQ,QAAQ,EAC1CA,EAAa,aAAa,YAAa,QAAQ,EAC/CA,EAAa,aAAa,cAAe,MAAM,EAC/CA,EAAa,aAAaT,GAAiB,MAAM,EAEjD,MAAMU,EAAczE,EAAe,cAAc,KAAK,EACtDyE,EAAY,UAAY,6BAExB,MAAMC,EAAgB1E,EAAe,cAAc,KAAK,EACxD0E,EAAc,UAAY,+BAA+BH,EAAW,eAAe,GACnFG,EAAc,MAAM,MAAQ,WAC5BA,EAAc,aAAaV,GAAwB,MAAM,EAEzD,MAAMxD,EAAcR,EAAe,cAAc,KAAK,EACtDQ,EAAY,UAAY,aACxBA,EAAY,MAAM,WAAa,WAC/BA,EAAY,YAAcL,EAE1BsE,EAAY,YAAYC,CAAa,EACrCD,EAAY,YAAYjE,CAAW,EACnCgE,EAAa,YAAYC,CAAW,EACpCL,GAAqBpE,EAAgBR,CAAO,EAAE,YAAYgF,CAAY,EAEtE,MAAMG,EAAgBjF,EAAoB8E,EAAchF,EAAQ,SAAS,EACzE,GAAI,CAACmF,EACH,OAAAH,EAAa,OAAA,EACN,QAAQ,OAAO,IAAI,MAAM,iCAAiC,CAAC,EAGpEA,EAAa,iBACX,kBACA,IAAM,CACJA,EAAa,OAAA,EACbG,EAAc,UAAA,CAChB,EACA,CAAE,KAAM,EAAA,CAAK,EAGf,GAAI,CACF,OAAAA,EAAc,KAAA,EACP,QAAQ,QAAA,CACjB,OAASxD,EAAO,CACd,OAAAqD,EAAa,OAAA,EACbG,EAAc,UAAA,EACP,QAAQ,OAAOxD,CAAK,CAC7B,CACF,CC7GA,IAAIyD,EAN0C,CAC5C,QAAS,CACP,iBAAkB,EAAA,CAEtB,EAUA,SAASC,EAAqB1E,EAAyB,CACrD,OAAOA,EAAQ,QAAQ,OAAQ;AAAA,CAAI,CACrC,CAOA,SAAS2E,GAAuC,CAE9C,OADc,WACD,MACf,CAQA,SAASC,EAAc/F,EAAsD,CAC3E,OAAO,QAAQ,QAAQA,CAAK,EAAE,KAAK,IAAA,EAAe,CACpD,CAQA,SAASgG,EACPC,EACwD,CACxD,MAAMC,EAASN,EAAQ,gBAAgBK,CAAU,EACjD,OAAO,OAAOC,GAAW,WACpBA,EACD,MACN,CAQA,SAASC,EAASC,EAAuB,CACvC,QAAQ,KAAK,qBAAqBA,CAAO,oDAAoD,CAC/F,CAQA,SAASC,EAAelF,EAAgC,CACtD,MAAMmF,EAAoBT,EAAqB1E,CAAO,EAChDoF,EAAiBP,EAAkB,QAAQ,EACjD,GAAIO,EACF,OAAOR,EAAcQ,EAAeD,CAAiB,CAAC,EAGxD,MAAME,EAAgBV,EAAA,EACtB,OAAIF,EAAQ,QAAQ,kBAAoB,OAAOY,GAAe,OAAU,YACtEA,EAAc,MAAMF,CAAiB,EAC9B,QAAQ,QAAA,IAGjBH,EAAS,QAAQ,EACV,QAAQ,QAAA,EACjB,CAQA,SAASM,EAAgBtF,EAAmC,CAC1D,MAAMmF,EAAoBT,EAAqB1E,CAAO,EAChDoF,EAAiBP,EAAkB,SAAS,EAClD,GAAIO,EACF,OAAO,QAAQ,QAAQA,EAAeD,CAAiB,CAA+B,EAAE,KACrFtG,GAAU,EAAQA,CAAK,EAI5B,MAAMwG,EAAgBV,EAAA,EACtB,OAAIF,EAAQ,QAAQ,kBAAoB,OAAOY,GAAe,SAAY,WACjE,QAAQ,QAAQA,EAAc,QAAQF,CAAiB,CAAC,GAGjEH,EAAS,SAAS,EACX,QAAQ,QAAQ,EAAK,EAC9B,CASA,SAASO,EAAcvF,EAAiB+D,EAA+B,CACrE,MAAMoB,EAAoBT,EAAqB1E,CAAO,EAChDoF,EAAiBP,EAAkB,OAAO,EAChD,OAAIO,EACKR,EAAcQ,EAAeD,EAAmBpB,CAAK,CAAC,GAG/DiB,EAAS,OAAO,EACT,QAAQ,QAAA,EACjB,CASA,SAASQ,EAAcV,EAA0C1F,EAAqC,CACpG,MAAMgG,EAAiBP,EAAkBC,CAAU,EACnD,OAAIM,EACKR,EAAcQ,EAAehG,CAAO,CAAC,GAG9C4F,EAASF,CAAU,EACZ,QAAQ,QAAA,EACjB,CAQO,SAASW,GAAyBC,EAA0C,CACjFjB,EAAUiB,CACZ,CAKO,MAAMC,CAAe,CAO1B,OAAc,OAAO3F,EAAgC,CACnD,MAAMmF,EAAoBT,EAAqB1E,CAAO,EACtD,OAAIf,EAAgBwF,EAAQ,QAAQ,SAAS,EACpC/D,GAAWyE,EAAmBV,EAAQ,OAAO,EAAE,MAAM,IAAMS,EAAeC,CAAiB,CAAC,EAG9FD,EAAeC,CAAiB,CACzC,CAQA,OAAc,QAAQnF,EAAmC,CACvD,MAAMmF,EAAoBT,EAAqB1E,CAAO,EACtD,OAAIf,EAAgBwF,EAAQ,QAAQ,SAAS,EACpCxD,GAAYkE,EAAmBV,EAAQ,OAAO,EAAE,MAAM,IAAMa,EAAgBH,CAAiB,CAAC,EAGhGG,EAAgBH,CAAiB,CAC1C,CASA,OAAc,MAAMnF,EAAiB+D,EAA+B,CAClE,MAAMoB,EAAoBT,EAAqB1E,CAAO,EACtD,OAAId,EAAgBuF,EAAQ,QAAQ,SAAS,EACpCN,GAAUgB,EAAmBpB,EAAOU,EAAQ,OAAO,EAAE,MAAM,IAChEc,EAAcJ,EAAmBpB,CAAK,CAAA,EAInCwB,EAAcJ,EAAmBpB,CAAK,CAC/C,CAQA,OAAc,WAAW3E,EAAqC,CAC5D,OAAIH,EAAgBwF,EAAQ,QAAQ,SAAS,EACpChB,GAAkBrE,EAASqF,EAAQ,OAAO,EAAE,MAAM,IACvDe,EAAc,aAAcpG,CAAO,CAAA,EAIhCoG,EAAc,aAAcpG,CAAO,CAC5C,CAQA,OAAc,YAAYA,EAAqC,CAC7D,OAAIH,EAAgBwF,EAAQ,QAAQ,SAAS,EACpCf,GAAmBtE,EAASqF,EAAQ,OAAO,EAAE,MAAM,IACxDe,EAAc,cAAepG,CAAO,CAAA,EAIjCoG,EAAc,cAAepG,CAAO,CAC7C,CASA,OAAc,gBAAgBmC,EAAqBvB,EAAgC,CACjF,OAAOqD,GAAuB9B,EAAQvB,CAAO,CAC/C,CAQA,OAAc,cAAcuD,EAA4C,CACtE,OAAOD,GAAqBC,CAAc,CAC5C,CACF,CC5QA,MAAMqC,EAAkD,CACtD,iBAAkB,EACpB,EAEMC,EAIF,CACF,UAAW,GACX,QAASD,CACX,EAOA,SAASjB,GAA8C,CAErD,OADc,WACD,MACf,CASA,SAASmB,GACPzG,EACAgG,EACwB,CACxB,MAAO,CACL,UAAWhG,EAAQ,WAAagG,GAAe,UAC/C,iBAAkBhG,EAAQ,kBAAoBuG,EAAwB,iBACtE,QACEvG,EAAQ,SAAWwG,EAAa,QAAQ,SAAWR,GAAe,OAAO,QAC3E,uBAAwBhG,EAAQ,uBAChC,wBAAyBA,EAAQ,uBAAA,CAErC,CAQO,SAAS0G,EACdV,EAA2CV,IAClC,CACT,MAAO,GAAQU,GAAe,OAASA,EAAc,UACvD,CAQO,SAASW,EAAQ3G,EAA0B,GAAU,CAC1D,MAAMgG,EAAgBV,EAAA,EACtB,GAAI,CAACU,GAAe,MAClB,MAAM,IAAI,MAAM,oDAAoD,EAGjEQ,EAAa,gBAChBA,EAAa,cAAgBR,EAAc,OAG7CQ,EAAa,QAAUC,GAAsBzG,EAASgG,CAAa,EAEjEQ,EAAa,QAAQ,SACrB,OAAOR,EAAc,MAAM,YAAe,YAE1CA,EAAc,MAAM,WAAWQ,EAAa,QAAQ,OAAO,EAE7DJ,GAAyB,CACvB,cAAeI,EAAa,cAC5B,QAASA,EAAa,OAAA,CACvB,EACDR,EAAc,MAAQM,EACtBE,EAAa,UAAY,EAC3B,CAOO,SAASI,IAAkB,CAChC,MAAMZ,EAAgBV,EAAA,EAClB,CAACU,GAAiB,CAACQ,EAAa,gBAIpCR,EAAc,MAAQQ,EAAa,cACnCA,EAAa,UAAY,GACzBA,EAAa,cAAgB,OAC/B,CAOO,SAASK,IAAuB,CACrC,OAAOL,EAAa,SACtB,CCnHA,MAAMM,EAAqB,kCAO3B,SAASxB,IAA8C,CAErD,OADc,WACD,MACf,CAQA,SAASyB,GAAef,EAAuC,CAC7D,MAAO,EAASA,EAAqDc,CAAkB,CACzF,CAQA,SAASE,GAAgBhB,EAAoC,CAC1DA,EAAqDc,CAAkB,EAAI,EAC9E,CAOA,SAASG,IAAmB,CAC1B,MAAMjB,EAAgBV,GAAA,EACtB,GAAI,GAACU,GAAiBe,GAAef,CAAa,GAIlD,IAAI,CAACU,EAA2BV,CAAa,EAAG,CAC9C,QAAQ,KACN,4FAAA,EAEF,MACF,CAEA,GAAI,CACFW,EAAQ,CAAE,UAAWX,EAAc,SAAA,CAAW,EAC9CgB,GAAgBhB,CAAa,CAC/B,OAASrE,EAAO,CACd,QAAQ,KAAK,wCAAyCA,CAAK,CAC7D,EACF,CAEAsF,GAAA,EC7CO,MAAMC,GAAU"}
@@ -1,20 +1,20 @@
1
- function D(e) {
1
+ function _(e) {
2
2
  return typeof e == "function";
3
3
  }
4
- function R(e) {
5
- return D(e?.Modal) ? e?.Modal : void 0;
4
+ function D(e) {
5
+ return _(e?.Modal) ? e?.Modal : void 0;
6
6
  }
7
7
  function $(e) {
8
- return D(e?.Toast) ? e?.Toast : void 0;
8
+ return _(e?.Toast) ? e?.Toast : void 0;
9
9
  }
10
10
  function v(e) {
11
- return !!R(e);
11
+ return !!D(e);
12
12
  }
13
13
  function Q(e) {
14
14
  return !!$(e);
15
15
  }
16
16
  function C(e, t, o) {
17
- const n = R(o);
17
+ const n = D(o);
18
18
  if (n)
19
19
  return typeof n.getOrCreateInstance == "function" ? n.getOrCreateInstance(e, t) : new n(e, t);
20
20
  }
@@ -46,17 +46,17 @@ function z(e, t, o) {
46
46
  r.className = "modal-dialog modal-dialog-centered";
47
47
  const i = e.createElement("div");
48
48
  i.className = "modal-content";
49
- const u = e.createElement("div");
50
- u.className = "modal-body";
49
+ const d = e.createElement("div");
50
+ d.className = "modal-body";
51
51
  const a = e.createElement("p");
52
- a.className = "mb-0", a.style.whiteSpace = "pre-line", a.textContent = t, u.appendChild(a);
52
+ a.className = "mb-0", a.style.whiteSpace = "pre-line", a.textContent = t, d.appendChild(a);
53
53
  const s = e.createElement("div");
54
54
  if (s.className = "modal-footer", o) {
55
- const d = e.createElement("button");
56
- d.type = "button", d.className = "btn btn-secondary", d.setAttribute(b, "cancel"), d.textContent = "Cancel", s.appendChild(d);
55
+ const f = e.createElement("button");
56
+ f.type = "button", f.className = "btn btn-secondary", f.setAttribute(b, "cancel"), f.textContent = "Cancel", s.appendChild(f);
57
57
  }
58
58
  const c = e.createElement("button");
59
- return c.type = "button", c.className = "btn btn-primary", c.setAttribute(b, "ok"), c.textContent = "OK", s.appendChild(c), i.append(u, s), r.appendChild(i), n.appendChild(r), n;
59
+ return c.type = "button", c.className = "btn btn-primary", c.setAttribute(b, "ok"), c.textContent = "OK", s.appendChild(c), i.append(d, s), r.appendChild(i), n.appendChild(r), n;
60
60
  }
61
61
  function Z(e, t) {
62
62
  const o = globalThis.document, n = z(o, e, !1);
@@ -66,7 +66,7 @@ function Z(e, t) {
66
66
  q(),
67
67
  t.bootstrap
68
68
  );
69
- return r ? new Promise((i, u) => {
69
+ return r ? new Promise((i, d) => {
70
70
  const a = () => {
71
71
  n.removeEventListener("hidden.bs.modal", s), n.remove(), r.dispose?.(), i();
72
72
  }, s = () => {
@@ -81,8 +81,8 @@ function Z(e, t) {
81
81
  ), n.addEventListener("hidden.bs.modal", s, { once: !0 });
82
82
  try {
83
83
  r.show();
84
- } catch (d) {
85
- n.removeEventListener("hidden.bs.modal", s), n.remove(), r.dispose?.(), u(d);
84
+ } catch (f) {
85
+ n.removeEventListener("hidden.bs.modal", s), n.remove(), r.dispose?.(), d(f);
86
86
  }
87
87
  }) : (n.remove(), Promise.reject(new Error("Bootstrap Modal is unavailable.")));
88
88
  }
@@ -94,16 +94,16 @@ function ee(e, t) {
94
94
  q(),
95
95
  t.bootstrap
96
96
  );
97
- return r ? new Promise((i, u) => {
97
+ return r ? new Promise((i, d) => {
98
98
  let a = !1;
99
99
  const s = () => {
100
100
  n.removeEventListener("hidden.bs.modal", c), n.remove(), r.dispose?.(), i(a);
101
101
  }, c = () => {
102
102
  s();
103
- }, d = n.querySelector(`[${b}="ok"]`), j = n.querySelector(
103
+ }, f = n.querySelector(`[${b}="ok"]`), j = n.querySelector(
104
104
  `[${b}="cancel"]`
105
105
  );
106
- d?.addEventListener(
106
+ f?.addEventListener(
107
107
  "click",
108
108
  () => {
109
109
  a = !0, r.hide();
@@ -119,18 +119,18 @@ function ee(e, t) {
119
119
  try {
120
120
  r.show();
121
121
  } catch (J) {
122
- n.removeEventListener("hidden.bs.modal", c), n.remove(), r.dispose?.(), u(J);
122
+ n.removeEventListener("hidden.bs.modal", c), n.remove(), r.dispose?.(), d(J);
123
123
  }
124
124
  }) : (n.remove(), Promise.reject(new Error("Bootstrap Modal is unavailable.")));
125
125
  }
126
126
  const T = "data-haori-bootstrap-owned", m = "data-haori-bootstrap-message-container", h = "data-haori-bootstrap-invalid-target";
127
- function M(e) {
127
+ function y(e) {
128
128
  return e instanceof HTMLInputElement && (e.type === "checkbox" || e.type === "radio");
129
129
  }
130
130
  function g(e) {
131
131
  return e instanceof HTMLInputElement && e.type === "radio";
132
132
  }
133
- function y(e) {
133
+ function M(e) {
134
134
  return e instanceof HTMLInputElement || e instanceof HTMLSelectElement || e instanceof HTMLTextAreaElement;
135
135
  }
136
136
  function N(e) {
@@ -217,13 +217,13 @@ function se(e) {
217
217
  });
218
218
  }
219
219
  function ce(e, t) {
220
- return (M(e) ? re(e) : y(e) ? O(e) : ie(e)).appendChild(te(document, t)), M(e) ? ae(e) : y(e) && (e.classList.add("is-invalid"), e.setAttribute(h, "true")), Promise.resolve();
220
+ return (y(e) ? re(e) : M(e) ? O(e) : ie(e)).appendChild(te(document, t)), y(e) ? ae(e) : M(e) && (e.classList.add("is-invalid"), e.setAttribute(h, "true")), Promise.resolve();
221
221
  }
222
222
  function le(e) {
223
- if (M(e)) {
223
+ if (y(e)) {
224
224
  const n = g(e) ? W(e) : k(e);
225
225
  (n ? N(n) : void 0)?.remove(), se(e);
226
- } else if (y(e)) {
226
+ } else if (M(e)) {
227
227
  const n = e.nextElementSibling;
228
228
  n instanceof HTMLElement && n.getAttribute(m) === "true" && n.remove(), I(e);
229
229
  }
@@ -281,12 +281,12 @@ function he(e, t) {
281
281
  function ve(e, t, o) {
282
282
  const n = globalThis.document, r = pe(t), i = n.createElement("div");
283
283
  i.className = "toast border bg-body text-body shadow-sm", i.setAttribute("role", "status"), i.setAttribute("aria-live", "polite"), i.setAttribute("aria-atomic", "true"), i.setAttribute(fe, "true");
284
- const u = n.createElement("div");
285
- u.className = "d-flex align-items-stretch";
284
+ const d = n.createElement("div");
285
+ d.className = "d-flex align-items-stretch";
286
286
  const a = n.createElement("div");
287
287
  a.className = `flex-shrink-0 rounded-start ${r.accentClassName}`, a.style.width = "0.375rem", a.setAttribute(me, "true");
288
288
  const s = n.createElement("div");
289
- s.className = "toast-body", s.style.whiteSpace = "pre-line", s.textContent = e, u.appendChild(a), u.appendChild(s), i.appendChild(u), he(n, o).appendChild(i);
289
+ s.className = "toast-body", s.style.whiteSpace = "pre-line", s.textContent = e, d.appendChild(a), d.appendChild(s), i.appendChild(d), he(n, o).appendChild(i);
290
290
  const c = X(i, o.bootstrap);
291
291
  if (!c)
292
292
  return i.remove(), Promise.reject(new Error("Bootstrap Toast is unavailable."));
@@ -299,8 +299,8 @@ function ve(e, t, o) {
299
299
  );
300
300
  try {
301
301
  return c.show(), Promise.resolve();
302
- } catch (d) {
303
- return i.remove(), c.dispose?.(), Promise.reject(d);
302
+ } catch (f) {
303
+ return i.remove(), c.dispose?.(), Promise.reject(f);
304
304
  }
305
305
  }
306
306
  const Ee = {
@@ -316,7 +316,7 @@ function p(e) {
316
316
  function G() {
317
317
  return globalThis.window;
318
318
  }
319
- function B(e) {
319
+ function H(e) {
320
320
  return Promise.resolve(e).then(() => {
321
321
  });
322
322
  }
@@ -330,7 +330,7 @@ function w(e) {
330
330
  function x(e) {
331
331
  const t = p(e), o = A("dialog");
332
332
  if (o)
333
- return B(o(t));
333
+ return H(o(t));
334
334
  const n = G();
335
335
  return l.options.fallbackToNative && typeof n?.alert == "function" ? (n.alert(t), Promise.resolve()) : (w("dialog"), Promise.resolve());
336
336
  }
@@ -343,13 +343,13 @@ function P(e) {
343
343
  const n = G();
344
344
  return l.options.fallbackToNative && typeof n?.confirm == "function" ? Promise.resolve(n.confirm(t)) : (w("confirm"), Promise.resolve(!1));
345
345
  }
346
- function _(e, t) {
346
+ function R(e, t) {
347
347
  const o = p(e), n = A("toast");
348
- return n ? B(n(o, t)) : (w("toast"), Promise.resolve());
348
+ return n ? H(n(o, t)) : (w("toast"), Promise.resolve());
349
349
  }
350
350
  function E(e, t) {
351
351
  const o = A(e);
352
- return o ? B(o(t)) : (w(e), Promise.resolve());
352
+ return o ? H(o(t)) : (w(e), Promise.resolve());
353
353
  }
354
354
  function Ce(e) {
355
355
  l = e;
@@ -385,8 +385,8 @@ class Te {
385
385
  static toast(t, o) {
386
386
  const n = p(t);
387
387
  return Q(l.options.bootstrap) ? ve(n, o, l.options).catch(
388
- () => _(n, o)
389
- ) : _(n, o);
388
+ () => R(n, o)
389
+ ) : R(n, o);
390
390
  }
391
391
  /**
392
392
  * 任意のダイアログ要素を開く。
@@ -432,53 +432,54 @@ class Te {
432
432
  }
433
433
  const K = {
434
434
  fallbackToNative: !0
435
- }, f = {
435
+ }, u = {
436
436
  installed: !1,
437
437
  options: K
438
438
  };
439
- function H() {
439
+ function B() {
440
440
  return globalThis.window;
441
441
  }
442
442
  function ge(e, t) {
443
443
  return {
444
444
  bootstrap: e.bootstrap ?? t?.bootstrap,
445
445
  fallbackToNative: e.fallbackToNative ?? K.fallbackToNative,
446
+ runtime: e.runtime ?? u.options.runtime ?? t?.Haori?.runtime,
446
447
  toastContainerSelector: e.toastContainerSelector,
447
448
  dialogContainerSelector: e.dialogContainerSelector
448
449
  };
449
450
  }
450
- function Ae(e = H()) {
451
+ function Ae(e = B()) {
451
452
  return !!(e?.Haori && e.bootstrap);
452
453
  }
453
454
  function we(e = {}) {
454
- const t = H();
455
+ const t = B();
455
456
  if (!t?.Haori)
456
457
  throw new Error("window.Haori is required before calling install().");
457
- f.originalHaori || (f.originalHaori = t.Haori), f.options = ge(e, t), Ce({
458
- originalHaori: f.originalHaori,
459
- options: f.options
460
- }), t.Haori = Te, f.installed = !0;
458
+ u.originalHaori || (u.originalHaori = t.Haori), u.options = ge(e, t), u.options.runtime && typeof t.Haori.setRuntime == "function" && t.Haori.setRuntime(u.options.runtime), Ce({
459
+ originalHaori: u.originalHaori,
460
+ options: u.options
461
+ }), t.Haori = Te, u.installed = !0;
461
462
  }
462
463
  function Se() {
463
- const e = H();
464
- !e || !f.originalHaori || (e.Haori = f.originalHaori, f.installed = !1, f.originalHaori = void 0);
464
+ const e = B();
465
+ !e || !u.originalHaori || (e.Haori = u.originalHaori, u.installed = !1, u.originalHaori = void 0);
465
466
  }
466
467
  function ke() {
467
- return f.installed;
468
+ return u.installed;
468
469
  }
469
470
  const V = "__haoriJsBootstrapAutoEnabled__";
470
- function Me() {
471
+ function ye() {
471
472
  return globalThis.window;
472
473
  }
473
- function ye(e) {
474
+ function Me(e) {
474
475
  return !!e[V];
475
476
  }
476
477
  function Ie(e) {
477
478
  e[V] = !0;
478
479
  }
479
480
  function Ne() {
480
- const e = Me();
481
- if (!(!e || ye(e))) {
481
+ const e = ye();
482
+ if (!(!e || Me(e))) {
482
483
  if (!Ae(e)) {
483
484
  console.warn(
484
485
  "[haori-bootstrap] Auto-enable skipped because window.Haori or window.bootstrap is missing."
@@ -493,13 +494,13 @@ function Ne() {
493
494
  }
494
495
  }
495
496
  Ne();
496
- const Be = "0.2.0";
497
+ const He = "0.3.0";
497
498
  export {
498
499
  Te as BootstrapHaori,
499
500
  Ae as hasAutoEnablePrerequisites,
500
501
  we as install,
501
502
  ke as isInstalled,
502
503
  Se as uninstall,
503
- Be as version
504
+ He as version
504
505
  };
505
506
  //# sourceMappingURL=haori-bootstrap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"haori-bootstrap.js","sources":["../src/bootstrap_resolver.ts","../src/dialog.ts","../src/message.ts","../src/modal.ts","../src/toast.ts","../src/bootstrap_haori.ts","../src/install.ts","../src/browser.ts","../src/index.ts"],"sourcesContent":["import type {\n BootstrapModalConstructor,\n BootstrapModalInstance,\n BootstrapModalOptions,\n BootstrapNamespace,\n BootstrapToastConstructor,\n BootstrapToastInstance,\n} from './types';\n\n/**\n * 値がコンストラクター関数かどうかを判定する。\n *\n * @param value 判定対象の値。\n * @return コンストラクター関数なら true。\n */\nfunction isConstructor<T>(value: unknown): value is new (...args: readonly unknown[]) => T {\n return typeof value === 'function';\n}\n\n/**\n * Bootstrap の Modal コンストラクターを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return Modal コンストラクター。見つからない場合は undefined。\n */\nexport function resolveModalConstructor(\n bootstrap?: BootstrapNamespace,\n): BootstrapModalConstructor | undefined {\n return isConstructor<BootstrapModalInstance>(bootstrap?.Modal)\n ? (bootstrap?.Modal as BootstrapModalConstructor)\n : undefined;\n}\n\n/**\n * Bootstrap の Toast コンストラクターを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return Toast コンストラクター。見つからない場合は undefined。\n */\nexport function resolveToastConstructor(\n bootstrap?: BootstrapNamespace,\n): BootstrapToastConstructor | undefined {\n return isConstructor<BootstrapToastInstance>(bootstrap?.Toast)\n ? (bootstrap?.Toast as BootstrapToastConstructor)\n : undefined;\n}\n\n/**\n * Modal が利用可能かどうかを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return 利用可能なら true。\n */\nexport function hasModalSupport(bootstrap?: BootstrapNamespace): boolean {\n return Boolean(resolveModalConstructor(bootstrap));\n}\n\n/**\n * Toast が利用可能かどうかを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return 利用可能なら true。\n */\nexport function hasToastSupport(bootstrap?: BootstrapNamespace): boolean {\n return Boolean(resolveToastConstructor(bootstrap));\n}\n\n/**\n * Modal インスタンスを取得または生成する。\n *\n * @param element 対象要素。\n * @param bootstrap Bootstrap 名前空間。\n * @return Modal インスタンス。生成できない場合は undefined。\n */\nexport function createModalInstance(\n element: HTMLElement,\n options?: BootstrapModalOptions,\n bootstrap?: BootstrapNamespace,\n): BootstrapModalInstance | undefined {\n const modalConstructor = resolveModalConstructor(bootstrap);\n if (!modalConstructor) {\n return undefined;\n }\n\n if (typeof modalConstructor.getOrCreateInstance === 'function') {\n return modalConstructor.getOrCreateInstance(element, options);\n }\n\n return new modalConstructor(element, options);\n}\n\n/**\n * Toast インスタンスを取得または生成する。\n *\n * @param element 対象要素。\n * @param bootstrap Bootstrap 名前空間。\n * @return Toast インスタンス。生成できない場合は undefined。\n */\nexport function createToastInstance(\n element: HTMLElement,\n bootstrap?: BootstrapNamespace,\n): BootstrapToastInstance | undefined {\n const toastConstructor = resolveToastConstructor(bootstrap);\n if (!toastConstructor) {\n return undefined;\n }\n\n if (typeof toastConstructor.getOrCreateInstance === 'function') {\n return toastConstructor.getOrCreateInstance(element);\n }\n\n return new toastConstructor(element);\n}\n","import { createModalInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\nconst DIALOG_CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-dialog';\nconst ACTION_ATTRIBUTE = 'data-haori-bootstrap-action';\n\n/**\n * dialog 系 modal の既定オプションを返す。\n *\n * @return Bootstrap Modal の生成オプション。\n */\nfunction createDialogModalOptions() {\n return {\n backdrop: 'static' as const,\n };\n}\n\n/**\n * dialog を挿入する親要素を解決する。\n *\n * @param documentObject 検索に使用する document。\n * @param options 解決済み導入設定。\n * @return 挿入先の要素。\n */\nfunction resolveDialogContainer(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n if (options.dialogContainerSelector) {\n const resolvedElement = documentObject.querySelector<HTMLElement>(\n options.dialogContainerSelector,\n );\n if (resolvedElement) {\n return resolvedElement;\n }\n }\n\n return documentObject.body;\n}\n\n/**\n * dialog または confirm 用の modal 要素を組み立てる。\n *\n * @param documentObject 生成に使用する document。\n * @param message 表示するメッセージ。\n * @param isConfirm confirm 用かどうか。\n * @return 生成した modal 要素。\n */\nfunction createModalShell(documentObject: Document, message: string, isConfirm: boolean): HTMLDivElement {\n const modalElement = documentObject.createElement('div');\n modalElement.className = 'modal fade';\n modalElement.tabIndex = -1;\n modalElement.setAttribute(DIALOG_CONTAINER_ATTRIBUTE, 'true');\n modalElement.setAttribute('aria-hidden', 'true');\n\n const dialogElement = documentObject.createElement('div');\n dialogElement.className = 'modal-dialog modal-dialog-centered';\n\n const contentElement = documentObject.createElement('div');\n contentElement.className = 'modal-content';\n\n const bodyElement = documentObject.createElement('div');\n bodyElement.className = 'modal-body';\n\n const messageElement = documentObject.createElement('p');\n messageElement.className = 'mb-0';\n messageElement.style.whiteSpace = 'pre-line';\n messageElement.textContent = message;\n bodyElement.appendChild(messageElement);\n\n const footerElement = documentObject.createElement('div');\n footerElement.className = 'modal-footer';\n\n if (isConfirm) {\n const cancelButton = documentObject.createElement('button');\n cancelButton.type = 'button';\n cancelButton.className = 'btn btn-secondary';\n cancelButton.setAttribute(ACTION_ATTRIBUTE, 'cancel');\n cancelButton.textContent = 'Cancel';\n footerElement.appendChild(cancelButton);\n }\n\n const okButton = documentObject.createElement('button');\n okButton.type = 'button';\n okButton.className = 'btn btn-primary';\n okButton.setAttribute(ACTION_ATTRIBUTE, 'ok');\n okButton.textContent = 'OK';\n footerElement.appendChild(okButton);\n\n contentElement.append(bodyElement, footerElement);\n dialogElement.appendChild(contentElement);\n modalElement.appendChild(dialogElement);\n return modalElement;\n}\n\n/**\n * 情報表示用の Bootstrap Modal を表示する。\n *\n * @param message 表示するメッセージ。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function showDialog(message: string, options: ResolvedInstallOptions): Promise<void> {\n const documentObject = globalThis.document;\n const modalElement = createModalShell(documentObject, message, false);\n resolveDialogContainer(documentObject, options).appendChild(modalElement);\n\n const modalInstance = createModalInstance(\n modalElement,\n createDialogModalOptions(),\n options.bootstrap,\n );\n if (!modalInstance) {\n modalElement.remove();\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n return new Promise<void>((resolve, reject) => {\n const finalize = (): void => {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n resolve();\n };\n\n const handleHidden = (): void => {\n finalize();\n };\n\n const okButton = modalElement.querySelector<HTMLButtonElement>(`[${ACTION_ATTRIBUTE}=\"ok\"]`);\n okButton?.addEventListener(\n 'click',\n () => {\n modalInstance.hide();\n },\n { once: true },\n );\n\n modalElement.addEventListener('hidden.bs.modal', handleHidden, { once: true });\n\n try {\n modalInstance.show();\n } catch (error) {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n reject(error);\n }\n });\n}\n\n/**\n * 確認用の Bootstrap Modal を表示する。\n *\n * @param message 表示するメッセージ。\n * @param options 解決済み導入設定。\n * @return OK のみ true を返す Promise。\n */\nexport function showConfirm(\n message: string,\n options: ResolvedInstallOptions,\n): Promise<boolean> {\n const documentObject = globalThis.document;\n const modalElement = createModalShell(documentObject, message, true);\n resolveDialogContainer(documentObject, options).appendChild(modalElement);\n\n const modalInstance = createModalInstance(\n modalElement,\n createDialogModalOptions(),\n options.bootstrap,\n );\n if (!modalInstance) {\n modalElement.remove();\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n return new Promise<boolean>((resolve, reject) => {\n let confirmed = false;\n\n const finalize = (): void => {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n resolve(confirmed);\n };\n\n const handleHidden = (): void => {\n finalize();\n };\n\n const okButton = modalElement.querySelector<HTMLButtonElement>(`[${ACTION_ATTRIBUTE}=\"ok\"]`);\n const cancelButton = modalElement.querySelector<HTMLButtonElement>(\n `[${ACTION_ATTRIBUTE}=\"cancel\"]`,\n );\n\n okButton?.addEventListener(\n 'click',\n () => {\n confirmed = true;\n modalInstance.hide();\n },\n { once: true },\n );\n cancelButton?.addEventListener(\n 'click',\n () => {\n confirmed = false;\n modalInstance.hide();\n },\n { once: true },\n );\n\n modalElement.addEventListener('hidden.bs.modal', handleHidden, { once: true });\n\n try {\n modalInstance.show();\n } catch (error) {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n reject(error);\n }\n });\n}\n","const OWNED_ATTRIBUTE = 'data-haori-bootstrap-owned';\nconst CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-message-container';\nconst INVALID_TARGET_ATTRIBUTE = 'data-haori-bootstrap-invalid-target';\n\n/**\n * 対象要素が checkbox または radio かどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return checkbox または radio の input 要素なら true。\n */\nfunction isChoiceInput(target: HTMLElement): target is HTMLInputElement {\n return (\n target instanceof HTMLInputElement &&\n (target.type === 'checkbox' || target.type === 'radio')\n );\n}\n\n/**\n * 対象要素が radio input かどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return radio の input 要素なら true。\n */\nfunction isRadioInput(target: HTMLElement): target is HTMLInputElement {\n return target instanceof HTMLInputElement && target.type === 'radio';\n}\n\n/**\n * 対象要素が通常の invalid-feedback を直後に付与するフィールドかどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return 入力系フィールドなら true。\n */\nfunction isFieldTarget(\n target: HTMLElement,\n): target is HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement {\n return (\n target instanceof HTMLInputElement ||\n target instanceof HTMLSelectElement ||\n target instanceof HTMLTextAreaElement\n );\n}\n\n/**\n * 子要素から管理対象のメッセージコンテナを取得する。\n *\n * @param target 検索対象の要素。\n * @return 管理対象コンテナ。見つからない場合は undefined。\n */\nfunction getDirectOwnedContainer(target: HTMLElement): HTMLElement | undefined {\n return Array.from(target.children).find(\n (element): element is HTMLElement =>\n element instanceof HTMLElement && element.getAttribute(CONTAINER_ATTRIBUTE) === 'true',\n );\n}\n\n/**\n * 管理対象のメッセージ要素を生成する。\n *\n * @param documentObject 生成に使用する document。\n * @param message 表示するメッセージ。\n * @return 生成したメッセージ要素。\n */\nfunction createMessageItem(documentObject: Document, message: string): HTMLDivElement {\n const messageElement = documentObject.createElement('div');\n messageElement.setAttribute(OWNED_ATTRIBUTE, 'true');\n messageElement.textContent = message;\n return messageElement;\n}\n\n/**\n * block container 配下の既存メッセージコンテナを取得する。\n *\n * @param target 検索対象の要素。\n * @return 既存コンテナ。見つからない場合は undefined。\n */\nfunction getOwnedDirectChild(target: HTMLElement): HTMLElement | undefined {\n return getDirectOwnedContainer(target);\n}\n\n/**\n * 指定した radio と同じグループに属する radio 要素一覧を取得する。\n *\n * @param target 基準となる radio 要素。\n * @return 同じグループに属する radio 要素一覧。\n */\nfunction getRadioGroupTargets(target: HTMLInputElement): HTMLInputElement[] {\n if (target.name) {\n const rootNode = target.form ?? target.ownerDocument;\n const escapedName = typeof CSS !== 'undefined' && typeof CSS.escape === 'function'\n ? CSS.escape(target.name)\n : target.name.replace(/([\"\\\\])/g, '\\\\$1');\n const groupTargets = Array.from(\n rootNode.querySelectorAll<HTMLInputElement>(`input[type=\"radio\"][name=\"${escapedName}\"]`),\n );\n if (groupTargets.length > 0) {\n return groupTargets;\n }\n }\n\n return [target];\n}\n\n/**\n * 複数要素の最も近い共通祖先要素を返す。\n *\n * @param elements 判定対象の要素一覧。\n * @return 共通祖先要素。見つからない場合は undefined。\n */\nfunction findCommonAncestor(elements: readonly HTMLElement[]): HTMLElement | undefined {\n const [firstElement, ...restElements] = elements;\n if (!firstElement) {\n return undefined;\n }\n\n let candidate: HTMLElement | null = firstElement;\n while (candidate) {\n if (restElements.every((element) => candidate?.contains(element))) {\n return candidate;\n }\n candidate = candidate.parentElement;\n }\n\n return undefined;\n}\n\n/**\n * radio group のメッセージ挿入先を解決する。\n *\n * @param target 対象の radio 要素。\n * @return 挿入先の要素。見つからない場合は undefined。\n */\nfunction resolveRadioMessageHost(target: HTMLInputElement): HTMLElement | undefined {\n const groupTargets = getRadioGroupTargets(target);\n const wrappers = groupTargets\n .map((element) => element.closest('.form-check'))\n .filter((element): element is HTMLElement => element instanceof HTMLElement);\n\n if (wrappers.length > 1) {\n const commonAncestor = findCommonAncestor(wrappers);\n if (commonAncestor && !wrappers.includes(commonAncestor)) {\n return commonAncestor;\n }\n }\n\n return resolveChoiceMessageHost(target);\n}\n\n/**\n * checkbox と radio のメッセージ挿入先を解決する。\n *\n * @param target 対象の input 要素。\n * @return 挿入先の form-check 要素。見つからない場合は undefined。\n */\nfunction resolveChoiceMessageHost(target: HTMLInputElement): HTMLElement | undefined {\n const closestFormCheck = target.closest('.form-check');\n return closestFormCheck instanceof HTMLElement ? closestFormCheck : undefined;\n}\n\n/**\n * 通常フィールドの直後に invalid-feedback コンテナを取得または生成する。\n *\n * @param target 対象の要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureFieldContainer(target: HTMLElement): HTMLElement {\n const nextElement = target.nextElementSibling;\n if (\n nextElement instanceof HTMLElement &&\n nextElement.getAttribute(CONTAINER_ATTRIBUTE) === 'true'\n ) {\n return nextElement;\n }\n\n const container = document.createElement('div');\n container.className = 'invalid-feedback d-block';\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n target.insertAdjacentElement('afterend', container);\n return container;\n}\n\n/**\n * checkbox と radio 用に form-check 末尾の invalid-feedback を取得または生成する。\n *\n * @param target 対象の input 要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureChoiceContainer(target: HTMLInputElement): HTMLElement {\n const hostElement = isRadioInput(target)\n ? resolveRadioMessageHost(target)\n : resolveChoiceMessageHost(target);\n if (!hostElement) {\n return ensureFieldContainer(target);\n }\n\n const existingContainer = getDirectOwnedContainer(hostElement);\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = 'invalid-feedback d-block';\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n hostElement.appendChild(container);\n return container;\n}\n\n/**\n * container target の先頭に alert コンテナを取得または生成する。\n *\n * @param target 対象の要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureBlockContainer(target: HTMLElement): HTMLElement {\n const existingContainer = getOwnedDirectChild(target);\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = 'alert alert-danger';\n container.setAttribute('role', 'alert');\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n target.insertAdjacentElement('afterbegin', container);\n return container;\n}\n\n/**\n * このライブラリが付けた is-invalid 状態だけを外す。\n *\n * @param target 状態を解除する要素。\n * @return 戻り値はない。\n */\nfunction removeOwnedInvalidState(target: HTMLElement): void {\n if (target.getAttribute(INVALID_TARGET_ATTRIBUTE) !== 'true') {\n return;\n }\n\n target.classList.remove('is-invalid');\n target.removeAttribute(INVALID_TARGET_ATTRIBUTE);\n}\n\n/**\n * choice input に対して、このライブラリが付けた invalid 状態を付与する。\n *\n * @param target 対象の input 要素。\n * @return 戻り値はない。\n */\nfunction markChoiceInvalidState(target: HTMLInputElement): void {\n const targets = isRadioInput(target) ? getRadioGroupTargets(target) : [target];\n targets.forEach((element) => {\n element.classList.add('is-invalid');\n element.setAttribute(INVALID_TARGET_ATTRIBUTE, 'true');\n });\n}\n\n/**\n * choice input に対して、このライブラリが付けた invalid 状態を解除する。\n *\n * @param target 対象の input 要素。\n * @return 戻り値はない。\n */\nfunction clearChoiceInvalidState(target: HTMLInputElement): void {\n const targets = isRadioInput(target) ? getRadioGroupTargets(target) : [target];\n targets.forEach((element) => {\n removeOwnedInvalidState(element);\n });\n}\n\n/**\n * 管理対象のエラーメッセージを追加する。\n *\n * @param target 追加先の要素。\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\nexport function addManagedErrorMessage(target: HTMLElement, message: string): Promise<void> {\n const container = isChoiceInput(target)\n ? ensureChoiceContainer(target)\n : isFieldTarget(target)\n ? ensureFieldContainer(target)\n : ensureBlockContainer(target);\n container.appendChild(createMessageItem(document, message));\n\n if (isChoiceInput(target)) {\n markChoiceInvalidState(target);\n } else if (isFieldTarget(target)) {\n target.classList.add('is-invalid');\n target.setAttribute(INVALID_TARGET_ATTRIBUTE, 'true');\n }\n\n return Promise.resolve();\n}\n\n/**\n * 管理対象のメッセージを削除する。\n *\n * @param parentOrTarget 削除対象の親要素または対象要素。\n * @return 完了時に解決される Promise。\n */\nexport function clearManagedMessages(parentOrTarget: HTMLElement): Promise<void> {\n if (isChoiceInput(parentOrTarget)) {\n const hostElement = isRadioInput(parentOrTarget)\n ? resolveRadioMessageHost(parentOrTarget)\n : resolveChoiceMessageHost(parentOrTarget);\n const ownedContainer = hostElement ? getDirectOwnedContainer(hostElement) : undefined;\n ownedContainer?.remove();\n clearChoiceInvalidState(parentOrTarget);\n } else if (isFieldTarget(parentOrTarget)) {\n const nextElement = parentOrTarget.nextElementSibling;\n if (\n nextElement instanceof HTMLElement &&\n nextElement.getAttribute(CONTAINER_ATTRIBUTE) === 'true'\n ) {\n nextElement.remove();\n }\n removeOwnedInvalidState(parentOrTarget);\n }\n\n const ownedContainers = parentOrTarget.querySelectorAll<HTMLElement>(\n `[${CONTAINER_ATTRIBUTE}=\"true\"]`,\n );\n ownedContainers.forEach((element) => {\n element.remove();\n });\n\n const invalidTargets = parentOrTarget.querySelectorAll<HTMLElement>(\n `[${INVALID_TARGET_ATTRIBUTE}=\"true\"]`,\n );\n invalidTargets.forEach((element) => {\n removeOwnedInvalidState(element);\n });\n\n return Promise.resolve();\n}\n","import { createModalInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\n/**\n * 既存要素を Bootstrap Modal として扱える最低限の属性へ整える。\n *\n * @param element 整形対象の要素。\n * @return 戻り値はない。\n */\nfunction prepareModalElement(element: HTMLElement): void {\n if (!element.classList.contains('modal')) {\n element.classList.add('modal');\n }\n\n if (element.tabIndex < 0) {\n element.tabIndex = -1;\n }\n\n if (!element.hasAttribute('aria-hidden')) {\n element.setAttribute('aria-hidden', 'true');\n }\n}\n\n/**\n * 任意要素を Bootstrap Modal として開く。\n *\n * @param element 開く対象の要素。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function openDialogElement(\n element: HTMLElement,\n options: ResolvedInstallOptions,\n): Promise<void> {\n prepareModalElement(element);\n const modalInstance = createModalInstance(element, undefined, options.bootstrap);\n if (!modalInstance) {\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n modalInstance.show();\n return Promise.resolve();\n}\n\n/**\n * 任意要素を Bootstrap Modal として閉じる。\n *\n * @param element 閉じる対象の要素。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function closeDialogElement(\n element: HTMLElement,\n options: ResolvedInstallOptions,\n): Promise<void> {\n prepareModalElement(element);\n const modalInstance = createModalInstance(element, undefined, options.bootstrap);\n if (!modalInstance) {\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n modalInstance.hide();\n return Promise.resolve();\n}\n","import { createToastInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\nconst TOAST_CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-toast-container';\nconst TOAST_ATTRIBUTE = 'data-haori-bootstrap-toast';\nconst TOAST_ACCENT_ATTRIBUTE = 'data-haori-bootstrap-toast-accent';\n\ninterface ToastAppearance {\n accentClassName: string;\n}\n\n/**\n * 通知レベルを toast 表示用の見た目へ変換する。\n *\n * @param level 通知レベル。\n * @return 対応する見た目定義。\n */\nfunction resolveToastAppearance(level?: string): ToastAppearance {\n switch (level) {\n case 'warning':\n return { accentClassName: 'bg-warning' };\n case 'error':\n return { accentClassName: 'bg-danger' };\n default:\n return { accentClassName: 'bg-info' };\n }\n}\n\n/**\n * toast コンテナを配置する親要素を解決する。\n *\n * @param documentObject 検索に使用する document。\n * @param options 解決済み導入設定。\n * @return 配置先の要素。\n */\nfunction resolveToastRoot(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n if (options.toastContainerSelector) {\n const resolvedElement = documentObject.querySelector<HTMLElement>(options.toastContainerSelector);\n if (resolvedElement) {\n return resolvedElement;\n }\n }\n\n return documentObject.body;\n}\n\n/**\n * toast コンテナを取得または生成する。\n *\n * @param documentObject 生成に使用する document。\n * @param options 解決済み導入設定。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureToastContainer(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n const rootElement = resolveToastRoot(documentObject, options);\n const existingContainer = rootElement.querySelector<HTMLElement>(\n `[${TOAST_CONTAINER_ATTRIBUTE}=\"true\"]`,\n );\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = documentObject.createElement('div');\n container.className = 'toast-container position-fixed bottom-0 end-0 p-3';\n container.setAttribute(TOAST_CONTAINER_ATTRIBUTE, 'true');\n rootElement.appendChild(container);\n return container;\n}\n\n/**\n * Bootstrap Toast を表示する。\n *\n * @param message 表示するメッセージ。\n * @param level 通知レベル。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function showToast(\n message: string,\n level: string | undefined,\n options: ResolvedInstallOptions,\n): Promise<void> {\n const documentObject = globalThis.document;\n const appearance = resolveToastAppearance(level);\n const toastElement = documentObject.createElement('div');\n toastElement.className = 'toast border bg-body text-body shadow-sm';\n toastElement.setAttribute('role', 'status');\n toastElement.setAttribute('aria-live', 'polite');\n toastElement.setAttribute('aria-atomic', 'true');\n toastElement.setAttribute(TOAST_ATTRIBUTE, 'true');\n\n const bodyWrapper = documentObject.createElement('div');\n bodyWrapper.className = 'd-flex align-items-stretch';\n\n const accentElement = documentObject.createElement('div');\n accentElement.className = `flex-shrink-0 rounded-start ${appearance.accentClassName}`;\n accentElement.style.width = '0.375rem';\n accentElement.setAttribute(TOAST_ACCENT_ATTRIBUTE, 'true');\n\n const bodyElement = documentObject.createElement('div');\n bodyElement.className = 'toast-body';\n bodyElement.style.whiteSpace = 'pre-line';\n bodyElement.textContent = message;\n\n bodyWrapper.appendChild(accentElement);\n bodyWrapper.appendChild(bodyElement);\n toastElement.appendChild(bodyWrapper);\n ensureToastContainer(documentObject, options).appendChild(toastElement);\n\n const toastInstance = createToastInstance(toastElement, options.bootstrap);\n if (!toastInstance) {\n toastElement.remove();\n return Promise.reject(new Error('Bootstrap Toast is unavailable.'));\n }\n\n toastElement.addEventListener(\n 'hidden.bs.toast',\n () => {\n toastElement.remove();\n toastInstance.dispose?.();\n },\n { once: true },\n );\n\n try {\n toastInstance.show();\n return Promise.resolve();\n } catch (error) {\n toastElement.remove();\n toastInstance.dispose?.();\n return Promise.reject(error);\n }\n}\n","import { hasModalSupport, hasToastSupport } from './bootstrap_resolver';\nimport { showConfirm, showDialog } from './dialog';\nimport { addManagedErrorMessage, clearManagedMessages } from './message';\nimport { closeDialogElement, openDialogElement } from './modal';\nimport { showToast } from './toast';\nimport type { HaoriGlobalObject, ResolvedInstallOptions } from './types';\n\n/**\n * BootstrapHaori が利用する内部コンテキスト。\n */\nexport interface BootstrapHaoriContext {\n /** 差し替え前の Haori 実装。 */\n originalHaori?: HaoriGlobalObject;\n /** 解決済みの導入設定。 */\n options: ResolvedInstallOptions;\n}\n\nconst defaultContext: BootstrapHaoriContext = {\n options: {\n fallbackToNative: true,\n },\n};\n\nlet context = defaultContext;\n\n/**\n * 表示用 message 中のエスケープ済み改行を実際の改行へ正規化する。\n *\n * @param message 正規化対象のメッセージ。\n * @return 正規化後のメッセージ。\n */\nfunction normalizeMessageText(message: string): string {\n return message.replace(/\\\\n/g, '\\n');\n}\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): Window | undefined {\n const scope = globalThis as typeof globalThis & { window?: Window };\n return scope.window;\n}\n\n/**\n * 値を Promise<void> 契約へ正規化する。\n *\n * @param value 正規化対象の値。\n * @return 完了時に解決される Promise。\n */\nfunction toPromiseVoid(value: Promise<void> | void | unknown): Promise<void> {\n return Promise.resolve(value).then(() => undefined);\n}\n\n/**\n * 元の Haori 実装から対象メソッドを取得する。\n *\n * @param methodName 取得対象のメソッド名。\n * @return 対象メソッド。見つからない場合は undefined。\n */\nfunction getOriginalMethod(\n methodName: keyof HaoriGlobalObject,\n): ((...args: readonly unknown[]) => unknown) | undefined {\n const method = context.originalHaori?.[methodName];\n return typeof method === 'function'\n ? (method as (...args: readonly unknown[]) => unknown)\n : undefined;\n}\n\n/**\n * no-op に正規化したことを警告する。\n *\n * @param apiName 利用できなかった API 名。\n * @return 戻り値はない。\n */\nfunction warnNoop(apiName: string): void {\n console.warn(`[haori-bootstrap] ${apiName} skipped because Bootstrap support is unavailable.`);\n}\n\n/**\n * dialog の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackDialog(message: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('dialog');\n if (originalMethod) {\n return toPromiseVoid(originalMethod(normalizedMessage));\n }\n\n const browserWindow = getBrowserWindow();\n if (context.options.fallbackToNative && typeof browserWindow?.alert === 'function') {\n browserWindow.alert(normalizedMessage);\n return Promise.resolve();\n }\n\n warnNoop('dialog');\n return Promise.resolve();\n}\n\n/**\n * confirm の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @return 確認結果を返す Promise。\n */\nfunction fallbackConfirm(message: string): Promise<boolean> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('confirm');\n if (originalMethod) {\n return Promise.resolve(originalMethod(normalizedMessage) as Promise<boolean> | boolean).then(\n (value) => Boolean(value),\n );\n }\n\n const browserWindow = getBrowserWindow();\n if (context.options.fallbackToNative && typeof browserWindow?.confirm === 'function') {\n return Promise.resolve(browserWindow.confirm(normalizedMessage));\n }\n\n warnNoop('confirm');\n return Promise.resolve(false);\n}\n\n/**\n * toast の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @param level 通知レベル。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackToast(message: string, level?: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('toast');\n if (originalMethod) {\n return toPromiseVoid(originalMethod(normalizedMessage, level));\n }\n\n warnNoop('toast');\n return Promise.resolve();\n}\n\n/**\n * openDialog または closeDialog の fallback 経路を処理する。\n *\n * @param methodName 呼び出す API 名。\n * @param element 対象要素。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackModal(methodName: 'openDialog' | 'closeDialog', element: HTMLElement): Promise<void> {\n const originalMethod = getOriginalMethod(methodName);\n if (originalMethod) {\n return toPromiseVoid(originalMethod(element));\n }\n\n warnNoop(methodName);\n return Promise.resolve();\n}\n\n/**\n * BootstrapHaori が参照する内部状態を更新する。\n *\n * @param nextContext 差し替え先が参照する内部コンテキスト。\n * @return 戻り値はない。\n */\nexport function setBootstrapHaoriContext(nextContext: BootstrapHaoriContext): void {\n context = nextContext;\n}\n\n/**\n * Haori の UI 系静的メソッドを差し替える最小ファサード。\n */\nexport class BootstrapHaori {\n /**\n * 情報表示ダイアログを表示する。\n *\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\n public static dialog(message: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasModalSupport(context.options.bootstrap)) {\n return showDialog(normalizedMessage, context.options).catch(() => fallbackDialog(normalizedMessage));\n }\n\n return fallbackDialog(normalizedMessage);\n }\n\n /**\n * 確認ダイアログを表示する。\n *\n * @param message 表示するメッセージ。\n * @return OK のみ true を返す Promise。\n */\n public static confirm(message: string): Promise<boolean> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasModalSupport(context.options.bootstrap)) {\n return showConfirm(normalizedMessage, context.options).catch(() => fallbackConfirm(normalizedMessage));\n }\n\n return fallbackConfirm(normalizedMessage);\n }\n\n /**\n * トースト通知を表示する。\n *\n * @param message 表示するメッセージ。\n * @param level 通知レベル。\n * @return 完了時に解決される Promise。\n */\n public static toast(message: string, level?: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasToastSupport(context.options.bootstrap)) {\n return showToast(normalizedMessage, level, context.options).catch(() =>\n fallbackToast(normalizedMessage, level),\n );\n }\n\n return fallbackToast(normalizedMessage, level);\n }\n\n /**\n * 任意のダイアログ要素を開く。\n *\n * @param element 開く対象の要素。\n * @return 完了時に解決される Promise。\n */\n public static openDialog(element: HTMLElement): Promise<void> {\n if (hasModalSupport(context.options.bootstrap)) {\n return openDialogElement(element, context.options).catch(() =>\n fallbackModal('openDialog', element),\n );\n }\n\n return fallbackModal('openDialog', element);\n }\n\n /**\n * 任意のダイアログ要素を閉じる。\n *\n * @param element 閉じる対象の要素。\n * @return 完了時に解決される Promise。\n */\n public static closeDialog(element: HTMLElement): Promise<void> {\n if (hasModalSupport(context.options.bootstrap)) {\n return closeDialogElement(element, context.options).catch(() =>\n fallbackModal('closeDialog', element),\n );\n }\n\n return fallbackModal('closeDialog', element);\n }\n\n /**\n * 管理対象のエラーメッセージを追加する。\n *\n * @param target 追加先の要素。\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\n public static addErrorMessage(target: HTMLElement, message: string): Promise<void> {\n return addManagedErrorMessage(target, message);\n }\n\n /**\n * 管理対象のメッセージを削除する。\n *\n * @param parentOrTarget 削除対象の親要素または対象要素。\n * @return 完了時に解決される Promise。\n */\n public static clearMessages(parentOrTarget: HTMLElement): Promise<void> {\n return clearManagedMessages(parentOrTarget);\n }\n}\n","import { BootstrapHaori, setBootstrapHaoriContext } from './bootstrap_haori';\nimport type {\n BrowserWindow,\n HaoriGlobalObject,\n InstallOptions,\n ResolvedInstallOptions,\n} from './types';\n\nconst DEFAULT_INSTALL_OPTIONS: ResolvedInstallOptions = {\n fallbackToNative: true,\n};\n\nconst installState: {\n installed: boolean;\n originalHaori?: HaoriGlobalObject;\n options: ResolvedInstallOptions;\n} = {\n installed: false,\n options: DEFAULT_INSTALL_OPTIONS,\n};\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): BrowserWindow | undefined {\n const scope = globalThis as typeof globalThis & { window?: BrowserWindow };\n return scope.window;\n}\n\n/**\n * install に渡された設定を既定値込みで解決する。\n *\n * @param options 指定された導入設定。\n * @param browserWindow 現在の window。\n * @return 解決済みの導入設定。\n */\nfunction resolveInstallOptions(\n options: InstallOptions,\n browserWindow: BrowserWindow | undefined,\n): ResolvedInstallOptions {\n return {\n bootstrap: options.bootstrap ?? browserWindow?.bootstrap,\n fallbackToNative: options.fallbackToNative ?? DEFAULT_INSTALL_OPTIONS.fallbackToNative,\n toastContainerSelector: options.toastContainerSelector,\n dialogContainerSelector: options.dialogContainerSelector,\n };\n}\n\n/**\n * 自動有効化に必要な前提が揃っているかを返す。\n *\n * @param browserWindow 判定対象の window。\n * @return 自動有効化可能なら true。\n */\nexport function hasAutoEnablePrerequisites(\n browserWindow: BrowserWindow | undefined = getBrowserWindow(),\n): boolean {\n return Boolean(browserWindow?.Haori && browserWindow.bootstrap);\n}\n\n/**\n * Bootstrap 対応 Haori を再適用し、必要なら設定を上書きする。\n *\n * @param options 上書きする導入設定。\n * @return 戻り値はない。\n */\nexport function install(options: InstallOptions = {}): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow?.Haori) {\n throw new Error('window.Haori is required before calling install().');\n }\n\n if (!installState.originalHaori) {\n installState.originalHaori = browserWindow.Haori;\n }\n\n installState.options = resolveInstallOptions(options, browserWindow);\n setBootstrapHaoriContext({\n originalHaori: installState.originalHaori,\n options: installState.options,\n });\n browserWindow.Haori = BootstrapHaori as unknown as HaoriGlobalObject;\n installState.installed = true;\n}\n\n/**\n * 元の Haori 実装を復元する。\n *\n * @return 戻り値はない。\n */\nexport function uninstall(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow || !installState.originalHaori) {\n return;\n }\n\n browserWindow.Haori = installState.originalHaori;\n installState.installed = false;\n installState.originalHaori = undefined;\n}\n\n/**\n * 現在 BootstrapHaori が有効かどうかを返す。\n *\n * @return 有効なら true。\n */\nexport function isInstalled(): boolean {\n return installState.installed;\n}\n","import { hasAutoEnablePrerequisites, install } from './install';\nimport type { BrowserWindow } from './types';\n\nconst AUTO_ENABLE_MARKER = '__haoriJsBootstrapAutoEnabled__';\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): BrowserWindow | undefined {\n const scope = globalThis as typeof globalThis & { window?: BrowserWindow };\n return scope.window;\n}\n\n/**\n * 既に自動有効化済みかどうかを返す。\n *\n * @param browserWindow 判定対象の window。\n * @return 既に自動有効化済みなら true。\n */\nfunction wasAutoEnabled(browserWindow: BrowserWindow): boolean {\n return Boolean((browserWindow as unknown as Record<string, unknown>)[AUTO_ENABLE_MARKER]);\n}\n\n/**\n * 自動有効化済みの印を付ける。\n *\n * @param browserWindow 更新対象の window。\n * @return 戻り値はない。\n */\nfunction markAutoEnabled(browserWindow: BrowserWindow): void {\n (browserWindow as unknown as Record<string, unknown>)[AUTO_ENABLE_MARKER] = true;\n}\n\n/**\n * 前提が揃っていれば自動有効化を試行する。\n *\n * @return 戻り値はない。\n */\nfunction autoEnable(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow || wasAutoEnabled(browserWindow)) {\n return;\n }\n\n if (!hasAutoEnablePrerequisites(browserWindow)) {\n console.warn(\n '[haori-bootstrap] Auto-enable skipped because window.Haori or window.bootstrap is missing.',\n );\n return;\n }\n\n try {\n install({ bootstrap: browserWindow.bootstrap });\n markAutoEnabled(browserWindow);\n } catch (error) {\n console.warn('[haori-bootstrap] Auto-enable failed.', error);\n }\n}\n\nautoEnable();\n","import './browser';\n\nexport { BootstrapHaori } from './bootstrap_haori';\nexport { hasAutoEnablePrerequisites, install, isInstalled, uninstall } from './install';\nexport type {\n BootstrapNamespace,\n BrowserWindow,\n HaoriBootstrapGlobal,\n HaoriGlobalObject,\n InstallOptions,\n ResolvedInstallOptions,\n} from './types';\n\n/**\n * パッケージの公開版数。\n */\nexport const version = '0.2.0';\n"],"names":["isConstructor","value","resolveModalConstructor","bootstrap","resolveToastConstructor","hasModalSupport","hasToastSupport","createModalInstance","element","options","modalConstructor","createToastInstance","toastConstructor","DIALOG_CONTAINER_ATTRIBUTE","ACTION_ATTRIBUTE","createDialogModalOptions","resolveDialogContainer","documentObject","resolvedElement","createModalShell","message","isConfirm","modalElement","dialogElement","contentElement","bodyElement","messageElement","footerElement","cancelButton","okButton","showDialog","modalInstance","resolve","reject","finalize","handleHidden","error","showConfirm","confirmed","OWNED_ATTRIBUTE","CONTAINER_ATTRIBUTE","INVALID_TARGET_ATTRIBUTE","isChoiceInput","target","isRadioInput","isFieldTarget","getDirectOwnedContainer","createMessageItem","getOwnedDirectChild","getRadioGroupTargets","rootNode","escapedName","groupTargets","findCommonAncestor","elements","firstElement","restElements","candidate","resolveRadioMessageHost","wrappers","commonAncestor","resolveChoiceMessageHost","closestFormCheck","ensureFieldContainer","nextElement","container","ensureChoiceContainer","hostElement","existingContainer","ensureBlockContainer","removeOwnedInvalidState","markChoiceInvalidState","clearChoiceInvalidState","addManagedErrorMessage","clearManagedMessages","parentOrTarget","prepareModalElement","openDialogElement","closeDialogElement","TOAST_CONTAINER_ATTRIBUTE","TOAST_ATTRIBUTE","TOAST_ACCENT_ATTRIBUTE","resolveToastAppearance","level","resolveToastRoot","ensureToastContainer","rootElement","showToast","appearance","toastElement","bodyWrapper","accentElement","toastInstance","defaultContext","context","normalizeMessageText","getBrowserWindow","toPromiseVoid","getOriginalMethod","methodName","method","warnNoop","apiName","fallbackDialog","normalizedMessage","originalMethod","browserWindow","fallbackConfirm","fallbackToast","fallbackModal","setBootstrapHaoriContext","nextContext","BootstrapHaori","DEFAULT_INSTALL_OPTIONS","installState","resolveInstallOptions","hasAutoEnablePrerequisites","install","uninstall","isInstalled","AUTO_ENABLE_MARKER","wasAutoEnabled","markAutoEnabled","autoEnable","version"],"mappings":"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"}
1
+ {"version":3,"file":"haori-bootstrap.js","sources":["../src/bootstrap_resolver.ts","../src/dialog.ts","../src/message.ts","../src/modal.ts","../src/toast.ts","../src/bootstrap_haori.ts","../src/install.ts","../src/browser.ts","../src/index.ts"],"sourcesContent":["import type {\n BootstrapModalConstructor,\n BootstrapModalInstance,\n BootstrapModalOptions,\n BootstrapNamespace,\n BootstrapToastConstructor,\n BootstrapToastInstance,\n} from './types';\n\n/**\n * 値がコンストラクター関数かどうかを判定する。\n *\n * @param value 判定対象の値。\n * @return コンストラクター関数なら true。\n */\nfunction isConstructor<T>(value: unknown): value is new (...args: readonly unknown[]) => T {\n return typeof value === 'function';\n}\n\n/**\n * Bootstrap の Modal コンストラクターを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return Modal コンストラクター。見つからない場合は undefined。\n */\nexport function resolveModalConstructor(\n bootstrap?: BootstrapNamespace,\n): BootstrapModalConstructor | undefined {\n return isConstructor<BootstrapModalInstance>(bootstrap?.Modal)\n ? (bootstrap?.Modal as BootstrapModalConstructor)\n : undefined;\n}\n\n/**\n * Bootstrap の Toast コンストラクターを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return Toast コンストラクター。見つからない場合は undefined。\n */\nexport function resolveToastConstructor(\n bootstrap?: BootstrapNamespace,\n): BootstrapToastConstructor | undefined {\n return isConstructor<BootstrapToastInstance>(bootstrap?.Toast)\n ? (bootstrap?.Toast as BootstrapToastConstructor)\n : undefined;\n}\n\n/**\n * Modal が利用可能かどうかを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return 利用可能なら true。\n */\nexport function hasModalSupport(bootstrap?: BootstrapNamespace): boolean {\n return Boolean(resolveModalConstructor(bootstrap));\n}\n\n/**\n * Toast が利用可能かどうかを返す。\n *\n * @param bootstrap Bootstrap 名前空間。\n * @return 利用可能なら true。\n */\nexport function hasToastSupport(bootstrap?: BootstrapNamespace): boolean {\n return Boolean(resolveToastConstructor(bootstrap));\n}\n\n/**\n * Modal インスタンスを取得または生成する。\n *\n * @param element 対象要素。\n * @param bootstrap Bootstrap 名前空間。\n * @return Modal インスタンス。生成できない場合は undefined。\n */\nexport function createModalInstance(\n element: HTMLElement,\n options?: BootstrapModalOptions,\n bootstrap?: BootstrapNamespace,\n): BootstrapModalInstance | undefined {\n const modalConstructor = resolveModalConstructor(bootstrap);\n if (!modalConstructor) {\n return undefined;\n }\n\n if (typeof modalConstructor.getOrCreateInstance === 'function') {\n return modalConstructor.getOrCreateInstance(element, options);\n }\n\n return new modalConstructor(element, options);\n}\n\n/**\n * Toast インスタンスを取得または生成する。\n *\n * @param element 対象要素。\n * @param bootstrap Bootstrap 名前空間。\n * @return Toast インスタンス。生成できない場合は undefined。\n */\nexport function createToastInstance(\n element: HTMLElement,\n bootstrap?: BootstrapNamespace,\n): BootstrapToastInstance | undefined {\n const toastConstructor = resolveToastConstructor(bootstrap);\n if (!toastConstructor) {\n return undefined;\n }\n\n if (typeof toastConstructor.getOrCreateInstance === 'function') {\n return toastConstructor.getOrCreateInstance(element);\n }\n\n return new toastConstructor(element);\n}\n","import { createModalInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\nconst DIALOG_CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-dialog';\nconst ACTION_ATTRIBUTE = 'data-haori-bootstrap-action';\n\n/**\n * dialog 系 modal の既定オプションを返す。\n *\n * @return Bootstrap Modal の生成オプション。\n */\nfunction createDialogModalOptions() {\n return {\n backdrop: 'static' as const,\n };\n}\n\n/**\n * dialog を挿入する親要素を解決する。\n *\n * @param documentObject 検索に使用する document。\n * @param options 解決済み導入設定。\n * @return 挿入先の要素。\n */\nfunction resolveDialogContainer(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n if (options.dialogContainerSelector) {\n const resolvedElement = documentObject.querySelector<HTMLElement>(\n options.dialogContainerSelector,\n );\n if (resolvedElement) {\n return resolvedElement;\n }\n }\n\n return documentObject.body;\n}\n\n/**\n * dialog または confirm 用の modal 要素を組み立てる。\n *\n * @param documentObject 生成に使用する document。\n * @param message 表示するメッセージ。\n * @param isConfirm confirm 用かどうか。\n * @return 生成した modal 要素。\n */\nfunction createModalShell(documentObject: Document, message: string, isConfirm: boolean): HTMLDivElement {\n const modalElement = documentObject.createElement('div');\n modalElement.className = 'modal fade';\n modalElement.tabIndex = -1;\n modalElement.setAttribute(DIALOG_CONTAINER_ATTRIBUTE, 'true');\n modalElement.setAttribute('aria-hidden', 'true');\n\n const dialogElement = documentObject.createElement('div');\n dialogElement.className = 'modal-dialog modal-dialog-centered';\n\n const contentElement = documentObject.createElement('div');\n contentElement.className = 'modal-content';\n\n const bodyElement = documentObject.createElement('div');\n bodyElement.className = 'modal-body';\n\n const messageElement = documentObject.createElement('p');\n messageElement.className = 'mb-0';\n messageElement.style.whiteSpace = 'pre-line';\n messageElement.textContent = message;\n bodyElement.appendChild(messageElement);\n\n const footerElement = documentObject.createElement('div');\n footerElement.className = 'modal-footer';\n\n if (isConfirm) {\n const cancelButton = documentObject.createElement('button');\n cancelButton.type = 'button';\n cancelButton.className = 'btn btn-secondary';\n cancelButton.setAttribute(ACTION_ATTRIBUTE, 'cancel');\n cancelButton.textContent = 'Cancel';\n footerElement.appendChild(cancelButton);\n }\n\n const okButton = documentObject.createElement('button');\n okButton.type = 'button';\n okButton.className = 'btn btn-primary';\n okButton.setAttribute(ACTION_ATTRIBUTE, 'ok');\n okButton.textContent = 'OK';\n footerElement.appendChild(okButton);\n\n contentElement.append(bodyElement, footerElement);\n dialogElement.appendChild(contentElement);\n modalElement.appendChild(dialogElement);\n return modalElement;\n}\n\n/**\n * 情報表示用の Bootstrap Modal を表示する。\n *\n * @param message 表示するメッセージ。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function showDialog(message: string, options: ResolvedInstallOptions): Promise<void> {\n const documentObject = globalThis.document;\n const modalElement = createModalShell(documentObject, message, false);\n resolveDialogContainer(documentObject, options).appendChild(modalElement);\n\n const modalInstance = createModalInstance(\n modalElement,\n createDialogModalOptions(),\n options.bootstrap,\n );\n if (!modalInstance) {\n modalElement.remove();\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n return new Promise<void>((resolve, reject) => {\n const finalize = (): void => {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n resolve();\n };\n\n const handleHidden = (): void => {\n finalize();\n };\n\n const okButton = modalElement.querySelector<HTMLButtonElement>(`[${ACTION_ATTRIBUTE}=\"ok\"]`);\n okButton?.addEventListener(\n 'click',\n () => {\n modalInstance.hide();\n },\n { once: true },\n );\n\n modalElement.addEventListener('hidden.bs.modal', handleHidden, { once: true });\n\n try {\n modalInstance.show();\n } catch (error) {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n reject(error);\n }\n });\n}\n\n/**\n * 確認用の Bootstrap Modal を表示する。\n *\n * @param message 表示するメッセージ。\n * @param options 解決済み導入設定。\n * @return OK のみ true を返す Promise。\n */\nexport function showConfirm(\n message: string,\n options: ResolvedInstallOptions,\n): Promise<boolean> {\n const documentObject = globalThis.document;\n const modalElement = createModalShell(documentObject, message, true);\n resolveDialogContainer(documentObject, options).appendChild(modalElement);\n\n const modalInstance = createModalInstance(\n modalElement,\n createDialogModalOptions(),\n options.bootstrap,\n );\n if (!modalInstance) {\n modalElement.remove();\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n return new Promise<boolean>((resolve, reject) => {\n let confirmed = false;\n\n const finalize = (): void => {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n resolve(confirmed);\n };\n\n const handleHidden = (): void => {\n finalize();\n };\n\n const okButton = modalElement.querySelector<HTMLButtonElement>(`[${ACTION_ATTRIBUTE}=\"ok\"]`);\n const cancelButton = modalElement.querySelector<HTMLButtonElement>(\n `[${ACTION_ATTRIBUTE}=\"cancel\"]`,\n );\n\n okButton?.addEventListener(\n 'click',\n () => {\n confirmed = true;\n modalInstance.hide();\n },\n { once: true },\n );\n cancelButton?.addEventListener(\n 'click',\n () => {\n confirmed = false;\n modalInstance.hide();\n },\n { once: true },\n );\n\n modalElement.addEventListener('hidden.bs.modal', handleHidden, { once: true });\n\n try {\n modalInstance.show();\n } catch (error) {\n modalElement.removeEventListener('hidden.bs.modal', handleHidden);\n modalElement.remove();\n modalInstance.dispose?.();\n reject(error);\n }\n });\n}\n","const OWNED_ATTRIBUTE = 'data-haori-bootstrap-owned';\nconst CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-message-container';\nconst INVALID_TARGET_ATTRIBUTE = 'data-haori-bootstrap-invalid-target';\n\n/**\n * 対象要素が checkbox または radio かどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return checkbox または radio の input 要素なら true。\n */\nfunction isChoiceInput(target: HTMLElement): target is HTMLInputElement {\n return (\n target instanceof HTMLInputElement &&\n (target.type === 'checkbox' || target.type === 'radio')\n );\n}\n\n/**\n * 対象要素が radio input かどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return radio の input 要素なら true。\n */\nfunction isRadioInput(target: HTMLElement): target is HTMLInputElement {\n return target instanceof HTMLInputElement && target.type === 'radio';\n}\n\n/**\n * 対象要素が通常の invalid-feedback を直後に付与するフィールドかどうかを判定する。\n *\n * @param target 判定対象の要素。\n * @return 入力系フィールドなら true。\n */\nfunction isFieldTarget(\n target: HTMLElement,\n): target is HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement {\n return (\n target instanceof HTMLInputElement ||\n target instanceof HTMLSelectElement ||\n target instanceof HTMLTextAreaElement\n );\n}\n\n/**\n * 子要素から管理対象のメッセージコンテナを取得する。\n *\n * @param target 検索対象の要素。\n * @return 管理対象コンテナ。見つからない場合は undefined。\n */\nfunction getDirectOwnedContainer(target: HTMLElement): HTMLElement | undefined {\n return Array.from(target.children).find(\n (element): element is HTMLElement =>\n element instanceof HTMLElement && element.getAttribute(CONTAINER_ATTRIBUTE) === 'true',\n );\n}\n\n/**\n * 管理対象のメッセージ要素を生成する。\n *\n * @param documentObject 生成に使用する document。\n * @param message 表示するメッセージ。\n * @return 生成したメッセージ要素。\n */\nfunction createMessageItem(documentObject: Document, message: string): HTMLDivElement {\n const messageElement = documentObject.createElement('div');\n messageElement.setAttribute(OWNED_ATTRIBUTE, 'true');\n messageElement.textContent = message;\n return messageElement;\n}\n\n/**\n * block container 配下の既存メッセージコンテナを取得する。\n *\n * @param target 検索対象の要素。\n * @return 既存コンテナ。見つからない場合は undefined。\n */\nfunction getOwnedDirectChild(target: HTMLElement): HTMLElement | undefined {\n return getDirectOwnedContainer(target);\n}\n\n/**\n * 指定した radio と同じグループに属する radio 要素一覧を取得する。\n *\n * @param target 基準となる radio 要素。\n * @return 同じグループに属する radio 要素一覧。\n */\nfunction getRadioGroupTargets(target: HTMLInputElement): HTMLInputElement[] {\n if (target.name) {\n const rootNode = target.form ?? target.ownerDocument;\n const escapedName = typeof CSS !== 'undefined' && typeof CSS.escape === 'function'\n ? CSS.escape(target.name)\n : target.name.replace(/([\"\\\\])/g, '\\\\$1');\n const groupTargets = Array.from(\n rootNode.querySelectorAll<HTMLInputElement>(`input[type=\"radio\"][name=\"${escapedName}\"]`),\n );\n if (groupTargets.length > 0) {\n return groupTargets;\n }\n }\n\n return [target];\n}\n\n/**\n * 複数要素の最も近い共通祖先要素を返す。\n *\n * @param elements 判定対象の要素一覧。\n * @return 共通祖先要素。見つからない場合は undefined。\n */\nfunction findCommonAncestor(elements: readonly HTMLElement[]): HTMLElement | undefined {\n const [firstElement, ...restElements] = elements;\n if (!firstElement) {\n return undefined;\n }\n\n let candidate: HTMLElement | null = firstElement;\n while (candidate) {\n if (restElements.every((element) => candidate?.contains(element))) {\n return candidate;\n }\n candidate = candidate.parentElement;\n }\n\n return undefined;\n}\n\n/**\n * radio group のメッセージ挿入先を解決する。\n *\n * @param target 対象の radio 要素。\n * @return 挿入先の要素。見つからない場合は undefined。\n */\nfunction resolveRadioMessageHost(target: HTMLInputElement): HTMLElement | undefined {\n const groupTargets = getRadioGroupTargets(target);\n const wrappers = groupTargets\n .map((element) => element.closest('.form-check'))\n .filter((element): element is HTMLElement => element instanceof HTMLElement);\n\n if (wrappers.length > 1) {\n const commonAncestor = findCommonAncestor(wrappers);\n if (commonAncestor && !wrappers.includes(commonAncestor)) {\n return commonAncestor;\n }\n }\n\n return resolveChoiceMessageHost(target);\n}\n\n/**\n * checkbox と radio のメッセージ挿入先を解決する。\n *\n * @param target 対象の input 要素。\n * @return 挿入先の form-check 要素。見つからない場合は undefined。\n */\nfunction resolveChoiceMessageHost(target: HTMLInputElement): HTMLElement | undefined {\n const closestFormCheck = target.closest('.form-check');\n return closestFormCheck instanceof HTMLElement ? closestFormCheck : undefined;\n}\n\n/**\n * 通常フィールドの直後に invalid-feedback コンテナを取得または生成する。\n *\n * @param target 対象の要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureFieldContainer(target: HTMLElement): HTMLElement {\n const nextElement = target.nextElementSibling;\n if (\n nextElement instanceof HTMLElement &&\n nextElement.getAttribute(CONTAINER_ATTRIBUTE) === 'true'\n ) {\n return nextElement;\n }\n\n const container = document.createElement('div');\n container.className = 'invalid-feedback d-block';\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n target.insertAdjacentElement('afterend', container);\n return container;\n}\n\n/**\n * checkbox と radio 用に form-check 末尾の invalid-feedback を取得または生成する。\n *\n * @param target 対象の input 要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureChoiceContainer(target: HTMLInputElement): HTMLElement {\n const hostElement = isRadioInput(target)\n ? resolveRadioMessageHost(target)\n : resolveChoiceMessageHost(target);\n if (!hostElement) {\n return ensureFieldContainer(target);\n }\n\n const existingContainer = getDirectOwnedContainer(hostElement);\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = 'invalid-feedback d-block';\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n hostElement.appendChild(container);\n return container;\n}\n\n/**\n * container target の先頭に alert コンテナを取得または生成する。\n *\n * @param target 対象の要素。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureBlockContainer(target: HTMLElement): HTMLElement {\n const existingContainer = getOwnedDirectChild(target);\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = 'alert alert-danger';\n container.setAttribute('role', 'alert');\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n target.insertAdjacentElement('afterbegin', container);\n return container;\n}\n\n/**\n * このライブラリが付けた is-invalid 状態だけを外す。\n *\n * @param target 状態を解除する要素。\n * @return 戻り値はない。\n */\nfunction removeOwnedInvalidState(target: HTMLElement): void {\n if (target.getAttribute(INVALID_TARGET_ATTRIBUTE) !== 'true') {\n return;\n }\n\n target.classList.remove('is-invalid');\n target.removeAttribute(INVALID_TARGET_ATTRIBUTE);\n}\n\n/**\n * choice input に対して、このライブラリが付けた invalid 状態を付与する。\n *\n * @param target 対象の input 要素。\n * @return 戻り値はない。\n */\nfunction markChoiceInvalidState(target: HTMLInputElement): void {\n const targets = isRadioInput(target) ? getRadioGroupTargets(target) : [target];\n targets.forEach((element) => {\n element.classList.add('is-invalid');\n element.setAttribute(INVALID_TARGET_ATTRIBUTE, 'true');\n });\n}\n\n/**\n * choice input に対して、このライブラリが付けた invalid 状態を解除する。\n *\n * @param target 対象の input 要素。\n * @return 戻り値はない。\n */\nfunction clearChoiceInvalidState(target: HTMLInputElement): void {\n const targets = isRadioInput(target) ? getRadioGroupTargets(target) : [target];\n targets.forEach((element) => {\n removeOwnedInvalidState(element);\n });\n}\n\n/**\n * 管理対象のエラーメッセージを追加する。\n *\n * @param target 追加先の要素。\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\nexport function addManagedErrorMessage(target: HTMLElement, message: string): Promise<void> {\n const container = isChoiceInput(target)\n ? ensureChoiceContainer(target)\n : isFieldTarget(target)\n ? ensureFieldContainer(target)\n : ensureBlockContainer(target);\n container.appendChild(createMessageItem(document, message));\n\n if (isChoiceInput(target)) {\n markChoiceInvalidState(target);\n } else if (isFieldTarget(target)) {\n target.classList.add('is-invalid');\n target.setAttribute(INVALID_TARGET_ATTRIBUTE, 'true');\n }\n\n return Promise.resolve();\n}\n\n/**\n * 管理対象のメッセージを削除する。\n *\n * @param parentOrTarget 削除対象の親要素または対象要素。\n * @return 完了時に解決される Promise。\n */\nexport function clearManagedMessages(parentOrTarget: HTMLElement): Promise<void> {\n if (isChoiceInput(parentOrTarget)) {\n const hostElement = isRadioInput(parentOrTarget)\n ? resolveRadioMessageHost(parentOrTarget)\n : resolveChoiceMessageHost(parentOrTarget);\n const ownedContainer = hostElement ? getDirectOwnedContainer(hostElement) : undefined;\n ownedContainer?.remove();\n clearChoiceInvalidState(parentOrTarget);\n } else if (isFieldTarget(parentOrTarget)) {\n const nextElement = parentOrTarget.nextElementSibling;\n if (\n nextElement instanceof HTMLElement &&\n nextElement.getAttribute(CONTAINER_ATTRIBUTE) === 'true'\n ) {\n nextElement.remove();\n }\n removeOwnedInvalidState(parentOrTarget);\n }\n\n const ownedContainers = parentOrTarget.querySelectorAll<HTMLElement>(\n `[${CONTAINER_ATTRIBUTE}=\"true\"]`,\n );\n ownedContainers.forEach((element) => {\n element.remove();\n });\n\n const invalidTargets = parentOrTarget.querySelectorAll<HTMLElement>(\n `[${INVALID_TARGET_ATTRIBUTE}=\"true\"]`,\n );\n invalidTargets.forEach((element) => {\n removeOwnedInvalidState(element);\n });\n\n return Promise.resolve();\n}\n","import { createModalInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\n/**\n * 既存要素を Bootstrap Modal として扱える最低限の属性へ整える。\n *\n * @param element 整形対象の要素。\n * @return 戻り値はない。\n */\nfunction prepareModalElement(element: HTMLElement): void {\n if (!element.classList.contains('modal')) {\n element.classList.add('modal');\n }\n\n if (element.tabIndex < 0) {\n element.tabIndex = -1;\n }\n\n if (!element.hasAttribute('aria-hidden')) {\n element.setAttribute('aria-hidden', 'true');\n }\n}\n\n/**\n * 任意要素を Bootstrap Modal として開く。\n *\n * @param element 開く対象の要素。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function openDialogElement(\n element: HTMLElement,\n options: ResolvedInstallOptions,\n): Promise<void> {\n prepareModalElement(element);\n const modalInstance = createModalInstance(element, undefined, options.bootstrap);\n if (!modalInstance) {\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n modalInstance.show();\n return Promise.resolve();\n}\n\n/**\n * 任意要素を Bootstrap Modal として閉じる。\n *\n * @param element 閉じる対象の要素。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function closeDialogElement(\n element: HTMLElement,\n options: ResolvedInstallOptions,\n): Promise<void> {\n prepareModalElement(element);\n const modalInstance = createModalInstance(element, undefined, options.bootstrap);\n if (!modalInstance) {\n return Promise.reject(new Error('Bootstrap Modal is unavailable.'));\n }\n\n modalInstance.hide();\n return Promise.resolve();\n}\n","import { createToastInstance } from './bootstrap_resolver';\nimport type { ResolvedInstallOptions } from './types';\n\nconst TOAST_CONTAINER_ATTRIBUTE = 'data-haori-bootstrap-toast-container';\nconst TOAST_ATTRIBUTE = 'data-haori-bootstrap-toast';\nconst TOAST_ACCENT_ATTRIBUTE = 'data-haori-bootstrap-toast-accent';\n\ninterface ToastAppearance {\n accentClassName: string;\n}\n\n/**\n * 通知レベルを toast 表示用の見た目へ変換する。\n *\n * @param level 通知レベル。\n * @return 対応する見た目定義。\n */\nfunction resolveToastAppearance(level?: string): ToastAppearance {\n switch (level) {\n case 'warning':\n return { accentClassName: 'bg-warning' };\n case 'error':\n return { accentClassName: 'bg-danger' };\n default:\n return { accentClassName: 'bg-info' };\n }\n}\n\n/**\n * toast コンテナを配置する親要素を解決する。\n *\n * @param documentObject 検索に使用する document。\n * @param options 解決済み導入設定。\n * @return 配置先の要素。\n */\nfunction resolveToastRoot(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n if (options.toastContainerSelector) {\n const resolvedElement = documentObject.querySelector<HTMLElement>(options.toastContainerSelector);\n if (resolvedElement) {\n return resolvedElement;\n }\n }\n\n return documentObject.body;\n}\n\n/**\n * toast コンテナを取得または生成する。\n *\n * @param documentObject 生成に使用する document。\n * @param options 解決済み導入設定。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureToastContainer(documentObject: Document, options: ResolvedInstallOptions): HTMLElement {\n const rootElement = resolveToastRoot(documentObject, options);\n const existingContainer = rootElement.querySelector<HTMLElement>(\n `[${TOAST_CONTAINER_ATTRIBUTE}=\"true\"]`,\n );\n if (existingContainer) {\n return existingContainer;\n }\n\n const container = documentObject.createElement('div');\n container.className = 'toast-container position-fixed bottom-0 end-0 p-3';\n container.setAttribute(TOAST_CONTAINER_ATTRIBUTE, 'true');\n rootElement.appendChild(container);\n return container;\n}\n\n/**\n * Bootstrap Toast を表示する。\n *\n * @param message 表示するメッセージ。\n * @param level 通知レベル。\n * @param options 解決済み導入設定。\n * @return 完了時に解決される Promise。\n */\nexport function showToast(\n message: string,\n level: string | undefined,\n options: ResolvedInstallOptions,\n): Promise<void> {\n const documentObject = globalThis.document;\n const appearance = resolveToastAppearance(level);\n const toastElement = documentObject.createElement('div');\n toastElement.className = 'toast border bg-body text-body shadow-sm';\n toastElement.setAttribute('role', 'status');\n toastElement.setAttribute('aria-live', 'polite');\n toastElement.setAttribute('aria-atomic', 'true');\n toastElement.setAttribute(TOAST_ATTRIBUTE, 'true');\n\n const bodyWrapper = documentObject.createElement('div');\n bodyWrapper.className = 'd-flex align-items-stretch';\n\n const accentElement = documentObject.createElement('div');\n accentElement.className = `flex-shrink-0 rounded-start ${appearance.accentClassName}`;\n accentElement.style.width = '0.375rem';\n accentElement.setAttribute(TOAST_ACCENT_ATTRIBUTE, 'true');\n\n const bodyElement = documentObject.createElement('div');\n bodyElement.className = 'toast-body';\n bodyElement.style.whiteSpace = 'pre-line';\n bodyElement.textContent = message;\n\n bodyWrapper.appendChild(accentElement);\n bodyWrapper.appendChild(bodyElement);\n toastElement.appendChild(bodyWrapper);\n ensureToastContainer(documentObject, options).appendChild(toastElement);\n\n const toastInstance = createToastInstance(toastElement, options.bootstrap);\n if (!toastInstance) {\n toastElement.remove();\n return Promise.reject(new Error('Bootstrap Toast is unavailable.'));\n }\n\n toastElement.addEventListener(\n 'hidden.bs.toast',\n () => {\n toastElement.remove();\n toastInstance.dispose?.();\n },\n { once: true },\n );\n\n try {\n toastInstance.show();\n return Promise.resolve();\n } catch (error) {\n toastElement.remove();\n toastInstance.dispose?.();\n return Promise.reject(error);\n }\n}\n","import { hasModalSupport, hasToastSupport } from './bootstrap_resolver';\nimport { showConfirm, showDialog } from './dialog';\nimport { addManagedErrorMessage, clearManagedMessages } from './message';\nimport { closeDialogElement, openDialogElement } from './modal';\nimport { showToast } from './toast';\nimport type { HaoriGlobalObject, ResolvedInstallOptions } from './types';\n\n/**\n * BootstrapHaori が利用する内部コンテキスト。\n */\nexport interface BootstrapHaoriContext {\n /** 差し替え前の Haori 実装。 */\n originalHaori?: HaoriGlobalObject;\n /** 解決済みの導入設定。 */\n options: ResolvedInstallOptions;\n}\n\nconst defaultContext: BootstrapHaoriContext = {\n options: {\n fallbackToNative: true,\n },\n};\n\nlet context = defaultContext;\n\n/**\n * 表示用 message 中のエスケープ済み改行を実際の改行へ正規化する。\n *\n * @param message 正規化対象のメッセージ。\n * @return 正規化後のメッセージ。\n */\nfunction normalizeMessageText(message: string): string {\n return message.replace(/\\\\n/g, '\\n');\n}\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): Window | undefined {\n const scope = globalThis as typeof globalThis & { window?: Window };\n return scope.window;\n}\n\n/**\n * 値を Promise<void> 契約へ正規化する。\n *\n * @param value 正規化対象の値。\n * @return 完了時に解決される Promise。\n */\nfunction toPromiseVoid(value: Promise<void> | void | unknown): Promise<void> {\n return Promise.resolve(value).then(() => undefined);\n}\n\n/**\n * 元の Haori 実装から対象メソッドを取得する。\n *\n * @param methodName 取得対象のメソッド名。\n * @return 対象メソッド。見つからない場合は undefined。\n */\nfunction getOriginalMethod(\n methodName: keyof HaoriGlobalObject,\n): ((...args: readonly unknown[]) => unknown) | undefined {\n const method = context.originalHaori?.[methodName];\n return typeof method === 'function'\n ? (method as (...args: readonly unknown[]) => unknown)\n : undefined;\n}\n\n/**\n * no-op に正規化したことを警告する。\n *\n * @param apiName 利用できなかった API 名。\n * @return 戻り値はない。\n */\nfunction warnNoop(apiName: string): void {\n console.warn(`[haori-bootstrap] ${apiName} skipped because Bootstrap support is unavailable.`);\n}\n\n/**\n * dialog の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackDialog(message: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('dialog');\n if (originalMethod) {\n return toPromiseVoid(originalMethod(normalizedMessage));\n }\n\n const browserWindow = getBrowserWindow();\n if (context.options.fallbackToNative && typeof browserWindow?.alert === 'function') {\n browserWindow.alert(normalizedMessage);\n return Promise.resolve();\n }\n\n warnNoop('dialog');\n return Promise.resolve();\n}\n\n/**\n * confirm の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @return 確認結果を返す Promise。\n */\nfunction fallbackConfirm(message: string): Promise<boolean> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('confirm');\n if (originalMethod) {\n return Promise.resolve(originalMethod(normalizedMessage) as Promise<boolean> | boolean).then(\n (value) => Boolean(value),\n );\n }\n\n const browserWindow = getBrowserWindow();\n if (context.options.fallbackToNative && typeof browserWindow?.confirm === 'function') {\n return Promise.resolve(browserWindow.confirm(normalizedMessage));\n }\n\n warnNoop('confirm');\n return Promise.resolve(false);\n}\n\n/**\n * toast の fallback 経路を処理する。\n *\n * @param message 表示対象のメッセージ。\n * @param level 通知レベル。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackToast(message: string, level?: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n const originalMethod = getOriginalMethod('toast');\n if (originalMethod) {\n return toPromiseVoid(originalMethod(normalizedMessage, level));\n }\n\n warnNoop('toast');\n return Promise.resolve();\n}\n\n/**\n * openDialog または closeDialog の fallback 経路を処理する。\n *\n * @param methodName 呼び出す API 名。\n * @param element 対象要素。\n * @return 完了時に解決される Promise。\n */\nfunction fallbackModal(methodName: 'openDialog' | 'closeDialog', element: HTMLElement): Promise<void> {\n const originalMethod = getOriginalMethod(methodName);\n if (originalMethod) {\n return toPromiseVoid(originalMethod(element));\n }\n\n warnNoop(methodName);\n return Promise.resolve();\n}\n\n/**\n * BootstrapHaori が参照する内部状態を更新する。\n *\n * @param nextContext 差し替え先が参照する内部コンテキスト。\n * @return 戻り値はない。\n */\nexport function setBootstrapHaoriContext(nextContext: BootstrapHaoriContext): void {\n context = nextContext;\n}\n\n/**\n * Haori の UI 系静的メソッドを差し替える最小ファサード。\n */\nexport class BootstrapHaori {\n /**\n * 情報表示ダイアログを表示する。\n *\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\n public static dialog(message: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasModalSupport(context.options.bootstrap)) {\n return showDialog(normalizedMessage, context.options).catch(() => fallbackDialog(normalizedMessage));\n }\n\n return fallbackDialog(normalizedMessage);\n }\n\n /**\n * 確認ダイアログを表示する。\n *\n * @param message 表示するメッセージ。\n * @return OK のみ true を返す Promise。\n */\n public static confirm(message: string): Promise<boolean> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasModalSupport(context.options.bootstrap)) {\n return showConfirm(normalizedMessage, context.options).catch(() => fallbackConfirm(normalizedMessage));\n }\n\n return fallbackConfirm(normalizedMessage);\n }\n\n /**\n * トースト通知を表示する。\n *\n * @param message 表示するメッセージ。\n * @param level 通知レベル。\n * @return 完了時に解決される Promise。\n */\n public static toast(message: string, level?: string): Promise<void> {\n const normalizedMessage = normalizeMessageText(message);\n if (hasToastSupport(context.options.bootstrap)) {\n return showToast(normalizedMessage, level, context.options).catch(() =>\n fallbackToast(normalizedMessage, level),\n );\n }\n\n return fallbackToast(normalizedMessage, level);\n }\n\n /**\n * 任意のダイアログ要素を開く。\n *\n * @param element 開く対象の要素。\n * @return 完了時に解決される Promise。\n */\n public static openDialog(element: HTMLElement): Promise<void> {\n if (hasModalSupport(context.options.bootstrap)) {\n return openDialogElement(element, context.options).catch(() =>\n fallbackModal('openDialog', element),\n );\n }\n\n return fallbackModal('openDialog', element);\n }\n\n /**\n * 任意のダイアログ要素を閉じる。\n *\n * @param element 閉じる対象の要素。\n * @return 完了時に解決される Promise。\n */\n public static closeDialog(element: HTMLElement): Promise<void> {\n if (hasModalSupport(context.options.bootstrap)) {\n return closeDialogElement(element, context.options).catch(() =>\n fallbackModal('closeDialog', element),\n );\n }\n\n return fallbackModal('closeDialog', element);\n }\n\n /**\n * 管理対象のエラーメッセージを追加する。\n *\n * @param target 追加先の要素。\n * @param message 表示するメッセージ。\n * @return 完了時に解決される Promise。\n */\n public static addErrorMessage(target: HTMLElement, message: string): Promise<void> {\n return addManagedErrorMessage(target, message);\n }\n\n /**\n * 管理対象のメッセージを削除する。\n *\n * @param parentOrTarget 削除対象の親要素または対象要素。\n * @return 完了時に解決される Promise。\n */\n public static clearMessages(parentOrTarget: HTMLElement): Promise<void> {\n return clearManagedMessages(parentOrTarget);\n }\n}\n","import { BootstrapHaori, setBootstrapHaoriContext } from './bootstrap_haori';\nimport type {\n BrowserWindow,\n HaoriGlobalObject,\n InstallOptions,\n ResolvedInstallOptions,\n} from './types';\n\nconst DEFAULT_INSTALL_OPTIONS: ResolvedInstallOptions = {\n fallbackToNative: true,\n};\n\nconst installState: {\n installed: boolean;\n originalHaori?: HaoriGlobalObject;\n options: ResolvedInstallOptions;\n} = {\n installed: false,\n options: DEFAULT_INSTALL_OPTIONS,\n};\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): BrowserWindow | undefined {\n const scope = globalThis as typeof globalThis & { window?: BrowserWindow };\n return scope.window;\n}\n\n/**\n * install に渡された設定を既定値込みで解決する。\n *\n * @param options 指定された導入設定。\n * @param browserWindow 現在の window。\n * @return 解決済みの導入設定。\n */\nfunction resolveInstallOptions(\n options: InstallOptions,\n browserWindow: BrowserWindow | undefined,\n): ResolvedInstallOptions {\n return {\n bootstrap: options.bootstrap ?? browserWindow?.bootstrap,\n fallbackToNative: options.fallbackToNative ?? DEFAULT_INSTALL_OPTIONS.fallbackToNative,\n runtime:\n options.runtime ?? installState.options.runtime ?? browserWindow?.Haori?.runtime,\n toastContainerSelector: options.toastContainerSelector,\n dialogContainerSelector: options.dialogContainerSelector,\n };\n}\n\n/**\n * 自動有効化に必要な前提が揃っているかを返す。\n *\n * @param browserWindow 判定対象の window。\n * @return 自動有効化可能なら true。\n */\nexport function hasAutoEnablePrerequisites(\n browserWindow: BrowserWindow | undefined = getBrowserWindow(),\n): boolean {\n return Boolean(browserWindow?.Haori && browserWindow.bootstrap);\n}\n\n/**\n * Bootstrap 対応 Haori を再適用し、必要なら設定を上書きする。\n *\n * @param options 上書きする導入設定。\n * @return 戻り値はない。\n */\nexport function install(options: InstallOptions = {}): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow?.Haori) {\n throw new Error('window.Haori is required before calling install().');\n }\n\n if (!installState.originalHaori) {\n installState.originalHaori = browserWindow.Haori;\n }\n\n installState.options = resolveInstallOptions(options, browserWindow);\n if (\n installState.options.runtime &&\n typeof browserWindow.Haori.setRuntime === 'function'\n ) {\n browserWindow.Haori.setRuntime(installState.options.runtime);\n }\n setBootstrapHaoriContext({\n originalHaori: installState.originalHaori,\n options: installState.options,\n });\n browserWindow.Haori = BootstrapHaori as unknown as HaoriGlobalObject;\n installState.installed = true;\n}\n\n/**\n * 元の Haori 実装を復元する。\n *\n * @return 戻り値はない。\n */\nexport function uninstall(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow || !installState.originalHaori) {\n return;\n }\n\n browserWindow.Haori = installState.originalHaori;\n installState.installed = false;\n installState.originalHaori = undefined;\n}\n\n/**\n * 現在 BootstrapHaori が有効かどうかを返す。\n *\n * @return 有効なら true。\n */\nexport function isInstalled(): boolean {\n return installState.installed;\n}\n","import { hasAutoEnablePrerequisites, install } from './install';\nimport type { BrowserWindow } from './types';\n\nconst AUTO_ENABLE_MARKER = '__haoriJsBootstrapAutoEnabled__';\n\n/**\n * 現在のブラウザ window を取得する。\n *\n * @return 現在の window。存在しない場合は undefined。\n */\nfunction getBrowserWindow(): BrowserWindow | undefined {\n const scope = globalThis as typeof globalThis & { window?: BrowserWindow };\n return scope.window;\n}\n\n/**\n * 既に自動有効化済みかどうかを返す。\n *\n * @param browserWindow 判定対象の window。\n * @return 既に自動有効化済みなら true。\n */\nfunction wasAutoEnabled(browserWindow: BrowserWindow): boolean {\n return Boolean((browserWindow as unknown as Record<string, unknown>)[AUTO_ENABLE_MARKER]);\n}\n\n/**\n * 自動有効化済みの印を付ける。\n *\n * @param browserWindow 更新対象の window。\n * @return 戻り値はない。\n */\nfunction markAutoEnabled(browserWindow: BrowserWindow): void {\n (browserWindow as unknown as Record<string, unknown>)[AUTO_ENABLE_MARKER] = true;\n}\n\n/**\n * 前提が揃っていれば自動有効化を試行する。\n *\n * @return 戻り値はない。\n */\nfunction autoEnable(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow || wasAutoEnabled(browserWindow)) {\n return;\n }\n\n if (!hasAutoEnablePrerequisites(browserWindow)) {\n console.warn(\n '[haori-bootstrap] Auto-enable skipped because window.Haori or window.bootstrap is missing.',\n );\n return;\n }\n\n try {\n install({ bootstrap: browserWindow.bootstrap });\n markAutoEnabled(browserWindow);\n } catch (error) {\n console.warn('[haori-bootstrap] Auto-enable failed.', error);\n }\n}\n\nautoEnable();\n","import './browser';\n\nexport { BootstrapHaori } from './bootstrap_haori';\nexport { hasAutoEnablePrerequisites, install, isInstalled, uninstall } from './install';\nexport type {\n BootstrapNamespace,\n BrowserWindow,\n HaoriBootstrapGlobal,\n HaoriGlobalObject,\n InstallOptions,\n ResolvedInstallOptions,\n} from './types';\n\n/**\n * パッケージの公開版数。\n */\nexport const version = '0.3.0';\n"],"names":["isConstructor","value","resolveModalConstructor","bootstrap","resolveToastConstructor","hasModalSupport","hasToastSupport","createModalInstance","element","options","modalConstructor","createToastInstance","toastConstructor","DIALOG_CONTAINER_ATTRIBUTE","ACTION_ATTRIBUTE","createDialogModalOptions","resolveDialogContainer","documentObject","resolvedElement","createModalShell","message","isConfirm","modalElement","dialogElement","contentElement","bodyElement","messageElement","footerElement","cancelButton","okButton","showDialog","modalInstance","resolve","reject","finalize","handleHidden","error","showConfirm","confirmed","OWNED_ATTRIBUTE","CONTAINER_ATTRIBUTE","INVALID_TARGET_ATTRIBUTE","isChoiceInput","target","isRadioInput","isFieldTarget","getDirectOwnedContainer","createMessageItem","getOwnedDirectChild","getRadioGroupTargets","rootNode","escapedName","groupTargets","findCommonAncestor","elements","firstElement","restElements","candidate","resolveRadioMessageHost","wrappers","commonAncestor","resolveChoiceMessageHost","closestFormCheck","ensureFieldContainer","nextElement","container","ensureChoiceContainer","hostElement","existingContainer","ensureBlockContainer","removeOwnedInvalidState","markChoiceInvalidState","clearChoiceInvalidState","addManagedErrorMessage","clearManagedMessages","parentOrTarget","prepareModalElement","openDialogElement","closeDialogElement","TOAST_CONTAINER_ATTRIBUTE","TOAST_ATTRIBUTE","TOAST_ACCENT_ATTRIBUTE","resolveToastAppearance","level","resolveToastRoot","ensureToastContainer","rootElement","showToast","appearance","toastElement","bodyWrapper","accentElement","toastInstance","defaultContext","context","normalizeMessageText","getBrowserWindow","toPromiseVoid","getOriginalMethod","methodName","method","warnNoop","apiName","fallbackDialog","normalizedMessage","originalMethod","browserWindow","fallbackConfirm","fallbackToast","fallbackModal","setBootstrapHaoriContext","nextContext","BootstrapHaori","DEFAULT_INSTALL_OPTIONS","installState","resolveInstallOptions","hasAutoEnablePrerequisites","install","uninstall","isInstalled","AUTO_ENABLE_MARKER","wasAutoEnabled","markAutoEnabled","autoEnable","version"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,4 +4,4 @@ export type { BootstrapNamespace, BrowserWindow, HaoriBootstrapGlobal, HaoriGlob
4
4
  /**
5
5
  * パッケージの公開版数。
6
6
  */
7
- export declare const version = "0.2.0";
7
+ export declare const version = "0.3.0";
package/dist/types.d.ts CHANGED
@@ -79,6 +79,8 @@ export interface InstallOptions {
79
79
  bootstrap?: BootstrapNamespace;
80
80
  /** Bootstrap 利用不可時に元の Haori へ委譲するか。 */
81
81
  fallbackToNative?: boolean;
82
+ /** Haori の実行モード。 */
83
+ runtime?: 'embedded' | 'demo';
82
84
  /** Toast 配置先セレクター。 */
83
85
  toastContainerSelector?: string;
84
86
  /** Dialog 配置先セレクター。 */
@@ -92,6 +94,8 @@ export interface ResolvedInstallOptions {
92
94
  bootstrap?: BootstrapNamespace;
93
95
  /** Bootstrap 利用不可時に元の Haori へ委譲するか。 */
94
96
  fallbackToNative: boolean;
97
+ /** Haori の実行モード。 */
98
+ runtime?: 'embedded' | 'demo';
95
99
  /** Toast 配置先セレクター。 */
96
100
  toastContainerSelector?: string;
97
101
  /** Dialog 配置先セレクター。 */
@@ -102,6 +106,10 @@ export interface ResolvedInstallOptions {
102
106
  */
103
107
  export interface HaoriGlobalObject {
104
108
  [key: string]: unknown;
109
+ /** 現在の実行モード。 */
110
+ runtime?: 'embedded' | 'demo';
111
+ /** 実行モードを設定する。 */
112
+ setRuntime?: (runtime: string) => void;
105
113
  dialog?: (message: string) => Promise<void> | void;
106
114
  confirm?: (message: string) => Promise<boolean> | boolean;
107
115
  toast?: (message: string, level?: string) => Promise<void> | void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haori-bootstrap",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Bootstrap-based UI extension library for Haori.js.",
5
5
  "type": "module",
6
6
  "main": "./dist/haori-bootstrap.js",
@@ -20,11 +20,8 @@
20
20
  "scripts": {
21
21
  "dev": "vite",
22
22
  "build": "vite build",
23
- "predev:demo": "npm run build",
24
23
  "dev:demo": "vite --config demo/vite.config.ts",
25
- "prebuild:demo": "npm run build",
26
24
  "build:demo": "vite build --config demo/vite.config.ts",
27
- "prepreview:demo": "npm run build:demo",
28
25
  "preview:demo": "vite preview --config demo/vite.config.ts",
29
26
  "test": "vitest run",
30
27
  "pretest:e2e": "npm run build",
@@ -38,7 +35,7 @@
38
35
  "format:check": "prettier --check \"{src,tests,demo}/**/*.{ts,js,json,html}\"",
39
36
  "type-check": "tsc --noEmit",
40
37
  "compile": "npm run type-check",
41
- "version": "node ./scripts/sync-version.mjs && git add src/index.ts package.json package-lock.json",
38
+ "version": "node ./scripts/sync-version.mjs && git add src/index.ts README.md README.ja.md demo/cdn.html demo/cdn.js playwright/demo.spec.ts package.json package-lock.json",
42
39
  "preview": "vite preview"
43
40
  },
44
41
  "repository": {