0% found this document useful (0 votes)
153 views

Platform Interface - Dart

The document describes a WebViewPlatformCallbacksHandler interface that is used to handle callbacks from a WebViewPlatformController. It defines methods for handling events like JavaScript messages, navigation requests, page loading status, and errors. The WebResourceError class represents errors that can occur when loading web resources. The WebViewPlatformController interface defines methods for controlling a webview, like loading URLs, updating settings, navigation, and evaluating JavaScript.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
153 views

Platform Interface - Dart

The document describes a WebViewPlatformCallbacksHandler interface that is used to handle callbacks from a WebViewPlatformController. It defines methods for handling events like JavaScript messages, navigation requests, page loading status, and errors. The WebResourceError class represents errors that can occur when loading web resources. The WebViewPlatformController interface defines methods for controlling a webview, like loading URLs, updating settings, navigation, and evaluating JavaScript.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

// Copyright 2019 The Chromium Authors. All rights reserved.

// Use of this source code is governed by a BSD-style license that can be


// found in the LICENSE file.

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';

import 'webview_flutter.dart';

/// Interface for callbacks made by [WebViewPlatformController].


///
/// The webview plugin implements this class, and passes an instance to the [Web
ViewPlatformController].
/// [WebViewPlatformController] is notifying this handler on events that happene
d on the platform's webview.
abstract class WebViewPlatformCallbacksHandler {
/// Invoked by [WebViewPlatformController] when a JavaScript channel message i
s received.
void onJavaScriptChannelMessage(String channel, String message);

/// Invoked by [WebViewPlatformController] when a navigation request is pendin


g.
///
/// 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);

/// Report web resource loading error to the host application.


void onWebResourceError(WebResourceError error);
}

/// Possible error type categorizations used by [WebResourceError].


enum WebResourceErrorType {
/// User authentication failed on server.
authentication,

/// Malformed URL.


badUrl,

/// Failed to connect to the server.


connect,

/// Failed to perform SSL handshake.


failedSslHandshake,

/// Generic file error.


file,
/// File not found.
fileNotFound,

/// Server or proxy hostname lookup failed.


hostLookup,
/// Failed to read or write to the server.
io,

/// User authentication failed on proxy.


proxyAuthentication,

/// Too many redirects.


redirectLoop,

/// Connection timed out.


timeout,

/// Too many requests during this load.


tooManyRequests,

/// Generic error.


unknown,

/// Resource load was canceled by Safe Browsing.


unsafeResource,

/// Unsupported authentication scheme (not basic or digest).


unsupportedAuthScheme,

/// Unsupported URI scheme.


unsupportedScheme,

/// The web content process was terminated.


webContentProcessTerminated,

/// The web view was invalidated.


webViewInvalidated,

/// A JavaScript exception occurred.


javaScriptExceptionOccurred,

/// The result of JavaScript execution could not be returned.


javaScriptResultTypeIsUnsupported,
}

/// Error returned in `WebView.onWebResourceError` when a web resource loading e


rror has occurred.
class WebResourceError {
/// Creates a new [WebResourceError]
///
/// A user should not need to instantiate this class, but will receive one in
/// [WebResourceErrorCallback].
WebResourceError({
@required this.errorCode,
@required this.description,
this.domain,
this.errorType,
this.failingUrl,
}) : assert(errorCode != null),
assert(description != null);
/// Raw code of the error from the respective platform.
///
/// On Android, the error code will be a constant from a
/// [WebViewClient](https://developer.android.com/reference/android/webkit/Web
ViewClient#summary) and
/// will have a corresponding [errorType].
///
/// On iOS, the error code will be a constant from `NSError.code` in
/// Objective-C. See
/// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual
/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html
/// for more information on error handling on iOS. Some possible error codes
/// can be found at https://developer.apple.com/documentation/webkit/wkerrorco
de?language=objc.
final int errorCode;

/// The domain of where to find the error code.


///
/// This field is only available on iOS and represents a "domain" from where
/// the [errorCode] is from. This value is taken directly from an `NSError`
/// in Objective-C. See
/// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual
/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html
/// for more information on error handling on iOS.
final String domain;

/// Description of the error that can be used to communicate the problem to th
e user.
final String description;

/// The type this error can be categorized as.


///
/// This will never be `null` on Android, but can be `null` on iOS.
final WebResourceErrorType errorType;

/// Gets the URL for which the resource request was made.
///
/// This value is not provided on iOS. Alternatively, you can keep track of
/// the last values provided to [WebViewPlatformController.loadUrl].
final String failingUrl;
}

/// Interface for talking to the webview's platform implementation.


///
/// An instance implementing this interface is passed to the `onWebViewPlatformC
reated` callback that is
/// passed to [WebViewPlatformBuilder#onWebViewPlatformCreated].
///
/// Platform implementations that live in a separate package should extend this
class rather than
/// implement it as webview_flutter does not consider newly added methods to be
breaking changes.
/// Extending this class (using `extends`) ensures that the subclass will get th
e default
/// implementation, while platform implementations that `implements` this interf
ace will be broken
/// by newly added [WebViewPlatformController] methods.
abstract class WebViewPlatformController {
/// Creates a new WebViewPlatform.
///
/// Callbacks made by the WebView will be delegated to `handler`.
///
/// The `handler` parameter must not be null.
WebViewPlatformController(WebViewPlatformCallbacksHandler handler);

/// Loads the specified URL.


///
/// If `headers` is not null and the URL is an HTTP URL, the key value paris i
n `headers` will
/// be added as key value pairs of HTTP headers for the request.
///
/// `url` must not be null.
///
/// Throws an ArgumentError if `url` is not a valid URL string.
Future<void> loadUrl(
String url,
Map<String, String> headers,
) {
throw UnimplementedError(
"WebView loadUrl is not implemented on the current platform");
}

/// Updates the webview settings.


///
/// Any non null field in `settings` will be set as the new setting value.
/// All null fields in `settings` are ignored.
Future<void> updateSettings(WebSettings setting) {
throw UnimplementedError(
"WebView updateSettings is not implemented on the current platform");
}

/// Accessor to the current URL that the WebView is displaying.


///
/// If no URL was ever loaded, returns `null`.
Future<String> currentUrl() {
throw UnimplementedError(
"WebView currentUrl is not implemented on the current platform");
}

/// Checks whether there's a back history item.


Future<bool> canGoBack() {
throw UnimplementedError(
"WebView canGoBack is not implemented on the current platform");
}

/// Checks whether there's a forward history item.


Future<bool> canGoForward() {
throw UnimplementedError(
"WebView canGoForward is not implemented on the current platform");
}

/// Goes back in the history of this WebView.


///
/// If there is no back history item this is a no-op.
Future<void> goBack() {
throw UnimplementedError(
"WebView goBack is not implemented on the current platform");
}

/// Goes forward in the history of this WebView.


///
/// If there is no forward history item this is a no-op.
Future<void> goForward() {
throw UnimplementedError(
"WebView goForward is not implemented on the current platform");
}

/// Reloads the current URL.


Future<void> reload() {
throw UnimplementedError(
"WebView reload is not implemented on the current platform");
}

/// Clears all caches used by the [WebView].


///
/// The following caches are cleared:
/// 1. Browser HTTP Cache.
/// 2. [Cache API](https://developers.google.com/web/fundamentals/instant-an
d-offline/web-storage/cache-api) caches.
/// These are not yet supported in iOS WkWebView. Service workers tend to u
se this cache.
/// 3. Application cache.
/// 4. Local Storage.
Future<void> clearCache() {
throw UnimplementedError(
"WebView clearCache is not implemented on the current platform");
}

/// Evaluates a JavaScript expression in the context of the current page.


///
/// The Future completes with an error if a JavaScript error occurred, or if t
he type of the
/// evaluated expression is not supported(e.g on iOS not all non primitive typ
e can be evaluated).
Future<String> evaluateJavascript(String javascriptString) {
throw UnimplementedError(
"WebView evaluateJavascript is not implemented on the current platform")
;
}

/// Adds new JavaScript channels to the set of enabled channels.


///
/// For each value in this list the platform's webview should make sure that a
corresponding
/// property with a postMessage method is set on `window`. For example for a J
avaScript channel
/// named `Foo` it should be possible for JavaScript code executing in the web
view to do
///
/// ```javascript
/// Foo.postMessage('hello');
/// ```
///
/// See also: [CreationParams.javascriptChannelNames].
Future<void> addJavascriptChannels(Set<String> javascriptChannelNames) {
throw UnimplementedError(
"WebView addJavascriptChannels is not implemented on the current platfor
m");
}

/// Removes JavaScript channel names from the set of enabled channels.
///
/// This disables channels that were previously enabled by [addJavaScriptChann
els] or through
/// [CreationParams.javascriptChannelNames].
Future<void> removeJavascriptChannels(Set<String> javascriptChannelNames) {
throw UnimplementedError(
"WebView removeJavascriptChannels is not implemented on the current plat
form");
}

/// Returns the title of the currently loaded page.


Future<String> getTitle() {
throw UnimplementedError(
"WebView getTitle is not implemented on the current platform");
}

/// Set the scrolled position of this view.


///
/// The parameters `x` and `y` specify the position to scroll to in WebView pi
xels.
Future<void> scrollTo(int x, int y) {
throw UnimplementedError(
"WebView scrollTo is not implemented on the current platform");
}

/// Move the scrolled position of this view.


///
/// The parameters `x` and `y` specify the amount of WebView pixels to scroll
by.
Future<void> scrollBy(int x, int y) {
throw UnimplementedError(
"WebView scrollBy is not implemented on the current platform");
}

/// Return the horizontal scroll position of this view.


///
/// Scroll position is measured from left.
Future<int> getScrollX() {
throw UnimplementedError(
"WebView getScrollX is not implemented on the current platform");
}

/// Return the vertical scroll position of this view.


///
/// Scroll position is measured from top.
Future<int> getScrollY() {
throw UnimplementedError(
"WebView getScrollY is not implemented on the current platform");
}
}

/// A single setting for configuring a WebViewPlatform which may be absent.


class WebSetting<T> {
/// Constructs an absent setting instance.
///
/// The [isPresent] field for the instance will be false.
///
/// Accessing [value] for an absent instance will throw.
WebSetting.absent()
: _value = null,
isPresent = false;

/// Constructs a setting of the given `value`.


///
/// The [isPresent] field for the instance will be true.
WebSetting.of(T value)
: _value = value,
isPresent = true;

final T _value;

/// The setting's value.


///
/// Throws if [WebSetting.isPresent] is false.
T get value {
if (!isPresent) {
throw StateError('Cannot access a value of an absent WebSetting');
}
assert(isPresent);
return _value;
}

/// True when this web setting instance contains a value.


///
/// When false the [WebSetting.value] getter throws.
final bool isPresent;

@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) return false;
final WebSetting<T> typedOther = other;
return typedOther.isPresent == isPresent && typedOther._value == _value;
}

@override
int get hashCode => hashValues(_value, isPresent);
}

/// Settings for configuring a WebViewPlatform.


///
/// Initial settings are passed as part of [CreationParams], settings updates ar
e sent with
/// [WebViewPlatform#updateSettings].
///
/// The `userAgent` parameter must not be null.
class WebSettings {
/// Construct an instance with initial settings. Future setting changes can be
/// sent with [WebviewPlatform#updateSettings].
///
/// The `userAgent` parameter must not be null.
WebSettings({
this.javascriptMode,
this.hasNavigationDelegate,
this.debuggingEnabled,
this.gestureNavigationEnabled,
@required this.userAgent,
}) : assert(userAgent != null);

/// The JavaScript execution mode to be used by the webview.


final JavascriptMode javascriptMode;

/// Whether the [WebView] has a [NavigationDelegate] set.


final bool hasNavigationDelegate;

/// Whether to enable the platform's webview content debugging tools.


///
/// See also: [WebView.debuggingEnabled].
final bool debuggingEnabled;
/// The value used for the HTTP `User-Agent:` request header.
///
/// If [userAgent.value] is null the platform's default user agent should be u
sed.
///
/// An absent value ([userAgent.isPresent] is false) represents no change to t
his setting from the
/// last time it was set.
///
/// See also [WebView.userAgent].
final WebSetting<String> userAgent;

/// Whether to allow swipe based navigation in iOS.


///
/// See also: [WebView.gestureNavigationEnabled]
final bool gestureNavigationEnabled;

@override
String toString() {
return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate:
$hasNavigationDelegate, debuggingEnabled: $debuggingEnabled, gestureNavigationEn
abled: $gestureNavigationEnabled, userAgent: $userAgent)';
}
}

/// Configuration to use when creating a new [WebViewPlatformController].


///
/// The `autoMediaPlaybackPolicy` parameter must not be null.
class CreationParams {
/// Constructs an instance to use when creating a new
/// [WebViewPlatformController].
///
/// The `autoMediaPlaybackPolicy` parameter must not be null.
CreationParams({
this.initialUrl,
this.webSettings,
this.javascriptChannelNames,
this.userAgent,
this.autoMediaPlaybackPolicy =
AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,
}) : assert(autoMediaPlaybackPolicy != null);

/// The initialUrl to load in the webview.


///
/// When null the webview will be created without loading any page.
final String initialUrl;

/// The initial [WebSettings] for the new webview.


///
/// This can later be updated with [WebViewPlatformController.updateSettings].
final WebSettings webSettings;

/// The initial set of JavaScript channels that are configured for this webvie
w.
///
/// For each value in this set the platform's webview should make sure that a
corresponding
/// property with a postMessage method is set on `window`. For example for a J
avaScript channel
/// named `Foo` it should be possible for JavaScript code executing in the web
view to do
///
/// ```javascript
/// Foo.postMessage('hello');
/// ```
// TODO(amirh): describe what should happen when postMessage is called once th
at code is migrated
// to PlatformWebView.
final Set<String> javascriptChannelNames;

/// The value used for the HTTP User-Agent: request header.
///
/// When null the platform's webview default is used for the User-Agent header
.
final String userAgent;

/// Which restrictions apply on automatic media playback.


final AutoMediaPlaybackPolicy autoMediaPlaybackPolicy;

@override
String toString() {
return '$runtimeType(initialUrl: $initialUrl, settings: $webSettings, javasc
riptChannelNames: $javascriptChannelNames, UserAgent: $userAgent)';
}
}

typedef WebViewPlatformCreatedCallback = void Function(


WebViewPlatformController webViewPlatformController);

/// Interface for a platform implementation of a WebView.


///
/// [WebView.platform] controls the builder that is used by [WebView].
/// [AndroidWebViewPlatform] and [CupertinoWebViewPlatform] are the default impl
ementations
/// for Android and iOS respectively.
abstract class WebViewPlatform {
/// Builds a new WebView.
///
/// Returns a Widget tree that embeds the created webview.
///
/// `creationParams` are the initial parameters used to setup the webview.
///
/// `webViewPlatformHandler` will be used for handling callbacks that are made
by the created
/// [WebViewPlatformController].
///
/// `onWebViewPlatformCreated` will be invoked after the platform specific [We
bViewPlatformController]
/// implementation is created with the [WebViewPlatformController] instance as
a parameter.
///
/// `gestureRecognizers` specifies which gestures should be consumed by the we
b view.
/// It is possible for other gesture recognizers to be competing with the web
view on pointer
/// events, e.g if the web view is inside a [ListView] the [ListView] will wan
t to handle
/// vertical drags. The web view will claim gestures that are recognized by an
y of the
/// recognizers on this list.
/// When `gestureRecognizers` is empty or null, the web view will only handle
pointer events for gestures that
/// were not claimed by any other gesture recognizer.
///
/// `webViewPlatformHandler` must not be null.
Widget build({
BuildContext context,
// TODO(amirh): convert this to be the actual parameters.
// I'm starting without it as the PR is starting to become pretty big.
// I'll followup with the conversion PR.
CreationParams creationParams,
@required WebViewPlatformCallbacksHandler webViewPlatformCallbacksHandler,
WebViewPlatformCreatedCallback onWebViewPlatformCreated,
Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers,
});

/// Clears all cookies for all [WebView] instances.


///
/// Returns true if cookies were present before clearing, else false.
Future<bool> clearCookies() {
throw UnimplementedError(
"WebView clearCookies is not implemented on the current platform");
}
}

You might also like