Skip to content

Commit 6927ef8

Browse files
authored
[desktop-webview-window] Control URL requests made by the webview (Breaking!) (#296)
* commit * commit * commit2 * revert main * cleanup * rename * changes * changes * changes * change how to set callback * extend launch by a switch allowing to decide whether the OnUrlRequestEvent is to be triggered or not
1 parent f36e553 commit 6927ef8

File tree

7 files changed

+62
-32
lines changed

7 files changed

+62
-32
lines changed

packages/desktop_webview_window/example/lib/main.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,15 @@ class _MyAppState extends State<MyApp> {
138138
..setBrightness(Brightness.dark)
139139
..setApplicationNameForUserAgent(" WebviewExample/1.0.0")
140140
..launch(_controller.text)
141-
..addOnUrlRequestCallback((url) {
141+
..setOnUrlRequestCallback((url) {
142142
debugPrint('url: $url');
143143
final uri = Uri.parse(url);
144144
if (uri.path == '/login_success') {
145145
debugPrint('login success. token: ${uri.queryParameters['token']}');
146146
webview.close();
147147
}
148+
// grant navigation request
149+
return true;
148150
})
149151
..onClose.whenComplete(() {
150152
debugPrint("on close");

packages/desktop_webview_window/lib/desktop_webview_window.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,12 @@ class WebviewWindow {
139139
break;
140140
case "onUrlRequested":
141141
final url = args['url'] as String;
142-
webview.notifyUrlChanged(url);
142+
final ret = webview.notifyUrlChanged(url);
143143
await _otherIsolateMessageHandler.invokeMethod('onUrlRequested', {
144144
'webViewId': viewId,
145145
'url': url,
146146
});
147-
break;
147+
return ret;
148148
case "onWebMessageReceived":
149149
final message = args['message'] as String;
150150
webview.notifyWebMessageReceived(message);

packages/desktop_webview_window/lib/src/webview.dart

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ typedef OnHistoryChangedCallback = void Function(
1010

1111
/// Callback when WebView start to load a URL.
1212
/// [url] is the URL string.
13-
typedef OnUrlRequestCallback = void Function(String url);
13+
typedef OnUrlRequestCallback = bool Function(String url);
1414

1515
/// Callback when WebView receives a web message
1616
/// [message] constains the webmessage
@@ -35,7 +35,7 @@ abstract class Webview {
3535
void setPromptHandler(PromptHandler? handler);
3636

3737
/// Navigates to the given URL.
38-
void launch(String url);
38+
void launch(String url, {bool triggerOnUrlRequestEvent=true});
3939

4040
/// change webview theme.
4141
///
@@ -74,9 +74,7 @@ abstract class Webview {
7474
/// Register a callback that will be invoked when the webview history changes.
7575
void setOnHistoryChangedCallback(OnHistoryChangedCallback? callback);
7676

77-
void addOnUrlRequestCallback(OnUrlRequestCallback callback);
78-
79-
void removeOnUrlRequestCallback(OnUrlRequestCallback callback);
77+
void setOnUrlRequestCallback(OnUrlRequestCallback? callback);
8078

8179
void addOnWebMessageReceivedCallback(OnWebMessageReceivedCallback callback);
8280

packages/desktop_webview_window/lib/src/webview_impl.dart

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ class WebviewImpl extends Webview {
2222

2323
OnHistoryChangedCallback? _onHistoryChanged;
2424

25-
final ValueNotifier<bool> _isNaivgating = ValueNotifier<bool>(false);
25+
final ValueNotifier<bool> _isNavigating = ValueNotifier<bool>(false);
2626

27-
final Set<OnUrlRequestCallback> _onUrlRequestCallbacks = {};
27+
OnUrlRequestCallback? _onUrlRequestCallback = null;
2828

2929
final Set<OnWebMessageReceivedCallback> _onWebMessageReceivedCallbacks = {};
3030

@@ -57,12 +57,14 @@ class WebviewImpl extends Webview {
5757
}
5858

5959
void onNavigationStarted() {
60-
_isNaivgating.value = true;
60+
_isNavigating.value = true;
6161
}
6262

63-
void notifyUrlChanged(String url) {
64-
for (final callback in _onUrlRequestCallbacks) {
65-
callback(url);
63+
bool notifyUrlChanged(String url) {
64+
if(_onUrlRequestCallback != null) {
65+
return _onUrlRequestCallback!(url);
66+
} else {
67+
return true;
6668
}
6769
}
6870

@@ -73,11 +75,11 @@ class WebviewImpl extends Webview {
7375
}
7476

7577
void onNavigationCompleted() {
76-
_isNaivgating.value = false;
78+
_isNavigating.value = false;
7779
}
7880

7981
@override
80-
ValueListenable<bool> get isNavigating => _isNaivgating;
82+
ValueListenable<bool> get isNavigating => _isNavigating;
8183

8284
@override
8385
void registerJavaScriptMessageHandler(
@@ -121,10 +123,11 @@ class WebviewImpl extends Webview {
121123
}
122124

123125
@override
124-
void launch(String url) async {
126+
void launch(String url, {bool triggerOnUrlRequestEvent=true}) async {
125127
await channel.invokeMethod("launch", {
126128
"url": url,
127129
"viewId": viewId,
130+
"triggerOnUrlRequestEvent": triggerOnUrlRequestEvent,
128131
});
129132
}
130133

@@ -223,13 +226,8 @@ class WebviewImpl extends Webview {
223226
}
224227

225228
@override
226-
void addOnUrlRequestCallback(OnUrlRequestCallback callback) {
227-
_onUrlRequestCallbacks.add(callback);
228-
}
229-
230-
@override
231-
void removeOnUrlRequestCallback(OnUrlRequestCallback callback) {
232-
_onUrlRequestCallbacks.remove(callback);
229+
void setOnUrlRequestCallback(OnUrlRequestCallback? callback) {
230+
_onUrlRequestCallback = callback;
233231
}
234232

235233
@override

packages/desktop_webview_window/windows/web_view.cc

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <utility>
99
#include <thread>
1010

11+
#include "flutter/method_result_functions.h"
12+
1113
#include "web_view.h"
1214
#include "utils.h"
1315
#include "strconv.h"
@@ -144,14 +146,34 @@ void WebView::OnWebviewControllerCreated() {
144146
std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
145147
{flutter::EncodableValue("id"), flutter::EncodableValue(web_view_id_)},
146148
}));
147-
LPWSTR uri;
148-
args->get_Uri(&uri);
149-
method_channel_->InvokeMethod(
150-
"onUrlRequested",
151-
std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
152-
{flutter::EncodableValue("id"), flutter::EncodableValue(web_view_id_)},
153-
{flutter::EncodableValue("url"), flutter::EncodableValue(wide_to_utf8(std::wstring(uri)))},
154-
}));
149+
150+
if (triggerOnUrlRequestedEvent) {
151+
LPWSTR uri;
152+
args->get_Uri(&uri);
153+
154+
auto result_handler = std::make_unique<flutter::MethodResultFunctions<>>(
155+
[uri, sender, this](const flutter::EncodableValue* success_value) {
156+
const bool letPass = std::get<bool>(*success_value);
157+
if (letPass) {
158+
this->setTriggerOnUrlRequestedEvent(false);
159+
sender->Navigate(uri);
160+
}
161+
},
162+
nullptr, nullptr);
163+
164+
method_channel_->InvokeMethod(
165+
"onUrlRequested",
166+
std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
167+
{flutter::EncodableValue("id"), flutter::EncodableValue(web_view_id_)},
168+
{flutter::EncodableValue("url"), flutter::EncodableValue(wide_to_utf8(std::wstring(uri)))},
169+
}), std::move(result_handler));
170+
171+
// navigation is canceled here and retriggered later from the callback passed to the method channel
172+
args->put_Cancel(true);
173+
} else {
174+
args->put_Cancel(false);
175+
triggerOnUrlRequestedEvent = true;
176+
}
155177
return S_OK;
156178
}
157179
).Get(), nullptr);
@@ -323,6 +345,10 @@ void WebView::PostWebMessageAsJson(const std::wstring& webmessage,
323345
}
324346
}
325347

348+
void WebView::setTriggerOnUrlRequestedEvent(const bool value) {
349+
this->triggerOnUrlRequestedEvent = value;
350+
}
351+
326352
WebView::~WebView() {
327353
if (webview_) {
328354
webview_->Stop();

packages/desktop_webview_window/windows/web_view.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class WebView {
6060
void PostWebMessageAsJson(const std::wstring &webmessage,
6161
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> completer);
6262

63+
void setTriggerOnUrlRequestedEvent(const bool value);
64+
6365
private:
6466
wil::unique_hwnd view_window_;
6567

@@ -79,6 +81,8 @@ class WebView {
7981

8082
std::wstring user_data_folder_;
8183

84+
bool triggerOnUrlRequestedEvent{true};
85+
8286
void OnWebviewControllerCreated();
8387

8488
[[nodiscard]] bool CanGoBack() const;

packages/desktop_webview_window/windows/web_view_window_plugin.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ void WebviewWindowPlugin::HandleMethodCall(
8686

8787
auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
8888
auto url = std::get<std::string>(arguments->at(flutter::EncodableValue("url")));
89+
auto triggerOnUrlRequestEvent = std::get<bool>(arguments->at(flutter::EncodableValue("triggerOnUrlRequestEvent")));
8990

9091
if (!windows_.count(window_id)) {
9192
result->Error("0", "can not find webview window for id");
@@ -95,6 +96,7 @@ void WebviewWindowPlugin::HandleMethodCall(
9596
result->Error("0", "webview window not ready");
9697
return;
9798
}
99+
windows_[window_id]->GetWebView()->setTriggerOnUrlRequestedEvent(triggerOnUrlRequestEvent);
98100
windows_[window_id]->GetWebView()->Navigate(utf8_to_wide(url));
99101
result->Success();
100102
} else if (method_call.method_name() == "addScriptToExecuteOnDocumentCreated") {

0 commit comments

Comments
 (0)