Skip to content

Commit

Permalink
[web] Use TrustedTypes from pkg web. (flutter#6273)
Browse files Browse the repository at this point in the history
During the `package:web` migration, some packages that needed the TrustedTypes API defined those as custom JS-interop.

In `google_identity_services_web`, the names of the JS-interop types clashed with those from the incoming package:web, breaking the build.

In `google_maps_flutter_web`, the whole definition code is redundant now that the standard API is exposed through package:web.

Part of: flutter/flutter#117022
  • Loading branch information
ditman authored Mar 5, 2024
1 parent 4200177 commit 83b72ba
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 128 deletions.
4 changes: 4 additions & 0 deletions packages/google_identity_services_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.3.1+1

* Uses `TrustedTypes` from `web: ^0.5.1`.

## 0.3.1

* Updates web code to package `web: ^0.5.0`.
Expand Down
6 changes: 3 additions & 3 deletions packages/google_identity_services_web/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ description: An example for the google_identity_services_web package, OneTap.
publish_to: 'none'

environment:
flutter: ">=3.16.0"
sdk: ">=3.2.0 <4.0.0"
sdk: ^3.3.0
flutter: ">=3.19.0"

dependencies:
flutter:
sdk: flutter
google_identity_services_web:
path: ../
http: ">=0.13.0 <2.0.0"
web: ^0.5.0
web: ^0.5.1

dev_dependencies:
build_runner: ^2.1.10 # To extract README excerpts only.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,60 +17,20 @@ extension NullableTrustedTypesGetter on web.Window {
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API
@JS('trustedTypes')
external TrustedTypePolicyFactory? get nullableTrustedTypes;

/// Bindings to window.trustedTypes.
///
/// This will crash if accessed in a browser that 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 trustedTypes;
external web.TrustedTypePolicyFactory? get nullableTrustedTypes;
}

/// This extension allows setting a TrustedScriptURL as the src of a script element,
/// which currently only accepts a string.
/// Allows setting a TrustedScriptURL as the src of a script element.
extension TrustedTypeSrcAttribute on web.HTMLScriptElement {
@JS('src')
external set trustedSrc(TrustedScriptURL value);
}

// TODO(kevmoo): drop all of this once `pkg:web` publishes `0.5.1`.

/// Bindings to a JS TrustedScriptURL.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/TrustedScriptURL
extension type TrustedScriptURL._(JSObject _) implements JSObject {}

/// Bindings to a JS TrustedTypePolicyFactory.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory
extension type TrustedTypePolicyFactory._(JSObject _) implements JSObject {
///
external TrustedTypePolicy createPolicy(
String policyName, [
TrustedTypePolicyOptions policyOptions,
]);
external set trustedSrc(web.TrustedScriptURL value);
}

/// Bindings to a JS TrustedTypePolicy.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicy
extension type TrustedTypePolicy._(JSObject _) implements JSObject {
///
/// Allows creating a script URL only from a string, with no arguments.
extension CreateScriptUrlNoArgs on web.TrustedTypePolicy {
/// Allows calling `createScriptURL` with only the `input` argument.
@JS('createScriptURL')
external TrustedScriptURL createScriptURLNoArgs(
external web.TrustedScriptURL createScriptURLNoArgs(
String input,
);
}

/// Bindings to a JS TrustedTypePolicyOptions (anonymous).
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory/createPolicy#policyoptions
extension type TrustedTypePolicyOptions._(JSObject _) implements JSObject {
///
external factory TrustedTypePolicyOptions({
JSFunction createScriptURL,
});
}
6 changes: 3 additions & 3 deletions packages/google_identity_services_web/lib/src/js_loader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ Future<void> loadWebSdk({
onGoogleLibraryLoad = () => completer.complete();

// If TrustedTypes are available, prepare a trusted URL.
TrustedScriptURL? trustedUrl;
web.TrustedScriptURL? trustedUrl;
if (web.window.nullableTrustedTypes != null) {
web.console.debug(
'TrustedTypes available. Creating policy: $trustedTypePolicyName'.toJS,
);
try {
final TrustedTypePolicy policy = web.window.trustedTypes.createPolicy(
final web.TrustedTypePolicy policy = web.window.trustedTypes.createPolicy(
trustedTypePolicyName,
TrustedTypePolicyOptions(
web.TrustedTypePolicyOptions(
createScriptURL: ((JSString url) => _url).toJS,
));
trustedUrl = policy.createScriptURLNoArgs(_url);
Expand Down
4 changes: 2 additions & 2 deletions packages/google_identity_services_web/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ name: google_identity_services_web
description: A Dart JS-interop layer for Google Identity Services. Google's new sign-in SDK for Web that supports multiple types of credentials.
repository: https://github.com/flutter/packages/tree/main/packages/google_identity_services_web
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_identiy_services_web%22
version: 0.3.1
version: 0.3.1+1

environment:
sdk: ^3.3.0

dependencies:
meta: ^1.3.0
web: ^0.5.0
web: ^0.5.1

dev_dependencies:
path: ^1.8.1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.5.6+2

* Uses `TrustedTypes` from `web: ^0.5.1`.

## 0.5.6+1

* Fixes an issue where `dart:js_interop` object literal factories did not
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ final gmaps.LatLng _nullGmapsLatLng = gmaps.LatLng(0, 0);
final gmaps.LatLngBounds _nullGmapsLatLngBounds =
gmaps.LatLngBounds(_nullGmapsLatLng, _nullGmapsLatLng);

// The TrustedType Policy used by this plugin. Used to sanitize InfoWindow contents.
TrustedTypePolicy? _gmapsTrustedTypePolicy;

// Converts a [Color] into a valid CSS value #RRGGBB.
String _getCssColor(Color color) {
return '#${color.value.toRadixString(16).padLeft(8, '0').substring(2)}';
Expand Down Expand Up @@ -222,17 +225,17 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) {
// 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!.getGoogleMapsTrustedTypesPolicy(
GoogleMapsTrustedTypePolicyOptions(
createHTML: (String html, JSAny? arguments) {
return sanitizeHtml(html);
_gmapsTrustedTypePolicy ??= window.trustedTypes.createPolicy(
'google_maps_flutter_sanitize',
TrustedTypePolicyOptions(
createHTML: (String html) {
return sanitizeHtml(html).toJS;
}.toJS,
),
);

snippet.trustedInnerHTML =
trustedTypePolicy.createHTML(markerSnippet, null);
_gmapsTrustedTypePolicy!.createHTMLNoArgs(markerSnippet);
} else {
// `sanitizeHtml` is used to clean the (potential) user input from (potential)
// XSS attacks through the contents of the marker InfoWindow.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
library;

import 'dart:js_interop';

import 'package:web/web.dart' as web;

/// This extension gives [web.Window] a nullable getter to the `trustedTypes`
Expand All @@ -21,75 +20,22 @@ extension NullableTrustedTypesGetter on web.Window {
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API
@JS('trustedTypes')
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('TrustedTypePolicyFactory')
extension type GoogleMapsTrustedTypePolicyFactory._(JSObject _)
implements JSObject {
/// The `TrustedTypePolicy` for Google Maps Flutter.
static GoogleMapsTrustedTypePolicy? _policy;

@JS('createPolicy')
external GoogleMapsTrustedTypePolicy _createPolicy(
String policyName, [
GoogleMapsTrustedTypePolicyOptions policyOptions,
]);

/// Get a new [GoogleMapsTrustedTypePolicy].
///
/// If a policy already exists, it will be returned.
/// Otherwise, a new policy is created.
///
/// 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!;
}
external web.TrustedTypePolicyFactory? 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('TrustedTypePolicy')
extension type GoogleMapsTrustedTypePolicy._(JSObject _) implements JSObject {
/// Create a new `TrustedHTML` instance with the given [input] and [arguments].
external GoogleMapsTrustedHTML 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('TrustedTypePolicyOptions')
extension type GoogleMapsTrustedTypePolicyOptions._(JSObject _)
implements JSObject {
/// Create a new `TrustedTypePolicyOptions` instance.
external factory GoogleMapsTrustedTypePolicyOptions({
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('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);
external set trustedInnerHTML(web.TrustedHTML trustedHTML);
}

/// Allows creating a TrustedHTML object from a string, with no arguments.
extension CreateHTMLNoArgs on web.TrustedTypePolicy {
/// Allows calling `createHTML` with only the `input` argument.
@JS('createHTML')
external web.TrustedHTML createHTMLNoArgs(
String input,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.6+1
version: 0.5.6+2

environment:
sdk: ^3.3.0
Expand All @@ -26,7 +26,7 @@ dependencies:
google_maps_flutter_platform_interface: ^2.5.0
sanitize_html: ^2.0.0
stream_transform: ^2.0.0
web: ^0.5.0
web: ^0.5.1

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 83b72ba

Please sign in to comment.