@pybara/pybara-js 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -11
- package/checkout.schema.json +143 -0
- package/dist/admin/core/PybaraAdminClient.d.ts +5 -0
- package/dist/admin/core/PybaraAdminClient.d.ts.map +1 -1
- package/dist/admin/index.d.ts +7 -2
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/{admin-D2vUTEg1.js → admin-B1pVP25-.js} +29 -7
- package/dist/checkout.d.ts +16 -10
- package/dist/checkout.d.ts.map +1 -1
- package/dist/gate.d.ts +13 -7
- package/dist/gate.d.ts.map +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/modal/config.d.ts +19 -0
- package/dist/modal/config.d.ts.map +1 -0
- package/dist/modal/index.d.ts +16 -0
- package/dist/modal/index.d.ts.map +1 -0
- package/dist/modal/index.js +1 -0
- package/dist/modal/lock-page-scroll.d.ts +9 -0
- package/dist/modal/lock-page-scroll.d.ts.map +1 -0
- package/dist/modal/modal.d.ts +160 -0
- package/dist/modal/modal.d.ts.map +1 -0
- package/dist/modal-BCDMoDW9.js +192 -0
- package/dist/pybara-js.iife.js +3 -3
- package/dist/pybara-js.js +177 -325
- package/dist/types.d.ts +16 -7
- package/dist/types.d.ts.map +1 -1
- package/package.json +22 -5
- package/dist/constants.d.ts +0 -13
- package/dist/constants.d.ts.map +0 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CheckoutModal — the merchant page's side of the Pybara checkout.
|
|
3
|
+
*
|
|
4
|
+
* A backdrop and an iframe onto pybara-wallet's checkout frame (mode 2, `/pay?mode=embedded`), where wallet choice, sign-in, token selection, confirmation and the payment itself all happen.
|
|
5
|
+
* This package never touches a wallet, a balance or a price: it opens the frame, posts it the payment data, and reports the outcome.
|
|
6
|
+
*
|
|
7
|
+
* The constructor builds the iframe straight away, hidden, so the frame loads in the background while the buyer is still filling in the form.
|
|
8
|
+
* open() and show() then only reveal an already-loaded frame, at the moment latency matters most.
|
|
9
|
+
*/
|
|
10
|
+
export interface ModalData {
|
|
11
|
+
/** Order or donation total in USD; the frame converts it into whichever token the buyer picks. Left out with a `checkout`, whose amount the frame converts itself. */
|
|
12
|
+
amountUSD?: number;
|
|
13
|
+
/** The recipient's principal (merchant or donation recipient); the frame checks it against the connecting origin's DNS record before any transfer. */
|
|
14
|
+
beneficiary: string;
|
|
15
|
+
/** Base64 salt for the deposit subaccount: random per order or donation, never reused. */
|
|
16
|
+
salt: string;
|
|
17
|
+
/** The platform's name for this checkout, e.g. the site name. Echoed back in onSuccess; a subscription also stores it as the name the buyer's wallet shows. */
|
|
18
|
+
reference: string;
|
|
19
|
+
}
|
|
20
|
+
export interface CheckoutModalConfig {
|
|
21
|
+
/** Where the wallet lives, e.g. 'https://pybara.io' (prod) or the staging wallet URL. */
|
|
22
|
+
walletUrl: string;
|
|
23
|
+
/** Decides settle.pay_and_log() vs. donate_and_log() inside the frame. Known before the order exists, unlike PaymentData. */
|
|
24
|
+
context: 'payment' | 'donation';
|
|
25
|
+
/** Replaces the success screen's default title ("You're all set!"), e.g. pybara-donate's "Thank you message" setting. Plain text; the frame escapes it. */
|
|
26
|
+
thankYouMessage?: string;
|
|
27
|
+
/** The payment is complete: the frame's success screen has appeared, and the modal stays open until the buyer closes it (onClose). The moment to confirm the payment server-side. */
|
|
28
|
+
onSuccess?: (data: {
|
|
29
|
+
blockIndex: string;
|
|
30
|
+
reference: string;
|
|
31
|
+
payerPrincipal: string;
|
|
32
|
+
token: string;
|
|
33
|
+
}) => void;
|
|
34
|
+
/** The frame refused, with an EmbeddedError; the modal has closed. */
|
|
35
|
+
onError?: (error: Error) => void;
|
|
36
|
+
/** The modal has closed: a cancellation before any onSuccess, or the buyer leaving the success screen after one. */
|
|
37
|
+
onClose?: () => void;
|
|
38
|
+
}
|
|
39
|
+
/** What show() needs that only exists once the order or donation does — unlike CheckoutModalConfig, known at construction. */
|
|
40
|
+
export interface PaymentData {
|
|
41
|
+
modalData: ModalData;
|
|
42
|
+
/**
|
|
43
|
+
* Present only for a recurring payment. totalPulls: 0 means unlimited, as in subs.mo's CreateSubscriptionArgs.
|
|
44
|
+
* With a `checkout`, totalPulls is left out: the frame computes it from durationMonths (absent: unlimited).
|
|
45
|
+
*/
|
|
46
|
+
recurring?: {
|
|
47
|
+
frequency: string;
|
|
48
|
+
totalPulls?: number;
|
|
49
|
+
/** Months the donor chose, when bounded. totalPulls is derived from it; the checkout shows both. */
|
|
50
|
+
durationMonths?: number;
|
|
51
|
+
};
|
|
52
|
+
/** Opaque key-value metadata forwarded unchanged to settle's pay_and_log()/donate_and_log(): order or donor details the platform already has (email, WooCommerce order ID, …). The frame never interprets them. */
|
|
53
|
+
sdkFields?: [string, string][];
|
|
54
|
+
/** The semantic checkout, which the frame turns into the log fields and the USD amount itself; sent instead of `sdkFields` and `modalData.amountUSD`, never with them. */
|
|
55
|
+
checkout?: Checkout;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Mirrors pybara-wallet's EmbeddedCheckout (modes/mode-2-embedded/contract.ts), version 1: a core every kind of checkout shares, and the part for its kind, matching `context`.
|
|
59
|
+
* The frame validates it field by field and refuses it with INVALID_CHECKOUT, naming the faulty field.
|
|
60
|
+
*/
|
|
61
|
+
export interface Checkout {
|
|
62
|
+
v: 1;
|
|
63
|
+
/** A decimal string in the currency's major units: "12.34" is €12.34, "1000" is ¥1,000. The frame reads it with the currency's ISO 4217 minor units. */
|
|
64
|
+
amount: string;
|
|
65
|
+
/** ISO 4217, uppercase. */
|
|
66
|
+
currency: string;
|
|
67
|
+
site: {
|
|
68
|
+
url: string;
|
|
69
|
+
name: string;
|
|
70
|
+
country?: string;
|
|
71
|
+
};
|
|
72
|
+
/** The integration's slug (a-z, 0-9, -), logged as a label. */
|
|
73
|
+
platform?: string;
|
|
74
|
+
pluginVersion?: string;
|
|
75
|
+
siteTerms?: {
|
|
76
|
+
version?: string;
|
|
77
|
+
acceptedAt?: string;
|
|
78
|
+
};
|
|
79
|
+
notify?: {
|
|
80
|
+
email?: string;
|
|
81
|
+
enabled?: boolean;
|
|
82
|
+
};
|
|
83
|
+
donation?: {
|
|
84
|
+
donor?: {
|
|
85
|
+
email?: string;
|
|
86
|
+
firstName?: string;
|
|
87
|
+
lastName?: string;
|
|
88
|
+
company?: string;
|
|
89
|
+
country?: string;
|
|
90
|
+
address?: {
|
|
91
|
+
line1?: string;
|
|
92
|
+
line2?: string;
|
|
93
|
+
city?: string;
|
|
94
|
+
state?: string;
|
|
95
|
+
postalCode?: string;
|
|
96
|
+
country?: string;
|
|
97
|
+
};
|
|
98
|
+
tos?: {
|
|
99
|
+
version?: string;
|
|
100
|
+
acceptedAt?: string;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
message?: string;
|
|
104
|
+
isAnonymous?: boolean;
|
|
105
|
+
wantsTaxReceipt?: boolean;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Mirrors pybara-wallet's EmbeddedErrorCode. Every value but RATE_UNAVAILABLE is a terminal refusal; the frame handles other transient failures with its own retry screen and never posts them.
|
|
110
|
+
* RATE_UNAVAILABLE: core's exchange rate for a checkout's currency could not be loaded, so the frame had no amount to show; worth trying again.
|
|
111
|
+
*/
|
|
112
|
+
declare const EMBEDDED_ERROR_CODES: readonly ["DESTINATION_REFUSED", "INVALID_BENEFICIARY", "INVALID_CHECKOUT", "NO_WALLET_AVAILABLE", "RATE_UNAVAILABLE", "SITE_MISMATCH"];
|
|
113
|
+
type EmbeddedErrorCode = typeof EMBEDDED_ERROR_CODES[number];
|
|
114
|
+
/**
|
|
115
|
+
* The error handed to onError() when the frame refuses.
|
|
116
|
+
* Carries `.code` so a platform branches on it rather than string-matching `.message`, which may be reworded or localised at any time.
|
|
117
|
+
*/
|
|
118
|
+
export declare class EmbeddedError extends Error {
|
|
119
|
+
readonly code: EmbeddedErrorCode | 'UNKNOWN';
|
|
120
|
+
constructor(code: EmbeddedErrorCode | 'UNKNOWN', message: string);
|
|
121
|
+
}
|
|
122
|
+
export declare class CheckoutModal {
|
|
123
|
+
private config;
|
|
124
|
+
private overlay;
|
|
125
|
+
private iframe;
|
|
126
|
+
/** Shown until the frame posts its first content height: the iframe starts at height 0, so the backdrop would otherwise look empty. */
|
|
127
|
+
private spinner;
|
|
128
|
+
private walletOrigin;
|
|
129
|
+
private handleMessage;
|
|
130
|
+
private handleEscapeKey;
|
|
131
|
+
/** False while the frame reports a payment or subscription in flight, so Escape cannot abandon it halfway. True by default, for a frame that never reports it. */
|
|
132
|
+
private closable;
|
|
133
|
+
/** Set once the iframe's `load` fires; until then show() cannot post to it. */
|
|
134
|
+
private iframeLoaded;
|
|
135
|
+
/** Held by show() when it runs before `load`; the `load` handler sends it. */
|
|
136
|
+
private pendingPaymentData;
|
|
137
|
+
constructor(config: CheckoutModalConfig);
|
|
138
|
+
/** Backdrop and iframe, built at construction and hidden until open() — see the file header for why. */
|
|
139
|
+
private createIframe;
|
|
140
|
+
private sendInitMessage;
|
|
141
|
+
/**
|
|
142
|
+
* Show the backdrop and its spinner now, before the payment data exists: a platform calls it on the buyer's click, while it still creates the order, so one overlay covers the whole sequence.
|
|
143
|
+
* Does nothing if already shown; show() calls it too. close() takes it down again if the platform fails before show().
|
|
144
|
+
*/
|
|
145
|
+
open(): void;
|
|
146
|
+
/** Reveal the (usually already loaded) iframe, opening the backdrop if open() has not already, and post the frame its payment data. */
|
|
147
|
+
show(data: PaymentData): void;
|
|
148
|
+
/**
|
|
149
|
+
* A message box instead of the frame, for a platform-side check that fails before checkout opens (a suspended merchant or recipient, a missing principal).
|
|
150
|
+
* The caller supplies the text, translated: everything after opening is the frame's to report, so this package holds no error copy.
|
|
151
|
+
*/
|
|
152
|
+
renderTerminalState(message: string): void;
|
|
153
|
+
/**
|
|
154
|
+
* Releases all state at once, so nothing can reach the frame any more; only the overlay element lingers for the close animation.
|
|
155
|
+
* renderTerminalState() relies on this: it builds its own overlay straight after, while the old one is still fading.
|
|
156
|
+
*/
|
|
157
|
+
close(): void;
|
|
158
|
+
}
|
|
159
|
+
export {};
|
|
160
|
+
//# sourceMappingURL=modal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../src/modal/modal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/* Pybara.js - pybara.com */
|
|
2
|
+
//#region src/modal/config.ts
|
|
3
|
+
var e = {
|
|
4
|
+
Z_INDEX: 999999,
|
|
5
|
+
BACKGROUND: "rgba(0, 0, 0, 0.7)"
|
|
6
|
+
}, t = {
|
|
7
|
+
OVERLAY_FADE_IN_MS: 200,
|
|
8
|
+
PANEL_OPEN_MS: 300,
|
|
9
|
+
PANEL_CLOSE_MS: 200,
|
|
10
|
+
OVERLAY_FADE_OUT_DELAY_MS: 50,
|
|
11
|
+
OVERLAY_FADE_OUT_MS: 150
|
|
12
|
+
}, n = 0, r = 0, i = 0;
|
|
13
|
+
function a(e) {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
}
|
|
16
|
+
function o(e) {
|
|
17
|
+
e.preventDefault();
|
|
18
|
+
}
|
|
19
|
+
function s(e) {
|
|
20
|
+
e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || [
|
|
21
|
+
"ArrowUp",
|
|
22
|
+
"ArrowDown",
|
|
23
|
+
"PageUp",
|
|
24
|
+
"PageDown",
|
|
25
|
+
"Home",
|
|
26
|
+
"End",
|
|
27
|
+
" "
|
|
28
|
+
].includes(e.key) && e.preventDefault();
|
|
29
|
+
}
|
|
30
|
+
function c() {
|
|
31
|
+
window.scrollTo(r, i);
|
|
32
|
+
}
|
|
33
|
+
function l() {
|
|
34
|
+
n === 0 && (r = window.scrollX, i = window.scrollY, window.addEventListener("wheel", a, { passive: !1 }), window.addEventListener("touchmove", o, { passive: !1 }), window.addEventListener("keydown", s), window.addEventListener("scroll", c)), n += 1;
|
|
35
|
+
}
|
|
36
|
+
function u() {
|
|
37
|
+
n !== 0 && (--n, n === 0 && (window.removeEventListener("wheel", a), window.removeEventListener("touchmove", o), window.removeEventListener("keydown", s), window.removeEventListener("scroll", c)));
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/modal/modal.ts
|
|
41
|
+
function d() {
|
|
42
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
43
|
+
}
|
|
44
|
+
var f = [
|
|
45
|
+
"DESTINATION_REFUSED",
|
|
46
|
+
"INVALID_BENEFICIARY",
|
|
47
|
+
"INVALID_CHECKOUT",
|
|
48
|
+
"NO_WALLET_AVAILABLE",
|
|
49
|
+
"RATE_UNAVAILABLE",
|
|
50
|
+
"SITE_MISMATCH"
|
|
51
|
+
];
|
|
52
|
+
function p(e) {
|
|
53
|
+
return f.includes(e) ? e : "UNKNOWN";
|
|
54
|
+
}
|
|
55
|
+
var m = class extends Error {
|
|
56
|
+
constructor(e, t) {
|
|
57
|
+
super(t), this.name = "EmbeddedError", this.code = e, Object.setPrototypeOf(this, new.target.prototype);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
function h(e) {
|
|
61
|
+
return typeof e == "object" && !!e && typeof e.type == "string" && e.type.startsWith("pybara_embedded_");
|
|
62
|
+
}
|
|
63
|
+
var g = class {
|
|
64
|
+
constructor(e) {
|
|
65
|
+
this.overlay = null, this.iframe = null, this.spinner = null, this.handleMessage = null, this.handleEscapeKey = null, this.closable = !0, this.iframeLoaded = !1, this.pendingPaymentData = null, this.config = e, this.walletOrigin = new URL(e.walletUrl).origin, this.createIframe();
|
|
66
|
+
}
|
|
67
|
+
createIframe() {
|
|
68
|
+
let n = document.createElement("div");
|
|
69
|
+
n.className = "pybara-checkout-overlay", n.style.cssText = `
|
|
70
|
+
position: fixed;
|
|
71
|
+
top: 0;
|
|
72
|
+
left: 0;
|
|
73
|
+
right: 0;
|
|
74
|
+
bottom: 0;
|
|
75
|
+
background: ${e.BACKGROUND};
|
|
76
|
+
z-index: ${e.Z_INDEX};
|
|
77
|
+
display: none;
|
|
78
|
+
align-items: center;
|
|
79
|
+
justify-content: center;
|
|
80
|
+
overscroll-behavior: none;
|
|
81
|
+
user-select: none;
|
|
82
|
+
`;
|
|
83
|
+
let r = document.createElement("iframe");
|
|
84
|
+
r.src = `${this.config.walletUrl}/pay?mode=embedded`, r.title = "Pybara Wallet", r.style.cssText = "\n width: 100%;\n max-width: 500px;\n height: 0;\n max-height: 90vh;\n border: none;\n border-radius: 20px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);\n overscroll-behavior: none;\n ";
|
|
85
|
+
let i = document.createElement("div");
|
|
86
|
+
i.setAttribute("aria-hidden", "true"), i.style.cssText = "\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n ", i.innerHTML = "\n <svg viewBox=\"0 0 50 50\" width=\"50\" height=\"50\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"white\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"80\" stroke-dashoffset=\"20\"/>\n </svg>\n ", i.querySelector("svg")?.animate([{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }], {
|
|
87
|
+
duration: 1e3,
|
|
88
|
+
iterations: Infinity
|
|
89
|
+
}), r.addEventListener("load", () => {
|
|
90
|
+
this.iframeLoaded = !0, this.pendingPaymentData &&= (this.sendInitMessage(this.pendingPaymentData), null);
|
|
91
|
+
}, { once: !0 }), this.handleMessage = (e) => {
|
|
92
|
+
if (e.origin === this.walletOrigin && e.source === r.contentWindow && h(e.data)) switch (e.data.type) {
|
|
93
|
+
case "pybara_embedded_result":
|
|
94
|
+
this.config.onSuccess?.({
|
|
95
|
+
blockIndex: e.data.blockIndex,
|
|
96
|
+
reference: e.data.reference,
|
|
97
|
+
payerPrincipal: e.data.payerPrincipal,
|
|
98
|
+
token: e.data.token
|
|
99
|
+
});
|
|
100
|
+
break;
|
|
101
|
+
case "pybara_embedded_error":
|
|
102
|
+
this.close(), this.config.onError?.(new m(p(e.data.code), e.data.message));
|
|
103
|
+
break;
|
|
104
|
+
case "pybara_embedded_closed":
|
|
105
|
+
this.close(), this.config.onClose?.();
|
|
106
|
+
break;
|
|
107
|
+
case "pybara_embedded_resize":
|
|
108
|
+
r.style.height !== `${e.data.height}px` && (r.style.height = `${e.data.height}px`), this.spinner && (this.spinner.remove(), this.spinner = null, d() || r.animate([{
|
|
109
|
+
transform: "translateY(20px)",
|
|
110
|
+
opacity: 0
|
|
111
|
+
}, {
|
|
112
|
+
transform: "none",
|
|
113
|
+
opacity: 1
|
|
114
|
+
}], {
|
|
115
|
+
duration: t.PANEL_OPEN_MS,
|
|
116
|
+
easing: "ease"
|
|
117
|
+
}));
|
|
118
|
+
break;
|
|
119
|
+
case "pybara_embedded_closable": this.closable = e.data.closable;
|
|
120
|
+
}
|
|
121
|
+
}, window.addEventListener("message", this.handleMessage), this.handleEscapeKey = (e) => {
|
|
122
|
+
e.key === "Escape" && this.closable && (this.close(), this.config.onClose?.());
|
|
123
|
+
}, document.addEventListener("keydown", this.handleEscapeKey), n.appendChild(i), n.appendChild(r), document.body.appendChild(n), this.overlay = n, this.iframe = r, this.spinner = i;
|
|
124
|
+
}
|
|
125
|
+
sendInitMessage(e) {
|
|
126
|
+
let t = {
|
|
127
|
+
type: "pybara_embedded_init",
|
|
128
|
+
beneficiary: e.modalData.beneficiary,
|
|
129
|
+
salt: e.modalData.salt,
|
|
130
|
+
...e.modalData.amountUSD === void 0 ? {} : { amountUSD: e.modalData.amountUSD },
|
|
131
|
+
reference: e.modalData.reference,
|
|
132
|
+
context: this.config.context,
|
|
133
|
+
...e.recurring ? { recurring: e.recurring } : {},
|
|
134
|
+
...e.sdkFields ? { sdkFields: e.sdkFields } : {},
|
|
135
|
+
...e.checkout ? { checkout: e.checkout } : {},
|
|
136
|
+
...this.config.thankYouMessage ? { thankYouMessage: this.config.thankYouMessage } : {}
|
|
137
|
+
};
|
|
138
|
+
this.iframe?.contentWindow?.postMessage(t, this.walletOrigin);
|
|
139
|
+
}
|
|
140
|
+
open() {
|
|
141
|
+
this.overlay && this.overlay.style.display !== "flex" && (l(), this.overlay.style.display = "flex", d() || this.overlay.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
142
|
+
duration: t.OVERLAY_FADE_IN_MS,
|
|
143
|
+
easing: "ease"
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
show(e) {
|
|
147
|
+
this.open(), this.iframeLoaded ? this.sendInitMessage(e) : this.pendingPaymentData = e;
|
|
148
|
+
}
|
|
149
|
+
renderTerminalState(t) {
|
|
150
|
+
this.close(), l();
|
|
151
|
+
let n = document.createElement("div");
|
|
152
|
+
n.className = "pybara-checkout-overlay", n.style.cssText = `
|
|
153
|
+
position: fixed;
|
|
154
|
+
top: 0;
|
|
155
|
+
left: 0;
|
|
156
|
+
right: 0;
|
|
157
|
+
bottom: 0;
|
|
158
|
+
background: ${e.BACKGROUND};
|
|
159
|
+
z-index: ${e.Z_INDEX};
|
|
160
|
+
display: flex;
|
|
161
|
+
align-items: center;
|
|
162
|
+
justify-content: center;
|
|
163
|
+
user-select: none;
|
|
164
|
+
`;
|
|
165
|
+
let r = document.createElement("div");
|
|
166
|
+
r.style.cssText = "\n background: #fff;\n border-radius: 12px;\n color: #666;\n padding: 2rem;\n line-height: 1.4;\n max-width: 360px;\n text-align: center;\n font-family: system-ui, sans-serif;\n user-select: text;\n ", r.textContent = t, n.appendChild(r), n.addEventListener("click", (e) => {
|
|
167
|
+
e.target === n && (n.remove(), u(), this.config.onClose?.());
|
|
168
|
+
}), document.body.appendChild(n), this.overlay = n;
|
|
169
|
+
}
|
|
170
|
+
close() {
|
|
171
|
+
this.handleMessage &&= (window.removeEventListener("message", this.handleMessage), null), this.handleEscapeKey &&= (document.removeEventListener("keydown", this.handleEscapeKey), null), u();
|
|
172
|
+
let e = this.overlay, n = this.iframe;
|
|
173
|
+
this.overlay = null, this.iframe = null, this.spinner = null, this.iframeLoaded = !1, this.pendingPaymentData = null, this.closable = !0, e && (e.style.display === "none" || d() ? e.remove() : (e.style.pointerEvents = "none", n?.animate([{
|
|
174
|
+
transform: "scale(1)",
|
|
175
|
+
opacity: 1
|
|
176
|
+
}, {
|
|
177
|
+
transform: "scale(0.95)",
|
|
178
|
+
opacity: 0
|
|
179
|
+
}], {
|
|
180
|
+
duration: t.PANEL_CLOSE_MS,
|
|
181
|
+
easing: "ease-out",
|
|
182
|
+
fill: "forwards"
|
|
183
|
+
}), e.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
184
|
+
duration: t.OVERLAY_FADE_OUT_MS,
|
|
185
|
+
delay: t.OVERLAY_FADE_OUT_DELAY_MS,
|
|
186
|
+
easing: "ease-out",
|
|
187
|
+
fill: "forwards"
|
|
188
|
+
}).finished.then(() => e.remove(), () => e.remove())));
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
//#endregion
|
|
192
|
+
export { m as n, g as t };
|