From 8800cc7f7b932150b9c06e405d54773483365d5c Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Fri, 27 Oct 2023 12:23:14 +0200 Subject: [PATCH 01/43] depend on package:web --- .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 2293fe78c14..c9424bfbd38 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -26,6 +26,7 @@ dependencies: google_maps_flutter_platform_interface: ^2.4.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 + web: ^0.3.0 dev_dependencies: flutter_test: From 0c9fc45030af110d998ed99c74f414bb79f7cb7f Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Fri, 27 Oct 2023 12:30:02 +0200 Subject: [PATCH 02/43] fix comment --- .../google_maps_flutter_web/lib/src/convert.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 8ca6a75559f..060d0a24fd4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -28,7 +28,7 @@ double _getCssOpacity(Color color) { // mapToolbarEnabled is unused in web, there's no "map toolbar" // myLocationButtonEnabled Widget not available in web yet, it needs to be built on top of the maps widget // See: https://developers.google.com/maps/documentation/javascript/examples/control-custom -// myLocationEnabled needs to be built through dart:html navigator.geolocation +// myLocationEnabled needs to be built through `navigator.geolocation` from package:web. // See: https://api.dart.dev/stable/2.8.4/dart-html/Geolocation-class.html // trafficEnabled is handled when creating the GMap object, since it needs to be added as a layer. // trackCameraPosition is just a boolean value that indicates if the map has an onCameraMove handler. From 8960e3d916bb589372da75322bd7a1ab320a8a87 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Fri, 27 Oct 2023 12:30:43 +0200 Subject: [PATCH 03/43] update import in base file --- .../google_maps_flutter_web/lib/google_maps_flutter_web.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index d1ef18d3067..8012cb414cd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -6,7 +6,6 @@ library google_maps_flutter_web; import 'dart:async'; import 'dart:convert'; -import 'dart:html' hide VoidCallback; import 'dart:js_util'; import 'dart:ui_web' as ui_web; @@ -20,6 +19,7 @@ import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:sanitize_html/sanitize_html.dart'; import 'package:stream_transform/stream_transform.dart'; +import 'package:web/web.dart'; import 'src/google_maps_inspector_web.dart'; import 'src/third_party/to_screen_location/to_screen_location.dart'; From b420f325b818f3c3671f0e51566327873fb0a391 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:07:35 +0200 Subject: [PATCH 04/43] depend on package web in the example app --- .../google_maps_flutter_web/example/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 7b2c31b6f53..838731e02db 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -12,6 +12,7 @@ dependencies: google_maps_flutter_platform_interface: ^2.4.0 google_maps_flutter_web: path: ../ + web: ^0.3.0 dev_dependencies: build_runner: ^2.1.1 From a0637f183b0b3f930f29400fc1fe857ace0de377 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:08:38 +0200 Subject: [PATCH 05/43] add utility function to create divs --- .../example/integration_test/test_utils.dart | 8 ++++++++ .../google_maps_flutter_web/lib/src/utils.dart | 6 ++++++ 2 files changed, 14 insertions(+) create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/test_utils.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/lib/src/utils.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/test_utils.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/test_utils.dart new file mode 100644 index 00000000000..b4340e0641f --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/test_utils.dart @@ -0,0 +1,8 @@ +import 'package:flutter/foundation.dart'; +import 'package:web/web.dart'; + +/// Convenience method to create a new [HTMLDivElement] element. +@visibleForTesting +HTMLDivElement createDivElement() { + return document.createElement('div') as HTMLDivElement; +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/utils.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/utils.dart new file mode 100644 index 00000000000..2ec743ee355 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/utils.dart @@ -0,0 +1,6 @@ +import 'package:web/web.dart'; + +/// Convenience method to create a new [HTMLDivElement] element. +HTMLDivElement createDivElement() { + return document.createElement('div') as HTMLDivElement; +} From 636e71f4ff6254213346e051864d1cb30b7e422f Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:15:59 +0200 Subject: [PATCH 06/43] migrate overlay.dart --- .../lib/src/overlay.dart | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart index 5dd092c67ee..91f3d4aab69 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart @@ -33,7 +33,7 @@ class TileOverlayController { } /// Renders a Tile for gmaps; delegating to the configured [TileProvider]. - HtmlElement? _getTile( + HTMLElement? _getTile( gmaps.Point? tileCoord, num? zoom, Document? ownerDocument, @@ -42,10 +42,10 @@ class TileOverlayController { return null; } - final ImageElement img = - ownerDocument!.createElement('img') as ImageElement; + final HTMLImageElement img = + ownerDocument!.createElement('img') as HTMLImageElement; img.width = img.height = logicalTileSize; - img.hidden = true; + img.hidden = true.toJS; img.setAttribute('decoding', 'async'); _tileOverlay.tileProvider! @@ -55,12 +55,19 @@ class TileOverlayController { return; } // Using img lets us take advantage of native decoding. - final String src = Url.createObjectUrl(Blob([tile.data])); + final String src = URL.createObjectURL( + // TODO(ditman): Improve Blob creation + // See https://github.com/dart-lang/web/issues/91 + Blob(tile.data!.map((int byte) => byte.toJS).toList().toJS), + ); img.src = src; - img.addEventListener('load', (_) { - img.hidden = false; - Url.revokeObjectUrl(src); - }); + img.addEventListener( + 'load', + allowInterop((_) { + img.hidden = false.toJS; + URL.revokeObjectURL(src); + }).toJS, + ); }); return img; From 639fe9765304d41d3228077b816c609f75af1eb5 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:20:15 +0200 Subject: [PATCH 07/43] migrate markers.dart --- .../lib/src/markers.dart | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index 52a659874f4..78b9a70407e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -39,11 +39,17 @@ class MarkersController extends GeometryController { // Google Maps' JS SDK does not have a click event on the InfoWindow, so // we make one... if (infoWindowOptions.content != null && - infoWindowOptions.content is HtmlElement) { - final HtmlElement content = infoWindowOptions.content! as HtmlElement; - content.onClick.listen((_) { - _onInfoWindowTap(marker.markerId); - }); + infoWindowOptions.content is HTMLElement) { + final HTMLElement content = infoWindowOptions.content! as HTMLElement; + + // TODO(ditman): Use the premade handler + // See https://github.com/dart-lang/web/issues/76 + content.addEventListener( + 'click', + allowInterop((_) { + _onInfoWindowTap(marker.markerId); + }).toJS, + ); } } @@ -91,7 +97,7 @@ class MarkersController extends GeometryController { _infoWindowOptionsFromMarker(marker); markerController.update( markerOptions, - newInfoWindowContent: infoWindow?.content as HtmlElement?, + newInfoWindowContent: infoWindow?.content as HTMLElement?, ); } } From c22678e5e62712875fe44444ebab310775f37aba Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:21:42 +0200 Subject: [PATCH 08/43] migrate marker.dart --- .../google_maps_flutter_web/lib/src/marker.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart index 77258504ef6..96b3181d807 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart @@ -69,7 +69,7 @@ class MarkerController { /// This cannot be called after [remove]. void update( gmaps.MarkerOptions options, { - HtmlElement? newInfoWindowContent, + HTMLElement? newInfoWindowContent, }) { assert(_marker != null, 'Cannot `update` Marker after calling `remove`.'); _marker!.options = options; From 147e5702c2abdc5c53ade46a843c53e1543d0cbd Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:28:41 +0200 Subject: [PATCH 09/43] migrate convert.dart --- .../lib/src/convert.dart | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 060d0a24fd4..6baa0bc8958 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -203,30 +203,25 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { // Add an outer wrapper to the contents of the infowindow, we need it to listen // to click events... - final HtmlElement container = DivElement() + final HTMLElement container = createDivElement() ..id = 'gmaps-marker-${marker.markerId.value}-infowindow'; if (markerTitle.isNotEmpty) { - final HtmlElement title = HeadingElement.h3() + final HTMLHeadingElement title = (document.createElement('h3') as HTMLHeadingElement) ..className = 'infowindow-title' ..innerText = markerTitle; - container.children.add(title); + container.appendChild(title); } if (markerSnippet.isNotEmpty) { - final HtmlElement snippet = DivElement() + final HTMLElement snippet = createDivElement() ..className = 'infowindow-snippet' // `sanitizeHtml` is used to clean the (potential) user input from (potential) // XSS attacks through the contents of the marker InfoWindow. // See: https://pub.dev/documentation/sanitize_html/latest/sanitize_html/sanitizeHtml.html // See: b/159137885, b/159598165 - // The NodeTreeSanitizer.trusted just tells setInnerHtml to leave the output - // of `sanitizeHtml` untouched. // ignore: unsafe_html - ..setInnerHtml( - sanitizeHtml(markerSnippet), - treeSanitizer: NodeTreeSanitizer.trusted, - ); - container.children.add(snippet); + ..innerHTML = sanitizeHtml(markerSnippet); + container.appendChild(snippet); } return gmaps.InfoWindowOptions() @@ -273,9 +268,12 @@ gmaps.Icon? _gmIconFromBitmapDescriptor(BitmapDescriptor bitmapDescriptor) { } else if (iconConfig[0] == 'fromBytes') { // Grab the bytes, and put them into a blob final List bytes = iconConfig[1]! as List; + // TODO(ditman): Improve Blob creation + // See https://github.com/dart-lang/web/issues/91 + // // Create a Blob from bytes, but let the browser figure out the encoding - final Blob blob = Blob([bytes]); - icon = gmaps.Icon()..url = Url.createObjectUrlFromBlob(blob); + final Blob blob = Blob(bytes.map((int byte) => byte.toJS).toList().toJS); + icon = gmaps.Icon()..url = URL.createObjectURL(blob); final gmaps.Size? size = _gmSizeFromIconConfig(iconConfig, 2); if (size != null) { From 5ff2982d4fba49bde08812526445e55008786863 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:32:56 +0200 Subject: [PATCH 10/43] migrate google_maps_controller.dart --- .../lib/src/google_maps_controller.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 494029ce02c..c577ba30021 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -7,7 +7,7 @@ part of '../google_maps_flutter_web.dart'; /// Type used when passing an override to the _createMap function. @visibleForTesting typedef DebugCreateMapFunction = gmaps.GMap Function( - HtmlElement div, gmaps.MapOptions options); + HTMLElement div, gmaps.MapOptions options); /// Encapsulates a [gmaps.GMap], its events, and where in the DOM it's rendered. class GoogleMapController { @@ -36,7 +36,7 @@ class GoogleMapController { // Register the view factory that will hold the `_div` that holds the map in the DOM. // The `_div` needs to be created outside of the ViewFactory (and cached!) so we can // use it to create the [gmaps.GMap] in the `init()` method of this class. - _div = DivElement() + _div = createDivElement() ..id = _getViewType(mapId) ..style.width = '100%' ..style.height = '100%'; @@ -74,7 +74,7 @@ class GoogleMapController { // The Flutter widget that contains the rendered Map. HtmlElementView? _widget; - late HtmlElement _div; + late HTMLElement _div; /// The Flutter widget that will contain the rendered Map. Used for caching. Widget? get widget { @@ -138,7 +138,7 @@ class GoogleMapController { DebugCreateMapFunction? _overrideCreateMap; - gmaps.GMap _createMap(HtmlElement div, gmaps.MapOptions options) { + gmaps.GMap _createMap(HTMLElement div, gmaps.MapOptions options) { if (_overrideCreateMap != null) { return _overrideCreateMap!(div, options); } From c4581dd8128dcb1ebe6b8b7e4475ecc6a3371cf2 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:38:09 +0200 Subject: [PATCH 11/43] migrate google map controller test --- .../integration_test/google_maps_controller_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 51c36a55a47..426cd834bdc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html' as html; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -14,6 +13,7 @@ import 'package:integration_test/integration_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'google_maps_controller_test.mocks.dart'; +import 'test_utils.dart'; // This value is used when comparing long~num, like // LatLng values. @@ -230,7 +230,7 @@ void main() { polygons = MockPolygonsController(); polylines = MockPolylinesController(); tileOverlays = MockTileOverlaysController(); - map = gmaps.GMap(html.DivElement()); + map = gmaps.GMap(createDivElement()); }); testWidgets('listens to map events', (WidgetTester tester) async { @@ -471,7 +471,7 @@ void main() { setUp(() { map = gmaps.GMap( - html.DivElement(), + createDivElement(), gmaps.MapOptions() ..zoom = 10 ..center = gmaps.LatLng(0, 0), From 0fb3d67368446c47a4ab0ae270a03cd81e9feb42 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:40:31 +0200 Subject: [PATCH 12/43] migrate markers test --- .../example/integration_test/marker_test.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart index 2e2d77b71de..e6b33cacfe7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart @@ -3,13 +3,14 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html' as html; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; import 'package:integration_test/integration_test.dart'; +import 'test_utils.dart'; + /// Test Markers void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -123,7 +124,7 @@ void main() { testWidgets('showInfoWindow', (WidgetTester tester) async { final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); - final gmaps.GMap map = gmaps.GMap(html.DivElement()); + final gmaps.GMap map = gmaps.GMap(createDivElement()); marker.set('map', map); final MarkerController controller = MarkerController( marker: marker, @@ -138,7 +139,7 @@ void main() { testWidgets('hideInfoWindow', (WidgetTester tester) async { final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); - final gmaps.GMap map = gmaps.GMap(html.DivElement()); + final gmaps.GMap map = gmaps.GMap(createDivElement()); marker.set('map', map); final MarkerController controller = MarkerController( marker: marker, @@ -156,7 +157,7 @@ void main() { setUp(() { final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); - final gmaps.GMap map = gmaps.GMap(html.DivElement()); + final gmaps.GMap map = gmaps.GMap(createDivElement()); marker.set('map', map); controller = MarkerController(marker: marker, infoWindow: infoWindow); }); From 98987373a067ba6d3647f699e3a769bfe3c3b3d2 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:45:39 +0200 Subject: [PATCH 13/43] migrate another markers test --- .../example/integration_test/markers_test.dart | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index 6a264064a3c..90c25b4a4a3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -4,7 +4,6 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:html' as html; import 'dart:typed_data'; import 'dart:ui'; @@ -14,8 +13,10 @@ import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; import 'package:http/http.dart' as http; import 'package:integration_test/integration_test.dart'; +import 'package:web/web.dart'; import 'resources/icon_image_base64.dart'; +import 'test_utils.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -28,7 +29,7 @@ void main() { setUp(() { events = StreamController>(); controller = MarkersController(stream: events); - map = gmaps.GMap(html.DivElement()); + map = gmaps.GMap(createDivElement()); controller.bindToMap(123, map); }); @@ -274,11 +275,11 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final html.HtmlElement? content = controller.markers[const MarkerId('1')] - ?.infoWindow?.content as html.HtmlElement?; - expect(content?.innerHtml, contains('title for test')); + final HTMLElement? content = controller.markers[const MarkerId('1')] + ?.infoWindow?.content as HTMLElement?; + expect(content?.innerHTML, contains('title for test')); expect( - content?.innerHtml, + content?.innerHTML, contains( 'Go to Google >>>', )); @@ -299,8 +300,8 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final html.HtmlElement? content = controller.markers[const MarkerId('1')] - ?.infoWindow?.content as html.HtmlElement?; + final HTMLElement? content = controller.markers[const MarkerId('1')] + ?.infoWindow?.content as HTMLElement?; content?.click(); From 18564d2123494f5daa55bf414c9f2d4fe8216c4c Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:52:12 +0200 Subject: [PATCH 14/43] migrate overlay_test.dart --- .../integration_test/overlay_test.dart | 53 +++++++++++++------ 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart index 29f902f7f1e..9dc7baa1b2f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart @@ -2,14 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; import 'dart:convert'; -import 'dart:html' as html; +import 'dart:js_interop'; +import 'dart:js_util'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:web/web.dart'; import 'resources/tile16_base64.dart'; @@ -43,7 +46,7 @@ void main() { final gmaps.Size size = controller.gmMapType.tileSize!; expect(size.width, TileOverlayController.logicalTileSize); expect(size.height, TileOverlayController.logicalTileSize); - expect(controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, html.document), + expect(controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document), null); }); @@ -55,16 +58,24 @@ void main() { ), ); - final html.ImageElement img = - controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, html.document)! - as html.ImageElement; + final HTMLImageElement img = + controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document)! + as HTMLImageElement; expect(img.naturalWidth, 0); expect(img.naturalHeight, 0); expect(img.hidden, true); - // Wait until the image is fully loaded and decoded before re-reading its attributes. - await img.onLoad.first; - await img.decode(); + final Completer imageLoadCompleter = Completer(); + + // Wait until the image is fully loaded and decoded before re-reading its attributes + img.onload = allowInterop((_) { + if (!imageLoadCompleter.isCompleted) { + imageLoadCompleter.complete(); + } + }).toJS; + + await imageLoadCompleter.future; + await img.decode().toDart; expect(img.hidden, false); expect(img.naturalWidth, 16); @@ -79,9 +90,9 @@ void main() { ), ); { - final html.ImageElement img = - controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, html.document)! - as html.ImageElement; + final HTMLImageElement img = + controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document)! + as HTMLImageElement; await null; // let `getTile` `then` complete expect( img.src, @@ -95,10 +106,20 @@ void main() { tileProvider: TestTileProvider(), )); { - final html.ImageElement img = - controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, html.document)! - as html.ImageElement; - await img.onLoad.first; + final HTMLImageElement img = + controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document)! + as HTMLImageElement; + + final Completer imageLoadCompleter = Completer(); + + img.onload = allowInterop((_) { + if (!imageLoadCompleter.isCompleted) { + imageLoadCompleter.complete(); + } + }).toJS; + + await imageLoadCompleter.future; + expect( img.src, isNotEmpty, @@ -109,7 +130,7 @@ void main() { controller.update(const TileOverlay(tileOverlayId: id)); { expect( - controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, html.document), + controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document), null, reason: 'Setting a null tileProvider should work.', ); From aa9533a79651021c131e607ff241f8dbbc18a7f0 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:54:31 +0200 Subject: [PATCH 15/43] migrate overlays_test.dart --- .../example/integration_test/overlays_test.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart index 8b6b34694f4..fce520c88f5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html' as html; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -14,9 +13,11 @@ import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' import 'package:integration_test/integration_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:web/web.dart'; @GenerateNiceMocks(>[MockSpec()]) import 'overlays_test.mocks.dart'; +import 'test_utils.dart'; MockTileProvider neverTileProvider() { final MockTileProvider tileProvider = MockTileProvider(); @@ -38,13 +39,13 @@ void main() { /// 0. void probeTiles() { for (final gmaps.MapType? mapType in map.overlayMapTypes!.array!) { - mapType?.getTile!(gmaps.Point(0, 0), 0, html.document); + mapType?.getTile!(gmaps.Point(0, 0), 0, document); } } setUp(() { controller = TileOverlaysController(); - map = gmaps.GMap(html.DivElement()); + map = gmaps.GMap(createDivElement()); controller.googleMap = map; tileProviders = [ From 1667de939eac01edd23b599b066df63b0db477ee Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:56:13 +0200 Subject: [PATCH 16/43] migrate shapes_test.dart --- .../example/integration_test/shapes_test.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index b9bc2d371c9..b1e01851c29 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html' as html; import 'dart:ui'; import 'package:flutter_test/flutter_test.dart'; @@ -13,6 +12,8 @@ import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; import 'package:integration_test/integration_test.dart'; +import 'test_utils.dart'; + // This value is used when comparing the results of // converting from a byte value to a double between 0 and 1. // (For Color opacity values, for example) @@ -25,7 +26,7 @@ void main() { late gmaps.GMap map; setUp(() { - map = gmaps.GMap(html.DivElement()); + map = gmaps.GMap(createDivElement()); }); group('CirclesController', () { From c43f31e1888272d483970eaaf509f4e9dea7e4fd Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 17:58:10 +0200 Subject: [PATCH 17/43] add missing imports --- .../google_maps_flutter_web/lib/google_maps_flutter_web.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index 8012cb414cd..e3530ff95aa 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -6,6 +6,7 @@ library google_maps_flutter_web; import 'dart:async'; import 'dart:convert'; +import 'dart:js_interop'; import 'dart:js_util'; import 'dart:ui_web' as ui_web; @@ -24,6 +25,7 @@ import 'package:web/web.dart'; import 'src/google_maps_inspector_web.dart'; import 'src/third_party/to_screen_location/to_screen_location.dart'; import 'src/types.dart'; +import 'src/utils.dart'; part 'src/circle.dart'; part 'src/circles.dart'; From a14981c389b07543c1f47b2281926345e038c986 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Sat, 28 Oct 2023 18:12:19 +0200 Subject: [PATCH 18/43] remove space --- .../google_maps_flutter_web/lib/src/overlay.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart index 91f3d4aab69..a25dfc5b51f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart @@ -42,7 +42,7 @@ class TileOverlayController { return null; } - final HTMLImageElement img = + final HTMLImageElement img = ownerDocument!.createElement('img') as HTMLImageElement; img.width = img.height = logicalTileSize; img.hidden = true.toJS; From 32d66fa0814783c7e6e0f4208202b1310fcdfca5 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Thu, 11 Jan 2024 10:56:04 +0100 Subject: [PATCH 19/43] switch to pkg google_maps beta --- .../google_maps_flutter_web/example/pubspec.yaml | 4 ++-- .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 838731e02db..ab7d9b76d4e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -12,13 +12,13 @@ dependencies: google_maps_flutter_platform_interface: ^2.4.0 google_maps_flutter_web: path: ../ - web: ^0.3.0 + web: ^0.4.0 dev_dependencies: build_runner: ^2.1.1 flutter_test: sdk: flutter - google_maps: ^6.1.0 + google_maps: 7.0.0-beta.1 # TODO: migrate to stable 7.0.0 once published google_maps_flutter: ^2.2.0 # Needed for projection_test.dart http: ">=0.13.0 <2.0.0" integration_test: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index c9424bfbd38..1669ca8ee31 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -22,11 +22,11 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - google_maps: ^6.1.0 + google_maps: 7.0.0-beta.1 # TODO: migrate to stable 7.0.0 once published google_maps_flutter_platform_interface: ^2.4.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 - web: ^0.3.0 + web: ^0.4.0 dev_dependencies: flutter_test: From 788d35a73bde956fd6d8ca17d7a374fbd63695ea Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Thu, 11 Jan 2024 10:57:37 +0100 Subject: [PATCH 20/43] add casts due to pkg:web 0.4.0 removing "implements JSObject" from Blob --- .../google_maps_flutter_web/lib/src/convert.dart | 2 +- .../google_maps_flutter_web/lib/src/overlay.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 6baa0bc8958..5d1a1c5da86 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -273,7 +273,7 @@ gmaps.Icon? _gmIconFromBitmapDescriptor(BitmapDescriptor bitmapDescriptor) { // // Create a Blob from bytes, but let the browser figure out the encoding final Blob blob = Blob(bytes.map((int byte) => byte.toJS).toList().toJS); - icon = gmaps.Icon()..url = URL.createObjectURL(blob); + icon = gmaps.Icon()..url = URL.createObjectURL(blob as JSObject); final gmaps.Size? size = _gmSizeFromIconConfig(iconConfig, 2); if (size != null) { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart index a25dfc5b51f..fb080c19f18 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart @@ -58,7 +58,7 @@ class TileOverlayController { final String src = URL.createObjectURL( // TODO(ditman): Improve Blob creation // See https://github.com/dart-lang/web/issues/91 - Blob(tile.data!.map((int byte) => byte.toJS).toList().toJS), + Blob(tile.data!.map((int byte) => byte.toJS).toList().toJS) as JSObject, ); img.src = src; img.addEventListener( From 1040103e77ce16122787640a75f4e7b2375fbb44 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Thu, 11 Jan 2024 10:58:48 +0100 Subject: [PATCH 21/43] format --- .../example/integration_test/markers_test.dart | 8 ++++---- .../example/integration_test/overlay_test.dart | 6 ++++-- .../google_maps_flutter_web/lib/src/convert.dart | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index 90c25b4a4a3..e7e38872be4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -275,8 +275,8 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final HTMLElement? content = controller.markers[const MarkerId('1')] - ?.infoWindow?.content as HTMLElement?; + final HTMLElement? content = controller + .markers[const MarkerId('1')]?.infoWindow?.content as HTMLElement?; expect(content?.innerHTML, contains('title for test')); expect( content?.innerHTML, @@ -300,8 +300,8 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final HTMLElement? content = controller.markers[const MarkerId('1')] - ?.infoWindow?.content as HTMLElement?; + final HTMLElement? content = controller + .markers[const MarkerId('1')]?.infoWindow?.content as HTMLElement?; content?.click(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart index 9dc7baa1b2f..f568351c9ef 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart @@ -46,8 +46,10 @@ void main() { final gmaps.Size size = controller.gmMapType.tileSize!; expect(size.width, TileOverlayController.logicalTileSize); expect(size.height, TileOverlayController.logicalTileSize); - expect(controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document), - null); + expect( + controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document), + null, + ); }); testWidgets('produces image tiles', (WidgetTester tester) async { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 5d1a1c5da86..1bbcf8a293e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -207,9 +207,10 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { ..id = 'gmaps-marker-${marker.markerId.value}-infowindow'; if (markerTitle.isNotEmpty) { - final HTMLHeadingElement title = (document.createElement('h3') as HTMLHeadingElement) - ..className = 'infowindow-title' - ..innerText = markerTitle; + final HTMLHeadingElement title = + (document.createElement('h3') as HTMLHeadingElement) + ..className = 'infowindow-title' + ..innerText = markerTitle; container.appendChild(title); } if (markerSnippet.isNotEmpty) { From edc00a8da7b1ffff85834c1d315f27f3cd84d618 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Thu, 11 Jan 2024 11:15:48 +0100 Subject: [PATCH 22/43] fix event listener type --- .../google_maps_flutter_web/lib/src/markers.dart | 11 +++-------- .../google_maps_flutter_web/lib/src/overlay.dart | 11 ++++------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index 78b9a70407e..26cb94f9ad2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -42,14 +42,9 @@ class MarkersController extends GeometryController { infoWindowOptions.content is HTMLElement) { final HTMLElement content = infoWindowOptions.content! as HTMLElement; - // TODO(ditman): Use the premade handler - // See https://github.com/dart-lang/web/issues/76 - content.addEventListener( - 'click', - allowInterop((_) { - _onInfoWindowTap(marker.markerId); - }).toJS, - ); + content.onclick = (JSAny? _) { + _onInfoWindowTap(marker.markerId); + }.toJS; } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart index fb080c19f18..89be62c0809 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart @@ -61,13 +61,10 @@ class TileOverlayController { Blob(tile.data!.map((int byte) => byte.toJS).toList().toJS) as JSObject, ); img.src = src; - img.addEventListener( - 'load', - allowInterop((_) { - img.hidden = false.toJS; - URL.revokeObjectURL(src); - }).toJS, - ); + img.onload = (JSAny? _) { + img.hidden = false.toJS; + URL.revokeObjectURL(src); + }.toJS; }); return img; From cd2b0e8c96e19521588ef9e3c7722fa69358e323 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Tue, 23 Jan 2024 10:59:35 +0100 Subject: [PATCH 23/43] add directionality --- .../google_maps_flutter_web/example/lib/main.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index 6bd536109f7..c32edb4b8ba 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -20,6 +20,9 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { @override Widget build(BuildContext context) { - return const Text('Testing... Look at the console output for results!'); + return const Directionality( + textDirection: TextDirection.ltr, + child: Text('Testing... Look at the console output for results!'), + ); } } From 861f2947b84ca7b5d3149d411cffe587a6787733 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Tue, 23 Jan 2024 11:13:54 +0100 Subject: [PATCH 24/43] fix version constraint for pkg:web --- .../google_maps_flutter_web/example/pubspec.yaml | 6 +++--- .../google_maps_flutter_web/pubspec.yaml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index ab7d9b76d4e..2f0d529efbd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -3,8 +3,8 @@ publish_to: none # Tests require flutter beta or greater to run. environment: - sdk: ^3.1.0 - flutter: ">=3.13.0" + sdk: "^3.3.0" + flutter: ">=3.19.0" dependencies: flutter: @@ -12,7 +12,7 @@ dependencies: google_maps_flutter_platform_interface: ^2.4.0 google_maps_flutter_web: path: ../ - web: ^0.4.0 + web: "^0.5.0" dev_dependencies: build_runner: ^2.1.1 diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 1669ca8ee31..ad93cd4edcc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.5.4+3 environment: - sdk: ">=3.1.0 <4.0.0" - flutter: ">=3.13.0" + sdk: "^3.3.0" + flutter: ">=3.19.0" flutter: plugin: @@ -26,7 +26,7 @@ dependencies: google_maps_flutter_platform_interface: ^2.4.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 - web: ^0.4.0 + web: "^0.5.0" dev_dependencies: flutter_test: From bb8810fa8b62880ad147fb02c49c45e1429043c6 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Tue, 23 Jan 2024 11:17:03 +0100 Subject: [PATCH 25/43] fix type error in overlay test --- .../example/integration_test/overlay_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart index f568351c9ef..2466c1ade5b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart @@ -70,7 +70,7 @@ void main() { final Completer imageLoadCompleter = Completer(); // Wait until the image is fully loaded and decoded before re-reading its attributes - img.onload = allowInterop((_) { + img.onload = allowInterop((JSAny? _) { if (!imageLoadCompleter.isCompleted) { imageLoadCompleter.complete(); } @@ -114,7 +114,7 @@ void main() { final Completer imageLoadCompleter = Completer(); - img.onload = allowInterop((_) { + img.onload = allowInterop((JSAny? _) { if (!imageLoadCompleter.isCompleted) { imageLoadCompleter.complete(); } From e578d869acc5786dc705c31bc79d93a36762012d Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Tue, 23 Jan 2024 11:19:48 +0100 Subject: [PATCH 26/43] fix lint warnings --- .../google_maps_flutter_web/lib/src/marker.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart index 96b3181d807..c1b0772a139 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart @@ -74,7 +74,7 @@ class MarkerController { assert(_marker != null, 'Cannot `update` Marker after calling `remove`.'); _marker!.options = options; if (_infoWindow != null && newInfoWindowContent != null) { - _infoWindow!.content = newInfoWindowContent; + _infoWindow.content = newInfoWindowContent; } } @@ -94,7 +94,7 @@ class MarkerController { void hideInfoWindow() { assert(_marker != null, 'Cannot `hideInfoWindow` on a `remove`d Marker.'); if (_infoWindow != null) { - _infoWindow!.close(); + _infoWindow.close(); _infoWindowShown = false; } } @@ -105,7 +105,7 @@ class MarkerController { void showInfoWindow() { assert(_marker != null, 'Cannot `showInfoWindow` on a `remove`d Marker.'); if (_infoWindow != null) { - _infoWindow!.open(_marker!.map, _marker); + _infoWindow.open(_marker!.map, _marker); _infoWindowShown = true; } } From 638a466efa4e3cf15e57d9cc422966d6e39d69d4 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Tue, 23 Jan 2024 13:17:39 +0100 Subject: [PATCH 27/43] fix hanging test --- .../example/integration_test/overlay_test.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart index 2466c1ade5b..09f5bb17314 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart @@ -76,6 +76,12 @@ void main() { } }).toJS; + img.onerror = allowInterop((Event? error) { + if (!imageLoadCompleter.isCompleted) { + imageLoadCompleter.completeError('Failed to load image.'); + } + }).toJS; + await imageLoadCompleter.future; await img.decode().toDart; @@ -120,6 +126,12 @@ void main() { } }).toJS; + img.onerror = allowInterop((Event? error) { + if (!imageLoadCompleter.isCompleted) { + imageLoadCompleter.completeError('Failed to load image.'); + } + }).toJS; + await imageLoadCompleter.future; expect( From 75db30dc125e886bf46ce611443b5d1497598a83 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Tue, 23 Jan 2024 13:47:19 +0100 Subject: [PATCH 28/43] use .toJS on Function directly --- .../example/integration_test/overlay_test.dart | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart index 09f5bb17314..5574da1867a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:js_interop'; -import 'dart:js_util'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; @@ -70,17 +69,17 @@ void main() { final Completer imageLoadCompleter = Completer(); // Wait until the image is fully loaded and decoded before re-reading its attributes - img.onload = allowInterop((JSAny? _) { + img.onload = (JSAny? _) { if (!imageLoadCompleter.isCompleted) { imageLoadCompleter.complete(); } - }).toJS; + }.toJS; - img.onerror = allowInterop((Event? error) { + img.onerror = (Event? error) { if (!imageLoadCompleter.isCompleted) { imageLoadCompleter.completeError('Failed to load image.'); } - }).toJS; + }.toJS; await imageLoadCompleter.future; await img.decode().toDart; @@ -120,17 +119,17 @@ void main() { final Completer imageLoadCompleter = Completer(); - img.onload = allowInterop((JSAny? _) { + img.onload = (JSAny? _) { if (!imageLoadCompleter.isCompleted) { imageLoadCompleter.complete(); } - }).toJS; + }.toJS; - img.onerror = allowInterop((Event? error) { + img.onerror = (Event? error) { if (!imageLoadCompleter.isCompleted) { imageLoadCompleter.completeError('Failed to load image.'); } - }).toJS; + }.toJS; await imageLoadCompleter.future; From 2c086d2f5d25ac4ae89a00ba62e9cdf239c95b68 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Wed, 31 Jan 2024 15:22:33 +0100 Subject: [PATCH 29/43] fix test --- .../integration_test/overlay_test.dart | 33 ++----------------- .../lib/src/convert.dart | 12 ++++--- .../lib/src/overlay.dart | 4 +-- 3 files changed, 11 insertions(+), 38 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart index 5574da1867a..0724da21127 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlay_test.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:async'; import 'dart:convert'; import 'dart:js_interop'; @@ -66,22 +65,8 @@ void main() { expect(img.naturalHeight, 0); expect(img.hidden, true); - final Completer imageLoadCompleter = Completer(); + await img.onLoad.first; - // Wait until the image is fully loaded and decoded before re-reading its attributes - img.onload = (JSAny? _) { - if (!imageLoadCompleter.isCompleted) { - imageLoadCompleter.complete(); - } - }.toJS; - - img.onerror = (Event? error) { - if (!imageLoadCompleter.isCompleted) { - imageLoadCompleter.completeError('Failed to load image.'); - } - }.toJS; - - await imageLoadCompleter.future; await img.decode().toDart; expect(img.hidden, false); @@ -117,21 +102,7 @@ void main() { controller.gmMapType.getTile!(gmaps.Point(0, 0), 0, document)! as HTMLImageElement; - final Completer imageLoadCompleter = Completer(); - - img.onload = (JSAny? _) { - if (!imageLoadCompleter.isCompleted) { - imageLoadCompleter.complete(); - } - }.toJS; - - img.onerror = (Event? error) { - if (!imageLoadCompleter.isCompleted) { - imageLoadCompleter.completeError('Failed to load image.'); - } - }.toJS; - - await imageLoadCompleter.future; + await img.onLoad.first; expect( img.src, diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 1bbcf8a293e..d3bac5b8c13 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -269,11 +269,15 @@ gmaps.Icon? _gmIconFromBitmapDescriptor(BitmapDescriptor bitmapDescriptor) { } else if (iconConfig[0] == 'fromBytes') { // Grab the bytes, and put them into a blob final List bytes = iconConfig[1]! as List; - // TODO(ditman): Improve Blob creation - // See https://github.com/dart-lang/web/issues/91 - // // Create a Blob from bytes, but let the browser figure out the encoding - final Blob blob = Blob(bytes.map((int byte) => byte.toJS).toList().toJS); + final Blob blob; + + if (bytes is Uint8List) { + blob = Blob([bytes.toJS].toJS); + } else { + blob = Blob([Uint8List.fromList(bytes).toJS].toJS); + } + icon = gmaps.Icon()..url = URL.createObjectURL(blob as JSObject); final gmaps.Size? size = _gmSizeFromIconConfig(iconConfig, 2); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart index 89be62c0809..29823d00b9f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/overlay.dart @@ -56,9 +56,7 @@ class TileOverlayController { } // Using img lets us take advantage of native decoding. final String src = URL.createObjectURL( - // TODO(ditman): Improve Blob creation - // See https://github.com/dart-lang/web/issues/91 - Blob(tile.data!.map((int byte) => byte.toJS).toList().toJS) as JSObject, + Blob([tile.data!.toJS].toJS) as JSObject, ); img.src = src; img.onload = (JSAny? _) { From fb7f53a5f5ea7ed60c37cbf21f2540d6eb37d280 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Thu, 8 Feb 2024 10:02:52 +0100 Subject: [PATCH 30/43] bump google_maps to 7.0.0 --- .../google_maps_flutter_web/example/pubspec.yaml | 2 +- .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 2f0d529efbd..2ffc521c585 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -18,7 +18,7 @@ dev_dependencies: build_runner: ^2.1.1 flutter_test: sdk: flutter - google_maps: 7.0.0-beta.1 # TODO: migrate to stable 7.0.0 once published + google_maps: ^7.0.0 google_maps_flutter: ^2.2.0 # Needed for projection_test.dart http: ">=0.13.0 <2.0.0" integration_test: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index ad93cd4edcc..f87eaf71446 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - google_maps: 7.0.0-beta.1 # TODO: migrate to stable 7.0.0 once published + google_maps: ^7.0.0 google_maps_flutter_platform_interface: ^2.4.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 From aee9770576e5b4b0ec181513efde88f47d53c867 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Wed, 14 Feb 2024 09:55:11 +0100 Subject: [PATCH 31/43] remove the utility in integration tests --- .../integration_test/google_maps_controller_test.dart | 2 +- .../example/integration_test/marker_test.dart | 3 +-- .../example/integration_test/markers_test.dart | 2 +- .../example/integration_test/overlays_test.dart | 2 +- .../example/integration_test/shapes_test.dart | 3 +-- .../example/integration_test/test_utils.dart | 8 -------- 6 files changed, 5 insertions(+), 15 deletions(-) delete mode 100644 packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/test_utils.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 426cd834bdc..af571076e46 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -9,11 +9,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'google_maps_controller_test.mocks.dart'; -import 'test_utils.dart'; // This value is used when comparing long~num, like // LatLng values. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart index e6b33cacfe7..c41d439d6fa 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart @@ -7,10 +7,9 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:integration_test/integration_test.dart'; -import 'test_utils.dart'; - /// Test Markers void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index e7e38872be4..a4147620864 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -11,12 +11,12 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:http/http.dart' as http; import 'package:integration_test/integration_test.dart'; import 'package:web/web.dart'; import 'resources/icon_image_base64.dart'; -import 'test_utils.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart index fce520c88f5..bf2517bb69f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart @@ -10,6 +10,7 @@ import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' hide GoogleMapController; +import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -17,7 +18,6 @@ import 'package:web/web.dart'; @GenerateNiceMocks(>[MockSpec()]) import 'overlays_test.mocks.dart'; -import 'test_utils.dart'; MockTileProvider neverTileProvider() { final MockTileProvider tileProvider = MockTileProvider(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index b1e01851c29..adac4d9bfff 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -10,10 +10,9 @@ import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps/google_maps_geometry.dart' as geometry; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:integration_test/integration_test.dart'; -import 'test_utils.dart'; - // This value is used when comparing the results of // converting from a byte value to a double between 0 and 1. // (For Color opacity values, for example) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/test_utils.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/test_utils.dart deleted file mode 100644 index b4340e0641f..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/test_utils.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:web/web.dart'; - -/// Convenience method to create a new [HTMLDivElement] element. -@visibleForTesting -HTMLDivElement createDivElement() { - return document.createElement('div') as HTMLDivElement; -} From 9f2716e1dfd43a369a2e15277493ffb7cc001245 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Wed, 14 Feb 2024 10:02:38 +0100 Subject: [PATCH 32/43] assert on Uint8List for the bitmap descriptor --- .../google_maps_flutter_web/lib/src/convert.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index d3bac5b8c13..093566956b9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -272,11 +272,12 @@ gmaps.Icon? _gmIconFromBitmapDescriptor(BitmapDescriptor bitmapDescriptor) { // Create a Blob from bytes, but let the browser figure out the encoding final Blob blob; - if (bytes is Uint8List) { - blob = Blob([bytes.toJS].toJS); - } else { - blob = Blob([Uint8List.fromList(bytes).toJS].toJS); - } + assert( + bytes is Uint8List, + 'The bytes for a BitmapDescriptor icon must be a Uint8List', + ); + + blob = Blob([(bytes as Uint8List).toJS].toJS); icon = gmaps.Icon()..url = URL.createObjectURL(blob as JSObject); From cb9c6654fda49800b60467b6e86fea19a1654f4a Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Wed, 14 Feb 2024 10:29:16 +0100 Subject: [PATCH 33/43] use trusted types policy to sanitize html --- .../lib/src/convert.dart | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 093566956b9..d82859699ce 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -221,7 +221,7 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { // See: https://pub.dev/documentation/sanitize_html/latest/sanitize_html/sanitizeHtml.html // See: b/159137885, b/159598165 // ignore: unsafe_html - ..innerHTML = sanitizeHtml(markerSnippet); + ..innerHTML = _sanitizeHtml(markerSnippet); container.appendChild(snippet); } @@ -525,3 +525,27 @@ gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) { return projection.fromPointToLatLng!(point)!; } + +String _sanitizeHtml(String htmlString) { + TrustedTypePolicy? trustedTypePolicy; + + try { + trustedTypePolicy = TrustedTypePolicyFactory().createPolicy( + 'google_maps_flutter_sanitize', + TrustedTypePolicyOptions( + createHTML: (String html) { + return sanitizeHtml(html); + }.toJS, + ), + ); + } catch (_) { + // Firefox and Safari don't support Trusted Types yet. + // See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility + } + + if (trustedTypePolicy == null) { + return sanitizeHtml(htmlString); + } + + return trustedTypePolicy.createHTML(htmlString, null).toString(); +} From aa4617129f94c7776a644076a6a62aec466d357a Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Wed, 14 Feb 2024 16:16:04 +0100 Subject: [PATCH 34/43] fix constructor --- .../google_maps_flutter_web/lib/src/convert.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index d82859699ce..249269675a3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -530,7 +530,7 @@ String _sanitizeHtml(String htmlString) { TrustedTypePolicy? trustedTypePolicy; try { - trustedTypePolicy = TrustedTypePolicyFactory().createPolicy( + trustedTypePolicy = window.trustedTypes.createPolicy( 'google_maps_flutter_sanitize', TrustedTypePolicyOptions( createHTML: (String html) { From 0523daa194a87ab74280a8f00a214a2996ea4463 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Wed, 14 Feb 2024 16:49:51 +0100 Subject: [PATCH 35/43] fix argument --- .../google_maps_flutter_web/lib/src/convert.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 249269675a3..e407bd9a2b2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -533,7 +533,7 @@ String _sanitizeHtml(String htmlString) { trustedTypePolicy = window.trustedTypes.createPolicy( 'google_maps_flutter_sanitize', TrustedTypePolicyOptions( - createHTML: (String html) { + createHTML: (String html, JSAny? arguments) { return sanitizeHtml(html); }.toJS, ), From e2df4b15f90bb66965d9e3a91a35caf265860bec Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Thu, 15 Feb 2024 09:08:25 +0100 Subject: [PATCH 36/43] handle undefined trusted types policy --- .../lib/google_maps_flutter_web.dart | 1 + .../google_maps_flutter_web/lib/src/convert.dart | 7 ++++--- .../lib/src/dom_window_extension.dart | 10 ++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index e3530ff95aa..22303b20903 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -22,6 +22,7 @@ import 'package:sanitize_html/sanitize_html.dart'; import 'package:stream_transform/stream_transform.dart'; import 'package:web/web.dart'; +import 'src/dom_window_extension.dart'; import 'src/google_maps_inspector_web.dart'; import 'src/third_party/to_screen_location/to_screen_location.dart'; import 'src/types.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index e407bd9a2b2..6f762485b0f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -530,7 +530,9 @@ String _sanitizeHtml(String htmlString) { TrustedTypePolicy? trustedTypePolicy; try { - trustedTypePolicy = window.trustedTypes.createPolicy( + // Firefox and Safari don't support Trusted Types yet. + // See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility + trustedTypePolicy = window.trustedTypesNullable?.createPolicy( 'google_maps_flutter_sanitize', TrustedTypePolicyOptions( createHTML: (String html, JSAny? arguments) { @@ -539,8 +541,7 @@ String _sanitizeHtml(String htmlString) { ), ); } catch (_) { - // Firefox and Safari don't support Trusted Types yet. - // See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility + // Fallback to not using the trusted types policy. } if (trustedTypePolicy == null) { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart new file mode 100644 index 00000000000..bb2fbfad338 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart @@ -0,0 +1,10 @@ +import 'dart:js_interop'; + +import 'package:web/web.dart'; + +/// This extension exists to handle unsupported features by certain browsers. +extension DomWindowExtension on Window { + /// Get the `trustedTypes` object from the window, if it is supported. + @JS('trustedTypes') + external TrustedTypePolicyFactory? get trustedTypesNullable; +} From e358399d719f96839222299dd7ce585acd0cfc0e Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Mon, 19 Feb 2024 11:20:36 +0100 Subject: [PATCH 37/43] bump version of google_maps_flutter_web --- .../google_maps_flutter/google_maps_flutter_web/CHANGELOG.md | 5 +++-- .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index a8de9d0147e..8476953537f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 0.5.5 -* Updates minimum supported SDK version to Flutter 3.13/Dart 3.1. +* Migrates to `dart:js_interop` and `package:web` APIs. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 0.5.4+3 diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index f87eaf71446..4281e854122 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.5.4+3 +version: 0.5.5 environment: sdk: "^3.3.0" From 736aec1e9d7873d787a383872cf187aed8c4e808 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Mon, 19 Feb 2024 11:29:31 +0100 Subject: [PATCH 38/43] fix license headers --- .../google_maps_flutter_web/lib/src/dom_window_extension.dart | 4 ++++ .../google_maps_flutter_web/lib/src/utils.dart | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart index bb2fbfad338..c24ded6f1d2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart @@ -1,3 +1,7 @@ +// Copyright 2013 The Flutter 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:js_interop'; import 'package:web/web.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/utils.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/utils.dart index 2ec743ee355..94bc0b6b90d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/utils.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/utils.dart @@ -1,3 +1,7 @@ +// Copyright 2013 The Flutter 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 'package:web/web.dart'; /// Convenience method to create a new [HTMLDivElement] element. From 8b4d7bbd007c072b148d1b01cc85080312f9656c Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Fri, 23 Feb 2024 11:14:07 +0100 Subject: [PATCH 39/43] adjust trusted types binding usage --- .../example/pubspec.yaml | 4 +- .../lib/src/convert.dart | 17 ++++--- .../lib/src/dom_window_extension.dart | 49 ++++++++++++++++++- .../google_maps_flutter_web/pubspec.yaml | 4 +- 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 2ffc521c585..98587d5217e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -12,13 +12,13 @@ dependencies: google_maps_flutter_platform_interface: ^2.4.0 google_maps_flutter_web: path: ../ - web: "^0.5.0" + web: ^0.5.0 dev_dependencies: build_runner: ^2.1.1 flutter_test: sdk: flutter - google_maps: ^7.0.0 + google_maps: ^7.1.0 google_maps_flutter: ^2.2.0 # Needed for projection_test.dart http: ">=0.13.0 <2.0.0" integration_test: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 6f762485b0f..68bfad4aef3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -532,14 +532,15 @@ String _sanitizeHtml(String htmlString) { try { // Firefox and Safari don't support Trusted Types yet. // See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility - trustedTypePolicy = window.trustedTypesNullable?.createPolicy( - 'google_maps_flutter_sanitize', - TrustedTypePolicyOptions( - createHTML: (String html, JSAny? arguments) { - return sanitizeHtml(html); - }.toJS, - ), - ); + trustedTypePolicy = + WindowWithTrustedTypes(window).trustedTypesNullable?.createPolicy( + 'google_maps_flutter_sanitize', + TrustedTypePolicyOptions( + createHTML: (String html, JSAny? arguments) { + return sanitizeHtml(html); + }.toJS, + ), + ); } catch (_) { // Fallback to not using the trusted types policy. } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart index c24ded6f1d2..ad00d933c53 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart @@ -6,9 +6,54 @@ import 'dart:js_interop'; import 'package:web/web.dart'; -/// This extension exists to handle unsupported features by certain browsers. -extension DomWindowExtension on Window { +/// This extension type exists to handle unsupported features by certain browsers. +@JS() +extension type WindowWithTrustedTypes(Window _) implements JSObject { /// Get the `trustedTypes` object from the window, if it is supported. @JS('trustedTypes') external TrustedTypePolicyFactory? get trustedTypesNullable; } + +// TODO(ditman): remove this extension type when we depend on package:web 0.5.1 +/// This extension exists as a stop gap until `package:web 0.5.1` is released. +/// That version provides the `TrustedTypes` API. +@JS() +extension type TrustedTypePolicyFactory._(JSObject _) implements JSObject { + /// Create a new `TrustedTypePolicy` instance + /// with the given [policyName] and [policyOptions]. + external TrustedTypePolicy createPolicy( + String policyName, [ + TrustedTypePolicyOptions policyOptions, + ]); +} + +// TODO(ditman): remove this extension type when we depend on package:web 0.5.1 +/// This extension exists as a stop gap until `package:web 0.5.1` is released. +/// That version provides the `TrustedTypes` API. +extension type TrustedTypePolicy._(JSObject _) implements JSObject { + /// Create a new `TrustedHTML` instance with the given [input] and [arguments]. + external TrustedHTML createHTML( + String input, + JSAny? arguments, + ); +} + +// TODO(ditman): remove this extension type when we depend on package:web 0.5.1 +/// This extension exists as a stop gap until `package:web 0.5.1` is released. +/// That version provides the `TrustedTypes` API. +@JS() +extension type TrustedTypePolicyOptions._(JSObject _) implements JSObject { + /// Create a new `TrustedTypePolicyOptions` instance. + external factory TrustedTypePolicyOptions({ + JSFunction createHTML, + }); +} + +// TODO(ditman): remove this extension type when we depend on package:web 0.5.1 +/// This extension exists as a stop gap until `package:web 0.5.1` is released. +/// That version provides the `TrustedTypes` API. +@JS() +extension type TrustedHTML._(JSObject _) implements JSObject { + // This type inherits `toString()` from `Object`. + // See also: https://developer.mozilla.org/en-US/docs/Web/API/TrustedHTML/toString +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 4281e854122..b4832fa2973 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -22,11 +22,11 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - google_maps: ^7.0.0 + google_maps: ^7.1.0 google_maps_flutter_platform_interface: ^2.4.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 - web: "^0.5.0" + web: ^0.5.0 dev_dependencies: flutter_test: From d8adca19279e5a4d43e2f72fba45b948df4c35bf Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Tue, 27 Feb 2024 13:05:23 +0100 Subject: [PATCH 40/43] fix quotes in pubspec & add ignore for upcoming lint --- .../example/integration_test/google_maps_controller_test.dart | 1 + .../example/integration_test/marker_test.dart | 1 + .../example/integration_test/markers_test.dart | 1 + .../example/integration_test/overlays_test.dart | 1 + .../example/integration_test/shapes_test.dart | 1 + .../google_maps_flutter_web/example/pubspec.yaml | 2 +- .../google_maps_flutter_web/lib/google_maps_flutter_web.dart | 1 - .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 2 +- 8 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index af571076e46..5c3ccbdc8c7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -9,6 +9,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +// ignore: implementation_imports import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mockito/annotations.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart index c41d439d6fa..0b284cac766 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +// ignore: implementation_imports import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index a4147620864..d965435b3a5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -11,6 +11,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +// ignore: implementation_imports import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:http/http.dart' as http; import 'package:integration_test/integration_test.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart index bf2517bb69f..c680c97a993 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/overlays_test.dart @@ -10,6 +10,7 @@ import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' hide GoogleMapController; +// ignore: implementation_imports import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mockito/annotations.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index adac4d9bfff..ad3d3d4a8a4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -10,6 +10,7 @@ import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps/google_maps_geometry.dart' as geometry; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +// ignore: implementation_imports import 'package:google_maps_flutter_web/src/utils.dart'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 98587d5217e..1a02cfa2a65 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -3,7 +3,7 @@ publish_to: none # Tests require flutter beta or greater to run. environment: - sdk: "^3.3.0" + sdk: ^3.3.0 flutter: ">=3.19.0" dependencies: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index 22303b20903..3f8ce90edfa 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -7,7 +7,6 @@ library google_maps_flutter_web; import 'dart:async'; import 'dart:convert'; import 'dart:js_interop'; -import 'dart:js_util'; import 'dart:ui_web' as ui_web; import 'package:collection/collection.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index b4832fa2973..f78289d04fc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -5,7 +5,7 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 0.5.5 environment: - sdk: "^3.3.0" + sdk: ^3.3.0 flutter: ">=3.19.0" flutter: From 52baeca82b3cd406dd1568bb11db349cc26f96e9 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Tue, 27 Feb 2024 14:49:33 +0100 Subject: [PATCH 41/43] add JS binding for MapStyler --- .../lib/google_maps_flutter_web.dart | 1 + .../lib/src/convert.dart | 7 +++- .../lib/src/map_styler.dart | 40 +++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/lib/src/map_styler.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index 3f8ce90edfa..fe44d41aa48 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -23,6 +23,7 @@ import 'package:web/web.dart'; import 'src/dom_window_extension.dart'; import 'src/google_maps_inspector_web.dart'; +import 'src/map_styler.dart'; import 'src/third_party/to_screen_location/to_screen_location.dart'; import 'src/types.dart'; import 'src/utils.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 68bfad4aef3..7d805aa7e19 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -139,10 +139,11 @@ List _mapStyles(String? mapStyleJson) { styles = (json.decode(mapStyleJson, reviver: (Object? key, Object? value) { if (value is Map && _isJsonMapStyle(value as Map)) { - List stylers = []; + List stylers = []; if (value['stylers'] != null) { stylers = (value['stylers']! as List) - .map((Object? e) => e != null ? jsify(e) : null) + .whereType>() + .map(MapStyler.fromJson) .toList(); } return gmaps.MapTypeStyle() @@ -277,6 +278,8 @@ gmaps.Icon? _gmIconFromBitmapDescriptor(BitmapDescriptor bitmapDescriptor) { 'The bytes for a BitmapDescriptor icon must be a Uint8List', ); + // TODO(ditman): Improve this conversion + // See https://github.com/dart-lang/web/issues/180 blob = Blob([(bytes as Uint8List).toJS].toJS); icon = gmaps.Icon()..url = URL.createObjectURL(blob as JSObject); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/map_styler.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/map_styler.dart new file mode 100644 index 00000000000..e6a871599cb --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/map_styler.dart @@ -0,0 +1,40 @@ +// Copyright 2013 The Flutter 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:js_interop'; + +/// The interop type for a Google Maps Map Styler. +/// +/// See: https://developers.google.com/maps/documentation/javascript/style-reference#stylers +@JS() +@staticInterop +@anonymous +extension type MapStyler._(JSObject _) implements JSObject { + /// Create a new [MapStyler] instance. + external factory MapStyler({ + String? hue, + num? lightness, + num? saturation, + num? gamma, + // ignore: non_constant_identifier_names + bool? invert_lightness, + String? visibility, + String? color, + int? weight, + }); + + /// Create a new [MapStyler] instance from the given [json]. + factory MapStyler.fromJson(Map json) { + return MapStyler( + hue: json['hue'] as String?, + lightness: json['lightness'] as num?, + saturation: json['saturation'] as num?, + gamma: json['gamma'] as num?, + invert_lightness: json['invert_lightness'] as bool?, + visibility: json['visibility'] as String?, + color: json['color'] as String?, + weight: json['weight'] as int?, + ); + } +} From 1951a6ad463ea70d2b066aa5062c8f5a12b50357 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Tue, 27 Feb 2024 15:38:47 +0100 Subject: [PATCH 42/43] set inner html to trusted html instance --- .../lib/src/convert.dart | 49 ++++++------ .../lib/src/dom_window_extension.dart | 75 +++++++++++++------ 2 files changed, 75 insertions(+), 49 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 7d805aa7e19..ceb2d15fe2b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -216,13 +216,32 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { } if (markerSnippet.isNotEmpty) { final HTMLElement snippet = createDivElement() - ..className = 'infowindow-snippet' + ..className = 'infowindow-snippet'; + + // Firefox and Safari don't support Trusted Types yet. + // See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility + if (window.nullableTrustedTypes != null) { + final GoogleMapsTrustedTypePolicy trustedTypePolicy = + window.nullableTrustedTypes!.getTrustedTypesPolicy( + 'google_maps_flutter_sanitize', + GoogleMapsTrustedTypePolicyOptions( + createHTML: (String html, JSAny? arguments) { + return sanitizeHtml(html); + }.toJS, + ), + ); + + snippet.trustedInnerHTML = + trustedTypePolicy.createHTML(markerSnippet, null); + } else { // `sanitizeHtml` is used to clean the (potential) user input from (potential) // XSS attacks through the contents of the marker InfoWindow. // See: https://pub.dev/documentation/sanitize_html/latest/sanitize_html/sanitizeHtml.html // See: b/159137885, b/159598165 // ignore: unsafe_html - ..innerHTML = _sanitizeHtml(markerSnippet); + snippet.innerHTML = sanitizeHtml(markerSnippet); + } + container.appendChild(snippet); } @@ -528,29 +547,3 @@ gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) { return projection.fromPointToLatLng!(point)!; } - -String _sanitizeHtml(String htmlString) { - TrustedTypePolicy? trustedTypePolicy; - - try { - // Firefox and Safari don't support Trusted Types yet. - // See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility - trustedTypePolicy = - WindowWithTrustedTypes(window).trustedTypesNullable?.createPolicy( - 'google_maps_flutter_sanitize', - TrustedTypePolicyOptions( - createHTML: (String html, JSAny? arguments) { - return sanitizeHtml(html); - }.toJS, - ), - ); - } catch (_) { - // Fallback to not using the trusted types policy. - } - - if (trustedTypePolicy == null) { - return sanitizeHtml(htmlString); - } - - return trustedTypePolicy.createHTML(htmlString, null).toString(); -} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart index ad00d933c53..9962dcd0fc9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart @@ -4,35 +4,62 @@ import 'dart:js_interop'; -import 'package:web/web.dart'; +import 'package:web/web.dart' as web; -/// This extension type exists to handle unsupported features by certain browsers. -@JS() -extension type WindowWithTrustedTypes(Window _) implements JSObject { - /// Get the `trustedTypes` object from the window, if it is supported. +/// This extension gives [web.Window] a nullable getter to the `trustedTypes` +/// property, which is used to check for feature support. +extension NullableTrustedTypesGetter on web.Window { + /// (Nullable) Bindings to window.trustedTypes. + /// + /// This may be null if the browser doesn't support the Trusted Types API. + /// + /// See: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API @JS('trustedTypes') - external TrustedTypePolicyFactory? get trustedTypesNullable; + external GoogleMapsTrustedTypePolicyFactory? get nullableTrustedTypes; } // TODO(ditman): remove this extension type when we depend on package:web 0.5.1 /// This extension exists as a stop gap until `package:web 0.5.1` is released. /// That version provides the `TrustedTypes` API. -@JS() -extension type TrustedTypePolicyFactory._(JSObject _) implements JSObject { - /// Create a new `TrustedTypePolicy` instance - /// with the given [policyName] and [policyOptions]. - external TrustedTypePolicy createPolicy( +@JS('TrustedTypePolicyFactory') +extension type GoogleMapsTrustedTypePolicyFactory._(JSObject _) + implements JSObject { + /// The `TrustedTypePolicy` for Google Maps Flutter. + static GoogleMapsTrustedTypePolicy? _policy; + + @JS('createPolicy') + external GoogleMapsTrustedTypePolicy _createPolicy( String policyName, [ - TrustedTypePolicyOptions policyOptions, + GoogleMapsTrustedTypePolicyOptions policyOptions, ]); + + /// Get a new [GoogleMapsTrustedTypePolicy]. + /// + /// If a policy already exists, it will be returned. + /// Otherwise, a new policy is created. + GoogleMapsTrustedTypePolicy getTrustedTypesPolicy( + String policyName, [ + GoogleMapsTrustedTypePolicyOptions? policyOptions, + ]) { + if (_policy == null) { + if (policyOptions != null) { + _policy = _createPolicy(policyName, policyOptions); + } else { + _policy = _createPolicy(policyName); + } + } + + return _policy!; + } } // TODO(ditman): remove this extension type when we depend on package:web 0.5.1 /// This extension exists as a stop gap until `package:web 0.5.1` is released. /// That version provides the `TrustedTypes` API. -extension type TrustedTypePolicy._(JSObject _) implements JSObject { +@JS('TrustedTypePolicy') +extension type GoogleMapsTrustedTypePolicy._(JSObject _) implements JSObject { /// Create a new `TrustedHTML` instance with the given [input] and [arguments]. - external TrustedHTML createHTML( + external GoogleMapsTrustedHTML createHTML( String input, JSAny? arguments, ); @@ -41,10 +68,11 @@ extension type TrustedTypePolicy._(JSObject _) implements JSObject { // TODO(ditman): remove this extension type when we depend on package:web 0.5.1 /// This extension exists as a stop gap until `package:web 0.5.1` is released. /// That version provides the `TrustedTypes` API. -@JS() -extension type TrustedTypePolicyOptions._(JSObject _) implements JSObject { +@JS('TrustedTypePolicyOptions') +extension type GoogleMapsTrustedTypePolicyOptions._(JSObject _) + implements JSObject { /// Create a new `TrustedTypePolicyOptions` instance. - external factory TrustedTypePolicyOptions({ + external factory GoogleMapsTrustedTypePolicyOptions({ JSFunction createHTML, }); } @@ -52,8 +80,13 @@ extension type TrustedTypePolicyOptions._(JSObject _) implements JSObject { // TODO(ditman): remove this extension type when we depend on package:web 0.5.1 /// This extension exists as a stop gap until `package:web 0.5.1` is released. /// That version provides the `TrustedTypes` API. -@JS() -extension type TrustedHTML._(JSObject _) implements JSObject { - // This type inherits `toString()` from `Object`. - // See also: https://developer.mozilla.org/en-US/docs/Web/API/TrustedHTML/toString +@JS('TrustedHTML') +extension type GoogleMapsTrustedHTML._(JSObject _) implements JSObject {} + +/// This extension provides a setter for the [web.HTMLElement] `innerHTML` property, +/// that accepts trusted HTML only. +extension TrustedInnerHTML on web.HTMLElement { + /// Set the inner HTML of this element to the given [trustedHTML]. + @JS('innerHTML') + external set trustedInnerHTML(GoogleMapsTrustedHTML trustedHTML); } From 6583739c447332bbd46acec9cb145b72ee971cf0 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 27 Feb 2024 15:43:45 -0800 Subject: [PATCH 43/43] Make getTTPolicy a little bit less generic looking. --- .../lib/src/convert.dart | 3 +-- .../lib/src/dom_window_extension.dart | 19 ++++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index ceb2d15fe2b..d8d77a7728a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -222,8 +222,7 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { // See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility if (window.nullableTrustedTypes != null) { final GoogleMapsTrustedTypePolicy trustedTypePolicy = - window.nullableTrustedTypes!.getTrustedTypesPolicy( - 'google_maps_flutter_sanitize', + window.nullableTrustedTypes!.getGoogleMapsTrustedTypesPolicy( GoogleMapsTrustedTypePolicyOptions( createHTML: (String html, JSAny? arguments) { return sanitizeHtml(html); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart index 9962dcd0fc9..f1b9ba34393 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart @@ -37,17 +37,14 @@ extension type GoogleMapsTrustedTypePolicyFactory._(JSObject _) /// /// If a policy already exists, it will be returned. /// Otherwise, a new policy is created. - GoogleMapsTrustedTypePolicy getTrustedTypesPolicy( - String policyName, [ - GoogleMapsTrustedTypePolicyOptions? policyOptions, - ]) { - if (_policy == null) { - if (policyOptions != null) { - _policy = _createPolicy(policyName, policyOptions); - } else { - _policy = _createPolicy(policyName); - } - } + /// + /// Because of we only cache one _policy, this method + /// specifically hardcoded to the GoogleMaps use case. + GoogleMapsTrustedTypePolicy getGoogleMapsTrustedTypesPolicy( + GoogleMapsTrustedTypePolicyOptions policyOptions, + ) { + const String policyName = 'google_maps_flutter_sanitize'; + _policy ??= _createPolicy(policyName, policyOptions); return _policy!; }