Skip to content

Commit 2c8ffc2

Browse files
aednlaxerilluminati1911
authored andcommitted
Add Advanced markers support (web)
1 parent 651c565 commit 2c8ffc2

22 files changed

+1960
-547
lines changed

packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.5.15
2+
3+
* Adds Advanced markers support.
4+
>>>>>>>
5+
16
## 0.5.14+2
27

38
* Fixes a bug where using `cloudMapId` for cloud-based styling would fail if the `style` property was also present.

packages/google_maps_flutter/google_maps_flutter_web/README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,26 @@ Modify the `<head>` tag of your `web/index.html` to load the Google Maps JavaScr
3232
The Google Maps Web SDK splits some of its functionality in [separate libraries](https://developers.google.com/maps/documentation/javascript/libraries#libraries-for-dynamic-library-import).
3333

3434
If your app needs the `drawing` library (to draw polygons, rectangles, polylines,
35-
circles or markers on a map), include it like this:
35+
circles or legacy markers on a map), include it like this:
3636

3737
```html
3838
<script
3939
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=drawing">
4040
</script>
4141
```
4242

43+
If your app uses Advanced Markers, include `marker` library like this:
44+
```html
45+
<script
46+
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=marker">
47+
</script>
48+
```
49+
4350
To request multiple libraries, separate them with commas:
4451

4552
```html
4653
<script
47-
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=drawing,visualization,places">
54+
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=drawing,marker,visualization,places">
4855
</script>
4956
```
5057

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:js_interop';
7+
8+
import 'package:flutter_test/flutter_test.dart';
9+
import 'package:google_maps/google_maps.dart' as gmaps;
10+
import 'package:google_maps_flutter_web/google_maps_flutter_web.dart';
11+
import 'package:google_maps_flutter_web/src/utils.dart';
12+
import 'package:integration_test/integration_test.dart';
13+
14+
/// Test Markers
15+
void main() {
16+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
17+
18+
// Since onTap/DragEnd events happen asynchronously, we need to store when the event
19+
// is fired. We use a completer so the test can wait for the future to be completed.
20+
late Completer<bool> methodCalledCompleter;
21+
22+
/// This is the future value of the [methodCalledCompleter]. Reinitialized
23+
/// in the [setUp] method, and completed (as `true`) by [onTap] and [onDragEnd]
24+
/// when those methods are called from the MarkerController.
25+
late Future<bool> methodCalled;
26+
27+
void onTap() {
28+
methodCalledCompleter.complete(true);
29+
}
30+
31+
void onDragStart(gmaps.LatLng _) {
32+
methodCalledCompleter.complete(true);
33+
}
34+
35+
void onDrag(gmaps.LatLng _) {
36+
methodCalledCompleter.complete(true);
37+
}
38+
39+
void onDragEnd(gmaps.LatLng _) {
40+
methodCalledCompleter.complete(true);
41+
}
42+
43+
setUp(() {
44+
methodCalledCompleter = Completer<bool>();
45+
methodCalled = methodCalledCompleter.future;
46+
});
47+
48+
group('MarkerController', () {
49+
late gmaps.AdvancedMarkerElement marker;
50+
51+
setUp(() {
52+
marker = gmaps.AdvancedMarkerElement();
53+
});
54+
55+
testWidgets('onTap gets called', (WidgetTester tester) async {
56+
AdvancedMarkerController(marker: marker, onTap: onTap);
57+
58+
// Trigger a click event...
59+
gmaps.event.trigger(
60+
marker,
61+
'click',
62+
gmaps.MapMouseEvent(),
63+
);
64+
65+
// The event handling is now truly async. Wait for it...
66+
expect(await methodCalled, isTrue);
67+
});
68+
69+
testWidgets('onDragStart gets called', (WidgetTester tester) async {
70+
AdvancedMarkerController(marker: marker, onDragStart: onDragStart);
71+
72+
// Trigger a drag end event...
73+
gmaps.event.trigger(
74+
marker,
75+
'dragstart',
76+
gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0),
77+
);
78+
79+
expect(await methodCalled, isTrue);
80+
});
81+
82+
testWidgets('onDrag gets called', (WidgetTester tester) async {
83+
AdvancedMarkerController(marker: marker, onDrag: onDrag);
84+
85+
// Trigger a drag end event...
86+
gmaps.event.trigger(
87+
marker,
88+
'drag',
89+
gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0),
90+
);
91+
92+
expect(await methodCalled, isTrue);
93+
});
94+
95+
testWidgets('onDragEnd gets called', (WidgetTester tester) async {
96+
AdvancedMarkerController(marker: marker, onDragEnd: onDragEnd);
97+
98+
// Trigger a drag end event...
99+
gmaps.event.trigger(
100+
marker,
101+
'dragend',
102+
gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0),
103+
);
104+
105+
expect(await methodCalled, isTrue);
106+
});
107+
108+
testWidgets('update', (WidgetTester tester) async {
109+
final AdvancedMarkerController controller =
110+
AdvancedMarkerController(marker: marker);
111+
final gmaps.AdvancedMarkerElementOptions options =
112+
gmaps.AdvancedMarkerElementOptions()
113+
..collisionBehavior =
114+
gmaps.CollisionBehavior.OPTIONAL_AND_HIDES_LOWER_PRIORITY
115+
..gmpDraggable = true
116+
..position = gmaps.LatLng(42, 54);
117+
118+
expect(marker.collisionBehavior, gmaps.CollisionBehavior.REQUIRED);
119+
expect(marker.gmpDraggable, isFalse);
120+
121+
controller.update(options);
122+
123+
expect(marker.gmpDraggable, isTrue);
124+
expect(
125+
marker.collisionBehavior,
126+
gmaps.CollisionBehavior.OPTIONAL_AND_HIDES_LOWER_PRIORITY,
127+
);
128+
final JSAny? position = marker.position;
129+
expect(position, isNotNull);
130+
expect(position is gmaps.LatLngLiteral, isTrue);
131+
expect((position! as gmaps.LatLngLiteral).lat, equals(42));
132+
expect((position as gmaps.LatLngLiteral).lng, equals(54));
133+
});
134+
135+
testWidgets('infoWindow null, showInfoWindow.',
136+
(WidgetTester tester) async {
137+
final AdvancedMarkerController controller =
138+
AdvancedMarkerController(marker: marker);
139+
140+
controller.showInfoWindow();
141+
142+
expect(controller.infoWindowShown, isFalse);
143+
});
144+
145+
testWidgets('showInfoWindow', (WidgetTester tester) async {
146+
final gmaps.InfoWindow infoWindow = gmaps.InfoWindow();
147+
final gmaps.Map map = gmaps.Map(createDivElement());
148+
marker.map = map;
149+
final AdvancedMarkerController controller = AdvancedMarkerController(
150+
marker: marker,
151+
infoWindow: infoWindow,
152+
);
153+
154+
controller.showInfoWindow();
155+
156+
expect(infoWindow.get('map'), map);
157+
expect(controller.infoWindowShown, isTrue);
158+
});
159+
160+
testWidgets('hideInfoWindow', (WidgetTester tester) async {
161+
final gmaps.InfoWindow infoWindow = gmaps.InfoWindow();
162+
final gmaps.Map map = gmaps.Map(createDivElement());
163+
marker.map = map;
164+
final AdvancedMarkerController controller = AdvancedMarkerController(
165+
marker: marker,
166+
infoWindow: infoWindow,
167+
);
168+
169+
controller.hideInfoWindow();
170+
171+
expect(infoWindow.get('map'), isNull);
172+
expect(controller.infoWindowShown, isFalse);
173+
});
174+
175+
group('remove', () {
176+
late AdvancedMarkerController controller;
177+
178+
setUp(() {
179+
final gmaps.InfoWindow infoWindow = gmaps.InfoWindow();
180+
final gmaps.Map map = gmaps.Map(createDivElement());
181+
marker.map = map;
182+
controller =
183+
AdvancedMarkerController(marker: marker, infoWindow: infoWindow);
184+
});
185+
186+
testWidgets('drops gmaps instance', (WidgetTester tester) async {
187+
controller.remove();
188+
189+
expect(controller.marker, isNull);
190+
});
191+
192+
testWidgets('cannot call update after remove',
193+
(WidgetTester tester) async {
194+
final gmaps.AdvancedMarkerElementOptions options =
195+
gmaps.AdvancedMarkerElementOptions()..gmpDraggable = true;
196+
197+
controller.remove();
198+
199+
expect(() {
200+
controller.update(options);
201+
}, throwsAssertionError);
202+
});
203+
204+
testWidgets('cannot call showInfoWindow after remove',
205+
(WidgetTester tester) async {
206+
controller.remove();
207+
208+
expect(() {
209+
controller.showInfoWindow();
210+
}, throwsAssertionError);
211+
});
212+
213+
testWidgets('cannot call hideInfoWindow after remove',
214+
(WidgetTester tester) async {
215+
controller.remove();
216+
217+
expect(() {
218+
controller.hideInfoWindow();
219+
}, throwsAssertionError);
220+
});
221+
});
222+
});
223+
}

0 commit comments

Comments
 (0)