feat: clickable square rail buttons when collapsed + eye icon toggle in manage panel
This commit is contained in:
@@ -802,6 +802,25 @@ function syncSessionScope(list: any) {
|
||||
}
|
||||
}
|
||||
|
||||
/** 显示/隐藏切换图标:睁眼/闭眼同族 SVG(对称设计,符合可见性规范) */
|
||||
function EyeIcon(props: { closed: boolean }) {
|
||||
return (
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden>
|
||||
{props.closed ? (
|
||||
<>
|
||||
<path d="M1.8 8s2.6-3.1 6.2-3.1S14.2 8 14.2 8s-2.6 3.1-6.2 3.1S1.8 8 1.8 8Z" stroke="currentColor" strokeWidth="1.2" strokeLinejoin="round" />
|
||||
<path d="M3.6 8h8.8" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<path d="M1.8 8s2.6-3.1 6.2-3.1S14.2 8 14.2 8s-2.6 3.1-6.2 3.1S1.8 8 1.8 8Z" stroke="currentColor" strokeWidth="1.2" strokeLinejoin="round" />
|
||||
<circle cx="8" cy="8" r="1.7" fill="currentColor" />
|
||||
</>
|
||||
)}
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
/** 管理面板改名输入:本地草稿,blur/Enter 才提交(清空时不会立刻弹回原名) */
|
||||
function RenameInput(props: { initial: string; placeholder: string; onCommit: (v: string) => void }) {
|
||||
const [val, setVal] = useState(props.initial)
|
||||
@@ -2079,15 +2098,37 @@ function buildCustomLayoutPrompt(req: string): string {
|
||||
: 16
|
||||
const popTop = clamp(sectionTop, MIN_TOP, Math.max(MIN_TOP, window.innerHeight - 540))
|
||||
|
||||
/** 收起态点击项目图标:视图覆盖/布局 → openSplit;入驻无视图 → 切绑定对话 */
|
||||
const openRailProject = (id: string) => {
|
||||
const pr = projectsRef.current.projects
|
||||
const layout = pr.layouts.find((l) => l.id === id)
|
||||
const view = pr.views[id]
|
||||
if (view || layout) openSplit((view ?? layout) as LayoutSpec)
|
||||
else {
|
||||
const bound = pr.bindings[id]
|
||||
if (bound) { try { sessionBridge?.sessions?.open?.(bound) } catch {} }
|
||||
}
|
||||
}
|
||||
|
||||
if (!wide) {
|
||||
const projectIcons = aliveRegisteredIds.map((id) => projects.iconOverrides[id] ?? metas[id]?.icon ?? '📦')
|
||||
const shortcutIcons = projects.shortcuts.map((s) => s.icon)
|
||||
const layoutIcons = projects.layouts.map((l) => l.icon ?? '🧱')
|
||||
const icons = [...projectIcons, ...shortcutIcons, ...layoutIcons]
|
||||
const railNames = [
|
||||
...aliveRegisteredIds.map((id) => projects.nameOverrides[id] ?? metas[id]?.name ?? id),
|
||||
...projects.shortcuts.map((s) => s.name),
|
||||
...projects.layouts.map((l) => projects.nameOverrides[l.id] ?? l.title),
|
||||
// 收起态 = 等行高的正方形圆角按钮,中间只留 emoji;点击 = 进入对应项目
|
||||
const railItems: { icon: string; name: string; onClick: (e: any) => void }[] = [
|
||||
{ icon: CONSOLE_ICON, name: t('console.name'), onClick: (e) => clickConsoleCard(e.currentTarget as HTMLElement) },
|
||||
...aliveRegisteredIds.map((id) => ({
|
||||
icon: projects.iconOverrides[id] ?? metas[id]?.icon ?? '📦',
|
||||
name: projects.nameOverrides[id] ?? metas[id]?.name ?? id,
|
||||
onClick: () => openRailProject(id),
|
||||
})),
|
||||
...projects.shortcuts.map((s) => ({
|
||||
icon: s.icon,
|
||||
name: s.name,
|
||||
onClick: () => { try { window.open(s.href, '_blank', 'noopener') } catch {} },
|
||||
})),
|
||||
...projects.layouts.map((l) => ({
|
||||
icon: l.icon ?? '🧱',
|
||||
name: projects.nameOverrides[l.id] ?? l.title,
|
||||
onClick: () => openSplit(l),
|
||||
})),
|
||||
]
|
||||
// 浮动态:fixed 定位到拖前高度(左/宽取折叠列实测几何);停靠态:文档流原位
|
||||
const railStyle = isFloat && railRect
|
||||
@@ -2096,9 +2137,13 @@ function buildCustomLayoutPrompt(req: string): string {
|
||||
return (
|
||||
<div ref={rootRef} className="dsh-wt_section dsh-wt_rail" style={railStyle}>
|
||||
<div className="dsh-wt_divider" />
|
||||
<div className="dsh-wt_railBox" title={railNames.join(' · ') || t('rail.title')}>
|
||||
{icons.length > 0
|
||||
? icons.map((icon, i) => <span key={i} className="dsh-wt_railIcon">{icon}</span>)
|
||||
<div className="dsh-wt_railBox">
|
||||
{railItems.length > 0
|
||||
? railItems.map((it, i) => (
|
||||
<button key={i} type="button" className="dsh-wt_railBtn" title={it.name} aria-label={it.name} onClick={it.onClick}>
|
||||
<span aria-hidden>{it.icon}</span>
|
||||
</button>
|
||||
))
|
||||
: <span className="dsh-wt_railIcon">≡</span>}
|
||||
</div>
|
||||
</div>
|
||||
@@ -2302,7 +2347,7 @@ function buildCustomLayoutPrompt(req: string): string {
|
||||
>{projects.iconOverrides[id] ?? meta?.icon ?? '📦'}</span>}
|
||||
<RenameInput initial={display} placeholder={t('manage.renamePh')} onCommit={(v) => renameProject(id, v)} />
|
||||
<button type="button" className="dsh-wt_manageBtn" title={isHidden ? t('manage.show') : t('manage.hide')} onClick={() => toggleHidden(id)}>
|
||||
{isHidden ? '🙈' : '👁'}
|
||||
<EyeIcon closed={isHidden} />
|
||||
</button>
|
||||
<button type="button" className="dsh-wt_manageBtn" title={t('manage.changeView')} onClick={() => setViewPickFor(id)}>🧩</button>
|
||||
<button
|
||||
|
||||
@@ -8,7 +8,9 @@ export const css = xtermCss + '\n' + [
|
||||
'.dsh-wt_section{box-sizing:border-box;display:flex;flex-direction:column;gap:6px;width:100%;padding:0}',
|
||||
'.dsh-wt_float{min-width:176px;max-width:264px;background:var(--dsw-alias-bg-base,#0b0e14);border:1px solid var(--dsw-alias-border-l2,#3a4150);border-radius:10px;padding:8px;box-shadow:var(--dsw-shadow-lv2,0 8px 24px rgba(0,0,0,.4))}',
|
||||
'.dsh-wt_rail{pointer-events:none}',
|
||||
'.dsh-wt_railBox{display:flex;flex-wrap:wrap;gap:3px;justify-content:center;padding:5px 3px;border:1px solid var(--dsw-alias-border-l2,#3a4150);border-radius:8px;background:var(--dsw-alias-bg-base,#0b0e14)}',
|
||||
'.dsh-wt_railBox{display:flex;flex-wrap:wrap;gap:5px;justify-content:center;padding:5px 3px;border:1px solid var(--dsw-alias-border-l2,#3a4150);border-radius:8px;background:var(--dsw-alias-bg-base,#0b0e14)}',
|
||||
'.dsh-wt_railBtn{flex:none;width:22px;height:22px;padding:0;display:flex;align-items:center;justify-content:center;border:1px solid var(--dsw-alias-border-l1,#262b36);border-radius:7px;background:var(--dsw-alias-fill-l1,rgba(255,255,255,.03));color:var(--dsw-alias-label-secondary,#9aa4b2);font:inherit;font-size:13px;line-height:1;cursor:pointer;pointer-events:auto}',
|
||||
'.dsh-wt_railBtn:hover{background:var(--dsw-alias-fill-l1,rgba(255,255,255,.08));border-color:var(--dsw-alias-state-accent-primary,#4f8ef7);color:var(--dsw-alias-label-primary,#e6e8eb)}',
|
||||
'.dsh-wt_railIcon{font-size:17px;line-height:22px}',
|
||||
// 分隔线
|
||||
'.dsh-wt_divider{flex:none;height:1px;background:var(--dsw-alias-border-l1,#262b36);margin:2px 0}',
|
||||
|
||||
@@ -1403,3 +1403,21 @@
|
||||
- 验证(probe-batch16):panelSweepGone(面板 ::before content none)✓、sweepRuleFound
|
||||
(样式表含 .dsh-wt_consoleSweep)✓;functional-diag 全 20 STEP ERROR_COUNT: 0。
|
||||
- 备注:纯客户端改动,F5 即生效;本地 ahead 5 待补推。
|
||||
|
||||
## 补记(第十五轮:收起态方形按钮 + 管理面板眼睛图标)
|
||||
|
||||
- 用户需求(6 点前排队,本轮执行):① 侧边栏收起时,项目收缩成的小 emoji 不可点、间距
|
||||
太挤——改成「边长=行高的正方形圆角按钮(中间只留 emoji)」,点击 = 进入对应项目;
|
||||
② 管理面板隐藏/显示图标原来是捂脸猴 🙈 太不正式——换成对称的睁眼/闭眼 SVG 切换。
|
||||
- 实现:① !wide 分支重构:railItems 数组(控制室🖥️ + 入驻项目 + 快捷方式 + 布局,各带
|
||||
onClick)——控制室走 clickConsoleCard(未绑定弹强制绑定)、入驻走 openRailProject
|
||||
(视图/布局 openSplit,否则切绑定对话)、快捷方式 window.open、布局 openSplit;
|
||||
渲染为 .dsh-wt_railBtn(22×22、圆角 7px、pointer-events:auto——.dsh-wt_rail 容器
|
||||
原本 pointer-events:none,这是之前不可点的根因);railBox gap 3→5px。② EyeIcon 组件
|
||||
(12px SVG:睁眼=眼轮廓+瞳孔圆、闭眼=同轮廓+水平线),替换 manage 行 🙈/👁,title
|
||||
照旧 隐藏/显示 切换。
|
||||
- 验证(probe-batch17.cjs 新增):眼睛——hasSvg/monkeyGone ✓、点击隐藏(闭眼线/
|
||||
title=显示/rowOff/持久化)✓、再点恢复 ✓;收起态——宿主 hHd-Xa_toggle 收起后 rail
|
||||
4 个 22×22 按钮(btnRadius 7px、gap 5px、pointer auto)✓、点 🧪 打开 t-bind ✓、
|
||||
重新展开 rail 消失 ✓;functional-diag 全 20 STEP ERROR_COUNT: 0。
|
||||
- 备注:纯客户端改动,F5 即生效。
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
// probe-batch17.cjs — 收起态方形按钮(可点击进项目)+ 管理面板睁眼/闭眼切换
|
||||
const http = require('http');
|
||||
const { spawn } = require('child_process');
|
||||
const WebSocket = require('ws');
|
||||
const PORT = 9378;
|
||||
const proc = spawn('C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', [
|
||||
'--headless=new', '--disable-gpu', '--no-first-run', '--no-default-browser-check',
|
||||
'--window-size=1440,900', '--force-device-scale-factor=1',
|
||||
'--remote-debugging-port=' + PORT,
|
||||
'--user-data-dir=C:\\Users\\SJL\\AppData\\Local\\Temp\\wt-chrome-batch17',
|
||||
'about:blank',
|
||||
], { stdio: 'ignore' });
|
||||
const getJSON = (p) => new Promise((res, rej) => {
|
||||
http.get({ host: '127.0.0.1', port: PORT, path: p }, (r) => { let d=''; r.on('data',c=>d+=c); r.on('end',()=>{try{res(JSON.parse(d))}catch(e){rej(e)}}) }).on('error', rej);
|
||||
});
|
||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
(async () => {
|
||||
let list = null;
|
||||
for (let i = 0; i < 40; i++) { try { list = await getJSON('/json/list'); if (list && list.length) break; } catch {} await sleep(500); }
|
||||
const target = list.find((t) => t.type === 'page') || list[0];
|
||||
const ws = new WebSocket(target.webSocketDebuggerUrl);
|
||||
let id = 0; const pending = new Map();
|
||||
const send = (method, params) => new Promise((res) => { const mid = ++id; pending.set(mid, res); ws.send(JSON.stringify({ id: mid, method, params })); });
|
||||
ws.on('message', (raw) => { const m = JSON.parse(String(raw)); if (m.id && pending.has(m.id)) { pending.get(m.id)(m); pending.delete(m.id); } });
|
||||
await new Promise((r) => ws.on('open', r));
|
||||
await send('Runtime.enable');
|
||||
await send('Page.enable');
|
||||
await send('Page.addScriptToEvaluateOnNewDocument', {
|
||||
source: "try{ if(location.origin==='http://127.0.0.1:3080'){ localStorage.setItem('dsh.worktable.view.v1', JSON.stringify({query:'',searchOpen:false,orderBy:'manual',dock:'footer',floatTop:null,sortMigratedV2:true})); localStorage.setItem('dsh.worktable.projects.v1', JSON.stringify({order:['t-bind'],lastUsed:{},hidden:[],nameOverrides:{},iconOverrides:{},shortcuts:[],layouts:[{id:'t-bind',title:'\u7ed1\u5b9a\u6d4b\u8bd5',icon:'\ud83e\uddea',top:null,left:null,main:[{id:'p1',title:'\u5185\u5bb91',min:200,content:null,tabs:[],active:0}],leftWidth:{default:260,min:160,max:480},chatWidth:{default:360,min:240,max:600},topHeight:{default:200,min:120,max:480},chatSide:'right',chatFullHeight:false}],bindings:{},folders:{},views:{},removed:[]})); } }catch(e){}",
|
||||
});
|
||||
await send('Page.navigate', { url: 'http://127.0.0.1:3080/' });
|
||||
const evaluate = async (expr) => {
|
||||
const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true, awaitPromise: true });
|
||||
if (r.result && r.result.exceptionDetails) return { __error: (r.result.exceptionDetails.exception || {}).description || r.result.exceptionDetails.text };
|
||||
return r.result && r.result.result ? r.result.result.value : undefined;
|
||||
};
|
||||
let ready = null;
|
||||
for (let i = 0; i < 30; i++) { await sleep(1000); ready = await evaluate("!!window.__dshWorktable"); if (ready === true) break; }
|
||||
await sleep(1500);
|
||||
await evaluate("(function(){ var b=document.querySelector('button[title=\"Open sidebar\"],button[aria-label=\"Open sidebar\"]'); if(b){b.click(); return true} return false })()");
|
||||
await sleep(1000);
|
||||
const out = await evaluate(`(async function(){
|
||||
var out = {};
|
||||
var sleep = function(ms){ return new Promise(function(r){ setTimeout(r, ms); }); };
|
||||
var vis = function(sel){ return [].slice.call(document.querySelectorAll(sel)).find(function(el){ return (getComputedStyle(el).visibility!=='hidden'&&el.getBoundingClientRect().height>0); }); };
|
||||
var st = window.__dshWorktable.splitStore;
|
||||
try {
|
||||
// A. 管理面板眼睛图标
|
||||
var btnS = document.querySelector('.dsh-wt_actions .dsh-wt_iconBtn:nth-child(2)');
|
||||
if (btnS) { btnS.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
|
||||
await sleep(400);
|
||||
var rows = document.querySelectorAll('.dsh-wt_settings .dsh-wt_manageRow');
|
||||
out.manageRows = rows.length;
|
||||
var row0 = rows[0];
|
||||
var hideBtn = row0 && [].slice.call(row0.querySelectorAll('.dsh-wt_manageBtn')).find(function(b){ var t = b.title || ''; return t.indexOf('显示') >= 0 || t.indexOf('隐藏') >= 0; });
|
||||
out.hideBtnFound = !!hideBtn;
|
||||
out.hasSvg = !!(hideBtn && hideBtn.querySelector('svg'));
|
||||
out.monkeyGone = !!(hideBtn && (hideBtn.textContent || '').indexOf('🙈') < 0);
|
||||
var titleBefore = hideBtn ? hideBtn.title : null;
|
||||
out.titleBefore = titleBefore;
|
||||
// 点击 → 隐藏(闭眼)
|
||||
if (hideBtn) { hideBtn.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
|
||||
await sleep(400);
|
||||
var j = JSON.parse(localStorage.getItem('dsh.worktable.projects.v1'));
|
||||
out.hiddenAfter = j.hidden;
|
||||
out.row0OffAfter = row0.classList.contains('dsh-wt_manageRowOff');
|
||||
var hideBtn2 = row0 && [].slice.call(row0.querySelectorAll('.dsh-wt_manageBtn')).find(function(b){ var t = b.title || ''; return t.indexOf('显示') >= 0 || t.indexOf('隐藏') >= 0; });
|
||||
out.titleAfter = hideBtn2 ? hideBtn2.title : null;
|
||||
var svgClosed = hideBtn2 && hideBtn2.querySelector('svg');
|
||||
out.closedHasLine = !!(svgClosed && svgClosed.querySelector('path[d*=\"3.6 8\"]'));
|
||||
// 再点 → 显示(睁眼)
|
||||
if (hideBtn2) { hideBtn2.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
|
||||
await sleep(400);
|
||||
var j2 = JSON.parse(localStorage.getItem('dsh.worktable.projects.v1'));
|
||||
out.hiddenRestored = !(j2.hidden && j2.hidden.length);
|
||||
var done = document.querySelector('.dsh-wt_manageDone');
|
||||
if (done) { done.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
|
||||
await sleep(300);
|
||||
// B. 收起侧栏 → 方形按钮
|
||||
var collapseBtn = document.querySelector('button.hHd-Xa_toggle');
|
||||
out.collapseFound = !!collapseBtn;
|
||||
if (collapseBtn) { collapseBtn.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
|
||||
await sleep(800);
|
||||
var rail = vis('.dsh-wt_rail');
|
||||
out.railShown = !!rail;
|
||||
var btns = document.querySelectorAll('.dsh-wt_railBtn');
|
||||
out.railBtnCount = btns.length;
|
||||
var b0 = btns[0];
|
||||
if (b0) {
|
||||
var br = b0.getBoundingClientRect();
|
||||
out.btnW = Math.round(br.width);
|
||||
out.btnH = Math.round(br.height);
|
||||
out.btn0Text = b0.textContent;
|
||||
out.btnRadius = getComputedStyle(b0).borderRadius;
|
||||
var box = b0.parentElement;
|
||||
out.boxGap = getComputedStyle(box).columnGap;
|
||||
out.btnPointer = getComputedStyle(b0).pointerEvents;
|
||||
}
|
||||
// 点击 t-bind 布局按钮(icon 🧪)→ 打开该项目
|
||||
var layoutBtn = [].slice.call(btns).find(function(b){ return b.textContent === '🧪'; });
|
||||
out.layoutBtnFound = !!layoutBtn;
|
||||
if (layoutBtn) { layoutBtn.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
|
||||
await sleep(900);
|
||||
out.specAfterRailClick = st.active && st.spec ? st.spec.id : null;
|
||||
st.close(); await sleep(300);
|
||||
// 重新展开侧栏(同一 hHd-Xa_toggle 按钮标题翻转)
|
||||
var expandBtn = document.querySelector('button.hHd-Xa_toggle');
|
||||
if (expandBtn) { expandBtn.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
|
||||
await sleep(800);
|
||||
out.railGoneAfterExpand = !vis('.dsh-wt_rail');
|
||||
} catch (e) { out.err = String(e && e.stack || e); }
|
||||
return out;
|
||||
})()`);
|
||||
console.log('RESULT ' + JSON.stringify(out));
|
||||
try { ws.close(); } catch {}
|
||||
proc.kill();
|
||||
})().catch((e) => { console.error('PROBE FAIL', e); try { proc.kill(); } catch {} });
|
||||
@@ -0,0 +1,59 @@
|
||||
// rail-toggle-probe.cjs — 找宿主侧栏收起按钮
|
||||
const http = require('http');
|
||||
const { spawn } = require('child_process');
|
||||
const WebSocket = require('ws');
|
||||
const PORT = 9379;
|
||||
const proc = spawn('C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', [
|
||||
'--headless=new', '--disable-gpu', '--no-first-run', '--no-default-browser-check',
|
||||
'--window-size=1440,900', '--force-device-scale-factor=1',
|
||||
'--remote-debugging-port=' + PORT,
|
||||
'--user-data-dir=C:\\Users\\SJL\\AppData\\Local\\Temp\\wt-chrome-rail1',
|
||||
'about:blank',
|
||||
], { stdio: 'ignore' });
|
||||
const getJSON = (p) => new Promise((res, rej) => {
|
||||
http.get({ host: '127.0.0.1', port: PORT, path: p }, (r) => { let d=''; r.on('data',c=>d+=c); r.on('end',()=>{try{res(JSON.parse(d))}catch(e){rej(e)}}) }).on('error', rej);
|
||||
});
|
||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
(async () => {
|
||||
let list = null;
|
||||
for (let i = 0; i < 40; i++) { try { list = await getJSON('/json/list'); if (list && list.length) break; } catch {} await sleep(500); }
|
||||
const target = list.find((t) => t.type === 'page') || list[0];
|
||||
const ws = new WebSocket(target.webSocketDebuggerUrl);
|
||||
let id = 0; const pending = new Map();
|
||||
const send = (method, params) => new Promise((res) => { const mid = ++id; pending.set(mid, res); ws.send(JSON.stringify({ id: mid, method, params })); });
|
||||
ws.on('message', (raw) => { const m = JSON.parse(String(raw)); if (m.id && pending.has(m.id)) { pending.get(m.id)(m); pending.delete(m.id); } });
|
||||
await new Promise((r) => ws.on('open', r));
|
||||
await send('Runtime.enable');
|
||||
await send('Page.enable');
|
||||
await send('Page.navigate', { url: 'http://127.0.0.1:3080/' });
|
||||
const evaluate = async (expr) => {
|
||||
const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true, awaitPromise: true });
|
||||
if (r.result && r.result.exceptionDetails) return { __error: (r.result.exceptionDetails.exception || {}).description || r.result.exceptionDetails.text };
|
||||
return r.result && r.result.result ? r.result.result.value : undefined;
|
||||
};
|
||||
let ready = null;
|
||||
for (let i = 0; i < 30; i++) { await sleep(1000); ready = await evaluate("!!window.__dshWorktable"); if (ready === true) break; }
|
||||
await sleep(1500);
|
||||
const out = await evaluate(`(function(){
|
||||
var out = {};
|
||||
var btns = [].slice.call(document.querySelectorAll('button'));
|
||||
// 收集所有带 title/aria 的按钮(去重),找疑似侧栏开关
|
||||
var cand = [];
|
||||
btns.forEach(function(b, i){
|
||||
var t = b.title || b.getAttribute('aria-label') || '';
|
||||
var cls = String(b.className || '');
|
||||
var r = b.getBoundingClientRect();
|
||||
if (r.width > 0 && (t || /side|collapse|rail|panel|bar/i.test(cls))) {
|
||||
cand.push({ t: t.slice(0,40), cls: cls.slice(0,60), w: Math.round(r.width), x: Math.round(r.left), y: Math.round(r.top) });
|
||||
}
|
||||
});
|
||||
out.candidates = cand.slice(0, 25);
|
||||
// 侧栏列内最顶部的按钮
|
||||
var col = document.querySelector('.pI_x6G_sidebarCol') || document.querySelector('[class*=sidebarCol]');
|
||||
out.sidebarColFound = !!col;
|
||||
return out;
|
||||
})()`);
|
||||
console.log('RESULT ' + JSON.stringify(out));
|
||||
try { ws.close(); } catch {}
|
||||
proc.kill();
|
||||
})().catch((e) => { console.error('PROBE FAIL', e); try { proc.kill(); } catch {} });
|
||||
Reference in New Issue
Block a user