hocmai-feedback-widget 0.2.0 → 0.2.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.
@@ -2,19 +2,45 @@ import type { Rect, CaptureBounds } from './types';
2
2
 
3
3
  export function calculateCaptureBounds(
4
4
  cropRect: Rect | undefined,
5
- buffer: number
5
+ buffer: number,
6
+ viewportWidth?: number,
7
+ viewportHeight?: number
6
8
  ): CaptureBounds {
9
+ // Use provided viewport dimensions or calculate them
10
+ const getViewportWidth = () => {
11
+ if (viewportWidth !== undefined) return viewportWidth;
12
+ if (window.visualViewport) return window.visualViewport.width;
13
+ return document.documentElement.clientWidth || window.innerWidth;
14
+ };
15
+
16
+ const getViewportHeight = () => {
17
+ if (viewportHeight !== undefined) return viewportHeight;
18
+ if (window.visualViewport) return window.visualViewport.height;
19
+ return document.documentElement.clientHeight || window.innerHeight;
20
+ };
21
+
7
22
  const targetX = cropRect ? cropRect.x : 0;
8
23
  const targetY = cropRect ? cropRect.y : 0;
9
- const targetWidth = cropRect ? cropRect.width : window.innerWidth;
10
- const targetHeight = cropRect ? cropRect.height : window.innerHeight;
24
+ const targetWidth = cropRect ? cropRect.width : getViewportWidth();
25
+ const targetHeight = cropRect ? cropRect.height : getViewportHeight();
11
26
 
12
- return {
27
+ const bounds = {
13
28
  left: targetX - buffer,
14
29
  top: targetY - buffer,
15
30
  right: targetX + targetWidth + buffer,
16
31
  bottom: targetY + targetHeight + buffer
17
32
  };
33
+
34
+ console.log('[ElementCollector] calculateCaptureBounds:', {
35
+ viewportWidth: viewportWidth || 'auto',
36
+ viewportHeight: viewportHeight || 'auto',
37
+ targetWidth,
38
+ targetHeight,
39
+ bounds,
40
+ scroll: { x: window.scrollX, y: window.scrollY }
41
+ });
42
+
43
+ return bounds;
18
44
  }
19
45
 
20
46
  export function isElementInViewport(
@@ -23,12 +49,25 @@ export function isElementInViewport(
23
49
  ): boolean {
24
50
  const rect = element.getBoundingClientRect();
25
51
 
52
+ // Convert bounds from document coordinates to viewport coordinates
53
+ // getBoundingClientRect() returns viewport-relative coordinates
54
+ // bounds are in document coordinates, so subtract scroll offset
55
+ const scrollX = window.scrollX || window.pageXOffset;
56
+ const scrollY = window.scrollY || window.pageYOffset;
57
+
58
+ const viewportBounds = {
59
+ left: bounds.left - scrollX,
60
+ top: bounds.top - scrollY,
61
+ right: bounds.right - scrollX,
62
+ bottom: bounds.bottom - scrollY
63
+ };
64
+
26
65
  // Outside viewport
27
66
  if (
28
- rect.bottom < bounds.top ||
29
- rect.top > bounds.bottom ||
30
- rect.right < bounds.left ||
31
- rect.left > bounds.right
67
+ rect.bottom < viewportBounds.top ||
68
+ rect.top > viewportBounds.bottom ||
69
+ rect.right < viewportBounds.left ||
70
+ rect.left > viewportBounds.right
32
71
  ) {
33
72
  return false;
34
73
  }
@@ -44,7 +83,7 @@ export function isElementInViewport(
44
83
  export function collectVisibleElements(bounds: CaptureBounds): Element[] {
45
84
  const all = Array.from(document.body.getElementsByTagName('*'));
46
85
 
47
- return all.filter(element => {
86
+ const filtered = all.filter(element => {
48
87
  // Skip non-HTML elements
49
88
  if (!(element instanceof HTMLElement)) return false;
50
89
 
@@ -61,6 +100,18 @@ export function collectVisibleElements(bounds: CaptureBounds): Element[] {
61
100
 
62
101
  return isElementInViewport(element as HTMLElement, bounds);
63
102
  });
103
+
104
+ console.log('[ElementCollector] collectVisibleElements:', {
105
+ total: all.length,
106
+ filtered: filtered.length,
107
+ bounds,
108
+ sampleElements: filtered.slice(0, 5).map(el => ({
109
+ tag: el.tagName,
110
+ rect: el.getBoundingClientRect()
111
+ }))
112
+ });
113
+
114
+ return filtered;
64
115
  }
65
116
 
66
117
  export function estimateDOMComplexity(element: HTMLElement): {
@@ -21,6 +21,23 @@ function serializeSVG(svg: SVGElement): string {
21
21
  return svgString;
22
22
  }
23
23
 
24
+ /**
25
+ * Check if SVG contains external resources that might cause CORS issues
26
+ */
27
+ function hasExternalResources(svgString: string): boolean {
28
+ // Check for external image references
29
+ if (svgString.includes('xlink:href="http') || svgString.includes('href="http')) {
30
+ return true;
31
+ }
32
+
33
+ // Check for external font references
34
+ if (svgString.includes('@font-face') && svgString.includes('url(http')) {
35
+ return true;
36
+ }
37
+
38
+ return false;
39
+ }
40
+
24
41
  /**
25
42
  * Render SVG element to canvas
26
43
  */
@@ -45,6 +62,12 @@ export async function renderSVG(
45
62
  // Serialize SVG to string
46
63
  const svgString = serializeSVG(svg);
47
64
 
65
+ // Check for external resources that might cause CORS issues
66
+ if (hasExternalResources(svgString)) {
67
+ console.warn('[SVG] Skipping SVG with external resources to prevent canvas tainting');
68
+ return { success: true }; // Skip but don't fail
69
+ }
70
+
48
71
  // Create blob URL
49
72
  const blob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' });
50
73
  const url = URL.createObjectURL(blob);
@@ -36,11 +36,26 @@ export const captureScreenshot = async (
36
36
  // Tier 2: Fallback to modern-screenshot
37
37
  console.log('[Screenshot] Tier 2: Attempting modern-screenshot...');
38
38
 
39
+ // Use Visual Viewport API for accurate mobile dimensions
40
+ const getViewportWidth = () => {
41
+ if (window.visualViewport) {
42
+ return window.visualViewport.width;
43
+ }
44
+ return document.documentElement.clientWidth || window.innerWidth;
45
+ };
46
+
47
+ const getViewportHeight = () => {
48
+ if (window.visualViewport) {
49
+ return window.visualViewport.height;
50
+ }
51
+ return document.documentElement.clientHeight || window.innerHeight;
52
+ };
53
+
39
54
  const element = document.documentElement;
40
55
  const targetX = cropRect ? cropRect.x : 0;
41
56
  const targetY = cropRect ? cropRect.y : 0;
42
- const targetWidth = cropRect ? cropRect.width : window.innerWidth;
43
- const targetHeight = cropRect ? cropRect.height : window.innerHeight;
57
+ const targetWidth = cropRect ? cropRect.width : getViewportWidth();
58
+ const targetHeight = cropRect ? cropRect.height : getViewportHeight();
44
59
 
45
60
  const scrollX = window.scrollX;
46
61
  const scrollY = window.scrollY;