From bda8bb557087de8af8fdf1142d030fddd4d2d805 Mon Sep 17 00:00:00 2001 From: WoNiu Date: Mon, 1 Apr 2024 21:41:42 +0800 Subject: [PATCH] =?UTF-8?q?windows=20=E5=88=9D=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/main.dart | 6 +- lib/main_page.dart | 290 ++++++++++++++--------------- lib/web_widget.dart | 84 ++++----- lib/windows/windowsJs.dart | 56 ++++++ lib/windows/windows_main_page.dart | 82 ++++---- lib/windows/windows_web_page.dart | 2 +- pubspec.yaml | 5 +- 7 files changed, 299 insertions(+), 226 deletions(-) create mode 100644 lib/windows/windowsJs.dart diff --git a/lib/main.dart b/lib/main.dart index 25ed56b..28cf15e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:web_synchronization_tool/main_page.dart'; import 'package:web_synchronization_tool/windows/windows_main_page.dart'; +import 'package:webview_windows/webview_windows.dart'; void main() async { @@ -22,8 +22,8 @@ class MyApp extends StatelessWidget { colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), - home: const MainPage(), - // home: const WindowsPage(), + // home: const MainPage(), + home: const WindowsPage(), ); } } diff --git a/lib/main_page.dart b/lib/main_page.dart index c55c756..7274962 100644 --- a/lib/main_page.dart +++ b/lib/main_page.dart @@ -1,145 +1,145 @@ - -import 'package:flutter/material.dart'; -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; -import 'package:web_synchronization_tool/web_widget.dart'; - -import 'JavaScriptString.dart'; - -class MainPage extends StatefulWidget { - const MainPage({super.key}); - - @override - State createState() => _MainPageState(); -} - -class _MainPageState extends State { - - late InAppWebViewController mainController; - late InAppWebViewController controller; - - bool asyncState = false; - - @override - void initState() { - super.initState(); - - } - - @override - void dispose() { - super.dispose(); - - WebStorageManager.instance().deleteAllData(); - } - - /// 注入触摸监听 - addTouchendEventJS(){ - - final clickJsUS = UserScript(groupName: 'touchend',source: JavaScriptString.touchendEventJSString, injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START); - mainController.addUserScript(userScript: clickJsUS); - - mainController.addJavaScriptHandler(handlerName: 'touchend', callback: (args){ - if (asyncState){ - int x = double.parse(args.first.toString()).toInt(); - int y = double.parse(args.last.toString()).toInt(); - controller.evaluateJavascript(source: JavaScriptString.clickJSString(x, y) ); - // controller.evaluateJavascript(source: JavaScriptString.touchendJsString(x, y) ); - // controller.evaluateJavascript(source: JavaScriptString.getClassTouchendJsString(x, y) ); - } - }); - - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Container( - height: 50, - color: Colors.white, - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Row( - children: [ - TextButton( - onPressed: () { - controller.evaluateJavascript(source: JavaScriptString.clickJSString(50, 100) ); - }, - child: const Text('模拟点击测试')), - TextButton( - onPressed: () { - mainController.evaluateJavascript(source: JavaScriptString.inputJsString(45) ); - controller.evaluateJavascript(source: JavaScriptString.inputJsString(45) ); - }, - child: const Text('模拟输入测试')), - Row( - children: [ - const Text('同步'), - Switch(value: asyncState, onChanged: (value){ - setState(() { - asyncState = value; - }); - }) - ], - ) - ], - ), - ), - Expanded(child: pageViewWidget()), - ], - ), - ); - } - - Widget pageViewWidget() { - return Row( - children: [ - Expanded( - child: Container( - color: Colors.yellow, - child: KeepAlivePage( - child: WebWidget(controlerCallBack: (_mainController) { - mainController = _mainController; - - addTouchendEventJS(); - - }), - ), - ), - ), - Expanded( - child: Container( - color: Colors.blue, - child: KeepAlivePage( - child: WebWidget(controlerCallBack: (_controller) { - controller = _controller; - }), - ), - ), - ) - ], - ); - } - -} - -class KeepAlivePage extends StatefulWidget { - final Widget child; - - KeepAlivePage({super.key , required this.child}); - - @override - _KeepAlivePageState createState() => _KeepAlivePageState(); -} - -class _KeepAlivePageState extends State with AutomaticKeepAliveClientMixin { - @override - bool get wantKeepAlive => true; - - @override - Widget build(BuildContext context) { - super.build(context); - return widget.child; - } -} +// +// import 'package:flutter/material.dart'; +// import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +// import 'package:web_synchronization_tool/web_widget.dart'; +// +// import 'JavaScriptString.dart'; +// +// class MainPage extends StatefulWidget { +// const MainPage({super.key}); +// +// @override +// State createState() => _MainPageState(); +// } +// +// class _MainPageState extends State { +// +// late InAppWebViewController mainController; +// late InAppWebViewController controller; +// +// bool asyncState = false; +// +// @override +// void initState() { +// super.initState(); +// +// } +// +// @override +// void dispose() { +// super.dispose(); +// +// WebStorageManager.instance().deleteAllData(); +// } +// +// /// 注入触摸监听 +// addTouchendEventJS(){ +// +// final clickJsUS = UserScript(groupName: 'touchend',source: JavaScriptString.touchendEventJSString, injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START); +// mainController.addUserScript(userScript: clickJsUS); +// +// mainController.addJavaScriptHandler(handlerName: 'touchend', callback: (args){ +// if (asyncState){ +// int x = double.parse(args.first.toString()).toInt(); +// int y = double.parse(args.last.toString()).toInt(); +// controller.evaluateJavascript(source: JavaScriptString.clickJSString(x, y) ); +// // controller.evaluateJavascript(source: JavaScriptString.touchendJsString(x, y) ); +// // controller.evaluateJavascript(source: JavaScriptString.getClassTouchendJsString(x, y) ); +// } +// }); +// +// } +// +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// body: Column( +// crossAxisAlignment: CrossAxisAlignment.stretch, +// children: [ +// Container( +// height: 50, +// color: Colors.white, +// padding: const EdgeInsets.symmetric(horizontal: 50), +// child: Row( +// children: [ +// TextButton( +// onPressed: () { +// controller.evaluateJavascript(source: JavaScriptString.clickJSString(50, 100) ); +// }, +// child: const Text('模拟点击测试')), +// TextButton( +// onPressed: () { +// mainController.evaluateJavascript(source: JavaScriptString.inputJsString(45) ); +// controller.evaluateJavascript(source: JavaScriptString.inputJsString(45) ); +// }, +// child: const Text('模拟输入测试')), +// Row( +// children: [ +// const Text('同步'), +// Switch(value: asyncState, onChanged: (value){ +// setState(() { +// asyncState = value; +// }); +// }) +// ], +// ) +// ], +// ), +// ), +// Expanded(child: pageViewWidget()), +// ], +// ), +// ); +// } +// +// Widget pageViewWidget() { +// return Row( +// children: [ +// Expanded( +// child: Container( +// color: Colors.yellow, +// child: KeepAlivePage( +// child: WebWidget(controlerCallBack: (_mainController) { +// mainController = _mainController; +// +// addTouchendEventJS(); +// +// }), +// ), +// ), +// ), +// Expanded( +// child: Container( +// color: Colors.blue, +// child: KeepAlivePage( +// child: WebWidget(controlerCallBack: (_controller) { +// controller = _controller; +// }), +// ), +// ), +// ) +// ], +// ); +// } +// +// } +// +// class KeepAlivePage extends StatefulWidget { +// final Widget child; +// +// KeepAlivePage({super.key , required this.child}); +// +// @override +// _KeepAlivePageState createState() => _KeepAlivePageState(); +// } +// +// class _KeepAlivePageState extends State with AutomaticKeepAliveClientMixin { +// @override +// bool get wantKeepAlive => true; +// +// @override +// Widget build(BuildContext context) { +// super.build(context); +// return widget.child; +// } +// } diff --git a/lib/web_widget.dart b/lib/web_widget.dart index 3c5f0d9..66d6800 100644 --- a/lib/web_widget.dart +++ b/lib/web_widget.dart @@ -1,42 +1,42 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; -import 'package:web_synchronization_tool/JavaScriptString.dart'; - -class WebWidget extends StatefulWidget { - WebWidget({super.key, required this.controlerCallBack}); - - final Function(InAppWebViewController) controlerCallBack; - - @override - State createState() => _WebWidgetState(); -} - -class _WebWidgetState extends State { - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - return InAppWebView( - initialUrlRequest: - URLRequest(url: WebUri('http://www.df6831.com')), - initialSettings: InAppWebViewSettings( - initialScale: 180, - loadWithOverviewMode: false, - useWideViewPort: false, - preferredContentMode: UserPreferredContentMode.MOBILE, - cacheEnabled: false, //启用缓存 - clearSessionCache: true,//清除会话缓存 - databaseEnabled:false, // 启用数据库 - domStorageEnabled: false,//启用 dom 存储 - incognito: true, //隐身模式 - sharedCookiesEnabled: false, // 共享Cookie - ), - onWebViewCreated: (_controller) { - widget.controlerCallBack(_controller); - }, - ); - } -} +// import 'package:flutter/material.dart'; +// import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +// import 'package:web_synchronization_tool/JavaScriptString.dart'; +// +// class WebWidget extends StatefulWidget { +// WebWidget({super.key, required this.controlerCallBack}); +// +// final Function(InAppWebViewController) controlerCallBack; +// +// @override +// State createState() => _WebWidgetState(); +// } +// +// class _WebWidgetState extends State { +// @override +// void initState() { +// super.initState(); +// } +// +// @override +// Widget build(BuildContext context) { +// return InAppWebView( +// initialUrlRequest: +// URLRequest(url: WebUri('http://www.df6831.com/mobile')),// +// initialSettings: InAppWebViewSettings( +// // initialScale: 180, +// loadWithOverviewMode: false, +// useWideViewPort: false, +// // preferredContentMode: UserPreferredContentMode.MOBILE, +// // cacheEnabled: false, //启用缓存 +// // clearSessionCache: true,//清除会话缓存 +// // databaseEnabled:false, // 启用数据库 +// // domStorageEnabled: false,//启用 dom 存储 +// incognito: true, //隐身模式 +// sharedCookiesEnabled: false, // 共享Cookie +// ), +// onWebViewCreated: (_controller) { +// widget.controlerCallBack(_controller); +// }, +// ); +// } +// } diff --git a/lib/windows/windowsJs.dart b/lib/windows/windowsJs.dart new file mode 100644 index 0000000..3adde9b --- /dev/null +++ b/lib/windows/windowsJs.dart @@ -0,0 +1,56 @@ +class WindowsJs { + /// 点击监听 + static String clickEventJs = ''' + document.addEventListener('click', function(event) { + var x = event.clientX; + var y = event.clientY; + + var value = {"x":x,"y":y}; + window.chrome.webview.postMessage(value); + + // 检查点击的元素是否有类名为 'btn' + if (event.target.classList.contains('btn')) { + // 获取按钮上显示的文本内容 + var buttonText = event.target.innerText; + + var btn = {"x":"成功获取到btn","y":buttonText}; + window.chrome.webview.postMessage(btn); + + // 阻止默认的链接跳转行为 + event.preventDefault(); + + // 在当前窗口打开目标地址 + window.location.href = "http://www.df6831.com/game/"; + + } + + });'''; + + /// 模拟点击 + static String clickJs(int x, int y) { + return 'document.elementFromPoint($x, $y).click();'; + } + + /// 输入 + static String inputJsString(int value) { + return ''' + var inputEvent = new Event('input', { + bubbles: true, + cancelable: true, + }); + var inputElement = document.querySelector(".input"); + inputElement.value = "$value"; + inputElement.dispatchEvent(inputEvent); + '''; + } + + static String zoom(int zoom){ + assert(zoom >= 1 && zoom <= 100, 'zoom 1 到 100'); + return ''' + // document.body.style.zoom = "$zoom%"; + document.body.style.transformOrigin = 'top left'; + document.body.style.transform = 'scale(${zoom / 100})'; + '''; + } + +} diff --git a/lib/windows/windows_main_page.dart b/lib/windows/windows_main_page.dart index 58448e2..8e72dad 100644 --- a/lib/windows/windows_main_page.dart +++ b/lib/windows/windows_main_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:web_synchronization_tool/windows/windowsJs.dart'; import 'windows_web_page.dart'; import 'package:webview_windows/webview_windows.dart'; @@ -25,6 +26,7 @@ class _WindowsPageState extends State { } Future controllerInit() async { + await mainController.initialize(); await controller.initialize(); @@ -33,7 +35,6 @@ class _WindowsPageState extends State { controller.clearCache(); controller.clearCookies(); - mainController.loadUrl('http://www.df6831.com/'); controller.loadUrl('http://www.df6831.com/'); @@ -42,22 +43,27 @@ class _WindowsPageState extends State { setState(() { initDone = true; }); + + // controller.setUserAgent('Mobile'); + + /// 通道消息 + mainController.webMessage.listen((event) { + print('mainController listen -- $event'); + controller.executeScript(WindowsJs.clickJs(event['x'], event['y'])); + }); + + /// 通道消息 + controller.webMessage.listen((event) { + // print('controller listen -- $event'); + }); + + } /// 注入点击监听 addClickEventJS() { - - controller.executeScript('document.documentElement.innerHTML').then((value){ - print(value); - }); - - mainController.addScriptToExecuteOnDocumentCreated( - JavaScriptString.clickEventJSString).then((value){ - print(value); - }); - - - + mainController.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs); + controller.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs); } @override @@ -75,33 +81,39 @@ class _WindowsPageState extends State { children: [ TextButton( onPressed: () { - controller.executeScript( - JavaScriptString.clickJSString(600, 280)).then((value){ - print(value); - }); + mainController.executeScript(WindowsJs.clickJs(200, 900)); + // controller.executeScript(WindowsJs.clickJs(600, 100)); }, child: const Text('模拟点击测试')), TextButton( onPressed: () { - mainController - .executeScript(JavaScriptString.inputJsString(45)); - controller - .executeScript(JavaScriptString.inputJsString(45)); + mainController.executeScript(WindowsJs.inputJsString(45)); + controller.executeScript(WindowsJs.inputJsString(45)); }, child: const Text('模拟输入测试')), TextButton( onPressed: () { - mainController.loadUrl('http://www.df6831.com/game/'); - // controller.loadUrl('http://www.df6831.com/game/'); + mainController.loadUrl('http://www.df6831.com/'); }, - child: const Text('跳转')), - const SizedBox( - width: 50, - child: TextField( - keyboardType: TextInputType.number, - decoration: InputDecoration(prefixText: '网页数量'), - ), - ) + child: const Text('跳转首页')), + TextButton( + onPressed: () { + mainController.executeScript(WindowsJs.zoom(70)); + controller.executeScript(WindowsJs.zoom(40)); + }, + child: const Text('缩放')), + TextButton( + onPressed: () { + mainController.openDevTools(); + }, + child: const Text('开发者')), + TextButton( + onPressed: () { + mainController.clearCookies(); + mainController.clearCache(); + }, + child: const Text('清除缓存')), + ], ), ), @@ -115,12 +127,16 @@ class _WindowsPageState extends State { Widget pageViewWidget() { return Row( children: [ - Expanded( + SizedBox( + width: 1000, + height: 1000, child: WindowsWebWidget( controller: mainController, ), ), - Expanded( + SizedBox( + width: 500, + height:400, child: WindowsWebWidget( controller: controller, ), diff --git a/lib/windows/windows_web_page.dart b/lib/windows/windows_web_page.dart index 542073f..5d2c963 100644 --- a/lib/windows/windows_web_page.dart +++ b/lib/windows/windows_web_page.dart @@ -21,7 +21,7 @@ class _WindowsWebWidgetState extends State { } Widget inWindowsWebView(){ - return Webview(widget.controller,); + return Webview(widget.controller); } } diff --git a/pubspec.yaml b/pubspec.yaml index c3f52cd..6385e4e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,8 +12,9 @@ dependencies: sdk: flutter cupertino_icons: ^1.0.2 - flutter_inappwebview: ^6.0.0 - webview_windows: ^0.4.0 + webview_windows: + path: ../flutter-webview-windows-main + window_manager: dev_dependencies: flutter_test: