diff --git a/plugin/lib/quickcomposer/browser/execScript.js b/plugin/lib/quickcomposer/browser/execScript.js index 21aec07..4153fa0 100644 --- a/plugin/lib/quickcomposer/browser/execScript.js +++ b/plugin/lib/quickcomposer/browser/execScript.js @@ -1,4 +1,5 @@ const { executeScript } = require("./browser"); +const fs = require("fs"); const clickElement = async (tab, selector) => { return await executeScript( @@ -128,12 +129,54 @@ const injectCSS = async (tab, css) => { tab, ` const style = document.createElement('style'); - style.textContent = \`${css}\`; + style.textContent = css; document.head.appendChild(style); - ` + `, + { css } ); }; +const injectRemoteScript = async (tab, url) => { + return await executeScript( + tab, + ` + return await new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.src = url; + script.type = 'text/javascript'; + script.onload = () => resolve(true); + script.onerror = () => reject(new Error('Failed to load script: ' + url)); + document.head.appendChild(script); + }); + `, + { url } + ); +}; + +const injectLocalScript = async (tab, filePath) => { + try { + if (!fs.existsSync(filePath)) { + throw new Error(`文件不存在: ${filePath}`); + } + + const content = fs.readFileSync(filePath, "utf8"); + + return await executeScript( + tab, + ` + const script = document.createElement('script'); + script.type = 'text/javascript'; + script.textContent = content; + document.head.appendChild(script); + return true; + `, + { content } + ); + } catch (error) { + throw new Error(`注入本地脚本失败: ${error.message}`); + } +}; + module.exports = { clickElement, inputText, @@ -148,4 +191,6 @@ module.exports = { getPageSize, waitForElement, injectCSS, + injectRemoteScript, + injectLocalScript, }; diff --git a/src/js/composer/commands/browserCommands.js b/src/js/composer/commands/browserCommands.js index e8e6998..bcc62a2 100644 --- a/src/js/composer/commands/browserCommands.js +++ b/src/js/composer/commands/browserCommands.js @@ -266,6 +266,73 @@ export const browserCommands = { }, ], }, + { + value: "quickcomposer.browser.injectRemoteScript", + label: "注入脚本/样式", + icon: "style", + isAsync: true, + config: [tabConfig], + subCommands: [ + { + label: "注入CDN脚本", + value: "quickcomposer.browser.injectRemoteScript", + icon: "javascript", + config: [ + { + component: "VariableInput", + icon: "link", + width: 12, + placeholder: "输入远程脚本URL", + }, + ], + }, + { + label: "注入本地脚本", + icon: "javascript", + value: "quickcomposer.browser.injectLocalScript", + config: [ + { + component: "VariableInput", + icon: "folder", + width: 12, + options: { + dialog: { + type: "open", + options: { + title: "选择脚本", + filters: [ + { + name: "JavaScript", + extensions: ["js"], + }, + { + name: "all", + extensions: ["*"], + }, + ], + properties: ["openFile"], + }, + }, + }, + placeholder: "输入本地脚本绝对路径", + }, + ], + }, + { + label: "注入CSS", + value: "quickcomposer.browser.injectCSS", + icon: "style", + config: [ + { + component: "CodeEditor", + icon: "style", + width: 12, + placeholder: "输入CSS代码", + }, + ], + }, + ], + }, { value: "quickcomposer.browser.setCookie", label: "Cookie操作", @@ -356,22 +423,6 @@ export const browserCommands = { }, ], }, - { - value: "quickcomposer.browser.injectCSS", - label: "注入CSS", - icon: "style", - isAsync: true, - config: [ - tabConfig, - { - label: "CSS内容", - component: "CodeEditor", - icon: "style", - width: 12, - placeholder: "输入CSS代码", - }, - ], - }, { value: "quickcomposer.browser.clickElement", label: "元素操作",