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.
@@ -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 targetElements = document.querySelectorAll(`[data-rbird-banner="${banner.placement || 'default'}"]`);
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
- // Restore visibility on error
160
- loader.style.visibility = 'visible';
161
- if (closeButton) {
162
- closeButton.style.visibility = originalCloseButtonVisibility;
163
- }
164
- if (toolbar) {
165
- toolbar.style.visibility = originalToolbarVisibility;
166
- }
167
- that.hideLoader();
168
- console.error('Screenshot error:', e);
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("https://api.releasebird.com/papi"),
69
- CONTENT_URL: JSON.stringify("https://wcontent.releasebird.net"),
68
+ API: JSON.stringify("http://localhost:8040/papi"),
69
+ CONTENT_URL: JSON.stringify("http://localhost:4001"),
70
70
  }),
71
71
  {
72
72
  apply: (compiler) => {