jnschulze / flutter-webview-windows Goto Github PK
View Code? Open in Web Editor NEWA WebView2-powered Flutter WebView implementation for the Windows platform.
License: BSD 3-Clause "New" or "Revised" License
A WebView2-powered Flutter WebView implementation for the Windows platform.
License: BSD 3-Clause "New" or "Revised" License
Some functions cannot work
1/When we are using some dropdownlist such as Select2 : https://select2.org/getting-started/basic-usage . We clicked Dropdown and it did not show.
2/ Scroll not work for jQuery Scrollbar : https://gromo.github.io/jquery.scrollbar/demo/basic.html
Hope to receive your feedback soon @jnschulze . Thank you!
Hi @jnschulze , While I was trying to send data from webcontent to flutter I am getting following error.
Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<dynamic, String>'
Here is the codesnippet:
In test.js file(trying to send json data):
function myFunction() {
var value = {"name":"tashi"}
window.chrome.webview.postMessage(value);
}
Now in main.dart (I have listener)
_controller.webMessage.listen((event) {
print(event);
});
when I run this code, I am getting error saying type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<dynamic, String>'
and error redirect me to this code in package
case 'webMessageReceived':
try {
final message = json.decode(map['value']);
_webMessageStreamController.add(message);
} catch (ex) {
_webMessageStreamController.addError(ex);
}
I believe in webviews_window.dart
Stream<Map<dynamic, String>>
get webMessage should be Stream<Map<String, dynamic>>
thanks for your help
Just about to start Flutter Windows platform development, have a quick question. Can we load a URL with custom UserAgent string?
How to block some links from automatically open external browser
App loads and crashes rendering the page.
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.2.2, on Microsoft Windows [Version 10.0.19042.1052], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.10.2)
[√] Android Studio (version 4.1.0)
[√] Connected device (3 available)
Dump file output from DebugDiag
webview_windows_plugin!RGBA_to_BGRA+be [H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\util\swizzle.h @ 198 + 5] 00001f7`87c1a070 00001f7`f0e8b000 0000000`000002d0 00000d3`00000500 H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\util\swizzle.h @ 198 + 5
webview_windows_plugin!TextureBridge::CopyFrame+43c [H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\texture_bridge.cc @ 135] 00001f7`fe2e4d20 00001f7`fe485af8 0000000`00000000 0000209`000004c0 H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\texture_bridge.cc @ 135
webview_windows_plugin!TextureBridge::CopyPixelBuffer+cd [H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\texture_bridge.cc @ 181 + 1a] 00001f7`fe2e4d20 0000000`000004c0 0000000`00000209 0000000`00000000 H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\texture_bridge.cc @ 181 + 1a
webview_windows_plugin!<lambda_5491a75f6462c500903d32c97520d5d0>::operator()+41 [H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\webview_bridge.cc @ 113] 00001f7`fdd4e318 0000000`000004c0 0000000`00000209 00001f7`f6c938e0 H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\webview_bridge.cc @ 113
webview_windows_plugin!std::invoke<<lambda_5491a75f6462c500903d32c97520d5d0> &,unsigned __int64,unsigned __int64>+2e [H:\Visual Studio 2019\VC\Tools\MSVC\14.29.30037\include\type_traits @ 1610] 00001f7`fdd4e318 00000d3`13b5db78 00000d3`13b5db80 0007ff8`aefadbe6 H:\Visual Studio 2019\VC\Tools\MSVC\14.29.30037\include\type_traits @ 1610
webview_windows_plugin!std::_Invoker_ret<FlutterDesktopPixelBuffer const *,0>::_Call<<lambda_5491a75f6462c500903d32c97520d5d0> &,unsigned __int64,unsigned __int64>+28 [H:\Visual Studio 2019\VC\Tools\MSVC\14.29.30037\include\functional @ 754] 00001f7`fdd4e318 00000d3`13b5db78 00000d3`13b5db80 0000000`00000000 H:\Visual Studio 2019\VC\Tools\MSVC\14.29.30037\include\functional @ 754
webview_windows_plugin!std::_Func_impl_no_alloc<<lambda_5491a75f6462c500903d32c97520d5d0>,FlutterDesktopPixelBuffer const *,unsigned __int64,unsigned __int64>::_Do_call+4d [H:\Visual Studio 2019\VC\Tools\MSVC\14.29.30037\include\functional @ 921] 00001f7`fdd4e310 00000d3`13b5db78 00000d3`13b5db80 00000d3`13b5db88 H:\Visual Studio 2019\VC\Tools\MSVC\14.29.30037\include\functional @ 921
webview_windows_plugin!std::_Func_class<FlutterDesktopPixelBuffer const *,unsigned __int64,unsigned __int64>::operator()+7b [H:\Visual Studio 2019\VC\Tools\MSVC\14.29.30037\include\functional @ 969] 00001f7`fdd4e310 0000000`000004c0 0000000`00000209 00001f7`e97f0d80 H:\Visual Studio 2019\VC\Tools\MSVC\14.29.30037\include\functional @ 969
webview_windows_plugin!flutter::PixelBufferTexture::CopyPixelBuffer+32 [H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\cpp_client_wrapper\include\flutter\texture_registrar.h @ 39] 00001f7`fdd4e310 0000000`000004c0 0000000`00000209 00000d3`13b5dc89 H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\cpp_client_wrapper\include\flutter\texture_registrar.h @ 39
webview_windows_plugin!<lambda_fe1592742860abf825dc927a0ab45d58>::operator()+37 [H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\cpp_client_wrapper\core_implementations.cc @ 168 + 14] 0000000`00000000 0000000`000004c0 0000000`00000209 00001f7`fdd4e310 H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\cpp_client_wrapper\core_implementations.cc @ 168 + 14
webview_windows_plugin!<lambda_fe1592742860abf825dc927a0ab45d58>::<lambda_invoker_cdecl>+2a [H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\cpp_client_wrapper\core_implementations.cc @ 170 + 2a] 0000000`000004c0 0000000`00000209 00001f7`fdd4e310 0000000`00000000 H:\git\FlutterWeb\flutter_webapp_test\windows\flutter\ephemeral\cpp_client_wrapper\core_implementations.cc @ 170 + 2a
flutter_windows+6d27 00001f7`ec53cea0 0007ff8`af6601a4 0000000`00000050 0007ff8`af96f9a7
flutter_windows+6cb8 0000000`00000007 0007ff8`af9b9900 00001f7`e9859648 0000000`00000030
flutter_windows!FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable+2712 00001f7`ec56a0f0 00001f7`f6c74100 00000d3`13b5e048 0007ff8`af0f9bd9
flutter_windows!FlutterDesktopGetDpiForMonitor+19c3d 00000d3`13b5e5c8 00000d3`13b5e700 0000000`00000018 0000000`00000088
flutter_windows!FlutterDesktopGetDpiForMonitor+2478d 00000d3`13b5e054 00000d3`13b5e058 00000d3`13b5e060 00000d3`13b5e068
flutter_windows!FlutterDesktopGetDpiForMonitor+245d7 0000000`3f800000 0000b77`6ffea99f 00001f7`fe35a0f0 0000000`00000007
flutter_windows!FlutterDesktopGetDpiForMonitor+39a7e6 3080000`41c00000 f800000`00000000 0000b77`6ffea97f 00001f7`849368f0
flutter_windows!FlutterDesktopGetDpiForMonitor+397e0b 00001f7`ec4f4ec0 00000d3`13b5e570 0000000`00000000 0007ff8`af27e8f3
flutter_windows!FlutterDesktopGetDpiForMonitor+39aae9 0000000`00000005 0000b77`6ffea8ef 0000000`00000005 00000d3`13b5e570
flutter_windows!FlutterDesktopGetDpiForMonitor+397e0b 00001f7`8493aec0 00000d3`13b5e570 0007ff8`b00b4398 00000d3`13b5e2e0
flutter_windows!FlutterDesktopGetDpiForMonitor+399afe 0000b77`6ffeabcf 00000d3`13b5e2e0 00000d3`13b5e570 00001f7`84937a60
flutter_windows!FlutterDesktopGetDpiForMonitor+397e0b 0000000`00000000 0000000`00000000 0000000`00000000 0000000`f89473be
flutter_windows!FlutterDesktopGetDpiForMonitor+399afe 0000000`00000000 0000000`00000000 0000b77`6ffeaacf 00001f7`84937d30
flutter_windows!FlutterDesktopGetDpiForMonitor+397e0b 00001f7`fe46f3a0 00000d3`13b5e570 0000000`00000000 0007ff8`af27e8f3
flutter_windows!FlutterDesktopGetDpiForMonitor+39aae9 0000000`00000000 0000000`00000000 0000b77`6ffeaa5f 00001f7`849371f0
flutter_windows!FlutterDesktopGetDpiForMonitor+397e0b 00001f7`fe010f20 00000d3`13b5e570 0000000`00000000 0007ff8`af27e8f3
flutter_windows!FlutterDesktopGetDpiForMonitor+39aae9 0000000`00000000 0000000`00000000 0000b77`6ffeadef 00001f7`84937160
flutter_windows!FlutterDesktopGetDpiForMonitor+397e0b 00001f7`fe46f100 00000d3`13b5e570 0000000`00000000 0007ff8`af27e8f3
flutter_windows!FlutterDesktopGetDpiForMonitor+39aae9 0000000`00000000 0007ff8`af27e8f3 0000000`00000000 0000000`00000000
flutter_windows!FlutterDesktopGetDpiForMonitor+397e0b 0000000`00000020 0007ff8`af100c38 00001f7`e97f0000 0007ff9`00000004
flutter_windows!FlutterDesktopGetDpiForMonitor+398930 00000d3`13b5f2e8 0000000`00000002 00001f7`849b3770 0007ff8`aef171c2
flutter_windows!FlutterDesktopGetDpiForMonitor+395e5b 00001f7`e97f0000 0007ff8`aef1745d 00001f7`f6c12470 0000000`0000004e
flutter_windows!FlutterDesktopGetDpiForMonitor+3a3c84 0000000`00000000 0007ff8`af545080 0000000`00000000 00000d3`13b5f930
flutter_windows!FlutterDesktopGetDpiForMonitor+3a499b 0000000`f8947371 0000000`00000000 0000000`ec54caa0 0000000`00000000
flutter_windows!FlutterDesktopGetDpiForMonitor+3a5683 00000d3`13b5f7c0 00000d3`13b5f7c8 0000000`00000000 0007ff8`afa88220
flutter_windows!FlutterDesktopGetDpiForMonitor+3a41ec 00001f7`ec43a6b8 0007ff8`aef1440d 00000d3`13b5f9c0 00003cb`03e2c288
flutter_windows!FlutterDesktopGetDpiForMonitor+3a3ed7 0000000`00000002 00003cb`03e1accc 0000000`00989680 0007ff8`af96fe87
flutter_windows!FlutterDesktopGetDpiForMonitor+3b5176 0000000`0000066f 0007ff9`219f0000 0000000`00000000 00001f7`ec4aae70
flutter_windows!FlutterDesktopGetDpiForMonitor+2cb1b 00000d3`13b5faa8 0007ff8`aef1309f 0000000`00000000 0000000`000004a8
flutter_windows!FlutterDesktopGetDpiForMonitor+35f66 00001f7`ec4f5d10 0000000`00000c84 0000b77`6ffeb30f 00000d3`13b5fc30
flutter_windows!FlutterDesktopGetDpiForMonitor+2ca38 0000000`00000000 0007ff9`21a407b0 0000000`00000000 0000000`00000000
flutter_windows!FlutterDesktopGetDpiForMonitor+3069f 0000000`00000000 00001f7`ec4a68e0 0000000`00000000 0000000`00000000
flutter_windows!FlutterDesktopGetDpiForMonitor+29c74 00001f7`ec4f2070 0000000`00000000 0000000`00000000 0000000`00000000
flutter_windows!ANGLEResetDisplayPlatform+328394 0000000`00000000 0000000`00000000 0000000`00000000 0000000`00000000
kernel32!BaseThreadInitThunk+14 0000000`00000000 0000000`00000000 0000000`00000000 0000000`00000000
ntdll!RtlUserThreadStart+21 0000000`00000000 0000000`00000000 0000000`00000000 0000000`00000000
Hey, I was wondering if it would be possible to programmatically interact with the DOM of the webpage?
Use cases would be to automate entering stuff into websites or click buttons.
The default webview implementation of flutter already supports this with the evaluateJavascript
function:
https://github.com/flutter/plugins/blob/84964325d304c2a153e1dd6dc5e96be31ee93d3c/packages/webview_flutter/webview_flutter_web/example/lib/web_view.dart#L239
flutter-webview-windows/example/windows/flutter/ephemeral/.plugin_symlinks/webview_windows/windows/third_party/fmt
does not contain a CMakeLists.txt file.
Using a custom dynamic tab widget, webview freeze entire app.
Please see the reproducible example in this repository ( please click on add button and wait 15 seconds to see the interface stucks )
https://github.com/filipenanclarez/poc_webview_windows_dinamic_tabs_flutter
Seems to be a dispose problem, but i'cant discover.
With flutter native webview widget, this problem no happens, so i think my custom tab widget is not the source of problem.
path configured ok
NuGet
CMake Error at flutter/ephemeral/.plugin_symlinks/webview_windows/windows/CMakeLists.txt:9 (add_subdirectory):
The source directory
C:/dart_templetes/flutter-webview-windows/example/windows/flutter/ephemeral/.plugin_symlinks/webview_windows/windows/third_party/fmt
does not contain a CMakeLists.txt file.
NUGET.EXE not found.
CMake Error at flutter/ephemeral/.plugin_symlinks/webview_windows/windows/CMakeLists.txt:14 (message):
Please install this executable, and run CMake again.
Exception: Unable to generate build files
Hi @jnschulze, the cursor position is not correct if the size of webview is small around <1000.
I believe this is happening because this is not working properly _controller._setSize(box.size);
in webview_windows.dart
Hi Niklas Schulze,
I want to add JavascriptInterface(bridge) to work between flutter & window webview
For example:
But I could not find document & example for it
How to do that?
Hope u can fix for this problem.
Example URL: https://wordpress.com/log-in
`
======== Exception caught by services library ======================================================
The following FormatException was thrown during a platform message callback:
Unexpected extension byte (at offset 7)
When the exception was thrown, this was the stack:
#0 _Utf8Decoder.convertSingle (dart:convert-patch/convert_patch.dart:1788:7)
#1 Utf8Decoder.convert (dart:convert/utf.dart:318:42)
#2 StandardMessageCodec.readValueOfType (package:flutter/src/services/message_codecs.dart:463:29)
#3 StandardMessageCodec.readValue (package:flutter/src/services/message_codecs.dart:438:12)
#4 StandardMessageCodec.readValueOfType (package:flutter/src/services/message_codecs.dart:489:39)
#5 StandardMessageCodec.readValue (package:flutter/src/services/message_codecs.dart:438:12)
#6 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:601:27)
#7 EventChannel.receiveBroadcastStream.. (package:flutter/src/services/platform_channel.dart:478:34)
#8 EventChannel.receiveBroadcastStream.. (package:flutter/src/services/platform_channel.dart:473:47)
#9 _DefaultBinaryMessenger.setMessageHandler. (package:flutter/src/services/binding.dart:379:35)
#10 _DefaultBinaryMessenger.setMessageHandler. (package:flutter/src/services/binding.dart:376:46)
#11 _invoke2. (dart:ui/hooks.dart:205:15)
#15 _invoke2 (dart:ui/hooks.dart:204:10)
#16 _ChannelCallbackRecord.invoke (dart:ui/channel_buffers.dart:42:5)
#17 _Channel.push (dart:ui/channel_buffers.dart:132:31)
#18 ChannelBuffers.push (dart:ui/channel_buffers.dart:329:17)
#19 PlatformDispatcher._dispatchPlatformMessage (dart:ui/platform_dispatcher.dart:544:22)
#20 _dispatchPlatformMessage (dart:ui/hooks.dart:92:31)
(elided 3 frames from dart:async)
====================================================================================================`
In the file webview_windows.dart
when I send a message from HTML/Javascript page (window.chrome.webview.postMessage("WebTask::Decrement Counter");)
I receive the message and process it in
line 212 _eventChannel.receiveBroadcastStream().listen((event) {.......
........
........
line 238 final message = json.decode(map['value']);
line 239 _webMessageStreamController.add(message);
I got this error:
[ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: type 'String' is not a subtype of type 'Map<dynamic, dynamic>'
#0 WebviewController.initialize. (package:webview_windows/webview_windows.dart:239:49)
.........
First, thank you for this package.
I getting an Exception when calling dispose on the WebViewController:
[ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: MissingPluginException(No implementation found for method dispose on channel io.jns.webview.win
I assume that calling dispose on the controller would remove the msedgewebview2.exe process, currently the browser processes are not removed and increases over time.
On executescript sometimes we need receive a return of executed script.
In native webview_flutter the executescript (evaluatejs) method return a Future so we can get the return of script.
I try to use mouse scroll . But It is not affected. I have tested it on WPF. It is working perfectly. Anh Touch support only click. Cannot move. Thank!
I tested it on https://joltfly.com/mouse-test/
First of all,Thanks for the great package. I have issue while loading web content,I have html and js file in assets folder,
If the feature is implemented please provide example for each cases, if not I hope this feature will come soon
It looks like WebView2 will get drag and drop support for composition mode soon.
-> make use of that API.
Hi there!
I've been trying to get this plugin to work but cannot.
I'm trying to build example app.
Exception:
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: LateInitializationError: Field '_methodChannel@18215898' has not been initialized.
#0 WebviewController._methodChannel (package:webview_windows/webview_windows.dart)
#1 WebviewController.loadUrl (package:webview_windows/webview_windows.dart:205:11)
#2 _MyAppState.initPlatformState (package:app/main.dart:39:23)
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.2.1, on Microsoft Windows [Version 10.0.19042.572], locale en-US)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
✗ Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/windows#android-setup for more details.
[✓] Chrome - develop for the web
[✓] Visual Studio - develop for Windows (Visual Studio Community 2019 16.8.6)
[✓] Android Studio (version 3.6)
[✓] VS Code (version 1.56.2)
[✓] Connected device (3 available)
Further information
I'm on latest Windows SDK.
Thanks a lot. Please help me out. 🙏
Hi! Amazing Package! thankyou!
Im trying to use this package to implement an oauth flow.
After users are redirected to google auth. google informs that the browser may not be secure and does not let the user log in.
Hopefully the attachment is good enuff to show what i mean.
P.S.
How do i close the webview? _controller.dispose() ?
I found this problem with some pages.
Below as reproducible example, it is the sample documentation code. I just change the url and get de content first, then try to use loadStringContent. Then we get no result and no error even on debug console. And the controller LoadingState.navigationCompleted state is never fired.
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:webview_windows/webview_windows.dart';
import 'package:http/http.dart' as http;
final navigatorKey = GlobalKey<NavigatorState>();
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _controller = WebviewController();
final _textController = TextEditingController();
bool _isWebviewSuspended = false;
var myUrl =
'https://2pinyin.net/xx/teste-maio-2021/25-12-2021/1102014241.xhtml';
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
// Optionally initialize the webview environment using
// a custom user data directory
// and/or a custom browser executable directory
// and/or custom chromium command line flags
//await WebviewController.initializeEnvironment(
// additionalArguments: '--show-fps-counter');
await _controller.initialize();
_controller.url.listen((url) {
_textController.text = url;
});
await _controller.setBackgroundColor(Colors.transparent);
await _controller.setPopupWindowPolicy(WebviewPopupWindowPolicy.deny);
// await _controller.loadUrl('about:blank');
var response = await http.get(Uri.parse(myUrl));
_controller.loadStringContent(response.body);
if (!mounted) return;
setState(() {});
}
Widget compositeView() {
if (!_controller.value.isInitialized) {
return const Text(
'Not Initialized',
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
Card(
elevation: 0,
child: TextField(
decoration: InputDecoration(
hintText: 'URL',
contentPadding: EdgeInsets.all(10.0),
suffixIcon: IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
_controller.reload();
},
)),
textAlignVertical: TextAlignVertical.center,
controller: _textController,
onSubmitted: (val) async {
var response = await http.get(Uri.parse(val));
_controller.loadStringContent(response.body);
// _controller.loadUrl(val);
},
),
),
Expanded(
child: Card(
color: Colors.transparent,
elevation: 0,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Stack(
children: [
Webview(
_controller,
permissionRequested: _onPermissionRequested,
),
StreamBuilder<LoadingState>(
stream: _controller.loadingState,
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.data == LoadingState.loading) {
return LinearProgressIndicator();
} else {
return SizedBox();
}
}),
],
))),
],
),
);
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
home: Scaffold(
floatingActionButton: FloatingActionButton(
tooltip: _isWebviewSuspended ? 'Resume webview' : 'Suspend webview',
onPressed: () async {
if (_isWebviewSuspended) {
await _controller.resume();
} else {
await _controller.suspend();
}
setState(() {
_isWebviewSuspended = !_isWebviewSuspended;
});
},
child: Icon(_isWebviewSuspended ? Icons.play_arrow : Icons.pause),
),
appBar: AppBar(
title: StreamBuilder<String>(
stream: _controller.title,
builder: (context, snapshot) {
return Text(snapshot.hasData
? snapshot.data!
: 'WebView (Windows) Example');
},
)),
body: Center(
child: compositeView(),
),
),
);
}
Future<WebviewPermissionDecision> _onPermissionRequested(
String url, WebviewPermissionKind kind, bool isUserInitiated) async {
final decision = await showDialog<WebviewPermissionDecision>(
context: navigatorKey.currentContext!,
builder: (BuildContext context) => AlertDialog(
title: const Text('WebView permission requested'),
content: Text('WebView has requested permission \'$kind\''),
actions: <Widget>[
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.deny),
child: const Text('Deny'),
),
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.allow),
child: const Text('Allow'),
),
],
),
);
return decision ?? WebviewPermissionDecision.none;
}
}
Can you make this widget compatible with UWP apps available on flutter alpha channel?
How to navigate (back/forward) ?
How to call js, or js to call dart
is there a plan to support High Dpi?
The folder MyApp.exe.WebView2 is automatically created in the location of flutter application.
If the application is installed in the Program Dirctory of Windows, the app has no write access to this folder.
There shoud be an option to configure the location of the folder or the default location should be somewhere else (eg should be located in %appdata%)
flutter-webview-windows default open webview in new window,but,How To use flutter-webview-windows toOpen Web Page Within My App
Hi @jnschulze, I'm trying to run webview in a bubble widget that can be resized if the corners are dragged. But the webview freezes after resize of the wibview container.
I believe this is happening because this is not working properly _controller._setSize(box.size);
in webview_windows.dart
The mouse can't control the webpage
--- stderr
CMake Error at flutter/webview_windows/CMakeLists.txt:32 (message):
Integrity check for
D:/flutter_qtalk/target/debug/build/qtalk_x-33ced172032e5b70/out/build/nuget.exe
failed
Since flutter 2.5 was released, there are a few Problems now:
Is there any way to support a transparent background for the webview?
I have problems with encode/charset of executeScript method . Please see below:
This is the peace of code:
This is the result:
Below as reproducible example, it is the sample documentation code. I just added the button to submit the script:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:webview_windows/webview_windows.dart';
final navigatorKey = GlobalKey<NavigatorState>();
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _controller = WebviewController();
final _textController = TextEditingController();
bool _isWebviewSuspended = false;
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
// Optionally initialize the webview environment using
// a custom user data directory
// and/or a custom browser executable directory
// and/or custom chromium command line flags
//await WebviewController.initializeEnvironment(
// additionalArguments: '--show-fps-counter');
await _controller.initialize();
_controller.url.listen((url) {
_textController.text = url;
});
await _controller.setBackgroundColor(Colors.transparent);
await _controller.setPopupWindowPolicy(WebviewPopupWindowPolicy.deny);
await _controller.loadUrl(
'https://2pinyin.net/xx/teste-maio-2021/25-12-2021/poc_webview_windows.html');
if (!mounted) return;
setState(() {});
}
Widget compositeView() {
if (!_controller.value.isInitialized) {
return const Text(
'Not Initialized',
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
Card(
elevation: 0,
child: TextField(
decoration: InputDecoration(
hintText: 'URL',
contentPadding: EdgeInsets.all(10.0),
suffixIcon: IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
_controller.reload();
},
)),
textAlignVertical: TextAlignVertical.center,
controller: _textController,
onSubmitted: (val) {
_controller.loadUrl(val);
},
),
),
Expanded(
child: Card(
color: Colors.transparent,
elevation: 0,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Stack(
children: [
Webview(
_controller,
permissionRequested: _onPermissionRequested,
),
StreamBuilder<LoadingState>(
stream: _controller.loadingState,
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.data == LoadingState.loading) {
return LinearProgressIndicator();
} else {
return SizedBox();
}
}),
],
))),
],
),
);
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
home: Scaffold(
floatingActionButton: FloatingActionButton(
tooltip: _isWebviewSuspended ? 'Resume webview' : 'Suspend webview',
// onPressed: () async {
// if (_isWebviewSuspended) {
// await _controller.resume();
// } else {
// await _controller.suspend();
// }
// setState(() {
// _isWebviewSuspended = !_isWebviewSuspended;
// });
// },
// child: Icon(_isWebviewSuspended ? Icons.play_arrow : Icons.pause),
// ),
onPressed: () {
var string = 'test à ç ã à Á';
_controller.executeScript('document.getElementById("content").innerHTML="$string"; alert("$string");');
},
child: Icon( Icons.send),
),
appBar: AppBar(
title: StreamBuilder<String>(
stream: _controller.title,
builder: (context, snapshot) {
return Text(snapshot.hasData
? snapshot.data!
: 'WebView (Windows) Example');
},
)),
body: Center(
child: compositeView(),
),
),
);
}
Future<WebviewPermissionDecision> _onPermissionRequested(
String url, WebviewPermissionKind kind, bool isUserInitiated) async {
final decision = await showDialog<WebviewPermissionDecision>(
context: navigatorKey.currentContext!,
builder: (BuildContext context) => AlertDialog(
title: const Text('WebView permission requested'),
content: Text('WebView has requested permission \'$kind\''),
actions: <Widget>[
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.deny),
child: const Text('Deny'),
),
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.allow),
child: const Text('Allow'),
),
],
),
);
return decision ?? WebviewPermissionDecision.none;
}
}
There's some changes on main which haven't made it to pub.dev yet. When using the git pubspec.yaml approach to get the latest commit, pubspec.yaml doesn't clone the repo with submodules so you get a cmake build error when building windows in release mode.
If you could push a new release to pubspec.yaml we could go back to using the normal pubspec way again.
Issue that pubspec yaml doesn't clone submodules: dart-lang/pub#2807
Cmake build error issue: #27
import 'package:canvas_lms/api.dart';
import 'package:canvas_lms/modal/DetailPage.dart';
import 'package:canvas_lms/modal/ModuleItems.dart';
import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:webview_windows/webview_windows.dart';
import 'package:canvas_lms/theme/theme.dart';
import 'package:canvas_lms/lang/lang.dart';
final navigatorKey = GlobalKey<NavigatorState>();
class ModulePageDetail extends StatefulWidget {
final String url;
const ModulePageDetail({Key key, this.url}) : super(key: key);
@override
_ModulePageDetailState createState() => _ModulePageDetailState();
}
class _ModulePageDetailState extends State<ModulePageDetail> {
HttpService httpService = HttpService();
Future<DetailPage> detailPage;
@override
void initState() {
detailPage = httpService.getPageModule(widget.url);
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<DetailPage>(
future: detailPage,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Container(
padding: EdgeInsets.all(10.0),
child: HtmlWidget(
"${snapshot.data.body}",
customStylesBuilder: (e) =>
e.classes.contains('link_iframe') ? {'color': 'red'} : null,
factoryBuilder: () => _WidgetFactory(),
webView: true,
),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
}
class _WidgetFactory extends WidgetFactory {
@override
void parse(BuildMetadata meta) {
super.parse(meta);
if (meta.element.classes.contains('link_iframe')) {
meta.register(BuildOp(
onWidgets: (meta, widgets) => listOrNull(
buildColumnPlaceholder(meta, widgets)?.wrapWith(
(_, child) => _QuoteWidget(child),
),
),
));
}
}
}
class _QuoteWidget extends StatelessWidget {
final Widget child;
_QuoteWidget(this.child);
@override
Widget build(BuildContext context) {
return Center(
child: FractionallySizedBox(
widthFactor: 0.5,
child: GestureDetector(
child: Text("Click here",
style: TextStyle(
decoration: TextDecoration.underline,
color: Colors.blue)),
onTap: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (BuildContext context) => FullScreenDialog(),
fullscreenDialog: true,
),
);
})),
);
}
}
class FullScreenDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color(ThemeBasic.APP_BAR),
title: Text(Vi.DIALOG_COURSE_DETAIL),
),
body: Container(
// child: WebviewComponent(),
child: Text('Data'),
),
);
}
}
class WebviewComponent extends StatefulWidget {
WebviewComponent({Key key}) : super(key: key);
@override
_WebviewComponentState createState() => _WebviewComponentState();
}
class _WebviewComponentState extends State<WebviewComponent> {
final _controller = WebviewController();
final _textController = TextEditingController();
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
await _controller.initialize();
_controller.url.listen((url) {
_textController.text = url;
});
await _controller.setBackgroundColor(Colors.transparent);
await _controller.loadUrl('https://flutter.dev');
if (!mounted) return;
setState(() {});
}
Widget compositeView() {
if (!_controller.value.isInitialized) {
return const Text(
'Not Initialized',
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return Container(
padding: EdgeInsets.all(20),
child: Column(
children: [
Card(
elevation: 0,
child: TextField(
decoration: InputDecoration(
hintText: 'URL',
contentPadding: EdgeInsets.all(10.0),
suffixIcon: IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
_controller.reload();
},
)),
textAlignVertical: TextAlignVertical.center,
controller: _textController,
onSubmitted: (val) {
_controller.loadUrl(val);
},
),
),
Expanded(
child: Card(
color: Colors.transparent,
elevation: 0,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Stack(
children: [
Webview(
_controller,
permissionRequested: _onPermissionRequested,
),
StreamBuilder<LoadingState>(
stream: _controller.loadingState,
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.data == LoadingState.loading) {
return LinearProgressIndicator();
} else {
return Container();
}
}),
],
))),
],
),
);
}
}
Future<WebviewPermissionDecision> _onPermissionRequested(
String url, WebviewPermissionKind kind, bool isUserInitiated) async {
final decision = await showDialog<WebviewPermissionDecision>(
context: navigatorKey.currentContext,
builder: (BuildContext context) => AlertDialog(
title: const Text('WebView permission requested'),
content: Text('WebView has requested permission \'$kind\''),
actions: <Widget>[
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.deny),
child: const Text('Deny'),
),
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.allow),
child: const Text('Allow'),
),
],
),
);
return decision ?? WebviewPermissionDecision.none;
}
@override
Widget build(BuildContext context) {
return Container(
child: compositeView(),
);
}
}
[√] Flutter (Channel stable, 2.2.3, on Microsoft Windows [Version 10.0.19043.1165], locale en-US)
[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
X No Java Development Kit (JDK) found; You must have the environment variable JAVA_HOME set and the java binary in your PATH. You can download the JDK from https://www.oracle.com/technetwork/java/javase/downloads/.
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.10.3)
[!] Android Studio (not installed)
[√] VS Code (version 1.58.2)
[√] Connected device (3 available)
! Doctor found issues in 2 categories.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: The command "setlocal [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: ..\..\nuget.exe install Microsoft.Windows.ImplementationLibrary -Version 1.0.210204.1
-ExcludeVersion -OutputDirectory C:/Users/admin/Documents/Projects/canvas/build/windows/packages [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: ..\..\nuget.exe install Microsoft.Web.WebView2 -Version 1.0.865-prerelease -ExcludeVersion -OutputDirectory C:/Users/admin/Documents/Projects/canvas/build/windows/packages [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: :cmEnd [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: :cmErrorLevel [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: exit /b %1 [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: :cmDone [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(145,5): error MSB3073: :VCEnd" exited with code 1. [C:\Users\admin\Documents\Projects\canvas\build\windows\plugins\webview_windows\DEPENDENCIES_DOWNLOAD.vcxproj]
Building Windows application...
Exception: Build process failed.
I tried to load web that contain permission. But it is not show dialog request permission
Sometimes Web Content is not loaded and the screen remains emtpy.
There is no error message reported, the following code can be used to reproduce the issue:
In most cases, the problem occurs when the sample app is initially called, but sometimes only after the refresh button has been pressed several times.
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:webview_windows/webview_windows.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _count = 0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton(
tooltip: 'Reload',
onPressed: () => setState(() {
_count++;
}),
child: Icon(Icons.refresh),
),
appBar: AppBar(title: Text('WebView (Windows) Example')),
body: Center(
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
MyBrowser(key: GlobalKey(), value: (++_count).toString()),
],
),
]),
),
),
);
}
}
class MyBrowser extends StatefulWidget {
final String value;
final double width;
final double height;
const MyBrowser({
Key? key,
required this.value,
this.width = 200,
this.height = 100,
}) : super(key: key);
@override
_MyBrowserState createState() => _MyBrowserState();
}
class _MyBrowserState extends State<MyBrowser> {
final _controller = WebviewController();
@override
void initState() {
super.initState();
initPlatformState();
}
@override
void dispose() {
super.dispose();
disposePlatformState();
}
Future<void> disposePlatformState() async {
await _controller.dispose();
}
Future<void> initPlatformState() async {
await _controller.initialize();
await _controller.setBackgroundColor(Colors.transparent);
await _controller.loadStringContent('<h2>${widget.value}</h2>');
if (!mounted) return;
setState(() {});
}
@override
Widget build(BuildContext context) {
if (!_controller.value.isInitialized) {
return Container(
width: widget.width,
height: widget.height,
child: Center(child: CircularProgressIndicator()),
);
} else {
return Container(
padding: EdgeInsets.all(10),
width: widget.width,
height: widget.height,
child: Webview(_controller),
);
}
}
}
First of all thanks to this huge effort and great pacakage.
Currently I am unable to run even after following the minimal amount of information in Readme.
Still following error is shown without much details. I tried flutter clean
and also git init submodule && git update submodule
as mentioned in issue #3 .
C:\Abhilash\Sources\dashboard\dashboard_frontend\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\util/capture.desktop.interop.h(4,10): fatal error C1083: Cannot open include file: 'windows.graphics.capture.interop.h': No such file or directory [C:\Abhilash\Sources\dashboard\dashboard_frontend\build\windows\plugins\webview_windows\webview_windows_plugin.vcxproj]
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\cppwinrt\winrt/base.h(6508,17): error C2220: the following warning is treated as an error [C:\Abhilash\Sources\dashboard\dashboard_frontend\build\windows\plugins\webview_windows\webview_windows_plugin.vcxproj]
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\cppwinrt\winrt/base.h(6508,17): warning C5205: delete of an abstract class 'winrt::impl::implements_delegate<winrt::Windows::UI::Core::DispatchedHandler,H>' that has a non-virtual destructor results in undefined behavior [C:\Abhilash\Sources\dashboard\dashboard_frontend\build\windows\plugins\webview_windows\webview_windows_plugin.vcxproj]
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\cppwinrt\winrt/base.h(6508,17): error C2220: the following warning is treated as an error [C:\Abhilash\Sources\dashboard\dashboard_frontend\build\windows\plugins\webview_windows\webview_windows_plugin.vcxproj]
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\cppwinrt\winrt/base.h(6508,17): warning C5205: delete of an abstract class 'winrt::impl::implements_delegate<winrt::Windows::UI::Core::DispatchedHandler,H>' that has a non-virtual destructor results in undefined behavior [C:\Abhilash\Sources\dashboard\dashboard_frontend\build\windows\plugins\webview_windows\webview_windows_plugin.vcxproj]
C:\Abhilash\Sources\dashboard\dashboard_frontend\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\util/capture.desktop.interop.h(4,10): fatal error C1083: Cannot open include file: 'windows.graphics.capture.interop.h': No such file or directory [C:\Abhilash\Sources\dashboard\dashboard_frontend\build\windows\plugins\webview_windows\webview_windows_plugin.vcxproj]
C:\Abhilash\Sources\dashboard\dashboard_frontend\windows\flutter\ephemeral\.plugin_symlinks\webview_windows\windows\util/capture.desktop.interop.h(4,10): fatal error C1083: Cannot open include file: 'windows.graphics.capture.interop.h': No such file or directory [C:\Abhilash\Sources\dashboard\dashboard_frontend\build\windows\plugins\webview_windows\webview_windows_plugin.vcxproj]
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.0.6, on Microsoft Windows [Version 10.0.18363.1441], locale de-DE)
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.7.6)
[√] Android Studio (version 4.1.0)
[√] VS Code (version 1.56.1)
[√] Connected device (3 available)
• No issues found!
Webview_flutter package has a way to set headers in load url parameter just like this Controller.loadUrl('https://xxxx.com', headers: header);
. I wonder if this can be added here it can help bypassing url a lots
Hey, first off, great work... I was looking for webview for windows for some time and the only workaround was using urlservice which opens a browser, etc... But I want to know does that plugin support cookies as well?
Is it possiable read html when page finished ?
We implement the same function on flutter_webview
return WebView(
...
onPageFinished: (result) async {
String html =
(await _mobileWebViewController!.evaluateJavascript(
"window.document.getElementsByTagName('html')[0].outerHTML;"));
//read(html);
},
...
}
Thanks~
This is the most important, or is there any alternative, which can communicate between JS and dart?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.