@dintero/checkout-web-sdk 0.10.2 → 0.11.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/dist/declarations/src/checkout.d.ts +2 -1
- package/dist/declarations/src/index.d.ts +4 -4
- package/dist/declarations/src/subscribe.d.ts +2 -2
- package/dist/dintero-checkout-web-sdk.cjs.dev.js +411 -397
- package/dist/dintero-checkout-web-sdk.cjs.prod.js +411 -397
- package/dist/dintero-checkout-web-sdk.esm.js +411 -397
- package/dist/dintero-checkout-web-sdk.umd.min.js +2 -2
- package/dist/dintero-checkout-web-sdk.umd.min.js.map +1 -1
- package/package.json +6 -6
|
@@ -2,7 +2,7 @@ import 'native-promise-only';
|
|
|
2
2
|
|
|
3
3
|
var pkg = {
|
|
4
4
|
name: "@dintero/checkout-web-sdk",
|
|
5
|
-
version: "0.
|
|
5
|
+
version: "0.11.1",
|
|
6
6
|
description: "Dintero Checkout SDK for web frontends",
|
|
7
7
|
main: "dist/dintero-checkout-web-sdk.cjs.js",
|
|
8
8
|
module: "dist/dintero-checkout-web-sdk.esm.js",
|
|
@@ -17,7 +17,7 @@ var pkg = {
|
|
|
17
17
|
},
|
|
18
18
|
scripts: {
|
|
19
19
|
build: "yarn tsc --noEmit && preconstruct build",
|
|
20
|
-
lint: "
|
|
20
|
+
lint: "biome check",
|
|
21
21
|
test: "vitest --config .vitest.config.mts",
|
|
22
22
|
"semantic-release": "semantic-release",
|
|
23
23
|
prepublishOnly: "yarn run build"
|
|
@@ -36,16 +36,16 @@ var pkg = {
|
|
|
36
36
|
devDependencies: {
|
|
37
37
|
"@babel/core": "7.28.5",
|
|
38
38
|
"@babel/preset-typescript": "7.28.5",
|
|
39
|
+
"@biomejs/biome": "2.3.10",
|
|
39
40
|
"@preconstruct/cli": "2.8.12",
|
|
40
41
|
"@semantic-release/exec": "7.1.0",
|
|
41
42
|
"@semantic-release/git": "10.0.1",
|
|
42
|
-
"@vitest/browser": "4.0.
|
|
43
|
+
"@vitest/browser": "4.0.16",
|
|
43
44
|
"@vitest/browser-webdriverio": "^4.0.4",
|
|
44
|
-
prettier: "3.6.2",
|
|
45
45
|
"semantic-release": "25.0.2",
|
|
46
46
|
typescript: "5.9.3",
|
|
47
|
-
vitest: "4.0.
|
|
48
|
-
webdriverio: "9.
|
|
47
|
+
vitest: "4.0.16",
|
|
48
|
+
webdriverio: "9.22.0"
|
|
49
49
|
},
|
|
50
50
|
dependencies: {
|
|
51
51
|
"native-promise-only": "0.8.1"
|
|
@@ -72,9 +72,65 @@ let InternalCheckoutEvents = /*#__PURE__*/function (InternalCheckoutEvents) {
|
|
|
72
72
|
InternalCheckoutEvents["ScrollToTop"] = "ScrollToTop";
|
|
73
73
|
InternalCheckoutEvents["ShowPopOutButton"] = "ShowPopOutButton";
|
|
74
74
|
InternalCheckoutEvents["HidePopOutButton"] = "HidePopOutButton";
|
|
75
|
+
InternalCheckoutEvents["TopLevelNavigation"] = "TopLevelNavigation";
|
|
75
76
|
return InternalCheckoutEvents;
|
|
76
77
|
}({});
|
|
77
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Creates an iframe and adds it to the container.
|
|
81
|
+
*
|
|
82
|
+
* Returns a promise that resolves to the iframe when the iframe has loaded.
|
|
83
|
+
* Rejects the promise if there is a problem loading the iframe.
|
|
84
|
+
*/
|
|
85
|
+
const createIframeAsync = (container, url) => {
|
|
86
|
+
if (!container || !container.appendChild) {
|
|
87
|
+
throw new Error("Invalid container");
|
|
88
|
+
}
|
|
89
|
+
const iframe = document.createElement("iframe");
|
|
90
|
+
|
|
91
|
+
// No border, transparent and stretch to 100% of the container width.
|
|
92
|
+
iframe.setAttribute("frameborder", "0");
|
|
93
|
+
iframe.setAttribute("allowTransparency", "true");
|
|
94
|
+
iframe.setAttribute("style", "width:100%; height:0;");
|
|
95
|
+
|
|
96
|
+
// TODO: Get this to work as expected, might be tricky with current
|
|
97
|
+
// tests since they will require the csp to be "unsafe-inline".
|
|
98
|
+
// The server needs to add the same property in the Content Security
|
|
99
|
+
// Policy headers in the response for this to work. A CSP header set by
|
|
100
|
+
// a meta tag in the iframe target will not be detected as a valid
|
|
101
|
+
// CSP from the iframe host.
|
|
102
|
+
// Content Security Policy, should be limited to "endpoint".
|
|
103
|
+
// iframe.setAttribute("csp", `default-src ${endpoint}`);
|
|
104
|
+
|
|
105
|
+
// Apply extra restrictions to the content in the iframe.
|
|
106
|
+
// allow popups is needed to open terms in new window
|
|
107
|
+
iframe.setAttribute("sandbox", "allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation");
|
|
108
|
+
|
|
109
|
+
// Needed for to allow apple pay from iframe
|
|
110
|
+
iframe.setAttribute("allow", "payment; clipboard-write *");
|
|
111
|
+
|
|
112
|
+
// The download priority of the resource in the <iframe>'s src attribute.
|
|
113
|
+
iframe.setAttribute("importance", "high");
|
|
114
|
+
|
|
115
|
+
// Set the iframe source to the url.
|
|
116
|
+
iframe.setAttribute("src", url);
|
|
117
|
+
|
|
118
|
+
// Resolve or reject promise when iframe loads.
|
|
119
|
+
|
|
120
|
+
// // Add iframe to the container.
|
|
121
|
+
// container.appendChild(iframe);
|
|
122
|
+
return {
|
|
123
|
+
iframe,
|
|
124
|
+
initiate: async () => {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
iframe.onload = () => resolve();
|
|
127
|
+
iframe.onerror = () => reject();
|
|
128
|
+
container.appendChild(iframe);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
|
|
78
134
|
/**
|
|
79
135
|
* Wraps window.location.assign()
|
|
80
136
|
*/
|
|
@@ -93,7 +149,8 @@ const getSessionUrl = options => {
|
|
|
93
149
|
language,
|
|
94
150
|
ui,
|
|
95
151
|
shouldCallValidateSession,
|
|
96
|
-
popOut
|
|
152
|
+
popOut,
|
|
153
|
+
redirect
|
|
97
154
|
} = options;
|
|
98
155
|
if (!endpoint) {
|
|
99
156
|
throw new Error("Invalid endpoint");
|
|
@@ -112,7 +169,9 @@ const getSessionUrl = options => {
|
|
|
112
169
|
if (popOut) {
|
|
113
170
|
params.append("role", "pop_out_launcher");
|
|
114
171
|
}
|
|
115
|
-
if (
|
|
172
|
+
if (
|
|
173
|
+
// biome-ignore lint/suspicious/noPrototypeBuiltins: test
|
|
174
|
+
options.hasOwnProperty("hideTestMessage") && options.hideTestMessage !== undefined && options.hideTestMessage === true) {
|
|
116
175
|
params.append("hide_test_message", "true");
|
|
117
176
|
}
|
|
118
177
|
const hostname = getHostname();
|
|
@@ -120,7 +179,7 @@ const getSessionUrl = options => {
|
|
|
120
179
|
params.append("sdk_hostname", hostname);
|
|
121
180
|
}
|
|
122
181
|
if (!redirect && !hostnameIsTop()) {
|
|
123
|
-
params.append("sdk_not_top_level", "
|
|
182
|
+
params.append("sdk_not_top_level", "true");
|
|
124
183
|
}
|
|
125
184
|
if (endpoint === "https://checkout.dintero.com") {
|
|
126
185
|
// Default endpoint will redirect via the view endpoint
|
|
@@ -162,7 +221,7 @@ const getHostname = () => {
|
|
|
162
221
|
hostname
|
|
163
222
|
} = window.location;
|
|
164
223
|
return hostname;
|
|
165
|
-
} catch (
|
|
224
|
+
} catch (_) {
|
|
166
225
|
return undefined;
|
|
167
226
|
}
|
|
168
227
|
};
|
|
@@ -174,7 +233,7 @@ const hostnameIsTop = () => {
|
|
|
174
233
|
const hostname = getHostname();
|
|
175
234
|
const topHostname = window.top.location.hostname;
|
|
176
235
|
return topHostname && hostname && hostname === topHostname;
|
|
177
|
-
} catch (
|
|
236
|
+
} catch (_) {
|
|
178
237
|
return false;
|
|
179
238
|
}
|
|
180
239
|
};
|
|
@@ -184,226 +243,142 @@ const url = {
|
|
|
184
243
|
windowLocationAssign
|
|
185
244
|
};
|
|
186
245
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
// Resolve or reject promise when iframe loads.
|
|
227
|
-
|
|
228
|
-
// // Add iframe to the container.
|
|
229
|
-
// container.appendChild(iframe);
|
|
230
|
-
return {
|
|
231
|
-
iframe,
|
|
232
|
-
initiate: async () => {
|
|
233
|
-
return new Promise((resolve, reject) => {
|
|
234
|
-
iframe.onload = () => resolve();
|
|
235
|
-
iframe.onerror = () => reject();
|
|
236
|
-
container.appendChild(iframe);
|
|
237
|
-
});
|
|
246
|
+
const createPopOutWindow = (sid, url, width, height) => {
|
|
247
|
+
return new Promise(resolve => {
|
|
248
|
+
try {
|
|
249
|
+
// Creates a centered pop up window
|
|
250
|
+
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
251
|
+
const top = window.screenY + (window.outerHeight - height) / 2;
|
|
252
|
+
const features = `width=${width},height=${height},left=${left},top=${top},location=no,menubar=no,toolbar=no,status=no`;
|
|
253
|
+
let popOut;
|
|
254
|
+
let timeout = -1;
|
|
255
|
+
// Set up listener for application loaded message from pop out window
|
|
256
|
+
const handleAppLoaded = event => {
|
|
257
|
+
const correctSource = event.source === popOut;
|
|
258
|
+
const correctOrigin = event.origin === new URL(url).origin;
|
|
259
|
+
const correctMessage = event.data && event.data.type === "AppLoaded";
|
|
260
|
+
const correctContext = event.data.context === "popOut";
|
|
261
|
+
const correctSid = event.data.sid === sid;
|
|
262
|
+
if (correctSource && correctOrigin && correctMessage && correctContext && correctSid) {
|
|
263
|
+
clearTimeout(timeout);
|
|
264
|
+
resolve(popOut);
|
|
265
|
+
window.removeEventListener("message", handleAppLoaded);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
window.addEventListener("message", handleAppLoaded);
|
|
269
|
+
// Open pop out
|
|
270
|
+
popOut = window.open(url, "dintero-checkout", features);
|
|
271
|
+
// Check that pop out was opened
|
|
272
|
+
if (!popOut) {
|
|
273
|
+
console.log("createPopOutWindow no popOut");
|
|
274
|
+
resolve(undefined);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
// Trigger timeout if pop out is not loaded
|
|
278
|
+
timeout = window.setTimeout(() => {
|
|
279
|
+
console.log("createPopOutWindow timeout");
|
|
280
|
+
resolve(undefined);
|
|
281
|
+
}, 10000);
|
|
282
|
+
} catch (_err) {
|
|
283
|
+
resolve(undefined);
|
|
238
284
|
}
|
|
239
|
-
};
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Unsubscribe handler from event(s).
|
|
244
|
-
*/
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Post a message acknowledgement to the checkout iframe.
|
|
248
|
-
*/
|
|
249
|
-
const postAck = (source, event) => {
|
|
250
|
-
if (event.data.mid && source) {
|
|
251
|
-
source.postMessage({
|
|
252
|
-
ack: event.data.mid
|
|
253
|
-
}, event.origin || "*");
|
|
254
|
-
}
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Post a SessionLock-event to the checkout iframe.
|
|
259
|
-
*/
|
|
260
|
-
const postSessionLock = (iframe, sid) => {
|
|
261
|
-
if (iframe.contentWindow) {
|
|
262
|
-
iframe.contentWindow.postMessage({
|
|
263
|
-
type: "LockSession",
|
|
264
|
-
sid
|
|
265
|
-
}, "*");
|
|
266
|
-
}
|
|
285
|
+
});
|
|
267
286
|
};
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
type: "ValidationResult",
|
|
276
|
-
sid,
|
|
277
|
-
...result
|
|
278
|
-
}, "*");
|
|
287
|
+
const openPopOut = async options => {
|
|
288
|
+
let unsubscribe;
|
|
289
|
+
let intervalId = -1;
|
|
290
|
+
let popOutWindow;
|
|
291
|
+
if (popOutWindow && !popOutWindow.closed) {
|
|
292
|
+
// Skip if already open.
|
|
293
|
+
return;
|
|
279
294
|
}
|
|
280
|
-
};
|
|
281
295
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
296
|
+
// Open popup window
|
|
297
|
+
const popOutUrl = url.getPopOutUrl(options);
|
|
298
|
+
popOutWindow = await createPopOutWindow(options.sid, popOutUrl, Math.min(480, window.screen.width), Math.min(840, window.screen.height));
|
|
299
|
+
const focusPopOut = () => {
|
|
300
|
+
if (popOutWindow) {
|
|
301
|
+
popOutWindow.focus();
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
const cleanUpClosed = () => {
|
|
305
|
+
window.clearInterval(intervalId);
|
|
306
|
+
intervalId = -1;
|
|
307
|
+
window.removeEventListener("beforeunload", closePopOut);
|
|
308
|
+
popOutWindow = undefined;
|
|
309
|
+
options.onClose();
|
|
310
|
+
if (unsubscribe) {
|
|
311
|
+
unsubscribe();
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
const closePopOut = () => {
|
|
315
|
+
if (popOutWindow) {
|
|
316
|
+
popOutWindow.close();
|
|
317
|
+
}
|
|
318
|
+
cleanUpClosed();
|
|
319
|
+
};
|
|
320
|
+
const checkIfPopupClosed = () => {
|
|
321
|
+
if (popOutWindow?.closed) {
|
|
322
|
+
cleanUpClosed();
|
|
323
|
+
}
|
|
324
|
+
};
|
|
293
325
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
*/
|
|
297
|
-
const postActivePaymentProductType = (iframe, sid, paymentProductType) => {
|
|
298
|
-
if (iframe.contentWindow) {
|
|
299
|
-
iframe.contentWindow.postMessage({
|
|
300
|
-
type: "SetActivePaymentProductType",
|
|
301
|
-
sid,
|
|
302
|
-
payment_product_type: paymentProductType
|
|
303
|
-
}, "*");
|
|
304
|
-
}
|
|
305
|
-
};
|
|
326
|
+
// Close pop out if current window is closed
|
|
327
|
+
window.addEventListener("beforeunload", closePopOut);
|
|
306
328
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
*/
|
|
310
|
-
const postValidatePopOutEvent = (iframe, sid) => {
|
|
311
|
-
if (iframe.contentWindow) {
|
|
312
|
-
iframe.contentWindow.postMessage({
|
|
313
|
-
type: "ValidatingPopOut",
|
|
314
|
-
sid
|
|
315
|
-
}, "*");
|
|
316
|
-
}
|
|
317
|
-
};
|
|
329
|
+
// Check if checkout is still open
|
|
330
|
+
intervalId = window.setInterval(checkIfPopupClosed, 200);
|
|
318
331
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
sid
|
|
327
|
-
}, "*");
|
|
328
|
-
}
|
|
332
|
+
// Set up pub/sub of messages from pop out to SDK
|
|
333
|
+
unsubscribe = options.onOpen(popOutWindow);
|
|
334
|
+
return {
|
|
335
|
+
close: closePopOut,
|
|
336
|
+
focus: focusPopOut,
|
|
337
|
+
popOutWindow
|
|
338
|
+
};
|
|
329
339
|
};
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
+
const postPopOutSessionLock = (popOutWindow, sid) => {
|
|
341
|
+
try {
|
|
342
|
+
if (popOutWindow) {
|
|
343
|
+
popOutWindow.postMessage({
|
|
344
|
+
type: "LockSession",
|
|
345
|
+
sid
|
|
346
|
+
}, "*");
|
|
347
|
+
}
|
|
348
|
+
} catch (e) {
|
|
349
|
+
console.error(e);
|
|
340
350
|
}
|
|
341
351
|
};
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
+
const postPopOutSessionRefresh = (popOutWindow, sid) => {
|
|
353
|
+
try {
|
|
354
|
+
if (popOutWindow) {
|
|
355
|
+
popOutWindow.postMessage({
|
|
356
|
+
type: "RefreshSession",
|
|
357
|
+
sid
|
|
358
|
+
}, "*");
|
|
359
|
+
}
|
|
360
|
+
} catch (e) {
|
|
361
|
+
console.error(e);
|
|
352
362
|
}
|
|
353
363
|
};
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
364
|
+
const postPopOutActivePaymentProductType = (popOutWindow, sid, paymentProductType) => {
|
|
365
|
+
try {
|
|
366
|
+
if (popOutWindow) {
|
|
367
|
+
popOutWindow.postMessage({
|
|
368
|
+
type: "SetActivePaymentProductType",
|
|
369
|
+
sid,
|
|
370
|
+
payment_product_type: paymentProductType
|
|
371
|
+
}, "*");
|
|
372
|
+
}
|
|
373
|
+
} catch (e) {
|
|
374
|
+
console.error(e);
|
|
365
375
|
}
|
|
366
376
|
};
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const subscribe = options => {
|
|
373
|
-
const {
|
|
374
|
-
sid,
|
|
375
|
-
endpoint,
|
|
376
|
-
handler,
|
|
377
|
-
eventTypes,
|
|
378
|
-
checkout
|
|
379
|
-
} = options;
|
|
380
|
-
|
|
381
|
-
// Wrap event handler in a function that checks for correct origin and
|
|
382
|
-
// filters on event type(s) in the event data.
|
|
383
|
-
const endpointUrl = new URL(endpoint);
|
|
384
|
-
const wrappedHandler = event => {
|
|
385
|
-
const correctOrigin = event.origin === endpointUrl.origin;
|
|
386
|
-
const correctWindow = event.source === checkout.iframe.contentWindow;
|
|
387
|
-
const correctSid = event.data && event.data.sid === sid;
|
|
388
|
-
const correctMessageType = eventTypes.indexOf(event.data && event.data.type) !== -1;
|
|
389
|
-
if (correctOrigin && correctWindow && correctSid && correctMessageType) {
|
|
390
|
-
postAck(checkout.iframe.contentWindow, event);
|
|
391
|
-
handler(event.data, checkout);
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
|
|
395
|
-
// Add event listener to the iframe.
|
|
396
|
-
window.addEventListener("message", wrappedHandler, false);
|
|
397
|
-
|
|
398
|
-
// Function to remove the event listener from the iframe.
|
|
399
|
-
const unsubscribe = () => {
|
|
400
|
-
window.removeEventListener("message", wrappedHandler, false);
|
|
401
|
-
};
|
|
402
|
-
|
|
403
|
-
// Return object with unsubscribe function.
|
|
404
|
-
return {
|
|
405
|
-
unsubscribe
|
|
406
|
-
};
|
|
377
|
+
const popOutModule = {
|
|
378
|
+
openPopOut,
|
|
379
|
+
postPopOutSessionLock,
|
|
380
|
+
postPopOutSessionRefresh,
|
|
381
|
+
postPopOutActivePaymentProductType
|
|
407
382
|
};
|
|
408
383
|
|
|
409
384
|
const getBackdropZIndex = () => {
|
|
@@ -412,8 +387,8 @@ const getBackdropZIndex = () => {
|
|
|
412
387
|
const highest = Array.from(elements).reduce((acc, element) => {
|
|
413
388
|
try {
|
|
414
389
|
const zIndexStr = document.defaultView.getComputedStyle(element, null).getPropertyValue("z-index");
|
|
415
|
-
const zIndex = parseInt(zIndexStr || "0");
|
|
416
|
-
if (!isNaN(zIndex) && zIndex > acc) {
|
|
390
|
+
const zIndex = Number.parseInt(zIndexStr || "0", 10);
|
|
391
|
+
if (!Number.isNaN(zIndex) && zIndex > acc) {
|
|
417
392
|
return zIndex;
|
|
418
393
|
}
|
|
419
394
|
} catch (e) {
|
|
@@ -753,9 +728,9 @@ const configureButton = (button, {
|
|
|
753
728
|
|
|
754
729
|
// Position
|
|
755
730
|
button.style.position = "absolute";
|
|
756
|
-
button.style.top = top
|
|
757
|
-
button.style.left = left
|
|
758
|
-
button.style.right = right
|
|
731
|
+
button.style.top = `${top}px`;
|
|
732
|
+
button.style.left = `${left}px`;
|
|
733
|
+
button.style.right = `${right}px`;
|
|
759
734
|
|
|
760
735
|
// Appearance from checkout
|
|
761
736
|
const {
|
|
@@ -783,7 +758,7 @@ const addHoverAndFocusVisibleStyles = (stylesHover, stylesFocusVisible) => {
|
|
|
783
758
|
}
|
|
784
759
|
const style = document.createElement("style");
|
|
785
760
|
style.setAttribute("id", styleId);
|
|
786
|
-
|
|
761
|
+
const content = [];
|
|
787
762
|
if (stylesHover) {
|
|
788
763
|
content.push(toCssEntity(`#${OPEN_POP_OUT_BUTTON_ID}:hover:not(:disabled)`, stylesHover));
|
|
789
764
|
}
|
|
@@ -802,182 +777,211 @@ const toCssParameters = keyValues => {
|
|
|
802
777
|
const slugify = str => {
|
|
803
778
|
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
804
779
|
};
|
|
805
|
-
const addPopOutButton = options => {
|
|
806
|
-
// Will add or update existing button
|
|
807
|
-
const {
|
|
808
|
-
container
|
|
809
|
-
} = options;
|
|
810
|
-
const exists = document.getElementById(OPEN_POP_OUT_BUTTON_ID);
|
|
811
|
-
const button = exists || document.createElement("button");
|
|
812
|
-
configureButton(button, options);
|
|
813
|
-
if (!exists) {
|
|
814
|
-
container.appendChild(button);
|
|
780
|
+
const addPopOutButton = options => {
|
|
781
|
+
// Will add or update existing button
|
|
782
|
+
const {
|
|
783
|
+
container
|
|
784
|
+
} = options;
|
|
785
|
+
const exists = document.getElementById(OPEN_POP_OUT_BUTTON_ID);
|
|
786
|
+
const button = exists || document.createElement("button");
|
|
787
|
+
configureButton(button, options);
|
|
788
|
+
if (!exists) {
|
|
789
|
+
container.appendChild(button);
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
const setPopOutButtonDisabled = disabled => {
|
|
793
|
+
try {
|
|
794
|
+
const button = document.getElementById(OPEN_POP_OUT_BUTTON_ID);
|
|
795
|
+
if (button) {
|
|
796
|
+
if (disabled) {
|
|
797
|
+
button.setAttribute("disabled", disabled.toString());
|
|
798
|
+
} else {
|
|
799
|
+
button.removeAttribute("disabled");
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
} catch (e) {
|
|
803
|
+
// Ignore error and continue
|
|
804
|
+
console.error(e);
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
const removePopOutButton = () => {
|
|
808
|
+
try {
|
|
809
|
+
const button = document.getElementById(OPEN_POP_OUT_BUTTON_ID);
|
|
810
|
+
if (button) {
|
|
811
|
+
button.remove();
|
|
812
|
+
}
|
|
813
|
+
} catch (e) {
|
|
814
|
+
// Ignore error and continue
|
|
815
|
+
console.error(e);
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* Unsubscribe handler from event(s).
|
|
821
|
+
*/
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Post a message acknowledgement to the checkout iframe.
|
|
825
|
+
*/
|
|
826
|
+
const postAck = (source, event) => {
|
|
827
|
+
if (event.data.mid && source) {
|
|
828
|
+
source.postMessage({
|
|
829
|
+
ack: event.data.mid
|
|
830
|
+
}, event.origin || "*");
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
* Post a SessionLock-event to the checkout iframe.
|
|
836
|
+
*/
|
|
837
|
+
const postSessionLock = (iframe, sid) => {
|
|
838
|
+
if (iframe.contentWindow) {
|
|
839
|
+
iframe.contentWindow.postMessage({
|
|
840
|
+
type: "LockSession",
|
|
841
|
+
sid
|
|
842
|
+
}, "*");
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Post the validation result to the checkout iframe
|
|
848
|
+
*/
|
|
849
|
+
const postValidationResult = (iframe, sid, result) => {
|
|
850
|
+
if (iframe.contentWindow) {
|
|
851
|
+
iframe.contentWindow.postMessage({
|
|
852
|
+
type: "ValidationResult",
|
|
853
|
+
sid,
|
|
854
|
+
...result
|
|
855
|
+
}, "*");
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Post RefreshSession-event to the checkout iframe.
|
|
861
|
+
*/
|
|
862
|
+
const postSessionRefresh = (iframe, sid) => {
|
|
863
|
+
if (iframe.contentWindow) {
|
|
864
|
+
iframe.contentWindow.postMessage({
|
|
865
|
+
type: "RefreshSession",
|
|
866
|
+
sid
|
|
867
|
+
}, "*");
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* Post SetActivePaymentProductType-event to the checkout iframe.
|
|
873
|
+
*/
|
|
874
|
+
const postActivePaymentProductType = (iframe, sid, paymentProductType) => {
|
|
875
|
+
if (iframe.contentWindow) {
|
|
876
|
+
iframe.contentWindow.postMessage({
|
|
877
|
+
type: "SetActivePaymentProductType",
|
|
878
|
+
sid,
|
|
879
|
+
payment_product_type: paymentProductType
|
|
880
|
+
}, "*");
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Post ClosePopOut-event to the checkout iframe.
|
|
886
|
+
*/
|
|
887
|
+
const postValidatePopOutEvent = (iframe, sid) => {
|
|
888
|
+
if (iframe.contentWindow) {
|
|
889
|
+
iframe.contentWindow.postMessage({
|
|
890
|
+
type: "ValidatingPopOut",
|
|
891
|
+
sid
|
|
892
|
+
}, "*");
|
|
815
893
|
}
|
|
816
894
|
};
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
}
|
|
827
|
-
} catch (e) {
|
|
828
|
-
// Ignore error and continue
|
|
829
|
-
console.error(e);
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* Post OpenPopOutFailed-event to the checkout iframe.
|
|
898
|
+
*/
|
|
899
|
+
const postOpenPopOutFailedEvent = (iframe, sid) => {
|
|
900
|
+
if (iframe.contentWindow) {
|
|
901
|
+
iframe.contentWindow.postMessage({
|
|
902
|
+
type: "OpenPopOutFailed",
|
|
903
|
+
sid
|
|
904
|
+
}, "*");
|
|
830
905
|
}
|
|
831
906
|
};
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* Post OpenedPopOut-event to the checkout iframe.
|
|
910
|
+
*/
|
|
911
|
+
const postOpenPopOutEvent = (iframe, sid) => {
|
|
912
|
+
if (iframe.contentWindow) {
|
|
913
|
+
iframe.contentWindow.postMessage({
|
|
914
|
+
type: "OpenedPopOut",
|
|
915
|
+
sid
|
|
916
|
+
}, "*");
|
|
841
917
|
}
|
|
842
918
|
};
|
|
843
919
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
const handleAppLoaded = event => {
|
|
855
|
-
const correctSource = event.source === popOut;
|
|
856
|
-
const correctOrigin = event.origin === new URL(url).origin;
|
|
857
|
-
const correctMessage = event.data && event.data.type === "AppLoaded";
|
|
858
|
-
const correctContext = event.data.context === "popOut";
|
|
859
|
-
const correctSid = event.data.sid === sid;
|
|
860
|
-
if (correctSource && correctOrigin && correctMessage && correctContext && correctSid) {
|
|
861
|
-
clearTimeout(timeout);
|
|
862
|
-
resolve(popOut);
|
|
863
|
-
window.removeEventListener("message", handleAppLoaded);
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
window.addEventListener("message", handleAppLoaded);
|
|
867
|
-
// Open pop out
|
|
868
|
-
popOut = window.open(url, "dintero-checkout", features);
|
|
869
|
-
// Check that pop out was opened
|
|
870
|
-
if (!popOut) {
|
|
871
|
-
console.log("createPopOutWindow no popOut");
|
|
872
|
-
resolve(undefined);
|
|
873
|
-
return;
|
|
874
|
-
}
|
|
875
|
-
// Trigger timeout if pop out is not loaded
|
|
876
|
-
timeout = window.setTimeout(() => {
|
|
877
|
-
console.log("createPopOutWindow timeout");
|
|
878
|
-
resolve(undefined);
|
|
879
|
-
}, 10000);
|
|
880
|
-
} catch (err) {
|
|
881
|
-
resolve(undefined);
|
|
882
|
-
}
|
|
883
|
-
});
|
|
920
|
+
/**
|
|
921
|
+
* Post ClosePopOut-event to the checkout iframe.
|
|
922
|
+
*/
|
|
923
|
+
const postClosePopOutEvent = (iframe, sid) => {
|
|
924
|
+
if (iframe.contentWindow) {
|
|
925
|
+
iframe.contentWindow.postMessage({
|
|
926
|
+
type: "ClosedPopOut",
|
|
927
|
+
sid
|
|
928
|
+
}, "*");
|
|
929
|
+
}
|
|
884
930
|
};
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* Post SetLanguage-event to the checkout iframe.
|
|
934
|
+
*/
|
|
935
|
+
const postSetLanguage = (iframe, sid, language) => {
|
|
936
|
+
if (iframe.contentWindow) {
|
|
937
|
+
iframe.contentWindow.postMessage({
|
|
938
|
+
type: "SetLanguage",
|
|
939
|
+
sid,
|
|
940
|
+
language
|
|
941
|
+
}, "*");
|
|
892
942
|
}
|
|
943
|
+
};
|
|
893
944
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
const checkIfPopupClosed = () => {
|
|
919
|
-
if (popOutWindow && popOutWindow.closed) {
|
|
920
|
-
cleanUpClosed();
|
|
945
|
+
/**
|
|
946
|
+
* Subscribe to events from an iframe given a handler and a set
|
|
947
|
+
* of event types.
|
|
948
|
+
*/
|
|
949
|
+
const subscribe = options => {
|
|
950
|
+
const {
|
|
951
|
+
sid,
|
|
952
|
+
endpoint,
|
|
953
|
+
handler,
|
|
954
|
+
eventTypes,
|
|
955
|
+
checkout
|
|
956
|
+
} = options;
|
|
957
|
+
|
|
958
|
+
// Wrap event handler in a function that checks for correct origin and
|
|
959
|
+
// filters on event type(s) in the event data.
|
|
960
|
+
const endpointUrl = new URL(endpoint);
|
|
961
|
+
const wrappedHandler = event => {
|
|
962
|
+
const correctOrigin = event.origin === endpointUrl.origin;
|
|
963
|
+
const correctWindow = event.source === checkout.iframe.contentWindow;
|
|
964
|
+
const correctSid = event.data && event.data.sid === sid;
|
|
965
|
+
const correctMessageType = eventTypes.indexOf(event.data?.type) !== -1;
|
|
966
|
+
if (correctOrigin && correctWindow && correctSid && correctMessageType) {
|
|
967
|
+
postAck(checkout.iframe.contentWindow, event);
|
|
968
|
+
handler(event.data, checkout);
|
|
921
969
|
}
|
|
922
970
|
};
|
|
923
971
|
|
|
924
|
-
//
|
|
925
|
-
window.addEventListener("
|
|
972
|
+
// Add event listener to the iframe.
|
|
973
|
+
window.addEventListener("message", wrappedHandler, false);
|
|
926
974
|
|
|
927
|
-
//
|
|
928
|
-
|
|
975
|
+
// Function to remove the event listener from the iframe.
|
|
976
|
+
const unsubscribe = () => {
|
|
977
|
+
window.removeEventListener("message", wrappedHandler, false);
|
|
978
|
+
};
|
|
929
979
|
|
|
930
|
-
//
|
|
931
|
-
unsubscribe = options.onOpen(popOutWindow);
|
|
980
|
+
// Return object with unsubscribe function.
|
|
932
981
|
return {
|
|
933
|
-
|
|
934
|
-
focus: focusPopOut,
|
|
935
|
-
popOutWindow
|
|
982
|
+
unsubscribe
|
|
936
983
|
};
|
|
937
984
|
};
|
|
938
|
-
const postPopOutSessionLock = (popOutWindow, sid) => {
|
|
939
|
-
try {
|
|
940
|
-
if (popOutWindow) {
|
|
941
|
-
popOutWindow.postMessage({
|
|
942
|
-
type: "LockSession",
|
|
943
|
-
sid
|
|
944
|
-
}, "*");
|
|
945
|
-
}
|
|
946
|
-
} catch (e) {
|
|
947
|
-
console.error(e);
|
|
948
|
-
}
|
|
949
|
-
};
|
|
950
|
-
const postPopOutSessionRefresh = (popOutWindow, sid) => {
|
|
951
|
-
try {
|
|
952
|
-
if (popOutWindow) {
|
|
953
|
-
popOutWindow.postMessage({
|
|
954
|
-
type: "RefreshSession",
|
|
955
|
-
sid
|
|
956
|
-
}, "*");
|
|
957
|
-
}
|
|
958
|
-
} catch (e) {
|
|
959
|
-
console.error(e);
|
|
960
|
-
}
|
|
961
|
-
};
|
|
962
|
-
const postPopOutActivePaymentProductType = (popOutWindow, sid, paymentProductType) => {
|
|
963
|
-
try {
|
|
964
|
-
if (popOutWindow) {
|
|
965
|
-
popOutWindow.postMessage({
|
|
966
|
-
type: "SetActivePaymentProductType",
|
|
967
|
-
sid,
|
|
968
|
-
payment_product_type: paymentProductType
|
|
969
|
-
}, "*");
|
|
970
|
-
}
|
|
971
|
-
} catch (e) {
|
|
972
|
-
console.error(e);
|
|
973
|
-
}
|
|
974
|
-
};
|
|
975
|
-
const popOutModule = {
|
|
976
|
-
openPopOut,
|
|
977
|
-
postPopOutSessionLock,
|
|
978
|
-
postPopOutSessionRefresh,
|
|
979
|
-
postPopOutActivePaymentProductType
|
|
980
|
-
};
|
|
981
985
|
|
|
982
986
|
/**
|
|
983
987
|
* An event handler that navigates to the href in the event.
|
|
@@ -1002,7 +1006,7 @@ const setIframeHeight = (event, checkout) => {
|
|
|
1002
1006
|
* An event handler that scrolls to the top of the iframe. This is useful when the user
|
|
1003
1007
|
* is navigated to another page.
|
|
1004
1008
|
*/
|
|
1005
|
-
const scrollToIframeTop = (
|
|
1009
|
+
const scrollToIframeTop = (_event, checkout) => {
|
|
1006
1010
|
try {
|
|
1007
1011
|
checkout.iframe.scrollIntoView({
|
|
1008
1012
|
block: "start",
|
|
@@ -1053,7 +1057,7 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1053
1057
|
const popOutCompletedHandler = {
|
|
1054
1058
|
internalPopOutHandler: true,
|
|
1055
1059
|
eventTypes: paymentCompletedEvents,
|
|
1056
|
-
handler: (eventData,
|
|
1060
|
+
handler: (eventData, _checkout) => {
|
|
1057
1061
|
if (eventData.href) {
|
|
1058
1062
|
// Remove open pop out button rendered by SDK
|
|
1059
1063
|
removePopOutButton();
|
|
@@ -1075,18 +1079,18 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1075
1079
|
// Check that we should handle the message
|
|
1076
1080
|
if (event.source === source && event.data.context === "popOut" && event.data.sid === checkout.options.sid) {
|
|
1077
1081
|
// Check if handler matches incoming event and trigger the handler if so.
|
|
1078
|
-
[
|
|
1082
|
+
for (const handlerObject of [
|
|
1079
1083
|
// SDK events for managing the pop out flow.
|
|
1080
1084
|
popOutChangedLanguageHandler, popOutCompletedHandler,
|
|
1081
1085
|
// Events configured when the checkout was embedded.
|
|
1082
|
-
...checkout.handlers]
|
|
1086
|
+
...checkout.handlers]) {
|
|
1083
1087
|
if (handlerObject.eventTypes.includes(event.data.type) && handlerObject.handler) {
|
|
1084
1088
|
// Invoking the handler function if the event type matches the handler.
|
|
1085
1089
|
safelyInvoke(() => {
|
|
1086
1090
|
handlerObject.handler(event.data, checkout);
|
|
1087
1091
|
});
|
|
1088
1092
|
}
|
|
1089
|
-
}
|
|
1093
|
+
}
|
|
1090
1094
|
}
|
|
1091
1095
|
};
|
|
1092
1096
|
// Add messageRouter event listener to the Pop Out
|
|
@@ -1227,7 +1231,7 @@ const handleShowButton = (event, checkout) => {
|
|
|
1227
1231
|
/**
|
|
1228
1232
|
* Remove the pop out button above the embedded iframe
|
|
1229
1233
|
*/
|
|
1230
|
-
const handleRemoveButton = (event,
|
|
1234
|
+
const handleRemoveButton = (event, _checkout) => {
|
|
1231
1235
|
if (event.type === InternalCheckoutEvents.HidePopOutButton) {
|
|
1232
1236
|
removePopOutButton();
|
|
1233
1237
|
}
|
|
@@ -1290,15 +1294,16 @@ const embed = async options => {
|
|
|
1290
1294
|
const {
|
|
1291
1295
|
iframe,
|
|
1292
1296
|
initiate
|
|
1293
|
-
} = createIframeAsync(innerContainer,
|
|
1297
|
+
} = createIframeAsync(innerContainer, url.getSessionUrl({
|
|
1294
1298
|
sid,
|
|
1295
1299
|
endpoint,
|
|
1296
1300
|
language,
|
|
1297
1301
|
ui: options.ui || "inline",
|
|
1298
1302
|
shouldCallValidateSession: onValidateSession !== undefined,
|
|
1299
1303
|
popOut,
|
|
1304
|
+
// biome-ignore lint/suspicious/noPrototypeBuiltins: test
|
|
1300
1305
|
...(options.hasOwnProperty("hideTestMessage") && {
|
|
1301
|
-
hideTestMessage: options
|
|
1306
|
+
hideTestMessage: options.hideTestMessage
|
|
1302
1307
|
})
|
|
1303
1308
|
}));
|
|
1304
1309
|
|
|
@@ -1312,7 +1317,9 @@ const embed = async options => {
|
|
|
1312
1317
|
// Try to remove backdrop if it exists
|
|
1313
1318
|
removeBackdrop();
|
|
1314
1319
|
}
|
|
1315
|
-
|
|
1320
|
+
for (const sub of subscriptions) {
|
|
1321
|
+
sub.unsubscribe();
|
|
1322
|
+
}
|
|
1316
1323
|
if (iframe.parentElement) {
|
|
1317
1324
|
innerContainer.removeChild(iframe);
|
|
1318
1325
|
}
|
|
@@ -1336,7 +1343,9 @@ const embed = async options => {
|
|
|
1336
1343
|
sid,
|
|
1337
1344
|
endpoint,
|
|
1338
1345
|
handler: sessionEvent => {
|
|
1339
|
-
|
|
1346
|
+
for (const sub of eventSubscriptions) {
|
|
1347
|
+
sub.unsubscribe();
|
|
1348
|
+
}
|
|
1340
1349
|
resolve(sessionEvent);
|
|
1341
1350
|
},
|
|
1342
1351
|
eventTypes: [resolveEvent],
|
|
@@ -1347,7 +1356,9 @@ const embed = async options => {
|
|
|
1347
1356
|
sid,
|
|
1348
1357
|
endpoint,
|
|
1349
1358
|
handler: () => {
|
|
1350
|
-
|
|
1359
|
+
for (const sub of eventSubscriptions) {
|
|
1360
|
+
sub.unsubscribe();
|
|
1361
|
+
}
|
|
1351
1362
|
reject(`Received unexpected event: ${rejectEvent}`);
|
|
1352
1363
|
},
|
|
1353
1364
|
eventTypes: [rejectEvent],
|
|
@@ -1387,7 +1398,7 @@ const embed = async options => {
|
|
|
1387
1398
|
* error message. Only used when the embed function in the SDK has a dedicated handler for onPayment, onError etc.
|
|
1388
1399
|
* If no custom handler is set the followHref handler is used instead.
|
|
1389
1400
|
*/
|
|
1390
|
-
const handleWithResult = (
|
|
1401
|
+
const handleWithResult = (_sid, endpoint, handler) => {
|
|
1391
1402
|
return (event, checkout) => {
|
|
1392
1403
|
if (!has_delivered_final_event) {
|
|
1393
1404
|
has_delivered_final_event = true;
|
|
@@ -1399,7 +1410,7 @@ const embed = async options => {
|
|
|
1399
1410
|
}
|
|
1400
1411
|
pairs.push(["language", checkout.language]);
|
|
1401
1412
|
pairs.push(["sdk", pkg.version]);
|
|
1402
|
-
const urlQuery = pairs.filter(([
|
|
1413
|
+
const urlQuery = pairs.filter(([_key, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
|
|
1403
1414
|
checkout.iframe.setAttribute("src", composeUrl(endpoint, "embedResult/", urlQuery));
|
|
1404
1415
|
handler(event, checkout);
|
|
1405
1416
|
}
|
|
@@ -1444,6 +1455,9 @@ const embed = async options => {
|
|
|
1444
1455
|
}, {
|
|
1445
1456
|
handler: scrollToIframeTop,
|
|
1446
1457
|
eventTypes: [InternalCheckoutEvents.ScrollToTop]
|
|
1458
|
+
}, {
|
|
1459
|
+
handler: followHref,
|
|
1460
|
+
eventTypes: [InternalCheckoutEvents.TopLevelNavigation]
|
|
1447
1461
|
}, {
|
|
1448
1462
|
handler: wrappedOnLoadedOrUpdated,
|
|
1449
1463
|
eventTypes: [CheckoutEvents.SessionLoaded, CheckoutEvents.SessionUpdated]
|
|
@@ -1495,10 +1509,10 @@ const embed = async options => {
|
|
|
1495
1509
|
session: undefined,
|
|
1496
1510
|
popOutWindow: undefined
|
|
1497
1511
|
};
|
|
1498
|
-
|
|
1512
|
+
for (const {
|
|
1499
1513
|
handler,
|
|
1500
1514
|
eventTypes
|
|
1501
|
-
})
|
|
1515
|
+
} of handlers) {
|
|
1502
1516
|
if (handler) {
|
|
1503
1517
|
subscriptions.push(subscribe({
|
|
1504
1518
|
sid,
|
|
@@ -1509,7 +1523,7 @@ const embed = async options => {
|
|
|
1509
1523
|
source: checkout.iframe.contentWindow
|
|
1510
1524
|
}));
|
|
1511
1525
|
}
|
|
1512
|
-
}
|
|
1526
|
+
}
|
|
1513
1527
|
|
|
1514
1528
|
// Add iframe to DOM
|
|
1515
1529
|
await initiate();
|