releasebird-javascript-sdk 1.0.47 → 1.0.49
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/build/index.js +1 -1
- package/package.json +1 -1
- package/published/1.0.47/index.js +1 -1
- package/published/1.0.48/index.js +1 -0
- package/published/1.0.49/index.js +1 -0
- package/published/latest/index.js +1 -1
- package/src/RbirdBannerManager.js +24 -1
- package/src/RbirdScreenshotManager.js +148 -10
- package/src/Styles.js +12 -0
- package/webpack.config.js +2 -2
|
@@ -21,6 +21,7 @@ export class RbirdBannerManager {
|
|
|
21
21
|
|
|
22
22
|
init(apiKey) {
|
|
23
23
|
if (typeof window === 'undefined') return;
|
|
24
|
+
console.log('[RbirdBannerManager] Initializing with API key:', apiKey);
|
|
24
25
|
this.apiKey = apiKey;
|
|
25
26
|
this.fetchAndDisplayBanners();
|
|
26
27
|
}
|
|
@@ -29,6 +30,9 @@ export class RbirdBannerManager {
|
|
|
29
30
|
const sessionManager = RbirdSessionManager.getInstance();
|
|
30
31
|
const state = sessionManager.getState();
|
|
31
32
|
|
|
33
|
+
console.log('[RbirdBannerManager] Fetching banners from:', `${API}/ewidget/banners/active`);
|
|
34
|
+
console.log('[RbirdBannerManager] User state:', state);
|
|
35
|
+
|
|
32
36
|
const http = new XMLHttpRequest();
|
|
33
37
|
http.open("GET", `${API}/ewidget/banners/active`);
|
|
34
38
|
http.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
@@ -45,9 +49,11 @@ export class RbirdBannerManager {
|
|
|
45
49
|
const self = this;
|
|
46
50
|
http.onreadystatechange = function () {
|
|
47
51
|
if (http.readyState === 4) {
|
|
52
|
+
console.log('[RbirdBannerManager] Response status:', http.status);
|
|
48
53
|
if (http.status === 200) {
|
|
49
54
|
try {
|
|
50
55
|
const response = JSON.parse(http.responseText);
|
|
56
|
+
console.log('[RbirdBannerManager] Received banners:', response);
|
|
51
57
|
self.banners = response;
|
|
52
58
|
self.renderBanners();
|
|
53
59
|
} catch (exp) {
|
|
@@ -58,28 +64,45 @@ export class RbirdBannerManager {
|
|
|
58
64
|
}
|
|
59
65
|
}
|
|
60
66
|
};
|
|
67
|
+
console.log('[RbirdBannerManager] Sending request...');
|
|
61
68
|
http.send();
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
renderBanners() {
|
|
72
|
+
console.log('[RbirdBannerManager] Rendering banners. Count:', this.banners?.length);
|
|
65
73
|
if (!this.banners || this.banners.length === 0) {
|
|
74
|
+
console.log('[RbirdBannerManager] No banners to render');
|
|
66
75
|
return;
|
|
67
76
|
}
|
|
68
77
|
|
|
69
78
|
this.banners.forEach(banner => {
|
|
79
|
+
console.log('[RbirdBannerManager] Processing banner:', banner.id, 'Type:', banner.type, 'Placement:', banner.placement);
|
|
70
80
|
if (banner.type === 'INLINE') {
|
|
71
81
|
this.renderInlineBanner(banner);
|
|
72
82
|
} else if (banner.type === 'FLOATING') {
|
|
73
83
|
this.renderFloatingBanner(banner);
|
|
84
|
+
} else {
|
|
85
|
+
console.warn('[RbirdBannerManager] Unknown banner type:', banner.type);
|
|
74
86
|
}
|
|
75
87
|
});
|
|
76
88
|
}
|
|
77
89
|
|
|
78
90
|
renderInlineBanner(banner) {
|
|
79
91
|
// Find all elements with data-rbird-banner attribute matching the banner's placement
|
|
80
|
-
const
|
|
92
|
+
const placement = banner.placement || 'default';
|
|
93
|
+
console.log('[RbirdBannerManager] Looking for inline banner placement:', placement);
|
|
94
|
+
const targetElements = document.querySelectorAll(`[data-rbird-banner="${placement}"]`);
|
|
95
|
+
|
|
96
|
+
console.log('[RbirdBannerManager] Found', targetElements.length, 'target elements for placement:', placement);
|
|
97
|
+
|
|
98
|
+
if (targetElements.length === 0) {
|
|
99
|
+
console.warn('[RbirdBannerManager] No target elements found for inline banner with placement:', placement,
|
|
100
|
+
'Make sure you have an element with data-rbird-banner="' + placement + '" in your HTML');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
81
103
|
|
|
82
104
|
targetElements.forEach(targetElement => {
|
|
105
|
+
console.log('[RbirdBannerManager] Appending banner to element:', targetElement);
|
|
83
106
|
const bannerElement = this.createBannerElement(banner, false);
|
|
84
107
|
targetElement.appendChild(bannerElement);
|
|
85
108
|
this.displayedBanners.add(banner.id);
|
|
@@ -110,6 +110,24 @@ export default class RbirdScreenshotManager {
|
|
|
110
110
|
|
|
111
111
|
// Use requestAnimationFrame to ensure the changes are applied before screenshot
|
|
112
112
|
requestAnimationFrame(() => {
|
|
113
|
+
// Temporarily disable external stylesheets to avoid CORS errors
|
|
114
|
+
const externalStylesheets = [];
|
|
115
|
+
const stylesheets = document.querySelectorAll('link[rel="stylesheet"]');
|
|
116
|
+
stylesheets.forEach((stylesheet) => {
|
|
117
|
+
const href = stylesheet.getAttribute('href');
|
|
118
|
+
// Check if it's an external stylesheet (different domain)
|
|
119
|
+
if (href && (href.startsWith('http://') || href.startsWith('https://')) &&
|
|
120
|
+
!href.includes(window.location.hostname)) {
|
|
121
|
+
externalStylesheets.push({
|
|
122
|
+
element: stylesheet,
|
|
123
|
+
disabled: stylesheet.disabled,
|
|
124
|
+
parent: stylesheet.parentNode
|
|
125
|
+
});
|
|
126
|
+
stylesheet.disabled = true;
|
|
127
|
+
console.log('[Screenshot] Temporarily disabling external stylesheet:', href);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
113
131
|
// Use html-to-image's toJpeg method with higher resolution
|
|
114
132
|
// Capture only the visible viewport
|
|
115
133
|
htmlToImage.toJpeg(document.body, {
|
|
@@ -118,6 +136,7 @@ export default class RbirdScreenshotManager {
|
|
|
118
136
|
cacheBust: true,
|
|
119
137
|
width: window.innerWidth,
|
|
120
138
|
height: window.innerHeight,
|
|
139
|
+
skipFonts: true, // Skip web fonts to avoid CORS issues
|
|
121
140
|
style: {
|
|
122
141
|
margin: '0',
|
|
123
142
|
padding: '0'
|
|
@@ -132,8 +151,35 @@ export default class RbirdScreenshotManager {
|
|
|
132
151
|
return false;
|
|
133
152
|
}
|
|
134
153
|
return true;
|
|
154
|
+
},
|
|
155
|
+
onclone: (clonedDocument) => {
|
|
156
|
+
// Remove external stylesheets that may cause CORS issues
|
|
157
|
+
const stylesheets = clonedDocument.querySelectorAll('link[rel="stylesheet"]');
|
|
158
|
+
stylesheets.forEach((stylesheet) => {
|
|
159
|
+
const href = stylesheet.getAttribute('href');
|
|
160
|
+
// Check if it's an external stylesheet (different domain)
|
|
161
|
+
if (href && (href.startsWith('http://') || href.startsWith('https://')) &&
|
|
162
|
+
!href.includes(window.location.hostname)) {
|
|
163
|
+
console.log('[Screenshot] Removing external stylesheet:', href);
|
|
164
|
+
stylesheet.remove();
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Remove any style elements that might have problematic imports
|
|
169
|
+
const styles = clonedDocument.querySelectorAll('style');
|
|
170
|
+
styles.forEach((style) => {
|
|
171
|
+
if (style.textContent && style.textContent.includes('@import')) {
|
|
172
|
+
console.log('[Screenshot] Removing style with @import');
|
|
173
|
+
style.remove();
|
|
174
|
+
}
|
|
175
|
+
});
|
|
135
176
|
}
|
|
136
177
|
}).then(function (dataUrl) {
|
|
178
|
+
// Re-enable external stylesheets
|
|
179
|
+
externalStylesheets.forEach(({element, disabled}) => {
|
|
180
|
+
element.disabled = disabled;
|
|
181
|
+
});
|
|
182
|
+
|
|
137
183
|
// Restore visibility
|
|
138
184
|
loader.style.visibility = 'visible';
|
|
139
185
|
if (closeButton) {
|
|
@@ -156,16 +202,108 @@ export default class RbirdScreenshotManager {
|
|
|
156
202
|
that.deactivateMarker();
|
|
157
203
|
|
|
158
204
|
}).catch((e) => {
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
205
|
+
// Re-enable external stylesheets on error
|
|
206
|
+
externalStylesheets.forEach(({element, disabled}) => {
|
|
207
|
+
element.disabled = disabled;
|
|
208
|
+
});
|
|
209
|
+
console.error('Screenshot error with toJpeg:', e);
|
|
210
|
+
|
|
211
|
+
// Try alternative method: toPng with more lenient options
|
|
212
|
+
console.log('[Screenshot] Trying alternative method with toPng...');
|
|
213
|
+
htmlToImage.toPng(document.body, {
|
|
214
|
+
quality: 0.95,
|
|
215
|
+
pixelRatio: 1, // Lower resolution for fallback
|
|
216
|
+
cacheBust: true,
|
|
217
|
+
width: window.innerWidth,
|
|
218
|
+
height: window.innerHeight,
|
|
219
|
+
skipFonts: true,
|
|
220
|
+
includeQueryParams: false,
|
|
221
|
+
style: {
|
|
222
|
+
margin: '0',
|
|
223
|
+
padding: '0'
|
|
224
|
+
},
|
|
225
|
+
filter: (node) => {
|
|
226
|
+
if (node.id === 'rbirdScreenshotLoader') {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
if (node.classList && node.classList.contains('menu')) {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
// Also filter out external iframes and problematic elements
|
|
233
|
+
if (node.tagName === 'IFRAME' || node.tagName === 'OBJECT' || node.tagName === 'EMBED') {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
return true;
|
|
237
|
+
},
|
|
238
|
+
onclone: (clonedDocument) => {
|
|
239
|
+
// More aggressive cleanup for fallback
|
|
240
|
+
const stylesheets = clonedDocument.querySelectorAll('link[rel="stylesheet"]');
|
|
241
|
+
stylesheets.forEach((stylesheet) => {
|
|
242
|
+
const href = stylesheet.getAttribute('href');
|
|
243
|
+
if (href && (href.startsWith('http://') || href.startsWith('https://')) &&
|
|
244
|
+
!href.includes(window.location.hostname)) {
|
|
245
|
+
stylesheet.remove();
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Remove all external scripts
|
|
250
|
+
const scripts = clonedDocument.querySelectorAll('script');
|
|
251
|
+
scripts.forEach((script) => {
|
|
252
|
+
const src = script.getAttribute('src');
|
|
253
|
+
if (src && (src.startsWith('http://') || src.startsWith('https://')) &&
|
|
254
|
+
!src.includes(window.location.hostname)) {
|
|
255
|
+
script.remove();
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Remove problematic style elements
|
|
260
|
+
const styles = clonedDocument.querySelectorAll('style');
|
|
261
|
+
styles.forEach((style) => {
|
|
262
|
+
if (style.textContent && (style.textContent.includes('@import') || style.textContent.includes('cookiehub'))) {
|
|
263
|
+
style.remove();
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}).then(function (dataUrl) {
|
|
268
|
+
// Re-enable external stylesheets (fallback success)
|
|
269
|
+
// Already re-enabled above, but ensure it's done
|
|
270
|
+
|
|
271
|
+
// Restore visibility
|
|
272
|
+
loader.style.visibility = 'visible';
|
|
273
|
+
if (closeButton) {
|
|
274
|
+
closeButton.style.visibility = originalCloseButtonVisibility;
|
|
275
|
+
}
|
|
276
|
+
if (toolbar) {
|
|
277
|
+
toolbar.style.visibility = originalToolbarVisibility;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
that.hideLoader();
|
|
281
|
+
|
|
282
|
+
const widgetInstance = that.getRbirdWebsiteWidget().getInstance();
|
|
283
|
+
if (widgetInstance.iframe) {
|
|
284
|
+
widgetInstance.iframe.contentWindow?.postMessage({
|
|
285
|
+
type: 'screenshot',
|
|
286
|
+
screenshot: dataUrl
|
|
287
|
+
}, '*');
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
that.deactivateMarker();
|
|
291
|
+
}).catch((fallbackError) => {
|
|
292
|
+
// Re-enable external stylesheets (fallback error)
|
|
293
|
+
// Already re-enabled above, but ensure it's done
|
|
294
|
+
|
|
295
|
+
// Restore visibility on final error
|
|
296
|
+
loader.style.visibility = 'visible';
|
|
297
|
+
if (closeButton) {
|
|
298
|
+
closeButton.style.visibility = originalCloseButtonVisibility;
|
|
299
|
+
}
|
|
300
|
+
if (toolbar) {
|
|
301
|
+
toolbar.style.visibility = originalToolbarVisibility;
|
|
302
|
+
}
|
|
303
|
+
that.hideLoader();
|
|
304
|
+
console.error('Screenshot failed with both methods:', fallbackError);
|
|
305
|
+
alert('Screenshot failed. This page has external resources that prevent screenshots from being captured. Please try on a different page.');
|
|
306
|
+
});
|
|
169
307
|
});
|
|
170
308
|
});
|
|
171
309
|
}, 100);
|
package/src/Styles.js
CHANGED
|
@@ -130,6 +130,18 @@ export const injectStyledCSS = (
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
/* iOS-spezifische Anpassung für dynamische Viewport-Höhe */
|
|
134
|
+
@supports (-webkit-touch-callout: none) {
|
|
135
|
+
.cta__modal {
|
|
136
|
+
height: 100dvh !important;
|
|
137
|
+
max-height: 100dvh !important;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.rbird-content-iframe {
|
|
141
|
+
height: 100dvh !important;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
133
145
|
.cta__modal_loading {
|
|
134
146
|
position: fixed;
|
|
135
147
|
outline: none;
|
package/webpack.config.js
CHANGED
|
@@ -65,8 +65,8 @@ module.exports = {
|
|
|
65
65
|
plugins: [
|
|
66
66
|
new webpack.DefinePlugin({
|
|
67
67
|
PRODUCTION: 'true',
|
|
68
|
-
API: JSON.stringify("
|
|
69
|
-
CONTENT_URL: JSON.stringify("
|
|
68
|
+
API: JSON.stringify("http://localhost:8040/papi"),
|
|
69
|
+
CONTENT_URL: JSON.stringify("http://localhost:4001"),
|
|
70
70
|
}),
|
|
71
71
|
{
|
|
72
72
|
apply: (compiler) => {
|