@skrillex1224/playwright-toolkit 2.1.230 → 2.1.231

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/README.md CHANGED
@@ -219,6 +219,7 @@ await page.context().addCookies(cookies);
219
219
 
220
220
  // 全页面滚动截图 (自动检测所有滚动元素,强制展开后截图,默认会执行 watermarkify)
221
221
  // 默认会将返回的 base64 压缩到 5MiB 以内,避免 Apify/Crawlee dataset 单条 item 超限
222
+ // 默认会额外保留一小段安全 buffer;如需精确贴边可传 { buffer: 0 }
222
223
  const base64Image = await Share.captureScreen(page);
223
224
 
224
225
  // 截图只使用当前页面运行时 viewport;移动端请通过 ActorInfo.device 切换,不再通过截图参数覆盖
package/dist/index.cjs CHANGED
@@ -505,6 +505,9 @@ var SUPPORTED_TYPES = /* @__PURE__ */ new Set(["png", "jpeg", "webp"]);
505
505
  var EXPANDED_SCROLLABLE_CLASS = "__pk_expanded__";
506
506
  var DEFAULT_MAX_HEIGHT = 8e3;
507
507
  var DEFAULT_SETTLE_MS = 1e3;
508
+ var DEFAULT_BUFFER_RATIO = 0.25;
509
+ var DEFAULT_BUFFER_MIN = 120;
510
+ var DEFAULT_BUFFER_MAX = 320;
508
511
  var toPositiveNumber = (value, fallback = 0) => {
509
512
  const n = Number(value);
510
513
  if (!Number.isFinite(n) || n <= 0) return fallback;
@@ -514,6 +517,10 @@ var toPositiveInteger = (value, fallback = 0) => {
514
517
  const number = Math.round(Number(value) || 0);
515
518
  return number > 0 ? number : fallback;
516
519
  };
520
+ var resolveDefaultBuffer = (viewport = {}) => {
521
+ const height = Math.max(1, Number(viewport.height) || 0);
522
+ return Math.round(Math.min(DEFAULT_BUFFER_MAX, Math.max(DEFAULT_BUFFER_MIN, height * DEFAULT_BUFFER_RATIO)));
523
+ };
517
524
  var normalizeType = (value) => {
518
525
  const raw = String(value || "png").trim().toLowerCase();
519
526
  if (!SUPPORTED_TYPES.has(raw)) return "png";
@@ -568,7 +575,21 @@ var expandScrollableContent = async (page, options = {}) => {
568
575
  if (Number(style.opacity) === 0) return false;
569
576
  return rect.width > 0 && rect.height > 0;
570
577
  };
571
- const isScrollableY = (el, style) => {
578
+ const rememberOriginalBoxStyles = (el) => {
579
+ if (!el || isDocumentElement(el) || el.classList.contains(className)) {
580
+ return;
581
+ }
582
+ el.dataset.pkOrigOverflow = el.style.overflow;
583
+ el.dataset.pkOrigOverflowPriority = el.style.getPropertyPriority("overflow") || "";
584
+ el.dataset.pkOrigHeight = el.style.height;
585
+ el.dataset.pkOrigHeightPriority = el.style.getPropertyPriority("height") || "";
586
+ el.dataset.pkOrigMinHeight = el.style.minHeight;
587
+ el.dataset.pkOrigMinHeightPriority = el.style.getPropertyPriority("min-height") || "";
588
+ el.dataset.pkOrigMaxHeight = el.style.maxHeight;
589
+ el.dataset.pkOrigMaxHeightPriority = el.style.getPropertyPriority("max-height") || "";
590
+ el.classList.add(className);
591
+ };
592
+ const isScrollableY = (el, style, rect) => {
572
593
  if (!el || el.scrollHeight <= el.clientHeight + 1) {
573
594
  return false;
574
595
  }
@@ -578,7 +599,16 @@ var expandScrollableContent = async (page, options = {}) => {
578
599
  const overflowY = String(style.overflowY || "").toLowerCase();
579
600
  const overflow = String(style.overflow || "").toLowerCase();
580
601
  const scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
581
- return scrollableOverflow.has(overflowY) || scrollableOverflow.has(overflow);
602
+ if (scrollableOverflow.has(overflowY) || scrollableOverflow.has(overflow)) {
603
+ return true;
604
+ }
605
+ const clippingOverflow = /* @__PURE__ */ new Set(["hidden", "clip"]);
606
+ const clipsY = clippingOverflow.has(overflowY) || clippingOverflow.has(overflow);
607
+ if (!clipsY || !rect) {
608
+ return false;
609
+ }
610
+ const viewportHeight = window.innerHeight || 0;
611
+ return rect.height >= viewportHeight * 0.25 || el.scrollHeight >= viewportHeight * 0.75;
582
612
  };
583
613
  const measureNeededHeight = (el) => {
584
614
  if (!el) return 0;
@@ -595,13 +625,42 @@ var expandScrollableContent = async (page, options = {}) => {
595
625
  return documentTop + scrollHeight;
596
626
  };
597
627
  const scrollableElements = [];
628
+ const expandElementToScrollHeight = (el) => {
629
+ if (!el || isDocumentElement(el)) return;
630
+ const scrollHeight = Math.ceil(el.scrollHeight || 0);
631
+ if (scrollHeight <= 0) return;
632
+ rememberOriginalBoxStyles(el);
633
+ el.style.setProperty("overflow", "visible", "important");
634
+ el.style.setProperty("height", `${scrollHeight}px`, "important");
635
+ el.style.setProperty("min-height", `${scrollHeight}px`, "important");
636
+ el.style.setProperty("max-height", "none", "important");
637
+ };
638
+ const expandClippingAncestors = (el) => {
639
+ for (let node = el?.parentElement; node && !isDocumentElement(node); node = node.parentElement) {
640
+ const style = window.getComputedStyle(node);
641
+ const rect = node.getBoundingClientRect();
642
+ if (!isVisible(node, style, rect)) continue;
643
+ const overflowY = String(style.overflowY || "").toLowerCase();
644
+ const overflow = String(style.overflow || "").toLowerCase();
645
+ const clipsContent = ["hidden", "clip", "auto", "scroll", "overlay"].includes(overflowY) || ["hidden", "clip", "auto", "scroll", "overlay"].includes(overflow);
646
+ if (!clipsContent) continue;
647
+ rememberOriginalBoxStyles(node);
648
+ node.style.setProperty("overflow", "visible", "important");
649
+ node.style.setProperty("max-height", "none", "important");
650
+ if (node.scrollHeight > node.clientHeight + 1) {
651
+ const scrollHeight = Math.ceil(node.scrollHeight || 0);
652
+ node.style.setProperty("height", `${scrollHeight}px`, "important");
653
+ node.style.setProperty("min-height", `${scrollHeight}px`, "important");
654
+ }
655
+ }
656
+ };
598
657
  candidates.forEach((el) => {
599
658
  const style = window.getComputedStyle(el);
600
659
  const rect = el.getBoundingClientRect();
601
660
  if (visibleOnly && !isVisible(el, style, rect)) {
602
661
  return;
603
662
  }
604
- if (!isScrollableY(el, style)) {
663
+ if (!isScrollableY(el, style, rect)) {
605
664
  return;
606
665
  }
607
666
  const neededHeight = measureNeededHeight(el);
@@ -615,25 +674,12 @@ var expandScrollableContent = async (page, options = {}) => {
615
674
  if (isDocumentElement(el)) {
616
675
  return;
617
676
  }
618
- if (!el.classList.contains(className)) {
619
- el.dataset.pkOrigOverflow = el.style.overflow;
620
- el.dataset.pkOrigOverflowPriority = el.style.getPropertyPriority("overflow") || "";
621
- el.dataset.pkOrigHeight = el.style.height;
622
- el.dataset.pkOrigHeightPriority = el.style.getPropertyPriority("height") || "";
623
- el.dataset.pkOrigMinHeight = el.style.minHeight;
624
- el.dataset.pkOrigMinHeightPriority = el.style.getPropertyPriority("min-height") || "";
625
- el.dataset.pkOrigMaxHeight = el.style.maxHeight;
626
- el.dataset.pkOrigMaxHeightPriority = el.style.getPropertyPriority("max-height") || "";
627
- el.classList.add(className);
628
- }
677
+ expandClippingAncestors(el);
629
678
  if (forceScrollableHeight) {
630
- const scrollHeight = Math.ceil(el.scrollHeight || 0);
631
- el.style.setProperty("overflow", "visible", "important");
632
- el.style.setProperty("height", `${scrollHeight}px`, "important");
633
- el.style.setProperty("min-height", `${scrollHeight}px`, "important");
634
- el.style.setProperty("max-height", "none", "important");
679
+ expandElementToScrollHeight(el);
635
680
  return;
636
681
  }
682
+ rememberOriginalBoxStyles(el);
637
683
  el.style.overflow = "visible";
638
684
  el.style.height = "auto";
639
685
  el.style.maxHeight = "none";
@@ -653,7 +699,7 @@ var expandScrollableContent = async (page, options = {}) => {
653
699
  };
654
700
  var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
655
701
  const originalViewport = await resolveCurrentViewportSize(page);
656
- const defaultBuffer = Math.round((originalViewport.height || 1080) / 2);
702
+ const defaultBuffer = resolveDefaultBuffer(originalViewport);
657
703
  const buffer = options.buffer ?? defaultBuffer;
658
704
  const maxHeight = toPositiveInteger(options.maxHeight, DEFAULT_MAX_HEIGHT);
659
705
  const settleMs = Math.max(0, Number(options.settleMs ?? DEFAULT_SETTLE_MS) || 0);
@@ -8325,7 +8371,7 @@ var Share = {
8325
8371
  *
8326
8372
  * @param {import('playwright').Page} page
8327
8373
  * @param {Object} [options]
8328
- * @param {number} [options.buffer]
8374
+ * @param {number} [options.buffer] 额外缓冲高度;默认按视口高度自动计算,传 0 可关闭
8329
8375
  * @param {boolean} [options.restore]
8330
8376
  * @param {number} [options.maxHeight]
8331
8377
  * @param {number} [options.maxBytes] 默认 5MiB,返回 base64 超过后会压缩
@@ -8338,7 +8384,7 @@ var Share = {
8338
8384
  const screenshotWatermarkify = resolveCaptureScreenWatermarkify(page, options.watermarkify);
8339
8385
  const compression = resolveImageCompression(options);
8340
8386
  const captureOptions = {
8341
- buffer: options.buffer ?? 0,
8387
+ ...Object.prototype.hasOwnProperty.call(options, "buffer") ? { buffer: options.buffer } : {},
8342
8388
  restore,
8343
8389
  maxHeight: options.maxHeight,
8344
8390
  type: "png",