typedef WebCanGoBack = Future Function(); typedef WebGoBack = Future Function(); typedef WebRunJavaScriptReturningResult = Future Function(String code); const visibleWebBackControlJavaScript = r''' (() => { const selectors = [ '.back-btn', '[aria-label="返回"]', '[aria-label="Back"]', '[title="返回"]', '[title="Back"]', ].join(','); const candidates = Array.from(document.querySelectorAll(selectors)); const control = candidates.find((element) => { const rect = element.getBoundingClientRect(); const style = window.getComputedStyle(element); if ( rect.width <= 0 || rect.height <= 0 || rect.bottom <= 0 || rect.right <= 0 || rect.top >= window.innerHeight || rect.left >= window.innerWidth || style.display === 'none' || style.visibility === 'hidden' || style.pointerEvents === 'none' || Number(style.opacity || 1) <= 0 ) return false; const x = Math.min(Math.max(rect.left + rect.width / 2, 0), window.innerWidth - 1); const y = Math.min(Math.max(rect.top + rect.height / 2, 0), window.innerHeight - 1); const topElement = document.elementFromPoint(x, y); return topElement !== null && (topElement === element || element.contains(topElement)); }); if (!control) return false; control.click(); return true; })() '''; Future tryGoBackInWebHistory({ required WebCanGoBack canGoBack, required WebGoBack goBack, }) async { if (!await canGoBack()) return false; await goBack(); return true; } Future tryGoBackUsingVisibleWebControl({ required WebRunJavaScriptReturningResult runJavaScriptReturningResult, }) async { final result = await runJavaScriptReturningResult( visibleWebBackControlJavaScript, ); if (result is bool) return result; return result.toString().replaceAll('"', '').trim().toLowerCase() == 'true'; }