客户端:把查询请求放到 GM 通道,等待结果返回
Tính đến
Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta
// @require https://update.greatest.deepsurf.us/scripts/548365/1654687/DQ%20Client%20%28for%20DeepQuery%20Secure%29.js
// ==UserScript==
// @name DQ Client (for DeepQuery Secure)
// @namespace dq.secure.client
// @version 1.0.0
// @description 客户端:把查询请求放到 GM 通道,等待结果返回
// @match http://*/*
// @match https://*/*
// @include about:blank
// @run-at document-start
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addValueChangeListener
// @grant GM_removeValueChangeListener
// @grant GM_getTab
// @grant GM_saveTab
// ==/UserScript==
(function(){
'use strict';
const now = () => Date.now();
const rid = () => (now().toString(36) + Math.random().toString(36).slice(2,8)).toUpperCase();
function getTabId(){
return new Promise(resolve=>{
GM_getTab(tab=>{
if(!tab) tab = {};
if(!tab.__dq_tab_id__){ tab.__dq_tab_id__ = rid(); try{ GM_saveTab(tab); }catch{} }
resolve(tab.__dq_tab_id__);
});
});
}
async function request(spec){
const TAB_ID = await getTabId();
const reqId = rid();
const KEY_REQ = `DQ_REQ:${TAB_ID}`;
const KEY_RES = `DQ_RES:${TAB_ID}:${reqId}`;
return await new Promise((resolve)=>{
const lid = GM_addValueChangeListener(KEY_RES, (name, oldVal, val, remote)=>{
if(!remote) return;
try{ GM_removeValueChangeListener(lid); }catch{}
try{ GM_setValue(name, null); }catch{}
resolve(val);
});
GM_setValue(KEY_REQ, { tabId: TAB_ID, reqId, spec, at: Date.now() });
});
}
// 语法糖,保持与旧 API 一致
const DQ = {
get: (spec)=>request(spec),
attr: ({framePath, chain, name, timeout, frameTimeout}) => request({framePath, chain, timeout, frameTimeout, pick: {attr: name}}),
prop: ({framePath, chain, name, timeout, frameTimeout}) => request({framePath, chain, timeout, frameTimeout, pick: {prop: name}}),
text: ({framePath, chain, timeout, frameTimeout}) => request({framePath, chain, timeout, frameTimeout, pick: {text: true}}),
html: ({framePath, chain, timeout, frameTimeout}) => request({framePath, chain, timeout, frameTimeout, pick: {html: true}}),
rect: ({framePath, chain, timeout, frameTimeout}) => request({framePath, chain, timeout, frameTimeout, pick: {rect: true}})
};
// 暴露到当前脚本的沙箱(不是 page)
window.DQ = DQ;
try{ console.debug('[DQ Client] ready: use await DQ.get({...})'); }catch{}
})();