@uxbertlabs/reportly 1.0.34 → 1.0.35

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.
@@ -1 +1 @@
1
- {"version":3,"file":"annotation.d.ts","sourceRoot":"","sources":["../../src/features/annotation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,UAAU,CAAC;AAElE,cAAM,iBAAiB;IACrB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,GAAG,CAAkC;IAC7C,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,qBAAqB,CAA6E;IAC1G,OAAO,CAAC,aAAa,CAAoE;IACzF,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,qBAAqB,CAAkC;;IAqB/D,YAAY,IAAI,iBAAiB;IAqDjC,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,wBAAwB;IAwDhC,IAAI,CAAC,IAAI,GAAE,UAAU,GAAG,UAAuB,GAAG,IAAI;IA8CtD,OAAO,CAAC,YAAY;IAmCpB,IAAI,IAAI,IAAI;IAkBZ,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAInC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,eAAe;IAqCvB,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,aAAa;IAgDrB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,eAAe;IA8DvB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,MAAM;IAmBd,IAAI,IAAI,IAAI;IAOZ,KAAK,IAAI,IAAI;IAMb,cAAc,IAAI,UAAU,GAAG,UAAU;IAInC,yBAAyB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAkDxG,OAAO,IAAI,IAAI;CAOhB;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"annotation.d.ts","sourceRoot":"","sources":["../../src/features/annotation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,UAAU,CAAC;AAElE,cAAM,iBAAiB;IACrB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,GAAG,CAAkC;IAC7C,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,qBAAqB,CAA6E;IAC1G,OAAO,CAAC,aAAa,CAAoE;IACzF,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,qBAAqB,CAAkC;;IAqB/D,YAAY,IAAI,iBAAiB;IAqDjC,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,wBAAwB;IAwDhC,IAAI,CAAC,IAAI,GAAE,UAAU,GAAG,UAAuB,GAAG,IAAI;IA8CtD,OAAO,CAAC,YAAY;IAmCpB,IAAI,IAAI,IAAI;IAkBZ,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAInC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,eAAe;IAqCvB,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,aAAa;IAgDrB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,eAAe;IA8DvB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,MAAM;IAmBd,IAAI,IAAI,IAAI;IAOZ,KAAK,IAAI,IAAI;IAMb,cAAc,IAAI,UAAU,GAAG,UAAU;IAInC,yBAAyB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IA8FxG,OAAO,IAAI,IAAI;CAOhB;AAED,eAAe,iBAAiB,CAAC"}
@@ -15,9 +15,17 @@ declare class Screenshot {
15
15
  */
16
16
  private waitForStability;
17
17
  /**
18
- * Wait for all images to finish loading
18
+ * Wait for CSS animations and transitions to complete
19
+ */
20
+ private waitForAnimations;
21
+ /**
22
+ * Wait for all images to finish loading, including lazy-loaded images
19
23
  */
20
24
  private waitForImages;
25
+ /**
26
+ * Trigger lazy-loading by briefly scrolling through the page
27
+ */
28
+ private triggerLazyLoading;
21
29
  /**
22
30
  * Wait for fonts to load
23
31
  */
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/features/screenshot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AAEvE,cAAM,UAAU;IACd,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAkC;gBAEpC,KAAK,CAAC,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM;IAS9G;;OAEG;IACH,OAAO,CAAC,IAAI;IAIZ;;OAEG;YACW,gBAAgB;IAc9B;;OAEG;YACW,aAAa;IAgB3B;;OAEG;YACW,YAAY;IAc1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAKb,OAAO,CAAC,IAAI,GAAE,UAAU,GAAG,UAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;IAuO1E,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,iBAAiB;IA6DzB,OAAO,CAAC,iBAAiB;IAOzB;;;OAGG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIjC;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAWtC;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;IAIhD;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,KAAK,IAAI,IAAI;CAGd;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/features/screenshot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AAEvE,cAAM,UAAU;IACd,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAkC;gBAEpC,KAAK,CAAC,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM;IAS9G;;OAEG;IACH,OAAO,CAAC,IAAI;IAIZ;;OAEG;YACW,gBAAgB;IAqB9B;;OAEG;YACW,iBAAiB;IAwC/B;;OAEG;YACW,aAAa;IA2C3B;;OAEG;YACW,kBAAkB;IAuChC;;OAEG;YACW,YAAY;IAc1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAKb,OAAO,CAAC,IAAI,GAAE,UAAU,GAAG,UAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;IAuO1E,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,iBAAiB;IA6DzB,OAAO,CAAC,iBAAiB;IAOzB;;;OAGG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIjC;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAWtC;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;IAIhD;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,KAAK,IAAI,IAAI;CAGd;AAED,eAAe,UAAU,CAAC"}
package/dist/index.cjs.js CHANGED
@@ -9328,36 +9328,122 @@ class Screenshot {
9328
9328
  * Wait for animations to complete and DOM to stabilize
9329
9329
  */
9330
9330
  async waitForStability() {
9331
+ console.log('⏳ Waiting for page stability...');
9331
9332
  // Wait for initial stabilization
9332
9333
  await this.wait(this.captureDelay);
9333
- // Wait for images to load
9334
+ // Wait for images to load (includes lazy-load triggering)
9334
9335
  await this.waitForImages();
9335
9336
  // Wait for fonts to load
9336
9337
  await this.waitForFonts();
9337
- // Additional short wait for any final rendering
9338
- await this.wait(100);
9338
+ // Wait for any ongoing animations/transitions to complete
9339
+ await this.waitForAnimations();
9340
+ // Additional wait for final rendering and layout shifts
9341
+ await this.wait(300);
9342
+ console.log('✅ Page stabilized and ready for capture');
9339
9343
  }
9340
9344
  /**
9341
- * Wait for all images to finish loading
9345
+ * Wait for CSS animations and transitions to complete
9346
+ */
9347
+ async waitForAnimations() {
9348
+ // Get all elements with animations or transitions
9349
+ const elements = document.querySelectorAll('*');
9350
+ const animationPromises = [];
9351
+ elements.forEach(element => {
9352
+ const styles = window.getComputedStyle(element);
9353
+ // Check for animations
9354
+ const animationDuration = parseFloat(styles.animationDuration || '0');
9355
+ if (animationDuration > 0) {
9356
+ animationPromises.push(new Promise(resolve => {
9357
+ const timeout = Math.min(animationDuration * 1000, 2000); // Max 2 seconds
9358
+ setTimeout(resolve, timeout);
9359
+ }));
9360
+ }
9361
+ // Check for transitions
9362
+ const transitionDuration = parseFloat(styles.transitionDuration || '0');
9363
+ if (transitionDuration > 0) {
9364
+ animationPromises.push(new Promise(resolve => {
9365
+ const timeout = Math.min(transitionDuration * 1000, 2000); // Max 2 seconds
9366
+ setTimeout(resolve, timeout);
9367
+ }));
9368
+ }
9369
+ });
9370
+ if (animationPromises.length > 0) {
9371
+ console.log(`⏳ Waiting for ${animationPromises.length} animations/transitions...`);
9372
+ await Promise.race([Promise.all(animationPromises), this.wait(2000) // Max 2 seconds total
9373
+ ]);
9374
+ }
9375
+ }
9376
+ /**
9377
+ * Wait for all images to finish loading, including lazy-loaded images
9342
9378
  */
9343
9379
  async waitForImages() {
9380
+ // First, trigger lazy-loading by scrolling through the page
9381
+ await this.triggerLazyLoading();
9382
+ // Now wait for all images to load
9344
9383
  const images = Array.from(document.images);
9345
- const imagePromises = images.map(img => {
9346
- if (img.complete) {
9384
+ console.log(`⏳ Waiting for ${images.length} images to load...`);
9385
+ const imagePromises = images.map((img, index) => {
9386
+ if (img.complete && img.naturalHeight !== 0) {
9347
9387
  return Promise.resolve();
9348
9388
  }
9349
9389
  return new Promise(resolve => {
9350
- img.addEventListener("load", () => resolve(), {
9390
+ const startTime = Date.now();
9391
+ const onLoad = () => {
9392
+ const loadTime = Date.now() - startTime;
9393
+ console.log(`✅ Image ${index + 1} loaded in ${loadTime}ms:`, img.src.substring(0, 80));
9394
+ resolve();
9395
+ };
9396
+ const onError = () => {
9397
+ console.warn(`❌ Image ${index + 1} failed to load:`, img.src.substring(0, 80));
9398
+ resolve(); // Still resolve to not block other images
9399
+ };
9400
+ const onTimeout = () => {
9401
+ console.warn(`⏰ Image ${index + 1} timed out after 5s:`, img.src.substring(0, 80));
9402
+ resolve();
9403
+ };
9404
+ img.addEventListener("load", onLoad, {
9351
9405
  once: true
9352
9406
  });
9353
- img.addEventListener("error", () => resolve(), {
9407
+ img.addEventListener("error", onError, {
9354
9408
  once: true
9355
9409
  });
9356
- // Timeout after 3 seconds for slow images
9357
- setTimeout(() => resolve(), 3000);
9410
+ // Increased timeout to 5 seconds for slow images
9411
+ setTimeout(onTimeout, 5000);
9358
9412
  });
9359
9413
  });
9360
9414
  await Promise.all(imagePromises);
9415
+ console.log(`✅ All ${images.length} images processed`);
9416
+ }
9417
+ /**
9418
+ * Trigger lazy-loading by briefly scrolling through the page
9419
+ */
9420
+ async triggerLazyLoading() {
9421
+ const originalScrollY = window.scrollY;
9422
+ const originalScrollX = window.scrollX;
9423
+ const pageHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
9424
+ console.log(`📜 Triggering lazy-load for page height: ${pageHeight}px`);
9425
+ // Scroll through the page in increments to trigger lazy-loading
9426
+ const scrollIncrement = window.innerHeight;
9427
+ const positions = [];
9428
+ // Generate scroll positions (every viewport height)
9429
+ for (let y = 0; y < pageHeight; y += scrollIncrement) {
9430
+ positions.push(y);
9431
+ }
9432
+ // Add final position
9433
+ if (positions[positions.length - 1] < pageHeight) {
9434
+ positions.push(pageHeight);
9435
+ }
9436
+ // Quickly scroll to each position to trigger lazy-load
9437
+ for (const position of positions) {
9438
+ window.scrollTo(0, position);
9439
+ // Small wait to let intersection observers fire
9440
+ await this.wait(50);
9441
+ }
9442
+ // Scroll back to original position
9443
+ window.scrollTo(originalScrollX, originalScrollY);
9444
+ console.log(`✅ Lazy-load triggered, returned to position: ${originalScrollY}px`);
9445
+ // Wait a bit for lazy-loaded images to start loading
9446
+ await this.wait(200);
9361
9447
  }
9362
9448
  /**
9363
9449
  * Wait for fonts to load
@@ -11634,28 +11720,74 @@ class AnnotationManager {
11634
11720
  if (tempCtx && this.canvas) {
11635
11721
  // Draw the base screenshot
11636
11722
  tempCtx.drawImage(img, 0, 0);
11637
- // If mode is specified and different from current canvas mode, we need to adjust
11638
- const isCanvasInViewportMode = this.canvas.classList.contains('viewport-mode');
11639
- const isTargetFullpage = mode === 'fullpage';
11640
- if (isCanvasInViewportMode && isTargetFullpage) {
11641
- // User drew in viewport mode, but we're capturing fullpage
11642
- // Need to offset annotations by current scroll position
11643
- const scrollOffsetX = window.scrollX;
11644
- const scrollOffsetY = window.scrollY;
11645
- // Create a temporary canvas for adjusted annotations
11723
+ // Determine the actual capture mode used
11724
+ const currentCanvasMode = this.getCurrentMode();
11725
+ const captureMode = mode || currentCanvasMode;
11726
+ console.log('📸 Exporting annotated screenshot:', {
11727
+ currentCanvasMode,
11728
+ captureMode,
11729
+ scrollPosition: {
11730
+ x: window.scrollX,
11731
+ y: window.scrollY
11732
+ },
11733
+ initialScrollPosition: this.initialScrollPosition,
11734
+ canvasSize: {
11735
+ width: this.canvas.width,
11736
+ height: this.canvas.height
11737
+ },
11738
+ screenshotSize: {
11739
+ width: img.width,
11740
+ height: img.height
11741
+ }
11742
+ });
11743
+ // We need to determine if annotations need to be offset
11744
+ // Annotations are stored in absolute page coordinates (with scroll offset added)
11745
+ // Screenshot might be:
11746
+ // - fullpage: captures entire page (no offset needed)
11747
+ // - viewport: captures current viewport (annotations need to be adjusted)
11748
+ if (captureMode === 'viewport') {
11749
+ // Screenshot is only the viewport, so we need to subtract scroll offset from annotations
11750
+ // to align them correctly with the viewport screenshot
11751
+ const scrollOffsetX = this.initialScrollPosition?.x ?? window.scrollX;
11752
+ const scrollOffsetY = this.initialScrollPosition?.y ?? window.scrollY;
11753
+ // Create a temporary canvas with viewport dimensions
11646
11754
  const adjustedCanvas = document.createElement('canvas');
11647
- adjustedCanvas.width = tempCanvas.width;
11648
- adjustedCanvas.height = tempCanvas.height;
11755
+ adjustedCanvas.width = window.innerWidth;
11756
+ adjustedCanvas.height = window.innerHeight;
11649
11757
  const adjustedCtx = adjustedCanvas.getContext('2d');
11650
11758
  if (adjustedCtx) {
11651
- // Draw annotations with scroll offset
11652
- adjustedCtx.drawImage(this.canvas, scrollOffsetX, scrollOffsetY);
11759
+ // Translate context to subtract scroll offset
11760
+ adjustedCtx.translate(-scrollOffsetX, -scrollOffsetY);
11761
+ // Draw the annotations canvas (which is in absolute page coordinates)
11762
+ adjustedCtx.drawImage(this.canvas, 0, 0);
11763
+ // Reset translation
11764
+ adjustedCtx.setTransform(1, 0, 0, 1, 0, 0);
11653
11765
  // Draw the adjusted annotations on top of screenshot
11654
- tempCtx.drawImage(adjustedCanvas, 0, 0);
11766
+ // Scale if screenshot dimensions don't match viewport (due to device pixel ratio)
11767
+ const scaleX = img.width / window.innerWidth;
11768
+ const scaleY = img.height / window.innerHeight;
11769
+ if (scaleX !== 1 || scaleY !== 1) {
11770
+ tempCtx.save();
11771
+ tempCtx.scale(scaleX, scaleY);
11772
+ tempCtx.drawImage(adjustedCanvas, 0, 0);
11773
+ tempCtx.restore();
11774
+ } else {
11775
+ tempCtx.drawImage(adjustedCanvas, 0, 0);
11776
+ }
11655
11777
  }
11656
11778
  } else {
11657
- // Draw annotations directly on top
11658
- tempCtx.drawImage(this.canvas, 0, 0);
11779
+ // Fullpage mode - annotations and screenshot are both in absolute page coordinates
11780
+ // Just need to handle potential scaling due to device pixel ratio
11781
+ const scaleX = img.width / this.canvas.width;
11782
+ const scaleY = img.height / this.canvas.height;
11783
+ if (scaleX !== 1 || scaleY !== 1) {
11784
+ tempCtx.save();
11785
+ tempCtx.scale(scaleX, scaleY);
11786
+ tempCtx.drawImage(this.canvas, 0, 0);
11787
+ tempCtx.restore();
11788
+ } else {
11789
+ tempCtx.drawImage(this.canvas, 0, 0);
11790
+ }
11659
11791
  }
11660
11792
  resolve(tempCanvas.toDataURL('image/png'));
11661
11793
  }