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