@uxbertlabs/reportly 1.0.34 → 1.0.36

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,7 +15,7 @@ declare class Screenshot {
15
15
  */
16
16
  private waitForStability;
17
17
  /**
18
- * Wait for all images to finish loading
18
+ * Wait for visible images to finish loading (no page scrolling to avoid annotation misalignment)
19
19
  */
20
20
  private waitForImages;
21
21
  /**
@@ -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;IAmB9B;;OAEG;YACW,aAAa;IA+C3B;;OAEG;YACW,YAAY;IAc1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAKb,OAAO,CAAC,IAAI,GAAE,UAAU,GAAG,UAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;IA0Q1E,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,60 @@ 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 currently loading images (NO scrolling to avoid misalignment)
9335
+ // The onclone callback will handle image src copying
9334
9336
  await this.waitForImages();
9335
9337
  // Wait for fonts to load
9336
9338
  await this.waitForFonts();
9337
- // Additional short wait for any final rendering
9339
+ // Brief wait for final rendering
9338
9340
  await this.wait(100);
9341
+ console.log("✅ Page stabilized and ready for capture");
9339
9342
  }
9340
9343
  /**
9341
- * Wait for all images to finish loading
9344
+ * Wait for visible images to finish loading (no page scrolling to avoid annotation misalignment)
9342
9345
  */
9343
9346
  async waitForImages() {
9344
9347
  const images = Array.from(document.images);
9345
- const imagePromises = images.map(img => {
9346
- if (img.complete) {
9347
- return Promise.resolve();
9348
- }
9348
+ // Filter to only images that are currently loading
9349
+ const loadingImages = images.filter(img => !img.complete || img.naturalHeight === 0);
9350
+ if (loadingImages.length === 0) {
9351
+ console.log("✅ All visible images already loaded");
9352
+ return;
9353
+ }
9354
+ console.log(`⏳ Waiting for ${loadingImages.length} loading images...`);
9355
+ const imagePromises = loadingImages.map(img => {
9349
9356
  return new Promise(resolve => {
9350
- img.addEventListener("load", () => resolve(), {
9357
+ if (img.complete && img.naturalHeight !== 0) {
9358
+ resolve();
9359
+ return;
9360
+ }
9361
+ const onLoad = () => {
9362
+ console.log(`✅ Image loaded`);
9363
+ resolve();
9364
+ };
9365
+ const onError = () => {
9366
+ console.warn(`❌ Image failed to load`);
9367
+ resolve(); // Still resolve to not block
9368
+ };
9369
+ const onTimeout = () => {
9370
+ console.warn(`⏰ Image timed out after 2s`);
9371
+ resolve();
9372
+ };
9373
+ img.addEventListener("load", onLoad, {
9351
9374
  once: true
9352
9375
  });
9353
- img.addEventListener("error", () => resolve(), {
9376
+ img.addEventListener("error", onError, {
9354
9377
  once: true
9355
9378
  });
9356
- // Timeout after 3 seconds for slow images
9357
- setTimeout(() => resolve(), 3000);
9379
+ // Shorter timeout - 2 seconds max
9380
+ setTimeout(onTimeout, 2000);
9358
9381
  });
9359
9382
  });
9360
9383
  await Promise.all(imagePromises);
9384
+ console.log(`✅ All ${loadingImages.length} images processed`);
9361
9385
  }
9362
9386
  /**
9363
9387
  * Wait for fonts to load
@@ -9418,7 +9442,8 @@ class Screenshot {
9418
9442
  y: window.scrollY,
9419
9443
  // Improved rendering options
9420
9444
  backgroundColor: null,
9421
- imageTimeout: 5000,
9445
+ imageTimeout: 15000,
9446
+ // Increased timeout for slow-loading images
9422
9447
  removeContainer: true,
9423
9448
  scale: window.devicePixelRatio || 1,
9424
9449
  onclone: clonedDoc => {
@@ -9435,11 +9460,25 @@ class Screenshot {
9435
9460
  // Disable transitions
9436
9461
  element.style.transition = "none";
9437
9462
  });
9438
- // Ensure lazy-loaded images are visible
9439
- const images = clonedBody.querySelectorAll("img");
9440
- images.forEach(img => {
9441
- img.style.opacity = "1";
9442
- img.style.visibility = "visible";
9463
+ // Process images in the cloned document
9464
+ const originalImages = document.body.querySelectorAll("img");
9465
+ const clonedImages = clonedBody.querySelectorAll("img");
9466
+ clonedImages.forEach((clonedImg, index) => {
9467
+ const originalImg = originalImages[index];
9468
+ if (originalImg) {
9469
+ // Copy the current src from original to ensure it loads
9470
+ clonedImg.src = originalImg.currentSrc || originalImg.src;
9471
+ // Force visibility
9472
+ clonedImg.style.opacity = "1";
9473
+ clonedImg.style.visibility = "visible";
9474
+ clonedImg.style.display = originalImg.style.display || "inline";
9475
+ if (originalImg.width) clonedImg.width = originalImg.width;
9476
+ if (originalImg.height) clonedImg.height = originalImg.height;
9477
+ // Remove lazy loading attributes that might interfere
9478
+ clonedImg.removeAttribute("loading");
9479
+ clonedImg.removeAttribute("data-src");
9480
+ clonedImg.removeAttribute("data-srcset");
9481
+ }
9443
9482
  });
9444
9483
  },
9445
9484
  ignoreElements: element => {
@@ -9472,8 +9511,6 @@ class Screenshot {
9472
9511
  }
9473
9512
  });
9474
9513
  } else {
9475
- // Wait a bit for scroll to settle
9476
- await this.wait(1000);
9477
9514
  // Capture the full page
9478
9515
  canvas = await html2canvas(document.body, {
9479
9516
  useCORS: true,
@@ -9481,7 +9518,8 @@ class Screenshot {
9481
9518
  logging: false,
9482
9519
  // Improved rendering options
9483
9520
  backgroundColor: null,
9484
- imageTimeout: 5000,
9521
+ imageTimeout: 15000,
9522
+ // Increased timeout for slow-loading images
9485
9523
  removeContainer: true,
9486
9524
  scale: window.devicePixelRatio || 1,
9487
9525
  onclone: clonedDoc => {
@@ -9498,11 +9536,25 @@ class Screenshot {
9498
9536
  // Disable transitions
9499
9537
  element.style.transition = "none";
9500
9538
  });
9501
- // Ensure lazy-loaded images are visible
9502
- const images = clonedBody.querySelectorAll("img");
9503
- images.forEach(img => {
9504
- img.style.opacity = "1";
9505
- img.style.visibility = "visible";
9539
+ // Process images in the cloned document
9540
+ const originalImages = document.body.querySelectorAll("img");
9541
+ const clonedImages = clonedBody.querySelectorAll("img");
9542
+ clonedImages.forEach((clonedImg, index) => {
9543
+ const originalImg = originalImages[index];
9544
+ if (originalImg) {
9545
+ // Copy the current src from original to ensure it loads
9546
+ clonedImg.src = originalImg.currentSrc || originalImg.src;
9547
+ // Force visibility
9548
+ clonedImg.style.opacity = "1";
9549
+ clonedImg.style.visibility = "visible";
9550
+ clonedImg.style.display = originalImg.style.display || "inline";
9551
+ if (originalImg.width) clonedImg.width = originalImg.width;
9552
+ if (originalImg.height) clonedImg.height = originalImg.height;
9553
+ // Remove lazy loading attributes that might interfere
9554
+ clonedImg.removeAttribute("loading");
9555
+ clonedImg.removeAttribute("data-src");
9556
+ clonedImg.removeAttribute("data-srcset");
9557
+ }
9506
9558
  });
9507
9559
  },
9508
9560
  ignoreElements: element => {
@@ -11634,28 +11686,74 @@ class AnnotationManager {
11634
11686
  if (tempCtx && this.canvas) {
11635
11687
  // Draw the base screenshot
11636
11688
  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
11689
+ // Determine the actual capture mode used
11690
+ const currentCanvasMode = this.getCurrentMode();
11691
+ const captureMode = mode || currentCanvasMode;
11692
+ console.log('📸 Exporting annotated screenshot:', {
11693
+ currentCanvasMode,
11694
+ captureMode,
11695
+ scrollPosition: {
11696
+ x: window.scrollX,
11697
+ y: window.scrollY
11698
+ },
11699
+ initialScrollPosition: this.initialScrollPosition,
11700
+ canvasSize: {
11701
+ width: this.canvas.width,
11702
+ height: this.canvas.height
11703
+ },
11704
+ screenshotSize: {
11705
+ width: img.width,
11706
+ height: img.height
11707
+ }
11708
+ });
11709
+ // We need to determine if annotations need to be offset
11710
+ // Annotations are stored in absolute page coordinates (with scroll offset added)
11711
+ // Screenshot might be:
11712
+ // - fullpage: captures entire page (no offset needed)
11713
+ // - viewport: captures current viewport (annotations need to be adjusted)
11714
+ if (captureMode === 'viewport') {
11715
+ // Screenshot is only the viewport, so we need to subtract scroll offset from annotations
11716
+ // to align them correctly with the viewport screenshot
11717
+ const scrollOffsetX = this.initialScrollPosition?.x ?? window.scrollX;
11718
+ const scrollOffsetY = this.initialScrollPosition?.y ?? window.scrollY;
11719
+ // Create a temporary canvas with viewport dimensions
11646
11720
  const adjustedCanvas = document.createElement('canvas');
11647
- adjustedCanvas.width = tempCanvas.width;
11648
- adjustedCanvas.height = tempCanvas.height;
11721
+ adjustedCanvas.width = window.innerWidth;
11722
+ adjustedCanvas.height = window.innerHeight;
11649
11723
  const adjustedCtx = adjustedCanvas.getContext('2d');
11650
11724
  if (adjustedCtx) {
11651
- // Draw annotations with scroll offset
11652
- adjustedCtx.drawImage(this.canvas, scrollOffsetX, scrollOffsetY);
11725
+ // Translate context to subtract scroll offset
11726
+ adjustedCtx.translate(-scrollOffsetX, -scrollOffsetY);
11727
+ // Draw the annotations canvas (which is in absolute page coordinates)
11728
+ adjustedCtx.drawImage(this.canvas, 0, 0);
11729
+ // Reset translation
11730
+ adjustedCtx.setTransform(1, 0, 0, 1, 0, 0);
11653
11731
  // Draw the adjusted annotations on top of screenshot
11654
- tempCtx.drawImage(adjustedCanvas, 0, 0);
11732
+ // Scale if screenshot dimensions don't match viewport (due to device pixel ratio)
11733
+ const scaleX = img.width / window.innerWidth;
11734
+ const scaleY = img.height / window.innerHeight;
11735
+ if (scaleX !== 1 || scaleY !== 1) {
11736
+ tempCtx.save();
11737
+ tempCtx.scale(scaleX, scaleY);
11738
+ tempCtx.drawImage(adjustedCanvas, 0, 0);
11739
+ tempCtx.restore();
11740
+ } else {
11741
+ tempCtx.drawImage(adjustedCanvas, 0, 0);
11742
+ }
11655
11743
  }
11656
11744
  } else {
11657
- // Draw annotations directly on top
11658
- tempCtx.drawImage(this.canvas, 0, 0);
11745
+ // Fullpage mode - annotations and screenshot are both in absolute page coordinates
11746
+ // Just need to handle potential scaling due to device pixel ratio
11747
+ const scaleX = img.width / this.canvas.width;
11748
+ const scaleY = img.height / this.canvas.height;
11749
+ if (scaleX !== 1 || scaleY !== 1) {
11750
+ tempCtx.save();
11751
+ tempCtx.scale(scaleX, scaleY);
11752
+ tempCtx.drawImage(this.canvas, 0, 0);
11753
+ tempCtx.restore();
11754
+ } else {
11755
+ tempCtx.drawImage(this.canvas, 0, 0);
11756
+ }
11659
11757
  }
11660
11758
  resolve(tempCanvas.toDataURL('image/png'));
11661
11759
  }