Skip to content

Commit

Permalink
Allow web view to be configured with additional gesture recognizers (#…
Browse files Browse the repository at this point in the history
…1268)

Also:

* Add support for `WebViewFactory.webViewGestureRecognizers`
* Add support for `WebViewFactory.webViewUnsupportedWorkaroundForIssue37`
* [fwfh_webview] v0.15.1-rc.1

---------

Co-authored-by: Stanislav <stanislav.petrik@maxylogic.com>
  • Loading branch information
daohoangson and stanislav216 committed Jun 9, 2024
1 parent 339c5a5 commit b052e65
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 32 deletions.
2 changes: 1 addition & 1 deletion packages/enhanced/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ dependencies:
fwfh_just_audio: ^0.14.3
fwfh_svg: ^0.8.1
fwfh_url_launcher: ^0.9.0+4
fwfh_webview: ^0.15.0
fwfh_webview: ^0.15.1-0
html: ^0.15.0

dependency_overrides:
Expand Down
8 changes: 8 additions & 0 deletions packages/fwfh_webview/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 0.15.1-rc.1

- Replace timers with ResizeObserver (#1241)
- Only apply IFRAME width & height if it has both attributes (#1244)
- Set IFRAME width & height to conform to platform view constraints (#1253)
- Add support for `WebViewFactory.webViewGestureRecognizers` (#1268, authored by @stanislav216)
- Add support for `WebViewFactory.webViewUnsupportedWorkaroundForIssue37` (#1268)

## 0.15.0

- Requires Flutter 3.16 (#1188)
Expand Down
22 changes: 12 additions & 10 deletions packages/fwfh_webview/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Add this to your app's `pubspec.yaml` file:
```yaml
dependencies:
flutter_widget_from_html_core: any
fwfh_webview: ^0.15.0
fwfh_webview: ^0.15.1
```
## Usage
Expand Down Expand Up @@ -47,15 +47,17 @@ class MyWidgetFactory extends WidgetFactory with WebViewFactory {

Configurable getters:

| | Type | Default |
| -------------------------------- | -------- | ------- |
| webView | bool | true |
| webViewDebuggingEnabled | bool | false |
| webViewJs | bool | true |
| webViewMediaPlaybackAlwaysAllow | bool | false |
| webViewOnAndroidHideCustomWidget | Function | null |
| webViewOnAndroidShowCustomWidget | Function | null |
| webViewUserAgent | String | null |
| | Type | Default |
| -------------------------------------- | -------- | ------- |
| webView | bool | true |
| webViewDebuggingEnabled | bool | false |
| webViewGestureRecognizers | Set | empty |
| webViewJs | bool | true |
| webViewMediaPlaybackAlwaysAllow | bool | false |
| webViewOnAndroidHideCustomWidget | Function | null |
| webViewOnAndroidShowCustomWidget | Function | null |
| webViewUnsupportedWorkaroundForIssue37 | bool | true |
| webViewUserAgent | String? | null |

Supported IFRAME attributes:

Expand Down
1 change: 1 addition & 0 deletions packages/fwfh_webview/lib/src/web_view/io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ class WebViewState extends State<WebView> {

Widget _buildWebView() => lib.WebViewWidget(
controller: _controller,
gestureRecognizers: widget.gestureRecognizers,
key: Key(widget.url),
);

Expand Down
10 changes: 10 additions & 0 deletions packages/fwfh_webview/lib/src/web_view/web_view.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';

import 'fallback.dart'
Expand Down Expand Up @@ -33,6 +35,11 @@ class WebView extends StatefulWidget {
/// {@endtemplate}
final bool debuggingEnabled;

/// {@template web_view.gestureRecognizers}
/// Specifies which gestures should be consumed by the web view.
/// {@endtemplate}
final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers;

/// The callback to handle navigation request.
///
/// This will be triggered on generated navigation within the web view.
Expand Down Expand Up @@ -74,11 +81,13 @@ class WebView extends StatefulWidget {
/// {@endtemplate}
final void Function(Widget child)? onAndroidShowCustomWidget;

/// {@template web_view.unsupportedWorkaroundForIssue37}
/// Controls whether or not to apply workaround for
/// [video continue playing after locking the phone or navigate to another screen](https://github.com/daohoangson/flutter_widget_from_html/issues/37)
/// issue.
///
/// Default: `true`.
/// {@endtemplate}
final bool unsupportedWorkaroundForIssue37;

/// {@template web_view.userAgent}
Expand All @@ -95,6 +104,7 @@ class WebView extends StatefulWidget {
@Deprecated('No longer used.') this.autoResizeIntervals = const [],
bool? autoResize,
this.debuggingEnabled = false,
this.gestureRecognizers = const <Factory<OneSequenceGestureRecognizer>>{},
this.interceptNavigationRequest,
this.js = true,
this.mediaPlaybackAlwaysAllow = false,
Expand Down
10 changes: 10 additions & 0 deletions packages/fwfh_webview/lib/src/web_view_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// ignore_for_file: deprecated_member_use

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

Expand All @@ -20,6 +21,10 @@ mixin WebViewFactory on WidgetFactory {
/// {@macro web_view.debuggingEnabled}
bool get webViewDebuggingEnabled => false;

/// {@macro web_view.gestureRecognizers}
Set<Factory<OneSequenceGestureRecognizer>> get webViewGestureRecognizers =>
const <Factory<OneSequenceGestureRecognizer>>{};

/// {@macro web_view.js}
bool get webViewJs => true;

Expand All @@ -32,6 +37,9 @@ mixin WebViewFactory on WidgetFactory {
/// {@macro web_view.onAndroidShowCustomWidget}
void Function(Widget widget)? get webViewOnAndroidShowCustomWidget => null;

/// {@macro web_view.unsupportedWorkaroundForIssue37}
bool get webViewUnsupportedWorkaroundForIssue37 => true;

/// {@macro web_view.userAgent}
String? get webViewUserAgent => null;

Expand Down Expand Up @@ -60,6 +68,7 @@ mixin WebViewFactory on WidgetFactory {
aspectRatio: dimensOk ? width / height : 16 / 9,
autoResize: !dimensOk && js,
debuggingEnabled: webViewDebuggingEnabled,
gestureRecognizers: webViewGestureRecognizers,
interceptNavigationRequest: (newUrl) {
if (newUrl == url) {
return false;
Expand All @@ -72,6 +81,7 @@ mixin WebViewFactory on WidgetFactory {
mediaPlaybackAlwaysAllow: webViewMediaPlaybackAlwaysAllow,
onAndroidHideCustomWidget: webViewOnAndroidHideCustomWidget,
onAndroidShowCustomWidget: webViewOnAndroidShowCustomWidget,
unsupportedWorkaroundForIssue37: webViewUnsupportedWorkaroundForIssue37,
userAgent: webViewUserAgent,
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/fwfh_webview/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: fwfh_webview
version: 0.15.0
version: 0.15.1-rc.1
description: WidgetFactory extension to render IFRAME with the official WebView plugin.
homepage: https://github.com/daohoangson/flutter_widget_from_html

Expand Down
16 changes: 6 additions & 10 deletions packages/fwfh_webview/test/_.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ String? webViewExplainer(helper.Explainer parent, Widget widget) {
final debuggingEnabled = widget.debuggingEnabled
? ',debuggingEnabled=${widget.debuggingEnabled}'
: '';
final gestureRecognizers = widget.gestureRecognizers.isNotEmpty
? ',gestureRecognizers=${widget.gestureRecognizers}'
: '';
final mediaPlaybackAlwaysAllow = widget.mediaPlaybackAlwaysAllow
? ',mediaPlaybackAlwaysAllow=${widget.mediaPlaybackAlwaysAllow}'
: '';
Expand All @@ -26,6 +29,7 @@ String? webViewExplainer(helper.Explainer parent, Widget widget) {
',aspectRatio=${widget.aspectRatio.toStringAsFixed(2)}'
"${widget.autoResize ? ',autoResize=${widget.autoResize}' : ''}"
'$debuggingEnabled'
'$gestureRecognizers'
"${!widget.js ? ',js=${widget.js}' : ''}"
'$mediaPlaybackAlwaysAllow'
'$unsupportedWorkaroundForIssue37'
Expand All @@ -41,7 +45,6 @@ Future<String> explain(
String html, {
Uri? baseUrl,
bool useExplainer = true,
bool webView = true,
}) async =>
helper.explain(
tester,
Expand All @@ -51,16 +54,9 @@ Future<String> explain(
html,
baseUrl: baseUrl,
key: helper.hwKey,
factoryBuilder: () => WebViewWidgetFactory(webView: webView),
factoryBuilder: () => WebViewWidgetFactory(),
),
useExplainer: useExplainer,
);

class WebViewWidgetFactory extends WidgetFactory with WebViewFactory {
final bool? _webView;

WebViewWidgetFactory({bool? webView}) : _webView = webView;

@override
bool get webView => _webView ?? super.webView;
}
class WebViewWidgetFactory extends WidgetFactory with WebViewFactory {}
143 changes: 133 additions & 10 deletions packages/fwfh_webview/test/web_view_factory_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:fwfh_webview/fwfh_webview.dart';

import '../../core/test/_.dart' as helper;
import '_.dart';
Expand All @@ -15,17 +17,103 @@ void main() {
const src = 'http://domain.com';
const defaultAspectRatio = '1.78';

testWidgets('renders clickable text', (tester) async {
group('getters', () {
const html = '<iframe src="$src"></iframe>';
final explained = await explain(tester, html, webView: false);
expect(
explained,
equals(
'[CssSizing:$sizingConstraints,child='
'[GestureDetector:child=[Text:$src]]'
']',
),
);

testWidgets('webView=false', (tester) async {
final explained = await helper.explain(
tester,
null,
hw: HtmlWidget(
html,
key: helper.hwKey,
factoryBuilder: () => _WebViewFalse(),
),
);
expect(
explained,
equals(
'[CssSizing:$sizingConstraints,child='
'[GestureDetector:child=[Text:$src]]'
']',
),
);
});

testWidgets('webViewDebuggingEnabled', (tester) async {
final explained = await helper.explain(
tester,
null,
explainer: webViewExplainer,
hw: HtmlWidget(
html,
key: helper.hwKey,
factoryBuilder: () => _WebViewDebuggingEnabled(),
),
);
expect(explained, contains('debuggingEnabled=true'));
});

testWidgets('webViewGestureRecognizers={Eager}', (tester) async {
final explained = await helper.explain(
tester,
null,
explainer: webViewExplainer,
hw: HtmlWidget(
html,
key: helper.hwKey,
factoryBuilder: () => _WebViewEagerGestureRecognizer(),
),
);
expect(
explained,
contains(
'gestureRecognizers={Factory(type: OneSequenceGestureRecognizer)}',
),
);
});

testWidgets('webViewMediaPlaybackAlwaysAllow', (tester) async {
final explained = await helper.explain(
tester,
null,
explainer: webViewExplainer,
hw: HtmlWidget(
html,
key: helper.hwKey,
factoryBuilder: () => _WebViewMediaPlaybackAlwaysAllow(),
),
);
expect(explained, contains('mediaPlaybackAlwaysAllow=true'));
});

testWidgets('webViewUnsupportedWorkaroundForIssue37', (tester) async {
final explained = await helper.explain(
tester,
null,
explainer: webViewExplainer,
hw: HtmlWidget(
html,
key: helper.hwKey,
factoryBuilder: () => _WebViewUnsupportedWorkaroundForIssue37False(),
),
);
expect(explained, contains('unsupportedWorkaroundForIssue37=false'));
});

testWidgets('webViewUserAgent=foo', (tester) async {
final explained = await helper.explain(
tester,
null,
explainer: webViewExplainer,
hw: HtmlWidget(
html,
key: helper.hwKey,
factoryBuilder: () => _WebViewUserAgentFoo(),
),
);
expect(explained, contains('userAgent=foo'));
});
});

group('renders web view', () {
Expand Down Expand Up @@ -244,3 +332,38 @@ void main() {
});
});
}

class _WebViewFalse extends WidgetFactory with WebViewFactory {
@override
bool get webView => false;
}

class _WebViewDebuggingEnabled extends WidgetFactory with WebViewFactory {
@override
bool get webViewDebuggingEnabled => true;
}

class _WebViewEagerGestureRecognizer extends WidgetFactory with WebViewFactory {
@override
Set<Factory<OneSequenceGestureRecognizer>> get webViewGestureRecognizers =>
const {
Factory<OneSequenceGestureRecognizer>(EagerGestureRecognizer.new),
};
}

class _WebViewMediaPlaybackAlwaysAllow extends WidgetFactory
with WebViewFactory {
@override
bool get webViewMediaPlaybackAlwaysAllow => true;
}

class _WebViewUnsupportedWorkaroundForIssue37False extends WidgetFactory
with WebViewFactory {
@override
bool get webViewUnsupportedWorkaroundForIssue37 => false;
}

class _WebViewUserAgentFoo extends WidgetFactory with WebViewFactory {
@override
String? get webViewUserAgent => 'foo';
}

1 comment on commit b052e65

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.