Skip to content
Merged
Prev Previous commit
Next Next commit
Preserve undefined and null output
  • Loading branch information
LinXunFeng committed Mar 24, 2025
commit 136205679dfe82d59d9925ba54a1daba089116c8
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ Future<void> main() async {
await expectLater(channelCompleter.future, completion('hello'));
});

testWidgets('JavaScriptChannel can receive undefined',
testWidgets('JavaScriptChannel can receive undefined and null',
(WidgetTester tester) async {
final Completer<void> pageFinished = Completer<void>();
final PlatformWebViewController controller = PlatformWebViewController(
Expand All @@ -291,12 +291,12 @@ Future<void> main() async {
unawaited(delegate.setOnPageFinished((_) => pageFinished.complete()));
unawaited(controller.setPlatformNavigationDelegate(delegate));

final Completer<String> channelCompleter = Completer<String>();
final List<String> messages = <String>[];
await controller.addJavaScriptChannel(
JavaScriptChannelParams(
name: 'Channel',
onMessageReceived: (JavaScriptMessage message) {
channelCompleter.complete(message.message);
messages.add(message.message);
},
),
);
Expand All @@ -316,7 +316,10 @@ Future<void> main() async {
await pageFinished.future;

await controller.runJavaScript('Channel.postMessage(undefined);');
await expectLater(channelCompleter.future, completion(''));
await controller.runJavaScript('Channel.postMessage(null);');

await tester.pumpAndSettle();
expect(messages, <String>['undefined', 'null']);
});

testWidgets('resize webview', (WidgetTester tester) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ class WebKitWebViewController extends PlatformWebViewController {
webKitParams.name,
),
]);
await _injectPostMessageOverride(webKitParams.name);
}

@override
Expand Down Expand Up @@ -768,6 +769,47 @@ window.addEventListener("error", function(e) {
await controller.addUserScript(overrideScript);
}

Future<void> _injectPostMessageOverride(String channelName) async {
final WKUserScript overrideScript =
_webKitParams.webKitProxy.newWKUserScript(
source: '''
var _flutter_webview_plugin_overrides = _flutter_webview_plugin_overrides || {};

_flutter_webview_plugin_overrides.originalPostMessageFunctions = _flutter_webview_plugin_overrides.originalPostMessageFunctions || {};

(function() {
if (window.webkit && window.webkit.messageHandlers) {
const handlerName = "$channelName";
const handler = window.webkit.messageHandlers[handlerName];

if (handler &&
typeof handler.postMessage === 'function' &&
!_flutter_webview_plugin_overrides.originalPostMessageFunctions[handlerName]) {

_flutter_webview_plugin_overrides.originalPostMessageFunctions[handlerName] = handler.postMessage;

handler.postMessage = function(data) {
if (data === undefined) {
return _flutter_webview_plugin_overrides.originalPostMessageFunctions[handlerName].call(this, "undefined");
}
if (data === null) {
return _flutter_webview_plugin_overrides.originalPostMessageFunctions[handlerName].call(this, "null");
}
return _flutter_webview_plugin_overrides.originalPostMessageFunctions[handlerName].call(this, data);
};
}
}
})();
''',
injectionTime: UserScriptInjectionTime.atDocumentStart,
isForMainFrameOnly: false,
);

final WKUserContentController controller =
await _webView.configuration.getUserContentController();
await controller.addUserScript(overrideScript);
}

// WKWebView does not support removing a single user script, so all user
// scripts and all message handlers are removed instead. And the JavaScript
// channels that shouldn't be removed are re-registered. Note that this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ void main() {
final WKUserScript userScript =
verify(mockUserContentController.addUserScript(captureAny))
.captured
.single as WKUserScript;
.toList().first as WKUserScript;
expect(userScript.source, 'window.name = webkit.messageHandlers.name;');
expect(
userScript.injectionTime,
Expand Down Expand Up @@ -1008,7 +1008,7 @@ void main() {
final WKUserScript userScript =
verify(mockUserContentController.addUserScript(captureAny))
.captured
.single as WKUserScript;
.toList().first as WKUserScript;
expect(userScript.source, 'window.name2 = webkit.messageHandlers.name2;');
expect(
userScript.injectionTime,
Expand Down