diff --git a/src/components/composer/common/CheckGroup.vue b/src/components/composer/common/CheckGroup.vue index db7ca74..0b54327 100644 --- a/src/components/composer/common/CheckGroup.vue +++ b/src/components/composer/common/CheckGroup.vue @@ -18,7 +18,9 @@ { 'check-btn--selected': isSelected(option.value) }, ]" :style="{ - flex: `1 0 ${100 / options.length}%`, + flex: `1 0 calc(${100 / options.length}% - ${ + (4 * (options.length - 1)) / options.length + }px)`, }" @click="toggleOption(option.value)" > @@ -108,7 +110,7 @@ export default defineComponent({ height: auto !important; min-height: 32px; font-size: 12px; - padding: 4px 12px; + padding: 4px 8px; border-radius: 4px !important; transition: all 0.3s; background-color: rgba(0, 0, 0, 0.03); diff --git a/src/components/composer/common/DictEditor.vue b/src/components/composer/common/DictEditor.vue index a0a1909..d271816 100644 --- a/src/components/composer/common/DictEditor.vue +++ b/src/components/composer/common/DictEditor.vue @@ -168,7 +168,10 @@ export default defineComponent({ }, emits: ["update:modelValue"], created() { - if (!this.modelValue || Object.keys(this.modelValue).length === 0) { + if ( + (!this.modelValue || Object.keys(this.modelValue).length === 0) && + !this.options?.disableAdd + ) { this.$emit("update:modelValue", { "": newVarInputVal("str") }); } }, diff --git a/src/components/composer/common/FunctionInput.vue b/src/components/composer/common/FunctionInput.vue new file mode 100644 index 0000000..ba508cb --- /dev/null +++ b/src/components/composer/common/FunctionInput.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/src/components/composer/network/AxiosConfigEditor.vue b/src/components/composer/network/AxiosConfigEditor.vue index a436b3e..ec17074 100644 --- a/src/components/composer/network/AxiosConfigEditor.vue +++ b/src/components/composer/network/AxiosConfigEditor.vue @@ -74,6 +74,7 @@ filled emit-value map-options + options-dense :options="contentTypes" @update:model-value=" updateArgvs('headers.Content-Type', $event) diff --git a/src/components/composer/param/ParamImporter.vue b/src/components/composer/param/ParamImporter.vue index 52a7d0b..7fb6ea8 100644 --- a/src/components/composer/param/ParamImporter.vue +++ b/src/components/composer/param/ParamImporter.vue @@ -23,6 +23,7 @@ import ControlInput from "components/composer/common/ControlInput.vue"; import CheckGroup from "components/composer/common/CheckGroup.vue"; import CheckButton from "components/composer/common/CheckButton.vue"; import TimeInput from "components/composer/common/TimeInput.vue"; +import FunctionInput from "components/composer/common/FunctionInput.vue"; import { QInput, QSelect, QToggle, QCheckbox } from "quasar"; const CodeEditor = defineAsyncComponent(() => import("components/composer/common/CodeEditor.vue") @@ -45,6 +46,7 @@ export default defineComponent({ QCheckbox, TimeInput, CodeEditor, + FunctionInput, }, props: { config: { @@ -85,6 +87,7 @@ export default defineComponent({ if (this.isQuasarSelect) { props.emitValue = true; props.mapOptions = true; + props.optionsDense = true; } return props; diff --git a/src/components/composer/ubrowser/UBrowserBasic.vue b/src/components/composer/ubrowser/UBrowserBasic.vue index c039457..3fb165e 100644 --- a/src/components/composer/ubrowser/UBrowserBasic.vue +++ b/src/components/composer/ubrowser/UBrowserBasic.vue @@ -1,126 +1,161 @@ + + diff --git a/src/components/composer/ubrowser/UBrowserEditor.vue b/src/components/composer/ubrowser/UBrowserEditor.vue index 416a2e0..c2e7544 100644 --- a/src/components/composer/ubrowser/UBrowserEditor.vue +++ b/src/components/composer/ubrowser/UBrowserEditor.vue @@ -1,52 +1,57 @@ diff --git a/src/components/composer/ubrowser/UBrowserOperations.vue b/src/components/composer/ubrowser/UBrowserOperations.vue index 082af2d..37af6a4 100644 --- a/src/components/composer/ubrowser/UBrowserOperations.vue +++ b/src/components/composer/ubrowser/UBrowserOperations.vue @@ -1,179 +1,174 @@ diff --git a/src/components/composer/ubrowser/operations/UBrowserCookieList.vue b/src/components/composer/ubrowser/operations/UBrowserCookieList.vue deleted file mode 100644 index d220864..0000000 --- a/src/components/composer/ubrowser/operations/UBrowserCookieList.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - diff --git a/src/components/composer/ubrowser/operations/UBrowserDeviceName.vue b/src/components/composer/ubrowser/operations/UBrowserDeviceName.vue deleted file mode 100644 index 4c45a43..0000000 --- a/src/components/composer/ubrowser/operations/UBrowserDeviceName.vue +++ /dev/null @@ -1,72 +0,0 @@ - - - diff --git a/src/components/composer/ubrowser/operations/UBrowserFileList.vue b/src/components/composer/ubrowser/operations/UBrowserFileList.vue deleted file mode 100644 index 12e20ea..0000000 --- a/src/components/composer/ubrowser/operations/UBrowserFileList.vue +++ /dev/null @@ -1,79 +0,0 @@ - - - diff --git a/src/components/composer/ubrowser/operations/UBrowserFunctionInput.vue b/src/components/composer/ubrowser/operations/UBrowserFunctionInput.vue deleted file mode 100644 index 7e8d5af..0000000 --- a/src/components/composer/ubrowser/operations/UBrowserFunctionInput.vue +++ /dev/null @@ -1,237 +0,0 @@ - - - - - diff --git a/src/components/composer/ubrowser/operations/UBrowserNamedParamList.vue b/src/components/composer/ubrowser/operations/UBrowserNamedParamList.vue deleted file mode 100644 index f99a4ef..0000000 --- a/src/components/composer/ubrowser/operations/UBrowserNamedParamList.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - diff --git a/src/components/composer/ubrowser/operations/UBrowserOperation.vue b/src/components/composer/ubrowser/operations/UBrowserOperation.vue deleted file mode 100644 index f3a191a..0000000 --- a/src/components/composer/ubrowser/operations/UBrowserOperation.vue +++ /dev/null @@ -1,266 +0,0 @@ - - - - - diff --git a/src/js/composer/commands/browserCommands.js b/src/js/composer/commands/browserCommands.js index ba709af..d4ed53e 100644 --- a/src/js/composer/commands/browserCommands.js +++ b/src/js/composer/commands/browserCommands.js @@ -375,7 +375,8 @@ export const browserCommands = { placeholder: "输入JavaScript代码,使用return返回结果", }, { - topLabel: "要传递的参数", + label: "要传递的参数", + isCollapse: false, component: "DictEditor", icon: "data_array", width: 12, diff --git a/src/js/composer/generateUBrowserCode.js b/src/js/composer/generateUBrowserCode.js index 26a509f..2e7f5f6 100644 --- a/src/js/composer/generateUBrowserCode.js +++ b/src/js/composer/generateUBrowserCode.js @@ -1,361 +1,102 @@ /** * 生成 UBrowser 代码 - * @param {Object} configs UBrowser 配置对象 - * @param {Array} selectedActions 已选择的操作列表 + * @param {Object} argvs UBrowser 配置对象 * @returns {string} 生成的代码 */ +import { stringifyVarInputVal } from "./varInputValManager"; import { stringifyArgv } from "./formatString"; -// 生成 goto 参数字符串 -function generateGotoArgs(goto) { - const args = []; - - // URL - const urlStr = stringifyArgv(goto.url); - args.push(urlStr); - - // Headers - if (goto.headers?.Referer?.value || goto.headers?.userAgent?.value) { - const headers = {}; - if (goto.headers.Referer?.value) { - headers.Referer = goto.headers.Referer; - } - if (goto.headers.userAgent?.value) { - headers.userAgent = goto.headers.userAgent; - } - console.log("Headers:", JSON.stringify(headers, null, 2)); - args.push(stringifyArgv(headers, true)); - } - - // Timeout - if (goto.timeout !== 60000) { - args.push(goto.timeout); - } - - return args.join(", "); -} - -// 生成 run 参数字符串 -function generateRunArgs(run) { - const options = {}; - const defaultValues = { - show: true, - center: true, - alwaysOnTop: false, - fullscreen: false, - fullscreenable: true, - resizable: true, - movable: true, - minimizable: true, - maximizable: true, - enableLargerThanScreen: false, - opacity: 1, - }; - - // 窗口显示控制 - if (run.show !== undefined && run.show !== defaultValues.show) - options.show = run.show; - if (run.center !== undefined && run.center !== defaultValues.center) - options.center = run.center; - if ( - run.alwaysOnTop !== undefined && - run.alwaysOnTop !== defaultValues.alwaysOnTop - ) - options.alwaysOnTop = run.alwaysOnTop; - if ( - run.fullscreen !== undefined && - run.fullscreen !== defaultValues.fullscreen - ) - options.fullscreen = run.fullscreen; - if ( - run.fullscreenable !== undefined && - run.fullscreenable !== defaultValues.fullscreenable - ) - options.fullscreenable = run.fullscreenable; - - // 窗口尺寸和位置 - 只有设置了值才添加 - if (run.width !== undefined && run.width > 0) options.width = run.width; - if (run.height !== undefined && run.height > 0) options.height = run.height; - if (run.x !== undefined && run.x !== 0) options.x = run.x; - if (run.y !== undefined && run.y !== 0) options.y = run.y; - - // 最大最小尺寸 - 只有设置了值才添加 - if (run.minWidth !== undefined && run.minWidth > 0) - options.minWidth = run.minWidth; - if (run.minHeight !== undefined && run.minHeight > 0) - options.minHeight = run.minHeight; - if (run.maxWidth !== undefined && run.maxWidth > 0) - options.maxWidth = run.maxWidth; - if (run.maxHeight !== undefined && run.maxHeight > 0) - options.maxHeight = run.maxHeight; - - // 窗口行为控制 - if (run.resizable !== undefined && run.resizable !== defaultValues.resizable) - options.resizable = run.resizable; - if (run.movable !== undefined && run.movable !== defaultValues.movable) - options.movable = run.movable; - if ( - run.minimizable !== undefined && - run.minimizable !== defaultValues.minimizable - ) - options.minimizable = run.minimizable; - if ( - run.maximizable !== undefined && - run.maximizable !== defaultValues.maximizable - ) - options.maximizable = run.maximizable; - if ( - run.enableLargerThanScreen !== undefined && - run.enableLargerThanScreen !== defaultValues.enableLargerThanScreen - ) - options.enableLargerThanScreen = run.enableLargerThanScreen; - - // 透明度 - 只有不是1时才添加 - if (run.opacity !== undefined && run.opacity !== defaultValues.opacity) - options.opacity = run.opacity; - - // 其他参数 - 只有设置了值才添加 - if (run.headless) options.headless = run.headless; - if (run.devtools) options.devtools = run.devtools; - if (run.timeout && run.timeout !== 60000) options.timeout = run.timeout; - if (run.proxy) options.proxy = run.proxy; - if (run.viewport) options.viewport = run.viewport; - - return Object.keys(options).length ? stringifyArgv(options) : ""; -} - -// 生成操作参数字符串 -function generateActionArgs(action, config) { - console.log( - "Generating args for action:", - action, - "config:", - JSON.stringify(config, null, 2) - ); - if (!config) return ""; - - let result; - switch (action) { - case "wait": - result = generateWaitArgs(config); - break; - case "click": - case "mousedown": - case "mouseup": - case "focus": - result = stringifyArgv(config.selector); - break; - case "css": - case "paste": - result = stringifyArgv(config.value); - break; - case "press": - result = generatePressArgs(config); - break; - case "screenshot": - result = generateScreenshotArgs(config); - break; - case "pdf": - result = generatePdfArgs(config); - break; - case "device": - result = generateDeviceArgs(config); - break; - case "cookies": - case "removeCookies": - result = stringifyArgv(config.name); - break; - case "setCookies": - result = generateSetCookiesArgs(config); - break; - case "evaluate": - result = generateEvaluateArgs(config); - break; - case "when": - result = generateWhenArgs(config); - break; - case "file": - result = generateFileArgs(config); - break; - case "value": - result = generateValueArgs(config); - break; - case "check": - result = generateCheckArgs(config); - break; - case "scroll": - result = generateScrollArgs(config); - break; - case "download": - result = generateDownloadArgs(config); - break; - case "devTools": - result = stringifyArgv(config.mode); - break; - default: - result = ""; - } - console.log( - "Generated args for action:", - action, - "result:", - JSON.stringify(result) - ); - return result; -} - -// 生成 wait 参数字符串 -function generateWaitArgs(config) { - switch (config.type) { - case "selector": - return stringifyArgv(config.selector); - case "function": - return config.function; - case "time": - return config.time; - default: - return ""; - } -} - -// 生成 press 参数字符串 -function generatePressArgs(config) { - const args = [stringifyArgv(config.key)]; - if (config.modifiers?.length) { - args.push(JSON.stringify(config.modifiers)); - } - return args.join(", "); -} - -// 生成 screenshot 参数字符串 -function generateScreenshotArgs(config) { - const args = []; - if (config.rect) { - args.push(stringifyArgv(config.rect)); - } else if (config.selector) { - args.push(stringifyArgv(config.selector)); - } - if (config.savePath) { - args.push(stringifyArgv(config.savePath)); - } - return args.join(", "); -} - -// 生成 pdf 参数字符串 -function generatePdfArgs(config) { - const args = []; - if (config.savePath) { - args.push(stringifyArgv(config.savePath)); - } - if (config.options) { - args.push(stringifyArgv(config.options)); - } - return args.join(", "); -} - -// 生成 device 参数字符串 -function generateDeviceArgs(config) { - if (config.type === "preset") { - return stringifyArgv(config.deviceName); - } else { - const options = {}; - if (config.size) options.size = config.size; - if (config.useragent) options.userAgent = config.useragent; - return stringifyArgv(options); - } -} - -// 生成 setCookies 参数字符串 -function generateSetCookiesArgs(config) { - if (!config.items?.length) return "[]"; - return stringifyArgv(config.items); -} - -// 生成 evaluate 参数字符串 -function generateEvaluateArgs(config) { - const args = [config.function]; - if (config.args?.length) { - args.push(...config.args.map(stringifyArgv)); - } - return args.join(", "); -} - -// 生成 when 参数字符串 -function generateWhenArgs(config) { - if (config.type === "function") { - return config.function; - } else { - return stringifyArgv(config.selector); - } -} - -// 生成 file 参数字符串 -function generateFileArgs(config) { - const args = [stringifyArgv(config.selector)]; - if (config.files) { - args.push(stringifyArgv(config.files)); - } - return args.join(", "); -} - -// 生成 value 参数字符串 -function generateValueArgs(config) { - return `${stringifyArgv(config.selector)}, ${stringifyArgv( - config.value - )}`; -} - -// 生成 check 参数字符串 -function generateCheckArgs(config) { - return `${stringifyArgv(config.selector)}, ${config.checked}`; -} - -// 生成 scroll 参数字符串 -function generateScrollArgs(config) { - if (config.type === "element") { - return stringifyArgv(config.selector); - } else { - if (config.x !== undefined) { - return `${config.x}, ${config.y}`; - } else { - return String(config.y); - } - } -} - -// 生成 download 参数字符串 -function generateDownloadArgs(config) { - const args = [stringifyArgv(config.url)]; - if (config.savePath) { - args.push(stringifyArgv(config.savePath)); - } - return args.join(", "); -} +// ubrowser 默认运行配置 +const defaultRunConfigs = { + show: true, + width: 800, + height: 600, + center: true, + minWidth: 0, + minHeight: 0, + resizable: true, + movable: true, + minimizable: true, + maximizable: true, + alwaysOnTop: false, + fullscreen: false, + fullscreenable: true, + enableLargerThanScreen: false, + opacity: 1, +}; // 生成完整的 ubrowser 代码 -export function generateUBrowserCode(configs, selectedActions) { - const lines = []; - const indent = " "; +export function generateUBrowserCode(argvs) { + const lines = ["utools.ubrowser"]; - // 添加 goto 参数 - if (configs.goto) { - const gotoArgs = generateGotoArgs(configs.goto); - lines.push(`${indent}goto(${gotoArgs}),`); + // 首先添加 goto 操作 + if (argvs.goto) { + const args = []; + // url + if (argvs.goto.url) { + args.push(stringifyVarInputVal(argvs.goto.url)); + } + + // headers + const headers = {}; + // 处理标准headers + Object.entries(argvs.goto.headers || {}).forEach(([key, value]) => { + if (value?.value) { + headers[key] = value.value; + } + }); + // 处理其他headers + Object.entries(argvs.goto.otherHeaders || {}).forEach(([key, value]) => { + if (value?.value) { + headers[key] = value.value; + } + }); + + if (Object.keys(headers).length > 0) { + args.push(stringifyArgv(headers)); + } + + // timeout + if (argvs.goto.timeout) { + if (args.length === 1) { + args.push("undefined"); + } + args.push(argvs.goto.timeout); + } + + lines[0] += `.goto(${args.join(", ")})`; } - // 添加选中的操作 - if (selectedActions?.length) { - selectedActions.forEach((action) => { - const args = generateActionArgs(action.value, configs[action.value]); - lines.push(`${indent}${action.value}(${args}),`); + // 添加其他操作 + if (argvs.operations?.length) { + argvs.operations.forEach(({ value, args }) => { + if (!args?.length) return; + + const stringifiedArgs = args + .map((arg) => stringifyArgv(arg)) + .filter(Boolean); + + lines.push(` .${value}(${stringifiedArgs.join(", ")})`); }); } - // 添加 run 参数 - const runArgs = generateRunArgs(configs.run || {}); - const runLine = runArgs ? `${indent}run(${runArgs})` : `${indent}run()`; - lines.push(runLine); + // 最后添加 run 配置(只包含非默认值) + if (argvs.run) { + const runOptions = {}; + Object.entries(argvs.run).forEach(([key, value]) => { + if (value !== defaultRunConfigs[key]) { + runOptions[key] = value; + } + }); - // 生成最终代码 - return `utools.ubrowser\n${lines.join("\n")}`; + if (Object.keys(runOptions).length > 0) { + lines.push( + ` .run(${JSON.stringify(runOptions, null, 2).replace(/\n/g, "\n ")})` + ); + } else { + lines.push(" .run()"); + } + } + + return lines.join("\n"); } diff --git a/src/js/composer/ubrowserConfig.js b/src/js/composer/ubrowserConfig.js index 2840dc3..b0d1ed8 100644 --- a/src/js/composer/ubrowserConfig.js +++ b/src/js/composer/ubrowserConfig.js @@ -1,549 +1,591 @@ -import { newVarInputVal } from "js/composer/varInputValManager"; +import { deviceName, userAgent } from "js/options/httpOptions"; // ubrowser 浏览器操作配置 -export const ubrowserOperationConfigs = [ - { +export const ubrowserOperationConfigs = { + waitTime: { value: "wait", - label: "等待", + label: "等待时间", + icon: "timer", config: [ { - key: "type", - label: "等待类型", - type: "button-toggle", - options: [ - { label: "等待时间", value: "time" }, - { label: "等待元素", value: "selector" }, - { label: "等待条件", value: "function" }, - ], - defaultValue: "time", - }, - { - key: "time", label: "等待时间(ms)", icon: "timer", component: "NumberInput", + min: 0, + step: 100, width: 12, - showWhen: "type", - showValue: "time", }, + ], + }, + waitElement: { + value: "wait", + label: "等待元素", + icon: "find_in_page", + config: [ { - key: "selector", label: "等待元素的CSS选择器", icon: "find_in_page", component: "VariableInput", width: 12, - showWhen: "type", - showValue: "selector", }, + ], + }, + waitCondition: { + value: "wait", + label: "等待条件", + icon: "code", + config: [ { - key: "function", - label: "等待条件(返回 true 时结束等待)", + label: "等待条件", icon: "code", - type: "function-with-params", + component: "FunctionInput", + placeholder: "返回true时结束等待", width: 12, - showWhen: "type", - showValue: "function", }, { - key: "timeout", label: "超时时间(ms)", icon: "timer_off", component: "NumberInput", width: 12, defaultValue: 60000, - showWhen: "type", - showValue: ["selector", "function"], + }, + { + topLabel: "传递给函数的参数值", + component: "ArrayEditor", }, ], - icon: "timer", }, - { + click: { value: "click", label: "点击", + icon: "mouse", config: [ { - key: "selector", label: "点击元素的CSS选择器", icon: "mouse", component: "VariableInput", + width: 12, }, ], - icon: "mouse", }, - { + css: { value: "css", label: "注入CSS", + icon: "style", config: [ { - key: "value", label: "注入的CSS样式", icon: "style", component: "VariableInput", + width: 12, }, ], - icon: "style", }, - { + press: { value: "press", label: "按键", + icon: "keyboard", config: [ { - key: "key", label: "按键", icon: "keyboard", component: "VariableInput", - width: 5, + width: 4, }, { - key: "modifiers", - label: "修饰键", - type: "checkbox-group", + component: "CheckGroup", options: [ { label: "Ctrl", value: "ctrl" }, { label: "Shift", value: "shift" }, { label: "Alt", value: "alt" }, { label: "Meta", value: "meta" }, ], - defaultValue: [], - width: 7, + width: 8, }, ], - icon: "keyboard", }, - { + paste: { value: "paste", label: "粘贴", + icon: "content_paste", config: [ { - key: "text", label: "粘贴内容", icon: "content_paste", component: "VariableInput", + width: 12, }, ], - icon: "content_paste", }, - { + viewport: { value: "viewport", label: "视窗", + icon: "crop", config: [ { - key: "width", label: "视窗宽度", - icon: "width", + icon: "swap_horiz", component: "NumberInput", + min: 0, + step: 100, width: 6, }, { - key: "height", label: "视窗高度", icon: "height", component: "NumberInput", + min: 0, + step: 100, width: 6, }, ], - icon: "crop", }, - { + screenshotElement: { value: "screenshot", - label: "截图", + label: "元素截图", + icon: "picture_as_pdf", config: [ { - key: "selector", label: "元素选择器", icon: "crop", component: "VariableInput", + width: 12, }, { - key: "rect.x", - label: "X坐标", - icon: "drag_handle", - component: "NumberInput", - width: 3, - }, - { - key: "rect.y", - label: "Y坐标", - icon: "drag_handle", - component: "NumberInput", - width: 3, - }, - { - key: "rect.width", - label: "宽度", - icon: "width", - component: "NumberInput", - width: 3, - }, - { - key: "rect.height", - label: "高度", - icon: "height", - component: "NumberInput", - width: 3, - }, - { - key: "savePath", label: "保存路径", icon: "save", component: "VariableInput", + options: { + dialog: { + type: "save", + options: { + defaultPath: "screenshot.png", + }, + }, + }, + width: 12, }, ], - icon: "picture_as_pdf", }, - { + screenshotPosition: { + value: "screenshot", + label: "区域截图", + icon: "crop", + config: [ + { + component: "OptionEditor", + options: { + x: { + label: "X坐标", + icon: "drag_handle", + component: "NumberInput", + min: 0, + step: 100, + width: 3, + }, + y: { + label: "Y坐标", + icon: "drag_handle", + component: "NumberInput", + min: 0, + step: 100, + width: 3, + }, + width: { + label: "宽度", + icon: "swap_horiz", + component: "NumberInput", + min: 0, + step: 100, + width: 3, + }, + height: { + label: "高度", + icon: "height", + component: "NumberInput", + min: 0, + step: 100, + width: 3, + }, + }, + }, + { + label: "保存路径", + icon: "save", + options: { + dialog: { + type: "save", + options: { + defaultPath: "screenshot.png", + }, + }, + }, + width: 12, + }, + ], + }, + pdf: { value: "pdf", label: "导出PDF", + icon: "picture_as_pdf", config: [ { - key: "options.marginsType", - label: "边距类型", - component: "q-select", - options: [ - { label: "默认边距", value: 0 }, - { label: "无边距", value: 1 }, - { label: "最小边距", value: 2 }, - ], - width: 6, + component: "OptionEditor", + options: { + format: { + label: "格式", + component: "QSelect", + options: [ + "A0", + "A1", + "A2", + "A3", + "A4", + "A5", + "A6", + "Legal", + "Letter", + "Tabloid", + "Ledger", + ], + width: 3, + }, + landscape: { + label: "横向打印", + component: "CheckButton", + width: 3, + }, + pageRanges: { + label: "页码范围", + component: "VariableInput", + placeholder: "1-5, 8", + width: 3, + }, + scale: { + label: "缩放", + component: "NumberInput", + min: 0, + step: 0.1, + width: 3, + }, + }, + defaultValue: { + format: "A4", + landscape: false, + pageRanges: "", + scale: 1, + }, }, { - key: "options.pageSize", - label: "页面大小", - component: "q-select", - options: ["A3", "A4", "A5", "Legal", "Letter", "Tabloid"], - width: 6, - }, - { - key: "savePath", label: "保存路径", icon: "save", component: "VariableInput", + width: 12, }, ], - icon: "devices", }, - { + device: { value: "device", label: "模拟设备", + icon: "phone_iphone", config: [ { - key: "type", - label: "设备类型", - type: "button-toggle", - options: [ - { label: "特定设备", value: "preset" }, - { label: "自定义设备", value: "custom" }, - ], - defaultValue: "preset", - }, - { - key: "deviceName", - label: "设备名称", - icon: "smartphone", - component: "VariableInput", - width: 12, - showWhen: "type", - showValue: "preset", - }, - { - key: "size", - label: "设备尺寸", - type: "device-size", - width: 12, - showWhen: "type", - showValue: "custom", - }, - { - key: "useragent", - label: "User-Agent", - icon: "devices", - component: "VariableInput", - width: 12, - showWhen: "type", - showValue: "custom", + component: "OptionEditor", + options: { + size: { + component: "DictEditor", + options: { + fixedKeys: ["width", "height"], + disableAdd: true, + }, + }, + userAgent: { + label: "User-Agent", + component: "VariableInput", + options: { + items: userAgent, + }, + }, + }, }, ], - icon: "phone_iphone", }, - { + cookies: { value: "cookies", label: "获取Cookie", + icon: "cookie", config: [ { - key: "name", label: "Cookie名称", icon: "cookie", component: "VariableInput", width: 12, }, ], - icon: "cookie", }, - { + setCookies: { value: "setCookies", label: "设置Cookie", - config: [{ key: "items", label: "Cookie列表", type: "cookie-list" }], icon: "cookie", - }, - { - value: "removeCookies", - label: "删除Cookie", config: [ { - key: "name", + label: "Cookie列表", + component: "ArrayEditor", + columns: { + name: { + label: "名称", + }, + value: { + label: "值", + }, + }, + }, + ], + }, + removeCookies: { + value: "removeCookies", + label: "删除Cookie", + icon: "cookie", + config: [ + { label: "Cookie名称", icon: "cookie", component: "VariableInput", + width: 12, }, ], - icon: "cookie", }, - { + clearCookies: { value: "clearCookies", label: "清空Cookie", + icon: "cookie", config: [ { - key: "url", label: "URL(可选)", icon: "link", component: "VariableInput", - }, - ], - icon: "cookie", - }, - { - value: "evaluate", - label: "执行代码", - config: [ - { - key: "function", - label: "执行的代码", - icon: "code", - type: "function-with-params", width: 12, }, ], - icon: "code", }, - { - value: "when", - label: "条件判断", + evaluate: { + value: "evaluate", + label: "执行代码", + icon: "code", config: [ { - key: "type", - label: "条件类型", - type: "button-toggle", - options: [ - { label: "等待元素", value: "selector" }, - { label: "等待条件", value: "function" }, - ], - defaultValue: "selector", + label: "执行的代码", + icon: "code", + component: "FunctionInput", + width: 12, }, { - key: "selector", - label: "等待元素的CSS选择器", + topLabel: "传递给函数的参数值", + component: "ArrayEditor", + }, + ], + }, + whenElement: { + value: "when", + label: "判断元素", + icon: "rule", + config: [ + { + label: "判断元素的CSS选择器", icon: "find_in_page", component: "VariableInput", width: 12, - showWhen: "type", - showValue: "selector", - }, - { - key: "function", - label: "等待条件(返回 true 时结束等待)", - icon: "code", - type: "function-with-params", - width: 12, - showWhen: "type", - showValue: "function", - }, - { - key: "timeout", - label: "超时时间(ms)", - icon: "timer_off", - component: "NumberInput", - width: 12, - defaultValue: 60000, - showWhen: "type", - showValue: ["selector", "function"], }, ], + }, + whenCondition: { + value: "when", + label: "判断条件", icon: "rule", - }, - { - value: "end", - label: "结束条件", - config: [], - icon: "stop", - }, - { - value: "mousedown", - label: "按下鼠标", config: [ { - key: "selector", + label: "判断条件", + icon: "code", + component: "FunctionInput", + width: 12, + placeholder: "返回true时结束判断", + }, + { + topLabel: "传递给函数的参数值", + component: "ArrayEditor", + }, + ], + }, + end: { + value: "end", + label: "结束判断", + icon: "stop", + config: [], + }, + mousedown: { + value: "mousedown", + label: "按下鼠标", + icon: "mouse", + config: [ + { label: "按下元素选择器", icon: "mouse", component: "VariableInput", + width: 12, }, ], - icon: "mouse", }, - { + mouseup: { value: "mouseup", label: "释放鼠标", + icon: "mouse", config: [ { - key: "selector", label: "释放元素选择器", icon: "mouse", component: "VariableInput", + width: 12, }, ], - icon: "mouse", }, - { + file: { value: "file", label: "上传文件", + icon: "upload_file", config: [ { - key: "selector", label: "文件输入框选择器", icon: "upload_file", component: "VariableInput", + placeholder: "必须是可选择文件的输入元素 input[type=file]", + width: 12, + }, + { + label: "文件列表", + component: "VariableInput", + icon: "image", + width: 12, + options: { + dialog: { + type: "open", + options: { + title: "选择文件", + properties: ["openFile", "multiSelections"], + }, + }, + }, }, - { key: "files", label: "文件列表", type: "file-list", width: 12 }, ], - icon: "upload_file", }, - { - value: "value", + setValue: { + value: "setValue", label: "设置值", + icon: "check_box", config: [ { - key: "selector", label: "元素选择器", icon: "varInput", component: "VariableInput", width: 6, }, { - key: "value", label: "设置的值", icon: "edit", component: "VariableInput", width: 6, }, ], - icon: "check_box", }, - { + check: { value: "check", label: "设置选中", + icon: "center_focus_strong", config: [ { - key: "selector", label: "复选框/选框选择器", icon: "check_box", component: "VariableInput", width: 8, }, { - key: "checked", label: "选中状态", - type: "boolean-toggle", + component: "CheckButton", defaultValue: false, width: 4, }, ], - icon: "center_focus_strong", }, - { + focus: { value: "focus", label: "聚焦元素", + icon: "swap_vert", config: [ { - key: "selector", label: "元素选择器", icon: "center_focus_strong", component: "VariableInput", + width: 12, }, ], - icon: "swap_vert", }, - { + scrollToElement: { value: "scroll", - label: "滚动", + label: "滚动到元素", + icon: "download", config: [ { - key: "type", - label: "滚动类型", - type: "button-toggle", - options: [ - { label: "滚动到元素", value: "element" }, - { label: "滚动到坐标", value: "position" }, - ], - defaultValue: "element", - }, - { - key: "selector", label: "目标元素选择器", icon: "swap_vert", component: "VariableInput", width: 12, - showWhen: "type", - showValue: "element", }, + ], + }, + scrollToPosition: { + value: "scroll", + label: "滚动到坐标", + icon: "download", + config: [ { - key: "x", label: "X坐标", icon: "drag_handle", component: "NumberInput", width: 6, - showWhen: "type", - showValue: "position", }, { - key: "y", label: "Y坐标", icon: "drag_handle", component: "NumberInput", width: 6, - showWhen: "type", - showValue: "position", }, ], - icon: "download", }, - { + download: { value: "download", label: "下载", + icon: "download", config: [ { - key: "url", label: "下载URL", icon: "link", component: "VariableInput", width: 6, }, { - key: "savePath", label: "保存路径", icon: "save", component: "VariableInput", width: 6, }, ], - icon: "download", }, - { + devTools: { value: "devTools", label: "开发工具", + icon: "developer_board", config: [ { - key: "mode", - label: "开发工具位置", - type: "button-toggle", + component: "ButtonGroup", options: [ { label: "右侧", value: "right" }, { label: "底部", value: "bottom" }, @@ -551,142 +593,20 @@ export const ubrowserOperationConfigs = [ { label: "分离", value: "detach" }, ], defaultValue: "right", + width: 12, }, ], - icon: "developer_board", }, - { + hide: { value: "hide", label: "隐藏", - config: [], icon: "visibility_off", + config: [], }, - { + show: { value: "show", label: "显示", - config: [], icon: "visibility", + config: [], }, -]; - -// 添加默认运行配置 -const defaultUBrowserRunConfigs = { - show: true, - width: 1280, - height: 800, - center: true, - minWidth: 800, - minHeight: 600, - resizable: true, - movable: true, - minimizable: true, - maximizable: true, - alwaysOnTop: false, - fullscreen: false, - fullscreenable: true, - enableLargerThanScreen: false, - opacity: 1, -}; - -// ubrowser 默认配置 基础参数-浏览器操作-运行参数 -export const defaultUBrowserConfigs = { - // 基础参数 - goto: { - url: newVarInputVal("str"), - headers: { - Referer: newVarInputVal("str"), - userAgent: newVarInputVal("str"), - }, - timeout: 60000, - }, - // 浏览器操作 - wait: { - value: "", - timeout: 60000, - }, - click: { - selector: newVarInputVal("str"), - }, - css: { - value: newVarInputVal("str"), - }, - press: { - key: newVarInputVal("str"), - modifiers: [], - }, - paste: { - text: newVarInputVal("str"), - }, - screenshot: { - selector: newVarInputVal("str"), - rect: { x: 0, y: 0, width: 0, height: 0 }, - savePath: newVarInputVal("str"), - }, - pdf: { - options: { - marginsType: 0, - pageSize: "A4", - }, - savePath: newVarInputVal("str"), - }, - device: { - size: { width: 1280, height: 800 }, - useragent: newVarInputVal("str"), - }, - cookies: { - name: newVarInputVal("str"), - }, - setCookies: { - items: [ - { - name: newVarInputVal("str"), - value: newVarInputVal("str"), - }, - ], - }, - removeCookies: { - name: newVarInputVal("str"), - }, - clearCookies: { - url: newVarInputVal("str"), - }, - evaluate: { - function: "", - params: [], - }, - when: { - condition: newVarInputVal("var"), - }, - mousedown: { - selector: newVarInputVal("str"), - }, - mouseup: { - selector: newVarInputVal("str"), - }, - file: { - selector: newVarInputVal("str"), - files: [], - }, - value: { - selector: newVarInputVal("str"), - value: newVarInputVal("str"), - }, - check: { - selector: newVarInputVal("str"), - checked: false, - }, - focus: { - selector: newVarInputVal("str"), - }, - scroll: { - target: newVarInputVal("str"), - x: 0, - y: 0, - }, - download: { - url: newVarInputVal("str"), - savePath: newVarInputVal("str"), - }, - // 运行参数 - run: defaultUBrowserRunConfigs, };