@skrillex1224/playwright-toolkit 2.1.227 → 2.1.228
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/dist/browser.js.map +2 -2
- package/dist/index.cjs +356 -93
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +356 -93
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -466,6 +466,9 @@ function createInternalLogger(moduleName, explicitLogger) {
|
|
|
466
466
|
};
|
|
467
467
|
}
|
|
468
468
|
|
|
469
|
+
// src/internals/screenshot.js
|
|
470
|
+
var import_delay = __toESM(require("delay"), 1);
|
|
471
|
+
|
|
469
472
|
// src/internals/viewport.js
|
|
470
473
|
var toPositiveInt = (value) => {
|
|
471
474
|
const number = Math.round(Number(value) || 0);
|
|
@@ -499,11 +502,18 @@ var DEFAULT_TIMEOUT_MS = 5e3;
|
|
|
499
502
|
var FORCED_FULLPAGE_TYPE = "jpeg";
|
|
500
503
|
var FORCED_FULLPAGE_QUALITY = 50;
|
|
501
504
|
var SUPPORTED_TYPES = /* @__PURE__ */ new Set(["png", "jpeg", "webp"]);
|
|
505
|
+
var EXPANDED_SCROLLABLE_CLASS = "__pk_expanded__";
|
|
506
|
+
var DEFAULT_MAX_HEIGHT = 8e3;
|
|
507
|
+
var DEFAULT_SETTLE_MS = 1e3;
|
|
502
508
|
var toPositiveNumber = (value, fallback = 0) => {
|
|
503
509
|
const n = Number(value);
|
|
504
510
|
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
505
511
|
return n;
|
|
506
512
|
};
|
|
513
|
+
var toPositiveInteger = (value, fallback = 0) => {
|
|
514
|
+
const number = Math.round(Number(value) || 0);
|
|
515
|
+
return number > 0 ? number : fallback;
|
|
516
|
+
};
|
|
507
517
|
var normalizeType = (value) => {
|
|
508
518
|
const raw = String(value || "png").trim().toLowerCase();
|
|
509
519
|
if (!SUPPORTED_TYPES.has(raw)) return "png";
|
|
@@ -532,6 +542,138 @@ var buildFullPageClip = (metrics, viewport, maxClipHeight) => {
|
|
|
532
542
|
scale: 1
|
|
533
543
|
};
|
|
534
544
|
};
|
|
545
|
+
var expandScrollableContent = async (page, options = {}) => {
|
|
546
|
+
return await page.evaluate(({ className, forceScrollableHeight, visibleOnly }) => {
|
|
547
|
+
const body = document.body;
|
|
548
|
+
const root = document.documentElement;
|
|
549
|
+
const scrollingElement = document.scrollingElement;
|
|
550
|
+
const candidates = [];
|
|
551
|
+
const seen = /* @__PURE__ */ new Set();
|
|
552
|
+
let maxHeight = window.innerHeight || 0;
|
|
553
|
+
const pushCandidate = (el) => {
|
|
554
|
+
if (!el || seen.has(el)) return;
|
|
555
|
+
seen.add(el);
|
|
556
|
+
candidates.push(el);
|
|
557
|
+
};
|
|
558
|
+
pushCandidate(scrollingElement);
|
|
559
|
+
pushCandidate(root);
|
|
560
|
+
pushCandidate(body);
|
|
561
|
+
document.querySelectorAll("*").forEach(pushCandidate);
|
|
562
|
+
const isDocumentElement = (el) => el === root || el === body || el === scrollingElement;
|
|
563
|
+
const isVisible = (el, style, rect) => {
|
|
564
|
+
if (!el || !style || !rect) return false;
|
|
565
|
+
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
|
|
566
|
+
return false;
|
|
567
|
+
}
|
|
568
|
+
if (Number(style.opacity) === 0) return false;
|
|
569
|
+
return rect.width > 0 && rect.height > 0;
|
|
570
|
+
};
|
|
571
|
+
const isScrollableY = (el, style) => {
|
|
572
|
+
if (!el || el.scrollHeight <= el.clientHeight + 1) {
|
|
573
|
+
return false;
|
|
574
|
+
}
|
|
575
|
+
if (isDocumentElement(el)) {
|
|
576
|
+
return true;
|
|
577
|
+
}
|
|
578
|
+
const overflowY = String(style.overflowY || "").toLowerCase();
|
|
579
|
+
const overflow = String(style.overflow || "").toLowerCase();
|
|
580
|
+
const scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
|
|
581
|
+
return scrollableOverflow.has(overflowY) || scrollableOverflow.has(overflow);
|
|
582
|
+
};
|
|
583
|
+
candidates.forEach((el) => {
|
|
584
|
+
const style = window.getComputedStyle(el);
|
|
585
|
+
const rect = el.getBoundingClientRect();
|
|
586
|
+
if (visibleOnly && !isVisible(el, style, rect)) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
if (!isScrollableY(el, style)) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
const scrollHeight = Math.ceil(el.scrollHeight || 0);
|
|
593
|
+
if (scrollHeight <= 0) {
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
if (scrollHeight > maxHeight) {
|
|
597
|
+
maxHeight = scrollHeight;
|
|
598
|
+
}
|
|
599
|
+
if (isDocumentElement(el)) {
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
if (!el.classList.contains(className)) {
|
|
603
|
+
el.dataset.pkOrigOverflow = el.style.overflow;
|
|
604
|
+
el.dataset.pkOrigOverflowPriority = el.style.getPropertyPriority("overflow") || "";
|
|
605
|
+
el.dataset.pkOrigHeight = el.style.height;
|
|
606
|
+
el.dataset.pkOrigHeightPriority = el.style.getPropertyPriority("height") || "";
|
|
607
|
+
el.dataset.pkOrigMinHeight = el.style.minHeight;
|
|
608
|
+
el.dataset.pkOrigMinHeightPriority = el.style.getPropertyPriority("min-height") || "";
|
|
609
|
+
el.dataset.pkOrigMaxHeight = el.style.maxHeight;
|
|
610
|
+
el.dataset.pkOrigMaxHeightPriority = el.style.getPropertyPriority("max-height") || "";
|
|
611
|
+
el.classList.add(className);
|
|
612
|
+
}
|
|
613
|
+
if (forceScrollableHeight) {
|
|
614
|
+
el.style.setProperty("overflow", "visible", "important");
|
|
615
|
+
el.style.setProperty("height", `${scrollHeight}px`, "important");
|
|
616
|
+
el.style.setProperty("min-height", `${scrollHeight}px`, "important");
|
|
617
|
+
el.style.setProperty("max-height", "none", "important");
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
el.style.overflow = "visible";
|
|
621
|
+
el.style.height = "auto";
|
|
622
|
+
el.style.maxHeight = "none";
|
|
623
|
+
});
|
|
624
|
+
return maxHeight;
|
|
625
|
+
}, {
|
|
626
|
+
className: EXPANDED_SCROLLABLE_CLASS,
|
|
627
|
+
forceScrollableHeight: Boolean(options.forceScrollableHeight),
|
|
628
|
+
visibleOnly: options.visibleOnly !== false
|
|
629
|
+
});
|
|
630
|
+
};
|
|
631
|
+
var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
632
|
+
const originalViewport = await resolveCurrentViewportSize(page);
|
|
633
|
+
const defaultBuffer = Math.round((originalViewport.height || 1080) / 2);
|
|
634
|
+
const buffer = options.buffer ?? defaultBuffer;
|
|
635
|
+
const maxHeight = toPositiveInteger(options.maxHeight, DEFAULT_MAX_HEIGHT);
|
|
636
|
+
const settleMs = Math.max(0, Number(options.settleMs ?? DEFAULT_SETTLE_MS) || 0);
|
|
637
|
+
const maxScrollHeight = await expandScrollableContent(page, {
|
|
638
|
+
forceScrollableHeight: options.forceScrollableHeight,
|
|
639
|
+
visibleOnly: options.visibleOnly !== false
|
|
640
|
+
});
|
|
641
|
+
const targetHeight = Math.min(maxScrollHeight + buffer, maxHeight);
|
|
642
|
+
await page.setViewportSize({
|
|
643
|
+
width: originalViewport.width,
|
|
644
|
+
height: targetHeight
|
|
645
|
+
});
|
|
646
|
+
if (settleMs > 0) {
|
|
647
|
+
await (0, import_delay.default)(settleMs);
|
|
648
|
+
}
|
|
649
|
+
return {
|
|
650
|
+
originalViewport,
|
|
651
|
+
maxScrollHeight,
|
|
652
|
+
targetHeight
|
|
653
|
+
};
|
|
654
|
+
};
|
|
655
|
+
var restoreExpandedFullPageScreenshot = async (page, state = {}) => {
|
|
656
|
+
await page.evaluate((className) => {
|
|
657
|
+
document.querySelectorAll(`.${className}`).forEach((el) => {
|
|
658
|
+
el.style.setProperty("overflow", el.dataset.pkOrigOverflow || "", el.dataset.pkOrigOverflowPriority || "");
|
|
659
|
+
el.style.setProperty("height", el.dataset.pkOrigHeight || "", el.dataset.pkOrigHeightPriority || "");
|
|
660
|
+
el.style.setProperty("min-height", el.dataset.pkOrigMinHeight || "", el.dataset.pkOrigMinHeightPriority || "");
|
|
661
|
+
el.style.setProperty("max-height", el.dataset.pkOrigMaxHeight || "", el.dataset.pkOrigMaxHeightPriority || "");
|
|
662
|
+
delete el.dataset.pkOrigOverflow;
|
|
663
|
+
delete el.dataset.pkOrigOverflowPriority;
|
|
664
|
+
delete el.dataset.pkOrigHeight;
|
|
665
|
+
delete el.dataset.pkOrigHeightPriority;
|
|
666
|
+
delete el.dataset.pkOrigMinHeight;
|
|
667
|
+
delete el.dataset.pkOrigMinHeightPriority;
|
|
668
|
+
delete el.dataset.pkOrigMaxHeight;
|
|
669
|
+
delete el.dataset.pkOrigMaxHeightPriority;
|
|
670
|
+
el.classList.remove(className);
|
|
671
|
+
});
|
|
672
|
+
}, EXPANDED_SCROLLABLE_CLASS);
|
|
673
|
+
if (state?.originalViewport) {
|
|
674
|
+
await page.setViewportSize(state.originalViewport);
|
|
675
|
+
}
|
|
676
|
+
};
|
|
535
677
|
var capturePageScreenshot = async (page, options = {}) => {
|
|
536
678
|
const fullPage = Boolean(options.fullPage);
|
|
537
679
|
const type = fullPage ? FORCED_FULLPAGE_TYPE : normalizeType(options.type);
|
|
@@ -585,6 +727,22 @@ var capturePageScreenshot = async (page, options = {}) => {
|
|
|
585
727
|
return await page.screenshot(fallbackOptions);
|
|
586
728
|
}
|
|
587
729
|
};
|
|
730
|
+
var captureExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
731
|
+
const state = await prepareExpandedFullPageScreenshot(page, options);
|
|
732
|
+
try {
|
|
733
|
+
return await capturePageScreenshot(page, {
|
|
734
|
+
fullPage: true,
|
|
735
|
+
type: options.type || "png",
|
|
736
|
+
quality: options.quality,
|
|
737
|
+
timeout: options.timeout,
|
|
738
|
+
maxClipHeight: state.targetHeight
|
|
739
|
+
});
|
|
740
|
+
} finally {
|
|
741
|
+
if (options.restore) {
|
|
742
|
+
await restoreExpandedFullPageScreenshot(page, state);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
};
|
|
588
746
|
|
|
589
747
|
// src/errors.js
|
|
590
748
|
var errors_exports = {};
|
|
@@ -2124,7 +2282,7 @@ var AntiCheat = {
|
|
|
2124
2282
|
};
|
|
2125
2283
|
|
|
2126
2284
|
// src/internals/humanize/desktop.js
|
|
2127
|
-
var
|
|
2285
|
+
var import_delay2 = __toESM(require("delay"), 1);
|
|
2128
2286
|
var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
|
|
2129
2287
|
var logger6 = createInternalLogger("Humanize");
|
|
2130
2288
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -2356,7 +2514,7 @@ var Humanize = {
|
|
|
2356
2514
|
}
|
|
2357
2515
|
await page.mouse.wheel(0, deltaY);
|
|
2358
2516
|
didScroll = true;
|
|
2359
|
-
await (0,
|
|
2517
|
+
await (0, import_delay2.default)(this.jitterMs(20 + Math.random() * 40, 0.2));
|
|
2360
2518
|
}
|
|
2361
2519
|
logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
2362
2520
|
return { element, didScroll };
|
|
@@ -2385,7 +2543,7 @@ var Humanize = {
|
|
|
2385
2543
|
restoreOnce.restored = true;
|
|
2386
2544
|
if (typeof restoreOnce.do !== "function") return;
|
|
2387
2545
|
try {
|
|
2388
|
-
await (0,
|
|
2546
|
+
await (0, import_delay2.default)(this.jitterMs(1e3));
|
|
2389
2547
|
await restoreOnce.do();
|
|
2390
2548
|
} catch (restoreError) {
|
|
2391
2549
|
logger6.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
@@ -2393,7 +2551,7 @@ var Humanize = {
|
|
|
2393
2551
|
};
|
|
2394
2552
|
try {
|
|
2395
2553
|
if (target == null) {
|
|
2396
|
-
await (0,
|
|
2554
|
+
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
2397
2555
|
await cursor.actions.click();
|
|
2398
2556
|
logger6.success("humanClick", "Clicked current position");
|
|
2399
2557
|
return true;
|
|
@@ -2427,7 +2585,7 @@ var Humanize = {
|
|
|
2427
2585
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
2428
2586
|
const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;
|
|
2429
2587
|
await cursor.actions.move({ x, y });
|
|
2430
|
-
await (0,
|
|
2588
|
+
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
2431
2589
|
await cursor.actions.click();
|
|
2432
2590
|
await restoreOnce();
|
|
2433
2591
|
logger6.success("humanClick");
|
|
@@ -2446,7 +2604,7 @@ var Humanize = {
|
|
|
2446
2604
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
2447
2605
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
2448
2606
|
logger6.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
2449
|
-
await (0,
|
|
2607
|
+
await (0, import_delay2.default)(ms);
|
|
2450
2608
|
logger6.success("randomSleep");
|
|
2451
2609
|
},
|
|
2452
2610
|
/**
|
|
@@ -2464,7 +2622,7 @@ var Humanize = {
|
|
|
2464
2622
|
const x = 100 + Math.random() * (viewportSize.width - 200);
|
|
2465
2623
|
const y = 100 + Math.random() * (viewportSize.height - 200);
|
|
2466
2624
|
await cursor.actions.move({ x, y });
|
|
2467
|
-
await (0,
|
|
2625
|
+
await (0, import_delay2.default)(this.jitterMs(600, 0.5));
|
|
2468
2626
|
}
|
|
2469
2627
|
logger6.success("simulateGaze");
|
|
2470
2628
|
},
|
|
@@ -2488,7 +2646,7 @@ var Humanize = {
|
|
|
2488
2646
|
try {
|
|
2489
2647
|
const locator = page.locator(selector);
|
|
2490
2648
|
await Humanize.humanClick(page, locator);
|
|
2491
|
-
await (0,
|
|
2649
|
+
await (0, import_delay2.default)(this.jitterMs(200, 0.4));
|
|
2492
2650
|
for (let i = 0; i < text.length; i++) {
|
|
2493
2651
|
const char = text[i];
|
|
2494
2652
|
let charDelay;
|
|
@@ -2500,11 +2658,11 @@ var Humanize = {
|
|
|
2500
2658
|
charDelay = this.jitterMs(baseDelay, 0.4);
|
|
2501
2659
|
}
|
|
2502
2660
|
await page.keyboard.type(char);
|
|
2503
|
-
await (0,
|
|
2661
|
+
await (0, import_delay2.default)(charDelay);
|
|
2504
2662
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
2505
2663
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
2506
2664
|
logger6.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
2507
|
-
await (0,
|
|
2665
|
+
await (0, import_delay2.default)(pauseTime);
|
|
2508
2666
|
}
|
|
2509
2667
|
}
|
|
2510
2668
|
logger6.success("humanType");
|
|
@@ -2538,7 +2696,7 @@ var Humanize = {
|
|
|
2538
2696
|
if (hasTarget) {
|
|
2539
2697
|
await this.humanClick(page, targetOrKey, { reactionDelay: focusDelay, scrollIfNeeded, throwOnMissing });
|
|
2540
2698
|
}
|
|
2541
|
-
await (0,
|
|
2699
|
+
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.45));
|
|
2542
2700
|
await page.keyboard.press(key, {
|
|
2543
2701
|
...keyboardOptions,
|
|
2544
2702
|
delay: this.jitterMs(holdDelay, 0.5)
|
|
@@ -2560,14 +2718,14 @@ var Humanize = {
|
|
|
2560
2718
|
try {
|
|
2561
2719
|
const locator = page.locator(selector);
|
|
2562
2720
|
await locator.click();
|
|
2563
|
-
await (0,
|
|
2721
|
+
await (0, import_delay2.default)(this.jitterMs(200, 0.4));
|
|
2564
2722
|
const currentValue = await locator.inputValue();
|
|
2565
2723
|
if (!currentValue || currentValue.length === 0) {
|
|
2566
2724
|
logger6.success("humanClear", "already empty");
|
|
2567
2725
|
return;
|
|
2568
2726
|
}
|
|
2569
2727
|
await page.keyboard.press("Meta+A");
|
|
2570
|
-
await (0,
|
|
2728
|
+
await (0, import_delay2.default)(this.jitterMs(100, 0.4));
|
|
2571
2729
|
await page.keyboard.press("Backspace");
|
|
2572
2730
|
logger6.success("humanClear");
|
|
2573
2731
|
} catch (error) {
|
|
@@ -2593,13 +2751,13 @@ var Humanize = {
|
|
|
2593
2751
|
const x = 100 + Math.random() * (viewportSize.width - 200);
|
|
2594
2752
|
const y = 100 + Math.random() * (viewportSize.height - 200);
|
|
2595
2753
|
await cursor.actions.move({ x, y });
|
|
2596
|
-
await (0,
|
|
2754
|
+
await (0, import_delay2.default)(this.jitterMs(350, 0.4));
|
|
2597
2755
|
} else if (action < 0.7) {
|
|
2598
2756
|
const scrollY = (Math.random() - 0.5) * 200;
|
|
2599
2757
|
await page.mouse.wheel(0, scrollY);
|
|
2600
|
-
await (0,
|
|
2758
|
+
await (0, import_delay2.default)(this.jitterMs(500, 0.4));
|
|
2601
2759
|
} else {
|
|
2602
|
-
await (0,
|
|
2760
|
+
await (0, import_delay2.default)(this.jitterMs(800, 0.5));
|
|
2603
2761
|
}
|
|
2604
2762
|
}
|
|
2605
2763
|
logger6.success("warmUpBrowsing");
|
|
@@ -2628,7 +2786,7 @@ var Humanize = {
|
|
|
2628
2786
|
const scrollAmount = stepDistance * factor * sign * jitter;
|
|
2629
2787
|
await page.mouse.wheel(0, scrollAmount);
|
|
2630
2788
|
const baseDelay = 60 + i * 25;
|
|
2631
|
-
await (0,
|
|
2789
|
+
await (0, import_delay2.default)(this.jitterMs(baseDelay, 0.3));
|
|
2632
2790
|
}
|
|
2633
2791
|
logger6.success("naturalScroll");
|
|
2634
2792
|
} catch (error) {
|
|
@@ -2774,7 +2932,7 @@ var MachineHumanize = {
|
|
|
2774
2932
|
};
|
|
2775
2933
|
|
|
2776
2934
|
// src/internals/humanize/shared.js
|
|
2777
|
-
var
|
|
2935
|
+
var import_delay3 = __toESM(require("delay"), 1);
|
|
2778
2936
|
var jitterMs = (base, jitterPercent = 0.3) => {
|
|
2779
2937
|
const jitter = Number(base || 0) * Number(jitterPercent || 0) * (Math.random() * 2 - 1);
|
|
2780
2938
|
return Math.max(10, Math.round(Number(base || 0) + jitter));
|
|
@@ -2800,7 +2958,7 @@ var resolveElement = async (page, target, { throwOnMissing = true } = {}) => {
|
|
|
2800
2958
|
}
|
|
2801
2959
|
return element;
|
|
2802
2960
|
};
|
|
2803
|
-
var waitJitter = (base, jitterPercent = 0.3) => (0,
|
|
2961
|
+
var waitJitter = (base, jitterPercent = 0.3) => (0, import_delay3.default)(jitterMs(base, jitterPercent));
|
|
2804
2962
|
|
|
2805
2963
|
// src/internals/humanize/mobile.js
|
|
2806
2964
|
var logger7 = createInternalLogger("Humanize.Mobile");
|
|
@@ -3601,8 +3759,8 @@ var callDelegate = (method, page, args) => {
|
|
|
3601
3759
|
return delegate[method](page, ...args);
|
|
3602
3760
|
};
|
|
3603
3761
|
var Humanize2 = {
|
|
3604
|
-
// M = Machine: native/mechanical operations for
|
|
3605
|
-
//
|
|
3762
|
+
// M = Machine: native/mechanical operations for兼容路径。
|
|
3763
|
+
// 这组 API 不做人类化处理,只保留原生 click / focus / fill / type 等语义。
|
|
3606
3764
|
M: MachineHumanize,
|
|
3607
3765
|
jitterMs(base, jitterPercent = 0.3) {
|
|
3608
3766
|
return Humanize.jitterMs(base, jitterPercent);
|
|
@@ -6109,7 +6267,7 @@ var Logger = {
|
|
|
6109
6267
|
};
|
|
6110
6268
|
|
|
6111
6269
|
// src/share.js
|
|
6112
|
-
var
|
|
6270
|
+
var import_delay4 = __toESM(require("delay"), 1);
|
|
6113
6271
|
|
|
6114
6272
|
// src/internals/watermarkify.js
|
|
6115
6273
|
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
@@ -6143,6 +6301,18 @@ var DEFAULT_STRIP_PROMPT_MAX_LINES = 3;
|
|
|
6143
6301
|
var DEFAULT_STRIP_CONTENT_SAFE_PADDING_X = 12;
|
|
6144
6302
|
var DEFAULT_STRIP_TEXT_WIDTH_SAFETY = 10;
|
|
6145
6303
|
var DEFAULT_BROWSER_COMPOSITOR_VIEWPORT_HEIGHT = 1200;
|
|
6304
|
+
var MOBILE_STRIP_HEIGHT = 104;
|
|
6305
|
+
var MOBILE_STRIP_PADDING_X = 14;
|
|
6306
|
+
var MOBILE_STRIP_PADDING_Y = 13;
|
|
6307
|
+
var MOBILE_STRIP_ROW_HEIGHT = 22;
|
|
6308
|
+
var MOBILE_STRIP_ROW_GAP = 7;
|
|
6309
|
+
var MOBILE_STRIP_LABEL_FONT_SIZE = 12.5;
|
|
6310
|
+
var MOBILE_STRIP_VALUE_FONT_SIZE = 13.5;
|
|
6311
|
+
var MOBILE_STRIP_LABEL_WIDTH = 45;
|
|
6312
|
+
var MOBILE_STRIP_PROMPT_LABEL_WIDTH = 60;
|
|
6313
|
+
var MOBILE_STRIP_LOC_LABEL_WIDTH = 30;
|
|
6314
|
+
var MOBILE_STRIP_IP_LABEL_WIDTH = 22;
|
|
6315
|
+
var MOBILE_STRIP_META_GAP = 12;
|
|
6146
6316
|
var WEAK_LOCATION_VALUES = /* @__PURE__ */ new Set(["cn", "\u4E2D\u56FD"]);
|
|
6147
6317
|
var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
6148
6318
|
/(?:中国)?移动$/i,
|
|
@@ -6927,10 +7097,16 @@ var resolveScreenshotWatermarkifyMeta = async (page, options = {}) => {
|
|
|
6927
7097
|
}),
|
|
6928
7098
|
watermark: options.watermark,
|
|
6929
7099
|
strip: options.strip,
|
|
6930
|
-
stripLogoSrc
|
|
7100
|
+
stripLogoSrc,
|
|
7101
|
+
device: resolvePageDevice(page)
|
|
6931
7102
|
};
|
|
6932
7103
|
};
|
|
6933
7104
|
var buildFontFamily = () => 'MiSans, "SF Pro Display", "PingFang SC", "Helvetica Neue", Arial, sans-serif';
|
|
7105
|
+
var resolvePageDevice = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
7106
|
+
var findStripSegment = (segments, kind) => {
|
|
7107
|
+
const found = Array.isArray(segments) ? segments.find((segment) => segment?.kind === kind) : null;
|
|
7108
|
+
return found && typeof found === "object" ? found : {};
|
|
7109
|
+
};
|
|
6934
7110
|
var buildStripSegmentLayout = (segment, options = {}) => {
|
|
6935
7111
|
const label = normalizeWhitespace(segment?.label || "");
|
|
6936
7112
|
const rawValue = normalizeWhitespace(segment?.rawValue || segment?.value || "-") || "-";
|
|
@@ -7258,6 +7434,116 @@ var renderStripDivider = (x, centerY, height) => {
|
|
|
7258
7434
|
/>
|
|
7259
7435
|
`;
|
|
7260
7436
|
};
|
|
7437
|
+
var renderMobileStripText = ({
|
|
7438
|
+
label,
|
|
7439
|
+
value,
|
|
7440
|
+
labelX,
|
|
7441
|
+
y,
|
|
7442
|
+
valueWidth,
|
|
7443
|
+
labelWidth = MOBILE_STRIP_LABEL_WIDTH,
|
|
7444
|
+
fontFamily
|
|
7445
|
+
}) => {
|
|
7446
|
+
const safeLabel = normalizeWhitespace(label) || "-";
|
|
7447
|
+
const safeValue = fitTextWithEllipsis(
|
|
7448
|
+
Array.from(normalizeWhitespace(value) || "-"),
|
|
7449
|
+
Math.max(18, valueWidth),
|
|
7450
|
+
MOBILE_STRIP_VALUE_FONT_SIZE
|
|
7451
|
+
);
|
|
7452
|
+
return `
|
|
7453
|
+
<text
|
|
7454
|
+
x="${labelX}"
|
|
7455
|
+
y="${y}"
|
|
7456
|
+
fill="#111111"
|
|
7457
|
+
fill-opacity="0.54"
|
|
7458
|
+
font-family="${fontFamily}"
|
|
7459
|
+
font-size="${MOBILE_STRIP_LABEL_FONT_SIZE}"
|
|
7460
|
+
font-weight="650"
|
|
7461
|
+
dominant-baseline="middle"
|
|
7462
|
+
>${escapeXml(safeLabel)}</text>
|
|
7463
|
+
<text
|
|
7464
|
+
x="${labelX + labelWidth}"
|
|
7465
|
+
y="${y}"
|
|
7466
|
+
fill="#111111"
|
|
7467
|
+
font-family="${fontFamily}"
|
|
7468
|
+
font-size="${MOBILE_STRIP_VALUE_FONT_SIZE}"
|
|
7469
|
+
font-weight="730"
|
|
7470
|
+
dominant-baseline="middle"
|
|
7471
|
+
>${escapeXml(safeValue)}</text>
|
|
7472
|
+
`;
|
|
7473
|
+
};
|
|
7474
|
+
var renderMobileStrip = ({ meta, width, height, fontFamily }) => {
|
|
7475
|
+
const stripHeight = MOBILE_STRIP_HEIGHT;
|
|
7476
|
+
const stripY = height - stripHeight;
|
|
7477
|
+
const contentX = MOBILE_STRIP_PADDING_X;
|
|
7478
|
+
const contentWidth = Math.max(1, width - MOBILE_STRIP_PADDING_X * 2);
|
|
7479
|
+
const prompt = findStripSegment(meta.stripSegments, "prompt");
|
|
7480
|
+
const time = findStripSegment(meta.stripSegments, "time");
|
|
7481
|
+
const location = findStripSegment(meta.stripSegments, "location");
|
|
7482
|
+
const ip = findStripSegment(meta.stripSegments, "ip");
|
|
7483
|
+
const row1Y = stripY + MOBILE_STRIP_PADDING_Y + MOBILE_STRIP_ROW_HEIGHT / 2;
|
|
7484
|
+
const row2Y = row1Y + MOBILE_STRIP_ROW_HEIGHT + MOBILE_STRIP_ROW_GAP;
|
|
7485
|
+
const row3Y = row2Y + MOBILE_STRIP_ROW_HEIGHT + MOBILE_STRIP_ROW_GAP;
|
|
7486
|
+
const promptValueWidth = contentWidth - MOBILE_STRIP_PROMPT_LABEL_WIDTH;
|
|
7487
|
+
const locValueX = contentX + MOBILE_STRIP_LOC_LABEL_WIDTH;
|
|
7488
|
+
const ipLabelX = Math.min(
|
|
7489
|
+
width - MOBILE_STRIP_PADDING_X - MOBILE_STRIP_IP_LABEL_WIDTH - 70,
|
|
7490
|
+
Math.max(
|
|
7491
|
+
locValueX + 80 + MOBILE_STRIP_META_GAP,
|
|
7492
|
+
contentX + Math.round(contentWidth * 0.52)
|
|
7493
|
+
)
|
|
7494
|
+
);
|
|
7495
|
+
const locValueWidth = Math.max(
|
|
7496
|
+
28,
|
|
7497
|
+
ipLabelX - locValueX - MOBILE_STRIP_META_GAP
|
|
7498
|
+
);
|
|
7499
|
+
const ipValueWidth = Math.max(
|
|
7500
|
+
28,
|
|
7501
|
+
width - MOBILE_STRIP_PADDING_X - (ipLabelX + MOBILE_STRIP_IP_LABEL_WIDTH)
|
|
7502
|
+
);
|
|
7503
|
+
return `
|
|
7504
|
+
<g id="strip">
|
|
7505
|
+
<rect x="0" y="${stripY}" width="${width}" height="${stripHeight}" fill="#ffffff" fill-opacity="0.985" />
|
|
7506
|
+
<rect x="0" y="${stripY}" width="${width}" height="1" fill="#111111" fill-opacity="0.10" />
|
|
7507
|
+
<rect x="${contentX}" y="${stripY}" width="${Math.max(96, Math.round(width * 0.36))}" height="2" fill="url(#stripAccent)" />
|
|
7508
|
+
${renderMobileStripText({
|
|
7509
|
+
label: "Prompt",
|
|
7510
|
+
value: prompt.rawValue || prompt.value || "-",
|
|
7511
|
+
labelX: contentX,
|
|
7512
|
+
y: row1Y,
|
|
7513
|
+
valueWidth: promptValueWidth,
|
|
7514
|
+
labelWidth: MOBILE_STRIP_PROMPT_LABEL_WIDTH,
|
|
7515
|
+
fontFamily
|
|
7516
|
+
})}
|
|
7517
|
+
${renderMobileStripText({
|
|
7518
|
+
label: "Time",
|
|
7519
|
+
value: time.rawValue || time.value || "-",
|
|
7520
|
+
labelX: contentX,
|
|
7521
|
+
y: row2Y,
|
|
7522
|
+
valueWidth: promptValueWidth,
|
|
7523
|
+
labelWidth: MOBILE_STRIP_LABEL_WIDTH,
|
|
7524
|
+
fontFamily
|
|
7525
|
+
})}
|
|
7526
|
+
${renderMobileStripText({
|
|
7527
|
+
label: "Loc",
|
|
7528
|
+
value: location.rawValue || location.value || "-",
|
|
7529
|
+
labelX: contentX,
|
|
7530
|
+
y: row3Y,
|
|
7531
|
+
valueWidth: locValueWidth,
|
|
7532
|
+
labelWidth: MOBILE_STRIP_LOC_LABEL_WIDTH,
|
|
7533
|
+
fontFamily
|
|
7534
|
+
})}
|
|
7535
|
+
${renderMobileStripText({
|
|
7536
|
+
label: "IP",
|
|
7537
|
+
value: ip.rawValue || ip.value || "-",
|
|
7538
|
+
labelX: ipLabelX,
|
|
7539
|
+
y: row3Y,
|
|
7540
|
+
valueWidth: ipValueWidth,
|
|
7541
|
+
labelWidth: MOBILE_STRIP_IP_LABEL_WIDTH,
|
|
7542
|
+
fontFamily
|
|
7543
|
+
})}
|
|
7544
|
+
</g>
|
|
7545
|
+
`;
|
|
7546
|
+
};
|
|
7261
7547
|
var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
7262
7548
|
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
|
|
7263
7549
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
@@ -7306,6 +7592,27 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
7306
7592
|
parts.push(`<g id="watermarks">${stamps.join("")}</g>`);
|
|
7307
7593
|
}
|
|
7308
7594
|
if (hasStrip) {
|
|
7595
|
+
if (normalizeDevice(meta.device) === Device.Mobile) {
|
|
7596
|
+
parts.push(renderMobileStrip({
|
|
7597
|
+
meta,
|
|
7598
|
+
width,
|
|
7599
|
+
height,
|
|
7600
|
+
fontFamily
|
|
7601
|
+
}));
|
|
7602
|
+
return `
|
|
7603
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
|
7604
|
+
<defs>
|
|
7605
|
+
<linearGradient id="stripAccent" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
7606
|
+
<stop offset="0%" stop-color="#111111" stop-opacity="0.98" />
|
|
7607
|
+
<stop offset="24%" stop-color="#111111" stop-opacity="0.68" />
|
|
7608
|
+
<stop offset="58%" stop-color="#111111" stop-opacity="0.08" />
|
|
7609
|
+
<stop offset="100%" stop-color="#111111" stop-opacity="0" />
|
|
7610
|
+
</linearGradient>
|
|
7611
|
+
</defs>
|
|
7612
|
+
${parts.join("")}
|
|
7613
|
+
</svg>
|
|
7614
|
+
`;
|
|
7615
|
+
}
|
|
7309
7616
|
const logoSize = 28;
|
|
7310
7617
|
const logoX = DEFAULT_STRIP_PADDING_LEFT;
|
|
7311
7618
|
const contentStartX = logoX + logoSize + DEFAULT_STRIP_GAP;
|
|
@@ -7432,16 +7739,16 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
7432
7739
|
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, imageInfo);
|
|
7433
7740
|
};
|
|
7434
7741
|
|
|
7435
|
-
// src/internals/
|
|
7742
|
+
// src/internals/compression.js
|
|
7436
7743
|
var import_jimp = require("jimp");
|
|
7437
|
-
var logger14 = createInternalLogger("
|
|
7744
|
+
var logger14 = createInternalLogger("Compression");
|
|
7438
7745
|
var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
|
|
7439
7746
|
var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
|
|
7440
7747
|
var DEFAULT_SCREENSHOT_QUALITY = 0.72;
|
|
7441
7748
|
var DEFAULT_SCREENSHOT_MIN_QUALITY = 0.38;
|
|
7442
7749
|
var DEFAULT_SCREENSHOT_MIN_SCALE = 0.25;
|
|
7443
7750
|
var SUPPORTED_SCREENSHOT_OUTPUT_TYPES = /* @__PURE__ */ new Set(["jpeg"]);
|
|
7444
|
-
var
|
|
7751
|
+
var toPositiveInteger2 = (value, fallback = 0) => {
|
|
7445
7752
|
const number = Math.floor(Number(value) || 0);
|
|
7446
7753
|
return number > 0 ? number : fallback;
|
|
7447
7754
|
};
|
|
@@ -7463,7 +7770,7 @@ var normalizeScreenshotOutputType = (value) => {
|
|
|
7463
7770
|
};
|
|
7464
7771
|
var getBase64BytesFromBuffer = (buffer) => Math.ceil(buffer.length / 3) * 4;
|
|
7465
7772
|
var toJpegQuality = (value) => Math.round(normalizeQuality2(value, DEFAULT_SCREENSHOT_QUALITY) * 100);
|
|
7466
|
-
var
|
|
7773
|
+
var resolveImageCompression = (options = {}) => {
|
|
7467
7774
|
const explicit = options.compression;
|
|
7468
7775
|
const source = explicit && typeof explicit === "object" && !Array.isArray(explicit) ? explicit : {};
|
|
7469
7776
|
const enabled = explicit !== false && source.enabled !== false && options.compress !== false;
|
|
@@ -7477,7 +7784,7 @@ var resolveCaptureScreenCompression = (options = {}) => {
|
|
|
7477
7784
|
);
|
|
7478
7785
|
return {
|
|
7479
7786
|
enabled,
|
|
7480
|
-
maxBytes:
|
|
7787
|
+
maxBytes: toPositiveInteger2(
|
|
7481
7788
|
source.maxBytes ?? source.maxBase64Bytes ?? options.maxBytes ?? options.maxBase64Bytes,
|
|
7482
7789
|
DEFAULT_SCREENSHOT_MAX_BYTES
|
|
7483
7790
|
),
|
|
@@ -7514,7 +7821,7 @@ var encodeJpeg = async (sourceImage, compression, scale, quality) => {
|
|
|
7514
7821
|
format: compression.outputType
|
|
7515
7822
|
};
|
|
7516
7823
|
};
|
|
7517
|
-
var
|
|
7824
|
+
var compressImageBuffer = async (buffer, compression) => {
|
|
7518
7825
|
const sourceImage = await import_jimp.Jimp.read(buffer);
|
|
7519
7826
|
const maxQuality = toJpegQuality(compression.quality);
|
|
7520
7827
|
const minQuality = Math.min(maxQuality, toJpegQuality(compression.minQuality));
|
|
@@ -7547,12 +7854,12 @@ var compressScreenshotBuffer = async (buffer, compression) => {
|
|
|
7547
7854
|
const fallback = !smallest || finalCandidate.bytes < smallest.bytes ? finalCandidate : smallest;
|
|
7548
7855
|
return { ...fallback, withinLimit: fallback.bytes <= compression.maxBytes };
|
|
7549
7856
|
};
|
|
7550
|
-
var
|
|
7857
|
+
var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
7551
7858
|
const originalBytes = getBase64BytesFromBuffer(buffer);
|
|
7552
7859
|
if (!compression.enabled || originalBytes <= compression.maxBytes) {
|
|
7553
7860
|
return buffer.toString("base64");
|
|
7554
7861
|
}
|
|
7555
|
-
const result = await
|
|
7862
|
+
const result = await compressImageBuffer(buffer, compression).catch((error) => {
|
|
7556
7863
|
logger14.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
|
|
7557
7864
|
return null;
|
|
7558
7865
|
});
|
|
@@ -7951,7 +8258,7 @@ var Share = {
|
|
|
7951
8258
|
);
|
|
7952
8259
|
nextProgressLogTs = now + 5e3;
|
|
7953
8260
|
}
|
|
7954
|
-
await (0,
|
|
8261
|
+
await (0, import_delay4.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
7955
8262
|
}
|
|
7956
8263
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
7957
8264
|
logger15.warning(
|
|
@@ -7989,71 +8296,27 @@ var Share = {
|
|
|
7989
8296
|
* @returns {Promise<string>} base64 image
|
|
7990
8297
|
*/
|
|
7991
8298
|
async captureScreen(page, options = {}) {
|
|
7992
|
-
const originalViewport = await resolveCurrentViewportSize(page);
|
|
7993
|
-
const defaultBuffer = Math.round((originalViewport.height || 1080) / 2);
|
|
7994
|
-
const buffer = options.buffer ?? defaultBuffer;
|
|
7995
8299
|
const restore = options.restore ?? false;
|
|
7996
|
-
const maxHeight = options.maxHeight ?? 8e3;
|
|
7997
8300
|
const screenshotWatermarkify = resolveCaptureScreenWatermarkify(page, options.watermarkify);
|
|
7998
|
-
const compression =
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
el.style.overflow = "visible";
|
|
8014
|
-
el.style.height = "auto";
|
|
8015
|
-
el.style.maxHeight = "none";
|
|
8016
|
-
}
|
|
8017
|
-
});
|
|
8018
|
-
return maxHeight2;
|
|
8019
|
-
});
|
|
8020
|
-
const targetHeight = Math.min(maxScrollHeight + buffer, maxHeight);
|
|
8021
|
-
await page.setViewportSize({
|
|
8022
|
-
width: originalViewport.width,
|
|
8023
|
-
height: targetHeight
|
|
8024
|
-
});
|
|
8025
|
-
await (0, import_delay3.default)(1e3);
|
|
8026
|
-
const capturedAt = /* @__PURE__ */ new Date();
|
|
8027
|
-
const rawBuffer = await capturePageScreenshot(page, {
|
|
8028
|
-
fullPage: true,
|
|
8029
|
-
type: "png",
|
|
8030
|
-
maxClipHeight: targetHeight
|
|
8301
|
+
const compression = resolveImageCompression(options);
|
|
8302
|
+
const captureOptions = {
|
|
8303
|
+
buffer: options.buffer ?? 0,
|
|
8304
|
+
restore,
|
|
8305
|
+
maxHeight: options.maxHeight,
|
|
8306
|
+
type: "png",
|
|
8307
|
+
visibleOnly: true
|
|
8308
|
+
};
|
|
8309
|
+
const capturedAt = /* @__PURE__ */ new Date();
|
|
8310
|
+
const rawBuffer = await captureExpandedFullPageScreenshot(page, captureOptions);
|
|
8311
|
+
let outputBuffer = rawBuffer;
|
|
8312
|
+
if (screenshotWatermarkify.enabled) {
|
|
8313
|
+
const watermarkifyMeta = await resolveScreenshotWatermarkifyMeta(page, {
|
|
8314
|
+
...screenshotWatermarkify,
|
|
8315
|
+
capturedAt
|
|
8031
8316
|
});
|
|
8032
|
-
|
|
8033
|
-
if (screenshotWatermarkify.enabled) {
|
|
8034
|
-
const watermarkifyMeta = await resolveScreenshotWatermarkifyMeta(page, {
|
|
8035
|
-
...screenshotWatermarkify,
|
|
8036
|
-
capturedAt
|
|
8037
|
-
});
|
|
8038
|
-
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
|
|
8039
|
-
}
|
|
8040
|
-
return await compressScreenshotBufferToBase64(outputBuffer, compression);
|
|
8041
|
-
} finally {
|
|
8042
|
-
if (restore) {
|
|
8043
|
-
await page.evaluate(() => {
|
|
8044
|
-
document.querySelectorAll(".__pk_expanded__").forEach((el) => {
|
|
8045
|
-
el.style.overflow = el.dataset.pkOrigOverflow || "";
|
|
8046
|
-
el.style.height = el.dataset.pkOrigHeight || "";
|
|
8047
|
-
el.style.maxHeight = el.dataset.pkOrigMaxHeight || "";
|
|
8048
|
-
delete el.dataset.pkOrigOverflow;
|
|
8049
|
-
delete el.dataset.pkOrigHeight;
|
|
8050
|
-
delete el.dataset.pkOrigMaxHeight;
|
|
8051
|
-
el.classList.remove("__pk_expanded__");
|
|
8052
|
-
});
|
|
8053
|
-
});
|
|
8054
|
-
await page.setViewportSize(originalViewport);
|
|
8055
|
-
}
|
|
8317
|
+
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
|
|
8056
8318
|
}
|
|
8319
|
+
return await compressImageBufferToBase64(outputBuffer, compression);
|
|
8057
8320
|
}
|
|
8058
8321
|
};
|
|
8059
8322
|
|