mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-29 12:22:44 +08:00
浏览器自动化新增设备模拟功能:在浏览器命令中添加设备模拟选项
This commit is contained in:
parent
179c0c567f
commit
f28e53ea53
301
plugin/lib/quickcomposer/browser/device.js
Normal file
301
plugin/lib/quickcomposer/browser/device.js
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
const { initCDP, cleanupCDP } = require("./cdp");
|
||||||
|
const { searchTarget } = require("./tabs");
|
||||||
|
|
||||||
|
// 预定义的设备列表
|
||||||
|
const devices = {
|
||||||
|
// iOS 设备
|
||||||
|
"iPhone X": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1",
|
||||||
|
viewport: {
|
||||||
|
width: 375,
|
||||||
|
height: 812,
|
||||||
|
deviceScaleFactor: 3,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iPhone 12 Pro": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1",
|
||||||
|
viewport: {
|
||||||
|
width: 390,
|
||||||
|
height: 844,
|
||||||
|
deviceScaleFactor: 3,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iPhone 14 Pro Max": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1",
|
||||||
|
viewport: {
|
||||||
|
width: 430,
|
||||||
|
height: 932,
|
||||||
|
deviceScaleFactor: 3,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iPad Pro": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (iPad; CPU OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1",
|
||||||
|
viewport: {
|
||||||
|
width: 1024,
|
||||||
|
height: 1366,
|
||||||
|
deviceScaleFactor: 2,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iPad Mini": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (iPad; CPU OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1",
|
||||||
|
viewport: {
|
||||||
|
width: 768,
|
||||||
|
height: 1024,
|
||||||
|
deviceScaleFactor: 2,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Android 设备
|
||||||
|
"Pixel 5": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36",
|
||||||
|
viewport: {
|
||||||
|
width: 393,
|
||||||
|
height: 851,
|
||||||
|
deviceScaleFactor: 2.75,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Pixel 7": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36",
|
||||||
|
viewport: {
|
||||||
|
width: 412,
|
||||||
|
height: 915,
|
||||||
|
deviceScaleFactor: 2.625,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Samsung Galaxy S20 Ultra": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36",
|
||||||
|
viewport: {
|
||||||
|
width: 412,
|
||||||
|
height: 915,
|
||||||
|
deviceScaleFactor: 3.5,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Samsung Galaxy Tab S7": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Linux; Android 14; SM-X710) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
||||||
|
viewport: {
|
||||||
|
width: 1600,
|
||||||
|
height: 2560,
|
||||||
|
deviceScaleFactor: 2,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Xiaomi 12 Pro": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36",
|
||||||
|
viewport: {
|
||||||
|
width: 390,
|
||||||
|
height: 844,
|
||||||
|
deviceScaleFactor: 3,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"HUAWEI Mate30 Pro": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36",
|
||||||
|
viewport: {
|
||||||
|
width: 392,
|
||||||
|
height: 835,
|
||||||
|
deviceScaleFactor: 3,
|
||||||
|
mobile: true,
|
||||||
|
hasTouch: true,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// 桌面设备
|
||||||
|
Desktop: {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
||||||
|
viewport: {
|
||||||
|
width: 1920,
|
||||||
|
height: 1080,
|
||||||
|
deviceScaleFactor: 1,
|
||||||
|
mobile: false,
|
||||||
|
hasTouch: false,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"MacBook Pro 16": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
||||||
|
viewport: {
|
||||||
|
width: 1728,
|
||||||
|
height: 1117,
|
||||||
|
deviceScaleFactor: 2,
|
||||||
|
mobile: false,
|
||||||
|
hasTouch: false,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"4K Display": {
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
||||||
|
viewport: {
|
||||||
|
width: 3840,
|
||||||
|
height: 2160,
|
||||||
|
deviceScaleFactor: 2,
|
||||||
|
mobile: false,
|
||||||
|
hasTouch: false,
|
||||||
|
isLandscape: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置设备模拟
|
||||||
|
const setDevice = async (tab, deviceName) => {
|
||||||
|
const target = await searchTarget(tab);
|
||||||
|
const { Network, Emulation } = await initCDP(target.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const device = devices[deviceName];
|
||||||
|
if (!device) {
|
||||||
|
throw new Error(`未找到设备配置: ${deviceName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置 User Agent
|
||||||
|
await Network.setUserAgentOverride({
|
||||||
|
userAgent: device.userAgent,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置视口
|
||||||
|
await Emulation.setDeviceMetricsOverride({
|
||||||
|
...device.viewport,
|
||||||
|
screenWidth: device.viewport.width,
|
||||||
|
screenHeight: device.viewport.height,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置触摸事件模拟
|
||||||
|
if (device.viewport.hasTouch) {
|
||||||
|
await Emulation.setTouchEmulationEnabled({
|
||||||
|
enabled: true,
|
||||||
|
maxTouchPoints: 5,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await cleanupCDP(target.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 自定义设备模拟
|
||||||
|
const setCustomDevice = async (tab, options) => {
|
||||||
|
const target = await searchTarget(tab);
|
||||||
|
const { Network, Emulation } = await initCDP(target.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
userAgent,
|
||||||
|
width = 1920,
|
||||||
|
height = 1080,
|
||||||
|
deviceScaleFactor = 1,
|
||||||
|
mobile = false,
|
||||||
|
hasTouch = false,
|
||||||
|
isLandscape = false,
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
// 设置 User Agent
|
||||||
|
if (userAgent) {
|
||||||
|
await Network.setUserAgentOverride({
|
||||||
|
userAgent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置视口
|
||||||
|
await Emulation.setDeviceMetricsOverride({
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
deviceScaleFactor,
|
||||||
|
mobile,
|
||||||
|
isLandscape,
|
||||||
|
screenWidth: width,
|
||||||
|
screenHeight: height,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置触摸事件模拟
|
||||||
|
if (hasTouch) {
|
||||||
|
await Emulation.setTouchEmulationEnabled({
|
||||||
|
enabled: true,
|
||||||
|
maxTouchPoints: 5,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await cleanupCDP(target.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 清除设备模拟
|
||||||
|
const clearDeviceEmulation = async (tab) => {
|
||||||
|
const target = await searchTarget(tab);
|
||||||
|
const { Network, Emulation } = await initCDP(target.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 先禁用触摸事件模拟
|
||||||
|
await Emulation.setTouchEmulationEnabled({
|
||||||
|
enabled: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 清除 User Agent 覆盖
|
||||||
|
await Network.setUserAgentOverride({
|
||||||
|
userAgent: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重置设备指标
|
||||||
|
await Emulation.setDeviceMetricsOverride({
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
deviceScaleFactor: 0,
|
||||||
|
mobile: false,
|
||||||
|
screenWidth: 0,
|
||||||
|
screenHeight: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 清除设备指标覆盖
|
||||||
|
await Emulation.clearDeviceMetricsOverride();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("清除设备模拟失败:", error);
|
||||||
|
} finally {
|
||||||
|
await cleanupCDP(target.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
setDevice,
|
||||||
|
setCustomDevice,
|
||||||
|
clearDeviceEmulation,
|
||||||
|
};
|
@ -5,6 +5,7 @@ const tabs = require("./tabs");
|
|||||||
const url = require("./url");
|
const url = require("./url");
|
||||||
const cookie = require("./cookie");
|
const cookie = require("./cookie");
|
||||||
const screenshot = require("./screenshot");
|
const screenshot = require("./screenshot");
|
||||||
|
const device = require("./device");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...url,
|
...url,
|
||||||
@ -14,4 +15,5 @@ module.exports = {
|
|||||||
...browserManager,
|
...browserManager,
|
||||||
...cookie,
|
...cookie,
|
||||||
...screenshot,
|
...screenshot,
|
||||||
|
...device,
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { newVarInputVal } from "js/composer/varInputValManager";
|
import { newVarInputVal } from "js/composer/varInputValManager";
|
||||||
|
import { deviceName, userAgent } from "js/options/httpOptions";
|
||||||
|
|
||||||
const tabConfig = {
|
const tabConfig = {
|
||||||
component: "OptionEditor",
|
component: "OptionEditor",
|
||||||
@ -6,7 +7,6 @@ const tabConfig = {
|
|||||||
options: {
|
options: {
|
||||||
by: {
|
by: {
|
||||||
component: "QSelect",
|
component: "QSelect",
|
||||||
label: "标签",
|
|
||||||
width: 3,
|
width: 3,
|
||||||
options: [
|
options: [
|
||||||
{ label: "当前标签页", value: "active" },
|
{ label: "当前标签页", value: "active" },
|
||||||
@ -19,7 +19,7 @@ const tabConfig = {
|
|||||||
component: "VariableInput",
|
component: "VariableInput",
|
||||||
icon: "tab",
|
icon: "tab",
|
||||||
width: 9,
|
width: 9,
|
||||||
placeholder: "当前标签页留空,其他支持模糊匹配",
|
placeholder: "选择当前标签页留空,URL/标题/ID支持模糊匹配",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
@ -625,5 +625,101 @@ export const browserCommands = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: "quickcomposer.browser.setDevice",
|
||||||
|
label: "设备模拟",
|
||||||
|
icon: "devices",
|
||||||
|
isAsync: true,
|
||||||
|
config: [tabConfig],
|
||||||
|
subCommands: [
|
||||||
|
{
|
||||||
|
value: "quickcomposer.browser.setDevice",
|
||||||
|
label: "使用预设设备",
|
||||||
|
icon: "smartphone",
|
||||||
|
config: [
|
||||||
|
{
|
||||||
|
label: "设备",
|
||||||
|
component: "QSelect",
|
||||||
|
icon: "devices",
|
||||||
|
width: 12,
|
||||||
|
options: [
|
||||||
|
...deviceName,
|
||||||
|
// 桌面设备
|
||||||
|
{ label: "Desktop", value: "Desktop" },
|
||||||
|
{ label: "MacBook Pro 16", value: "MacBook Pro 16" },
|
||||||
|
{ label: "4K Display", value: "4K Display" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "quickcomposer.browser.setCustomDevice",
|
||||||
|
label: "自定义设备",
|
||||||
|
icon: "build",
|
||||||
|
config: [
|
||||||
|
{
|
||||||
|
label: "设备配置",
|
||||||
|
component: "OptionEditor",
|
||||||
|
icon: "settings",
|
||||||
|
width: 12,
|
||||||
|
options: {
|
||||||
|
width: {
|
||||||
|
label: "宽度",
|
||||||
|
component: "NumberInput",
|
||||||
|
width: 3,
|
||||||
|
defaultValue: 1920,
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
label: "高度",
|
||||||
|
component: "NumberInput",
|
||||||
|
width: 3,
|
||||||
|
defaultValue: 1080,
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
deviceScaleFactor: {
|
||||||
|
label: "设备像素比",
|
||||||
|
component: "NumberInput",
|
||||||
|
width: 3,
|
||||||
|
defaultValue: 1,
|
||||||
|
min: 1,
|
||||||
|
step: 0.1,
|
||||||
|
},
|
||||||
|
mobile: {
|
||||||
|
label: "移动设备",
|
||||||
|
component: "CheckButton",
|
||||||
|
width: 3,
|
||||||
|
},
|
||||||
|
hasTouch: {
|
||||||
|
label: "触摸屏",
|
||||||
|
component: "CheckButton",
|
||||||
|
width: 3,
|
||||||
|
},
|
||||||
|
isLandscape: {
|
||||||
|
label: "横屏",
|
||||||
|
component: "CheckButton",
|
||||||
|
width: 3,
|
||||||
|
},
|
||||||
|
userAgent: {
|
||||||
|
label: "User Agent",
|
||||||
|
component: "VariableInput",
|
||||||
|
icon: "code",
|
||||||
|
width: 6,
|
||||||
|
placeholder: "留空使用默认",
|
||||||
|
options: {
|
||||||
|
items: userAgent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "quickcomposer.browser.clearDeviceEmulation",
|
||||||
|
label: "清除设备模拟",
|
||||||
|
icon: "clear",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -67,15 +67,22 @@ export const commonHeaders = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const deviceName = [
|
export const deviceName = [
|
||||||
{ label: "iPhone 11", value: "iPhone 11" },
|
|
||||||
{ label: "iPhone X", value: "iPhone X" },
|
{ label: "iPhone X", value: "iPhone X" },
|
||||||
{ label: "iPad", value: "iPad" },
|
{ label: "iPhone 12 Pro", value: "iPhone 12 Pro" },
|
||||||
{ label: "iPhone 6/7/8 Plus", value: "iPhone 6/7/8 Plus" },
|
{ label: "iPhone 14 Pro Max", value: "iPhone 14 Pro Max" },
|
||||||
{ label: "iPhone 6/7/8", value: "iPhone 6/7/8" },
|
{ label: "iPad Pro", value: "iPad Pro" },
|
||||||
{ label: "iPhone 5/SE", value: "iPhone 5/SE" },
|
{ label: "iPad Mini", value: "iPad Mini" },
|
||||||
{ label: "HUAWEI Mate10", value: "HUAWEI Mate10" },
|
{ label: "Pixel 5", value: "Pixel 5" },
|
||||||
{ label: "HUAWEI Mate20", value: "HUAWEI Mate20" },
|
{ label: "Pixel 7", value: "Pixel 7" },
|
||||||
{ label: "HUAWEI Mate30", value: "HUAWEI Mate30" },
|
{
|
||||||
|
label: "Samsung Galaxy S20 Ultra",
|
||||||
|
value: "Samsung Galaxy S20 Ultra",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Samsung Galaxy Tab S7",
|
||||||
|
value: "Samsung Galaxy Tab S7",
|
||||||
|
},
|
||||||
|
{ label: "Xiaomi 12 Pro", value: "Xiaomi 12 Pro" },
|
||||||
{ label: "HUAWEI Mate30 Pro", value: "HUAWEI Mate30 Pro" },
|
{ label: "HUAWEI Mate30 Pro", value: "HUAWEI Mate30 Pro" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user