diff --git a/src/components/CommandEditor.vue b/src/components/CommandEditor.vue
index 97170ca..6466f7d 100644
--- a/src/components/CommandEditor.vue
+++ b/src/components/CommandEditor.vue
@@ -195,6 +195,11 @@ export default {
},
insertText(text) {
this.$refs.editor.repacleEditorSelection(text);
+ this.$refs.editor.formatDocument();
+ },
+ replaceText(text) {
+ this.$refs.editor.setEditorValue(text);
+ this.$refs.editor.formatDocument();
},
handleComposer({ type, code }) {
switch (type) {
@@ -203,7 +208,7 @@ export default {
case "insert":
return this.insertText(code);
case "apply":
- return this.$refs.editor.setEditorValue(code);
+ return this.replaceText(code);
}
},
// 保存
diff --git a/src/components/editor/CommandLanguageBar.vue b/src/components/editor/CommandLanguageBar.vue
index 877ef34..3ea3972 100644
--- a/src/components/editor/CommandLanguageBar.vue
+++ b/src/components/editor/CommandLanguageBar.vue
@@ -221,10 +221,10 @@ export default {
"program-changed",
"run",
"save",
- "show-recorder",
- "show-actions",
+ // "show-recorder",
+ // "show-actions",
"show-help",
- "add-action",
+ "use-composer",
],
computed: {
programLanguages() {
diff --git a/src/components/editor/MonacoEditor.vue b/src/components/editor/MonacoEditor.vue
index c203a3a..eb46449 100644
--- a/src/components/editor/MonacoEditor.vue
+++ b/src/components/editor/MonacoEditor.vue
@@ -66,6 +66,16 @@ export default {
minimap: {
enabled: false,
},
+ formatOnType: true,
+ formatOnPaste: true,
+ autoIndent: "full",
+ // JavaScript 特定的格式化选项
+ "javascript.format.insertSpaceAfterSemicolonInForStatements": true,
+ "javascript.format.insertSpaceBeforeAndAfterBinaryOperators": true,
+ "javascript.format.insertSpaceAfterConstructor": true,
+ "javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": true,
+ "javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": true,
+ "javascript.format.insertSpaceAfterKeywordsInControlFlowStatements": true,
};
this.editor = monaco.editor.create(
document.getElementById("monacoEditor"),
@@ -212,6 +222,9 @@ export default {
};
this.rawEditor().executeEdits("my-source", [op]);
},
+ formatDocument() {
+ this.rawEditor().getAction("editor.action.formatDocument").run();
+ },
listenEditorValue() {
this.rawEditor().focus();
this.rawEditor().onDidChangeModelContent(() => {
diff --git a/src/components/editor/composer/CommandComposer.vue b/src/components/editor/composer/CommandComposer.vue
index 8f17cb5..b7048a6 100644
--- a/src/components/editor/composer/CommandComposer.vue
+++ b/src/components/editor/composer/CommandComposer.vue
@@ -61,6 +61,7 @@ export default defineComponent({
availableCommands,
};
},
+ emits: ["use-composer", "update:modelValue"],
methods: {
addCommand(action) {
this.commandFlow.push({
@@ -84,8 +85,9 @@ export default defineComponent({
outputVars.set(index, varName);
line += `let ${varName} = `;
}
-
- if (cmd.useOutput !== null) {
+ if (cmd.value === "ubrowser") {
+ line += cmd.argv;
+ } else if (cmd.useOutput !== null) {
const inputVar = outputVars.get(cmd.useOutput);
line += `${cmd.value}(${inputVar})`;
} else {
diff --git a/src/components/editor/composer/composerConfig.js b/src/components/editor/composer/composerConfig.js
index e89eda6..646b161 100644
--- a/src/components/editor/composer/composerConfig.js
+++ b/src/components/editor/composer/composerConfig.js
@@ -1,3 +1,9 @@
+export {
+ ubrowserActionIcons,
+ ubrowserOperationConfigs,
+ defaultUBrowserConfigs,
+} from "./ubrowser/ubrowserConfig";
+
// 定义命令图标映射
export const commandIcons = {
open: "folder_open",
@@ -137,58 +143,3 @@ export const commandsAcceptOutput = {
send: true,
copyTo: true,
};
-
-// 添加 ubrowser 操作图标映射
-export const ubrowserActionIcons = {
- wait: "timer",
- click: "mouse",
- css: "style",
- press: "keyboard",
- paste: "content_paste",
- screenshot: "photo_camera",
- pdf: "picture_as_pdf",
- device: "devices",
- cookies: "cookie",
- evaluate: "code",
- when: "rule",
- mousedown: "mouse",
- mouseup: "mouse",
- file: "upload_file",
- value: "edit",
- check: "check_box",
- focus: "center_focus_strong",
- scroll: "swap_vert",
- download: "download",
- hide: "visibility_off",
- show: "visibility",
- devTools: "developer_board",
-};
-
-// 添加 ubrowser 可用操作列表
-export const ubrowserAvailableActions = [
- { label: "等待", value: "wait" },
- { label: "点击", value: "click" },
- { label: "注入CSS", value: "css" },
- { label: "按键", value: "press" },
- { label: "粘贴", value: "paste" },
- { label: "截图", value: "screenshot" },
- { label: "导出PDF", value: "pdf" },
- { label: "模拟设备", value: "device" },
- { label: "获取Cookie", value: "cookies" },
- { label: "设置Cookie", value: "setCookies" },
- { label: "删除Cookie", value: "removeCookies" },
- { label: "清除Cookie", value: "clearCookies" },
- { label: "执行脚本", value: "evaluate" },
- { label: "条件判断", value: "when" },
- { label: "鼠标按下", value: "mousedown" },
- { label: "鼠标释放", value: "mouseup" },
- { label: "上传文件", value: "file" },
- { label: "设置值", value: "value" },
- { label: "选中状态", value: "check" },
- { label: "获取焦点", value: "focus" },
- { label: "滚动", value: "scroll" },
- { label: "下载", value: "download" },
- { label: "隐藏", value: "hide" },
- { label: "显示", value: "show" },
- { label: "开发工具", value: "devTools" },
-];
diff --git a/src/components/editor/composer/ubrowser/UBrowserBasic.vue b/src/components/editor/composer/ubrowser/UBrowserBasic.vue
index 86f9168..c221db2 100644
--- a/src/components/editor/composer/ubrowser/UBrowserBasic.vue
+++ b/src/components/editor/composer/ubrowser/UBrowserBasic.vue
@@ -15,22 +15,6 @@
-
-
-
-
-
-
-
-
-
@@ -48,20 +32,57 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -76,10 +97,14 @@ export default defineComponent({
required: true,
},
},
- emits: ["update:configs"],
data() {
return {
+ selectedUA: null,
localConfigs: {
+ useragent: {
+ preset: null,
+ value: "",
+ },
goto: {
url: "",
headers: {
@@ -89,27 +114,83 @@ export default defineComponent({
timeout: 60000,
},
},
+ userAgentOptions: [
+ {
+ label: "Chrome (Windows)",
+ value:
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
+ },
+ {
+ label: "Chrome (macOS)",
+ value:
+ "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",
+ },
+ {
+ label: "Chrome (Linux)",
+ value:
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
+ },
+ {
+ label: "IE 11",
+ value:
+ "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
+ },
+ {
+ label: "微信 (Android)",
+ value:
+ "Mozilla/5.0 (Linux; Android 14; Pixel 8 Build/UQ1A.240205.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/122.0.6261.64 Mobile Safari/537.36 XWEB/1160027 MMWEBSDK/20231202 MMWEBID/2308 MicroMessenger/8.0.47.2560(0x28002F35) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64",
+ },
+ {
+ label: "微信 (iOS)",
+ value:
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.47(0x18002f2c) NetType/WIFI Language/zh_CN",
+ },
+ {
+ label: "iPhone",
+ value:
+ "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",
+ },
+ {
+ label: "iPad",
+ value:
+ "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",
+ },
+ {
+ label: "Android Phone",
+ value:
+ "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36",
+ },
+ {
+ label: "Android Tablet",
+ value:
+ "Mozilla/5.0 (Linux; Android 14; SM-X710) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
+ },
+ ],
};
},
created() {
// 初始化本地配置
- this.localConfigs = JSON.parse(JSON.stringify(this.configs));
+ this.localConfigs = _.cloneDeep(this.configs);
},
methods: {
updateConfigs() {
- this.$emit(
- "update:configs",
- JSON.parse(JSON.stringify(this.localConfigs))
- );
+ this.$emit("update:configs", _.cloneDeep(this.localConfigs));
},
},
watch: {
configs: {
deep: true,
handler(newConfigs) {
- this.localConfigs = JSON.parse(JSON.stringify(newConfigs));
+ this.localConfigs = _.cloneDeep(newConfigs);
},
},
+ selectedUA(value) {
+ if (value) {
+ this.localConfigs.goto.headers.userAgent = value;
+ this.updateConfigs();
+ this.selectedUA = null;
+ }
+ },
},
});
diff --git a/src/components/editor/composer/ubrowser/UBrowserEditor.vue b/src/components/editor/composer/ubrowser/UBrowserEditor.vue
index a1fae37..846330e 100644
--- a/src/components/editor/composer/ubrowser/UBrowserEditor.vue
+++ b/src/components/editor/composer/ubrowser/UBrowserEditor.vue
@@ -66,6 +66,8 @@ import { defineComponent } from "vue";
import UBrowserBasic from "./UBrowserBasic.vue";
import UBrowserOperations from "./UBrowserOperations.vue";
import UBrowserRun from "./UBrowserRun.vue";
+import { defaultUBrowserConfigs } from "./ubrowserConfig";
+import { generateUBrowserCode } from "./generateUBrowserCode";
export default defineComponent({
name: "UBrowserEditor",
@@ -85,142 +87,7 @@ export default defineComponent({
return {
step: 1,
selectedActions: [],
- configs: {
- // 基础参数
- useragent: {
- value: "",
- },
- goto: {
- url: "",
- headers: {
- Referer: "",
- userAgent: "",
- },
- timeout: 60000,
- },
- // 浏览器操作
- wait: {
- value: "",
- timeout: 60000,
- },
- click: {
- selector: "",
- },
- css: {
- value: "",
- },
- press: {
- key: "",
- modifiers: [],
- },
- paste: {
- text: "",
- },
- screenshot: {
- selector: "",
- rect: { x: 0, y: 0, width: 0, height: 0 },
- savePath: "",
- },
- pdf: {
- options: {
- marginsType: 0,
- pageSize: "A4",
- },
- savePath: "",
- },
- device: {
- size: { width: 1280, height: 800 },
- useragent: "",
- },
- cookies: {
- name: "",
- },
- setCookies: {
- items: [{ name: "", value: "" }],
- },
- removeCookies: {
- name: "",
- },
- clearCookies: {
- url: "",
- },
- evaluate: {
- function: "",
- params: [],
- },
- when: {
- condition: "",
- },
- mousedown: {
- selector: "",
- },
- mouseup: {
- selector: "",
- },
- file: {
- selector: "",
- files: [],
- },
- value: {
- selector: "",
- value: "",
- },
- check: {
- selector: "",
- checked: false,
- },
- focus: {
- selector: "",
- },
- scroll: {
- target: "",
- x: 0,
- y: 0,
- },
- download: {
- url: "",
- savePath: "",
- },
- // 运行参数
- run: {
- show: true,
- width: 1280,
- height: 800,
- x: undefined,
- y: undefined,
- center: true,
- minWidth: 800,
- minHeight: 600,
- maxWidth: undefined,
- maxHeight: undefined,
- resizable: true,
- movable: true,
- minimizable: true,
- maximizable: true,
- alwaysOnTop: false,
- fullscreen: false,
- fullscreenable: true,
- enableLargerThanScreen: false,
- opacity: 1,
- },
- },
- defaultRunConfigs: {
- 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,
- },
+ configs: _.cloneDeep(defaultUBrowserConfigs),
};
},
methods: {
@@ -235,249 +102,31 @@ export default defineComponent({
this.selectedActions.splice(index, 1);
}
},
- generateCode() {
- let code = "utools.ubrowser";
-
- // 基础参数
- if (this.configs.useragent.value) {
- code += `.useragent('${this.configs.useragent.value}')`;
- }
-
- if (this.configs.goto.url) {
- const gotoOptions = {};
- if (this.configs.goto.headers.Referer) {
- gotoOptions.headers = gotoOptions.headers || {};
- gotoOptions.headers.Referer = this.configs.goto.headers.Referer;
- }
- if (this.configs.goto.headers.userAgent) {
- gotoOptions.headers = gotoOptions.headers || {};
- gotoOptions.headers["User-Agent"] =
- this.configs.goto.headers.userAgent;
- }
- if (this.configs.goto.timeout !== 60000) {
- gotoOptions.timeout = this.configs.goto.timeout;
- }
-
- code += `.goto('${this.configs.goto.url}'${
- Object.keys(gotoOptions).length
- ? `, ${JSON.stringify(gotoOptions)}`
- : ""
- })`;
- }
-
- // 浏览器操作
- this.selectedActions.forEach((action) => {
- const config = this.configs[action.value];
- switch (action.value) {
- case "wait":
- if (config.value) {
- code += `.wait('${config.value}'${
- config.timeout !== 60000 ? `, ${config.timeout}` : ""
- })`;
- }
- break;
-
- case "click":
- if (config.selector) {
- code += `.click('${config.selector}')`;
- }
- break;
-
- case "css":
- if (config.value) {
- code += `.css('${config.value}')`;
- }
- break;
-
- case "press":
- if (config.key) {
- const modifiers = config.modifiers.length
- ? `, ${JSON.stringify(config.modifiers)}`
- : "";
- code += `.press('${config.key}'${modifiers})`;
- }
- break;
-
- case "paste":
- if (config.text) {
- code += `.paste('${config.text}')`;
- }
- break;
-
- case "screenshot":
- if (config.selector || config.savePath) {
- const options = {};
- if (config.selector) options.selector = config.selector;
- if (config.rect.width && config.rect.height) {
- options.rect = config.rect;
- }
- code += `.screenshot('${config.savePath}'${
- Object.keys(options).length
- ? `, ${JSON.stringify(options)}`
- : ""
- })`;
- }
- break;
-
- case "pdf":
- if (config.savePath) {
- code += `.pdf('${config.savePath}'${
- config.options ? `, ${JSON.stringify(config.options)}` : ""
- })`;
- }
- break;
-
- case "device":
- if (config.size.width && config.size.height) {
- const options = {
- size: config.size,
- };
- if (config.useragent) options.useragent = config.useragent;
- code += `.device(${JSON.stringify(options)})`;
- }
- break;
-
- case "cookies":
- if (config.name) {
- code += `.cookies('${config.name}')`;
- }
- break;
-
- case "setCookies":
- if (config.items?.length) {
- code += `.setCookies(${JSON.stringify(config.items)})`;
- }
- break;
-
- case "removeCookies":
- if (config.name) {
- code += `.removeCookies('${config.name}')`;
- }
- break;
-
- case "clearCookies":
- code += `.clearCookies(${config.url ? `'${config.url}'` : ""})`;
- break;
-
- case "evaluate":
- if (config.function) {
- const params = config.params.length
- ? `, ${JSON.stringify(config.params)}`
- : "";
- code += `.evaluate(\`${config.function}\`${params})`;
- }
- break;
-
- case "when":
- if (config.condition) {
- code += `.when('${config.condition}')`;
- }
- break;
-
- case "mousedown":
- case "mouseup":
- if (config.selector) {
- code += `.${action.value}('${config.selector}')`;
- }
- break;
-
- case "file":
- if (config.selector && config.files?.length) {
- code += `.file('${config.selector}', ${JSON.stringify(
- config.files
- )})`;
- }
- break;
-
- case "value":
- if (config.selector) {
- code += `.value('${config.selector}', '${config.value}')`;
- }
- break;
-
- case "check":
- if (config.selector) {
- code += `.check('${config.selector}'${
- config.checked !== undefined ? `, ${config.checked}` : ""
- })`;
- }
- break;
-
- case "focus":
- if (config.selector) {
- code += `.focus('${config.selector}')`;
- }
- break;
-
- case "scroll":
- if (config.type === "element" && config.selector) {
- code += `.scroll('${config.selector}')`;
- } else if (config.type === "position") {
- if (config.x !== undefined && config.y !== undefined) {
- code += `.scroll(${config.x}, ${config.y})`;
- } else if (config.y !== undefined) {
- code += `.scroll(${config.y})`;
- }
- }
- break;
-
- case "download":
- if (config.url) {
- code += `.download('${config.url}'${
- config.savePath ? `, '${config.savePath}'` : ""
- })`;
- }
- break;
-
- case "hide":
- case "show":
- code += `.${action.value}()`;
- break;
-
- case "devTools":
- if (config.mode) {
- code += `.devTools('${config.mode}')`;
- } else {
- code += `.devTools()`;
- }
- break;
- }
- });
-
- // 运行参数
- const runOptions = {};
- Object.entries(this.configs.run).forEach(([key, value]) => {
- if (
- value !== undefined &&
- value !== null &&
- value !== this.defaultRunConfigs[key]
- ) {
- runOptions[key] = value;
- }
- });
-
- code += `.run(${
- Object.keys(runOptions).length ? JSON.stringify(runOptions) : ""
- })`;
-
- this.$emit("update:modelValue", code);
- },
},
watch: {
configs: {
deep: true,
handler() {
- this.generateCode();
+ this.$emit(
+ "update:modelValue",
+ generateUBrowserCode(this.configs, this.selectedActions)
+ );
},
},
selectedActions: {
handler() {
- this.generateCode();
+ this.$emit(
+ "update:modelValue",
+ generateUBrowserCode(this.configs, this.selectedActions)
+ );
},
},
step: {
handler() {
- this.generateCode();
+ this.$emit(
+ "update:modelValue",
+ generateUBrowserCode(this.configs, this.selectedActions)
+ );
},
},
},
diff --git a/src/components/editor/composer/ubrowser/UBrowserOperations.vue b/src/components/editor/composer/ubrowser/UBrowserOperations.vue
index 60c5898..c662ec6 100644
--- a/src/components/editor/composer/ubrowser/UBrowserOperations.vue
+++ b/src/components/editor/composer/ubrowser/UBrowserOperations.vue
@@ -4,8 +4,10 @@
- {{ action.label }}
+ {{ label }}
@@ -43,7 +45,9 @@
@@ -72,11 +76,11 @@
/>
-
+
@@ -88,10 +92,7 @@
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserCheckbox.vue b/src/components/editor/composer/ubrowser/operations/UBrowserCheckbox.vue
new file mode 100644
index 0000000..c368d48
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserCheckbox.vue
@@ -0,0 +1,37 @@
+
+
+ {{ label }}
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserCheckboxGroup.vue b/src/components/editor/composer/ubrowser/operations/UBrowserCheckboxGroup.vue
new file mode 100644
index 0000000..adb26f7
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserCheckboxGroup.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserCookieList.vue b/src/components/editor/composer/ubrowser/operations/UBrowserCookieList.vue
new file mode 100644
index 0000000..6efc7ec
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserCookieList.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+ handleUpdate(index, 'name', value)
+ "
+ />
+
+
+ handleUpdate(index, 'value', value)
+ "
+ />
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserDeviceName.vue b/src/components/editor/composer/ubrowser/operations/UBrowserDeviceName.vue
new file mode 100644
index 0000000..e418576
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserDeviceName.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserDeviceSize.vue b/src/components/editor/composer/ubrowser/operations/UBrowserDeviceSize.vue
new file mode 100644
index 0000000..3b47402
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserDeviceSize.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserFileList.vue b/src/components/editor/composer/ubrowser/operations/UBrowserFileList.vue
new file mode 100644
index 0000000..11da2a4
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserFileList.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+ handleUpdate(index, value)"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserFunctionInput.vue b/src/components/editor/composer/ubrowser/operations/UBrowserFunctionInput.vue
new file mode 100644
index 0000000..f417ed1
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserFunctionInput.vue
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+
+
+ {{ param }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserInput.vue b/src/components/editor/composer/ubrowser/operations/UBrowserInput.vue
index 2402bbe..caa9394 100644
--- a/src/components/editor/composer/ubrowser/operations/UBrowserInput.vue
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserInput.vue
@@ -1,26 +1,16 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserNamedParamList.vue b/src/components/editor/composer/ubrowser/operations/UBrowserNamedParamList.vue
new file mode 100644
index 0000000..b90121e
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserNamedParamList.vue
@@ -0,0 +1,82 @@
+
+
+
{{ label }}
+
+
+ handleUpdate(index, 'name', value)"
+ />
+
+
+ handleUpdate(index, 'value', value)"
+ />
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserOperation.vue b/src/components/editor/composer/ubrowser/operations/UBrowserOperation.vue
index cf6cbc5..26f2b96 100644
--- a/src/components/editor/composer/ubrowser/operations/UBrowserOperation.vue
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserOperation.vue
@@ -7,240 +7,119 @@
>
-
-
-
-
+
-
- {{ field.label }}
-
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+ />
-
-
-
-
-
+ />
-
-
-
-
- {{ field.label }}
-
-
+
+
-
-
-
- {{ field.label }}
-
-
+
+
+
+
+
+
+
+
+
+
+ updateValue('function', value)"
+ @update:args="(value) => updateValue('args', value)"
+ />
@@ -250,9 +129,35 @@
-
-
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserSelect.vue b/src/components/editor/composer/ubrowser/operations/UBrowserSelect.vue
new file mode 100644
index 0000000..b413d9b
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserSelect.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/operations/UBrowserTextarea.vue b/src/components/editor/composer/ubrowser/operations/UBrowserTextarea.vue
new file mode 100644
index 0000000..ec93ba1
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/operations/UBrowserTextarea.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/editor/composer/ubrowser/ubrowserConfig.js b/src/components/editor/composer/ubrowser/ubrowserConfig.js
new file mode 100644
index 0000000..6cbcea3
--- /dev/null
+++ b/src/components/editor/composer/ubrowser/ubrowserConfig.js
@@ -0,0 +1,629 @@
+// ubrowser 浏览器操作配置
+export const ubrowserOperationConfigs = {
+ wait: {
+ label: "等待",
+ 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",
+ type: "input",
+ inputType: "number",
+ width: 12,
+ showWhen: "type",
+ showValue: "time",
+ },
+ {
+ key: "selector",
+ label: "等待元素的CSS选择器",
+ icon: "find_in_page",
+ type: "input",
+ 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",
+ type: "input",
+ inputType: "number",
+ width: 12,
+ defaultValue: 60000,
+ showWhen: "type",
+ showValue: ["selector", "function"],
+ },
+ ],
+ icon: "timer",
+ },
+ click: {
+ label: "点击",
+ config: [
+ {
+ key: "selector",
+ label: "点击元素的CSS选择器",
+ icon: "mouse",
+ type: "input",
+ },
+ ],
+ icon: "mouse",
+ },
+ css: {
+ label: "注入CSS",
+ config: [
+ {
+ key: "value",
+ label: "注入的CSS样式",
+ icon: "style",
+ type: "textarea",
+ },
+ ],
+ icon: "style",
+ },
+ press: {
+ label: "按键",
+ config: [
+ {
+ key: "key",
+ label: "按键",
+ icon: "keyboard",
+ type: "input",
+ width: 5,
+ },
+ {
+ key: "modifiers",
+ label: "修饰键",
+ type: "checkbox-group",
+ options: [
+ { label: "Ctrl", value: "ctrl" },
+ { label: "Shift", value: "shift" },
+ { label: "Alt", value: "alt" },
+ { label: "Meta", value: "meta" },
+ ],
+ defaultValue: [],
+ width: 7,
+ },
+ ],
+ icon: "keyboard",
+ },
+ paste: {
+ label: "粘贴",
+ config: [
+ {
+ key: "text",
+ label: "粘贴内容",
+ icon: "content_paste",
+ type: "input",
+ },
+ ],
+ icon: "content_paste",
+ },
+ viewport: {
+ label: "视窗",
+ config: [
+ {
+ key: "width",
+ label: "视窗宽度",
+ icon: "width",
+ type: "input",
+ inputType: "number",
+ width: 6,
+ },
+ {
+ key: "height",
+ label: "视窗高度",
+ icon: "height",
+ type: "input",
+ inputType: "number",
+ width: 6,
+ },
+ ],
+ icon: "crop",
+ },
+ screenshot: {
+ label: "截图",
+ config: [
+ { key: "selector", label: "元素选择器", icon: "crop", type: "input" },
+ {
+ key: "rect.x",
+ label: "X坐标",
+ icon: "drag_handle",
+ type: "input",
+ inputType: "number",
+ width: 3,
+ },
+ {
+ key: "rect.y",
+ label: "Y坐标",
+ icon: "drag_handle",
+ type: "input",
+ inputType: "number",
+ width: 3,
+ },
+ {
+ key: "rect.width",
+ label: "宽度",
+ icon: "width",
+ type: "input",
+ inputType: "number",
+ width: 3,
+ },
+ {
+ key: "rect.height",
+ label: "高度",
+ icon: "height",
+ type: "input",
+ inputType: "number",
+ width: 3,
+ },
+ { key: "savePath", label: "保存路径", icon: "save", type: "input" },
+ ],
+ icon: "picture_as_pdf",
+ },
+ pdf: {
+ label: "导出PDF",
+ config: [
+ {
+ key: "options.marginsType",
+ label: "边距类型",
+ type: "select",
+ options: [
+ { label: "默认边距", value: 0 },
+ { label: "无边距", value: 1 },
+ { label: "最小边距", value: 2 },
+ ],
+ width: 6,
+ },
+ {
+ key: "options.pageSize",
+ label: "页面大小",
+ type: "select",
+ options: ["A3", "A4", "A5", "Legal", "Letter", "Tabloid"],
+ width: 6,
+ },
+ { key: "savePath", label: "保存路径", icon: "save", type: "input" },
+ ],
+ icon: "devices",
+ },
+ device: {
+ label: "模拟设备",
+ config: [
+ {
+ key: "type",
+ label: "设备类型",
+ type: "button-toggle",
+ options: [
+ { label: "特定设备", value: "preset" },
+ { label: "自定义设备", value: "custom" },
+ ],
+ defaultValue: "preset",
+ },
+ {
+ key: "deviceName",
+ label: "设备名称",
+ icon: "smartphone",
+ type: "input",
+ 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",
+ type: "input",
+ width: 12,
+ showWhen: "type",
+ showValue: "custom",
+ },
+ ],
+ icon: "cookie",
+ },
+ setCookies: {
+ label: "设置Cookie",
+ config: [{ key: "items", label: "Cookie列表", type: "cookie-list" }],
+ icon: "cookie",
+ },
+ removeCookies: {
+ label: "删除Cookie",
+ config: [
+ { key: "name", label: "Cookie名称", icon: "cookie", type: "input" },
+ ],
+ icon: "cookie",
+ },
+ clearCookies: {
+ label: "清空Cookie",
+ config: [{ key: "url", label: "URL(可选)", icon: "link", type: "input" }],
+ icon: "cookie",
+ },
+ evaluate: {
+ label: "执行代码",
+ config: [
+ {
+ key: "function",
+ label: "执行的代码",
+ icon: "code",
+ type: "function-with-params",
+ width: 12,
+ },
+ ],
+ icon: "code",
+ },
+ when: {
+ label: "条件判断",
+ config: [
+ {
+ key: "type",
+ label: "条件类型",
+ type: "button-toggle",
+ options: [
+ { label: "等待元素", value: "selector" },
+ { label: "等待条件", value: "function" },
+ ],
+ defaultValue: "selector",
+ },
+ {
+ key: "selector",
+ label: "等待元素的CSS选择器",
+ icon: "find_in_page",
+ type: "input",
+ 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",
+ type: "input",
+ inputType: "number",
+ width: 12,
+ defaultValue: 60000,
+ showWhen: "type",
+ showValue: ["selector", "function"],
+ },
+ ],
+ icon: "rule",
+ },
+ end: {
+ label: "结束条件",
+ config: [],
+ icon: "stop",
+ },
+ mousedown: {
+ label: "按下鼠标",
+ config: [
+ {
+ key: "selector",
+ label: "按下元素选择器",
+ icon: "mouse",
+ type: "input",
+ },
+ ],
+ icon: "mouse",
+ },
+ mouseup: {
+ label: "释放鼠标",
+ config: [
+ {
+ key: "selector",
+ label: "释放元素选择器",
+ icon: "mouse",
+ type: "input",
+ },
+ ],
+ icon: "mouse",
+ },
+ file: {
+ label: "上传文件",
+ config: [
+ {
+ key: "selector",
+ label: "文件输入框选择器",
+ icon: "upload_file",
+ type: "input",
+ },
+ { key: "files", label: "文件列表", type: "file-list", width: 12 },
+ ],
+ icon: "upload_file",
+ },
+ value: {
+ label: "设置值",
+ config: [
+ {
+ key: "selector",
+ label: "元素选择器",
+ icon: "input",
+ type: "input",
+ width: 6,
+ },
+ {
+ key: "value",
+ label: "设置的值",
+ icon: "edit",
+ type: "input",
+ width: 6,
+ },
+ ],
+ icon: "check_box",
+ },
+ check: {
+ label: "设置选中",
+ config: [
+ {
+ key: "selector",
+ label: "复选框/选框选择器",
+ icon: "check_box",
+ type: "input",
+ width: 8,
+ },
+ {
+ key: "checked",
+ label: "选中状态",
+ type: "checkbox",
+ defaultValue: false,
+ width: 4,
+ },
+ ],
+ icon: "center_focus_strong",
+ },
+ focus: {
+ label: "聚焦元素",
+ config: [
+ {
+ key: "selector",
+ label: "元素选择器",
+ icon: "center_focus_strong",
+ type: "input",
+ },
+ ],
+ icon: "swap_vert",
+ },
+ scroll: {
+ label: "滚动",
+ config: [
+ {
+ key: "type",
+ label: "滚动类型",
+ type: "button-toggle",
+ options: [
+ { label: "滚动到元素", value: "element" },
+ { label: "滚动到坐标", value: "position" },
+ ],
+ defaultValue: "element",
+ },
+ {
+ key: "selector",
+ label: "目标元素选择器",
+ icon: "swap_vert",
+ type: "input",
+ width: 12,
+ showWhen: "type",
+ showValue: "element",
+ },
+ {
+ key: "x",
+ label: "X坐标",
+ icon: "drag_handle",
+ type: "input",
+ inputType: "number",
+ width: 6,
+ showWhen: "type",
+ showValue: "position",
+ },
+ {
+ key: "y",
+ label: "Y坐标",
+ icon: "drag_handle",
+ type: "input",
+ inputType: "number",
+ width: 6,
+ showWhen: "type",
+ showValue: "position",
+ },
+ ],
+ icon: "download",
+ },
+ download: {
+ label: "下载",
+ config: [
+ {
+ key: "url",
+ label: "下载URL",
+ icon: "link",
+ type: "input",
+ width: 6,
+ },
+ {
+ key: "savePath",
+ label: "保存路径",
+ icon: "save",
+ type: "input",
+ width: 6,
+ },
+ ],
+ icon: "download",
+ },
+ devTools: {
+ label: "开发工具",
+ config: [
+ {
+ key: "mode",
+ label: "开发工具位置",
+ type: "button-toggle",
+ options: [
+ { label: "右侧", value: "right" },
+ { label: "底部", value: "bottom" },
+ { label: "独立", value: "undocked" },
+ { label: "分离", value: "detach" },
+ ],
+ defaultValue: "right",
+ },
+ ],
+ icon: "developer_board",
+ },
+};
+
+// 添加默认运行配置
+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 = {
+ // 基础参数
+ useragent: {
+ value: "",
+ },
+ goto: {
+ url: "",
+ headers: {
+ Referer: "",
+ userAgent: "",
+ },
+ timeout: 60000,
+ },
+ // 浏览器操作
+ wait: {
+ value: "",
+ timeout: 60000,
+ },
+ click: {
+ selector: "",
+ },
+ css: {
+ value: "",
+ },
+ press: {
+ key: "",
+ modifiers: [],
+ },
+ paste: {
+ text: "",
+ },
+ screenshot: {
+ selector: "",
+ rect: { x: 0, y: 0, width: 0, height: 0 },
+ savePath: "",
+ },
+ pdf: {
+ options: {
+ marginsType: 0,
+ pageSize: "A4",
+ },
+ savePath: "",
+ },
+ device: {
+ size: { width: 1280, height: 800 },
+ useragent: "",
+ },
+ cookies: {
+ name: "",
+ },
+ setCookies: {
+ items: [{ name: "", value: "" }],
+ },
+ removeCookies: {
+ name: "",
+ },
+ clearCookies: {
+ url: "",
+ },
+ evaluate: {
+ function: "",
+ params: [],
+ },
+ when: {
+ condition: "",
+ },
+ mousedown: {
+ selector: "",
+ },
+ mouseup: {
+ selector: "",
+ },
+ file: {
+ selector: "",
+ files: [],
+ },
+ value: {
+ selector: "",
+ value: "",
+ },
+ check: {
+ selector: "",
+ checked: false,
+ },
+ focus: {
+ selector: "",
+ },
+ scroll: {
+ target: "",
+ x: 0,
+ y: 0,
+ },
+ download: {
+ url: "",
+ savePath: "",
+ },
+ // 运行参数
+ run: defaultUBrowserRunConfigs,
+};
+
+// 定义 ubrowser 操作图标映射
+// 格式:{ wait: 'timer', ...}
+export const ubrowserActionIcons = _.mapValues(
+ ubrowserOperationConfigs,
+ (config) => config.icon
+);