Compare commits

..

2 Commits

Author SHA1 Message Date
WoNiu bda8bb5570 windows 初版 2024-04-01 21:41:42 +08:00
WoNiu 87b3157e14 网页 手机端 初版 2024-03-31 20:15:43 +08:00
8 changed files with 388 additions and 189 deletions

View File

@ -1,20 +1,102 @@
class JavaScriptString { class JavaScriptString {
/// ///
static String clickEventkJSString = static String clickEventJSString =
'''document.addEventListener('click', function(event) { '''document.addEventListener('click', function(event) {
var x = event.clientX; var x = event.clientX;
var y = event.clientY; var y = event.clientY;
console.log('点击坐标x=' + x + ', y=' + y); console.log('点击坐标x=' + x + ', y=' + y);
window.flutter_inappwebview.callHandler('Click', x, y); window.flutter_inappwebview.callHandler('click', x, y);
});'''; });''';
///
static String touchendEventJSString =
'''document.addEventListener('touchend', function(event) {
var x = event.changedTouches[0].clientX;
var y = event.changedTouches[0].clientY;
//
var target = event.target;
// class和id
var targetClass = target.className;
var targetId = target.id;
console.log('Class: ' + targetClass);
console.log('Id: ' + targetId);
console.log('触摸坐标x=' + x + ', y=' + y);
window.flutter_inappwebview.callHandler('touchend', x, y);
});''';
/// 退
static String loginOutJsString = '''
\$.ajax({
type: "GET",
url: "/api/logout.do",
success: function(t) {
"index.html" != location.pathname ? window.location.href = "index.html" : location.reload()
},
error: function(t) {
var e = \$.parseJSON(t.responseText + "");
alert(e.msg, 2)
}
})
''';
/// ///
static String clickJSString(int x, int y) { static String clickJSString(int x, int y) {
return 'document.elementFromPoint($x, $y).click();'; return 'document.elementFromPoint($x, $y).click();';
} }
///
static String touchendJsString(int x, int y) {
return '''
''';
}
///
static String getClassTouchendJsString(int x, int y) {
return '''
try{
//
var x = $x;
var y = $y;
// touchstart事件
var touchstartEvent = new TouchEvent('touchstart', {
bubbles: true,
cancelable: true,
view: window,
changedTouches: [new Touch({ identifier: Date.now(), target: document.body, clientX: x, clientY: y })],
targetTouches: [new Touch({ identifier: Date.now(), target: document.body, clientX: x, clientY: y })]
});
// touchstartEvent
document.body.dispatchEvent(touchstartEvent);
// touchend事件
var touchendEvent = new TouchEvent('touchend', {
bubbles: true,
cancelable: true,
view: window,
changedTouches: [new Touch({ identifier: Date.now(), target: document.body, clientX: x, clientY: y })],
targetTouches: [new Touch({ identifier: Date.now(), target: document.body, clientX: x, clientY: y })]
});
// touchend事件
document.body.dispatchEvent(touchendEvent);
} catch (t) {
console.log('模拟触摸错误 -- ' + t);
}
''';
}
/// ///
static String inputJsString(int value) { static String inputJsString(int value) {
return ''' return '''
@ -24,7 +106,7 @@ var inputEvent = new Event('input', {
cancelable: true, cancelable: true,
}); });
var inputElement = document.querySelector(".bet-money"); var inputElement = document.querySelector(".input");
inputElement.value = "$value"; inputElement.value = "$value";

View File

@ -1,8 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:web_synchronization_tool/main_page.dart'; import 'package:web_synchronization_tool/main_page.dart';
import 'package:web_synchronization_tool/windows/windows_main_page.dart'; import 'package:web_synchronization_tool/windows/windows_main_page.dart';
import 'package:webview_windows/webview_windows.dart';
void main() async {
// await InAppWebViewController.setWebContentsDebuggingEnabled(true);
void main() {
runApp(const MyApp()); runApp(const MyApp());
} }
@ -18,8 +22,8 @@ class MyApp extends StatelessWidget {
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true, useMaterial3: true,
), ),
home: const MainPage(), // home: const MainPage(),
// home: const WindowsPage(), home: const WindowsPage(),
); );
} }
} }

View File

@ -1,116 +1,145 @@
import 'package:flutter/material.dart'; //
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; // import 'package:flutter/material.dart';
import 'package:web_synchronization_tool/web_widget.dart'; // import 'package:flutter_inappwebview/flutter_inappwebview.dart';
// import 'package:web_synchronization_tool/web_widget.dart';
import 'JavaScriptString.dart'; //
// import 'JavaScriptString.dart';
class MainPage extends StatefulWidget { //
const MainPage({super.key}); // class MainPage extends StatefulWidget {
// const MainPage({super.key});
@override //
State<MainPage> createState() => _MainPageState(); // @override
} // State<MainPage> createState() => _MainPageState();
// }
class _MainPageState extends State<MainPage> { //
// class _MainPageState extends State<MainPage> {
late InAppWebViewController mainController; //
late InAppWebViewController controller; // late InAppWebViewController mainController;
// late InAppWebViewController controller;
@override //
void initState() { // bool asyncState = false;
super.initState(); //
// @override
// void initState() {
} // super.initState();
//
/// // }
addClickEventJS(){ //
// @override
final clickJsUS = UserScript(groupName: 'click',source: JavaScriptString.clickEventkJSString, injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START); // void dispose() {
// super.dispose();
mainController.addUserScript(userScript: clickJsUS); //
// WebStorageManager.instance().deleteAllData();
mainController.addJavaScriptHandler(handlerName: 'Click', callback: (args){ // }
controller.evaluateJavascript(source: JavaScriptString.clickJSString(args.first, args.last) ); //
}); // ///
// addTouchendEventJS(){
} //
// final clickJsUS = UserScript(groupName: 'touchend',source: JavaScriptString.touchendEventJSString, injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START);
@override // mainController.addUserScript(userScript: clickJsUS);
Widget build(BuildContext context) { //
return Scaffold( // mainController.addJavaScriptHandler(handlerName: 'touchend', callback: (args){
body: Column( // if (asyncState){
children: [ // int x = double.parse(args.first.toString()).toInt();
Container( // int y = double.parse(args.last.toString()).toInt();
height: 50, // controller.evaluateJavascript(source: JavaScriptString.clickJSString(x, y) );
color: Colors.white, // // controller.evaluateJavascript(source: JavaScriptString.touchendJsString(x, y) );
padding: const EdgeInsets.symmetric(horizontal: 50), // // controller.evaluateJavascript(source: JavaScriptString.getClassTouchendJsString(x, y) );
child: Row( // }
children: [ // });
TextButton( //
onPressed: () { // }
controller.evaluateJavascript(source: JavaScriptString.clickJSString(600, 280) ); //
}, // @override
child: const Text('模拟点击测试')), // Widget build(BuildContext context) {
TextButton( // return Scaffold(
onPressed: () { // body: Column(
mainController.evaluateJavascript(source: JavaScriptString.inputJsString(45) ); // crossAxisAlignment: CrossAxisAlignment.stretch,
controller.evaluateJavascript(source: JavaScriptString.inputJsString(45) ); // children: [
}, // Container(
child: const Text('模拟输入测试')), // height: 50,
const SizedBox( // color: Colors.white,
width: 50, // padding: const EdgeInsets.symmetric(horizontal: 50),
child: TextField( // child: Row(
keyboardType: TextInputType.number, // children: [
decoration: InputDecoration(prefixText: '网页数量'), // TextButton(
), // onPressed: () {
) // controller.evaluateJavascript(source: JavaScriptString.clickJSString(50, 100) );
], // },
), // child: const Text('模拟点击测试')),
), // TextButton(
Expanded(child: pageViewWidget()), // onPressed: () {
], // mainController.evaluateJavascript(source: JavaScriptString.inputJsString(45) );
), // controller.evaluateJavascript(source: JavaScriptString.inputJsString(45) );
); // },
} // child: const Text('模拟输入测试')),
// Row(
Widget pageViewWidget() { // children: [
return PageView( // const Text('同步'),
children: <Widget>[ // Switch(value: asyncState, onChanged: (value){
KeepAlivePage( // setState(() {
child: WebWidget(controlerCallBack: (_mainController) { // asyncState = value;
mainController = _mainController; // });
// })
addClickEventJS(); // ],
}), // )
), // ],
KeepAlivePage( // ),
child: WebWidget(controlerCallBack: (_controller) { // ),
controller = _controller; // Expanded(child: pageViewWidget()),
}), // ],
) // ),
], // );
); // }
} //
// Widget pageViewWidget() {
} // return Row(
// children: <Widget>[
class KeepAlivePage extends StatefulWidget { // Expanded(
final Widget child; // child: Container(
// color: Colors.yellow,
KeepAlivePage({super.key , required this.child}); // child: KeepAlivePage(
// child: WebWidget(controlerCallBack: (_mainController) {
@override // mainController = _mainController;
_KeepAlivePageState createState() => _KeepAlivePageState(); //
} // addTouchendEventJS();
//
class _KeepAlivePageState extends State<KeepAlivePage> with AutomaticKeepAliveClientMixin { // }),
@override // ),
bool get wantKeepAlive => true; // ),
// ),
@override // Expanded(
Widget build(BuildContext context) { // child: Container(
super.build(context); // color: Colors.blue,
return widget.child; // 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<KeepAlivePage> with AutomaticKeepAliveClientMixin {
// @override
// bool get wantKeepAlive => true;
//
// @override
// Widget build(BuildContext context) {
// super.build(context);
// return widget.child;
// }
// }

View File

@ -1,31 +1,42 @@
import 'package:flutter/material.dart'; // import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; // import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:web_synchronization_tool/JavaScriptString.dart'; // import 'package:web_synchronization_tool/JavaScriptString.dart';
//
class WebWidget extends StatefulWidget { // class WebWidget extends StatefulWidget {
WebWidget({super.key, required this.controlerCallBack}); // WebWidget({super.key, required this.controlerCallBack});
//
final Function(InAppWebViewController) controlerCallBack; // final Function(InAppWebViewController) controlerCallBack;
//
@override // @override
State<WebWidget> createState() => _WebWidgetState(); // State<WebWidget> createState() => _WebWidgetState();
} // }
//
class _WebWidgetState extends State<WebWidget> { // class _WebWidgetState extends State<WebWidget> {
@override // @override
void initState() { // void initState() {
super.initState(); // super.initState();
} // }
//
@override // @override
Widget build(BuildContext context) { // Widget build(BuildContext context) {
return InAppWebView( // return InAppWebView(
initialUrlRequest: // initialUrlRequest:
URLRequest(url: WebUri('http://www.df6831.com/game/')), // URLRequest(url: WebUri('http://www.df6831.com/mobile')),//
initialSettings: InAppWebViewSettings(initialScale: 200,loadWithOverviewMode: false,useWideViewPort: false), // initialSettings: InAppWebViewSettings(
onWebViewCreated: (_controller) { // // initialScale: 180,
widget.controlerCallBack(_controller); // 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);
// },
// );
// }
// }

View File

@ -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})';
''';
}
}

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:web_synchronization_tool/windows/windowsJs.dart';
import 'windows_web_page.dart'; import 'windows_web_page.dart';
import 'package:webview_windows/webview_windows.dart'; import 'package:webview_windows/webview_windows.dart';
@ -25,6 +26,7 @@ class _WindowsPageState extends State<WindowsPage> {
} }
Future controllerInit() async { Future controllerInit() async {
await mainController.initialize(); await mainController.initialize();
await controller.initialize(); await controller.initialize();
@ -33,7 +35,6 @@ class _WindowsPageState extends State<WindowsPage> {
controller.clearCache(); controller.clearCache();
controller.clearCookies(); controller.clearCookies();
mainController.loadUrl('http://www.df6831.com/'); mainController.loadUrl('http://www.df6831.com/');
controller.loadUrl('http://www.df6831.com/'); controller.loadUrl('http://www.df6831.com/');
@ -42,22 +43,27 @@ class _WindowsPageState extends State<WindowsPage> {
setState(() { setState(() {
initDone = true; 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() { addClickEventJS() {
mainController.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs);
controller.executeScript('document.documentElement.innerHTML').then((value){ controller.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs);
print(value);
});
mainController.addScriptToExecuteOnDocumentCreated(
JavaScriptString.clickEventkJSString).then((value){
print(value);
});
} }
@override @override
@ -75,33 +81,39 @@ class _WindowsPageState extends State<WindowsPage> {
children: [ children: [
TextButton( TextButton(
onPressed: () { onPressed: () {
controller.executeScript( mainController.executeScript(WindowsJs.clickJs(200, 900));
JavaScriptString.clickJSString(600, 280)).then((value){ // controller.executeScript(WindowsJs.clickJs(600, 100));
print(value);
});
}, },
child: const Text('模拟点击测试')), child: const Text('模拟点击测试')),
TextButton( TextButton(
onPressed: () { onPressed: () {
mainController mainController.executeScript(WindowsJs.inputJsString(45));
.executeScript(JavaScriptString.inputJsString(45)); controller.executeScript(WindowsJs.inputJsString(45));
controller
.executeScript(JavaScriptString.inputJsString(45));
}, },
child: const Text('模拟输入测试')), child: const Text('模拟输入测试')),
TextButton( TextButton(
onPressed: () { onPressed: () {
mainController.loadUrl('http://www.df6831.com/game/'); mainController.loadUrl('http://www.df6831.com/');
// controller.loadUrl('http://www.df6831.com/game/');
}, },
child: const Text('跳转')), child: const Text('跳转首页')),
const SizedBox( TextButton(
width: 50, onPressed: () {
child: TextField( mainController.executeScript(WindowsJs.zoom(70));
keyboardType: TextInputType.number, controller.executeScript(WindowsJs.zoom(40));
decoration: InputDecoration(prefixText: '网页数量'), },
), 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<WindowsPage> {
Widget pageViewWidget() { Widget pageViewWidget() {
return Row( return Row(
children: [ children: [
Expanded( SizedBox(
width: 1000,
height: 1000,
child: WindowsWebWidget( child: WindowsWebWidget(
controller: mainController, controller: mainController,
), ),
), ),
Expanded( SizedBox(
width: 500,
height:400,
child: WindowsWebWidget( child: WindowsWebWidget(
controller: controller, controller: controller,
), ),

View File

@ -21,7 +21,7 @@ class _WindowsWebWidgetState extends State<WindowsWebWidget> {
} }
Widget inWindowsWebView(){ Widget inWindowsWebView(){
return Webview(widget.controller,); return Webview(widget.controller);
} }
} }

View File

@ -12,8 +12,9 @@ dependencies:
sdk: flutter sdk: flutter
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
flutter_inappwebview: ^6.0.0 webview_windows:
webview_windows: ^0.4.0 path: ../flutter-webview-windows-main
window_manager:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: