@skrillex1224/playwright-toolkit 2.1.207 → 2.1.208
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 +33 -2
- package/dist/browser.js +0 -11
- package/dist/browser.js.map +2 -2
- package/dist/index.cjs +913 -16
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +913 -16
- package/dist/index.js.map +4 -4
- package/index.d.ts +54 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -292,17 +292,6 @@ var ActorInfo = {
|
|
|
292
292
|
"id"
|
|
293
293
|
]
|
|
294
294
|
}
|
|
295
|
-
}),
|
|
296
|
-
quark: createActorInfo({
|
|
297
|
-
key: "quark",
|
|
298
|
-
name: "\u5938\u514B",
|
|
299
|
-
domain: "ai.quark.cn",
|
|
300
|
-
path: "/s",
|
|
301
|
-
share: {
|
|
302
|
-
mode: "dom",
|
|
303
|
-
prefix: "",
|
|
304
|
-
xurl: []
|
|
305
|
-
}
|
|
306
295
|
})
|
|
307
296
|
};
|
|
308
297
|
|
|
@@ -3257,7 +3246,7 @@ var Mutation = {
|
|
|
3257
3246
|
if (text.length <= max) return text;
|
|
3258
3247
|
return `${text.slice(0, max)}...`;
|
|
3259
3248
|
};
|
|
3260
|
-
const
|
|
3249
|
+
const normalizeText2 = (value) => String(value || "").replace(/\s+/g, " ").trim();
|
|
3261
3250
|
const normalizeHtml = (value) => String(value || "").trim();
|
|
3262
3251
|
const hashSnapshot = (value) => createHash("sha256").update(String(value || "")).digest("hex");
|
|
3263
3252
|
const buildState = async () => {
|
|
@@ -3322,7 +3311,7 @@ var Mutation = {
|
|
|
3322
3311
|
if (frame) {
|
|
3323
3312
|
try {
|
|
3324
3313
|
const frameSnapshot = await readFrameSnapshot(frame);
|
|
3325
|
-
text =
|
|
3314
|
+
text = normalizeText2(frameSnapshot?.text || "");
|
|
3326
3315
|
html = normalizeHtml(frameSnapshot?.html || "");
|
|
3327
3316
|
frameUrl = String(frameSnapshot?.url || "").trim();
|
|
3328
3317
|
readyState = String(frameSnapshot?.readyState || "").trim();
|
|
@@ -3336,7 +3325,7 @@ var Mutation = {
|
|
|
3336
3325
|
} else {
|
|
3337
3326
|
try {
|
|
3338
3327
|
const elementSnapshot = await readElementSnapshot(handle);
|
|
3339
|
-
text =
|
|
3328
|
+
text = normalizeText2(elementSnapshot?.text || "");
|
|
3340
3329
|
html = normalizeHtml(elementSnapshot?.html || "");
|
|
3341
3330
|
} catch (error) {
|
|
3342
3331
|
source = "main-unreadable";
|
|
@@ -4530,6 +4519,905 @@ var Logger = {
|
|
|
4530
4519
|
|
|
4531
4520
|
// src/share.js
|
|
4532
4521
|
import delay2 from "delay";
|
|
4522
|
+
|
|
4523
|
+
// src/internals/watermarkify.js
|
|
4524
|
+
var SCREENSHOT_WATERMARKIFY_HOST_ID = "__pk_screenshot_watermarkify__";
|
|
4525
|
+
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
4526
|
+
var DEFAULT_RESOLVER_TIMEOUT_MS = 180;
|
|
4527
|
+
var DEFAULT_IP_LOOKUP_TIMEOUT_MS = 1e4;
|
|
4528
|
+
var DEFAULT_WATERMARK_OPACITY = 0.156;
|
|
4529
|
+
var DEFAULT_WATERMARK_ROTATE_DEG = -16;
|
|
4530
|
+
var DEFAULT_WATERMARK_CELL_WIDTH = 860;
|
|
4531
|
+
var DEFAULT_WATERMARK_CELL_HEIGHT = 330;
|
|
4532
|
+
var DEFAULT_STRIP_LOGO_URL = "https://static.heartbitai.com/geo/icon/favicon.png";
|
|
4533
|
+
var DEFAULT_IP_LOOKUP_URL = "http://myip.ipip.net";
|
|
4534
|
+
var DEFAULT_LOGO_FETCH_TIMEOUT_MS = 2500;
|
|
4535
|
+
var WEAK_LOCATION_VALUES = /* @__PURE__ */ new Set(["cn", "\u4E2D\u56FD"]);
|
|
4536
|
+
var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
4537
|
+
/(?:中国)?移动$/i,
|
|
4538
|
+
/(?:中国)?联通$/i,
|
|
4539
|
+
/(?:中国)?电信$/i,
|
|
4540
|
+
/铁通$/i,
|
|
4541
|
+
/教育网$/i,
|
|
4542
|
+
/广电$/i,
|
|
4543
|
+
/鹏博士$/i,
|
|
4544
|
+
/阿里云$/i,
|
|
4545
|
+
/腾讯云$/i,
|
|
4546
|
+
/百度云$/i,
|
|
4547
|
+
/华为云$/i,
|
|
4548
|
+
/cloudflare$/i,
|
|
4549
|
+
/amazon$/i,
|
|
4550
|
+
/aws$/i,
|
|
4551
|
+
/azure$/i,
|
|
4552
|
+
/google$/i,
|
|
4553
|
+
/oracle$/i,
|
|
4554
|
+
/linode$/i,
|
|
4555
|
+
/vultr$/i,
|
|
4556
|
+
/digitalocean$/i
|
|
4557
|
+
];
|
|
4558
|
+
var cachedStripLogoSrcPromise = null;
|
|
4559
|
+
var normalizeText = (value) => String(value || "").trim();
|
|
4560
|
+
var toInline = (value, maxLen = 200) => {
|
|
4561
|
+
const text = normalizeText(value);
|
|
4562
|
+
if (!text) return "";
|
|
4563
|
+
return text.replace(/\s+/g, " ").trim().slice(0, maxLen);
|
|
4564
|
+
};
|
|
4565
|
+
var shortenTail = (value, maxLen = 80) => {
|
|
4566
|
+
const text = toInline(value, Math.max(maxLen * 2, maxLen + 8));
|
|
4567
|
+
if (!text || text.length <= maxLen) return text;
|
|
4568
|
+
return `${text.slice(0, Math.max(0, maxLen - 1)).trimEnd()}\u2026`;
|
|
4569
|
+
};
|
|
4570
|
+
var shortenMiddle = (value, maxLen = 56, headLen = 32, tailLen = 14) => {
|
|
4571
|
+
const text = toInline(value, Math.max(maxLen * 2, maxLen + headLen + tailLen));
|
|
4572
|
+
if (!text || text.length <= maxLen) return text;
|
|
4573
|
+
const safeHeadLen = Math.max(4, Math.min(headLen, maxLen - 5));
|
|
4574
|
+
const safeTailLen = Math.max(4, Math.min(tailLen, maxLen - safeHeadLen - 1));
|
|
4575
|
+
return `${text.slice(0, safeHeadLen).trimEnd()}\u2026${text.slice(-safeTailLen).trimStart()}`;
|
|
4576
|
+
};
|
|
4577
|
+
var padDatePart = (value) => String(value).padStart(2, "0");
|
|
4578
|
+
var formatUtcOffsetLabel = (offsetHours = DEFAULT_TIMEZONE_OFFSET) => {
|
|
4579
|
+
const sign = offsetHours >= 0 ? "+" : "-";
|
|
4580
|
+
const absolute = Math.abs(offsetHours);
|
|
4581
|
+
const hours = Math.trunc(absolute);
|
|
4582
|
+
const minutes = Math.round((absolute - hours) * 60);
|
|
4583
|
+
if (!minutes) {
|
|
4584
|
+
return `UTC${sign}${hours}`;
|
|
4585
|
+
}
|
|
4586
|
+
return `UTC${sign}${hours}:${padDatePart(minutes)}`;
|
|
4587
|
+
};
|
|
4588
|
+
var formatTimestampForUtcOffset = (date, offsetHours = DEFAULT_TIMEZONE_OFFSET) => {
|
|
4589
|
+
const source = date instanceof Date ? date : new Date(date || Date.now());
|
|
4590
|
+
const shifted = new Date(source.getTime() + offsetHours * 60 * 60 * 1e3);
|
|
4591
|
+
return [
|
|
4592
|
+
`${shifted.getUTCFullYear()}-${padDatePart(shifted.getUTCMonth() + 1)}-${padDatePart(shifted.getUTCDate())}`,
|
|
4593
|
+
`${padDatePart(shifted.getUTCHours())}:${padDatePart(shifted.getUTCMinutes())}:${padDatePart(shifted.getUTCSeconds())}`,
|
|
4594
|
+
formatUtcOffsetLabel(offsetHours)
|
|
4595
|
+
].join(" ");
|
|
4596
|
+
};
|
|
4597
|
+
var normalizeWhitespace = (value) => String(value || "").replace(/\u00a0/g, " ").replace(/\s+/g, " ").trim();
|
|
4598
|
+
var stripLocationNetworkSuffix = (value) => {
|
|
4599
|
+
const parts = normalizeWhitespace(value).split(" ").filter(Boolean);
|
|
4600
|
+
if (parts.length <= 1) {
|
|
4601
|
+
return normalizeWhitespace(value);
|
|
4602
|
+
}
|
|
4603
|
+
const last = parts[parts.length - 1];
|
|
4604
|
+
if (!LOCATION_NETWORK_SUFFIX_PATTERNS.some((pattern) => pattern.test(last))) {
|
|
4605
|
+
return parts.join(" ");
|
|
4606
|
+
}
|
|
4607
|
+
return parts.slice(0, -1).join(" ").trim();
|
|
4608
|
+
};
|
|
4609
|
+
var isWeakLocationValue = (value) => {
|
|
4610
|
+
const text = normalizeWhitespace(value).toLowerCase();
|
|
4611
|
+
if (!text) return true;
|
|
4612
|
+
if (WEAK_LOCATION_VALUES.has(text)) return true;
|
|
4613
|
+
return /^[a-z]{2,3}$/i.test(text);
|
|
4614
|
+
};
|
|
4615
|
+
var pickHeaderValue = async (response, names = []) => {
|
|
4616
|
+
if (!response || typeof response.headerValue !== "function") return "";
|
|
4617
|
+
for (const name of names) {
|
|
4618
|
+
const value = await response.headerValue(name).catch(() => null);
|
|
4619
|
+
const text = normalizeText(value);
|
|
4620
|
+
if (text) return text;
|
|
4621
|
+
}
|
|
4622
|
+
return "";
|
|
4623
|
+
};
|
|
4624
|
+
var parseIpIpResponse = (rawText) => {
|
|
4625
|
+
const text = normalizeWhitespace(rawText);
|
|
4626
|
+
if (!text) return null;
|
|
4627
|
+
const ipMatch = text.match(/当前\s*IP[::]\s*([^\s]+)/i) || text.match(/\b((?:\d{1,3}\.){3}\d{1,3}|(?:[0-9a-f]{0,4}:){2,}[0-9a-f]{0,4})\b/i);
|
|
4628
|
+
const locationMatch = text.match(/来自于[::]?\s*(.+)$/i);
|
|
4629
|
+
const ip = toInline(ipMatch?.[1], 80);
|
|
4630
|
+
const rawLocation = toInline(locationMatch?.[1], 120);
|
|
4631
|
+
const location = toInline(stripLocationNetworkSuffix(rawLocation), 80) || rawLocation;
|
|
4632
|
+
if (!ip && !location) {
|
|
4633
|
+
return null;
|
|
4634
|
+
}
|
|
4635
|
+
return { ip, location };
|
|
4636
|
+
};
|
|
4637
|
+
var fillEnrichment = (target, source) => {
|
|
4638
|
+
if (!target || !source || typeof source !== "object") {
|
|
4639
|
+
return target;
|
|
4640
|
+
}
|
|
4641
|
+
if (!target.ip && source.ip) {
|
|
4642
|
+
target.ip = toInline(source.ip, 80);
|
|
4643
|
+
}
|
|
4644
|
+
if (!target.location && source.location) {
|
|
4645
|
+
target.location = toInline(source.location, 80);
|
|
4646
|
+
}
|
|
4647
|
+
return target;
|
|
4648
|
+
};
|
|
4649
|
+
var getHostname = (url) => {
|
|
4650
|
+
try {
|
|
4651
|
+
const parsed = new URL(url);
|
|
4652
|
+
return parsed.hostname || parsed.host || "\u672C\u5730\u9875\u9762";
|
|
4653
|
+
} catch {
|
|
4654
|
+
if (/^https?:\/\//i.test(url)) {
|
|
4655
|
+
return url;
|
|
4656
|
+
}
|
|
4657
|
+
return "\u672C\u5730\u9875\u9762";
|
|
4658
|
+
}
|
|
4659
|
+
};
|
|
4660
|
+
var withTimeout = async (promise, timeoutMs) => {
|
|
4661
|
+
const safeTimeoutMs = Math.max(0, Number(timeoutMs) || 0);
|
|
4662
|
+
if (!safeTimeoutMs) {
|
|
4663
|
+
return promise;
|
|
4664
|
+
}
|
|
4665
|
+
let timer = null;
|
|
4666
|
+
try {
|
|
4667
|
+
return await Promise.race([
|
|
4668
|
+
promise,
|
|
4669
|
+
new Promise((resolve) => {
|
|
4670
|
+
timer = setTimeout(() => resolve(null), safeTimeoutMs);
|
|
4671
|
+
})
|
|
4672
|
+
]);
|
|
4673
|
+
} finally {
|
|
4674
|
+
if (timer) clearTimeout(timer);
|
|
4675
|
+
}
|
|
4676
|
+
};
|
|
4677
|
+
var fetchAsDataUrl = async (url, timeoutMs = DEFAULT_LOGO_FETCH_TIMEOUT_MS) => {
|
|
4678
|
+
if (typeof fetch !== "function") {
|
|
4679
|
+
return "";
|
|
4680
|
+
}
|
|
4681
|
+
const controller = typeof AbortController === "function" ? new AbortController() : null;
|
|
4682
|
+
const safeTimeoutMs = Math.max(300, Number(timeoutMs) || DEFAULT_LOGO_FETCH_TIMEOUT_MS);
|
|
4683
|
+
const timer = controller ? setTimeout(() => controller.abort(), safeTimeoutMs) : null;
|
|
4684
|
+
try {
|
|
4685
|
+
const response = await fetch(url, {
|
|
4686
|
+
redirect: "follow",
|
|
4687
|
+
signal: controller?.signal
|
|
4688
|
+
});
|
|
4689
|
+
if (!response?.ok) {
|
|
4690
|
+
return "";
|
|
4691
|
+
}
|
|
4692
|
+
const contentType = normalizeText(response.headers?.get?.("content-type")) || "image/png";
|
|
4693
|
+
if (!/^image\//i.test(contentType)) {
|
|
4694
|
+
return "";
|
|
4695
|
+
}
|
|
4696
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
4697
|
+
if (!buffer.length) {
|
|
4698
|
+
return "";
|
|
4699
|
+
}
|
|
4700
|
+
return `data:${contentType};base64,${buffer.toString("base64")}`;
|
|
4701
|
+
} catch {
|
|
4702
|
+
return "";
|
|
4703
|
+
} finally {
|
|
4704
|
+
if (timer) clearTimeout(timer);
|
|
4705
|
+
}
|
|
4706
|
+
};
|
|
4707
|
+
var resolveStripLogoSrc = async () => {
|
|
4708
|
+
if (!cachedStripLogoSrcPromise) {
|
|
4709
|
+
cachedStripLogoSrcPromise = (async () => {
|
|
4710
|
+
const dataUrl = await fetchAsDataUrl(DEFAULT_STRIP_LOGO_URL);
|
|
4711
|
+
return dataUrl || DEFAULT_STRIP_LOGO_URL;
|
|
4712
|
+
})();
|
|
4713
|
+
}
|
|
4714
|
+
const resolved = await cachedStripLogoSrcPromise.catch(() => DEFAULT_STRIP_LOGO_URL);
|
|
4715
|
+
return normalizeText(resolved) || DEFAULT_STRIP_LOGO_URL;
|
|
4716
|
+
};
|
|
4717
|
+
var normalizeLayer = (value, defaults) => {
|
|
4718
|
+
if (value === false) {
|
|
4719
|
+
return {
|
|
4720
|
+
...defaults,
|
|
4721
|
+
enabled: false
|
|
4722
|
+
};
|
|
4723
|
+
}
|
|
4724
|
+
if (value && typeof value === "object") {
|
|
4725
|
+
return {
|
|
4726
|
+
...defaults,
|
|
4727
|
+
...value,
|
|
4728
|
+
enabled: value.enabled !== false
|
|
4729
|
+
};
|
|
4730
|
+
}
|
|
4731
|
+
return {
|
|
4732
|
+
...defaults,
|
|
4733
|
+
enabled: true
|
|
4734
|
+
};
|
|
4735
|
+
};
|
|
4736
|
+
var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
4737
|
+
const resolver = typeof options.resolver === "function" ? options.resolver : null;
|
|
4738
|
+
if (!resolver) {
|
|
4739
|
+
return null;
|
|
4740
|
+
}
|
|
4741
|
+
const response = options.response && typeof options.response === "object" ? options.response : null;
|
|
4742
|
+
const serverAddr = response && typeof response.serverAddr === "function" ? await response.serverAddr().catch(() => null) : null;
|
|
4743
|
+
const controller = typeof AbortController === "function" ? new AbortController() : null;
|
|
4744
|
+
try {
|
|
4745
|
+
const resolved = await withTimeout(
|
|
4746
|
+
Promise.resolve(resolver({
|
|
4747
|
+
page,
|
|
4748
|
+
response,
|
|
4749
|
+
url: baseMeta.url,
|
|
4750
|
+
hostname: baseMeta.hostname,
|
|
4751
|
+
title: baseMeta.title,
|
|
4752
|
+
query: baseMeta.query,
|
|
4753
|
+
taskId: baseMeta.taskId,
|
|
4754
|
+
serverAddr,
|
|
4755
|
+
signal: controller?.signal
|
|
4756
|
+
})).catch(() => null),
|
|
4757
|
+
options.resolverTimeoutMs ?? DEFAULT_RESOLVER_TIMEOUT_MS
|
|
4758
|
+
);
|
|
4759
|
+
if (!resolved || typeof resolved !== "object") {
|
|
4760
|
+
return null;
|
|
4761
|
+
}
|
|
4762
|
+
return {
|
|
4763
|
+
ip: toInline(resolved.ip, 80),
|
|
4764
|
+
location: toInline(resolved.location, 80)
|
|
4765
|
+
};
|
|
4766
|
+
} finally {
|
|
4767
|
+
controller?.abort();
|
|
4768
|
+
}
|
|
4769
|
+
};
|
|
4770
|
+
var openProbePage = async (page) => {
|
|
4771
|
+
if (!page || typeof page.context !== "function") {
|
|
4772
|
+
return null;
|
|
4773
|
+
}
|
|
4774
|
+
const context = page.context();
|
|
4775
|
+
if (!context) {
|
|
4776
|
+
return null;
|
|
4777
|
+
}
|
|
4778
|
+
if (typeof context.newPage === "function") {
|
|
4779
|
+
try {
|
|
4780
|
+
const probePage2 = await context.newPage();
|
|
4781
|
+
return {
|
|
4782
|
+
page: probePage2,
|
|
4783
|
+
close: async () => {
|
|
4784
|
+
await probePage2.close().catch(() => {
|
|
4785
|
+
});
|
|
4786
|
+
}
|
|
4787
|
+
};
|
|
4788
|
+
} catch {
|
|
4789
|
+
}
|
|
4790
|
+
}
|
|
4791
|
+
const browser = typeof context.browser === "function" ? context.browser() : null;
|
|
4792
|
+
if (!browser || typeof browser.newContext !== "function") {
|
|
4793
|
+
return null;
|
|
4794
|
+
}
|
|
4795
|
+
const probeContext = await browser.newContext().catch(() => null);
|
|
4796
|
+
if (!probeContext || typeof probeContext.newPage !== "function") {
|
|
4797
|
+
await probeContext?.close?.().catch(() => {
|
|
4798
|
+
});
|
|
4799
|
+
return null;
|
|
4800
|
+
}
|
|
4801
|
+
const probePage = await probeContext.newPage().catch(async () => {
|
|
4802
|
+
await probeContext.close().catch(() => {
|
|
4803
|
+
});
|
|
4804
|
+
return null;
|
|
4805
|
+
});
|
|
4806
|
+
if (!probePage) {
|
|
4807
|
+
return null;
|
|
4808
|
+
}
|
|
4809
|
+
return {
|
|
4810
|
+
page: probePage,
|
|
4811
|
+
close: async () => {
|
|
4812
|
+
await probeContext.close().catch(() => {
|
|
4813
|
+
});
|
|
4814
|
+
}
|
|
4815
|
+
};
|
|
4816
|
+
};
|
|
4817
|
+
var resolveWithIpLookup = async (page, options = {}) => {
|
|
4818
|
+
if (!page || typeof page.context !== "function" || options.ipLookup === false) {
|
|
4819
|
+
return null;
|
|
4820
|
+
}
|
|
4821
|
+
const probeScope = await openProbePage(page);
|
|
4822
|
+
if (!probeScope?.page) {
|
|
4823
|
+
return null;
|
|
4824
|
+
}
|
|
4825
|
+
const timeoutMs = Math.max(
|
|
4826
|
+
300,
|
|
4827
|
+
Number(options.ipLookupTimeoutMs) || DEFAULT_IP_LOOKUP_TIMEOUT_MS
|
|
4828
|
+
);
|
|
4829
|
+
try {
|
|
4830
|
+
const probePage = probeScope.page;
|
|
4831
|
+
const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
|
|
4832
|
+
waitUntil: "commit",
|
|
4833
|
+
timeout: timeoutMs
|
|
4834
|
+
}).catch(() => null);
|
|
4835
|
+
let rawText = "";
|
|
4836
|
+
if (response && typeof response.text === "function") {
|
|
4837
|
+
rawText = String(await withTimeout(
|
|
4838
|
+
response.text().catch(() => ""),
|
|
4839
|
+
timeoutMs
|
|
4840
|
+
) || "");
|
|
4841
|
+
}
|
|
4842
|
+
if (!rawText) {
|
|
4843
|
+
rawText = String(await withTimeout(
|
|
4844
|
+
probePage.evaluate(() => {
|
|
4845
|
+
return document.body?.innerText || document.documentElement?.innerText || "";
|
|
4846
|
+
}).catch(() => ""),
|
|
4847
|
+
Math.min(timeoutMs, 500)
|
|
4848
|
+
) || "");
|
|
4849
|
+
}
|
|
4850
|
+
return parseIpIpResponse(rawText);
|
|
4851
|
+
} catch {
|
|
4852
|
+
return null;
|
|
4853
|
+
} finally {
|
|
4854
|
+
await probeScope.close().catch(() => {
|
|
4855
|
+
});
|
|
4856
|
+
}
|
|
4857
|
+
};
|
|
4858
|
+
var resolveEnrichment = async (page, baseMeta, options) => {
|
|
4859
|
+
const response = options.response && typeof options.response === "object" ? options.response : null;
|
|
4860
|
+
const merged = {
|
|
4861
|
+
ip: toInline(options.ip, 80),
|
|
4862
|
+
location: toInline(options.location, 80)
|
|
4863
|
+
};
|
|
4864
|
+
if (!merged.ip || !merged.location) {
|
|
4865
|
+
fillEnrichment(
|
|
4866
|
+
merged,
|
|
4867
|
+
await resolveWithCustomResolver(page, baseMeta, options)
|
|
4868
|
+
);
|
|
4869
|
+
}
|
|
4870
|
+
if ((!merged.ip || !merged.location) && options.ipLookup !== false) {
|
|
4871
|
+
fillEnrichment(
|
|
4872
|
+
merged,
|
|
4873
|
+
await resolveWithIpLookup(page, options)
|
|
4874
|
+
);
|
|
4875
|
+
}
|
|
4876
|
+
if (!merged.location || isWeakLocationValue(merged.location)) {
|
|
4877
|
+
const headerLocation = toInline(await pickHeaderValue(response, [
|
|
4878
|
+
"cf-ipcountry",
|
|
4879
|
+
"x-vercel-ip-country",
|
|
4880
|
+
"x-country-code",
|
|
4881
|
+
"x-geo-country"
|
|
4882
|
+
]), 80);
|
|
4883
|
+
if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
|
|
4884
|
+
merged.location = headerLocation || merged.location;
|
|
4885
|
+
}
|
|
4886
|
+
}
|
|
4887
|
+
return merged;
|
|
4888
|
+
};
|
|
4889
|
+
var buildWatermarkStamp = ({ taskId, captureTime, ip, location }) => {
|
|
4890
|
+
const parts = [
|
|
4891
|
+
`TaskID ${shortenMiddle(taskId, 56, 24, 16) || "-"}`,
|
|
4892
|
+
`Time ${captureTime}`,
|
|
4893
|
+
`Loc ${shortenTail(location, 20) || "-"}`,
|
|
4894
|
+
`IP ${toInline(ip, 24) || "-"}`
|
|
4895
|
+
];
|
|
4896
|
+
return parts.join(" | ");
|
|
4897
|
+
};
|
|
4898
|
+
var buildStripSegments = ({ taskId, captureTime, ip, location }) => {
|
|
4899
|
+
return [
|
|
4900
|
+
{
|
|
4901
|
+
kind: "taskId",
|
|
4902
|
+
label: "TaskID",
|
|
4903
|
+
value: toInline(taskId, 240) || "-",
|
|
4904
|
+
rawValue: toInline(taskId, 240) || "-"
|
|
4905
|
+
},
|
|
4906
|
+
{
|
|
4907
|
+
kind: "time",
|
|
4908
|
+
label: "Time",
|
|
4909
|
+
value: captureTime,
|
|
4910
|
+
rawValue: captureTime
|
|
4911
|
+
},
|
|
4912
|
+
{
|
|
4913
|
+
kind: "location",
|
|
4914
|
+
label: "Loc",
|
|
4915
|
+
value: shortenTail(location, 24) || "-",
|
|
4916
|
+
rawValue: toInline(location, 80) || "-"
|
|
4917
|
+
},
|
|
4918
|
+
{
|
|
4919
|
+
kind: "ip",
|
|
4920
|
+
label: "IP",
|
|
4921
|
+
value: toInline(ip, 28) || "-",
|
|
4922
|
+
rawValue: toInline(ip, 80) || "-"
|
|
4923
|
+
}
|
|
4924
|
+
];
|
|
4925
|
+
};
|
|
4926
|
+
var createBaseWatermarkifyOptions = () => ({
|
|
4927
|
+
enabled: true,
|
|
4928
|
+
timezoneOffsetHours: DEFAULT_TIMEZONE_OFFSET,
|
|
4929
|
+
response: null,
|
|
4930
|
+
ip: "",
|
|
4931
|
+
location: "",
|
|
4932
|
+
query: "",
|
|
4933
|
+
taskId: "",
|
|
4934
|
+
ipLookup: true,
|
|
4935
|
+
ipLookupTimeoutMs: DEFAULT_IP_LOOKUP_TIMEOUT_MS,
|
|
4936
|
+
resolver: null,
|
|
4937
|
+
resolverTimeoutMs: DEFAULT_RESOLVER_TIMEOUT_MS,
|
|
4938
|
+
watermark: normalizeLayer(void 0, {
|
|
4939
|
+
opacity: DEFAULT_WATERMARK_OPACITY,
|
|
4940
|
+
rotateDeg: DEFAULT_WATERMARK_ROTATE_DEG,
|
|
4941
|
+
cellWidth: DEFAULT_WATERMARK_CELL_WIDTH,
|
|
4942
|
+
cellHeight: DEFAULT_WATERMARK_CELL_HEIGHT
|
|
4943
|
+
}),
|
|
4944
|
+
strip: normalizeLayer(void 0, {})
|
|
4945
|
+
});
|
|
4946
|
+
var createDisabledWatermarkifyOptions = () => ({
|
|
4947
|
+
...createBaseWatermarkifyOptions(),
|
|
4948
|
+
enabled: false,
|
|
4949
|
+
watermark: normalizeLayer(false, {
|
|
4950
|
+
opacity: DEFAULT_WATERMARK_OPACITY,
|
|
4951
|
+
rotateDeg: DEFAULT_WATERMARK_ROTATE_DEG,
|
|
4952
|
+
cellWidth: DEFAULT_WATERMARK_CELL_WIDTH,
|
|
4953
|
+
cellHeight: DEFAULT_WATERMARK_CELL_HEIGHT
|
|
4954
|
+
}),
|
|
4955
|
+
strip: normalizeLayer(false, {})
|
|
4956
|
+
});
|
|
4957
|
+
var normalizeScreenshotWatermarkify = (value) => {
|
|
4958
|
+
const base = createBaseWatermarkifyOptions();
|
|
4959
|
+
if (value === false) {
|
|
4960
|
+
return createDisabledWatermarkifyOptions();
|
|
4961
|
+
}
|
|
4962
|
+
if (value == null || value === true) {
|
|
4963
|
+
return base;
|
|
4964
|
+
}
|
|
4965
|
+
const source = value && typeof value === "object" ? value : {};
|
|
4966
|
+
const timezoneOffsetHoursRaw = Number(source.timezoneOffsetHours);
|
|
4967
|
+
const ipLookupTimeoutMsRaw = Number(source.ipLookupTimeoutMs);
|
|
4968
|
+
const resolverTimeoutMsRaw = Number(source.resolverTimeoutMs);
|
|
4969
|
+
return {
|
|
4970
|
+
...base,
|
|
4971
|
+
enabled: source.enabled !== false,
|
|
4972
|
+
timezoneOffsetHours: Number.isFinite(timezoneOffsetHoursRaw) ? timezoneOffsetHoursRaw : DEFAULT_TIMEZONE_OFFSET,
|
|
4973
|
+
response: source.response ?? null,
|
|
4974
|
+
ip: normalizeText(source.ip),
|
|
4975
|
+
location: normalizeText(source.location),
|
|
4976
|
+
query: toInline(source.query, 140),
|
|
4977
|
+
taskId: toInline(source.taskId, 120),
|
|
4978
|
+
ipLookup: source.ipLookup !== false,
|
|
4979
|
+
ipLookupTimeoutMs: Number.isFinite(ipLookupTimeoutMsRaw) ? ipLookupTimeoutMsRaw : DEFAULT_IP_LOOKUP_TIMEOUT_MS,
|
|
4980
|
+
resolver: typeof source.resolver === "function" ? source.resolver : null,
|
|
4981
|
+
resolverTimeoutMs: Number.isFinite(resolverTimeoutMsRaw) ? resolverTimeoutMsRaw : DEFAULT_RESOLVER_TIMEOUT_MS,
|
|
4982
|
+
watermark: normalizeLayer(source.watermark, {
|
|
4983
|
+
opacity: DEFAULT_WATERMARK_OPACITY,
|
|
4984
|
+
rotateDeg: DEFAULT_WATERMARK_ROTATE_DEG,
|
|
4985
|
+
cellWidth: DEFAULT_WATERMARK_CELL_WIDTH,
|
|
4986
|
+
cellHeight: DEFAULT_WATERMARK_CELL_HEIGHT
|
|
4987
|
+
}),
|
|
4988
|
+
strip: normalizeLayer(source.strip, {})
|
|
4989
|
+
};
|
|
4990
|
+
};
|
|
4991
|
+
var resolveScreenshotWatermarkifyMeta = async (page, options = {}) => {
|
|
4992
|
+
const timezoneOffsetHours = options.timezoneOffsetHours ?? DEFAULT_TIMEZONE_OFFSET;
|
|
4993
|
+
const url = normalizeText(page?.url?.()) || "about:blank";
|
|
4994
|
+
const title = normalizeText(await page.title().catch(() => "")) || "\u672A\u547D\u540D\u9875\u9762";
|
|
4995
|
+
const hostname = getHostname(url);
|
|
4996
|
+
const query = normalizeText(options.query) || title || "\u672A\u63D0\u4F9B Query";
|
|
4997
|
+
const taskId = normalizeText(options.taskId) || "-";
|
|
4998
|
+
const captureTime = formatTimestampForUtcOffset(/* @__PURE__ */ new Date(), timezoneOffsetHours);
|
|
4999
|
+
const [enrichment, stripLogoSrc] = await Promise.all([
|
|
5000
|
+
resolveEnrichment(page, {
|
|
5001
|
+
url,
|
|
5002
|
+
hostname,
|
|
5003
|
+
title,
|
|
5004
|
+
query,
|
|
5005
|
+
taskId
|
|
5006
|
+
}, options),
|
|
5007
|
+
resolveStripLogoSrc()
|
|
5008
|
+
]);
|
|
5009
|
+
const ip = enrichment.ip || "-";
|
|
5010
|
+
const location = enrichment.location || "-";
|
|
5011
|
+
return {
|
|
5012
|
+
watermarkText: buildWatermarkStamp({
|
|
5013
|
+
taskId,
|
|
5014
|
+
captureTime,
|
|
5015
|
+
ip,
|
|
5016
|
+
location
|
|
5017
|
+
}),
|
|
5018
|
+
stripSegments: buildStripSegments({
|
|
5019
|
+
taskId,
|
|
5020
|
+
captureTime,
|
|
5021
|
+
ip,
|
|
5022
|
+
location
|
|
5023
|
+
}),
|
|
5024
|
+
watermark: options.watermark,
|
|
5025
|
+
strip: options.strip,
|
|
5026
|
+
stripLogoSrc
|
|
5027
|
+
};
|
|
5028
|
+
};
|
|
5029
|
+
var installScreenshotWatermarkify = async (page, meta) => {
|
|
5030
|
+
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
|
|
5031
|
+
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
5032
|
+
if (!page || !meta || !hasWatermark && !hasStrip) {
|
|
5033
|
+
return async () => {
|
|
5034
|
+
};
|
|
5035
|
+
}
|
|
5036
|
+
await page.evaluate(({ hostId, watermarkifyMeta, defaults }) => {
|
|
5037
|
+
const previousHost = document.getElementById(hostId);
|
|
5038
|
+
if (previousHost && typeof previousHost.__pkCleanup === "function") {
|
|
5039
|
+
previousHost.__pkCleanup();
|
|
5040
|
+
}
|
|
5041
|
+
previousHost?.remove();
|
|
5042
|
+
const mountPoint = document.body || document.documentElement;
|
|
5043
|
+
if (!mountPoint) return;
|
|
5044
|
+
const createNode = (tagName, className) => {
|
|
5045
|
+
const node = document.createElement(tagName);
|
|
5046
|
+
if (className) node.className = className;
|
|
5047
|
+
return node;
|
|
5048
|
+
};
|
|
5049
|
+
const safeText = (value) => String(value || "").trim();
|
|
5050
|
+
const host = document.createElement("div");
|
|
5051
|
+
host.id = hostId;
|
|
5052
|
+
host.style.position = "fixed";
|
|
5053
|
+
host.style.inset = "0";
|
|
5054
|
+
host.style.width = "100vw";
|
|
5055
|
+
host.style.height = "100vh";
|
|
5056
|
+
host.style.pointerEvents = "none";
|
|
5057
|
+
host.style.zIndex = "2147483646";
|
|
5058
|
+
const shadow = host.attachShadow({ mode: "open" });
|
|
5059
|
+
const style = document.createElement("style");
|
|
5060
|
+
style.textContent = `
|
|
5061
|
+
:host {
|
|
5062
|
+
all: initial;
|
|
5063
|
+
position: fixed;
|
|
5064
|
+
inset: 0;
|
|
5065
|
+
width: 100vw;
|
|
5066
|
+
height: 100vh;
|
|
5067
|
+
pointer-events: none;
|
|
5068
|
+
z-index: 2147483646;
|
|
5069
|
+
}
|
|
5070
|
+
|
|
5071
|
+
.root {
|
|
5072
|
+
position: absolute;
|
|
5073
|
+
inset: 0;
|
|
5074
|
+
width: 100%;
|
|
5075
|
+
height: 100%;
|
|
5076
|
+
overflow: hidden;
|
|
5077
|
+
pointer-events: none;
|
|
5078
|
+
font-family: MiSans, "SF Pro Display", "PingFang SC", "Helvetica Neue", Arial, sans-serif;
|
|
5079
|
+
}
|
|
5080
|
+
|
|
5081
|
+
.watermark {
|
|
5082
|
+
position: absolute;
|
|
5083
|
+
inset: 0;
|
|
5084
|
+
overflow: hidden;
|
|
5085
|
+
pointer-events: none;
|
|
5086
|
+
}
|
|
5087
|
+
|
|
5088
|
+
.wmStamp {
|
|
5089
|
+
position: absolute;
|
|
5090
|
+
left: 0;
|
|
5091
|
+
top: 0;
|
|
5092
|
+
transform-origin: left center;
|
|
5093
|
+
pointer-events: none;
|
|
5094
|
+
white-space: nowrap;
|
|
5095
|
+
}
|
|
5096
|
+
|
|
5097
|
+
.wmStampText {
|
|
5098
|
+
color: rgba(17, 17, 17, var(--wm-opacity, 0.15));
|
|
5099
|
+
font-size: 19px;
|
|
5100
|
+
font-weight: 720;
|
|
5101
|
+
line-height: 1;
|
|
5102
|
+
letter-spacing: 0.032em;
|
|
5103
|
+
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.44);
|
|
5104
|
+
-webkit-text-stroke: 0.22px rgba(255, 255, 255, 0.12);
|
|
5105
|
+
font-variant-numeric: tabular-nums;
|
|
5106
|
+
filter: saturate(0.92);
|
|
5107
|
+
}
|
|
5108
|
+
|
|
5109
|
+
.strip {
|
|
5110
|
+
position: absolute;
|
|
5111
|
+
left: 0;
|
|
5112
|
+
right: 0;
|
|
5113
|
+
bottom: 0;
|
|
5114
|
+
min-height: 78px;
|
|
5115
|
+
padding: 0 22px 0 20px;
|
|
5116
|
+
display: flex;
|
|
5117
|
+
align-items: center;
|
|
5118
|
+
overflow: hidden;
|
|
5119
|
+
border-top: 1px solid rgba(17, 17, 17, 0.1);
|
|
5120
|
+
background:
|
|
5121
|
+
linear-gradient(180deg, rgba(255, 255, 255, 0.995) 0%, rgba(248, 248, 247, 0.985) 100%);
|
|
5122
|
+
box-shadow:
|
|
5123
|
+
0 -22px 48px rgba(15, 23, 42, 0.1),
|
|
5124
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.92);
|
|
5125
|
+
backdrop-filter: blur(16px);
|
|
5126
|
+
-webkit-backdrop-filter: blur(16px);
|
|
5127
|
+
}
|
|
5128
|
+
|
|
5129
|
+
.strip::before {
|
|
5130
|
+
content: "";
|
|
5131
|
+
position: absolute;
|
|
5132
|
+
left: 20px;
|
|
5133
|
+
right: 52%;
|
|
5134
|
+
top: 0;
|
|
5135
|
+
height: 2px;
|
|
5136
|
+
border-radius: 999px;
|
|
5137
|
+
background: linear-gradient(
|
|
5138
|
+
90deg,
|
|
5139
|
+
rgba(17, 17, 17, 0.98) 0%,
|
|
5140
|
+
rgba(17, 17, 17, 0.68) 24%,
|
|
5141
|
+
rgba(17, 17, 17, 0.08) 58%,
|
|
5142
|
+
rgba(17, 17, 17, 0) 100%
|
|
5143
|
+
);
|
|
5144
|
+
}
|
|
5145
|
+
|
|
5146
|
+
.stripInner {
|
|
5147
|
+
position: relative;
|
|
5148
|
+
z-index: 1;
|
|
5149
|
+
display: flex;
|
|
5150
|
+
align-items: center;
|
|
5151
|
+
gap: 16px;
|
|
5152
|
+
width: 100%;
|
|
5153
|
+
min-width: 0;
|
|
5154
|
+
}
|
|
5155
|
+
|
|
5156
|
+
.stripLogo {
|
|
5157
|
+
position: relative;
|
|
5158
|
+
width: 28px;
|
|
5159
|
+
height: 28px;
|
|
5160
|
+
flex: none;
|
|
5161
|
+
display: flex;
|
|
5162
|
+
align-items: center;
|
|
5163
|
+
justify-content: center;
|
|
5164
|
+
}
|
|
5165
|
+
|
|
5166
|
+
.stripLogoImg {
|
|
5167
|
+
width: 28px;
|
|
5168
|
+
height: 28px;
|
|
5169
|
+
object-fit: contain;
|
|
5170
|
+
display: block;
|
|
5171
|
+
}
|
|
5172
|
+
|
|
5173
|
+
.segments {
|
|
5174
|
+
display: flex;
|
|
5175
|
+
align-items: center;
|
|
5176
|
+
gap: 0;
|
|
5177
|
+
flex: 1 1 auto;
|
|
5178
|
+
min-width: 0;
|
|
5179
|
+
white-space: nowrap;
|
|
5180
|
+
}
|
|
5181
|
+
|
|
5182
|
+
.segment {
|
|
5183
|
+
position: relative;
|
|
5184
|
+
display: inline-flex;
|
|
5185
|
+
align-items: center;
|
|
5186
|
+
gap: 10px;
|
|
5187
|
+
min-width: 0;
|
|
5188
|
+
flex: none;
|
|
5189
|
+
padding-right: 16px;
|
|
5190
|
+
margin-right: 16px;
|
|
5191
|
+
}
|
|
5192
|
+
|
|
5193
|
+
.segment:not(:last-child)::after {
|
|
5194
|
+
content: "";
|
|
5195
|
+
position: absolute;
|
|
5196
|
+
top: 50%;
|
|
5197
|
+
right: 0;
|
|
5198
|
+
width: 1px;
|
|
5199
|
+
height: 25px;
|
|
5200
|
+
transform: translateY(-50%);
|
|
5201
|
+
background: linear-gradient(
|
|
5202
|
+
180deg,
|
|
5203
|
+
rgba(148, 163, 184, 0) 0%,
|
|
5204
|
+
rgba(148, 163, 184, 0.34) 24%,
|
|
5205
|
+
rgba(148, 163, 184, 0.34) 76%,
|
|
5206
|
+
rgba(148, 163, 184, 0) 100%
|
|
5207
|
+
);
|
|
5208
|
+
}
|
|
5209
|
+
|
|
5210
|
+
.segmentTaskId {
|
|
5211
|
+
flex: 1 1 auto;
|
|
5212
|
+
max-width: none;
|
|
5213
|
+
min-width: 0;
|
|
5214
|
+
}
|
|
5215
|
+
|
|
5216
|
+
.label {
|
|
5217
|
+
width: 52px;
|
|
5218
|
+
color: rgba(17, 17, 17, 0.42);
|
|
5219
|
+
font-size: 12px;
|
|
5220
|
+
font-weight: 600;
|
|
5221
|
+
line-height: 1;
|
|
5222
|
+
letter-spacing: 0.01em;
|
|
5223
|
+
flex: none;
|
|
5224
|
+
display: inline-flex;
|
|
5225
|
+
align-items: center;
|
|
5226
|
+
justify-content: flex-start;
|
|
5227
|
+
}
|
|
5228
|
+
|
|
5229
|
+
.value {
|
|
5230
|
+
color: #111111;
|
|
5231
|
+
font-size: 18px;
|
|
5232
|
+
font-weight: 710;
|
|
5233
|
+
line-height: 1;
|
|
5234
|
+
min-width: 0;
|
|
5235
|
+
overflow: hidden;
|
|
5236
|
+
text-overflow: ellipsis;
|
|
5237
|
+
font-variant-numeric: tabular-nums;
|
|
5238
|
+
display: inline-flex;
|
|
5239
|
+
align-items: center;
|
|
5240
|
+
}
|
|
5241
|
+
|
|
5242
|
+
.segmentTaskId .value {
|
|
5243
|
+
color: #101010;
|
|
5244
|
+
font-size: 15px;
|
|
5245
|
+
font-weight: 760;
|
|
5246
|
+
letter-spacing: -0.01em;
|
|
5247
|
+
}
|
|
5248
|
+
|
|
5249
|
+
.segmentTime .value {
|
|
5250
|
+
color: #202020;
|
|
5251
|
+
font-size: 17px;
|
|
5252
|
+
font-weight: 700;
|
|
5253
|
+
}
|
|
5254
|
+
|
|
5255
|
+
.segmentLocation .value,
|
|
5256
|
+
.segmentIp .value {
|
|
5257
|
+
color: #2a2a2a;
|
|
5258
|
+
font-size: 17px;
|
|
5259
|
+
font-weight: 700;
|
|
5260
|
+
}
|
|
5261
|
+
|
|
5262
|
+
`;
|
|
5263
|
+
const root = createNode("div", "root");
|
|
5264
|
+
const watermarkNode = createNode("div", "watermark");
|
|
5265
|
+
const stripNode = createNode("div", "strip");
|
|
5266
|
+
const stripInner = createNode("div", "stripInner");
|
|
5267
|
+
const stripLogo = createNode("div", "stripLogo");
|
|
5268
|
+
const stripLogoImg = createNode("img", "stripLogoImg");
|
|
5269
|
+
const stripSegmentsNode = createNode("div", "segments");
|
|
5270
|
+
stripLogoImg.alt = "";
|
|
5271
|
+
stripLogoImg.decoding = "async";
|
|
5272
|
+
stripLogoImg.referrerPolicy = "no-referrer";
|
|
5273
|
+
stripLogoImg.src = safeText(watermarkifyMeta?.stripLogoSrc) || defaults.logoUrl;
|
|
5274
|
+
stripLogo.appendChild(stripLogoImg);
|
|
5275
|
+
stripInner.appendChild(stripLogo);
|
|
5276
|
+
stripInner.appendChild(stripSegmentsNode);
|
|
5277
|
+
stripNode.appendChild(stripInner);
|
|
5278
|
+
root.appendChild(watermarkNode);
|
|
5279
|
+
root.appendChild(stripNode);
|
|
5280
|
+
shadow.appendChild(style);
|
|
5281
|
+
shadow.appendChild(root);
|
|
5282
|
+
mountPoint.appendChild(host);
|
|
5283
|
+
const buildSegmentNode = (segment) => {
|
|
5284
|
+
const kind = String(segment?.kind || "").trim();
|
|
5285
|
+
const label = String(segment?.label || "").trim();
|
|
5286
|
+
const value = String(segment?.value || "").trim();
|
|
5287
|
+
const rawValue = String(segment?.rawValue || value).trim();
|
|
5288
|
+
const classSuffix = kind ? ` segment${kind.slice(0, 1).toUpperCase()}${kind.slice(1)}` : "";
|
|
5289
|
+
const segmentNode = createNode("span", `segment${classSuffix}`);
|
|
5290
|
+
const labelNode = createNode("span", "label");
|
|
5291
|
+
const valueNode = createNode("span", "value");
|
|
5292
|
+
labelNode.textContent = label;
|
|
5293
|
+
valueNode.textContent = value;
|
|
5294
|
+
segmentNode.title = rawValue ? `${label} ${rawValue}` : label;
|
|
5295
|
+
segmentNode.appendChild(labelNode);
|
|
5296
|
+
segmentNode.appendChild(valueNode);
|
|
5297
|
+
return segmentNode;
|
|
5298
|
+
};
|
|
5299
|
+
const renderStrip = () => {
|
|
5300
|
+
const stripSegments = Array.isArray(watermarkifyMeta?.stripSegments) ? watermarkifyMeta.stripSegments : [];
|
|
5301
|
+
if (!watermarkifyMeta?.strip?.enabled || stripSegments.length === 0) {
|
|
5302
|
+
stripNode.remove();
|
|
5303
|
+
return;
|
|
5304
|
+
}
|
|
5305
|
+
const fragment = document.createDocumentFragment();
|
|
5306
|
+
for (const segment of stripSegments) {
|
|
5307
|
+
fragment.appendChild(buildSegmentNode(segment));
|
|
5308
|
+
}
|
|
5309
|
+
stripSegmentsNode.replaceChildren(fragment);
|
|
5310
|
+
};
|
|
5311
|
+
const waitForLogo = async () => {
|
|
5312
|
+
if (!stripLogoImg.getAttribute("src")) {
|
|
5313
|
+
return;
|
|
5314
|
+
}
|
|
5315
|
+
await new Promise((resolve) => {
|
|
5316
|
+
let settled = false;
|
|
5317
|
+
const done = () => {
|
|
5318
|
+
if (settled) return;
|
|
5319
|
+
settled = true;
|
|
5320
|
+
resolve();
|
|
5321
|
+
};
|
|
5322
|
+
const fail = () => {
|
|
5323
|
+
if (settled) return;
|
|
5324
|
+
stripLogo.remove();
|
|
5325
|
+
done();
|
|
5326
|
+
};
|
|
5327
|
+
const timeoutDone = () => {
|
|
5328
|
+
if (settled) return;
|
|
5329
|
+
done();
|
|
5330
|
+
};
|
|
5331
|
+
if (stripLogoImg.complete && stripLogoImg.naturalWidth > 0) {
|
|
5332
|
+
done();
|
|
5333
|
+
return;
|
|
5334
|
+
}
|
|
5335
|
+
if (stripLogoImg.complete && stripLogoImg.naturalWidth === 0) {
|
|
5336
|
+
fail();
|
|
5337
|
+
return;
|
|
5338
|
+
}
|
|
5339
|
+
stripLogoImg.addEventListener("load", done, { once: true });
|
|
5340
|
+
stripLogoImg.addEventListener("error", fail, { once: true });
|
|
5341
|
+
setTimeout(timeoutDone, 2500);
|
|
5342
|
+
});
|
|
5343
|
+
};
|
|
5344
|
+
const renderWatermark = () => {
|
|
5345
|
+
const stampText = safeText(watermarkifyMeta?.watermarkText);
|
|
5346
|
+
if (!watermarkifyMeta?.watermark?.enabled || !stampText) {
|
|
5347
|
+
watermarkNode.remove();
|
|
5348
|
+
return;
|
|
5349
|
+
}
|
|
5350
|
+
const cellWidth = Math.max(680, Number(watermarkifyMeta.watermark.cellWidth) || defaults.cellWidth);
|
|
5351
|
+
const cellHeight = Math.max(260, Number(watermarkifyMeta.watermark.cellHeight) || defaults.cellHeight);
|
|
5352
|
+
const rotateDeg = Number(watermarkifyMeta.watermark.rotateDeg) || defaults.rotateDeg;
|
|
5353
|
+
const opacity = Math.min(0.22, Math.max(0.05, Number(watermarkifyMeta.watermark.opacity) || defaults.opacity));
|
|
5354
|
+
const width = watermarkNode.clientWidth || window.innerWidth || document.documentElement.clientWidth || cellWidth;
|
|
5355
|
+
const height = watermarkNode.clientHeight || window.innerHeight || document.documentElement.clientHeight || cellHeight;
|
|
5356
|
+
const rowOffset = Math.round(cellWidth * 0.24);
|
|
5357
|
+
const startX = -Math.round(cellWidth * 0.16);
|
|
5358
|
+
const startY = -Math.round(cellHeight * 0.12);
|
|
5359
|
+
const cols = Math.ceil((width + cellWidth * 1.1) / cellWidth) + 1;
|
|
5360
|
+
const rows = Math.ceil((height + cellHeight * 0.9) / cellHeight) + 1;
|
|
5361
|
+
const fragment = document.createDocumentFragment();
|
|
5362
|
+
for (let row = 0; row < rows; row += 1) {
|
|
5363
|
+
for (let col = 0; col < cols; col += 1) {
|
|
5364
|
+
const stamp = createNode("div", "wmStamp");
|
|
5365
|
+
const stampTextNode = createNode("div", "wmStampText");
|
|
5366
|
+
const x = startX + col * cellWidth + (row % 2 ? rowOffset : 0);
|
|
5367
|
+
const y = startY + row * cellHeight + (row % 2 ? 14 : -8);
|
|
5368
|
+
stamp.style.transform = `translate(${x}px, ${y}px) rotate(${rotateDeg}deg)`;
|
|
5369
|
+
stampTextNode.style.setProperty("--wm-opacity", String(opacity));
|
|
5370
|
+
stampTextNode.textContent = stampText;
|
|
5371
|
+
stamp.appendChild(stampTextNode);
|
|
5372
|
+
fragment.appendChild(stamp);
|
|
5373
|
+
}
|
|
5374
|
+
}
|
|
5375
|
+
watermarkNode.replaceChildren(fragment);
|
|
5376
|
+
};
|
|
5377
|
+
let resizeFrame = 0;
|
|
5378
|
+
const queueWatermarkRender = () => {
|
|
5379
|
+
if (!watermarkNode.isConnected) return;
|
|
5380
|
+
cancelAnimationFrame(resizeFrame);
|
|
5381
|
+
resizeFrame = requestAnimationFrame(() => {
|
|
5382
|
+
renderWatermark();
|
|
5383
|
+
});
|
|
5384
|
+
};
|
|
5385
|
+
const handleResize = () => {
|
|
5386
|
+
queueWatermarkRender();
|
|
5387
|
+
};
|
|
5388
|
+
host.__pkCleanup = () => {
|
|
5389
|
+
cancelAnimationFrame(resizeFrame);
|
|
5390
|
+
window.removeEventListener("resize", handleResize);
|
|
5391
|
+
};
|
|
5392
|
+
renderStrip();
|
|
5393
|
+
renderWatermark();
|
|
5394
|
+
queueWatermarkRender();
|
|
5395
|
+
window.addEventListener("resize", handleResize, { passive: true });
|
|
5396
|
+
return waitForLogo();
|
|
5397
|
+
}, {
|
|
5398
|
+
hostId: SCREENSHOT_WATERMARKIFY_HOST_ID,
|
|
5399
|
+
watermarkifyMeta: meta,
|
|
5400
|
+
defaults: {
|
|
5401
|
+
opacity: DEFAULT_WATERMARK_OPACITY,
|
|
5402
|
+
rotateDeg: DEFAULT_WATERMARK_ROTATE_DEG,
|
|
5403
|
+
cellWidth: DEFAULT_WATERMARK_CELL_WIDTH,
|
|
5404
|
+
cellHeight: DEFAULT_WATERMARK_CELL_HEIGHT,
|
|
5405
|
+
logoUrl: DEFAULT_STRIP_LOGO_URL
|
|
5406
|
+
}
|
|
5407
|
+
});
|
|
5408
|
+
return async () => {
|
|
5409
|
+
await page.evaluate((hostId) => {
|
|
5410
|
+
const host = document.getElementById(hostId);
|
|
5411
|
+
if (host && typeof host.__pkCleanup === "function") {
|
|
5412
|
+
host.__pkCleanup();
|
|
5413
|
+
}
|
|
5414
|
+
host?.remove();
|
|
5415
|
+
}, SCREENSHOT_WATERMARKIFY_HOST_ID).catch(() => {
|
|
5416
|
+
});
|
|
5417
|
+
};
|
|
5418
|
+
};
|
|
5419
|
+
|
|
5420
|
+
// src/share.js
|
|
4533
5421
|
var logger11 = createInternalLogger("Share");
|
|
4534
5422
|
var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
|
|
4535
5423
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
@@ -4540,14 +5428,14 @@ var toSnapshot = (value, maxLen) => {
|
|
|
4540
5428
|
if (!text) return "";
|
|
4541
5429
|
return text.replace(/\s+/g, " ").trim().slice(0, maxLen);
|
|
4542
5430
|
};
|
|
4543
|
-
var
|
|
5431
|
+
var toInline2 = (value, maxLen = 200) => {
|
|
4544
5432
|
const text = String(value || "");
|
|
4545
5433
|
if (!text) return "";
|
|
4546
5434
|
return text.replace(/\s+/g, " ").trim().slice(0, maxLen);
|
|
4547
5435
|
};
|
|
4548
5436
|
var toJsonInline = (value, maxLen = 260) => {
|
|
4549
5437
|
try {
|
|
4550
|
-
return
|
|
5438
|
+
return toInline2(JSON.stringify(value), maxLen);
|
|
4551
5439
|
} catch {
|
|
4552
5440
|
return "[\u4E0D\u53EF\u5E8F\u5217\u5316]";
|
|
4553
5441
|
}
|
|
@@ -4935,6 +5823,9 @@ var Share = {
|
|
|
4935
5823
|
const buffer = options.buffer ?? defaultBuffer;
|
|
4936
5824
|
const restore = options.restore ?? false;
|
|
4937
5825
|
const maxHeight = options.maxHeight ?? 8e3;
|
|
5826
|
+
const screenshotWatermarkify = normalizeScreenshotWatermarkify(options.watermarkify ?? true);
|
|
5827
|
+
let cleanupScreenshotWatermarkify = async () => {
|
|
5828
|
+
};
|
|
4938
5829
|
try {
|
|
4939
5830
|
const maxScrollHeight = await page.evaluate(() => {
|
|
4940
5831
|
let maxHeight2 = document.body.scrollHeight;
|
|
@@ -4962,6 +5853,11 @@ var Share = {
|
|
|
4962
5853
|
height: targetHeight
|
|
4963
5854
|
});
|
|
4964
5855
|
await delay2(1e3);
|
|
5856
|
+
if (screenshotWatermarkify.enabled) {
|
|
5857
|
+
const watermarkifyMeta = await resolveScreenshotWatermarkifyMeta(page, screenshotWatermarkify);
|
|
5858
|
+
cleanupScreenshotWatermarkify = await installScreenshotWatermarkify(page, watermarkifyMeta);
|
|
5859
|
+
await delay2(120);
|
|
5860
|
+
}
|
|
4965
5861
|
const buffer_ = await capturePageScreenshot(page, {
|
|
4966
5862
|
fullPage: true,
|
|
4967
5863
|
type: "png",
|
|
@@ -4969,6 +5865,7 @@ var Share = {
|
|
|
4969
5865
|
});
|
|
4970
5866
|
return buffer_.toString("base64");
|
|
4971
5867
|
} finally {
|
|
5868
|
+
await cleanupScreenshotWatermarkify();
|
|
4972
5869
|
if (restore) {
|
|
4973
5870
|
await page.evaluate(() => {
|
|
4974
5871
|
document.querySelectorAll(".__pk_expanded__").forEach((el) => {
|