@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.js
CHANGED
|
@@ -439,6 +439,9 @@ function createInternalLogger(moduleName, explicitLogger) {
|
|
|
439
439
|
};
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
+
// src/internals/screenshot.js
|
|
443
|
+
import delay from "delay";
|
|
444
|
+
|
|
442
445
|
// src/internals/viewport.js
|
|
443
446
|
var toPositiveInt = (value) => {
|
|
444
447
|
const number = Math.round(Number(value) || 0);
|
|
@@ -472,11 +475,18 @@ var DEFAULT_TIMEOUT_MS = 5e3;
|
|
|
472
475
|
var FORCED_FULLPAGE_TYPE = "jpeg";
|
|
473
476
|
var FORCED_FULLPAGE_QUALITY = 50;
|
|
474
477
|
var SUPPORTED_TYPES = /* @__PURE__ */ new Set(["png", "jpeg", "webp"]);
|
|
478
|
+
var EXPANDED_SCROLLABLE_CLASS = "__pk_expanded__";
|
|
479
|
+
var DEFAULT_MAX_HEIGHT = 8e3;
|
|
480
|
+
var DEFAULT_SETTLE_MS = 1e3;
|
|
475
481
|
var toPositiveNumber = (value, fallback = 0) => {
|
|
476
482
|
const n = Number(value);
|
|
477
483
|
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
478
484
|
return n;
|
|
479
485
|
};
|
|
486
|
+
var toPositiveInteger = (value, fallback = 0) => {
|
|
487
|
+
const number = Math.round(Number(value) || 0);
|
|
488
|
+
return number > 0 ? number : fallback;
|
|
489
|
+
};
|
|
480
490
|
var normalizeType = (value) => {
|
|
481
491
|
const raw = String(value || "png").trim().toLowerCase();
|
|
482
492
|
if (!SUPPORTED_TYPES.has(raw)) return "png";
|
|
@@ -505,6 +515,138 @@ var buildFullPageClip = (metrics, viewport, maxClipHeight) => {
|
|
|
505
515
|
scale: 1
|
|
506
516
|
};
|
|
507
517
|
};
|
|
518
|
+
var expandScrollableContent = async (page, options = {}) => {
|
|
519
|
+
return await page.evaluate(({ className, forceScrollableHeight, visibleOnly }) => {
|
|
520
|
+
const body = document.body;
|
|
521
|
+
const root = document.documentElement;
|
|
522
|
+
const scrollingElement = document.scrollingElement;
|
|
523
|
+
const candidates = [];
|
|
524
|
+
const seen = /* @__PURE__ */ new Set();
|
|
525
|
+
let maxHeight = window.innerHeight || 0;
|
|
526
|
+
const pushCandidate = (el) => {
|
|
527
|
+
if (!el || seen.has(el)) return;
|
|
528
|
+
seen.add(el);
|
|
529
|
+
candidates.push(el);
|
|
530
|
+
};
|
|
531
|
+
pushCandidate(scrollingElement);
|
|
532
|
+
pushCandidate(root);
|
|
533
|
+
pushCandidate(body);
|
|
534
|
+
document.querySelectorAll("*").forEach(pushCandidate);
|
|
535
|
+
const isDocumentElement = (el) => el === root || el === body || el === scrollingElement;
|
|
536
|
+
const isVisible = (el, style, rect) => {
|
|
537
|
+
if (!el || !style || !rect) return false;
|
|
538
|
+
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
if (Number(style.opacity) === 0) return false;
|
|
542
|
+
return rect.width > 0 && rect.height > 0;
|
|
543
|
+
};
|
|
544
|
+
const isScrollableY = (el, style) => {
|
|
545
|
+
if (!el || el.scrollHeight <= el.clientHeight + 1) {
|
|
546
|
+
return false;
|
|
547
|
+
}
|
|
548
|
+
if (isDocumentElement(el)) {
|
|
549
|
+
return true;
|
|
550
|
+
}
|
|
551
|
+
const overflowY = String(style.overflowY || "").toLowerCase();
|
|
552
|
+
const overflow = String(style.overflow || "").toLowerCase();
|
|
553
|
+
const scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
|
|
554
|
+
return scrollableOverflow.has(overflowY) || scrollableOverflow.has(overflow);
|
|
555
|
+
};
|
|
556
|
+
candidates.forEach((el) => {
|
|
557
|
+
const style = window.getComputedStyle(el);
|
|
558
|
+
const rect = el.getBoundingClientRect();
|
|
559
|
+
if (visibleOnly && !isVisible(el, style, rect)) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
if (!isScrollableY(el, style)) {
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
const scrollHeight = Math.ceil(el.scrollHeight || 0);
|
|
566
|
+
if (scrollHeight <= 0) {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
if (scrollHeight > maxHeight) {
|
|
570
|
+
maxHeight = scrollHeight;
|
|
571
|
+
}
|
|
572
|
+
if (isDocumentElement(el)) {
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
if (!el.classList.contains(className)) {
|
|
576
|
+
el.dataset.pkOrigOverflow = el.style.overflow;
|
|
577
|
+
el.dataset.pkOrigOverflowPriority = el.style.getPropertyPriority("overflow") || "";
|
|
578
|
+
el.dataset.pkOrigHeight = el.style.height;
|
|
579
|
+
el.dataset.pkOrigHeightPriority = el.style.getPropertyPriority("height") || "";
|
|
580
|
+
el.dataset.pkOrigMinHeight = el.style.minHeight;
|
|
581
|
+
el.dataset.pkOrigMinHeightPriority = el.style.getPropertyPriority("min-height") || "";
|
|
582
|
+
el.dataset.pkOrigMaxHeight = el.style.maxHeight;
|
|
583
|
+
el.dataset.pkOrigMaxHeightPriority = el.style.getPropertyPriority("max-height") || "";
|
|
584
|
+
el.classList.add(className);
|
|
585
|
+
}
|
|
586
|
+
if (forceScrollableHeight) {
|
|
587
|
+
el.style.setProperty("overflow", "visible", "important");
|
|
588
|
+
el.style.setProperty("height", `${scrollHeight}px`, "important");
|
|
589
|
+
el.style.setProperty("min-height", `${scrollHeight}px`, "important");
|
|
590
|
+
el.style.setProperty("max-height", "none", "important");
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
el.style.overflow = "visible";
|
|
594
|
+
el.style.height = "auto";
|
|
595
|
+
el.style.maxHeight = "none";
|
|
596
|
+
});
|
|
597
|
+
return maxHeight;
|
|
598
|
+
}, {
|
|
599
|
+
className: EXPANDED_SCROLLABLE_CLASS,
|
|
600
|
+
forceScrollableHeight: Boolean(options.forceScrollableHeight),
|
|
601
|
+
visibleOnly: options.visibleOnly !== false
|
|
602
|
+
});
|
|
603
|
+
};
|
|
604
|
+
var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
605
|
+
const originalViewport = await resolveCurrentViewportSize(page);
|
|
606
|
+
const defaultBuffer = Math.round((originalViewport.height || 1080) / 2);
|
|
607
|
+
const buffer = options.buffer ?? defaultBuffer;
|
|
608
|
+
const maxHeight = toPositiveInteger(options.maxHeight, DEFAULT_MAX_HEIGHT);
|
|
609
|
+
const settleMs = Math.max(0, Number(options.settleMs ?? DEFAULT_SETTLE_MS) || 0);
|
|
610
|
+
const maxScrollHeight = await expandScrollableContent(page, {
|
|
611
|
+
forceScrollableHeight: options.forceScrollableHeight,
|
|
612
|
+
visibleOnly: options.visibleOnly !== false
|
|
613
|
+
});
|
|
614
|
+
const targetHeight = Math.min(maxScrollHeight + buffer, maxHeight);
|
|
615
|
+
await page.setViewportSize({
|
|
616
|
+
width: originalViewport.width,
|
|
617
|
+
height: targetHeight
|
|
618
|
+
});
|
|
619
|
+
if (settleMs > 0) {
|
|
620
|
+
await delay(settleMs);
|
|
621
|
+
}
|
|
622
|
+
return {
|
|
623
|
+
originalViewport,
|
|
624
|
+
maxScrollHeight,
|
|
625
|
+
targetHeight
|
|
626
|
+
};
|
|
627
|
+
};
|
|
628
|
+
var restoreExpandedFullPageScreenshot = async (page, state = {}) => {
|
|
629
|
+
await page.evaluate((className) => {
|
|
630
|
+
document.querySelectorAll(`.${className}`).forEach((el) => {
|
|
631
|
+
el.style.setProperty("overflow", el.dataset.pkOrigOverflow || "", el.dataset.pkOrigOverflowPriority || "");
|
|
632
|
+
el.style.setProperty("height", el.dataset.pkOrigHeight || "", el.dataset.pkOrigHeightPriority || "");
|
|
633
|
+
el.style.setProperty("min-height", el.dataset.pkOrigMinHeight || "", el.dataset.pkOrigMinHeightPriority || "");
|
|
634
|
+
el.style.setProperty("max-height", el.dataset.pkOrigMaxHeight || "", el.dataset.pkOrigMaxHeightPriority || "");
|
|
635
|
+
delete el.dataset.pkOrigOverflow;
|
|
636
|
+
delete el.dataset.pkOrigOverflowPriority;
|
|
637
|
+
delete el.dataset.pkOrigHeight;
|
|
638
|
+
delete el.dataset.pkOrigHeightPriority;
|
|
639
|
+
delete el.dataset.pkOrigMinHeight;
|
|
640
|
+
delete el.dataset.pkOrigMinHeightPriority;
|
|
641
|
+
delete el.dataset.pkOrigMaxHeight;
|
|
642
|
+
delete el.dataset.pkOrigMaxHeightPriority;
|
|
643
|
+
el.classList.remove(className);
|
|
644
|
+
});
|
|
645
|
+
}, EXPANDED_SCROLLABLE_CLASS);
|
|
646
|
+
if (state?.originalViewport) {
|
|
647
|
+
await page.setViewportSize(state.originalViewport);
|
|
648
|
+
}
|
|
649
|
+
};
|
|
508
650
|
var capturePageScreenshot = async (page, options = {}) => {
|
|
509
651
|
const fullPage = Boolean(options.fullPage);
|
|
510
652
|
const type = fullPage ? FORCED_FULLPAGE_TYPE : normalizeType(options.type);
|
|
@@ -558,6 +700,22 @@ var capturePageScreenshot = async (page, options = {}) => {
|
|
|
558
700
|
return await page.screenshot(fallbackOptions);
|
|
559
701
|
}
|
|
560
702
|
};
|
|
703
|
+
var captureExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
704
|
+
const state = await prepareExpandedFullPageScreenshot(page, options);
|
|
705
|
+
try {
|
|
706
|
+
return await capturePageScreenshot(page, {
|
|
707
|
+
fullPage: true,
|
|
708
|
+
type: options.type || "png",
|
|
709
|
+
quality: options.quality,
|
|
710
|
+
timeout: options.timeout,
|
|
711
|
+
maxClipHeight: state.targetHeight
|
|
712
|
+
});
|
|
713
|
+
} finally {
|
|
714
|
+
if (options.restore) {
|
|
715
|
+
await restoreExpandedFullPageScreenshot(page, state);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
};
|
|
561
719
|
|
|
562
720
|
// src/errors.js
|
|
563
721
|
var errors_exports = {};
|
|
@@ -2096,7 +2254,7 @@ var AntiCheat = {
|
|
|
2096
2254
|
};
|
|
2097
2255
|
|
|
2098
2256
|
// src/internals/humanize/desktop.js
|
|
2099
|
-
import
|
|
2257
|
+
import delay2 from "delay";
|
|
2100
2258
|
import { createCursor } from "ghost-cursor-playwright";
|
|
2101
2259
|
var logger6 = createInternalLogger("Humanize");
|
|
2102
2260
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -2328,7 +2486,7 @@ var Humanize = {
|
|
|
2328
2486
|
}
|
|
2329
2487
|
await page.mouse.wheel(0, deltaY);
|
|
2330
2488
|
didScroll = true;
|
|
2331
|
-
await
|
|
2489
|
+
await delay2(this.jitterMs(20 + Math.random() * 40, 0.2));
|
|
2332
2490
|
}
|
|
2333
2491
|
logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
2334
2492
|
return { element, didScroll };
|
|
@@ -2357,7 +2515,7 @@ var Humanize = {
|
|
|
2357
2515
|
restoreOnce.restored = true;
|
|
2358
2516
|
if (typeof restoreOnce.do !== "function") return;
|
|
2359
2517
|
try {
|
|
2360
|
-
await
|
|
2518
|
+
await delay2(this.jitterMs(1e3));
|
|
2361
2519
|
await restoreOnce.do();
|
|
2362
2520
|
} catch (restoreError) {
|
|
2363
2521
|
logger6.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
@@ -2365,7 +2523,7 @@ var Humanize = {
|
|
|
2365
2523
|
};
|
|
2366
2524
|
try {
|
|
2367
2525
|
if (target == null) {
|
|
2368
|
-
await
|
|
2526
|
+
await delay2(this.jitterMs(reactionDelay, 0.4));
|
|
2369
2527
|
await cursor.actions.click();
|
|
2370
2528
|
logger6.success("humanClick", "Clicked current position");
|
|
2371
2529
|
return true;
|
|
@@ -2399,7 +2557,7 @@ var Humanize = {
|
|
|
2399
2557
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
2400
2558
|
const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;
|
|
2401
2559
|
await cursor.actions.move({ x, y });
|
|
2402
|
-
await
|
|
2560
|
+
await delay2(this.jitterMs(reactionDelay, 0.4));
|
|
2403
2561
|
await cursor.actions.click();
|
|
2404
2562
|
await restoreOnce();
|
|
2405
2563
|
logger6.success("humanClick");
|
|
@@ -2418,7 +2576,7 @@ var Humanize = {
|
|
|
2418
2576
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
2419
2577
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
2420
2578
|
logger6.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
2421
|
-
await
|
|
2579
|
+
await delay2(ms);
|
|
2422
2580
|
logger6.success("randomSleep");
|
|
2423
2581
|
},
|
|
2424
2582
|
/**
|
|
@@ -2436,7 +2594,7 @@ var Humanize = {
|
|
|
2436
2594
|
const x = 100 + Math.random() * (viewportSize.width - 200);
|
|
2437
2595
|
const y = 100 + Math.random() * (viewportSize.height - 200);
|
|
2438
2596
|
await cursor.actions.move({ x, y });
|
|
2439
|
-
await
|
|
2597
|
+
await delay2(this.jitterMs(600, 0.5));
|
|
2440
2598
|
}
|
|
2441
2599
|
logger6.success("simulateGaze");
|
|
2442
2600
|
},
|
|
@@ -2460,7 +2618,7 @@ var Humanize = {
|
|
|
2460
2618
|
try {
|
|
2461
2619
|
const locator = page.locator(selector);
|
|
2462
2620
|
await Humanize.humanClick(page, locator);
|
|
2463
|
-
await
|
|
2621
|
+
await delay2(this.jitterMs(200, 0.4));
|
|
2464
2622
|
for (let i = 0; i < text.length; i++) {
|
|
2465
2623
|
const char = text[i];
|
|
2466
2624
|
let charDelay;
|
|
@@ -2472,11 +2630,11 @@ var Humanize = {
|
|
|
2472
2630
|
charDelay = this.jitterMs(baseDelay, 0.4);
|
|
2473
2631
|
}
|
|
2474
2632
|
await page.keyboard.type(char);
|
|
2475
|
-
await
|
|
2633
|
+
await delay2(charDelay);
|
|
2476
2634
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
2477
2635
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
2478
2636
|
logger6.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
2479
|
-
await
|
|
2637
|
+
await delay2(pauseTime);
|
|
2480
2638
|
}
|
|
2481
2639
|
}
|
|
2482
2640
|
logger6.success("humanType");
|
|
@@ -2510,7 +2668,7 @@ var Humanize = {
|
|
|
2510
2668
|
if (hasTarget) {
|
|
2511
2669
|
await this.humanClick(page, targetOrKey, { reactionDelay: focusDelay, scrollIfNeeded, throwOnMissing });
|
|
2512
2670
|
}
|
|
2513
|
-
await
|
|
2671
|
+
await delay2(this.jitterMs(reactionDelay, 0.45));
|
|
2514
2672
|
await page.keyboard.press(key, {
|
|
2515
2673
|
...keyboardOptions,
|
|
2516
2674
|
delay: this.jitterMs(holdDelay, 0.5)
|
|
@@ -2532,14 +2690,14 @@ var Humanize = {
|
|
|
2532
2690
|
try {
|
|
2533
2691
|
const locator = page.locator(selector);
|
|
2534
2692
|
await locator.click();
|
|
2535
|
-
await
|
|
2693
|
+
await delay2(this.jitterMs(200, 0.4));
|
|
2536
2694
|
const currentValue = await locator.inputValue();
|
|
2537
2695
|
if (!currentValue || currentValue.length === 0) {
|
|
2538
2696
|
logger6.success("humanClear", "already empty");
|
|
2539
2697
|
return;
|
|
2540
2698
|
}
|
|
2541
2699
|
await page.keyboard.press("Meta+A");
|
|
2542
|
-
await
|
|
2700
|
+
await delay2(this.jitterMs(100, 0.4));
|
|
2543
2701
|
await page.keyboard.press("Backspace");
|
|
2544
2702
|
logger6.success("humanClear");
|
|
2545
2703
|
} catch (error) {
|
|
@@ -2565,13 +2723,13 @@ var Humanize = {
|
|
|
2565
2723
|
const x = 100 + Math.random() * (viewportSize.width - 200);
|
|
2566
2724
|
const y = 100 + Math.random() * (viewportSize.height - 200);
|
|
2567
2725
|
await cursor.actions.move({ x, y });
|
|
2568
|
-
await
|
|
2726
|
+
await delay2(this.jitterMs(350, 0.4));
|
|
2569
2727
|
} else if (action < 0.7) {
|
|
2570
2728
|
const scrollY = (Math.random() - 0.5) * 200;
|
|
2571
2729
|
await page.mouse.wheel(0, scrollY);
|
|
2572
|
-
await
|
|
2730
|
+
await delay2(this.jitterMs(500, 0.4));
|
|
2573
2731
|
} else {
|
|
2574
|
-
await
|
|
2732
|
+
await delay2(this.jitterMs(800, 0.5));
|
|
2575
2733
|
}
|
|
2576
2734
|
}
|
|
2577
2735
|
logger6.success("warmUpBrowsing");
|
|
@@ -2600,7 +2758,7 @@ var Humanize = {
|
|
|
2600
2758
|
const scrollAmount = stepDistance * factor * sign * jitter;
|
|
2601
2759
|
await page.mouse.wheel(0, scrollAmount);
|
|
2602
2760
|
const baseDelay = 60 + i * 25;
|
|
2603
|
-
await
|
|
2761
|
+
await delay2(this.jitterMs(baseDelay, 0.3));
|
|
2604
2762
|
}
|
|
2605
2763
|
logger6.success("naturalScroll");
|
|
2606
2764
|
} catch (error) {
|
|
@@ -2746,7 +2904,7 @@ var MachineHumanize = {
|
|
|
2746
2904
|
};
|
|
2747
2905
|
|
|
2748
2906
|
// src/internals/humanize/shared.js
|
|
2749
|
-
import
|
|
2907
|
+
import delay3 from "delay";
|
|
2750
2908
|
var jitterMs = (base, jitterPercent = 0.3) => {
|
|
2751
2909
|
const jitter = Number(base || 0) * Number(jitterPercent || 0) * (Math.random() * 2 - 1);
|
|
2752
2910
|
return Math.max(10, Math.round(Number(base || 0) + jitter));
|
|
@@ -2772,7 +2930,7 @@ var resolveElement = async (page, target, { throwOnMissing = true } = {}) => {
|
|
|
2772
2930
|
}
|
|
2773
2931
|
return element;
|
|
2774
2932
|
};
|
|
2775
|
-
var waitJitter = (base, jitterPercent = 0.3) =>
|
|
2933
|
+
var waitJitter = (base, jitterPercent = 0.3) => delay3(jitterMs(base, jitterPercent));
|
|
2776
2934
|
|
|
2777
2935
|
// src/internals/humanize/mobile.js
|
|
2778
2936
|
var logger7 = createInternalLogger("Humanize.Mobile");
|
|
@@ -3573,8 +3731,8 @@ var callDelegate = (method, page, args) => {
|
|
|
3573
3731
|
return delegate[method](page, ...args);
|
|
3574
3732
|
};
|
|
3575
3733
|
var Humanize2 = {
|
|
3576
|
-
// M = Machine: native/mechanical operations for
|
|
3577
|
-
//
|
|
3734
|
+
// M = Machine: native/mechanical operations for兼容路径。
|
|
3735
|
+
// 这组 API 不做人类化处理,只保留原生 click / focus / fill / type 等语义。
|
|
3578
3736
|
M: MachineHumanize,
|
|
3579
3737
|
jitterMs(base, jitterPercent = 0.3) {
|
|
3580
3738
|
return Humanize.jitterMs(base, jitterPercent);
|
|
@@ -6081,7 +6239,7 @@ var Logger = {
|
|
|
6081
6239
|
};
|
|
6082
6240
|
|
|
6083
6241
|
// src/share.js
|
|
6084
|
-
import
|
|
6242
|
+
import delay4 from "delay";
|
|
6085
6243
|
|
|
6086
6244
|
// src/internals/watermarkify.js
|
|
6087
6245
|
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
@@ -6115,6 +6273,18 @@ var DEFAULT_STRIP_PROMPT_MAX_LINES = 3;
|
|
|
6115
6273
|
var DEFAULT_STRIP_CONTENT_SAFE_PADDING_X = 12;
|
|
6116
6274
|
var DEFAULT_STRIP_TEXT_WIDTH_SAFETY = 10;
|
|
6117
6275
|
var DEFAULT_BROWSER_COMPOSITOR_VIEWPORT_HEIGHT = 1200;
|
|
6276
|
+
var MOBILE_STRIP_HEIGHT = 104;
|
|
6277
|
+
var MOBILE_STRIP_PADDING_X = 14;
|
|
6278
|
+
var MOBILE_STRIP_PADDING_Y = 13;
|
|
6279
|
+
var MOBILE_STRIP_ROW_HEIGHT = 22;
|
|
6280
|
+
var MOBILE_STRIP_ROW_GAP = 7;
|
|
6281
|
+
var MOBILE_STRIP_LABEL_FONT_SIZE = 12.5;
|
|
6282
|
+
var MOBILE_STRIP_VALUE_FONT_SIZE = 13.5;
|
|
6283
|
+
var MOBILE_STRIP_LABEL_WIDTH = 45;
|
|
6284
|
+
var MOBILE_STRIP_PROMPT_LABEL_WIDTH = 60;
|
|
6285
|
+
var MOBILE_STRIP_LOC_LABEL_WIDTH = 30;
|
|
6286
|
+
var MOBILE_STRIP_IP_LABEL_WIDTH = 22;
|
|
6287
|
+
var MOBILE_STRIP_META_GAP = 12;
|
|
6118
6288
|
var WEAK_LOCATION_VALUES = /* @__PURE__ */ new Set(["cn", "\u4E2D\u56FD"]);
|
|
6119
6289
|
var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
6120
6290
|
/(?:中国)?移动$/i,
|
|
@@ -6899,10 +7069,16 @@ var resolveScreenshotWatermarkifyMeta = async (page, options = {}) => {
|
|
|
6899
7069
|
}),
|
|
6900
7070
|
watermark: options.watermark,
|
|
6901
7071
|
strip: options.strip,
|
|
6902
|
-
stripLogoSrc
|
|
7072
|
+
stripLogoSrc,
|
|
7073
|
+
device: resolvePageDevice(page)
|
|
6903
7074
|
};
|
|
6904
7075
|
};
|
|
6905
7076
|
var buildFontFamily = () => 'MiSans, "SF Pro Display", "PingFang SC", "Helvetica Neue", Arial, sans-serif';
|
|
7077
|
+
var resolvePageDevice = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
7078
|
+
var findStripSegment = (segments, kind) => {
|
|
7079
|
+
const found = Array.isArray(segments) ? segments.find((segment) => segment?.kind === kind) : null;
|
|
7080
|
+
return found && typeof found === "object" ? found : {};
|
|
7081
|
+
};
|
|
6906
7082
|
var buildStripSegmentLayout = (segment, options = {}) => {
|
|
6907
7083
|
const label = normalizeWhitespace(segment?.label || "");
|
|
6908
7084
|
const rawValue = normalizeWhitespace(segment?.rawValue || segment?.value || "-") || "-";
|
|
@@ -7230,6 +7406,116 @@ var renderStripDivider = (x, centerY, height) => {
|
|
|
7230
7406
|
/>
|
|
7231
7407
|
`;
|
|
7232
7408
|
};
|
|
7409
|
+
var renderMobileStripText = ({
|
|
7410
|
+
label,
|
|
7411
|
+
value,
|
|
7412
|
+
labelX,
|
|
7413
|
+
y,
|
|
7414
|
+
valueWidth,
|
|
7415
|
+
labelWidth = MOBILE_STRIP_LABEL_WIDTH,
|
|
7416
|
+
fontFamily
|
|
7417
|
+
}) => {
|
|
7418
|
+
const safeLabel = normalizeWhitespace(label) || "-";
|
|
7419
|
+
const safeValue = fitTextWithEllipsis(
|
|
7420
|
+
Array.from(normalizeWhitespace(value) || "-"),
|
|
7421
|
+
Math.max(18, valueWidth),
|
|
7422
|
+
MOBILE_STRIP_VALUE_FONT_SIZE
|
|
7423
|
+
);
|
|
7424
|
+
return `
|
|
7425
|
+
<text
|
|
7426
|
+
x="${labelX}"
|
|
7427
|
+
y="${y}"
|
|
7428
|
+
fill="#111111"
|
|
7429
|
+
fill-opacity="0.54"
|
|
7430
|
+
font-family="${fontFamily}"
|
|
7431
|
+
font-size="${MOBILE_STRIP_LABEL_FONT_SIZE}"
|
|
7432
|
+
font-weight="650"
|
|
7433
|
+
dominant-baseline="middle"
|
|
7434
|
+
>${escapeXml(safeLabel)}</text>
|
|
7435
|
+
<text
|
|
7436
|
+
x="${labelX + labelWidth}"
|
|
7437
|
+
y="${y}"
|
|
7438
|
+
fill="#111111"
|
|
7439
|
+
font-family="${fontFamily}"
|
|
7440
|
+
font-size="${MOBILE_STRIP_VALUE_FONT_SIZE}"
|
|
7441
|
+
font-weight="730"
|
|
7442
|
+
dominant-baseline="middle"
|
|
7443
|
+
>${escapeXml(safeValue)}</text>
|
|
7444
|
+
`;
|
|
7445
|
+
};
|
|
7446
|
+
var renderMobileStrip = ({ meta, width, height, fontFamily }) => {
|
|
7447
|
+
const stripHeight = MOBILE_STRIP_HEIGHT;
|
|
7448
|
+
const stripY = height - stripHeight;
|
|
7449
|
+
const contentX = MOBILE_STRIP_PADDING_X;
|
|
7450
|
+
const contentWidth = Math.max(1, width - MOBILE_STRIP_PADDING_X * 2);
|
|
7451
|
+
const prompt = findStripSegment(meta.stripSegments, "prompt");
|
|
7452
|
+
const time = findStripSegment(meta.stripSegments, "time");
|
|
7453
|
+
const location = findStripSegment(meta.stripSegments, "location");
|
|
7454
|
+
const ip = findStripSegment(meta.stripSegments, "ip");
|
|
7455
|
+
const row1Y = stripY + MOBILE_STRIP_PADDING_Y + MOBILE_STRIP_ROW_HEIGHT / 2;
|
|
7456
|
+
const row2Y = row1Y + MOBILE_STRIP_ROW_HEIGHT + MOBILE_STRIP_ROW_GAP;
|
|
7457
|
+
const row3Y = row2Y + MOBILE_STRIP_ROW_HEIGHT + MOBILE_STRIP_ROW_GAP;
|
|
7458
|
+
const promptValueWidth = contentWidth - MOBILE_STRIP_PROMPT_LABEL_WIDTH;
|
|
7459
|
+
const locValueX = contentX + MOBILE_STRIP_LOC_LABEL_WIDTH;
|
|
7460
|
+
const ipLabelX = Math.min(
|
|
7461
|
+
width - MOBILE_STRIP_PADDING_X - MOBILE_STRIP_IP_LABEL_WIDTH - 70,
|
|
7462
|
+
Math.max(
|
|
7463
|
+
locValueX + 80 + MOBILE_STRIP_META_GAP,
|
|
7464
|
+
contentX + Math.round(contentWidth * 0.52)
|
|
7465
|
+
)
|
|
7466
|
+
);
|
|
7467
|
+
const locValueWidth = Math.max(
|
|
7468
|
+
28,
|
|
7469
|
+
ipLabelX - locValueX - MOBILE_STRIP_META_GAP
|
|
7470
|
+
);
|
|
7471
|
+
const ipValueWidth = Math.max(
|
|
7472
|
+
28,
|
|
7473
|
+
width - MOBILE_STRIP_PADDING_X - (ipLabelX + MOBILE_STRIP_IP_LABEL_WIDTH)
|
|
7474
|
+
);
|
|
7475
|
+
return `
|
|
7476
|
+
<g id="strip">
|
|
7477
|
+
<rect x="0" y="${stripY}" width="${width}" height="${stripHeight}" fill="#ffffff" fill-opacity="0.985" />
|
|
7478
|
+
<rect x="0" y="${stripY}" width="${width}" height="1" fill="#111111" fill-opacity="0.10" />
|
|
7479
|
+
<rect x="${contentX}" y="${stripY}" width="${Math.max(96, Math.round(width * 0.36))}" height="2" fill="url(#stripAccent)" />
|
|
7480
|
+
${renderMobileStripText({
|
|
7481
|
+
label: "Prompt",
|
|
7482
|
+
value: prompt.rawValue || prompt.value || "-",
|
|
7483
|
+
labelX: contentX,
|
|
7484
|
+
y: row1Y,
|
|
7485
|
+
valueWidth: promptValueWidth,
|
|
7486
|
+
labelWidth: MOBILE_STRIP_PROMPT_LABEL_WIDTH,
|
|
7487
|
+
fontFamily
|
|
7488
|
+
})}
|
|
7489
|
+
${renderMobileStripText({
|
|
7490
|
+
label: "Time",
|
|
7491
|
+
value: time.rawValue || time.value || "-",
|
|
7492
|
+
labelX: contentX,
|
|
7493
|
+
y: row2Y,
|
|
7494
|
+
valueWidth: promptValueWidth,
|
|
7495
|
+
labelWidth: MOBILE_STRIP_LABEL_WIDTH,
|
|
7496
|
+
fontFamily
|
|
7497
|
+
})}
|
|
7498
|
+
${renderMobileStripText({
|
|
7499
|
+
label: "Loc",
|
|
7500
|
+
value: location.rawValue || location.value || "-",
|
|
7501
|
+
labelX: contentX,
|
|
7502
|
+
y: row3Y,
|
|
7503
|
+
valueWidth: locValueWidth,
|
|
7504
|
+
labelWidth: MOBILE_STRIP_LOC_LABEL_WIDTH,
|
|
7505
|
+
fontFamily
|
|
7506
|
+
})}
|
|
7507
|
+
${renderMobileStripText({
|
|
7508
|
+
label: "IP",
|
|
7509
|
+
value: ip.rawValue || ip.value || "-",
|
|
7510
|
+
labelX: ipLabelX,
|
|
7511
|
+
y: row3Y,
|
|
7512
|
+
valueWidth: ipValueWidth,
|
|
7513
|
+
labelWidth: MOBILE_STRIP_IP_LABEL_WIDTH,
|
|
7514
|
+
fontFamily
|
|
7515
|
+
})}
|
|
7516
|
+
</g>
|
|
7517
|
+
`;
|
|
7518
|
+
};
|
|
7233
7519
|
var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
7234
7520
|
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
|
|
7235
7521
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
@@ -7278,6 +7564,27 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
7278
7564
|
parts.push(`<g id="watermarks">${stamps.join("")}</g>`);
|
|
7279
7565
|
}
|
|
7280
7566
|
if (hasStrip) {
|
|
7567
|
+
if (normalizeDevice(meta.device) === Device.Mobile) {
|
|
7568
|
+
parts.push(renderMobileStrip({
|
|
7569
|
+
meta,
|
|
7570
|
+
width,
|
|
7571
|
+
height,
|
|
7572
|
+
fontFamily
|
|
7573
|
+
}));
|
|
7574
|
+
return `
|
|
7575
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
|
7576
|
+
<defs>
|
|
7577
|
+
<linearGradient id="stripAccent" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
7578
|
+
<stop offset="0%" stop-color="#111111" stop-opacity="0.98" />
|
|
7579
|
+
<stop offset="24%" stop-color="#111111" stop-opacity="0.68" />
|
|
7580
|
+
<stop offset="58%" stop-color="#111111" stop-opacity="0.08" />
|
|
7581
|
+
<stop offset="100%" stop-color="#111111" stop-opacity="0" />
|
|
7582
|
+
</linearGradient>
|
|
7583
|
+
</defs>
|
|
7584
|
+
${parts.join("")}
|
|
7585
|
+
</svg>
|
|
7586
|
+
`;
|
|
7587
|
+
}
|
|
7281
7588
|
const logoSize = 28;
|
|
7282
7589
|
const logoX = DEFAULT_STRIP_PADDING_LEFT;
|
|
7283
7590
|
const contentStartX = logoX + logoSize + DEFAULT_STRIP_GAP;
|
|
@@ -7404,16 +7711,16 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
7404
7711
|
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, imageInfo);
|
|
7405
7712
|
};
|
|
7406
7713
|
|
|
7407
|
-
// src/internals/
|
|
7714
|
+
// src/internals/compression.js
|
|
7408
7715
|
import { Jimp, JimpMime, ResizeStrategy } from "jimp";
|
|
7409
|
-
var logger14 = createInternalLogger("
|
|
7716
|
+
var logger14 = createInternalLogger("Compression");
|
|
7410
7717
|
var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
|
|
7411
7718
|
var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
|
|
7412
7719
|
var DEFAULT_SCREENSHOT_QUALITY = 0.72;
|
|
7413
7720
|
var DEFAULT_SCREENSHOT_MIN_QUALITY = 0.38;
|
|
7414
7721
|
var DEFAULT_SCREENSHOT_MIN_SCALE = 0.25;
|
|
7415
7722
|
var SUPPORTED_SCREENSHOT_OUTPUT_TYPES = /* @__PURE__ */ new Set(["jpeg"]);
|
|
7416
|
-
var
|
|
7723
|
+
var toPositiveInteger2 = (value, fallback = 0) => {
|
|
7417
7724
|
const number = Math.floor(Number(value) || 0);
|
|
7418
7725
|
return number > 0 ? number : fallback;
|
|
7419
7726
|
};
|
|
@@ -7435,7 +7742,7 @@ var normalizeScreenshotOutputType = (value) => {
|
|
|
7435
7742
|
};
|
|
7436
7743
|
var getBase64BytesFromBuffer = (buffer) => Math.ceil(buffer.length / 3) * 4;
|
|
7437
7744
|
var toJpegQuality = (value) => Math.round(normalizeQuality2(value, DEFAULT_SCREENSHOT_QUALITY) * 100);
|
|
7438
|
-
var
|
|
7745
|
+
var resolveImageCompression = (options = {}) => {
|
|
7439
7746
|
const explicit = options.compression;
|
|
7440
7747
|
const source = explicit && typeof explicit === "object" && !Array.isArray(explicit) ? explicit : {};
|
|
7441
7748
|
const enabled = explicit !== false && source.enabled !== false && options.compress !== false;
|
|
@@ -7449,7 +7756,7 @@ var resolveCaptureScreenCompression = (options = {}) => {
|
|
|
7449
7756
|
);
|
|
7450
7757
|
return {
|
|
7451
7758
|
enabled,
|
|
7452
|
-
maxBytes:
|
|
7759
|
+
maxBytes: toPositiveInteger2(
|
|
7453
7760
|
source.maxBytes ?? source.maxBase64Bytes ?? options.maxBytes ?? options.maxBase64Bytes,
|
|
7454
7761
|
DEFAULT_SCREENSHOT_MAX_BYTES
|
|
7455
7762
|
),
|
|
@@ -7486,7 +7793,7 @@ var encodeJpeg = async (sourceImage, compression, scale, quality) => {
|
|
|
7486
7793
|
format: compression.outputType
|
|
7487
7794
|
};
|
|
7488
7795
|
};
|
|
7489
|
-
var
|
|
7796
|
+
var compressImageBuffer = async (buffer, compression) => {
|
|
7490
7797
|
const sourceImage = await Jimp.read(buffer);
|
|
7491
7798
|
const maxQuality = toJpegQuality(compression.quality);
|
|
7492
7799
|
const minQuality = Math.min(maxQuality, toJpegQuality(compression.minQuality));
|
|
@@ -7519,12 +7826,12 @@ var compressScreenshotBuffer = async (buffer, compression) => {
|
|
|
7519
7826
|
const fallback = !smallest || finalCandidate.bytes < smallest.bytes ? finalCandidate : smallest;
|
|
7520
7827
|
return { ...fallback, withinLimit: fallback.bytes <= compression.maxBytes };
|
|
7521
7828
|
};
|
|
7522
|
-
var
|
|
7829
|
+
var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
7523
7830
|
const originalBytes = getBase64BytesFromBuffer(buffer);
|
|
7524
7831
|
if (!compression.enabled || originalBytes <= compression.maxBytes) {
|
|
7525
7832
|
return buffer.toString("base64");
|
|
7526
7833
|
}
|
|
7527
|
-
const result = await
|
|
7834
|
+
const result = await compressImageBuffer(buffer, compression).catch((error) => {
|
|
7528
7835
|
logger14.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
|
|
7529
7836
|
return null;
|
|
7530
7837
|
});
|
|
@@ -7923,7 +8230,7 @@ var Share = {
|
|
|
7923
8230
|
);
|
|
7924
8231
|
nextProgressLogTs = now + 5e3;
|
|
7925
8232
|
}
|
|
7926
|
-
await
|
|
8233
|
+
await delay4(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
7927
8234
|
}
|
|
7928
8235
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
7929
8236
|
logger15.warning(
|
|
@@ -7961,71 +8268,27 @@ var Share = {
|
|
|
7961
8268
|
* @returns {Promise<string>} base64 image
|
|
7962
8269
|
*/
|
|
7963
8270
|
async captureScreen(page, options = {}) {
|
|
7964
|
-
const originalViewport = await resolveCurrentViewportSize(page);
|
|
7965
|
-
const defaultBuffer = Math.round((originalViewport.height || 1080) / 2);
|
|
7966
|
-
const buffer = options.buffer ?? defaultBuffer;
|
|
7967
8271
|
const restore = options.restore ?? false;
|
|
7968
|
-
const maxHeight = options.maxHeight ?? 8e3;
|
|
7969
8272
|
const screenshotWatermarkify = resolveCaptureScreenWatermarkify(page, options.watermarkify);
|
|
7970
|
-
const compression =
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
el.style.overflow = "visible";
|
|
7986
|
-
el.style.height = "auto";
|
|
7987
|
-
el.style.maxHeight = "none";
|
|
7988
|
-
}
|
|
7989
|
-
});
|
|
7990
|
-
return maxHeight2;
|
|
7991
|
-
});
|
|
7992
|
-
const targetHeight = Math.min(maxScrollHeight + buffer, maxHeight);
|
|
7993
|
-
await page.setViewportSize({
|
|
7994
|
-
width: originalViewport.width,
|
|
7995
|
-
height: targetHeight
|
|
7996
|
-
});
|
|
7997
|
-
await delay3(1e3);
|
|
7998
|
-
const capturedAt = /* @__PURE__ */ new Date();
|
|
7999
|
-
const rawBuffer = await capturePageScreenshot(page, {
|
|
8000
|
-
fullPage: true,
|
|
8001
|
-
type: "png",
|
|
8002
|
-
maxClipHeight: targetHeight
|
|
8273
|
+
const compression = resolveImageCompression(options);
|
|
8274
|
+
const captureOptions = {
|
|
8275
|
+
buffer: options.buffer ?? 0,
|
|
8276
|
+
restore,
|
|
8277
|
+
maxHeight: options.maxHeight,
|
|
8278
|
+
type: "png",
|
|
8279
|
+
visibleOnly: true
|
|
8280
|
+
};
|
|
8281
|
+
const capturedAt = /* @__PURE__ */ new Date();
|
|
8282
|
+
const rawBuffer = await captureExpandedFullPageScreenshot(page, captureOptions);
|
|
8283
|
+
let outputBuffer = rawBuffer;
|
|
8284
|
+
if (screenshotWatermarkify.enabled) {
|
|
8285
|
+
const watermarkifyMeta = await resolveScreenshotWatermarkifyMeta(page, {
|
|
8286
|
+
...screenshotWatermarkify,
|
|
8287
|
+
capturedAt
|
|
8003
8288
|
});
|
|
8004
|
-
|
|
8005
|
-
if (screenshotWatermarkify.enabled) {
|
|
8006
|
-
const watermarkifyMeta = await resolveScreenshotWatermarkifyMeta(page, {
|
|
8007
|
-
...screenshotWatermarkify,
|
|
8008
|
-
capturedAt
|
|
8009
|
-
});
|
|
8010
|
-
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
|
|
8011
|
-
}
|
|
8012
|
-
return await compressScreenshotBufferToBase64(outputBuffer, compression);
|
|
8013
|
-
} finally {
|
|
8014
|
-
if (restore) {
|
|
8015
|
-
await page.evaluate(() => {
|
|
8016
|
-
document.querySelectorAll(".__pk_expanded__").forEach((el) => {
|
|
8017
|
-
el.style.overflow = el.dataset.pkOrigOverflow || "";
|
|
8018
|
-
el.style.height = el.dataset.pkOrigHeight || "";
|
|
8019
|
-
el.style.maxHeight = el.dataset.pkOrigMaxHeight || "";
|
|
8020
|
-
delete el.dataset.pkOrigOverflow;
|
|
8021
|
-
delete el.dataset.pkOrigHeight;
|
|
8022
|
-
delete el.dataset.pkOrigMaxHeight;
|
|
8023
|
-
el.classList.remove("__pk_expanded__");
|
|
8024
|
-
});
|
|
8025
|
-
});
|
|
8026
|
-
await page.setViewportSize(originalViewport);
|
|
8027
|
-
}
|
|
8289
|
+
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
|
|
8028
8290
|
}
|
|
8291
|
+
return await compressImageBufferToBase64(outputBuffer, compression);
|
|
8029
8292
|
}
|
|
8030
8293
|
};
|
|
8031
8294
|
|