Skip to content

Commit 1951a6a

Browse files
committed
set inner html to trusted html instance
1 parent 52baeca commit 1951a6a

File tree

2 files changed

+75
-49
lines changed

2 files changed

+75
-49
lines changed

packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,32 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) {
216216
}
217217
if (markerSnippet.isNotEmpty) {
218218
final HTMLElement snippet = createDivElement()
219-
..className = 'infowindow-snippet'
219+
..className = 'infowindow-snippet';
220+
221+
// Firefox and Safari don't support Trusted Types yet.
222+
// See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility
223+
if (window.nullableTrustedTypes != null) {
224+
final GoogleMapsTrustedTypePolicy trustedTypePolicy =
225+
window.nullableTrustedTypes!.getTrustedTypesPolicy(
226+
'google_maps_flutter_sanitize',
227+
GoogleMapsTrustedTypePolicyOptions(
228+
createHTML: (String html, JSAny? arguments) {
229+
return sanitizeHtml(html);
230+
}.toJS,
231+
),
232+
);
233+
234+
snippet.trustedInnerHTML =
235+
trustedTypePolicy.createHTML(markerSnippet, null);
236+
} else {
220237
// `sanitizeHtml` is used to clean the (potential) user input from (potential)
221238
// XSS attacks through the contents of the marker InfoWindow.
222239
// See: https://pub.dev/documentation/sanitize_html/latest/sanitize_html/sanitizeHtml.html
223240
// See: b/159137885, b/159598165
224241
// ignore: unsafe_html
225-
..innerHTML = _sanitizeHtml(markerSnippet);
242+
snippet.innerHTML = sanitizeHtml(markerSnippet);
243+
}
244+
226245
container.appendChild(snippet);
227246
}
228247

@@ -528,29 +547,3 @@ gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) {
528547

529548
return projection.fromPointToLatLng!(point)!;
530549
}
531-
532-
String _sanitizeHtml(String htmlString) {
533-
TrustedTypePolicy? trustedTypePolicy;
534-
535-
try {
536-
// Firefox and Safari don't support Trusted Types yet.
537-
// See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility
538-
trustedTypePolicy =
539-
WindowWithTrustedTypes(window).trustedTypesNullable?.createPolicy(
540-
'google_maps_flutter_sanitize',
541-
TrustedTypePolicyOptions(
542-
createHTML: (String html, JSAny? arguments) {
543-
return sanitizeHtml(html);
544-
}.toJS,
545-
),
546-
);
547-
} catch (_) {
548-
// Fallback to not using the trusted types policy.
549-
}
550-
551-
if (trustedTypePolicy == null) {
552-
return sanitizeHtml(htmlString);
553-
}
554-
555-
return trustedTypePolicy.createHTML(htmlString, null).toString();
556-
}

packages/google_maps_flutter/google_maps_flutter_web/lib/src/dom_window_extension.dart

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,62 @@
44

55
import 'dart:js_interop';
66

7-
import 'package:web/web.dart';
7+
import 'package:web/web.dart' as web;
88

9-
/// This extension type exists to handle unsupported features by certain browsers.
10-
@JS()
11-
extension type WindowWithTrustedTypes(Window _) implements JSObject {
12-
/// Get the `trustedTypes` object from the window, if it is supported.
9+
/// This extension gives [web.Window] a nullable getter to the `trustedTypes`
10+
/// property, which is used to check for feature support.
11+
extension NullableTrustedTypesGetter on web.Window {
12+
/// (Nullable) Bindings to window.trustedTypes.
13+
///
14+
/// This may be null if the browser doesn't support the Trusted Types API.
15+
///
16+
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API
1317
@JS('trustedTypes')
14-
external TrustedTypePolicyFactory? get trustedTypesNullable;
18+
external GoogleMapsTrustedTypePolicyFactory? get nullableTrustedTypes;
1519
}
1620

1721
// TODO(ditman): remove this extension type when we depend on package:web 0.5.1
1822
/// This extension exists as a stop gap until `package:web 0.5.1` is released.
1923
/// That version provides the `TrustedTypes` API.
20-
@JS()
21-
extension type TrustedTypePolicyFactory._(JSObject _) implements JSObject {
22-
/// Create a new `TrustedTypePolicy` instance
23-
/// with the given [policyName] and [policyOptions].
24-
external TrustedTypePolicy createPolicy(
24+
@JS('TrustedTypePolicyFactory')
25+
extension type GoogleMapsTrustedTypePolicyFactory._(JSObject _)
26+
implements JSObject {
27+
/// The `TrustedTypePolicy` for Google Maps Flutter.
28+
static GoogleMapsTrustedTypePolicy? _policy;
29+
30+
@JS('createPolicy')
31+
external GoogleMapsTrustedTypePolicy _createPolicy(
2532
String policyName, [
26-
TrustedTypePolicyOptions policyOptions,
33+
GoogleMapsTrustedTypePolicyOptions policyOptions,
2734
]);
35+
36+
/// Get a new [GoogleMapsTrustedTypePolicy].
37+
///
38+
/// If a policy already exists, it will be returned.
39+
/// Otherwise, a new policy is created.
40+
GoogleMapsTrustedTypePolicy getTrustedTypesPolicy(
41+
String policyName, [
42+
GoogleMapsTrustedTypePolicyOptions? policyOptions,
43+
]) {
44+
if (_policy == null) {
45+
if (policyOptions != null) {
46+
_policy = _createPolicy(policyName, policyOptions);
47+
} else {
48+
_policy = _createPolicy(policyName);
49+
}
50+
}
51+
52+
return _policy!;
53+
}
2854
}
2955

3056
// TODO(ditman): remove this extension type when we depend on package:web 0.5.1
3157
/// This extension exists as a stop gap until `package:web 0.5.1` is released.
3258
/// That version provides the `TrustedTypes` API.
33-
extension type TrustedTypePolicy._(JSObject _) implements JSObject {
59+
@JS('TrustedTypePolicy')
60+
extension type GoogleMapsTrustedTypePolicy._(JSObject _) implements JSObject {
3461
/// Create a new `TrustedHTML` instance with the given [input] and [arguments].
35-
external TrustedHTML createHTML(
62+
external GoogleMapsTrustedHTML createHTML(
3663
String input,
3764
JSAny? arguments,
3865
);
@@ -41,19 +68,25 @@ extension type TrustedTypePolicy._(JSObject _) implements JSObject {
4168
// TODO(ditman): remove this extension type when we depend on package:web 0.5.1
4269
/// This extension exists as a stop gap until `package:web 0.5.1` is released.
4370
/// That version provides the `TrustedTypes` API.
44-
@JS()
45-
extension type TrustedTypePolicyOptions._(JSObject _) implements JSObject {
71+
@JS('TrustedTypePolicyOptions')
72+
extension type GoogleMapsTrustedTypePolicyOptions._(JSObject _)
73+
implements JSObject {
4674
/// Create a new `TrustedTypePolicyOptions` instance.
47-
external factory TrustedTypePolicyOptions({
75+
external factory GoogleMapsTrustedTypePolicyOptions({
4876
JSFunction createHTML,
4977
});
5078
}
5179

5280
// TODO(ditman): remove this extension type when we depend on package:web 0.5.1
5381
/// This extension exists as a stop gap until `package:web 0.5.1` is released.
5482
/// That version provides the `TrustedTypes` API.
55-
@JS()
56-
extension type TrustedHTML._(JSObject _) implements JSObject {
57-
// This type inherits `toString()` from `Object`.
58-
// See also: https://developer.mozilla.org/en-US/docs/Web/API/TrustedHTML/toString
83+
@JS('TrustedHTML')
84+
extension type GoogleMapsTrustedHTML._(JSObject _) implements JSObject {}
85+
86+
/// This extension provides a setter for the [web.HTMLElement] `innerHTML` property,
87+
/// that accepts trusted HTML only.
88+
extension TrustedInnerHTML on web.HTMLElement {
89+
/// Set the inner HTML of this element to the given [trustedHTML].
90+
@JS('innerHTML')
91+
external set trustedInnerHTML(GoogleMapsTrustedHTML trustedHTML);
5992
}

0 commit comments

Comments
 (0)