()
| 301 | } |
| 302 | |
| 303 | function findRefreshButton() { |
| 304 | const selectors = [ |
| 305 | 'div[role="button"][data-tooltip="刷新"]', |
| 306 | 'div[role="button"][aria-label="刷新"]', |
| 307 | 'div[role="button"][data-tooltip*="刷新"]', |
| 308 | 'div[role="button"][aria-label*="刷新"]', |
| 309 | 'div[role="button"][data-tooltip="Refresh"]', |
| 310 | 'div[role="button"][aria-label="Refresh"]', |
| 311 | 'div[role="button"][data-tooltip*="Refresh"]', |
| 312 | 'div[role="button"][aria-label*="Refresh"]', |
| 313 | 'div[act="20"][role="button"]', |
| 314 | 'div.asf.T-I-J3.J-J5-Ji', |
| 315 | ]; |
| 316 | |
| 317 | for (const selector of selectors) { |
| 318 | const matched = document.querySelector(selector); |
| 319 | const button = matched?.closest?.('[role="button"]') || matched; |
| 320 | if (button && isVisibleElement(button)) { |
| 321 | return button; |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | return Array.from(document.querySelectorAll('div[role="button"], button')).find((element) => { |
| 326 | const text = normalizeText( |
| 327 | element.getAttribute('aria-label') |
| 328 | || element.getAttribute('data-tooltip') |
| 329 | || element.getAttribute('title') |
| 330 | || element.textContent |
| 331 | ); |
| 332 | return /刷新|Refresh/i.test(text); |
| 333 | }) || null; |
| 334 | } |
| 335 | |
| 336 | function collectThreadRows() { |
| 337 | const candidates = [ |
no test coverage detected