diff --git a/packages/google_sign_in/google_sign_in_web/CHANGELOG.md b/packages/google_sign_in/google_sign_in_web/CHANGELOG.md index b11c6249a5a..a5cbeea796a 100644 --- a/packages/google_sign_in/google_sign_in_web/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_web/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.12.3+1 + +* Updates `FlexHtmlElementView` (the widget backing `renderButton`) to not + rely on web engine knowledge (a platform view CSS selector) to operate. + ## 0.12.3 * Migrates to `package:web`. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/flexible_size_html_element_view_test.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/flexible_size_html_element_view_test.dart index 23ff99ac309..839c9abb5f7 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/flexible_size_html_element_view_test.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/flexible_size_html_element_view_test.dart @@ -22,12 +22,12 @@ void main() { widgetFactoryNumber++; }); - testWidgets('empty case, calls onPlatformViewCreated', + testWidgets('empty case, calls onElementCreated', (WidgetTester tester) async { - final Completer viewCreatedCompleter = Completer(); + final Completer viewCreatedCompleter = Completer(); - await pumpResizableWidget(tester, onPlatformViewCreated: (int id) { - viewCreatedCompleter.complete(id); + await pumpResizableWidget(tester, onElementCreated: (Object view) { + viewCreatedCompleter.complete(view); }); await tester.pumpAndSettle(); @@ -59,7 +59,7 @@ void main() { final Element element = await pumpResizableWidget( tester, - onPlatformViewCreated: injectElement(resizable), + onElementCreated: injectElement(resizable), ); await tester.pumpAndSettle(); @@ -80,7 +80,7 @@ void main() { final Element element = await pumpResizableWidget( tester, initialSize: initialSize, - onPlatformViewCreated: injectElement(resizable), + onElementCreated: injectElement(resizable), ); await tester.pumpAndSettle(); @@ -103,7 +103,7 @@ void main() { final Element element = await pumpResizableWidget( tester, initialSize: initialSize, - onPlatformViewCreated: injectElement(resizable), + onElementCreated: injectElement(resizable), ); await tester.pumpAndSettle(); @@ -134,12 +134,12 @@ void main() { /// Injects a ResizableFromJs widget into the `tester`. Future pumpResizableWidget( WidgetTester tester, { - void Function(int)? onPlatformViewCreated, + void Function(Object)? onElementCreated, Size? initialSize, }) async { await tester.pumpWidget(ResizableFromJs( instanceId: widgetFactoryNumber, - onPlatformViewCreated: onPlatformViewCreated, + onElementCreated: onElementCreated, initialSize: initialSize, )); // Needed for JS to have time to kick-off. @@ -155,7 +155,7 @@ Future pumpResizableWidget( class ResizableFromJs extends StatelessWidget { ResizableFromJs({ required this.instanceId, - this.onPlatformViewCreated, + this.onElementCreated, this.initialSize, super.key, }) { @@ -173,7 +173,7 @@ class ResizableFromJs extends StatelessWidget { } final int instanceId; - final void Function(int)? onPlatformViewCreated; + final void Function(Object)? onElementCreated; final Size? initialSize; @override @@ -184,7 +184,7 @@ class ResizableFromJs extends StatelessWidget { child: FlexHtmlElementView( viewType: 'resizable_from_js_$instanceId', key: Key('resizable_from_js_$instanceId'), - onPlatformViewCreated: onPlatformViewCreated, + onElementCreated: onElementCreated, initialSize: initialSize ?? const Size(640, 480), ), ), @@ -199,11 +199,9 @@ void resize(web.HTMLElement resizable, Size size) { 'width: ${size.width}px; height: ${size.height}px; background: #fabada'); } -/// Returns a function that can be used to inject `element` in `onPlatformViewCreated` callbacks. -void Function(int) injectElement(web.HTMLElement element) { - return (int viewId) { - final web.Element? root = - web.document.querySelector('#test_element_$viewId'); - root!.appendChild(element); +/// Returns an `onElementCreated` callback that injects [element]. +ElementCreatedCallback injectElement(web.HTMLElement element) { + return (Object root) { + (root as web.HTMLElement).appendChild(element); }; } diff --git a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart index 04128216853..d2cf1420da7 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart @@ -195,12 +195,8 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { if (snapshot.hasData) { return FlexHtmlElementView( viewType: 'gsi_login_button', - onPlatformViewCreated: (int viewId) { - final web.Element? element = - web.document.querySelector('#sign_in_button_$viewId'); - assert(element != null, - 'Cannot render GSI button. DOM is not ready!'); - _gisClient.renderButton(element!, config); + onElementCreated: (Object element) { + _gisClient.renderButton(element, config); }); } return const Text('Getting ready'); diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/flexible_size_html_element_view.dart b/packages/google_sign_in/google_sign_in_web/lib/src/flexible_size_html_element_view.dart index 56a251d4ed2..bd395a6adb9 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/flexible_size_html_element_view.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/flexible_size_html_element_view.dart @@ -2,9 +2,10 @@ // 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 'dart:ui_web' as ui_web; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:web/web.dart' as web; /// An HTMLElementView widget that resizes with its contents. @@ -13,15 +14,15 @@ class FlexHtmlElementView extends StatefulWidget { const FlexHtmlElementView({ super.key, required this.viewType, - this.onPlatformViewCreated, + this.onElementCreated, this.initialSize, }); /// See [HtmlElementView.viewType]. final String viewType; - /// See [HtmlElementView.onPlatformViewCreated]. - final PlatformViewCreatedCallback? onPlatformViewCreated; + /// See [HtmlElementView.fromTagName] `onElementCreated`. + final ElementCreatedCallback? onElementCreated; /// The initial Size for the widget, before it starts tracking its contents. final Size? initialSize; @@ -55,13 +56,15 @@ class _FlexHtmlElementView extends State { /// Update the state with the new `size`, if needed. void _doResize(Size size) { if (size != _lastReportedSize) { - final String log = [ - 'Resizing: ', - widget.viewType, - size.width, - size.height - ].join(' '); - web.console.debug(log.toJS); + if (kDebugMode) { + final String log = [ + 'Resizing: ', + widget.viewType, + size.width, + size.height + ].join(' '); + web.console.debug(log.toJS); + } setState(() { _lastReportedSize = size; }); @@ -105,12 +108,11 @@ class _FlexHtmlElementView extends State { } /// Registers a MutationObserver on the root element of the HtmlElementView. - void _registerListeners(web.Element? root) { - assert(root != null, 'DOM is not ready for the FlexHtmlElementView'); + void _registerListeners(web.Element root) { _mutationObserver = web.MutationObserver(_onMutationRecords.toJS); // Monitor the size of the child element, whenever it's created... _mutationObserver!.observe( - root!, + root, web.MutationObserverInit( childList: true, ), @@ -123,10 +125,13 @@ class _FlexHtmlElementView extends State { size: _lastReportedSize ?? widget.initialSize ?? const Size(1, 1), child: HtmlElementView( viewType: widget.viewType, - onPlatformViewCreated: (int viewId) async { - _registerListeners(_locatePlatformViewRoot(viewId)); - if (widget.onPlatformViewCreated != null) { - widget.onPlatformViewCreated!(viewId); + onPlatformViewCreated: (int viewId) { + final ElementCreatedCallback? callback = widget.onElementCreated; + final web.Element root = + ui_web.platformViewRegistry.getViewById(viewId) as web.Element; + _registerListeners(root); + if (callback != null) { + callback(root); } }), ); @@ -140,11 +145,3 @@ class _FlexHtmlElementView extends State { web.Element? _locateSizeProvider(web.NodeList elements) { return elements.item(0) as web.Element?; } - -/// Finds the root element of a platform view by its `viewId`. -/// -/// This element matches the one returned by the registered platform view factory. -web.Element? _locatePlatformViewRoot(int viewId) { - return web.document - .querySelector('flt-platform-view[slot\$="-$viewId"] :first-child'); -} diff --git a/packages/google_sign_in/google_sign_in_web/pubspec.yaml b/packages/google_sign_in/google_sign_in_web/pubspec.yaml index c0c7e16dd3a..90697ff63c1 100644 --- a/packages/google_sign_in/google_sign_in_web/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_web/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android, iOS and Web. repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22 -version: 0.12.3 +version: 0.12.3+1 environment: sdk: ">=3.2.0 <4.0.0"