Skip to content

Commit c9033ca

Browse files
Reverts "[pointer_interceptor] Add ios implementation and move web implementation to federated structure" (#5591)
Reverts #5500 Initiated by: stuartmorgan This change reverts the following previous change: Original Description: Addresses flutter/flutter#30143 by adding an iOS implementation This PR is Part 2 of #5233
1 parent 96310cc commit c9033ca

File tree

130 files changed

+269
-4048
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+269
-4048
lines changed

packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
## NEXT
2-
3-
* Adds iOS implementation.
4-
51
## 0.9.3+7
62

73
* Updates metadata to point to new source folder

packages/pointer_interceptor/pointer_interceptor/README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
# pointer_interceptor
22

3-
| | iOS | Web |
4-
|-------------|---------|-----|
5-
| **Support** | iOS 11+ | Any |
3+
`PointerInterceptor` is a widget that prevents mouse events (in web) from being captured by an underlying [`HtmlElementView`](https://api.flutter.dev/flutter/widgets/HtmlElementView-class.html).
64

7-
`PointerInterceptor` is a widget that prevents mouse events from being captured by an underlying [`HtmlElementView`](https://api.flutter.dev/flutter/widgets/HtmlElementView-class.html) in web, or an underlying [`PlatformView`](https://api.flutter.dev/flutter/widgets/PlatformViewLink-class.html) on iOS.
5+
You can use this widget in a cross-platform app freely. In mobile, where the issue that this plugin fixes does not exist, the widget acts as a pass-through of its `children`, without adding anything to the render tree.
86

97
## What is the problem?
108

11-
When overlaying Flutter widgets on top of `HtmlElementView`/`PlatformView` widgets that respond to mouse gestures (handle clicks, for example), the clicks will be consumed by the `HtmlElementView`/`PlatformView`, and not relayed to Flutter.
9+
When overlaying Flutter widgets on top of `HtmlElementView` widgets that respond to mouse gestures (handle clicks, for example), the clicks will be consumed by the `HtmlElementView`, and not relayed to Flutter.
1210

13-
The result is that Flutter widget's `onTap` (and other) handlers won't fire as expected, but they'll affect the underlying native platform view.
11+
The result is that Flutter widget's `onTap` (and other) handlers won't fire as expected, but they'll affect the underlying webview.
1412

1513
|The problem...|
1614
|:-:|
1715
|![Depiction of problematic areas](https://raw.githubusercontent.com/flutter/packages/main/packages/pointer_interceptor/doc/img/affected-areas.png)|
1816
|_In the dashed areas, mouse events won't work as expected. The `HtmlElementView` will consume them before Flutter sees them._|
1917

18+
2019
## How does this work?
2120

22-
In web, `PointerInterceptor` creates a platform view consisting of an empty HTML element, while on iOS it creates an empty `UIView` instead. The element has the size of its `child` widget, and is inserted in the layer tree _behind_ its child in paint order.
21+
`PointerInterceptor` creates a platform view consisting of an empty HTML element. The element has the size of its `child` widget, and is inserted in the layer tree _behind_ its child in paint order.
2322

2423
This empty platform view doesn't do anything with mouse events, other than preventing them from reaching other platform views underneath it.
2524

packages/pointer_interceptor/pointer_interceptor/example/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
/build/
3333

3434
# Web related
35+
lib/generated_plugin_registrant.dart
3536

3637
# Symbolication related
3738
app.*.symbols

packages/pointer_interceptor/pointer_interceptor/example/.metadata

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,7 @@
44
# This file should be version controlled and should not be manually edited.
55

66
version:
7-
revision: "969911d1d09d6c4f145e9ce27c08093e8c285561"
8-
channel: "main"
7+
revision: e6bd95bc5caa5e34c5b0285a559673984374b7ea
8+
channel: master
99

1010
project_type: app
11-
12-
# Tracks metadata for the flutter migrate command
13-
migration:
14-
platforms:
15-
- platform: root
16-
create_revision: 969911d1d09d6c4f145e9ce27c08093e8c285561
17-
base_revision: 969911d1d09d6c4f145e9ce27c08093e8c285561
18-
- platform: ios
19-
create_revision: 969911d1d09d6c4f145e9ce27c08093e8c285561
20-
base_revision: 969911d1d09d6c4f145e9ce27c08093e8c285561
21-
22-
# User provided section
23-
24-
# List of Local paths (relative to this file) that should be
25-
# ignored by the migrate tool.
26-
#
27-
# Files that are not part of the templates will be ignored by default.
28-
unmanaged_files:
29-
- 'lib/main.dart'
30-
- 'ios/Runner.xcodeproj/project.pbxproj'

packages/pointer_interceptor/pointer_interceptor/example/integration_test/widget_test.dart

Lines changed: 167 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,176 @@
44

55
// ignore_for_file: avoid_print
66

7+
import 'dart:html' as html;
8+
9+
// Imports the Flutter Driver API.
10+
import 'package:flutter/src/widgets/framework.dart';
711
import 'package:flutter_test/flutter_test.dart';
812
import 'package:integration_test/integration_test.dart';
913

14+
import 'package:pointer_interceptor_example/main.dart' as app;
15+
16+
final Finder nonClickableButtonFinder =
17+
find.byKey(const Key('transparent-button'));
18+
final Finder clickableWrappedButtonFinder =
19+
find.byKey(const Key('wrapped-transparent-button'));
20+
final Finder clickableButtonFinder = find.byKey(const Key('clickable-button'));
21+
final Finder backgroundFinder =
22+
find.byKey(const ValueKey<String>('background-widget'));
23+
1024
void main() {
1125
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
12-
// TODO(louisehsu): given the difficulty of making the same integration tests
13-
// work for both web and ios implementations, please find tests in their respective
14-
// platform implementation packages.
15-
testWidgets('placeholder test', (WidgetTester tester) async {});
26+
27+
group('Without semantics', () {
28+
testWidgets(
29+
'on wrapped elements, the browser does not hit the background-html-view',
30+
(WidgetTester tester) async {
31+
app.main();
32+
await tester.pumpAndSettle();
33+
34+
final html.Element element =
35+
_getHtmlElementAtCenter(clickableButtonFinder, tester);
36+
37+
expect(element.id, isNot('background-html-view'));
38+
}, semanticsEnabled: false);
39+
40+
testWidgets(
41+
'on wrapped elements with intercepting set to false, the browser hits the background-html-view',
42+
(WidgetTester tester) async {
43+
app.main();
44+
await tester.pumpAndSettle();
45+
46+
final html.Element element =
47+
_getHtmlElementAtCenter(clickableWrappedButtonFinder, tester);
48+
49+
expect(element.id, 'background-html-view');
50+
}, semanticsEnabled: false);
51+
52+
testWidgets(
53+
'on unwrapped elements, the browser hits the background-html-view',
54+
(WidgetTester tester) async {
55+
app.main();
56+
await tester.pumpAndSettle();
57+
58+
final html.Element element =
59+
_getHtmlElementAtCenter(nonClickableButtonFinder, tester);
60+
61+
expect(element.id, 'background-html-view');
62+
}, semanticsEnabled: false);
63+
64+
testWidgets('on background directly', (WidgetTester tester) async {
65+
app.main();
66+
await tester.pumpAndSettle();
67+
68+
final html.Element element =
69+
_getHtmlElementAt(tester.getTopLeft(backgroundFinder));
70+
71+
expect(element.id, 'background-html-view');
72+
}, semanticsEnabled: false);
73+
});
74+
75+
group('With semantics', () {
76+
testWidgets('finds semantics of wrapped widgets',
77+
(WidgetTester tester) async {
78+
app.main();
79+
await tester.pumpAndSettle();
80+
81+
if (!_newSemanticsAvailable()) {
82+
print('Skipping test: Needs flutter > 2.10');
83+
return;
84+
}
85+
86+
final html.Element element =
87+
_getHtmlElementAtCenter(clickableButtonFinder, tester);
88+
89+
expect(element.tagName.toLowerCase(), 'flt-semantics');
90+
expect(element.getAttribute('aria-label'), 'Works As Expected');
91+
});
92+
93+
testWidgets(
94+
'finds semantics of wrapped widgets with intercepting set to false',
95+
(WidgetTester tester) async {
96+
app.main();
97+
await tester.pumpAndSettle();
98+
99+
if (!_newSemanticsAvailable()) {
100+
print('Skipping test: Needs flutter > 2.10');
101+
return;
102+
}
103+
104+
final html.Element element =
105+
_getHtmlElementAtCenter(clickableWrappedButtonFinder, tester);
106+
107+
expect(element.tagName.toLowerCase(), 'flt-semantics');
108+
expect(element.getAttribute('aria-label'),
109+
'Never calls onPressed transparent');
110+
});
111+
112+
testWidgets('finds semantics of unwrapped elements',
113+
(WidgetTester tester) async {
114+
app.main();
115+
await tester.pumpAndSettle();
116+
117+
if (!_newSemanticsAvailable()) {
118+
print('Skipping test: Needs flutter > 2.10');
119+
return;
120+
}
121+
122+
final html.Element element =
123+
_getHtmlElementAtCenter(nonClickableButtonFinder, tester);
124+
125+
expect(element.tagName.toLowerCase(), 'flt-semantics');
126+
expect(element.getAttribute('aria-label'), 'Never calls onPressed');
127+
});
128+
129+
// Notice that, when hit-testing the background platform view, instead of
130+
// finding a semantics node, the platform view itself is found. This is
131+
// because the platform view does not add interactive semantics nodes into
132+
// the framework's semantics tree. Instead, its semantics is determined by
133+
// the HTML content of the platform view itself. Flutter's semantics tree
134+
// simply allows the hit test to land on the platform view by making itself
135+
// hit test transparent.
136+
testWidgets('on background directly', (WidgetTester tester) async {
137+
app.main();
138+
await tester.pumpAndSettle();
139+
140+
final html.Element element =
141+
_getHtmlElementAt(tester.getTopLeft(backgroundFinder));
142+
143+
expect(element.id, 'background-html-view');
144+
});
145+
});
146+
}
147+
148+
// Calls [_getHtmlElementAt] passing it the center of the widget identified by
149+
// the `finder`.
150+
html.Element _getHtmlElementAtCenter(Finder finder, WidgetTester tester) {
151+
final Offset point = tester.getCenter(finder);
152+
return _getHtmlElementAt(point);
153+
}
154+
155+
// Locates the DOM element at the given `point` using `elementFromPoint`.
156+
//
157+
// `elementFromPoint` is an approximate proxy for a hit test, although it's
158+
// sensitive to the presence of shadow roots and browser quirks (not all
159+
// browsers agree on what it should return in all situations). Since this test
160+
// runs only in Chromium, it relies on Chromium's behavior.
161+
html.Element _getHtmlElementAt(Offset point) {
162+
// Probe at the shadow so the browser reports semantics nodes in addition to
163+
// platform view elements. If probed from `html.document` the browser hides
164+
// the contents of <flt-glass-name> as an implementation detail.
165+
final html.ShadowRoot glassPaneShadow =
166+
html.document.querySelector('flt-glass-pane')!.shadowRoot!;
167+
return glassPaneShadow.elementFromPoint(point.dx.toInt(), point.dy.toInt())!;
168+
}
169+
170+
// TODO(dit): Remove this after flutter master (2.13) lands into stable.
171+
// This detects that we can do new semantics assertions by looking at the 'id'
172+
// attribute on flt-semantics elements (it is now set in 2.13 and up).
173+
bool _newSemanticsAvailable() {
174+
final html.ShadowRoot glassPaneShadow =
175+
html.document.querySelector('flt-glass-pane')!.shadowRoot!;
176+
final List<html.Element> elements =
177+
glassPaneShadow.querySelectorAll('flt-semantics[id]');
178+
return elements.isNotEmpty;
16179
}

packages/pointer_interceptor/pointer_interceptor/example/ios/.gitignore

Lines changed: 0 additions & 34 deletions
This file was deleted.

packages/pointer_interceptor/pointer_interceptor/example/ios/Flutter/AppFrameworkInfo.plist

Lines changed: 0 additions & 26 deletions
This file was deleted.

packages/pointer_interceptor/pointer_interceptor/example/ios/Flutter/Debug.xcconfig

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/pointer_interceptor/pointer_interceptor/example/ios/Flutter/Release.xcconfig

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/pointer_interceptor/pointer_interceptor/example/ios/Podfile

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)