@placetopay/lightbox-sdk 2.1.4 → 2.2.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/dist/core/assemblers.d.ts +1 -1
- package/dist/core/assemblers.js +30 -2
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +5 -4
- package/dist/helpers.d.ts +8 -2
- package/dist/helpers.js +146 -8
- package/dist/types.d.ts +4 -0
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { MountLightboxOptions } from '../types';
|
|
2
|
-
export declare const mountLightbox: ({ id, url, element, callbacks, styles, closeButtonEnabled, enforceStyles, }: MountLightboxOptions) => void;
|
|
2
|
+
export declare const mountLightbox: ({ id, url, element, callbacks, styles, closeButtonEnabled, enforceStyles, allowRedirects, backupTarget, }: MountLightboxOptions) => void;
|
|
3
3
|
export declare const unmountLightbox: (target: string) => void;
|
package/dist/core/assemblers.js
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import { Styles, ElementIds, LightboxEvents as LE } from '../constants';
|
|
2
|
-
import { setStyle, unsetStyle } from '../helpers';
|
|
2
|
+
import { setStyle, unsetStyle, openWithBackup, closePopupByLightboxId, hasOpenedPopup } from '../helpers';
|
|
3
3
|
let listener;
|
|
4
|
-
export const mountLightbox = ({ id, url, element, callbacks, styles, closeButtonEnabled, enforceStyles, }) => {
|
|
4
|
+
export const mountLightbox = ({ id, url, element, callbacks, styles, closeButtonEnabled, enforceStyles, allowRedirects, backupTarget, }) => {
|
|
5
|
+
// Only respect allowRedirects for 'self' redirection
|
|
6
|
+
if (backupTarget === 'self' && !allowRedirects) {
|
|
7
|
+
// If allowRedirects is false and backupTarget is 'self', don't redirect
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
// Check if we need to use fallback behavior for Safari/iOS
|
|
11
|
+
const isSafariOrIOS = navigator.userAgent.match(/iPhone|iPad|iPod/i) ||
|
|
12
|
+
/^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
13
|
+
if (isSafariOrIOS) {
|
|
14
|
+
if (window.self !== window.top) {
|
|
15
|
+
window.parent.postMessage({ type: "placetopay-lightbox:redirect", url }, "*"); // dont change this, it would be a broken change
|
|
16
|
+
}
|
|
17
|
+
// For popup and blank, always allow (ignore allowRedirects)
|
|
18
|
+
// For self, only allow if allowRedirects is true
|
|
19
|
+
if (backupTarget !== 'self' || allowRedirects) {
|
|
20
|
+
openWithBackup(url, backupTarget, id);
|
|
21
|
+
mountListener({ id, callbacks, styles, closeButton: undefined, enforceStyles });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Normal lightbox mounting for non-Safari/iOS browsers
|
|
5
26
|
const wrapper = document.createElement('div');
|
|
6
27
|
wrapper.id = id;
|
|
7
28
|
wrapper.className = ElementIds.WRAPPER_ID;
|
|
@@ -45,6 +66,13 @@ const mountListener = ({ id, callbacks, styles, closeButton, enforceStyles }) =>
|
|
|
45
66
|
globalThis.addEventListener('message', listener);
|
|
46
67
|
};
|
|
47
68
|
export const unmountLightbox = (target) => {
|
|
69
|
+
// Check if there's a popup/window opened for this lightbox ID
|
|
70
|
+
if (hasOpenedPopup(target)) {
|
|
71
|
+
closePopupByLightboxId(target);
|
|
72
|
+
globalThis.removeEventListener('message', listener);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Handle normal lightbox unmounting
|
|
48
76
|
const element = document.getElementById(target);
|
|
49
77
|
if (element) {
|
|
50
78
|
element.remove();
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { InitialOptions, LightboxInstance, ApiStructure, LightboxStyles } from '../types';
|
|
2
2
|
export declare const isInside: () => boolean;
|
|
3
|
-
export declare const updateStyles: (styles: LightboxStyles) =>
|
|
4
|
-
export declare const hideCloseButton: () =>
|
|
3
|
+
export declare const updateStyles: (styles: LightboxStyles) => any;
|
|
4
|
+
export declare const hideCloseButton: () => any;
|
|
5
5
|
export declare const emitClose: (payload?: unknown, preventClose?: boolean) => void;
|
|
6
|
-
export declare const emit: ({ type, payload, preventClose }: ApiStructure) =>
|
|
6
|
+
export declare const emit: ({ type, payload, preventClose }: ApiStructure) => any;
|
|
7
7
|
export declare const createLightbox: (url: string, options?: InitialOptions) => LightboxInstance;
|
package/dist/core/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LightboxEvents as LE } from '../constants';
|
|
2
|
-
import { postMessage
|
|
2
|
+
import { postMessage } from '../helpers';
|
|
3
3
|
import { mountLightbox, unmountLightbox } from './assemblers';
|
|
4
4
|
export const isInside = () => globalThis.location !== globalThis.parent.location;
|
|
5
5
|
export const updateStyles = (styles) => postMessage(LE.UPDATE_STYLES, styles);
|
|
@@ -9,7 +9,7 @@ export const emitClose = (payload, preventClose) => {
|
|
|
9
9
|
};
|
|
10
10
|
export const emit = ({ type, payload, preventClose }) => postMessage(type, payload, preventClose);
|
|
11
11
|
export const createLightbox = (url, options) => {
|
|
12
|
-
var _a, _b, _c, _d, _e, _f;
|
|
12
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
13
13
|
const lightbox = {
|
|
14
14
|
id: (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : new URL(url).origin,
|
|
15
15
|
element: (_b = options === null || options === void 0 ? void 0 : options.element) !== null && _b !== void 0 ? _b : document.body,
|
|
@@ -17,6 +17,7 @@ export const createLightbox = (url, options) => {
|
|
|
17
17
|
callbacks: (_d = options === null || options === void 0 ? void 0 : options.callbacks) !== null && _d !== void 0 ? _d : {},
|
|
18
18
|
closeButton: (_e = options === null || options === void 0 ? void 0 : options.closeButton) !== null && _e !== void 0 ? _e : true,
|
|
19
19
|
styles: (_f = options === null || options === void 0 ? void 0 : options.styles) !== null && _f !== void 0 ? _f : {},
|
|
20
|
+
backupTarget: (_g = options === null || options === void 0 ? void 0 : options.backupTarget) !== null && _g !== void 0 ? _g : 'self',
|
|
20
21
|
url: url,
|
|
21
22
|
close: () => unmountLightbox(lightbox.id),
|
|
22
23
|
updateStyles,
|
|
@@ -26,8 +27,6 @@ export const createLightbox = (url, options) => {
|
|
|
26
27
|
},
|
|
27
28
|
open: () => {
|
|
28
29
|
var _a;
|
|
29
|
-
if (lightbox.allowRedirects)
|
|
30
|
-
redirectBasedOnDriver(url);
|
|
31
30
|
mountLightbox({
|
|
32
31
|
id: lightbox.id,
|
|
33
32
|
url,
|
|
@@ -36,6 +35,8 @@ export const createLightbox = (url, options) => {
|
|
|
36
35
|
styles: lightbox.styles,
|
|
37
36
|
closeButtonEnabled: lightbox.closeButton,
|
|
38
37
|
enforceStyles: (_a = options === null || options === void 0 ? void 0 : options.enforceStyles) !== null && _a !== void 0 ? _a : false,
|
|
38
|
+
allowRedirects: lightbox.allowRedirects,
|
|
39
|
+
backupTarget: lightbox.backupTarget,
|
|
39
40
|
});
|
|
40
41
|
},
|
|
41
42
|
};
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import type { BackupTarget } from './types';
|
|
2
|
+
export declare const postMessage: (type: string, payload?: unknown, preventClose?: boolean) => any;
|
|
2
3
|
export declare const setStyle: (name: string, value: string) => void;
|
|
3
4
|
export declare const unsetStyle: (name: string) => void;
|
|
4
|
-
export declare const
|
|
5
|
+
export declare const mountBackdrop: () => void;
|
|
6
|
+
export declare const unmountBackdrop: () => void;
|
|
7
|
+
export declare const openWithBackup: (url: string, backupTarget?: BackupTarget, lightboxId?: string) => Window;
|
|
8
|
+
export declare const closePopupByLightboxId: (lightboxId: string) => void;
|
|
9
|
+
export declare const hasOpenedPopup: (lightboxId: string) => boolean;
|
|
10
|
+
export declare const getOpenedPopupType: (lightboxId: string) => BackupTarget | null;
|
package/dist/helpers.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const postMessage = (type, payload, preventClose) => {
|
|
2
|
-
|
|
2
|
+
const target = globalThis.opener || globalThis.parent;
|
|
3
|
+
return target.postMessage({ type, preventClose, payload }, '*');
|
|
3
4
|
};
|
|
4
5
|
export const setStyle = (name, value) => {
|
|
5
6
|
document.documentElement.style.setProperty(name, value);
|
|
@@ -7,13 +8,150 @@ export const setStyle = (name, value) => {
|
|
|
7
8
|
export const unsetStyle = (name) => {
|
|
8
9
|
document.documentElement.style.removeProperty(name);
|
|
9
10
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
let openedWindow = null;
|
|
12
|
+
let backdropElement = null;
|
|
13
|
+
const openedWindows = {};
|
|
14
|
+
// Private translations
|
|
15
|
+
const translations = {
|
|
16
|
+
en: {
|
|
17
|
+
popupTitle: 'Popup Opened',
|
|
18
|
+
popupMessage: 'Please complete the process in the popup window. This window will remain blocked until finished.',
|
|
19
|
+
},
|
|
20
|
+
es: {
|
|
21
|
+
popupTitle: 'Popup Abierto',
|
|
22
|
+
popupMessage: 'Por favor, complete el proceso en la ventana emergente. Esta ventana permanecerá bloqueada hasta que finalice.',
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
function getLanguage() {
|
|
26
|
+
const lang = navigator.language || navigator.userLanguage;
|
|
27
|
+
return lang.startsWith('es') ? 'es' : 'en';
|
|
28
|
+
}
|
|
29
|
+
function getText(key) {
|
|
30
|
+
const lang = getLanguage();
|
|
31
|
+
return translations[lang][key];
|
|
32
|
+
}
|
|
33
|
+
export const mountBackdrop = () => {
|
|
34
|
+
if (backdropElement)
|
|
35
|
+
return;
|
|
36
|
+
backdropElement = document.createElement('div');
|
|
37
|
+
backdropElement.className = 'placetopay-lightbox-backdrop-overlay';
|
|
38
|
+
backdropElement.style.cssText = `
|
|
39
|
+
position: fixed;
|
|
40
|
+
top: 0;
|
|
41
|
+
left: 0;
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 100%;
|
|
44
|
+
background-color: rgba(0, 0, 0, 0.7);
|
|
45
|
+
z-index: 9998;
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
50
|
+
`;
|
|
51
|
+
const messageContainer = document.createElement('div');
|
|
52
|
+
messageContainer.className = 'placetopay-lightbox-backdrop-message-container';
|
|
53
|
+
messageContainer.style.cssText = `
|
|
54
|
+
background: linear-gradient(135deg, #1f2937 0%, #111827 100%);
|
|
55
|
+
border-radius: 16px;
|
|
56
|
+
padding: 40px;
|
|
57
|
+
max-width: 420px;
|
|
58
|
+
margin: 20px;
|
|
59
|
+
text-align: center;
|
|
60
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
|
61
|
+
backdrop-filter: blur(20px);
|
|
62
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
63
|
+
`;
|
|
64
|
+
const title = document.createElement('h2');
|
|
65
|
+
title.className = 'placetopay-lightbox-backdrop-title';
|
|
66
|
+
title.textContent = getText('popupTitle');
|
|
67
|
+
title.style.cssText = `
|
|
68
|
+
margin: 0 0 20px 0;
|
|
69
|
+
font-size: 22px;
|
|
70
|
+
font-weight: 700;
|
|
71
|
+
color: #ffffff;
|
|
72
|
+
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
73
|
+
`;
|
|
74
|
+
const message = document.createElement('p');
|
|
75
|
+
message.className = 'placetopay-lightbox-backdrop-message';
|
|
76
|
+
message.textContent = getText('popupMessage');
|
|
77
|
+
message.style.cssText = `
|
|
78
|
+
margin: 0;
|
|
79
|
+
font-size: 15px;
|
|
80
|
+
line-height: 1.6;
|
|
81
|
+
color: #d1d5db;
|
|
82
|
+
opacity: 0.9;
|
|
83
|
+
`;
|
|
84
|
+
messageContainer.appendChild(title);
|
|
85
|
+
messageContainer.appendChild(message);
|
|
86
|
+
backdropElement.appendChild(messageContainer);
|
|
87
|
+
document.body.appendChild(backdropElement);
|
|
88
|
+
document.body.classList.add('placetopay-lightbox-open');
|
|
89
|
+
// Add body styles to prevent scrolling
|
|
90
|
+
document.body.style.overflow = 'hidden';
|
|
91
|
+
// Monitor the popup window
|
|
92
|
+
if (openedWindow) {
|
|
93
|
+
const checkClosed = setInterval(() => {
|
|
94
|
+
if (openedWindow === null || openedWindow === void 0 ? void 0 : openedWindow.closed) {
|
|
95
|
+
clearInterval(checkClosed);
|
|
96
|
+
unmountBackdrop();
|
|
97
|
+
}
|
|
98
|
+
}, 1000);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
export const unmountBackdrop = () => {
|
|
102
|
+
if (backdropElement) {
|
|
103
|
+
document.body.removeChild(backdropElement);
|
|
104
|
+
backdropElement = null;
|
|
105
|
+
}
|
|
106
|
+
// Restore body styles
|
|
107
|
+
document.body.style.overflow = '';
|
|
108
|
+
document.body.classList.remove('placetopay-lightbox-open');
|
|
109
|
+
openedWindow = null;
|
|
110
|
+
};
|
|
111
|
+
export const openWithBackup = (url, backupTarget = 'self', lightboxId) => {
|
|
112
|
+
switch (backupTarget) {
|
|
113
|
+
case 'blank':
|
|
114
|
+
openedWindow = window.open(url, '_blank');
|
|
115
|
+
break;
|
|
116
|
+
case 'popup': {
|
|
117
|
+
const popupWidth = 512;
|
|
118
|
+
const popupHeight = 640;
|
|
119
|
+
// Calculate center position
|
|
120
|
+
const left = (window.screen.width - popupWidth) / 2;
|
|
121
|
+
const top = (window.screen.height - popupHeight) / 2;
|
|
122
|
+
openedWindow = window.open(url, 'placetopay', `popup=true,width=${popupWidth},height=${popupHeight},left=${left},top=${top}`);
|
|
123
|
+
break;
|
|
16
124
|
}
|
|
17
|
-
|
|
125
|
+
case 'self':
|
|
126
|
+
default:
|
|
127
|
+
window.location.href = url;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
if (openedWindow && lightboxId) {
|
|
131
|
+
openedWindows[lightboxId] = { window: openedWindow, type: backupTarget };
|
|
132
|
+
}
|
|
133
|
+
if (openedWindow) {
|
|
134
|
+
mountBackdrop();
|
|
18
135
|
}
|
|
136
|
+
else {
|
|
137
|
+
window.location.href = url;
|
|
138
|
+
}
|
|
139
|
+
return openedWindow;
|
|
140
|
+
};
|
|
141
|
+
export const closePopupByLightboxId = (lightboxId) => {
|
|
142
|
+
const openedWindow = openedWindows[lightboxId];
|
|
143
|
+
if (openedWindow) {
|
|
144
|
+
if (!openedWindow.window.closed) {
|
|
145
|
+
openedWindow.window.close();
|
|
146
|
+
}
|
|
147
|
+
delete openedWindows[lightboxId];
|
|
148
|
+
unmountBackdrop();
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
export const hasOpenedPopup = (lightboxId) => {
|
|
152
|
+
return lightboxId in openedWindows;
|
|
153
|
+
};
|
|
154
|
+
export const getOpenedPopupType = (lightboxId) => {
|
|
155
|
+
const openedWindow = openedWindows[lightboxId];
|
|
156
|
+
return openedWindow ? openedWindow.type : null;
|
|
19
157
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type ClientCallback = (payload?: unknown) => void;
|
|
2
2
|
export type ClientCallbacks = Record<string, ClientCallback | undefined>;
|
|
3
|
+
export type BackupTarget = 'self' | 'popup' | 'blank';
|
|
3
4
|
export type LightboxStyles = Partial<{
|
|
4
5
|
backdropColor: string;
|
|
5
6
|
backdropOpacity: number;
|
|
@@ -26,6 +27,7 @@ export type ExposedOptions = Partial<{
|
|
|
26
27
|
callbacks: ClientCallbacks;
|
|
27
28
|
closeButton: boolean;
|
|
28
29
|
styles: LightboxStyles;
|
|
30
|
+
backupTarget: BackupTarget;
|
|
29
31
|
}>;
|
|
30
32
|
export type InitialOptions = ExposedOptions & InternalOptions;
|
|
31
33
|
export type MountLightboxOptions = {
|
|
@@ -36,6 +38,8 @@ export type MountLightboxOptions = {
|
|
|
36
38
|
styles: LightboxStyles;
|
|
37
39
|
closeButtonEnabled: boolean;
|
|
38
40
|
enforceStyles: boolean;
|
|
41
|
+
allowRedirects: boolean;
|
|
42
|
+
backupTarget: BackupTarget;
|
|
39
43
|
};
|
|
40
44
|
export type MountListenerOptions = {
|
|
41
45
|
id: string;
|
package/package.json
CHANGED