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