haori-bootstrap 0.3.0 → 0.3.1

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.3.0
5
+ Version: 0.3.1
6
6
 
7
7
  ## 概要
8
8
 
@@ -43,7 +43,7 @@ npm install haori-bootstrap
43
43
  />
44
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.3.0/dist/haori-bootstrap.iife.js"></script>
46
+ <script src="https://cdn.jsdelivr.net/npm/haori-bootstrap@0.3.1/dist/haori-bootstrap.iife.js"></script>
47
47
  ```
48
48
 
49
49
  IIFE 版は、window.Haori と window.bootstrap が利用可能な場合に自動で有効化されます。
@@ -77,10 +77,18 @@ install({
77
77
  | openDialog(element) | 任意要素の表示 | Promise<void> |
78
78
  | closeDialog(element) | 任意要素の非表示 | Promise<void> |
79
79
  | addErrorMessage(target, message) | 管理対象エラーメッセージの追加 | Promise<void> |
80
+ | addMessage(target, message, level?) | レベル付き管理対象メッセージを追加(`'error'` \| `'success'` \| `'warning'` \| `'info'`)。再呼び出し時は Bootstrap 検証クラス(`is-invalid` / `is-valid`)も切り替わります。 | Promise<void> |
80
81
  | clearMessages(parentOrTarget) | 管理対象メッセージのみ削除 | Promise<void> |
81
82
  | install(options) | Bootstrap 対応 Haori を再適用し、runtime を含めて設定を上書き | void |
82
83
  | uninstall() | 元の Haori 実装を復元 | void |
83
84
 
85
+ ### install オプション
86
+
87
+ | オプション | 型 | デフォルト | 説明 |
88
+ | ---- | ---- | ---- | ---- |
89
+ | toastPosition | `'top-start' \| 'top-center' \| 'top-end' \| 'bottom-start' \| 'bottom-center' \| 'bottom-end'` | `'bottom-end'` | トーストコンテナの表示位置。変更は次のトースト表示時に反映されます。 |
90
+ | toastDelay | `number` | Bootstrap デフォルト (5000ms) | トースト通知の自動非表示までの時間 (ms)。 |
91
+
84
92
  ## Procedure 連携例
85
93
 
86
94
  既存の Procedure は、data-click-* と data-click-*-message をそのまま利用できます。
@@ -151,12 +159,12 @@ git push origin main --follow-tags
151
159
  - npm アカウントで 2FA を有効化している場合は、write 操作用の bypass 2FA を有効にした token を使います。
152
160
  - `NPM_TOKEN` の作成に、パッケージの事前公開は不要です。
153
161
 
154
- 名称変更後の初回 `0.3.0` 公開の例:
162
+ 名称変更後の初回 `0.3.1` 公開の例:
155
163
 
156
164
  ```bash
157
165
  git push origin main
158
- git tag 0.3.0
159
- git push origin 0.3.0
166
+ git tag 0.3.1
167
+ git push origin 0.3.1
160
168
  ```
161
169
 
162
170
  初回公開チェックリスト:
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.3.0
5
+ Version: 0.3.1
6
6
 
7
7
  ## Overview
8
8
 
@@ -43,7 +43,7 @@ Load dependencies in this order for browser direct loading:
43
43
  />
44
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.3.0/dist/haori-bootstrap.iife.js"></script>
46
+ <script src="https://cdn.jsdelivr.net/npm/haori-bootstrap@0.3.1/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.
@@ -77,10 +77,18 @@ install({
77
77
  | openDialog(element) | Open an arbitrary dialog element | Promise<void> |
78
78
  | closeDialog(element) | Close an arbitrary dialog element | Promise<void> |
79
79
  | addErrorMessage(target, message) | Append managed error messages | Promise<void> |
80
+ | addMessage(target, message, level?) | Append a level-aware managed message (`'error'` \| `'success'` \| `'warning'` \| `'info'`). Switches Bootstrap validation classes (`is-invalid` / `is-valid`) on re-call. | Promise<void> |
80
81
  | clearMessages(parentOrTarget) | Remove only managed messages | Promise<void> |
81
82
  | install(options) | Re-apply Bootstrap-backed Haori with overridden options, including runtime | void |
82
83
  | uninstall() | Restore the original Haori implementation | void |
83
84
 
85
+ ### install options
86
+
87
+ | Option | Type | Default | Description |
88
+ | ---- | ---- | ---- | ---- |
89
+ | toastPosition | `'top-start' \| 'top-center' \| 'top-end' \| 'bottom-start' \| 'bottom-center' \| 'bottom-end'` | `'bottom-end'` | Toast container position. The new position takes effect the next time a toast is shown. |
90
+ | toastDelay | `number` | Bootstrap default (5000ms) | Auto-hide delay in milliseconds for toast notifications. |
91
+
84
92
  ## Procedure Integration Example
85
93
 
86
94
  Existing Procedure flows can keep using data-click-* and data-click-*-message attributes.
@@ -128,15 +136,15 @@ git push origin main --follow-tags
128
136
 
129
137
  After pushing, publish a GitHub Release from the generated version tag. The release workflow then publishes the package and uploads `dist.zip` automatically.
130
138
 
131
- Example next patch release after `0.3.0`:
139
+ Example next patch release after `0.3.1`:
132
140
 
133
141
  ```bash
134
- # version becomes 0.3.1
142
+ # version becomes 0.3.2
135
143
  npm version patch
136
144
  git push origin main --follow-tags
137
145
  ```
138
146
 
139
- Create and publish the GitHub Release for the pushed tag such as `0.3.1`.
147
+ Create and publish the GitHub Release for the pushed tag such as `0.3.2`.
140
148
 
141
149
  Release automation:
142
150
 
@@ -151,12 +159,12 @@ First release only:
151
159
  - If npm account 2FA is enabled, create the token with bypass 2FA for write actions.
152
160
  - The package does not need to be published already to create `NPM_TOKEN`.
153
161
 
154
- Example for the first `0.3.0` release after the package rename:
162
+ Example for the first `0.3.1` release after the package rename:
155
163
 
156
164
  ```bash
157
165
  git push origin main
158
- git tag 0.3.0
159
- git push origin 0.3.0
166
+ git tag 0.3.1
167
+ git push origin 0.3.1
160
168
  ```
161
169
 
162
170
  First release checklist:
@@ -63,6 +63,15 @@ export declare class BootstrapHaori {
63
63
  * @return 完了時に解決される Promise。
64
64
  */
65
65
  static addErrorMessage(target: HTMLElement, message: string): Promise<void>;
66
+ /**
67
+ * 管理対象のメッセージをレベル付きで追加する。
68
+ *
69
+ * @param target 追加先の要素。
70
+ * @param message 表示するメッセージ。
71
+ * @param level メッセージレベル (error / success / warning / info)。省略時は error。
72
+ * @return 完了時に解決される Promise。
73
+ */
74
+ static addMessage(target: HTMLElement, message: string, level?: string): Promise<void>;
66
75
  /**
67
76
  * 管理対象のメッセージを削除する。
68
77
  *
@@ -1,4 +1,4 @@
1
- import { BootstrapModalConstructor, BootstrapModalInstance, BootstrapModalOptions, BootstrapNamespace, BootstrapToastConstructor, BootstrapToastInstance } from './types';
1
+ import { BootstrapModalConstructor, BootstrapModalInstance, BootstrapModalOptions, BootstrapNamespace, BootstrapToastConstructor, BootstrapToastInstance, BootstrapToastOptions } from './types';
2
2
  /**
3
3
  * Bootstrap の Modal コンストラクターを返す。
4
4
  *
@@ -39,7 +39,8 @@ export declare function createModalInstance(element: HTMLElement, options?: Boot
39
39
  * Toast インスタンスを取得または生成する。
40
40
  *
41
41
  * @param element 対象要素。
42
+ * @param toastOptions Toast 設定。
42
43
  * @param bootstrap Bootstrap 名前空間。
43
44
  * @return Toast インスタンス。生成できない場合は undefined。
44
45
  */
45
- export declare function createToastInstance(element: HTMLElement, bootstrap?: BootstrapNamespace): BootstrapToastInstance | undefined;
46
+ export declare function createToastInstance(element: HTMLElement, toastOptions?: BootstrapToastOptions, bootstrap?: BootstrapNamespace): BootstrapToastInstance | undefined;
@@ -1,3 +1,3 @@
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})({});
1
+ var HaoriBootstrap=(function(p){"use strict";function F(e){return typeof e=="function"}function z(e){return F(e?.Modal)?e?.Modal:void 0}function O(e){return F(e?.Toast)?e?.Toast:void 0}function k(e){return!!z(e)}function ue(e){return!!O(e)}function L(e,o,t){const n=z(t);if(n)return typeof n.getOrCreateInstance=="function"?n.getOrCreateInstance(e,o):new n(e,o)}function de(e,o,t){const n=O(t);if(n)return typeof n.getOrCreateInstance=="function"?n.getOrCreateInstance(e,o):new n(e,o)}const fe="data-haori-bootstrap-dialog",w="data-haori-bootstrap-action",me="data-haori-bootstrap-dialog-title";let be=0;function W(){return{backdrop:"static",keyboard:!1}}function G(e,o){if(o.dialogContainerSelector){const t=e.querySelector(o.dialogContainerSelector);if(t)return t}return e.body}function V(e,o,t,n){const r=e.createElement("div");r.className="modal fade",r.tabIndex=-1,r.setAttribute(fe,"true"),r.setAttribute("aria-hidden","true");const i=e.createElement("div");i.className="modal-dialog modal-dialog-centered";const c=e.createElement("div");if(c.className="modal-content",n){const u=`haori-dialog-title-${++be}`,A=e.createElement("div");A.className="modal-header";const M=e.createElement("h5");M.className="modal-title",M.id=u,M.setAttribute(me,"true"),M.textContent=n,A.appendChild(M),c.appendChild(A),r.setAttribute("aria-labelledby",u)}const a=e.createElement("div");a.className="modal-body";const d=e.createElement("p");d.className="mb-0",d.style.whiteSpace="pre-line",d.textContent=o,a.appendChild(d);const l=e.createElement("div");if(l.className="modal-footer",t){const u=e.createElement("button");u.type="button",u.className="btn btn-secondary",u.setAttribute(w,"cancel"),u.textContent="Cancel",l.appendChild(u)}const b=e.createElement("button");return b.type="button",b.className="btn btn-primary",b.setAttribute(w,"ok"),b.textContent="OK",l.appendChild(b),c.append(a,l),i.appendChild(c),r.appendChild(i),r}function pe(e,o){const t=globalThis.document,n=V(t,e,!1,o.dialogTitle);G(t,o).appendChild(n);const r=L(n,W(),o.bootstrap);return r?new Promise((i,c)=>{const a=()=>{n.removeEventListener("hidden.bs.modal",d),n.remove(),r.dispose?.(),i()},d=()=>{a()};n.querySelector(`[${w}="ok"]`)?.addEventListener("click",()=>{r.hide()},{once:!0}),n.addEventListener("hidden.bs.modal",d,{once:!0});try{r.show()}catch(b){n.removeEventListener("hidden.bs.modal",d),n.remove(),r.dispose?.(),c(b)}}):(n.remove(),Promise.reject(new Error("Bootstrap Modal is unavailable.")))}function he(e,o){const t=globalThis.document,n=V(t,e,!0,o.dialogTitle);G(t,o).appendChild(n);const r=L(n,W(),o.bootstrap);return r?new Promise((i,c)=>{let a=!1;const d=()=>{n.removeEventListener("hidden.bs.modal",l),n.remove(),r.dispose?.(),i(a)},l=()=>{d()},b=n.querySelector(`[${w}="ok"]`),u=n.querySelector(`[${w}="cancel"]`);b?.addEventListener("click",()=>{a=!0,r.hide()},{once:!0}),u?.addEventListener("click",()=>{a=!1,r.hide()},{once:!0}),n.addEventListener("hidden.bs.modal",l,{once:!0});try{r.show()}catch(A){n.removeEventListener("hidden.bs.modal",l),n.remove(),r.dispose?.(),c(A)}}):(n.remove(),Promise.reject(new Error("Bootstrap Modal is unavailable.")))}const h="data-haori-bootstrap-owned",m="data-haori-bootstrap-message-container",C="data-haori-bootstrap-invalid-target",y="data-haori-bootstrap-valid-target";function S(e){return e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")}function E(e){return e instanceof HTMLInputElement&&e.type==="radio"}function I(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function B(e){return Array.from(e.children).find(o=>o instanceof HTMLElement&&o.getAttribute(m)==="true")}function j(e,o){const t=e.createElement("div");return t.setAttribute(h,"true"),t.textContent=o,t}function K(e){return B(e)}function N(e){if(e.name){const o=e.form??e.ownerDocument,t=typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(e.name):e.name.replace(/(["\\])/g,"\\$1"),n=Array.from(o.querySelectorAll(`input[type="radio"][name="${t}"]`));if(n.length>0)return n}return[e]}function Ee(e){const[o,...t]=e;if(!o)return;let n=o;for(;n;){if(t.every(r=>n?.contains(r)))return n;n=n.parentElement}}function D(e){const t=N(e).map(n=>n.closest(".form-check")).filter(n=>n instanceof HTMLElement);if(t.length>1){const n=Ee(t);if(n&&!t.includes(n))return n}return H(e)}function H(e){const o=e.closest(".form-check");return o instanceof HTMLElement?o:void 0}function J(e){const o=e.nextElementSibling;if(o instanceof HTMLElement&&o.getAttribute(m)==="true")return o;const t=document.createElement("div");return t.className="invalid-feedback d-block",t.setAttribute(h,"true"),t.setAttribute(m,"true"),e.insertAdjacentElement("afterend",t),t}function ve(e){const o=E(e)?D(e):H(e);if(!o)return J(e);const t=B(o);if(t)return t;const n=document.createElement("div");return n.className="invalid-feedback d-block",n.setAttribute(h,"true"),n.setAttribute(m,"true"),o.appendChild(n),n}function Te(e){const o=K(e);if(o)return o;const t=document.createElement("div");return t.className="alert alert-danger",t.setAttribute("role","alert"),t.setAttribute(h,"true"),t.setAttribute(m,"true"),e.insertAdjacentElement("afterbegin",t),t}function v(e){e.getAttribute(C)==="true"&&(e.classList.remove("is-invalid"),e.removeAttribute(C))}function T(e){e.getAttribute(y)==="true"&&(e.classList.remove("is-valid"),e.removeAttribute(y))}function Q(e){switch(e){case"success":return"alert alert-success";case"warning":return"alert alert-warning";case"info":return"alert alert-info";default:return"alert alert-danger"}}function P(e){return e==="success"?"valid-feedback d-block":"invalid-feedback d-block"}function X(e){(E(e)?N(e):[e]).forEach(t=>{t.classList.add("is-invalid"),t.setAttribute(C,"true")})}function Ae(e){(E(e)?N(e):[e]).forEach(t=>{v(t)})}function Y(e,o){const t=e.nextElementSibling;if(t instanceof HTMLElement&&t.getAttribute(m)==="true")return t.className=P(o),t;const n=document.createElement("div");return n.className=P(o),n.setAttribute(h,"true"),n.setAttribute(m,"true"),e.insertAdjacentElement("afterend",n),n}function Ce(e,o){const t=E(e)?D(e):H(e);if(!t)return Y(e,o);const n=B(t);if(n)return n.className=P(o),n;const r=document.createElement("div");return r.className=P(o),r.setAttribute(h,"true"),r.setAttribute(m,"true"),t.appendChild(r),r}function ge(e,o){const t=K(e);if(t)return t.className=Q(o),t;const n=document.createElement("div");return n.className=Q(o),n.setAttribute("role","alert"),n.setAttribute(h,"true"),n.setAttribute(m,"true"),e.insertAdjacentElement("afterbegin",n),n}function we(e,o){return(S(e)?ve(e):I(e)?J(e):Te(e)).appendChild(j(document,o)),S(e)?X(e):I(e)&&(e.classList.add("is-invalid"),e.setAttribute(C,"true")),Promise.resolve()}function ye(e,o,t){if((S(e)?Ce(e,t):I(e)?Y(e,t):ge(e,t)).appendChild(j(document,o)),S(e)){const r=E(e)?N(e):[e];t==="success"?r.forEach(i=>{v(i),i.classList.add("is-valid"),i.setAttribute(y,"true")}):!t||t==="error"?(r.forEach(i=>T(i)),X(e)):r.forEach(i=>{T(i),v(i)})}else I(e)&&(t==="success"?(v(e),e.classList.add("is-valid"),e.setAttribute(y,"true")):!t||t==="error"?(T(e),e.classList.add("is-invalid"),e.setAttribute(C,"true")):(T(e),v(e)));return Promise.resolve()}function Se(e){if(S(e)){const r=E(e)?D(e):H(e);(r?B(r):void 0)?.remove(),Ae(e),(E(e)?N(e):[e]).forEach(a=>T(a))}else if(I(e)){const r=e.nextElementSibling;r instanceof HTMLElement&&r.getAttribute(m)==="true"&&r.remove(),v(e),T(e)}return e.querySelectorAll(`[${m}="true"]`).forEach(r=>{r.remove()}),e.querySelectorAll(`[${C}="true"]`).forEach(r=>{v(r)}),e.querySelectorAll(`[${y}="true"]`).forEach(r=>{T(r)}),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 Ie(e,o){Z(e);const t=L(e,void 0,o.bootstrap);return t?(t.show(),Promise.resolve()):Promise.reject(new Error("Bootstrap Modal is unavailable."))}function Ne(e,o){Z(e);const t=L(e,void 0,o.bootstrap);return t?(t.hide(),Promise.resolve()):Promise.reject(new Error("Bootstrap Modal is unavailable."))}const ee="data-haori-bootstrap-toast-container",Me="data-haori-bootstrap-toast",ke="data-haori-bootstrap-toast-accent",Le="data-haori-bootstrap-toast-dismiss",te={"top-start":"top-0 start-0","top-center":"top-0 start-50 translate-middle-x","top-end":"top-0 end-0","bottom-start":"bottom-0 start-0","bottom-center":"bottom-0 start-50 translate-middle-x","bottom-end":"bottom-0 end-0"};function Be(e){switch(e){case"success":return{accentClassName:"bg-success"};case"warning":return{accentClassName:"bg-warning"};case"error":return{accentClassName:"bg-danger"};default:return{accentClassName:"bg-info"}}}function He(e,o){if(o.toastContainerSelector){const t=e.querySelector(o.toastContainerSelector);if(t)return t}return e.body}function Pe(e,o){const t=He(e,o),n=te[o.toastPosition??"bottom-end"],r=t.querySelector(`[${ee}="true"]`);if(r){const c=Object.values(te).flatMap(a=>a.split(" "));return r.classList.remove(...c),r.classList.add(...n.split(" ")),r}const i=e.createElement("div");return i.className=`toast-container position-fixed ${n} p-3`,i.setAttribute(ee,"true"),t.appendChild(i),i}function Re(e,o,t){const n=globalThis.document,r=Be(o),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(Me,"true");const c=n.createElement("div");c.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(ke,"true");const d=n.createElement("div");d.className="toast-body",d.style.whiteSpace="pre-line",d.textContent=e;const l=n.createElement("button");l.type="button",l.className="btn-close me-2 m-auto flex-shrink-0",l.setAttribute("aria-label","Close"),l.setAttribute(Le,"true"),c.appendChild(a),c.appendChild(d),c.appendChild(l),i.appendChild(c),Pe(n,t).appendChild(i);const b=t.toastDelay!==void 0?{delay:t.toastDelay}:void 0,u=de(i,b,t.bootstrap);if(!u)return i.remove(),Promise.reject(new Error("Bootstrap Toast is unavailable."));l.addEventListener("click",()=>{u.hide?.()}),i.addEventListener("hidden.bs.toast",()=>{i.remove(),u.dispose?.()},{once:!0});try{return u.show(),Promise.resolve()}catch(A){return i.remove(),u.dispose?.(),Promise.reject(A)}}let f={options:{fallbackToNative:!0}};function g(e){return e.replace(/\\n/g,`
2
+ `)}function oe(){return globalThis.window}function $(e){return Promise.resolve(e).then(()=>{})}function R(e){const o=f.originalHaori?.[e];return typeof o=="function"?o:void 0}function _(e){console.warn(`[haori-bootstrap] ${e} skipped because Bootstrap support is unavailable.`)}function ne(e){const o=g(e),t=R("dialog");if(t)return $(t(o));const n=oe();return f.options.fallbackToNative&&typeof n?.alert=="function"?(n.alert(o),Promise.resolve()):(_("dialog"),Promise.resolve())}function re(e){const o=g(e),t=R("confirm");if(t)return Promise.resolve(t(o)).then(r=>!!r);const n=oe();return f.options.fallbackToNative&&typeof n?.confirm=="function"?Promise.resolve(n.confirm(o)):(_("confirm"),Promise.resolve(!1))}function ie(e,o){const t=g(e),n=R("toast");return n?$(n(t,o)):(_("toast"),Promise.resolve())}function x(e,o){const t=R(e);return t?$(t(o)):(_(e),Promise.resolve())}function _e(e){f=e}class se{static dialog(o){const t=g(o);return k(f.options.bootstrap)?pe(t,f.options).catch(()=>ne(t)):ne(t)}static confirm(o){const t=g(o);return k(f.options.bootstrap)?he(t,f.options).catch(()=>re(t)):re(t)}static toast(o,t){const n=g(o);return ue(f.options.bootstrap)?Re(n,t,f.options).catch(()=>ie(n,t)):ie(n,t)}static openDialog(o){return k(f.options.bootstrap)?Ie(o,f.options).catch(()=>x("openDialog",o)):x("openDialog",o)}static closeDialog(o){return k(f.options.bootstrap)?Ne(o,f.options).catch(()=>x("closeDialog",o)):x("closeDialog",o)}static addErrorMessage(o,t){return we(o,t)}static addMessage(o,t,n){return ye(o,t,n)}static clearMessages(o){return Se(o)}}const q={fallbackToNative:!0},s={installed:!1,options:q};function U(){return globalThis.window}function xe(e,o){return{bootstrap:e.bootstrap??o?.bootstrap,fallbackToNative:e.fallbackToNative??q.fallbackToNative,runtime:e.runtime??s.options.runtime??o?.Haori?.runtime,toastContainerSelector:e.toastContainerSelector??s.options.toastContainerSelector,dialogContainerSelector:e.dialogContainerSelector??s.options.dialogContainerSelector,dialogTitle:e.dialogTitle??s.options.dialogTitle,toastPosition:e.toastPosition??s.options.toastPosition,toastDelay:e.toastDelay??s.options.toastDelay}}function ae(e=U()){return!!(e?.Haori&&e.bootstrap)}function ce(e={}){const o=U();if(!o?.Haori)throw new Error("window.Haori is required before calling install().");if(s.originalHaori||(s.originalHaori=o.Haori,s.originalRuntime=o.Haori.runtime),s.options=xe(e,o),s.options.runtime){const t=s.originalHaori??o.Haori;typeof t.setRuntime=="function"?t.setRuntime(s.options.runtime):console.warn("[haori-bootstrap] Haori.setRuntime が利用できません。runtime 設定は無視されます。")}_e({originalHaori:s.originalHaori,options:s.options}),o.Haori=se,s.installed=!0}function De(){const e=U();!e||!s.originalHaori||(s.originalHaori.runtime=s.originalRuntime,e.Haori=s.originalHaori,s.installed=!1,s.originalHaori=void 0,s.originalRuntime=void 0,s.options=q)}function $e(){return s.installed}const le="__haoriJsBootstrapAutoEnabled__";function qe(){return globalThis.window}function Ue(e){return!!e[le]}function Fe(e){e[le]=!0}function ze(){const e=qe();if(!(!e||Ue(e))){if(!ae(e)){console.warn("[haori-bootstrap] Auto-enable skipped because window.Haori or window.bootstrap is missing.");return}try{ce({bootstrap:e.bootstrap}),Fe(e)}catch(o){console.warn("[haori-bootstrap] Auto-enable failed.",o)}}}ze();const Oe="0.3.1";return p.BootstrapHaori=se,p.hasAutoEnablePrerequisites=ae,p.install=ce,p.isInstalled=$e,p.uninstall=De,p.version=Oe,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"}),p})({});
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 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":"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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 BootstrapToastOptions,\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 toastOptions Toast 設定。\n * @param bootstrap Bootstrap 名前空間。\n * @return Toast インスタンス。生成できない場合は undefined。\n */\nexport function createToastInstance(\n element: HTMLElement,\n toastOptions?: BootstrapToastOptions,\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, toastOptions);\n }\n\n return new toastConstructor(element, toastOptions);\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';\nconst DIALOG_TITLE_ATTRIBUTE = 'data-haori-bootstrap-dialog-title';\n\nlet dialogTitleCounter = 0;\n\n/**\n * dialog 系 modal の既定オプションを返す。\n *\n * @return Bootstrap Modal の生成オプション。\n */\nfunction createDialogModalOptions() {\n return {\n backdrop: 'static' as const,\n keyboard: false,\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 * @param title ヘッダーに表示するタイトル。未指定はヘッダーなし。\n * @return 生成した modal 要素。\n */\nfunction createModalShell(\n documentObject: Document,\n message: string,\n isConfirm: boolean,\n title?: string,\n): 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 if (title) {\n const titleId = `haori-dialog-title-${++dialogTitleCounter}`;\n const headerElement = documentObject.createElement('div');\n headerElement.className = 'modal-header';\n\n const titleElement = documentObject.createElement('h5');\n titleElement.className = 'modal-title';\n titleElement.id = titleId;\n titleElement.setAttribute(DIALOG_TITLE_ATTRIBUTE, 'true');\n titleElement.textContent = title;\n headerElement.appendChild(titleElement);\n\n contentElement.appendChild(headerElement);\n modalElement.setAttribute('aria-labelledby', titleId);\n }\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, options.dialogTitle);\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, options.dialogTitle);\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';\nconst VALID_TARGET_ATTRIBUTE = 'data-haori-bootstrap-valid-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 * このライブラリが付けた is-valid 状態だけを外す。\n *\n * @param target 状態を解除する要素。\n * @return 戻り値はない。\n */\nfunction removeOwnedValidState(target: HTMLElement): void {\n if (target.getAttribute(VALID_TARGET_ATTRIBUTE) !== 'true') {\n return;\n }\n\n target.classList.remove('is-valid');\n target.removeAttribute(VALID_TARGET_ATTRIBUTE);\n}\n\n/**\n * レベルに応じた alert クラスを返す。\n *\n * @param level メッセージレベル。\n * @return 対応する alert クラス文字列。\n */\nfunction resolveBlockAlertClass(level?: string): string {\n switch (level) {\n case 'success':\n return 'alert alert-success';\n case 'warning':\n return 'alert alert-warning';\n case 'info':\n return 'alert alert-info';\n default:\n return 'alert alert-danger';\n }\n}\n\n/**\n * レベルに応じた feedback クラスを返す。\n *\n * @param level メッセージレベル。\n * @return 対応する feedback クラス文字列。\n */\nfunction resolveFieldFeedbackClass(level?: string): string {\n return level === 'success' ? 'valid-feedback d-block' : 'invalid-feedback d-block';\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 level メッセージレベル。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureFieldContainerForLevel(target: HTMLElement, level?: string): HTMLElement {\n const nextElement = target.nextElementSibling;\n if (\n nextElement instanceof HTMLElement &&\n nextElement.getAttribute(CONTAINER_ATTRIBUTE) === 'true'\n ) {\n nextElement.className = resolveFieldFeedbackClass(level);\n return nextElement;\n }\n\n const container = document.createElement('div');\n container.className = resolveFieldFeedbackClass(level);\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n target.insertAdjacentElement('afterend', container);\n return container;\n}\n\n/**\n * レベルに応じた choice 用コンテナを取得または生成する。\n *\n * @param target 対象の input 要素。\n * @param level メッセージレベル。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureChoiceContainerForLevel(target: HTMLInputElement, level?: string): HTMLElement {\n const hostElement = isRadioInput(target)\n ? resolveRadioMessageHost(target)\n : resolveChoiceMessageHost(target);\n if (!hostElement) {\n return ensureFieldContainerForLevel(target, level);\n }\n\n const existingContainer = getDirectOwnedContainer(hostElement);\n if (existingContainer) {\n existingContainer.className = resolveFieldFeedbackClass(level);\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = resolveFieldFeedbackClass(level);\n container.setAttribute(OWNED_ATTRIBUTE, 'true');\n container.setAttribute(CONTAINER_ATTRIBUTE, 'true');\n hostElement.appendChild(container);\n return container;\n}\n\n/**\n * レベルに応じたブロック用コンテナを取得または生成する。\n *\n * @param target 対象要素。\n * @param level メッセージレベル。\n * @return 取得または生成したコンテナ。\n */\nfunction ensureBlockContainerForLevel(target: HTMLElement, level?: string): HTMLElement {\n const existingContainer = getOwnedDirectChild(target);\n if (existingContainer) {\n existingContainer.className = resolveBlockAlertClass(level);\n return existingContainer;\n }\n\n const container = document.createElement('div');\n container.className = resolveBlockAlertClass(level);\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 * 管理対象のエラーメッセージを追加する。\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 target 追加先の要素。\n * @param message 表示するメッセージ。\n * @param level メッセージレベル (error / success / warning / info)。省略時は error。\n * @return 完了時に解決される Promise。\n */\nexport function addManagedMessage(\n target: HTMLElement,\n message: string,\n level?: string,\n): Promise<void> {\n const container = isChoiceInput(target)\n ? ensureChoiceContainerForLevel(target, level)\n : isFieldTarget(target)\n ? ensureFieldContainerForLevel(target, level)\n : ensureBlockContainerForLevel(target, level);\n container.appendChild(createMessageItem(document, message));\n\n if (isChoiceInput(target)) {\n const targets = isRadioInput(target) ? getRadioGroupTargets(target) : [target];\n if (level === 'success') {\n targets.forEach((element) => {\n removeOwnedInvalidState(element);\n element.classList.add('is-valid');\n element.setAttribute(VALID_TARGET_ATTRIBUTE, 'true');\n });\n } else if (!level || level === 'error') {\n targets.forEach((element) => removeOwnedValidState(element));\n markChoiceInvalidState(target);\n } else {\n targets.forEach((element) => {\n removeOwnedValidState(element);\n removeOwnedInvalidState(element);\n });\n }\n } else if (isFieldTarget(target)) {\n if (level === 'success') {\n removeOwnedInvalidState(target);\n target.classList.add('is-valid');\n target.setAttribute(VALID_TARGET_ATTRIBUTE, 'true');\n } else if (!level || level === 'error') {\n removeOwnedValidState(target);\n target.classList.add('is-invalid');\n target.setAttribute(INVALID_TARGET_ATTRIBUTE, 'true');\n } else {\n removeOwnedValidState(target);\n removeOwnedInvalidState(target);\n }\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 const choiceTargets = isRadioInput(parentOrTarget)\n ? getRadioGroupTargets(parentOrTarget)\n : [parentOrTarget];\n choiceTargets.forEach((element) => removeOwnedValidState(element));\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 removeOwnedValidState(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 const validTargets = parentOrTarget.querySelectorAll<HTMLElement>(\n `[${VALID_TARGET_ATTRIBUTE}=\"true\"]`,\n );\n validTargets.forEach((element) => {\n removeOwnedValidState(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, ToastPosition } 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';\nconst TOAST_DISMISS_ATTRIBUTE = 'data-haori-bootstrap-toast-dismiss';\n\ninterface ToastAppearance {\n accentClassName: string;\n}\n\nconst TOAST_POSITION_CLASSES: Record<ToastPosition, string> = {\n 'top-start': 'top-0 start-0',\n 'top-center': 'top-0 start-50 translate-middle-x',\n 'top-end': 'top-0 end-0',\n 'bottom-start': 'bottom-0 start-0',\n 'bottom-center': 'bottom-0 start-50 translate-middle-x',\n 'bottom-end': 'bottom-0 end-0',\n};\n\n/**\n * 通知レベルを toast 表示用の見た目へ変換する。\n *\n * @param level 通知レベル。\n * @return 対応する見た目定義。\n */\nfunction resolveToastAppearance(level?: string): ToastAppearance {\n switch (level) {\n case 'success':\n return { accentClassName: 'bg-success' };\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 positionClasses = TOAST_POSITION_CLASSES[options.toastPosition ?? 'bottom-end'];\n const existingContainer = rootElement.querySelector<HTMLElement>(\n `[${TOAST_CONTAINER_ATTRIBUTE}=\"true\"]`,\n );\n if (existingContainer) {\n const allPositionClasses = Object.values(TOAST_POSITION_CLASSES)\n .flatMap(c => c.split(' '));\n existingContainer.classList.remove(...allPositionClasses);\n existingContainer.classList.add(...positionClasses.split(' '));\n return existingContainer;\n }\n\n const container = documentObject.createElement('div');\n container.className = `toast-container position-fixed ${positionClasses} 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 const dismissButton = documentObject.createElement('button');\n dismissButton.type = 'button';\n dismissButton.className = 'btn-close me-2 m-auto flex-shrink-0';\n dismissButton.setAttribute('aria-label', 'Close');\n dismissButton.setAttribute(TOAST_DISMISS_ATTRIBUTE, 'true');\n\n bodyWrapper.appendChild(accentElement);\n bodyWrapper.appendChild(bodyElement);\n bodyWrapper.appendChild(dismissButton);\n toastElement.appendChild(bodyWrapper);\n ensureToastContainer(documentObject, options).appendChild(toastElement);\n\n const toastOptions = options.toastDelay !== undefined ? { delay: options.toastDelay } : undefined;\n const toastInstance = createToastInstance(toastElement, toastOptions, options.bootstrap);\n if (!toastInstance) {\n toastElement.remove();\n return Promise.reject(new Error('Bootstrap Toast is unavailable.'));\n }\n\n dismissButton.addEventListener('click', () => {\n toastInstance.hide?.();\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, addManagedMessage, 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 target 追加先の要素。\n * @param message 表示するメッセージ。\n * @param level メッセージレベル (error / success / warning / info)。省略時は error。\n * @return 完了時に解決される Promise。\n */\n public static addMessage(target: HTMLElement, message: string, level?: string): Promise<void> {\n return addManagedMessage(target, message, level);\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 originalRuntime?: 'embedded' | 'demo';\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:\n options.toastContainerSelector ?? installState.options.toastContainerSelector,\n dialogContainerSelector:\n options.dialogContainerSelector ?? installState.options.dialogContainerSelector,\n dialogTitle: options.dialogTitle ?? installState.options.dialogTitle,\n toastPosition: options.toastPosition ?? installState.options.toastPosition,\n toastDelay: options.toastDelay ?? installState.options.toastDelay,\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 installState.originalRuntime = browserWindow.Haori.runtime as 'embedded' | 'demo' | undefined;\n }\n\n installState.options = resolveInstallOptions(options, browserWindow);\n if (installState.options.runtime) {\n const targetHaori = installState.originalHaori ?? browserWindow.Haori;\n if (typeof targetHaori.setRuntime === 'function') {\n targetHaori.setRuntime(installState.options.runtime);\n } else {\n console.warn(\n '[haori-bootstrap] Haori.setRuntime が利用できません。runtime 設定は無視されます。',\n );\n }\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 installState.originalHaori.runtime = installState.originalRuntime;\n browserWindow.Haori = installState.originalHaori;\n installState.installed = false;\n installState.originalHaori = undefined;\n installState.originalRuntime = undefined;\n installState.options = DEFAULT_INSTALL_OPTIONS;\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.1';\n"],"names":["isConstructor","value","resolveModalConstructor","bootstrap","resolveToastConstructor","hasModalSupport","hasToastSupport","createModalInstance","element","options","modalConstructor","createToastInstance","toastOptions","toastConstructor","DIALOG_CONTAINER_ATTRIBUTE","ACTION_ATTRIBUTE","DIALOG_TITLE_ATTRIBUTE","dialogTitleCounter","createDialogModalOptions","resolveDialogContainer","documentObject","resolvedElement","createModalShell","message","isConfirm","title","modalElement","dialogElement","contentElement","titleId","headerElement","titleElement","bodyElement","messageElement","footerElement","cancelButton","okButton","showDialog","modalInstance","resolve","reject","finalize","handleHidden","error","showConfirm","confirmed","OWNED_ATTRIBUTE","CONTAINER_ATTRIBUTE","INVALID_TARGET_ATTRIBUTE","VALID_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","removeOwnedValidState","resolveBlockAlertClass","level","resolveFieldFeedbackClass","markChoiceInvalidState","clearChoiceInvalidState","ensureFieldContainerForLevel","ensureChoiceContainerForLevel","ensureBlockContainerForLevel","addManagedErrorMessage","addManagedMessage","targets","clearManagedMessages","parentOrTarget","prepareModalElement","openDialogElement","closeDialogElement","TOAST_CONTAINER_ATTRIBUTE","TOAST_ATTRIBUTE","TOAST_ACCENT_ATTRIBUTE","TOAST_DISMISS_ATTRIBUTE","TOAST_POSITION_CLASSES","resolveToastAppearance","resolveToastRoot","ensureToastContainer","rootElement","positionClasses","allPositionClasses","c","showToast","appearance","toastElement","bodyWrapper","accentElement","dismissButton","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","targetHaori","uninstall","isInstalled","AUTO_ENABLE_MARKER","wasAutoEnabled","markAutoEnabled","autoEnable","version"],"mappings":"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"}