Skip to content

Commit

Permalink
[desktop-webview-window] Control URL requests made by the webview (Br…
Browse files Browse the repository at this point in the history
…eaking!) (#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
  • Loading branch information
Iri-Hor committed Nov 8, 2023
1 parent f36e553 commit 6927ef8
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 32 deletions.
4 changes: 3 additions & 1 deletion packages/desktop_webview_window/example/lib/main.dart
Expand Up @@ -138,13 +138,15 @@ class _MyAppState extends State<MyApp> {
..setBrightness(Brightness.dark)
..setApplicationNameForUserAgent(" WebviewExample/1.0.0")
..launch(_controller.text)
..addOnUrlRequestCallback((url) {
..setOnUrlRequestCallback((url) {
debugPrint('url: $url');
final uri = Uri.parse(url);
if (uri.path == '/login_success') {
debugPrint('login success. token: ${uri.queryParameters['token']}');
webview.close();
}
// grant navigation request
return true;
})
..onClose.whenComplete(() {
debugPrint("on close");
Expand Down
Expand Up @@ -139,12 +139,12 @@ class WebviewWindow {
break;
case "onUrlRequested":
final url = args['url'] as String;
webview.notifyUrlChanged(url);
final ret = webview.notifyUrlChanged(url);
await _otherIsolateMessageHandler.invokeMethod('onUrlRequested', {
'webViewId': viewId,
'url': url,
});
break;
return ret;
case "onWebMessageReceived":
final message = args['message'] as String;
webview.notifyWebMessageReceived(message);
Expand Down
8 changes: 3 additions & 5 deletions packages/desktop_webview_window/lib/src/webview.dart
Expand Up @@ -10,7 +10,7 @@ typedef OnHistoryChangedCallback = void Function(

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

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

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

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

void addOnUrlRequestCallback(OnUrlRequestCallback callback);

void removeOnUrlRequestCallback(OnUrlRequestCallback callback);
void setOnUrlRequestCallback(OnUrlRequestCallback? callback);

void addOnWebMessageReceivedCallback(OnWebMessageReceivedCallback callback);

Expand Down
30 changes: 14 additions & 16 deletions packages/desktop_webview_window/lib/src/webview_impl.dart
Expand Up @@ -22,9 +22,9 @@ class WebviewImpl extends Webview {

OnHistoryChangedCallback? _onHistoryChanged;

final ValueNotifier<bool> _isNaivgating = ValueNotifier<bool>(false);
final ValueNotifier<bool> _isNavigating = ValueNotifier<bool>(false);

final Set<OnUrlRequestCallback> _onUrlRequestCallbacks = {};
OnUrlRequestCallback? _onUrlRequestCallback = null;

final Set<OnWebMessageReceivedCallback> _onWebMessageReceivedCallbacks = {};

Expand Down Expand Up @@ -57,12 +57,14 @@ class WebviewImpl extends Webview {
}

void onNavigationStarted() {
_isNaivgating.value = true;
_isNavigating.value = true;
}

void notifyUrlChanged(String url) {
for (final callback in _onUrlRequestCallbacks) {
callback(url);
bool notifyUrlChanged(String url) {
if(_onUrlRequestCallback != null) {
return _onUrlRequestCallback!(url);
} else {
return true;
}
}

Expand All @@ -73,11 +75,11 @@ class WebviewImpl extends Webview {
}

void onNavigationCompleted() {
_isNaivgating.value = false;
_isNavigating.value = false;
}

@override
ValueListenable<bool> get isNavigating => _isNaivgating;
ValueListenable<bool> get isNavigating => _isNavigating;

@override
void registerJavaScriptMessageHandler(
Expand Down Expand Up @@ -121,10 +123,11 @@ class WebviewImpl extends Webview {
}

@override
void launch(String url) async {
void launch(String url, {bool triggerOnUrlRequestEvent=true}) async {
await channel.invokeMethod("launch", {
"url": url,
"viewId": viewId,
"triggerOnUrlRequestEvent": triggerOnUrlRequestEvent,
});
}

Expand Down Expand Up @@ -223,13 +226,8 @@ class WebviewImpl extends Webview {
}

@override
void addOnUrlRequestCallback(OnUrlRequestCallback callback) {
_onUrlRequestCallbacks.add(callback);
}

@override
void removeOnUrlRequestCallback(OnUrlRequestCallback callback) {
_onUrlRequestCallbacks.remove(callback);
void setOnUrlRequestCallback(OnUrlRequestCallback? callback) {
_onUrlRequestCallback = callback;
}

@override
Expand Down
42 changes: 34 additions & 8 deletions packages/desktop_webview_window/windows/web_view.cc
Expand Up @@ -8,6 +8,8 @@
#include <utility>
#include <thread>

#include "flutter/method_result_functions.h"

#include "web_view.h"
#include "utils.h"
#include "strconv.h"
Expand Down Expand Up @@ -144,14 +146,34 @@ void WebView::OnWebviewControllerCreated() {
std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("id"), flutter::EncodableValue(web_view_id_)},
}));
LPWSTR uri;
args->get_Uri(&uri);
method_channel_->InvokeMethod(
"onUrlRequested",
std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("id"), flutter::EncodableValue(web_view_id_)},
{flutter::EncodableValue("url"), flutter::EncodableValue(wide_to_utf8(std::wstring(uri)))},
}));

if (triggerOnUrlRequestedEvent) {
LPWSTR uri;
args->get_Uri(&uri);

auto result_handler = std::make_unique<flutter::MethodResultFunctions<>>(
[uri, sender, this](const flutter::EncodableValue* success_value) {
const bool letPass = std::get<bool>(*success_value);
if (letPass) {
this->setTriggerOnUrlRequestedEvent(false);
sender->Navigate(uri);
}
},
nullptr, nullptr);

method_channel_->InvokeMethod(
"onUrlRequested",
std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("id"), flutter::EncodableValue(web_view_id_)},
{flutter::EncodableValue("url"), flutter::EncodableValue(wide_to_utf8(std::wstring(uri)))},
}), std::move(result_handler));

// navigation is canceled here and retriggered later from the callback passed to the method channel
args->put_Cancel(true);
} else {
args->put_Cancel(false);
triggerOnUrlRequestedEvent = true;
}
return S_OK;
}
).Get(), nullptr);
Expand Down Expand Up @@ -323,6 +345,10 @@ void WebView::PostWebMessageAsJson(const std::wstring& webmessage,
}
}

void WebView::setTriggerOnUrlRequestedEvent(const bool value) {
this->triggerOnUrlRequestedEvent = value;
}

WebView::~WebView() {
if (webview_) {
webview_->Stop();
Expand Down
4 changes: 4 additions & 0 deletions packages/desktop_webview_window/windows/web_view.h
Expand Up @@ -60,6 +60,8 @@ class WebView {
void PostWebMessageAsJson(const std::wstring &webmessage,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> completer);

void setTriggerOnUrlRequestedEvent(const bool value);

private:
wil::unique_hwnd view_window_;

Expand All @@ -79,6 +81,8 @@ class WebView {

std::wstring user_data_folder_;

bool triggerOnUrlRequestedEvent{true};

void OnWebviewControllerCreated();

[[nodiscard]] bool CanGoBack() const;
Expand Down
Expand Up @@ -86,6 +86,7 @@ void WebviewWindowPlugin::HandleMethodCall(

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

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

0 comments on commit 6927ef8

Please sign in to comment.