mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-07 21:46:12 +08:00
优化浏览器设置Cookie、执行脚本和等待元素的功能
This commit is contained in:
parent
c3a07ed0b5
commit
06938cade1
@ -60,16 +60,22 @@ module.exports = {
|
|||||||
executeScript: async function (
|
executeScript: async function (
|
||||||
browser = "Microsoft Edge",
|
browser = "Microsoft Edge",
|
||||||
script,
|
script,
|
||||||
newScope = true
|
args = {}
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
// 默认在两边加上括号让脚本每次在新的作用域执行,防止变量污染
|
// 构建参数列表
|
||||||
if (newScope) script = "{" + script + "}";
|
const argNames = Object.keys(args);
|
||||||
|
const argValues = Object.values(args).map((v) => JSON.stringify(v));
|
||||||
|
|
||||||
|
script = `
|
||||||
|
(function(${argNames.join(", ")}) {
|
||||||
|
${script}
|
||||||
|
})(${argValues.join(", ")})
|
||||||
|
`;
|
||||||
// 使用JSON.stringify处理转义
|
// 使用JSON.stringify处理转义
|
||||||
const escapedScript = JSON.stringify(script);
|
const escapedScript = JSON.stringify(script);
|
||||||
console.log(escapedScript);
|
|
||||||
|
|
||||||
return await quickcommand.runAppleScript(`
|
let result = await quickcommand.runAppleScript(`
|
||||||
tell application "${browser}"
|
tell application "${browser}"
|
||||||
tell front window
|
tell front window
|
||||||
tell active tab
|
tell active tab
|
||||||
@ -78,8 +84,23 @@ module.exports = {
|
|||||||
end tell
|
end tell
|
||||||
end tell
|
end tell
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
result = result?.trim() || "";
|
||||||
|
if (result === "missing value") {
|
||||||
|
// 脚本没有返回值
|
||||||
|
return;
|
||||||
|
} else if (result === "##execute_script_success##") {
|
||||||
|
// 模拟操作执行成功
|
||||||
|
return true;
|
||||||
|
} else if (result === "##execute_script_failed##") {
|
||||||
|
// 模拟操作执行失败
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
quickcommand.showSystemMessageBox("执行失败", error.toString());
|
quickcommand.showSystemMessageBox("执行失败", error.toString());
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -89,9 +110,9 @@ module.exports = {
|
|||||||
const element = document.querySelector('${selector}');
|
const element = document.querySelector('${selector}');
|
||||||
if (element) {
|
if (element) {
|
||||||
element.click();
|
element.click();
|
||||||
'success';
|
return '##execute_script_success##';
|
||||||
} else {
|
} else {
|
||||||
'element not found';
|
return '##execute_script_failed##';
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
@ -105,9 +126,9 @@ module.exports = {
|
|||||||
element.value = '${text}';
|
element.value = '${text}';
|
||||||
element.dispatchEvent(new Event('input'));
|
element.dispatchEvent(new Event('input'));
|
||||||
element.dispatchEvent(new Event('change'));
|
element.dispatchEvent(new Event('change'));
|
||||||
'success';
|
return '##execute_script_success##';
|
||||||
} else {
|
} else {
|
||||||
'element not found';
|
return '##execute_script_failed##';
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
@ -117,7 +138,7 @@ module.exports = {
|
|||||||
getText: async function (browser = "Microsoft Edge", selector) {
|
getText: async function (browser = "Microsoft Edge", selector) {
|
||||||
const script = `
|
const script = `
|
||||||
const element = document.querySelector('${selector}');
|
const element = document.querySelector('${selector}');
|
||||||
element ? element.textContent : '';
|
return element ? element.textContent : '';
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
},
|
},
|
||||||
@ -126,7 +147,7 @@ module.exports = {
|
|||||||
getHtml: async function (browser = "Microsoft Edge", selector) {
|
getHtml: async function (browser = "Microsoft Edge", selector) {
|
||||||
const script = `
|
const script = `
|
||||||
const element = document.querySelector('${selector}');
|
const element = document.querySelector('${selector}');
|
||||||
element ? element.innerHTML : '';
|
return element ? element.innerHTML : '';
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
},
|
},
|
||||||
@ -137,9 +158,9 @@ module.exports = {
|
|||||||
const element = document.querySelector('${selector}');
|
const element = document.querySelector('${selector}');
|
||||||
if (element) {
|
if (element) {
|
||||||
element.style.display = 'none';
|
element.style.display = 'none';
|
||||||
'success';
|
return '##execute_script_success##';
|
||||||
} else {
|
} else {
|
||||||
'element not found';
|
return '##execute_script_failed##';
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
@ -151,9 +172,9 @@ module.exports = {
|
|||||||
const element = document.querySelector('${selector}');
|
const element = document.querySelector('${selector}');
|
||||||
if (element) {
|
if (element) {
|
||||||
element.style.display = '';
|
element.style.display = '';
|
||||||
'success';
|
return '##execute_script_success##';
|
||||||
} else {
|
} else {
|
||||||
'element not found';
|
return '##execute_script_failed##';
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
@ -165,7 +186,7 @@ module.exports = {
|
|||||||
const style = document.createElement('style');
|
const style = document.createElement('style');
|
||||||
style.textContent = \`${css}\`;
|
style.textContent = \`${css}\`;
|
||||||
document.head.appendChild(style);
|
document.head.appendChild(style);
|
||||||
'success';
|
return '##execute_script_success##';
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
},
|
},
|
||||||
@ -176,23 +197,25 @@ module.exports = {
|
|||||||
cookies,
|
cookies,
|
||||||
options = {}
|
options = {}
|
||||||
) {
|
) {
|
||||||
// 在外部构建所有cookie的设置语句
|
|
||||||
console.log(cookies, options);
|
|
||||||
const cookieStatements = cookies
|
const cookieStatements = cookies
|
||||||
.map((cookie) => {
|
.map((cookie) => {
|
||||||
let cookieString = `${cookie.name}=${cookie.value}`;
|
let cookieString = `${cookie.name}=${cookie.value}`;
|
||||||
if (options.expires) cookieString += `;expires=${options.expires}`;
|
if (options.expires) {
|
||||||
|
const expiresDate = new Date(
|
||||||
|
Date.now() + options.expires * 60 * 60 * 1000
|
||||||
|
);
|
||||||
|
cookieString += `;expires=${expiresDate.toUTCString()}`;
|
||||||
|
}
|
||||||
if (options.path) cookieString += `;path=${options.path}`;
|
if (options.path) cookieString += `;path=${options.path}`;
|
||||||
if (options.domain) cookieString += `;domain=${options.domain}`;
|
if (options.domain) cookieString += `;domain=${options.domain}`;
|
||||||
if (options.secure) cookieString += ";secure";
|
if (options.secure) cookieString += ";secure";
|
||||||
if (options.sameSite) cookieString += `;samesite=${options.sameSite}`;
|
|
||||||
return `document.cookie = ${JSON.stringify(cookieString)};`;
|
return `document.cookie = ${JSON.stringify(cookieString)};`;
|
||||||
})
|
})
|
||||||
.join("\n");
|
.join("\n");
|
||||||
|
|
||||||
const script = `
|
const script = `
|
||||||
${cookieStatements}
|
${cookieStatements}
|
||||||
'success';
|
return '##execute_script_success##';
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
@ -205,7 +228,7 @@ module.exports = {
|
|||||||
.split('; ')
|
.split('; ')
|
||||||
.find(row => row.startsWith('${name}='))
|
.find(row => row.startsWith('${name}='))
|
||||||
?.split('=')[1];
|
?.split('=')[1];
|
||||||
value || '';
|
return value || '';
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
},
|
},
|
||||||
@ -221,7 +244,7 @@ module.exports = {
|
|||||||
document.cookie = '${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT' +
|
document.cookie = '${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT' +
|
||||||
(${domain ? `'; domain=${domain}'` : "''"}) +
|
(${domain ? `'; domain=${domain}'` : "''"}) +
|
||||||
(${path ? `'; path=${path}'` : "''"});
|
(${path ? `'; path=${path}'` : "''"});
|
||||||
'success';
|
return '##execute_script_success##';
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
},
|
},
|
||||||
@ -230,7 +253,7 @@ module.exports = {
|
|||||||
scrollTo: async function (browser = "Microsoft Edge", x, y) {
|
scrollTo: async function (browser = "Microsoft Edge", x, y) {
|
||||||
const script = `
|
const script = `
|
||||||
window.scrollTo(${x}, ${y});
|
window.scrollTo(${x}, ${y});
|
||||||
'success';
|
return '##execute_script_success##';
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
},
|
},
|
||||||
@ -241,9 +264,9 @@ module.exports = {
|
|||||||
const element = document.querySelector('${selector}');
|
const element = document.querySelector('${selector}');
|
||||||
if (element) {
|
if (element) {
|
||||||
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
'success';
|
return '##execute_script_success##';
|
||||||
} else {
|
} else {
|
||||||
'element not found';
|
return '##execute_script_failed##';
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
return await this.executeScript(browser, script);
|
||||||
@ -252,7 +275,7 @@ module.exports = {
|
|||||||
// 获取滚动位置
|
// 获取滚动位置
|
||||||
getScrollPosition: async function (browser = "Microsoft Edge") {
|
getScrollPosition: async function (browser = "Microsoft Edge") {
|
||||||
const script = `
|
const script = `
|
||||||
JSON.stringify({
|
return JSON.stringify({
|
||||||
x: window.pageXOffset || document.documentElement.scrollLeft,
|
x: window.pageXOffset || document.documentElement.scrollLeft,
|
||||||
y: window.pageYOffset || document.documentElement.scrollTop
|
y: window.pageYOffset || document.documentElement.scrollTop
|
||||||
});
|
});
|
||||||
@ -263,7 +286,7 @@ module.exports = {
|
|||||||
// 获取页面尺寸
|
// 获取页面尺寸
|
||||||
getPageSize: async function (browser = "Microsoft Edge") {
|
getPageSize: async function (browser = "Microsoft Edge") {
|
||||||
const script = `
|
const script = `
|
||||||
JSON.stringify({
|
return JSON.stringify({
|
||||||
width: Math.max(
|
width: Math.max(
|
||||||
document.documentElement.scrollWidth,
|
document.documentElement.scrollWidth,
|
||||||
document.documentElement.clientWidth
|
document.documentElement.clientWidth
|
||||||
@ -283,65 +306,24 @@ module.exports = {
|
|||||||
selector,
|
selector,
|
||||||
timeout = 5000
|
timeout = 5000
|
||||||
) {
|
) {
|
||||||
const script = `
|
const startTime = Date.now();
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
const element = document.querySelector('${selector}');
|
|
||||||
if (element) {
|
|
||||||
resolve('found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const observer = new MutationObserver((mutations, obs) => {
|
// 检查元素是否存在的函数
|
||||||
const element = document.querySelector('${selector}');
|
const checkScript = `
|
||||||
if (element) {
|
|
||||||
obs.disconnect();
|
|
||||||
resolve('found');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
observer.observe(document.body, {
|
|
||||||
childList: true,
|
|
||||||
subtree: true
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
observer.disconnect();
|
|
||||||
reject('timeout');
|
|
||||||
}, ${timeout});
|
|
||||||
});
|
|
||||||
`;
|
|
||||||
return await this.executeScript(browser, script);
|
|
||||||
},
|
|
||||||
|
|
||||||
// 监听元素变化
|
|
||||||
observeElement: async function (
|
|
||||||
browser = "Microsoft Edge",
|
|
||||||
selector,
|
|
||||||
callback
|
|
||||||
) {
|
|
||||||
const script = `
|
|
||||||
const element = document.querySelector('${selector}');
|
const element = document.querySelector('${selector}');
|
||||||
if (!element) return 'element not found';
|
return element ? '##execute_script_success##' : '##execute_script_failed##';
|
||||||
|
|
||||||
const observer = new MutationObserver((mutations) => {
|
|
||||||
const data = mutations.map(mutation => ({
|
|
||||||
type: mutation.type,
|
|
||||||
target: mutation.target.outerHTML,
|
|
||||||
addedNodes: Array.from(mutation.addedNodes).map(node => node.outerHTML),
|
|
||||||
removedNodes: Array.from(mutation.removedNodes).map(node => node.outerHTML)
|
|
||||||
}));
|
|
||||||
window.webkit.messageHandlers.callback.postMessage(JSON.stringify(data));
|
|
||||||
});
|
|
||||||
|
|
||||||
observer.observe(element, {
|
|
||||||
attributes: true,
|
|
||||||
childList: true,
|
|
||||||
subtree: true,
|
|
||||||
characterData: true
|
|
||||||
});
|
|
||||||
|
|
||||||
'success';
|
|
||||||
`;
|
`;
|
||||||
return await this.executeScript(browser, script);
|
|
||||||
|
// 轮询检查元素
|
||||||
|
while (Date.now() - startTime < timeout) {
|
||||||
|
const result = await this.executeScript(browser, checkScript);
|
||||||
|
if (result === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 等待100ms再次检查
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
<q-icon name="code" />
|
<q-icon name="code" />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<q-btn dense flat icon="arrow_drop_down">
|
<q-btn dense flat icon="menu">
|
||||||
<q-menu>
|
<q-menu>
|
||||||
<q-list dense>
|
<q-list dense>
|
||||||
<q-item
|
<q-item
|
||||||
@ -256,6 +256,9 @@ export default defineComponent({
|
|||||||
handleInput(val, index) {
|
handleInput(val, index) {
|
||||||
this.inputValue = val;
|
this.inputValue = val;
|
||||||
const item = this.allItems[index];
|
const item = this.allItems[index];
|
||||||
|
if (val in this.modelValue && val !== item.key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const dict = { ...this.modelValue };
|
const dict = { ...this.modelValue };
|
||||||
delete dict[item.key];
|
delete dict[item.key];
|
||||||
dict[val] = item.value;
|
dict[val] = item.value;
|
||||||
@ -265,6 +268,9 @@ export default defineComponent({
|
|||||||
this.inputValue = "";
|
this.inputValue = "";
|
||||||
const value = val?.value || val;
|
const value = val?.value || val;
|
||||||
const item = this.allItems[index];
|
const item = this.allItems[index];
|
||||||
|
if (value in this.modelValue && value !== item.key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const dict = { ...this.modelValue };
|
const dict = { ...this.modelValue };
|
||||||
delete dict[item.key];
|
delete dict[item.key];
|
||||||
dict[value] = item.value;
|
dict[value] = item.value;
|
||||||
|
@ -495,6 +495,13 @@ export const macosCommands = {
|
|||||||
width: 12,
|
width: 12,
|
||||||
placeholder: "输入JavaScript代码",
|
placeholder: "输入JavaScript代码",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "args",
|
||||||
|
topLabel: "要传递的参数",
|
||||||
|
component: "DictEditor",
|
||||||
|
icon: "data_array",
|
||||||
|
width: 12,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -737,11 +744,46 @@ export const macosCommands = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "选项",
|
label: "选项",
|
||||||
component: "DictEditor",
|
component: "OptionEditor",
|
||||||
icon: "settings",
|
icon: "settings",
|
||||||
width: 12,
|
width: 12,
|
||||||
options: {
|
options: {
|
||||||
optionKeys: ["expires", "path", "domain", "secure", "sameSite"],
|
expires: {
|
||||||
|
label: "过期时间",
|
||||||
|
component: "q-select",
|
||||||
|
icon: "timer",
|
||||||
|
width: 6,
|
||||||
|
options: [
|
||||||
|
{ label: "关闭浏览器失效", value: false },
|
||||||
|
{ label: "1小时", value: 1 },
|
||||||
|
{ label: "1天", value: 24 },
|
||||||
|
{ label: "1年", value: 24 * 365 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
path: {
|
||||||
|
label: "路径",
|
||||||
|
component: "VariableInput",
|
||||||
|
icon: "folder",
|
||||||
|
width: 6,
|
||||||
|
},
|
||||||
|
domain: {
|
||||||
|
label: "域名",
|
||||||
|
component: "VariableInput",
|
||||||
|
icon: "domain",
|
||||||
|
width: 6,
|
||||||
|
},
|
||||||
|
secure: {
|
||||||
|
label: "安全",
|
||||||
|
component: "CheckButton",
|
||||||
|
icon: "lock",
|
||||||
|
width: 6,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultValue: {
|
||||||
|
expires: false,
|
||||||
|
path: newVarInputVal("str", "/"),
|
||||||
|
domain: newVarInputVal("str", ""),
|
||||||
|
secure: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -892,46 +934,6 @@ export const macosCommands = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
value: "quickcomposer.macos.browser.observeElement",
|
|
||||||
label: "监听元素",
|
|
||||||
desc: "监听指定元素的变化",
|
|
||||||
icon: "visibility",
|
|
||||||
config: [
|
|
||||||
{
|
|
||||||
key: "browser",
|
|
||||||
component: "ButtonGroup",
|
|
||||||
defaultValue: "Microsoft Edge",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: "Edge 浏览器",
|
|
||||||
value: "Microsoft Edge",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Chrome 浏览器",
|
|
||||||
value: "Google Chrome",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
width: 12,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "selector",
|
|
||||||
label: "选择器",
|
|
||||||
component: "VariableInput",
|
|
||||||
icon: "code",
|
|
||||||
width: 12,
|
|
||||||
placeholder: "输入CSS选择器",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "callback",
|
|
||||||
label: "回调函数",
|
|
||||||
component: "CodeEditor",
|
|
||||||
icon: "code",
|
|
||||||
width: 12,
|
|
||||||
placeholder: "输入回调函数代码",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user