Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[webview_flutter] Add support for onPageStarted event #2295

Merged
merged 7 commits into from
Dec 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/webview_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.3.18

* Add support for onPageStarted event.

## 0.3.17

* Fix pedantic lint errors. Added missing documentation and awaited some futures
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package io.flutter.plugins.webviewflutter;

import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.os.Build;
import android.util.Log;
import android.view.KeyEvent;
Expand Down Expand Up @@ -66,6 +67,12 @@ private boolean shouldOverrideUrlLoading(WebView view, String url) {
return true;
}

private void onPageStarted(WebView view, String url) {
Map<String, Object> args = new HashMap<>();
args.put("url", url);
methodChannel.invokeMethod("onPageStarted", args);
}

private void onPageFinished(WebView view, String url) {
Map<String, Object> args = new HashMap<>();
args.put("url", url);
Expand Down Expand Up @@ -106,6 +113,11 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request
return FlutterWebViewClient.this.shouldOverrideUrlLoading(view, request);
}

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
FlutterWebViewClient.this.onPageStarted(view, url);
}

@Override
public void onPageFinished(WebView view, String url) {
FlutterWebViewClient.this.onPageFinished(view, url);
Expand All @@ -132,6 +144,11 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) {
return FlutterWebViewClient.this.shouldOverrideUrlLoading(view, url);
}

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
FlutterWebViewClient.this.onPageStarted(view, url);
}

@Override
public void onPageFinished(WebView view, String url) {
FlutterWebViewClient.this.onPageFinished(view, url);
Expand Down
3 changes: 3 additions & 0 deletions packages/webview_flutter/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ class _WebViewExampleState extends State<WebViewExample> {
print('allowing navigation to $request');
return NavigationDecision.navigate;
},
onPageStarted: (String url) {
print('Page started loading: $url');
},
onPageFinished: (String url) {
print('Page finished loading: $url');
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ void main() {
testWidgets('loadUrl with headers', (WidgetTester tester) async {
final Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
final StreamController<String> pageStarts = StreamController<String>();
final StreamController<String> pageLoads = StreamController<String>();
await tester.pumpWidget(
Directionality(
Expand All @@ -73,6 +74,9 @@ void main() {
controllerCompleter.complete(controller);
},
javascriptMode: JavascriptMode.unrestricted,
onPageStarted: (String url) {
pageStarts.add(url);
},
onPageFinished: (String url) {
pageLoads.add(url);
},
Expand All @@ -88,7 +92,9 @@ void main() {
final String currentUrl = await controller.currentUrl();
expect(currentUrl, 'https://flutter-header-echo.herokuapp.com/');

await pageStarts.stream.firstWhere((String url) => url == currentUrl);
await pageLoads.stream.firstWhere((String url) => url == currentUrl);

final String content = await controller
.evaluateJavascript('document.documentElement.innerText');
expect(content.contains('flutter_test_header'), isTrue);
Expand All @@ -97,6 +103,7 @@ void main() {
testWidgets('JavaScriptChannel', (WidgetTester tester) async {
final Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
final Completer<void> pageStarted = Completer<void>();
final Completer<void> pageLoaded = Completer<void>();
final List<String> messagesReceived = <String>[];
await tester.pumpWidget(
Expand All @@ -121,13 +128,17 @@ void main() {
},
),
].toSet(),
onPageStarted: (String url) {
pageStarted.complete(null);
},
onPageFinished: (String url) {
pageLoaded.complete(null);
},
),
),
);
final WebViewController controller = await controllerCompleter.future;
await pageStarted.future;
await pageLoaded.future;

expect(messagesReceived, isEmpty);
Expand Down Expand Up @@ -155,6 +166,7 @@ void main() {
final String resizeTestBase64 =
base64Encode(const Utf8Encoder().convert(resizeTest));
final Completer<void> resizeCompleter = Completer<void>();
final Completer<void> pageStarted = Completer<void>();
final Completer<void> pageLoaded = Completer<void>();
final Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
Expand All @@ -176,6 +188,9 @@ void main() {
},
),
].toSet(),
onPageStarted: (String url) {
pageStarted.complete(null);
},
onPageFinished: (String url) {
pageLoaded.complete(null);
},
Expand All @@ -198,6 +213,7 @@ void main() {
);

await controllerCompleter.future;
await pageStarted.future;
await pageLoaded.future;

expect(resizeCompleter.isCompleted, false);
Expand Down Expand Up @@ -343,6 +359,7 @@ void main() {
testWidgets('Auto media playback', (WidgetTester tester) async {
Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
Completer<void> pageStarted = Completer<void>();
Completer<void> pageLoaded = Completer<void>();

await tester.pumpWidget(
Expand All @@ -355,6 +372,9 @@ void main() {
controllerCompleter.complete(controller);
},
javascriptMode: JavascriptMode.unrestricted,
onPageStarted: (String url) {
pageStarted.complete(null);
},
onPageFinished: (String url) {
pageLoaded.complete(null);
},
Expand All @@ -363,12 +383,14 @@ void main() {
),
);
WebViewController controller = await controllerCompleter.future;
await pageStarted.future;
await pageLoaded.future;

String isPaused = await controller.evaluateJavascript('isPaused();');
expect(isPaused, _webviewBool(false));

controllerCompleter = Completer<WebViewController>();
pageStarted = Completer<void>();
pageLoaded = Completer<void>();

// We change the key to re-create a new webview as we change the initialMediaPlaybackPolicy
Expand All @@ -382,6 +404,9 @@ void main() {
controllerCompleter.complete(controller);
},
javascriptMode: JavascriptMode.unrestricted,
onPageStarted: (String url) {
pageStarted.complete(null);
},
onPageFinished: (String url) {
pageLoaded.complete(null);
},
Expand All @@ -392,6 +417,7 @@ void main() {
);

controller = await controllerCompleter.future;
await pageStarted.future;
await pageLoaded.future;

isPaused = await controller.evaluateJavascript('isPaused();');
Expand All @@ -402,6 +428,7 @@ void main() {
(WidgetTester tester) async {
final Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
Completer<void> pageStarted = Completer<void>();
Completer<void> pageLoaded = Completer<void>();

final GlobalKey key = GlobalKey();
Expand All @@ -415,6 +442,9 @@ void main() {
controllerCompleter.complete(controller);
},
javascriptMode: JavascriptMode.unrestricted,
onPageStarted: (String url) {
pageStarted.complete(null);
},
onPageFinished: (String url) {
pageLoaded.complete(null);
},
Expand All @@ -423,11 +453,13 @@ void main() {
),
);
final WebViewController controller = await controllerCompleter.future;
await pageStarted.future;
await pageLoaded.future;

String isPaused = await controller.evaluateJavascript('isPaused();');
expect(isPaused, _webviewBool(false));

pageStarted = Completer<void>();
pageLoaded = Completer<void>();

await tester.pumpWidget(
Expand All @@ -440,6 +472,9 @@ void main() {
controllerCompleter.complete(controller);
},
javascriptMode: JavascriptMode.unrestricted,
onPageStarted: (String url) {
pageStarted.complete(null);
},
onPageFinished: (String url) {
pageLoaded.complete(null);
},
Expand All @@ -451,6 +486,7 @@ void main() {

await controller.reload();

await pageStarted.future;
await pageLoaded.future;

isPaused = await controller.evaluateJavascript('isPaused();');
Expand All @@ -469,6 +505,7 @@ void main() {
''';
final String getTitleTestBase64 =
base64Encode(const Utf8Encoder().convert(getTitleTest));
final Completer<void> pageStarted = Completer<void>();
final Completer<void> pageLoaded = Completer<void>();
final Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
Expand All @@ -481,6 +518,9 @@ void main() {
onWebViewCreated: (WebViewController controller) {
controllerCompleter.complete(controller);
},
onPageStarted: (String url) {
pageStarted.complete(null);
},
onPageFinished: (String url) {
pageLoaded.complete(null);
},
Expand All @@ -489,6 +529,7 @@ void main() {
);

final WebViewController controller = await controllerCompleter.future;
await pageStarted.future;
await pageLoaded.future;

final String title = await controller.getTitle();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ - (instancetype)initWithChannel:(FlutterMethodChannel*)channel {
return self;
}

#pragma mark - WKNavigationDelegate conformance

- (void)webView:(WKWebView*)webView didStartProvisionalNavigation:(WKNavigation*)navigation {
[_methodChannel invokeMethod:@"onPageStarted" arguments:@{@"url" : webView.URL.absoluteString}];
}

- (void)webView:(WKWebView*)webView
decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
Expand Down
3 changes: 3 additions & 0 deletions packages/webview_flutter/lib/platform_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ abstract class WebViewPlatformCallbacksHandler {
/// If true is returned the navigation is allowed, otherwise it is blocked.
FutureOr<bool> onNavigationRequest({String url, bool isForMainFrame});

/// Invoked by [WebViewPlatformController] when a page has started loading.
void onPageStarted(String url);

/// Invoked by [WebViewPlatformController] when a page has finished loading.
void onPageFinished(String url);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/webview_flutter/lib/src/webview_method_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController {
case 'onPageFinished':
_platformCallbacksHandler.onPageFinished(call.arguments['url']);
return null;
case 'onPageStarted':
_platformCallbacksHandler.onPageStarted(call.arguments['url']);
return null;
}
throw MissingPluginException(
'${call.method} was invoked but has no handler');
Expand Down
14 changes: 14 additions & 0 deletions packages/webview_flutter/lib/webview_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ enum NavigationDecision {
typedef FutureOr<NavigationDecision> NavigationDelegate(
NavigationRequest navigation);

/// Signature for when a [WebView] has started loading a page.
typedef void PageStartedCallback(String url);

/// Signature for when a [WebView] has finished loading a page.
typedef void PageFinishedCallback(String url);

Expand Down Expand Up @@ -142,6 +145,7 @@ class WebView extends StatefulWidget {
this.javascriptChannels,
this.navigationDelegate,
this.gestureRecognizers,
this.onPageStarted,
this.onPageFinished,
this.debuggingEnabled = false,
this.userAgent,
Expand Down Expand Up @@ -257,6 +261,9 @@ class WebView extends StatefulWidget {
/// * When a navigationDelegate is set HTTP requests do not include the HTTP referer header.
final NavigationDelegate navigationDelegate;

/// Invoked when a page starts loading.
final PageStartedCallback onPageStarted;

/// Invoked when a page has finished loading.
///
/// This is invoked only for the main frame.
Expand Down Expand Up @@ -452,6 +459,13 @@ class _PlatformCallbacksHandler implements WebViewPlatformCallbacksHandler {
return allowNavigation;
}

@override
void onPageStarted(String url) {
if (_widget.onPageStarted != null) {
_widget.onPageStarted(url);
}
}

@override
void onPageFinished(String url) {
if (_widget.onPageFinished != null) {
Expand Down
Loading