feat: add evaluateJavascriptViaWebview

This commit is contained in:
kodjomoustapha 2025-01-06 13:04:04 +01:00
parent 26550912a6
commit b4c09bbee0
3 changed files with 97 additions and 0 deletions

View file

@ -841,6 +841,32 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
],
namedParams: []),
isStatic: true),
'evaluateJavascriptViaWebview': BridgeMethodDef(
BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.future, [
BridgeTypeRef(
CoreTypes.string,
)
])),
params: [
BridgeParameter(
'url',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
false),
BridgeParameter(
'headers',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.map, [
BridgeTypeRef(CoreTypes.string),
BridgeTypeRef(CoreTypes.string)
])),
false),
BridgeParameter(
'scripts',
BridgeTypeAnnotation(BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])),
false),
]),
),
},
bridge: true);
@ -1009,6 +1035,17 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
}))
.toList());
}))),
"evaluateJavascriptViaWebview" => $Function((_, __, List<$Value?> args) =>
$Future.wrap(MBridge.evaluateJavascriptViaWebview(
args[0]!.$value,
(args[1]!.$value as Map).map((key, value) => MapEntry(
key.$reified.toString(), value.$reified.toString())),
(args[2]!.$value as List)
.map((e) => e.$reified.toString())
.toList())
.then((value) {
return $String(value);
}))),
"toVideo" => $Function((_, __, List<$Value?> args) {
final value = MBridge.toVideo(
args[0]!.$value,

View file

@ -1,5 +1,6 @@
import 'package:flutter_qjs/flutter_qjs.dart';
import 'package:js_packer/js_packer.dart';
import 'package:mangayomi/eval/javascript/http.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/utils/cryptoaes/js_unpacker.dart';
import 'package:mangayomi/utils/log/log.dart';
@ -31,6 +32,12 @@ class JsUtils {
runtime.onMessage('unpackJs', (dynamic args) {
return JSPacker(args[0]).unpack() ?? "";
});
runtime.onMessage('evaluateJavascriptViaWebview', (dynamic args) async {
return await MBridge.evaluateJavascriptViaWebview(
args[0]!,
(args[1]! as Map).toMapStringString!,
(args[2]! as List).map((e) => e.toString()).toList());
});
runtime.evaluate('''
console.log = function (message) {
@ -129,6 +136,12 @@ function parseDates(value, dateFormat, dateFormatLocale) {
JSON.stringify([value, dateFormat, dateFormatLocale])
);
}
async function evaluateJavascriptViaWebview(url, headers, scripts) {
return await sendMessage(
"evaluateJavascriptViaWebview",
JSON.stringify([url, headers, scripts])
);
}
''');
}
}

View file

@ -3,6 +3,7 @@ import 'package:bot_toast/bot_toast.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:go_router/go_router.dart';
import 'package:html/dom.dart' hide Text;
import 'package:intl/date_symbol_data_local.dart';
@ -11,6 +12,7 @@ import 'package:js_packer/js_packer.dart';
import 'package:json_path/json_path.dart';
import 'package:mangayomi/eval/model/document.dart';
import 'package:mangayomi/eval/javascript/http.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/router/router.dart';
import 'package:mangayomi/services/anime_extractors/dood_extractor.dart';
@ -625,6 +627,51 @@ class MBridge {
return text;
}
}
static Future<String> evaluateJavascriptViaWebview(
String url, Map<String, String> headers, List<String> scripts,
{int time = 30}) async {
int t = 0;
bool timeOut = false;
bool isOk = false;
String response = "";
HeadlessInAppWebView? headlessWebView;
headlessWebView = HeadlessInAppWebView(
webViewEnvironment: webViewEnvironment,
onWebViewCreated: (controller) {
controller.addJavaScriptHandler(
handlerName: 'setResponse',
callback: (args) {
response = args[0] as String;
isOk = true;
},
);
},
initialUrlRequest: URLRequest(url: WebUri(url), headers: headers),
onLoadStop: (controller, url) async {
for (var script in scripts) {
await controller.platform.evaluateJavascript(source: script);
}
},
);
headlessWebView.run();
await Future.doWhile(() async {
timeOut = time == t;
if (timeOut || isOk) {
return false;
}
await Future.delayed(const Duration(seconds: 1));
t++;
return true;
});
try {
headlessWebView.dispose();
} catch (_) {}
return response;
}
}
final List<String> _dateFormats = [