diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index e0b43fca37cf5..0d5195996786a 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -515,7 +515,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/canvaskit/viewport_metrics.dart FILE: ../../../flutter/lib/web_ui/lib/src/engine/clipboard.dart FILE: ../../../flutter/lib/web_ui/lib/src/engine/color_filter.dart FILE: ../../../flutter/lib/web_ui/lib/src/engine/configuration.dart -FILE: ../../../flutter/lib/web_ui/lib/src/engine/dom_renderer.dart +FILE: ../../../flutter/lib/web_ui/lib/src/engine/embedder.dart FILE: ../../../flutter/lib/web_ui/lib/src/engine/engine_canvas.dart FILE: ../../../flutter/lib/web_ui/lib/src/engine/font_change_util.dart FILE: ../../../flutter/lib/web_ui/lib/src/engine/frame_reference.dart @@ -638,7 +638,6 @@ FILE: ../../../flutter/lib/web_ui/lib/src/ui/path_metrics.dart FILE: ../../../flutter/lib/web_ui/lib/src/ui/platform_dispatcher.dart FILE: ../../../flutter/lib/web_ui/lib/src/ui/pointer.dart FILE: ../../../flutter/lib/web_ui/lib/src/ui/semantics.dart -FILE: ../../../flutter/lib/web_ui/lib/src/ui/test_embedding.dart FILE: ../../../flutter/lib/web_ui/lib/src/ui/text.dart FILE: ../../../flutter/lib/web_ui/lib/src/ui/tile_mode.dart FILE: ../../../flutter/lib/web_ui/lib/src/ui/window.dart diff --git a/lib/web_ui/lib/src/engine.dart b/lib/web_ui/lib/src/engine.dart index 862d155153e84..5148cb4b0c66c 100644 --- a/lib/web_ui/lib/src/engine.dart +++ b/lib/web_ui/lib/src/engine.dart @@ -41,7 +41,7 @@ import '../ui.dart' as ui; // ignore: unused_import import 'engine/configuration.dart'; -import 'engine/dom_renderer.dart'; +import 'engine/embedder.dart'; import 'engine/keyboard.dart'; import 'engine/mouse_cursor.dart'; import 'engine/navigation/js_url_strategy.dart'; @@ -130,7 +130,7 @@ export 'engine/color_filter.dart'; export 'engine/configuration.dart'; -export 'engine/dom_renderer.dart'; +export 'engine/embedder.dart'; export 'engine/engine_canvas.dart'; @@ -413,8 +413,8 @@ void initializeEngine() { _engineInitialized = true; - // Initialize the DomRenderer before initializing framework bindings. - ensureDomRendererInitialized(); + // Initialize the FlutterViewEmbedder before initializing framework bindings. + ensureFlutterViewEmbedderInitialized(); WebExperiments.ensureInitialized(); diff --git a/lib/web_ui/lib/src/engine/canvas_pool.dart b/lib/web_ui/lib/src/engine/canvas_pool.dart index adf606367240d..02bf5507ad67d 100644 --- a/lib/web_ui/lib/src/engine/canvas_pool.dart +++ b/lib/web_ui/lib/src/engine/canvas_pool.dart @@ -11,7 +11,6 @@ import 'package:meta/meta.dart'; import 'package:ui/ui.dart' as ui; import 'browser_detection.dart'; -import 'dom_renderer.dart'; import 'engine_canvas.dart'; import 'html/bitmap_canvas.dart'; import 'html/painting.dart'; @@ -751,7 +750,7 @@ class CanvasPool extends _SaveStackTracking { rect.center.dx - shaderBounds.left; final double cy = shaderBounds == null ? rect.center.dy : rect.center.dy - shaderBounds.top; - DomRenderer.ellipse(context, cx, cy, rect.width / 2, + drawEllipse(context, cx, cy, rect.width / 2, rect.height / 2, 0, 0, 2.0 * math.pi, false); contextHandle.paint(style); } @@ -762,7 +761,7 @@ class CanvasPool extends _SaveStackTracking { final ui.Rect? shaderBounds = contextHandle._shaderBounds; final double cx = shaderBounds == null ? c.dx : c.dx - shaderBounds.left; final double cy = shaderBounds == null ? c.dy : c.dy - shaderBounds.top; - DomRenderer.ellipse(context, cx, cy, radius, radius, 0, 0, 2.0 * math.pi, false); + drawEllipse(context, cx, cy, radius, radius, 0, 0, 2.0 * math.pi, false); contextHandle.paint(style); } diff --git a/lib/web_ui/lib/src/engine/canvaskit/initialization.dart b/lib/web_ui/lib/src/engine/canvaskit/initialization.dart index 704896a6e062f..87b77f6d9d154 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/initialization.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/initialization.dart @@ -13,7 +13,7 @@ import 'package:js/js.dart'; import '../../engine.dart' show kProfileMode; import '../browser_detection.dart'; import '../configuration.dart'; -import '../dom_renderer.dart'; +import '../embedder.dart'; import 'canvaskit_api.dart'; import 'fonts.dart'; @@ -78,7 +78,7 @@ Future initializeCanvasKit({String? canvasKitBase}) { /// Add a Skia scene host. skiaSceneHost = html.Element.tag('flt-scene'); - domRenderer.renderScene(skiaSceneHost); + flutterViewEmbedder.renderScene(skiaSceneHost); return canvasKitCompleter.future; } diff --git a/lib/web_ui/lib/src/engine/dom_renderer.dart b/lib/web_ui/lib/src/engine/embedder.dart similarity index 80% rename from lib/web_ui/lib/src/engine/dom_renderer.dart rename to lib/web_ui/lib/src/engine/embedder.dart index 2b01a2408c42b..fe22f42982a89 100644 --- a/lib/web_ui/lib/src/engine/dom_renderer.dart +++ b/lib/web_ui/lib/src/engine/embedder.dart @@ -21,26 +21,29 @@ import 'text_editing/text_editing.dart'; import 'util.dart'; import 'window.dart'; -class DomRenderer { - DomRenderer() { - if (assertionsEnabled) { - _debugFrameStatistics = DebugDomRendererFrameStatistics(); - } - +/// Controls the placement and lifecycle of a Flutter view on the web page. +/// +/// Manages several top-level elements that host Flutter-generated content, +/// including: +/// +/// - [glassPaneElement], the root element of a Flutter view. +/// - [glassPaneShadow], the shadow root used to isolate Flutter-rendered +/// content from the surrounding page content, including from the platform +/// views. +/// - [sceneElement], the element that hosts Flutter layers and pictures, and +/// projects platform views. +/// - [sceneHostElement], the anchor that provides a stable location in the DOM +/// tree for the [sceneElement]. +/// - [semanticsHostElement], hosts the ARIA-annotated semantics tree. +class FlutterViewEmbedder { + FlutterViewEmbedder() { reset(); - assert(() { _setupHotRestart(); return true; }()); } - static const int vibrateLongPress = 50; - static const int vibrateLightImpact = 10; - static const int vibrateMediumImpact = 20; - static const int vibrateHeavyImpact = 30; - static const int vibrateSelectionClick = 10; - // The tag name for the root view of the flutter app (glass-pane) static const String _glassPaneTagName = 'flt-glass-pane'; @@ -175,52 +178,6 @@ class DomRenderer { final html.Element rootElement = html.document.body!; - html.Element createElement(String tagName, {html.Element? parent}) { - final html.Element element = html.document.createElement(tagName); - parent?.append(element); - return element; - } - - void appendText(html.Element parent, String text) { - parent.appendText(text); - } - - static void setElementStyle( - html.Element element, String name, String? value) { - if (value == null) { - element.style.removeProperty(name); - } else { - element.style.setProperty(name, value); - } - } - - static void setClipPath(html.Element element, String? value) { - if (browserEngine == BrowserEngine.webkit) { - if (value == null) { - element.style.removeProperty('-webkit-clip-path'); - } else { - element.style.setProperty('-webkit-clip-path', value); - } - } - if (value == null) { - element.style.removeProperty('clip-path'); - } else { - element.style.setProperty('clip-path', value); - } - } - - void setThemeColor(ui.Color color) { - html.MetaElement? theme = - html.document.querySelector('#flutterweb-theme') as html.MetaElement?; - if (theme == null) { - theme = html.MetaElement() - ..id = 'flutterweb-theme' - ..name = 'theme-color'; - html.document.head!.append(theme); - } - theme.content = colorToCssString(color)!; - } - static const String defaultFontStyle = 'normal'; static const String defaultFontWeight = 'normal'; static const double defaultFontSize = 14; @@ -313,7 +270,7 @@ class DomRenderer { // IMPORTANT: the glass pane element must come after the scene element in the DOM node list so // it can intercept input events. _glassPaneElement?.remove(); - final html.Element glassPaneElement = createElement(_glassPaneTagName); + final html.Element glassPaneElement = html.document.createElement(_glassPaneTagName); _glassPaneElement = glassPaneElement; glassPaneElement.style ..position = 'absolute' @@ -331,11 +288,11 @@ class DomRenderer { _glassPaneShadow = glassPaneElementHostNode; // Don't allow the scene to receive pointer events. - _sceneHostElement = createElement('flt-scene-host') + _sceneHostElement = html.document.createElement('flt-scene-host') ..style.pointerEvents = 'none'; final html.Element semanticsHostElement = - createElement('flt-semantics-host'); + html.document.createElement('flt-semantics-host'); semanticsHostElement.style ..position = 'absolute' ..transformOrigin = '0 0 0'; @@ -456,41 +413,6 @@ class DomRenderer { } } - /// Removes all children of a DOM node. - void removeAllChildren(html.Node node) { - while (node.lastChild != null) { - node.lastChild!.remove(); - } - } - - static bool? _ellipseFeatureDetected; - - /// Draws CanvasElement ellipse with fallback. - static void ellipse( - html.CanvasRenderingContext2D context, - double centerX, - double centerY, - double radiusX, - double radiusY, - double rotation, - double startAngle, - double endAngle, - bool antiClockwise) { - // ignore: implicit_dynamic_function - _ellipseFeatureDetected ??= js_util.getProperty(context, 'ellipse') != null; - if (_ellipseFeatureDetected!) { - context.ellipse(centerX, centerY, radiusX, radiusY, rotation, startAngle, - endAngle, antiClockwise); - } else { - context.save(); - context.translate(centerX, centerY); - context.rotate(rotation); - context.scale(radiusX, radiusY); - context.arc(0, 0, 1, startAngle, endAngle, antiClockwise); - context.restore(); - } - } - static const String orientationLockTypeAny = 'any'; static const String orientationLockTypeNatural = 'natural'; static const String orientationLockTypeLandscape = 'landscape'; @@ -596,36 +518,14 @@ class DomRenderer { /// Removes a global resource element. void removeResource(html.Element? element) { - element?.remove(); - } - - /// Provides haptic feedback. - void vibrate(int durationMs) { - final html.Navigator navigator = html.window.navigator; - if (js_util.hasProperty(navigator, 'vibrate')) { - // ignore: implicit_dynamic_function - js_util.callMethod(navigator, 'vibrate', [durationMs]); + if (element == null) { + return; } + assert(element.parent == _resourcesHost); + element.remove(); } String get currentHtml => _rootApplicationElement?.outerHtml ?? ''; - - DebugDomRendererFrameStatistics? _debugFrameStatistics; - - DebugDomRendererFrameStatistics? debugFlushFrameStatistics() { - if (!assertionsEnabled) { - throw Exception('This code should not be reachable in production.'); - } - final DebugDomRendererFrameStatistics? current = _debugFrameStatistics; - _debugFrameStatistics = DebugDomRendererFrameStatistics(); - return current; - } - - void debugRulerCacheHit() => _debugFrameStatistics!.paragraphRulerCacheHits++; - void debugRulerCacheMiss() => - _debugFrameStatistics!.paragraphRulerCacheMisses++; - void debugRichTextLayout() => _debugFrameStatistics!.richTextLayouts++; - void debugPlainTextLayout() => _debugFrameStatistics!.plainTextLayouts++; } // Applies the required global CSS to an incoming [html.CssStyleSheet] `sheet`. @@ -633,7 +533,7 @@ void applyGlobalCssRulesToSheet( html.CssStyleSheet sheet, { required BrowserEngine browserEngine, required bool hasAutofillOverlay, - String glassPaneTagName = DomRenderer._glassPaneTagName, + String glassPaneTagName = FlutterViewEmbedder._glassPaneTagName, }) { final bool isWebKit = browserEngine == BrowserEngine.webkit; final bool isFirefox = browserEngine == BrowserEngine.firefox; @@ -752,48 +652,9 @@ void applyGlobalCssRulesToSheet( } } -/// Miscellaneous statistics collecting during a single frame's execution. -/// -/// This is useful when profiling the app. This class should only be used when -/// assertions are enabled and therefore is not suitable for collecting any -/// time measurements. It is mostly useful for counting certain events. -class DebugDomRendererFrameStatistics { - /// The number of times we reused a previously initialized paragraph ruler to - /// measure a paragraph of text. - int paragraphRulerCacheHits = 0; - - /// The number of times we had to create a new paragraph ruler to measure a - /// paragraph of text. - int paragraphRulerCacheMisses = 0; - - /// The number of times we used a paragraph ruler to measure a paragraph of - /// text. - int get totalParagraphRulerAccesses => - paragraphRulerCacheHits + paragraphRulerCacheMisses; - - /// The number of times a paragraph of rich text was laid out this frame. - int richTextLayouts = 0; - - /// The number of times a paragraph of plain text was laid out this frame. - int plainTextLayouts = 0; - - @override - String toString() { - return ''' -Frame statistics: - Paragraph ruler cache hits: $paragraphRulerCacheHits - Paragraph ruler cache misses: $paragraphRulerCacheMisses - Paragraph ruler accesses: $totalParagraphRulerAccesses - Rich text layouts: $richTextLayouts - Plain text layouts: $plainTextLayouts -''' - .trim(); - } -} - -/// Singleton DOM renderer. -DomRenderer get domRenderer => ensureDomRendererInitialized(); +/// The embedder singleton. +FlutterViewEmbedder get flutterViewEmbedder => ensureFlutterViewEmbedderInitialized(); -/// Initializes the [DomRenderer], if it's not already initialized. -DomRenderer ensureDomRendererInitialized() => _domRenderer ??= DomRenderer(); -DomRenderer? _domRenderer; +/// Initializes the [FlutterViewEmbedder], if it's not already initialized. +FlutterViewEmbedder ensureFlutterViewEmbedderInitialized() => _flutterViewEmbedder ??= FlutterViewEmbedder(); +FlutterViewEmbedder? _flutterViewEmbedder; diff --git a/lib/web_ui/lib/src/engine/host_node.dart b/lib/web_ui/lib/src/engine/host_node.dart index cb5a1c34b149a..5dead990ceda5 100644 --- a/lib/web_ui/lib/src/engine/host_node.dart +++ b/lib/web_ui/lib/src/engine/host_node.dart @@ -5,7 +5,7 @@ import 'dart:html' as html; import 'browser_detection.dart'; -import 'dom_renderer.dart'; +import 'embedder.dart'; import 'text_editing/text_editing.dart'; /// The interface required to host a flutter app in the DOM, and its tests. diff --git a/lib/web_ui/lib/src/engine/html/backdrop_filter.dart b/lib/web_ui/lib/src/engine/html/backdrop_filter.dart index 4758ad33e2d5b..73e7d71ef1095 100644 --- a/lib/web_ui/lib/src/engine/html/backdrop_filter.dart +++ b/lib/web_ui/lib/src/engine/html/backdrop_filter.dart @@ -7,7 +7,6 @@ import 'dart:html' as html; import 'package:ui/ui.dart' as ui; import '../browser_detection.dart'; -import '../dom_renderer.dart'; import '../util.dart'; import '../vector_math.dart'; import 'shaders/shader.dart'; @@ -122,10 +121,10 @@ class PersistedBackdropFilter extends PersistedContainerSurface // Gaussian blur with standard deviation (normal distribution), // the blur will fall within 2 * sigma pixels. if (browserEngine == BrowserEngine.webkit) { - DomRenderer.setElementStyle(_filterElement!, '-webkit-backdrop-filter', + setElementStyle(_filterElement!, '-webkit-backdrop-filter', filter.filterAttribute); } - DomRenderer.setElementStyle(_filterElement!, 'backdrop-filter', filter.filterAttribute); + setElementStyle(_filterElement!, 'backdrop-filter', filter.filterAttribute); } } diff --git a/lib/web_ui/lib/src/engine/html/clip.dart b/lib/web_ui/lib/src/engine/html/clip.dart index 29cc4a3443b6d..bd63ab4d0376e 100644 --- a/lib/web_ui/lib/src/engine/html/clip.dart +++ b/lib/web_ui/lib/src/engine/html/clip.dart @@ -7,7 +7,6 @@ import 'dart:svg' as svg; import 'package:ui/ui.dart' as ui; -import '../dom_renderer.dart'; import '../shadow.dart'; import '../util.dart'; import 'dom_canvas.dart'; @@ -363,7 +362,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface _clipElement = svgClipPath; rootElement!.append(_clipElement!); if (elevation == 0.0) { - DomRenderer.setClipPath(rootElement!, createSvgClipUrl()); + setClipPath(rootElement!, createSvgClipUrl()); final html.CssStyleDeclaration rootElementStyle = rootElement!.style; rootElementStyle ..overflow = '' @@ -378,7 +377,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface return; } - DomRenderer.setClipPath(childContainer!, createSvgClipUrl()); + setClipPath(childContainer!, createSvgClipUrl()); final html.CssStyleDeclaration rootElementStyle = rootElement!.style; rootElementStyle ..overflow = '' @@ -438,7 +437,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface _svgElement = null; // Reset style on prior element since we may have switched between // rect/rrect and arbitrary path. - DomRenderer.setClipPath(rootElement!, ''); + setClipPath(rootElement!, ''); _applyShape(); } else { // Reuse clipElement from prior surface. @@ -518,7 +517,7 @@ svg.SvgSvgElement createSvgClipDef(html.HtmlElement element, ui.Path clipPath) { final ui.Rect pathBounds = clipPath.getBounds(); final svg.SvgSvgElement svgClipPath = pathToSvgClipPath(clipPath, scaleX: 1.0 / pathBounds.right, scaleY: 1.0 / pathBounds.bottom); - DomRenderer.setClipPath(element, createSvgClipUrl()); + setClipPath(element, createSvgClipUrl()); // We need to set width and height for the clipElement to cover the // bounds of the path since browsers such as Safari and Edge // seem to incorrectly intersect the element bounding rect with diff --git a/lib/web_ui/lib/src/engine/html/color_filter.dart b/lib/web_ui/lib/src/engine/html/color_filter.dart index 4e9cfe70c32bd..d64c108072ff3 100644 --- a/lib/web_ui/lib/src/engine/html/color_filter.dart +++ b/lib/web_ui/lib/src/engine/html/color_filter.dart @@ -10,7 +10,7 @@ import 'package:ui/ui.dart' as ui; import '../browser_detection.dart'; import '../canvaskit/color_filter.dart'; import '../color_filter.dart'; -import '../dom_renderer.dart'; +import '../embedder.dart'; import '../util.dart'; import 'bitmap_canvas.dart'; import 'path_to_svg_clip.dart'; @@ -53,7 +53,7 @@ class PersistedColorFilter extends PersistedContainerSurface @override void discard() { super.discard(); - domRenderer.removeResource(_filterElement); + flutterViewEmbedder.removeResource(_filterElement); // Do not detach the child container from the root. It is permanently // attached. The elements are reused together and are detached from the DOM // together. @@ -72,7 +72,7 @@ class PersistedColorFilter extends PersistedContainerSurface @override void apply() { - domRenderer.removeResource(_filterElement); + flutterViewEmbedder.removeResource(_filterElement); _filterElement = null; final EngineColorFilter? engineValue = filter as EngineColorFilter?; if (engineValue == null) { @@ -138,7 +138,7 @@ class PersistedColorFilter extends PersistedContainerSurface // Use SVG filter for blend mode. final SvgFilter svgFilter = svgFilterFromBlendMode(filterColor, colorFilterBlendMode); _filterElement = svgFilter.element; - domRenderer.addResource(_filterElement!); + flutterViewEmbedder.addResource(_filterElement!); style.filter = 'url(#${svgFilter.id})'; if (colorFilterBlendMode == ui.BlendMode.saturation || colorFilterBlendMode == ui.BlendMode.multiply || @@ -150,7 +150,7 @@ class PersistedColorFilter extends PersistedContainerSurface void _applyMatrixColorFilter(CkMatrixColorFilter colorFilter) { final SvgFilter svgFilter = svgFilterFromColorMatrix(colorFilter.matrix); _filterElement = svgFilter.element; - domRenderer.addResource(_filterElement!); + flutterViewEmbedder.addResource(_filterElement!); childContainer!.style.filter = 'url(#${svgFilter.id})'; } diff --git a/lib/web_ui/lib/src/engine/html/dom_canvas.dart b/lib/web_ui/lib/src/engine/html/dom_canvas.dart index adf5af768d084..3c769a9ed3a75 100644 --- a/lib/web_ui/lib/src/engine/html/dom_canvas.dart +++ b/lib/web_ui/lib/src/engine/html/dom_canvas.dart @@ -10,7 +10,6 @@ import 'dart:typed_data'; import 'package:ui/ui.dart' as ui; import '../browser_detection.dart'; -import '../dom_renderer.dart'; import '../engine_canvas.dart'; import '../html_image_codec.dart'; import '../text/paragraph.dart'; @@ -32,7 +31,7 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking { @override void clear() { super.clear(); - domRenderer.removeAllChildren(rootElement); + removeAllChildren(rootElement); } @override @@ -165,7 +164,7 @@ html.HtmlElement buildDrawRectElement( ui.Rect rect, SurfacePaintData paint, String tagName, Matrix4 transform) { assert(paint.shader == null); final html.HtmlElement rectangle = - domRenderer.createElement(tagName) as html.HtmlElement; + html.document.createElement(tagName) as html.HtmlElement; assert(() { rectangle.setAttribute('flt-rect', '$rect'); rectangle.setAttribute('flt-paint', '$paint'); diff --git a/lib/web_ui/lib/src/engine/html/offset.dart b/lib/web_ui/lib/src/engine/html/offset.dart index ebe53c0c4c8e4..a23b5124a9914 100644 --- a/lib/web_ui/lib/src/engine/html/offset.dart +++ b/lib/web_ui/lib/src/engine/html/offset.dart @@ -6,7 +6,7 @@ import 'dart:html' as html; import 'package:ui/ui.dart' as ui; -import '../dom_renderer.dart'; +import '../util.dart'; import '../vector_math.dart'; import 'surface.dart'; @@ -42,8 +42,8 @@ class PersistedOffset extends PersistedContainerSurface @override html.Element createElement() { final html.Element element = html.document.createElement('flt-offset'); - DomRenderer.setElementStyle(element, 'position', 'absolute'); - DomRenderer.setElementStyle(element, 'transform-origin', '0 0 0'); + setElementStyle(element, 'position', 'absolute'); + setElementStyle(element, 'transform-origin', '0 0 0'); return element; } diff --git a/lib/web_ui/lib/src/engine/html/opacity.dart b/lib/web_ui/lib/src/engine/html/opacity.dart index b9020f1a3772e..4348fc33a49dc 100644 --- a/lib/web_ui/lib/src/engine/html/opacity.dart +++ b/lib/web_ui/lib/src/engine/html/opacity.dart @@ -6,7 +6,7 @@ import 'dart:html' as html; import 'package:ui/ui.dart' as ui; -import '../dom_renderer.dart'; +import '../util.dart'; import '../vector_math.dart'; import 'surface.dart'; @@ -43,16 +43,16 @@ class PersistedOpacity extends PersistedContainerSurface @override html.Element createElement() { - final html.Element element = domRenderer.createElement('flt-opacity'); - DomRenderer.setElementStyle(element, 'position', 'absolute'); - DomRenderer.setElementStyle(element, 'transform-origin', '0 0 0'); + final html.Element element = html.document.createElement('flt-opacity'); + setElementStyle(element, 'position', 'absolute'); + setElementStyle(element, 'transform-origin', '0 0 0'); return element; } @override void apply() { final html.Element element = rootElement!; - DomRenderer.setElementStyle(element, 'opacity', '${alpha / 255}'); + setElementStyle(element, 'opacity', '${alpha / 255}'); element.style.transform = 'translate(${offset.dx}px, ${offset.dy}px)'; } diff --git a/lib/web_ui/lib/src/engine/html/picture.dart b/lib/web_ui/lib/src/engine/html/picture.dart index 1b73f914446c4..b105c998e81ac 100644 --- a/lib/web_ui/lib/src/engine/html/picture.dart +++ b/lib/web_ui/lib/src/engine/html/picture.dart @@ -8,7 +8,6 @@ import 'dart:typed_data'; import 'package:ui/ui.dart' as ui; -import '../dom_renderer.dart'; import '../engine_canvas.dart'; import '../frame_reference.dart'; import '../picture.dart'; @@ -350,7 +349,7 @@ class PersistedPicture extends PersistedLeafSurface { oldSurface._canvas = null; } if (rootElement != null) { - domRenderer.removeAllChildren(rootElement!); + removeAllChildren(rootElement!); } if (_canvas != null && _canvas != oldCanvas) { _recycleCanvas(_canvas); @@ -432,7 +431,7 @@ class PersistedPicture extends PersistedLeafSurface { _recycleCanvas(_canvas); final DomCanvas domCanvas = DomCanvas(rootElement!); _canvas = domCanvas; - domRenderer.removeAllChildren(rootElement!); + removeAllChildren(rootElement!); picture.recordingCanvas!.apply(domCanvas, _optimalLocalCullRect!); } @@ -473,7 +472,7 @@ class PersistedPicture extends PersistedLeafSurface { surfaceStatsFor(this).paintPixelCount += bitmapCanvas.bitmapPixelCount; } - domRenderer.removeAllChildren(rootElement!); + removeAllChildren(rootElement!); rootElement!.append(bitmapCanvas.rootElement); bitmapCanvas.clear(); picture.recordingCanvas!.apply(bitmapCanvas, _optimalLocalCullRect!); diff --git a/lib/web_ui/lib/src/engine/html/shader_mask.dart b/lib/web_ui/lib/src/engine/html/shader_mask.dart index 9168a30caab39..7f27cd7b22fa6 100644 --- a/lib/web_ui/lib/src/engine/html/shader_mask.dart +++ b/lib/web_ui/lib/src/engine/html/shader_mask.dart @@ -7,7 +7,7 @@ import 'dart:html' as html; import 'package:ui/ui.dart' as ui; import '../browser_detection.dart'; -import '../dom_renderer.dart'; +import '../embedder.dart'; import 'bitmap_canvas.dart'; import 'color_filter.dart'; import 'shaders/shader.dart'; @@ -57,7 +57,7 @@ class PersistedShaderMask extends PersistedContainerSurface @override void discard() { super.discard(); - domRenderer.removeResource(_shaderElement); + flutterViewEmbedder.removeResource(_shaderElement); // Do not detach the child container from the root. It is permanently // attached. The elements are reused together and are detached from the DOM // together. @@ -83,7 +83,7 @@ class PersistedShaderMask extends PersistedContainerSurface @override void apply() { - domRenderer.removeResource(_shaderElement); + flutterViewEmbedder.removeResource(_shaderElement); _shaderElement = null; if (shader is ui.Gradient) { rootElement!.style @@ -162,7 +162,7 @@ class PersistedShaderMask extends PersistedContainerSurface } else { rootElement!.style.filter = 'url(#${svgFilter.id})'; } - domRenderer.addResource(_shaderElement!); + flutterViewEmbedder.addResource(_shaderElement!); } } diff --git a/lib/web_ui/lib/src/engine/html/transform.dart b/lib/web_ui/lib/src/engine/html/transform.dart index 44135a28cae61..d3e1f8f53a2be 100644 --- a/lib/web_ui/lib/src/engine/html/transform.dart +++ b/lib/web_ui/lib/src/engine/html/transform.dart @@ -7,7 +7,6 @@ import 'dart:typed_data'; import 'package:ui/ui.dart' as ui; -import '../dom_renderer.dart'; import '../util.dart'; import '../vector_math.dart'; import 'surface.dart'; @@ -43,9 +42,9 @@ class PersistedTransform extends PersistedContainerSurface @override html.Element createElement() { - final html.Element element = domRenderer.createElement('flt-transform'); - DomRenderer.setElementStyle(element, 'position', 'absolute'); - DomRenderer.setElementStyle(element, 'transform-origin', '0 0 0'); + final html.Element element = html.document.createElement('flt-transform'); + setElementStyle(element, 'position', 'absolute'); + setElementStyle(element, 'transform-origin', '0 0 0'); return element; } diff --git a/lib/web_ui/lib/src/engine/mouse_cursor.dart b/lib/web_ui/lib/src/engine/mouse_cursor.dart index cc67b9d08f0cb..3e5979bdedd86 100644 --- a/lib/web_ui/lib/src/engine/mouse_cursor.dart +++ b/lib/web_ui/lib/src/engine/mouse_cursor.dart @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dom_renderer.dart'; +import 'embedder.dart'; +import 'util.dart'; /// Provides mouse cursor bindings, such as the `flutter/mousecursor` channel. class MouseCursor { @@ -65,8 +66,8 @@ class MouseCursor { } void activateSystemCursor(String? kind) { - DomRenderer.setElementStyle( - domRenderer.glassPaneElement!, + setElementStyle( + flutterViewEmbedder.glassPaneElement!, 'cursor', _mapKindToCssValue(kind), ); diff --git a/lib/web_ui/lib/src/engine/platform_dispatcher.dart b/lib/web_ui/lib/src/engine/platform_dispatcher.dart index 8d8e1d369608c..7620518f95842 100644 --- a/lib/web_ui/lib/src/engine/platform_dispatcher.dart +++ b/lib/web_ui/lib/src/engine/platform_dispatcher.dart @@ -16,7 +16,7 @@ import 'canvaskit/initialization.dart'; import 'canvaskit/layer_scene_builder.dart'; import 'canvaskit/rasterizer.dart'; import 'clipboard.dart'; -import 'dom_renderer.dart'; +import 'embedder.dart'; import 'html/scene.dart'; import 'mouse_cursor.dart'; import 'platform_views/message_handler.dart'; @@ -420,7 +420,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { return; case 'HapticFeedback.vibrate': final String? type = decoded.arguments as String?; - domRenderer.vibrate(_getHapticFeedbackDuration(type)); + _vibrate(_getHapticFeedbackDuration(type)); replyToPlatformMessage(callback, codec.encodeSuccessEnvelope(true)); return; case 'SystemChrome.setApplicationSwitcherDescription': @@ -429,12 +429,12 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { final String label = arguments['label'] as String? ?? ''; final int primaryColor = arguments['primaryColor'] as int? ?? 0xFF000000; html.document.title = label; - domRenderer.setThemeColor(ui.Color(primaryColor)); + setThemeColor(ui.Color(primaryColor)); replyToPlatformMessage(callback, codec.encodeSuccessEnvelope(true)); return; case 'SystemChrome.setPreferredOrientations': final List arguments = decoded.arguments as List; - domRenderer.setPreferredOrientation(arguments).then((bool success) { + flutterViewEmbedder.setPreferredOrientation(arguments).then((bool success) { replyToPlatformMessage( callback, codec.encodeSuccessEnvelope(success)); }); @@ -483,7 +483,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { _platformViewMessageHandler ??= PlatformViewMessageHandler( contentManager: platformViewManager, contentHandler: (html.Element content) { - domRenderer.glassPaneElement!.append(content); + flutterViewEmbedder.glassPaneElement!.append(content); }, ); _platformViewMessageHandler!.handlePlatformViewCall(data, callback!); @@ -530,17 +530,23 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { } int _getHapticFeedbackDuration(String? type) { + const int vibrateLongPress = 50; + const int vibrateLightImpact = 10; + const int vibrateMediumImpact = 20; + const int vibrateHeavyImpact = 30; + const int vibrateSelectionClick = 10; + switch (type) { case 'HapticFeedbackType.lightImpact': - return DomRenderer.vibrateLightImpact; + return vibrateLightImpact; case 'HapticFeedbackType.mediumImpact': - return DomRenderer.vibrateMediumImpact; + return vibrateMediumImpact; case 'HapticFeedbackType.heavyImpact': - return DomRenderer.vibrateHeavyImpact; + return vibrateHeavyImpact; case 'HapticFeedbackType.selectionClick': - return DomRenderer.vibrateSelectionClick; + return vibrateSelectionClick; default: - return DomRenderer.vibrateLongPress; + return vibrateLongPress; } } @@ -600,7 +606,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { rasterizer!.draw(layerScene.layerTree); } else { final SurfaceScene surfaceScene = scene as SurfaceScene; - domRenderer.renderScene(surfaceScene.webOnlyRootElement); + flutterViewEmbedder.renderScene(surfaceScene.webOnlyRootElement); } frameTimingsOnRasterFinish(); } @@ -721,7 +727,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { _configuration = _configuration.copyWith(locales: const []); } - // Called by DomRenderer when browser languages change. + // Called by FlutterViewEmbedder when browser languages change. void updateLocales() { _configuration = _configuration.copyWith(locales: parseBrowserLanguages()); } @@ -1117,3 +1123,12 @@ num? _parseFontSize(html.Element element) { return fontSize; } + +/// Provides haptic feedback. +void _vibrate(int durationMs) { + final html.Navigator navigator = html.window.navigator; + if (js_util.hasProperty(navigator, 'vibrate')) { + // ignore: implicit_dynamic_function + js_util.callMethod(navigator, 'vibrate', [durationMs]); + } +} diff --git a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart index 064bed679ac29..58bf6a37c2895 100644 --- a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart +++ b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart @@ -5,7 +5,7 @@ import 'dart:html' as html; import '../browser_detection.dart'; -import '../dom_renderer.dart'; +import '../embedder.dart'; import '../util.dart'; import 'slots.dart'; @@ -154,7 +154,7 @@ class PlatformViewManager { final html.Element slot = html.document.createElement('slot') ..style.display = 'none' ..setAttribute('name', tombstoneName); - domRenderer.glassPaneShadow!.append(slot); + flutterViewEmbedder.glassPaneShadow!.append(slot); // Link the element to the new slot element.setAttribute('slot', tombstoneName); // Delete both the element, and the new slot diff --git a/lib/web_ui/lib/src/engine/rrect_renderer.dart b/lib/web_ui/lib/src/engine/rrect_renderer.dart index c23514b6d7ab2..fd7832d190ad2 100644 --- a/lib/web_ui/lib/src/engine/rrect_renderer.dart +++ b/lib/web_ui/lib/src/engine/rrect_renderer.dart @@ -7,7 +7,7 @@ import 'dart:math' as math; import 'package:ui/ui.dart' as ui; -import 'dom_renderer.dart'; +import 'util.dart'; /// Renders an RRect using path primitives. abstract class RRectRenderer { @@ -203,7 +203,7 @@ class RRectToCanvasRenderer extends RRectRenderer { @override void ellipse(double centerX, double centerY, double radiusX, double radiusY, double rotation, double startAngle, double endAngle, bool antiClockwise) { - DomRenderer.ellipse(context, centerX, centerY, radiusX, radiusY, rotation, startAngle, + drawEllipse(context, centerX, centerY, radiusX, radiusY, rotation, startAngle, endAngle, antiClockwise); } } diff --git a/lib/web_ui/lib/src/engine/semantics/semantics.dart b/lib/web_ui/lib/src/engine/semantics/semantics.dart index e0264bd34635c..5ae98324c7a94 100644 --- a/lib/web_ui/lib/src/engine/semantics/semantics.dart +++ b/lib/web_ui/lib/src/engine/semantics/semantics.dart @@ -12,7 +12,7 @@ import '../../engine.dart' show registerHotRestartListener; import '../alarm_clock.dart'; import '../browser_detection.dart'; import '../configuration.dart'; -import '../dom_renderer.dart'; +import '../embedder.dart'; import '../platform_dispatcher.dart'; import '../util.dart'; import '../vector_math.dart'; @@ -1594,7 +1594,7 @@ class EngineSemanticsOwner { if (_rootSemanticsElement == null) { final SemanticsObject root = _semanticsTree[0]!; _rootSemanticsElement = root.element; - domRenderer.semanticsHostElement!.append(root.element); + flutterViewEmbedder.semanticsHostElement!.append(root.element); } _finalizeTree(); diff --git a/lib/web_ui/lib/src/engine/semantics/text_field.dart b/lib/web_ui/lib/src/engine/semantics/text_field.dart index 0e3f4a7fc8b10..a8aaadcf2c8f8 100644 --- a/lib/web_ui/lib/src/engine/semantics/text_field.dart +++ b/lib/web_ui/lib/src/engine/semantics/text_field.dart @@ -220,7 +220,7 @@ class TextField extends RoleManager { void _setupDomElement() { // On iOS, even though the semantic text field is transparent, the cursor // and text highlighting are still visible. The cursor and text selection - // are made invisible by CSS in [DomRenderer.reset]. + // are made invisible by CSS in [FlutterViewEmbedder.reset]. // But there's one more case where iOS highlights text. That's when there's // and autocorrect suggestion. To disable that, we have to do the following: editableElement diff --git a/lib/web_ui/lib/src/engine/test_embedding.dart b/lib/web_ui/lib/src/engine/test_embedding.dart index 058c9874b0b4d..e72751635dc06 100644 --- a/lib/web_ui/lib/src/engine/test_embedding.dart +++ b/lib/web_ui/lib/src/engine/test_embedding.dart @@ -7,7 +7,43 @@ import 'dart:html' as html; import 'package:ui/ui.dart' as ui; -import 'navigation/url_strategy.dart'; +import '../engine.dart'; + +Future? _testPlatformInitializedFuture; + +Future ensureTestPlatformInitializedThenRunTest(dynamic Function() body) { + if (_testPlatformInitializedFuture == null) { + ui.debugEmulateFlutterTesterEnvironment = true; + + // Initializing the platform will ensure that the test font is loaded. + _testPlatformInitializedFuture = + ui.webOnlyInitializePlatform(assetManager: WebOnlyMockAssetManager()); + } + return _testPlatformInitializedFuture!.then((_) => body()); +} + +Future? _platformInitializedFuture; + +Future initializeTestFlutterViewEmbedder({double devicePixelRatio = 3.0}) { + // Force-initialize FlutterViewEmbedder so it doesn't overwrite test pixel ratio. + ensureFlutterViewEmbedderInitialized(); + + // The following parameters are hard-coded in Flutter's test embedder. Since + // we don't have an embedder yet this is the lowest-most layer we can put + // this stuff in. + window.debugOverrideDevicePixelRatio(devicePixelRatio); + window.webOnlyDebugPhysicalSizeOverride = + ui.Size(800 * devicePixelRatio, 600 * devicePixelRatio); + scheduleFrameCallback = () {}; + ui.debugEmulateFlutterTesterEnvironment = true; + + // Initialize platform once and reuse across all tests. + if (_platformInitializedFuture != null) { + return _platformInitializedFuture!; + } + return _platformInitializedFuture = + ui.webOnlyInitializePlatform(assetManager: WebOnlyMockAssetManager()); +} const bool _debugLogHistoryActions = false; diff --git a/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart b/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart index 3896e06efabd8..84bf98cbec18b 100644 --- a/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/canvas_paragraph.dart @@ -6,7 +6,7 @@ import 'dart:html' as html; import 'package:ui/ui.dart' as ui; -import '../dom_renderer.dart'; +import '../embedder.dart'; import '../html/bitmap_canvas.dart'; import '../profiler.dart'; import '../util.dart'; @@ -144,7 +144,7 @@ class CanvasParagraph implements EngineParagraph { html.HtmlElement _createDomElement() { final html.HtmlElement rootElement = - domRenderer.createElement('p') as html.HtmlElement; + html.document.createElement('p') as html.HtmlElement; // 1. Set paragraph-level styles. _applyNecessaryParagraphStyles(element: rootElement, style: paragraphStyle); @@ -181,7 +181,7 @@ class CanvasParagraph implements EngineParagraph { for (int i = 0; i < lines.length; i++) { // Insert a
element before each line except the first line. if (i > 0) { - element.append(domRenderer.createElement('br')); + element.append(html.document.createElement('br')); } final EngineLineMetrics line = lines[i]; @@ -197,13 +197,13 @@ class CanvasParagraph implements EngineParagraph { } if (buffer.isNotEmpty) { - domRenderer.appendText(element, buffer.toString()); + element.appendText(buffer.toString()); buffer.clear(); } if (box is SpanBox) { span = box.span; - element = domRenderer.createElement('span') as html.HtmlElement; + element = html.document.createElement('span') as html.HtmlElement; applyTextStyleToElement( element: element, style: box.span.style, @@ -225,13 +225,13 @@ class CanvasParagraph implements EngineParagraph { } if (buffer.isNotEmpty) { - domRenderer.appendText(element, buffer.toString()); + element.appendText(buffer.toString()); buffer.clear(); } final String? ellipsis = line.ellipsis; if (ellipsis != null) { - domRenderer.appendText(element, ellipsis); + element.appendText(ellipsis); } } @@ -598,7 +598,7 @@ class RootStyleNode extends StyleNode { ui.TextBaseline? get _textBaseline => null; @override - String get _fontFamily => paragraphStyle.fontFamily ?? DomRenderer.defaultFontFamily; + String get _fontFamily => paragraphStyle.fontFamily ?? FlutterViewEmbedder.defaultFontFamily; @override List? get _fontFamilyFallback => null; @@ -607,7 +607,7 @@ class RootStyleNode extends StyleNode { List? get _fontFeatures => null; @override - double get _fontSize => paragraphStyle.fontSize ?? DomRenderer.defaultFontSize; + double get _fontSize => paragraphStyle.fontSize ?? FlutterViewEmbedder.defaultFontSize; @override double? get _letterSpacing => null; diff --git a/lib/web_ui/lib/src/engine/text/measurement.dart b/lib/web_ui/lib/src/engine/text/measurement.dart index 4b1053350f649..0d9adc807ebe2 100644 --- a/lib/web_ui/lib/src/engine/text/measurement.dart +++ b/lib/web_ui/lib/src/engine/text/measurement.dart @@ -5,7 +5,7 @@ import 'dart:html' as html; import '../../engine.dart' show registerHotRestartListener; -import '../dom_renderer.dart'; +import '../embedder.dart'; // TODO(yjbanov): this is a hack we use to compute ideographic baseline; this // number is the ratio ideographic/alphabetic for font Ahem, @@ -17,7 +17,7 @@ const double baselineRatioHack = 1.1662499904632568; /// Hosts ruler DOM elements in a hidden container under a `root` [html.Node]. /// -/// The `root` [html.Node] is optional. Defaults to [domRenderer.glassPaneShadow]. +/// The `root` [html.Node] is optional. Defaults to [flutterViewEmbedder.glassPaneShadow]. class RulerHost { RulerHost({html.Node? root}) { _rulerHost.style @@ -29,7 +29,7 @@ class RulerHost { ..width = '0' ..height = '0'; - (root ?? domRenderer.glassPaneShadow!.node).append(_rulerHost); + (root ?? flutterViewEmbedder.glassPaneShadow!.node).append(_rulerHost); registerHotRestartListener(dispose); } diff --git a/lib/web_ui/lib/src/engine/text/paragraph.dart b/lib/web_ui/lib/src/engine/text/paragraph.dart index 78829587a5df6..c033ed9507740 100644 --- a/lib/web_ui/lib/src/engine/text/paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/paragraph.dart @@ -8,7 +8,7 @@ import 'dart:math' as math; import 'package:ui/ui.dart' as ui; import '../browser_detection.dart'; -import '../dom_renderer.dart'; +import '../embedder.dart'; import '../html/bitmap_canvas.dart'; import '../util.dart'; import 'layout_service.dart'; @@ -429,7 +429,7 @@ class EngineTextStyle implements ui.TextStyle { } } if (fontFamily.isEmpty) { - return DomRenderer.defaultFontFamily; + return FlutterViewEmbedder.defaultFontFamily; } return fontFamily; } @@ -453,7 +453,7 @@ class EngineTextStyle implements ui.TextStyle { TextHeightStyle _createHeightStyle() { return TextHeightStyle( fontFamily: effectiveFontFamily, - fontSize: fontSize ?? DomRenderer.defaultFontSize, + fontSize: fontSize ?? FlutterViewEmbedder.defaultFontSize, height: height, // TODO(mdebbar): Pass the actual value when font features become supported // https://github.com/flutter/flutter/issues/64595 @@ -744,7 +744,7 @@ void applyTextStyleToElement({ _textDecorationToCssString(style.decoration, style.decorationStyle); if (textDecoration != null) { if (browserEngine == BrowserEngine.webkit) { - DomRenderer.setElementStyle( + setElementStyle( element, '-webkit-text-decoration', textDecoration); } else { cssStyle.textDecoration = textDecoration; @@ -766,7 +766,7 @@ void applyTextStyleToElement({ html.Element createPlaceholderElement({ required ParagraphPlaceholder placeholder, }) { - final html.Element element = domRenderer.createElement('span'); + final html.Element element = html.document.createElement('span'); final html.CssStyleDeclaration style = element.style; style ..display = 'inline-block' diff --git a/lib/web_ui/lib/src/engine/text/ruler.dart b/lib/web_ui/lib/src/engine/text/ruler.dart index 79d1d2d20445c..9ef928d15a1e6 100644 --- a/lib/web_ui/lib/src/engine/text/ruler.dart +++ b/lib/web_ui/lib/src/engine/text/ruler.dart @@ -7,7 +7,7 @@ import 'dart:html' as html; import 'package:ui/ui.dart' as ui; import '../browser_detection.dart'; -import '../dom_renderer.dart'; +import '../embedder.dart'; import '../util.dart'; import 'measurement.dart'; import 'paragraph.dart'; @@ -24,7 +24,7 @@ String buildCssFontString({ if (fontStyle != null) { result.write(fontStyle == ui.FontStyle.normal ? 'normal' : 'italic'); } else { - result.write(DomRenderer.defaultFontStyle); + result.write(FlutterViewEmbedder.defaultFontStyle); } result.write(' '); @@ -32,14 +32,14 @@ String buildCssFontString({ if (fontWeight != null) { result.write(fontWeightToCss(fontWeight)); } else { - result.write(DomRenderer.defaultFontWeight); + result.write(FlutterViewEmbedder.defaultFontWeight); } result.write(' '); if (fontSize != null) { result.write(fontSize.floor()); } else { - result.write(DomRenderer.defaultFontSize); + result.write(FlutterViewEmbedder.defaultFontSize); } result.write('px '); result.write(canonicalizeFontFamily(fontFamily)); @@ -98,7 +98,7 @@ class ParagraphGeometricStyle { } final String? localFontFamily = fontFamily; if (localFontFamily == null || localFontFamily.isEmpty) { - return DomRenderer.defaultFontFamily; + return FlutterViewEmbedder.defaultFontFamily; } return localFontFamily; } @@ -124,7 +124,7 @@ class ParagraphGeometricStyle { if (style == null) { style = TextHeightStyle( fontFamily: effectiveFontFamily, - fontSize: fontSize ?? DomRenderer.defaultFontSize, + fontSize: fontSize ?? FlutterViewEmbedder.defaultFontSize, height: lineHeight, // TODO(mdebbar): Pass the actual value when font features become supported // https://github.com/flutter/flutter/issues/64595 diff --git a/lib/web_ui/lib/src/engine/text_editing/text_editing.dart b/lib/web_ui/lib/src/engine/text_editing/text_editing.dart index 3eee473f2894d..ba89068469add 100644 --- a/lib/web_ui/lib/src/engine/text_editing/text_editing.dart +++ b/lib/web_ui/lib/src/engine/text_editing/text_editing.dart @@ -11,7 +11,7 @@ import 'package:meta/meta.dart'; import 'package:ui/ui.dart' as ui; import '../browser_detection.dart'; -import '../dom_renderer.dart'; +import '../embedder.dart'; import '../host_node.dart'; import '../platform_dispatcher.dart'; import '../semantics.dart'; @@ -46,7 +46,7 @@ void _emptyCallback(dynamic _) {} /// The default [HostNode] that hosts all DOM required for text editing when a11y is not enabled. @visibleForTesting -HostNode get defaultTextEditingRoot => domRenderer.glassPaneShadow!; +HostNode get defaultTextEditingRoot => flutterViewEmbedder.glassPaneShadow!; /// These style attributes are constant throughout the life time of an input /// element. @@ -1180,7 +1180,7 @@ class IOSTextEditingStrategy extends GloballyPositionedTextEditingStrategy { // On iOS, blur is trigerred in the following cases: // // 1. The browser app is sent to the background (or the tab is changed). In - // this case, the window loses focus (see [domRenderer.windowHasFocus]), + // this case, the window loses focus (see [flutterViewEmbedder.windowHasFocus]), // so we close the input connection with the framework. // 2. The user taps on another focusable element. In this case, we refocus // the input field and wait for the framework to manage the focus change. @@ -1189,7 +1189,7 @@ class IOSTextEditingStrategy extends GloballyPositionedTextEditingStrategy { // okay because the virtual keyboard will hide, and as soon as the user // taps the text field again, the virtual keyboard will come up. subscriptions.add(activeDomElement.onBlur.listen((_) { - if (domRenderer.windowHasFocus) { + if (flutterViewEmbedder.windowHasFocus) { activeDomElement.focus(); } else { owner.sendTextConnectionClosedToFrameworkIfAny(); @@ -1301,11 +1301,11 @@ class AndroidTextEditingStrategy extends GloballyPositionedTextEditingStrategy { subscriptions.add(html.document.onSelectionChange.listen(handleChange)); subscriptions.add(activeDomElement.onBlur.listen((_) { - if (domRenderer.windowHasFocus) { + if (flutterViewEmbedder.windowHasFocus) { // Chrome on Android will hide the onscreen keyboard when you tap outside // the text box. Instead, we want the framework to tell us to hide the // keyboard via `TextInput.clearClient` or `TextInput.hide`. Therefore - // refocus as long as [domRenderer.windowHasFocus] is true. + // refocus as long as [flutterViewEmbedder.windowHasFocus] is true. activeDomElement.focus(); } else { owner.sendTextConnectionClosedToFrameworkIfAny(); diff --git a/lib/web_ui/lib/src/engine/util.dart b/lib/web_ui/lib/src/engine/util.dart index 48868be64b835..eaba1dd2e0d41 100644 --- a/lib/web_ui/lib/src/engine/util.dart +++ b/lib/web_ui/lib/src/engine/util.dart @@ -682,3 +682,78 @@ num? parseFloat(String source) { String bytesToHexString(List data) { return data.map((int byte) => '0x' + byte.toRadixString(16).padLeft(2, '0')).join(' '); } + +/// Sets a style property on [element]. +/// +/// [name] is the name of the property. [value] is the value of the property. +/// If [value] is null, removes the style property. +void setElementStyle( + html.Element element, String name, String? value) { + if (value == null) { + element.style.removeProperty(name); + } else { + element.style.setProperty(name, value); + } +} + +void setClipPath(html.Element element, String? value) { + if (browserEngine == BrowserEngine.webkit) { + if (value == null) { + element.style.removeProperty('-webkit-clip-path'); + } else { + element.style.setProperty('-webkit-clip-path', value); + } + } + if (value == null) { + element.style.removeProperty('clip-path'); + } else { + element.style.setProperty('clip-path', value); + } +} + +void setThemeColor(ui.Color color) { + html.MetaElement? theme = + html.document.querySelector('#flutterweb-theme') as html.MetaElement?; + if (theme == null) { + theme = html.MetaElement() + ..id = 'flutterweb-theme' + ..name = 'theme-color'; + html.document.head!.append(theme); + } + theme.content = colorToCssString(color)!; +} + +bool? _ellipseFeatureDetected; + +/// Draws CanvasElement ellipse with fallback. +void drawEllipse( + html.CanvasRenderingContext2D context, + double centerX, + double centerY, + double radiusX, + double radiusY, + double rotation, + double startAngle, + double endAngle, + bool antiClockwise) { + // ignore: implicit_dynamic_function + _ellipseFeatureDetected ??= js_util.getProperty(context, 'ellipse') != null; + if (_ellipseFeatureDetected!) { + context.ellipse(centerX, centerY, radiusX, radiusY, rotation, startAngle, + endAngle, antiClockwise); + } else { + context.save(); + context.translate(centerX, centerY); + context.rotate(rotation); + context.scale(radiusX, radiusY); + context.arc(0, 0, 1, startAngle, endAngle, antiClockwise); + context.restore(); + } +} + +/// Removes all children of a DOM node. +void removeAllChildren(html.Node node) { + while (node.lastChild != null) { + node.lastChild!.remove(); + } +} diff --git a/lib/web_ui/lib/src/ui/test_embedding.dart b/lib/web_ui/lib/src/ui/test_embedding.dart deleted file mode 100644 index 3e70d919540f4..0000000000000 --- a/lib/web_ui/lib/src/ui/test_embedding.dart +++ /dev/null @@ -1,43 +0,0 @@ -// 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. - -// TODO(yjbanov): the Web-only API below need to be cleaned up. - -part of ui; - -Future? _testPlatformInitializedFuture; - -Future ensureTestPlatformInitializedThenRunTest(dynamic Function() body) { - if (_testPlatformInitializedFuture == null) { - debugEmulateFlutterTesterEnvironment = true; - - // Initializing the platform will ensure that the test font is loaded. - _testPlatformInitializedFuture = - webOnlyInitializePlatform(assetManager: engine.WebOnlyMockAssetManager()); - } - return _testPlatformInitializedFuture!.then((_) => body()); -} - -Future? _platformInitializedFuture; - -Future webOnlyInitializeTestDomRenderer({double devicePixelRatio = 3.0}) { - // Force-initialize DomRenderer so it doesn't overwrite test pixel ratio. - engine.ensureDomRendererInitialized(); - - // The following parameters are hard-coded in Flutter's test embedder. Since - // we don't have an embedder yet this is the lowest-most layer we can put - // this stuff in. - engine.window.debugOverrideDevicePixelRatio(devicePixelRatio); - engine.window.webOnlyDebugPhysicalSizeOverride = - Size(800 * devicePixelRatio, 600 * devicePixelRatio); - engine.scheduleFrameCallback = () {}; - debugEmulateFlutterTesterEnvironment = true; - - // Initialize platform once and reuse across all tests. - if (_platformInitializedFuture != null) { - return _platformInitializedFuture!; - } - return _platformInitializedFuture = - webOnlyInitializePlatform(assetManager: engine.WebOnlyMockAssetManager()); -} diff --git a/lib/web_ui/lib/ui.dart b/lib/web_ui/lib/ui.dart index 7b59a3d2d68dc..cd032c270f3fd 100644 --- a/lib/web_ui/lib/ui.dart +++ b/lib/web_ui/lib/ui.dart @@ -32,7 +32,6 @@ part 'src/ui/path_metrics.dart'; part 'src/ui/platform_dispatcher.dart'; part 'src/ui/pointer.dart'; part 'src/ui/semantics.dart'; -part 'src/ui/test_embedding.dart'; part 'src/ui/text.dart'; part 'src/ui/tile_mode.dart'; part 'src/ui/window.dart'; diff --git a/lib/web_ui/test/canvas_test.dart b/lib/web_ui/test/canvas_test.dart index 9e87bd100d835..76a61b57d929f 100644 --- a/lib/web_ui/test/canvas_test.dart +++ b/lib/web_ui/test/canvas_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:html' as html; + import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; @@ -31,7 +33,7 @@ void testMain() { }) { test(description, () { testFn(BitmapCanvas(canvasSize, RenderStrategy())); - testFn(DomCanvas(domRenderer.createElement('flt-picture'))); + testFn(DomCanvas(html.document.createElement('flt-picture'))); testFn(mockCanvas = MockEngineCanvas()); whenDone?.call(); }); diff --git a/lib/web_ui/test/canvaskit/embedded_views_test.dart b/lib/web_ui/test/canvaskit/embedded_views_test.dart index b3f03f5a483dd..af02c950c68ac 100644 --- a/lib/web_ui/test/canvaskit/embedded_views_test.dart +++ b/lib/web_ui/test/canvaskit/embedded_views_test.dart @@ -42,9 +42,9 @@ void testMain() { // as a child of the glassPane, and the slot lives in the glassPane // shadow root. The slot is the one that has pointer events auto. final html.Element contents = - domRenderer.glassPaneElement!.querySelector('#view-0')!; + flutterViewEmbedder.glassPaneElement!.querySelector('#view-0')!; final html.Element slot = - domRenderer.sceneElement!.querySelector('slot')!; + flutterViewEmbedder.sceneElement!.querySelector('slot')!; final html.Element contentsHost = contents.parent!; final html.Element slotHost = slot.parent!; @@ -77,11 +77,11 @@ void testMain() { dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.sceneElement!.querySelectorAll('#sk_path_defs').single, + flutterViewEmbedder.sceneElement!.querySelectorAll('#sk_path_defs').single, isNotNull, ); expect( - domRenderer.sceneElement! + flutterViewEmbedder.sceneElement! .querySelectorAll('#sk_path_defs') .single .querySelectorAll('clipPath') @@ -89,7 +89,7 @@ void testMain() { isNotNull, ); expect( - domRenderer.sceneElement! + flutterViewEmbedder.sceneElement! .querySelectorAll('flt-clip') .single .style @@ -119,7 +119,7 @@ void testMain() { // Transformations happen on the slot element. final html.Element slotHost = - domRenderer.sceneElement!.querySelector('flt-platform-view-slot')!; + flutterViewEmbedder.sceneElement!.querySelector('flt-platform-view-slot')!; expect( slotHost.style.transform, @@ -161,7 +161,7 @@ void testMain() { // Transformations happen on the slot element. final html.Element slotHost = - domRenderer.sceneElement!.querySelector('flt-platform-view-slot')!; + flutterViewEmbedder.sceneElement!.querySelector('flt-platform-view-slot')!; expect( getTransformChain(slotHost), @@ -190,7 +190,7 @@ void testMain() { // Transformations happen on the slot element. final html.Element slotHost = - domRenderer.sceneElement!.querySelector('flt-platform-view-slot')!; + flutterViewEmbedder.sceneElement!.querySelector('flt-platform-view-slot')!; expect( getTransformChain(slotHost), @@ -234,7 +234,7 @@ void testMain() { } int countCanvases() { - return domRenderer.sceneElement!.querySelectorAll('canvas').length; + return flutterViewEmbedder.sceneElement!.querySelectorAll('canvas').length; } // Frame 1: @@ -337,7 +337,7 @@ void testMain() { } int countCanvases() { - return domRenderer.sceneElement!.querySelectorAll('canvas').length; + return flutterViewEmbedder.sceneElement!.querySelectorAll('canvas').length; } // Frame 1: @@ -379,11 +379,11 @@ void testMain() { dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.sceneElement!.querySelector('flt-platform-view-slot'), + flutterViewEmbedder.sceneElement!.querySelector('flt-platform-view-slot'), isNotNull, ); expect( - domRenderer.glassPaneElement!.querySelector('flt-platform-view'), + flutterViewEmbedder.glassPaneElement!.querySelector('flt-platform-view'), isNotNull, ); @@ -394,11 +394,11 @@ void testMain() { dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.sceneElement!.querySelector('flt-platform-view-slot'), + flutterViewEmbedder.sceneElement!.querySelector('flt-platform-view-slot'), isNull, ); expect( - domRenderer.glassPaneElement!.querySelector('flt-platform-view'), + flutterViewEmbedder.glassPaneElement!.querySelector('flt-platform-view'), isNull, ); }); @@ -419,11 +419,11 @@ void testMain() { dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.sceneElement!.querySelector('flt-platform-view-slot'), + flutterViewEmbedder.sceneElement!.querySelector('flt-platform-view-slot'), isNotNull, ); expect( - domRenderer.glassPaneElement!.querySelector('flt-platform-view'), + flutterViewEmbedder.glassPaneElement!.querySelector('flt-platform-view'), isNotNull, ); @@ -435,10 +435,10 @@ void testMain() { dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.sceneElement!.querySelectorAll('flt-platform-view-slot'), + flutterViewEmbedder.sceneElement!.querySelectorAll('flt-platform-view-slot'), hasLength(1)); expect( - domRenderer.glassPaneElement!.querySelectorAll('flt-platform-view'), + flutterViewEmbedder.glassPaneElement!.querySelectorAll('flt-platform-view'), hasLength(2)); // Render a frame without a platform view, but also without disposing of @@ -448,13 +448,13 @@ void testMain() { dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.sceneElement!.querySelector('flt-platform-view-slot'), + flutterViewEmbedder.sceneElement!.querySelector('flt-platform-view-slot'), isNull, ); // The actual contents of the platform view are kept in the dom, until // it's actually disposed of! expect( - domRenderer.glassPaneElement!.querySelector('flt-platform-view'), + flutterViewEmbedder.glassPaneElement!.querySelector('flt-platform-view'), isNotNull, ); }); @@ -481,7 +481,7 @@ void testMain() { } final html.Node skPathDefs = - domRenderer.sceneElement!.querySelector('#sk_path_defs')!; + flutterViewEmbedder.sceneElement!.querySelector('#sk_path_defs')!; expect(skPathDefs.childNodes, hasLength(0)); @@ -572,7 +572,7 @@ void testMain() { // The below line should not throw an error. dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.glassPaneShadow! + flutterViewEmbedder.glassPaneShadow! .querySelectorAll('flt-platform-view-slot'), isEmpty); }); @@ -595,7 +595,7 @@ void testMain() { // The below line should not throw an error. dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.glassPaneShadow! + flutterViewEmbedder.glassPaneShadow! .querySelectorAll('flt-platform-view-slot'), hasLength(1)); HtmlViewEmbedder.debugDisableOverlays = false; @@ -624,7 +624,7 @@ void testMain() { dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.glassPaneShadow! + flutterViewEmbedder.glassPaneShadow! .querySelectorAll('flt-platform-view-slot'), hasLength(2)); @@ -635,7 +635,7 @@ void testMain() { // The below line should not throw an error. dispatcher.rasterizer!.draw(sb.build().layerTree); expect( - domRenderer.glassPaneShadow! + flutterViewEmbedder.glassPaneShadow! .querySelectorAll('flt-platform-view-slot'), hasLength(1)); diff --git a/lib/web_ui/test/canvaskit/hot_restart_test.dart b/lib/web_ui/test/canvaskit/hot_restart_test.dart index d187fbb7a8284..4b4a8a3c5815b 100644 --- a/lib/web_ui/test/canvaskit/hot_restart_test.dart +++ b/lib/web_ui/test/canvaskit/hot_restart_test.dart @@ -21,7 +21,7 @@ void testMain() { () async { expect(windowFlutterCanvasKit, isNull); - DomRenderer(); + FlutterViewEmbedder(); await ui.webOnlyInitializePlatform( assetManager: WebOnlyMockAssetManager()); expect(windowFlutterCanvasKit, isNotNull); @@ -29,7 +29,7 @@ void testMain() { final CanvasKit? firstCanvasKitInstance = windowFlutterCanvasKit; // Triggers a reset of the CanvasKit script element. - DomRenderer(); + FlutterViewEmbedder(); await ui.webOnlyInitializePlatform( assetManager: WebOnlyMockAssetManager()); // The instance is the same. diff --git a/lib/web_ui/test/canvaskit/initialization_test.dart b/lib/web_ui/test/canvaskit/initialization_test.dart index 49c614b07537f..0a1a9c89a0d31 100644 --- a/lib/web_ui/test/canvaskit/initialization_test.dart +++ b/lib/web_ui/test/canvaskit/initialization_test.dart @@ -19,7 +19,7 @@ void testMain() { setUpCanvasKitTest(); test('populates flt-renderer and flt-build-mode', () { - DomRenderer(); + FlutterViewEmbedder(); expect(html.document.body!.attributes['flt-renderer'], 'canvaskit (requested explicitly)'); expect(html.document.body!.attributes['flt-build-mode'], 'debug'); diff --git a/lib/web_ui/test/clipboard_test.dart b/lib/web_ui/test/clipboard_test.dart index 1e6174e233c5e..d28ea3f92e975 100644 --- a/lib/web_ui/test/clipboard_test.dart +++ b/lib/web_ui/test/clipboard_test.dart @@ -8,14 +8,13 @@ import 'dart:typed_data'; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; -import 'package:ui/ui.dart' as ui; void main() { internalBootstrapBrowserTest(() => testMain); } Future testMain() async { - await ui.webOnlyInitializeTestDomRenderer(); + await initializeTestFlutterViewEmbedder(); group('message handler', () { const String testText = 'test text'; diff --git a/lib/web_ui/test/dom_renderer_test.dart b/lib/web_ui/test/embedder_test.dart similarity index 62% rename from lib/web_ui/test/dom_renderer_test.dart rename to lib/web_ui/test/embedder_test.dart index 0bdc44863deb4..6ba119da14be7 100644 --- a/lib/web_ui/test/dom_renderer_test.dart +++ b/lib/web_ui/test/embedder_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @JS() -library dom_renderer_test; // We need this to mess with the ShadowDOM. +library embedder_test; // We need this to mess with the ShadowDOM. import 'dart:html' as html; @@ -17,41 +17,12 @@ void main() { void testMain() { test('populates flt-renderer and flt-build-mode', () { - DomRenderer(); + FlutterViewEmbedder(); expect(html.document.body!.attributes['flt-renderer'], 'html (requested explicitly)'); expect(html.document.body!.attributes['flt-build-mode'], 'debug'); }); - test('creating elements works', () { - final DomRenderer renderer = DomRenderer(); - final html.Element element = renderer.createElement('div'); - expect(element, isNotNull); - }); - - test('can set style properties on elements', () { - final DomRenderer renderer = DomRenderer(); - final html.Element element = renderer.createElement('div'); - DomRenderer.setElementStyle(element, 'color', 'red'); - expect(element.style.color, 'red'); - }); - - test('can remove style properties from elements', () { - final DomRenderer renderer = DomRenderer(); - final html.Element element = renderer.createElement('div'); - DomRenderer.setElementStyle(element, 'color', 'blue'); - expect(element.style.color, 'blue'); - DomRenderer.setElementStyle(element, 'color', null); - expect(element.style.color, ''); - }); - - test('elements can have children', () { - final DomRenderer renderer = DomRenderer(); - final html.Element element = renderer.createElement('div'); - renderer.createElement('div', parent: element); - expect(element.children, hasLength(1)); - }); - test('innerHeight/innerWidth are equal to visualViewport height and width', () { if (html.window.visualViewport != null) { @@ -67,8 +38,8 @@ void testMain() { html.document.head!.append(existingMeta); expect(existingMeta.isConnected, isTrue); - final DomRenderer renderer = DomRenderer(); - renderer.reset(); + final FlutterViewEmbedder embedder = FlutterViewEmbedder(); + embedder.reset(); }, // TODO(ferhat): https://github.com/flutter/flutter/issues/46638 // TODO(ferhat): https://github.com/flutter/flutter/issues/50828 @@ -76,19 +47,17 @@ void testMain() { browserEngine == BrowserEngine.edge); test('accesibility placeholder is attached after creation', () { - final DomRenderer renderer = DomRenderer(); + final FlutterViewEmbedder embedder = FlutterViewEmbedder(); expect( - renderer.glassPaneShadow?.querySelectorAll('flt-semantics-placeholder'), + embedder.glassPaneShadow?.querySelectorAll('flt-semantics-placeholder'), isNotEmpty, ); }); test('renders a shadowRoot by default', () { - final DomRenderer renderer = DomRenderer(); - - final HostNode hostNode = renderer.glassPaneShadow!; - + final FlutterViewEmbedder embedder = FlutterViewEmbedder(); + final HostNode hostNode = embedder.glassPaneShadow!; expect(hostNode.node, isA()); }); @@ -98,48 +67,45 @@ void testMain() { attachShadow = null; // Break ShadowDOM - final DomRenderer renderer = DomRenderer(); - - final HostNode hostNode = renderer.glassPaneShadow!; - + final FlutterViewEmbedder embedder = FlutterViewEmbedder(); + final HostNode hostNode = embedder.glassPaneShadow!; expect(hostNode.node, isA()); expect( (hostNode.node as html.Element).tagName, equalsIgnoringCase('flt-element-host-node'), ); - attachShadow = oldAttachShadow; // Restore ShadowDOM }); test('should add/remove global resource', () { - final DomRenderer renderer = DomRenderer(); + final FlutterViewEmbedder embedder = FlutterViewEmbedder(); final html.DivElement resource = html.DivElement(); - renderer.addResource(resource); + embedder.addResource(resource); final html.Element? resourceRoot = resource.parent; expect(resourceRoot, isNotNull); expect(resourceRoot!.childNodes.length, 1); - renderer.removeResource(resource); + embedder.removeResource(resource); expect(resourceRoot.childNodes.length, 0); }); test('hide placeholder text for textfield', () { - final DomRenderer renderer = DomRenderer(); + final FlutterViewEmbedder embedder = FlutterViewEmbedder(); final html.InputElement regularTextField = html.InputElement(); regularTextField.placeholder = 'Now you see me'; - renderer.addResource(regularTextField); + embedder.addResource(regularTextField); regularTextField.focus(); - html.CssStyleDeclaration? style = renderer.glassPaneShadow?.querySelector('input')?.getComputedStyle('::placeholder'); + html.CssStyleDeclaration? style = embedder.glassPaneShadow?.querySelector('input')?.getComputedStyle('::placeholder'); expect(style, isNotNull); expect(style?.opacity, isNot('0')); final html.InputElement textField = html.InputElement(); textField.placeholder = 'Now you dont'; textField.classes.add('flt-text-editing'); - renderer.addResource(textField); + embedder.addResource(textField); textField.focus(); - style = renderer.glassPaneShadow?.querySelector('input.flt-text-editing')?.getComputedStyle('::placeholder'); + style = embedder.glassPaneShadow?.querySelector('input.flt-text-editing')?.getComputedStyle('::placeholder'); expect(style, isNotNull); expect(style?.opacity, '0'); }, skip: browserEngine != BrowserEngine.firefox); diff --git a/lib/web_ui/test/engine/image/html_image_codec_test.dart b/lib/web_ui/test/engine/image/html_image_codec_test.dart index ac3cfeb0b2cf8..1b8eb76d82cc3 100644 --- a/lib/web_ui/test/engine/image/html_image_codec_test.dart +++ b/lib/web_ui/test/engine/image/html_image_codec_test.dart @@ -8,6 +8,7 @@ import 'dart:typed_data'; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine/html_image_codec.dart'; +import 'package:ui/src/engine/test_embedding.dart'; import 'package:ui/ui.dart' as ui; void main() { @@ -15,7 +16,7 @@ void main() { } Future testMain() async { - await ui.webOnlyInitializeTestDomRenderer(); + await initializeTestFlutterViewEmbedder(); group('HtmCodec', () { test('supports raw images - RGBA8888', () async { final Completer completer = Completer(); diff --git a/lib/web_ui/test/engine/pointer_binding_test.dart b/lib/web_ui/test/engine/pointer_binding_test.dart index c804355bf5acd..1fd6533b63018 100644 --- a/lib/web_ui/test/engine/pointer_binding_test.dart +++ b/lib/web_ui/test/engine/pointer_binding_test.dart @@ -7,9 +7,9 @@ import 'dart:js_util' as js_util; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; -import 'package:ui/src/engine.dart' show domRenderer, window; +import 'package:ui/src/engine.dart' show flutterViewEmbedder, window; import 'package:ui/src/engine/browser_detection.dart'; -import 'package:ui/src/engine/dom_renderer.dart'; +import 'package:ui/src/engine/embedder.dart'; import 'package:ui/src/engine/pointer_binding.dart'; import 'package:ui/ui.dart' as ui; @@ -46,11 +46,11 @@ void main() { } void testMain() { - final html.Element glassPane = domRenderer.glassPaneElement!; + final html.Element glassPane = flutterViewEmbedder.glassPaneElement!; double dpi = 1.0; setUp(() { - ensureDomRendererInitialized(); + ensureFlutterViewEmbedderInitialized(); ui.window.onPointerDataPacket = null; dpi = window.devicePixelRatio; }); diff --git a/lib/web_ui/test/engine/semantics/semantics_test.dart b/lib/web_ui/test/engine/semantics/semantics_test.dart index a4a7299b77f52..327e59bf53e4f 100644 --- a/lib/web_ui/test/engine/semantics/semantics_test.dart +++ b/lib/web_ui/test/engine/semantics/semantics_test.dart @@ -12,7 +12,7 @@ import 'package:quiver/testing/async.dart'; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; -import 'package:ui/src/engine.dart' show domRenderer; +import 'package:ui/src/engine.dart' show flutterViewEmbedder; import 'package:ui/src/engine/browser_detection.dart'; import 'package:ui/src/engine/semantics.dart'; import 'package:ui/src/engine/vector_math.dart'; @@ -85,7 +85,7 @@ void _testEngineSemanticsOwner() { }); test('placeholder enables semantics', () async { - domRenderer.reset(); // triggers `autoEnableOnTap` to be called + flutterViewEmbedder.reset(); // triggers `autoEnableOnTap` to be called expect(semantics().semanticsEnabled, isFalse); // Synthesize a click on the placeholder. @@ -112,7 +112,7 @@ void _testEngineSemanticsOwner() { }); test('auto-enables semantics', () async { - domRenderer.reset(); // triggers `autoEnableOnTap` to be called + flutterViewEmbedder.reset(); // triggers `autoEnableOnTap` to be called expect(semantics().semanticsEnabled, isFalse); final html.Element placeholder = diff --git a/lib/web_ui/test/engine/semantics/semantics_tester.dart b/lib/web_ui/test/engine/semantics/semantics_tester.dart index 8771201643414..db61c7321ea31 100644 --- a/lib/web_ui/test/engine/semantics/semantics_tester.dart +++ b/lib/web_ui/test/engine/semantics/semantics_tester.dart @@ -7,7 +7,7 @@ import 'dart:html' as html; import 'dart:typed_data'; import 'package:test/test.dart'; -import 'package:ui/src/engine.dart' show domRenderer, toMatrix32; +import 'package:ui/src/engine.dart' show flutterViewEmbedder, toMatrix32; import 'package:ui/src/engine/browser_detection.dart'; import 'package:ui/src/engine/host_node.dart'; import 'package:ui/src/engine/semantics.dart'; @@ -23,7 +23,7 @@ import '../../matchers.dart'; /// so we don't have to hardcode html.document across the test. (The host of a /// normal flutter app used to be html.document, but now that the app is wrapped /// in a Shadow DOM, that's not the case anymore.) -HostNode get appHostNode => domRenderer.glassPaneShadow!; +HostNode get appHostNode => flutterViewEmbedder.glassPaneShadow!; /// CSS style applied to the root of the semantics tree. // TODO(yjbanov): this should be handled internally by [expectSemanticsTree]. diff --git a/lib/web_ui/test/engine/semantics/text_field_test.dart b/lib/web_ui/test/engine/semantics/text_field_test.dart index 018969d7864a1..43bca8dd7f630 100644 --- a/lib/web_ui/test/engine/semantics/text_field_test.dart +++ b/lib/web_ui/test/engine/semantics/text_field_test.dart @@ -121,7 +121,7 @@ void testMain() { ); final TextField textField = textFieldSemantics.debugRoleManagerFor(Role.textField)! as TextField; - expect(html.document.activeElement, domRenderer.glassPaneElement); + expect(html.document.activeElement, flutterViewEmbedder.glassPaneElement); expect(appHostNode.activeElement, strategy.domElement); expect(textField.editableElement, strategy.domElement); expect((textField.editableElement as dynamic).value, 'hello'); @@ -174,7 +174,7 @@ void testMain() { final TextField textField = textFieldSemantics.debugRoleManagerFor(Role.textField)! as TextField; expect(textField.editableElement, strategy.domElement); - expect(html.document.activeElement, domRenderer.glassPaneElement); + expect(html.document.activeElement, flutterViewEmbedder.glassPaneElement); expect(appHostNode.activeElement, strategy.domElement); // The input should not refocus after blur. @@ -205,7 +205,7 @@ void testMain() { isFocused: true, ); expect(strategy.domElement, isNotNull); - expect(html.document.activeElement, domRenderer.glassPaneElement); + expect(html.document.activeElement, flutterViewEmbedder.glassPaneElement); expect(appHostNode.activeElement, strategy.domElement); strategy.disable(); @@ -237,7 +237,7 @@ void testMain() { isFocused: true, ); expect(strategy.domElement, isNotNull); - expect(html.document.activeElement, domRenderer.glassPaneElement); + expect(html.document.activeElement, flutterViewEmbedder.glassPaneElement); expect(appHostNode.activeElement, strategy.domElement); // Blur the element without telling the framework. @@ -261,7 +261,7 @@ void testMain() { value: 'hello', isFocused: true, ); - expect(html.document.activeElement, domRenderer.glassPaneElement); + expect(html.document.activeElement, flutterViewEmbedder.glassPaneElement); expect(appHostNode.activeElement, strategy.domElement); strategy.disable(); @@ -286,7 +286,7 @@ void testMain() { final html.TextAreaElement textArea = strategy.domElement! as html.TextAreaElement; - expect(html.document.activeElement, domRenderer.glassPaneElement); + expect(html.document.activeElement, flutterViewEmbedder.glassPaneElement); expect(appHostNode.activeElement, strategy.domElement); strategy.enable( @@ -392,7 +392,7 @@ void testMain() { createTwoFieldSemantics(tester, focusFieldId: 1); expect(tester.apply().length, 3); - expect(html.document.activeElement, domRenderer.glassPaneElement); + expect(html.document.activeElement, flutterViewEmbedder.glassPaneElement); expect(appHostNode.activeElement, tester.getTextField(1).editableElement); expect(strategy.domElement, tester.getTextField(1).editableElement); diff --git a/lib/web_ui/test/engine/util_test.dart b/lib/web_ui/test/engine/util_test.dart index ae943ec8f7d2c..3563e36f21998 100644 --- a/lib/web_ui/test/engine/util_test.dart +++ b/lib/web_ui/test/engine/util_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:html' as html; import 'dart:typed_data'; import 'package:test/bootstrap/browser.dart'; @@ -101,4 +102,18 @@ void testMain() { expect(parseFloat('text 108'), isNull); expect(parseFloat('another text 108'), isNull); }); + + test('can set style properties on elements', () { + final html.Element element = html.document.createElement('div'); + setElementStyle(element, 'color', 'red'); + expect(element.style.color, 'red'); + }); + + test('can remove style properties from elements', () { + final html.Element element = html.document.createElement('div'); + setElementStyle(element, 'color', 'blue'); + expect(element.style.color, 'blue'); + setElementStyle(element, 'color', null); + expect(element.style.color, ''); + }); } diff --git a/lib/web_ui/test/engine/window_test.dart b/lib/web_ui/test/engine/window_test.dart index 8fa9850d36aff..ab09ba30d2b01 100644 --- a/lib/web_ui/test/engine/window_test.dart +++ b/lib/web_ui/test/engine/window_test.dart @@ -326,7 +326,7 @@ void testMain() { localeChangedCount += 1; }; - ensureDomRendererInitialized(); + ensureFlutterViewEmbedderInitialized(); // We populate the initial list of locales automatically (only test that we // got some locales; some contributors may be in different locales, so we diff --git a/lib/web_ui/test/html/bitmap_canvas_golden_test.dart b/lib/web_ui/test/html/bitmap_canvas_golden_test.dart index c78e491848b7b..4521c6c700857 100644 --- a/lib/web_ui/test/html/bitmap_canvas_golden_test.dart +++ b/lib/web_ui/test/html/bitmap_canvas_golden_test.dart @@ -26,13 +26,13 @@ Future testMain() async { // Create a element to make sure our CSS reset applies correctly. final html.Element testScene = html.Element.tag('flt-scene'); testScene.append(canvas.rootElement); - domRenderer.glassPaneShadow!.querySelector('flt-scene-host')!.append(testScene); + flutterViewEmbedder.glassPaneShadow!.querySelector('flt-scene-host')!.append(testScene); } setUpStableTestFonts(); tearDown(() { - domRenderer.glassPaneShadow?.querySelector('flt-scene')?.remove(); + flutterViewEmbedder.glassPaneShadow?.querySelector('flt-scene')?.remove(); }); /// Draws several lines, some aligned precisely with the pixel grid, and some @@ -248,7 +248,7 @@ Future testMain() async { final html.Element sceneElement = scene.webOnlyRootElement!; sceneElement.querySelector('flt-clip')!.append(canvas.rootElement); - domRenderer.glassPaneShadow!.querySelector('flt-scene-host')!.append(sceneElement); + flutterViewEmbedder.glassPaneShadow!.querySelector('flt-scene-host')!.append(sceneElement); await matchGoldenFile( 'bitmap_canvas_draws_text_on_top_of_canvas.png', diff --git a/lib/web_ui/test/html/paragraph/bidi_golden_test.dart b/lib/web_ui/test/html/paragraph/bidi_golden_test.dart index 49b5aca522908..1132b39e56928 100644 --- a/lib/web_ui/test/html/paragraph/bidi_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/bidi_golden_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:html' as html; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; @@ -91,7 +92,7 @@ Future testMain() async { test('basic bidi starting with ltr (DOM)', () { const Rect bounds = Rect.fromLTWH(0, 0, 340, 600); - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); const double height = 40; @@ -195,7 +196,7 @@ Future testMain() async { test('basic bidi starting with rtl (DOM)', () { const Rect bounds = Rect.fromLTWH(0, 0, 340, 600); - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); const double height = 40; @@ -303,7 +304,7 @@ Future testMain() async { test('multiline bidi (DOM)', () { const Rect bounds = Rect.fromLTWH(0, 0, 400, 500); - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); const double height = 95; @@ -417,7 +418,7 @@ Future testMain() async { test('multi span bidi (DOM)', () { const Rect bounds = Rect.fromLTWH(0, 0, 400, 900); - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); const double height = 95; @@ -536,7 +537,7 @@ Future testMain() async { test('bidi with selection (DOM)', () { const Rect bounds = Rect.fromLTWH(0, 0, 400, 500); - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); const double height = 95; diff --git a/lib/web_ui/test/html/paragraph/general_golden_test.dart b/lib/web_ui/test/html/paragraph/general_golden_test.dart index 261c452a075ac..527a8c980624d 100644 --- a/lib/web_ui/test/html/paragraph/general_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/general_golden_test.dart @@ -114,7 +114,7 @@ Future testMain() async { }); test('respects alignment in DOM mode', () { - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); Offset offset = Offset.zero; CanvasParagraph paragraph; @@ -192,7 +192,7 @@ Future testMain() async { }); test('alignment and transform (DOM)', () { - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); testAlignAndTransform(canvas); return takeScreenshot(canvas, bounds, 'canvas_paragraph_align_transform_dom'); }); @@ -221,7 +221,7 @@ Future testMain() async { test('giant paragraph style (DOM)', () { const Rect bounds = Rect.fromLTWH(0, 0, 300, 200); - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); testGiantParagraphStyles(canvas); return takeScreenshot(canvas, bounds, 'canvas_paragraph_giant_paragraph_style_dom'); }); @@ -233,7 +233,7 @@ Future testMain() async { final String oldBodyFontSize = html.document.body!.style.fontSize; html.document.body!.style.fontSize = '100px'; - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); Offset offset = const Offset(10.0, 10.0); final CanvasParagraph paragraph = rich( @@ -462,7 +462,7 @@ Future testMain() async { test('font features (DOM)', () { const Rect bounds = Rect.fromLTWH(0, 0, 600, 500); - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); testFontFeatures(canvas); return takeScreenshot(canvas, bounds, 'canvas_paragraph_font_features_dom'); }); @@ -498,7 +498,7 @@ Future testMain() async { test('background style (DOM)', () { const Rect bounds = Rect.fromLTWH(0, 0, 300, 200); - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); testBackgroundStyle(canvas); return takeScreenshot(canvas, bounds, 'canvas_paragraph_background_style_dom'); }); diff --git a/lib/web_ui/test/html/paragraph/overflow_golden_test.dart b/lib/web_ui/test/html/paragraph/overflow_golden_test.dart index a948f53a4b59e..44ab8d2915456 100644 --- a/lib/web_ui/test/html/paragraph/overflow_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/overflow_golden_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:html' as html; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; @@ -115,7 +116,7 @@ Future testMain() async { test('ellipsis (dom)', () { const Rect bounds = Rect.fromLTWH(0, 0, 300, 300); - final EngineCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final EngineCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); testEllipsis(canvas); return takeScreenshot(canvas, bounds, 'canvas_paragraph_ellipsis_dom'); }); diff --git a/lib/web_ui/test/html/paragraph/placeholders_golden_test.dart b/lib/web_ui/test/html/paragraph/placeholders_golden_test.dart index f8d1ae1c1a065..4118621a6ec6a 100644 --- a/lib/web_ui/test/html/paragraph/placeholders_golden_test.dart +++ b/lib/web_ui/test/html/paragraph/placeholders_golden_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:html' as html; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; @@ -92,7 +93,7 @@ Future testMain() async { }); test('draws paragraphs with placeholders and text align in DOM mode', () { - final DomCanvas canvas = DomCanvas(domRenderer.createElement('flt-picture')); + final DomCanvas canvas = DomCanvas(html.document.createElement('flt-picture')); const List aligns = [ TextAlign.left, diff --git a/lib/web_ui/test/html/paragraph/text_scuba.dart b/lib/web_ui/test/html/paragraph/text_scuba.dart index e63718242bf74..6766456f43ffa 100644 --- a/lib/web_ui/test/html/paragraph/text_scuba.dart +++ b/lib/web_ui/test/html/paragraph/text_scuba.dart @@ -98,7 +98,7 @@ void testEachCanvas(String description, CanvasTest body, return body(BitmapCanvas(bounds, RenderStrategy())); }); test('$description (dom)', () { - return body(DomCanvas(domRenderer.createElement('flt-picture'))); + return body(DomCanvas(html.document.createElement('flt-picture'))); }); } diff --git a/lib/web_ui/test/html/shaders/shader_mask_golden_test.dart b/lib/web_ui/test/html/shaders/shader_mask_golden_test.dart index 394d447ac520b..3bc5d9ee07fa3 100644 --- a/lib/web_ui/test/html/shaders/shader_mask_golden_test.dart +++ b/lib/web_ui/test/html/shaders/shader_mask_golden_test.dart @@ -37,7 +37,7 @@ Future testMain() async { debugShowClipLayers = true; SurfaceSceneBuilder.debugForgetFrameScene(); for (final html.Node scene in - domRenderer.sceneHostElement!.querySelectorAll('flt-scene')) { + flutterViewEmbedder.sceneHostElement!.querySelectorAll('flt-scene')) { scene.remove(); } initWebGl(); @@ -162,7 +162,7 @@ void _renderCirclesScene(BlendMode blendMode) { builder.addPicture(Offset.zero, circles2); builder.pop(); - domRenderer.sceneHostElement!.append(builder.build().webOnlyRootElement!); + flutterViewEmbedder.sceneHostElement!.append(builder.build().webOnlyRootElement!); } Picture _drawTestPictureWithText( @@ -218,5 +218,5 @@ void _renderTextScene(BlendMode blendMode) { builder.addPicture(Offset.zero, textPicture2); builder.pop(); - domRenderer.sceneHostElement!.append(builder.build().webOnlyRootElement!); + flutterViewEmbedder.sceneHostElement!.append(builder.build().webOnlyRootElement!); } diff --git a/lib/web_ui/test/matchers.dart b/lib/web_ui/test/matchers.dart index d21407222f469..0d3d2101dbfce 100644 --- a/lib/web_ui/test/matchers.dart +++ b/lib/web_ui/test/matchers.dart @@ -454,7 +454,7 @@ void expectPageHtml(String expectedHtml, /// Currently rendered HTML DOM as an HTML string. String get currentHtml { - return domRenderer.sceneElement?.outerHtml ?? ''; + return flutterViewEmbedder.sceneElement?.outerHtml ?? ''; } class SceneTester { diff --git a/lib/web_ui/test/text/canvas_paragraph_builder_test.dart b/lib/web_ui/test/text/canvas_paragraph_builder_test.dart index a9e5122b90a20..64693293032cb 100644 --- a/lib/web_ui/test/text/canvas_paragraph_builder_test.dart +++ b/lib/web_ui/test/text/canvas_paragraph_builder_test.dart @@ -33,7 +33,7 @@ void main() { } Future testMain() async { - await webOnlyInitializeTestDomRenderer(); + await initializeTestFlutterViewEmbedder(); setUpAll(() { WebExperiments.ensureInitialized(); @@ -408,8 +408,8 @@ Future testMain() async { TextStyle styleWithDefaults({ Color color = const Color(0xFFFF0000), - String fontFamily = DomRenderer.defaultFontFamily, - double fontSize = DomRenderer.defaultFontSize, + String fontFamily = FlutterViewEmbedder.defaultFontFamily, + double fontSize = FlutterViewEmbedder.defaultFontSize, FontWeight? fontWeight, FontStyle? fontStyle, double? height, diff --git a/lib/web_ui/test/text/canvas_paragraph_test.dart b/lib/web_ui/test/text/canvas_paragraph_test.dart index 3649e5c5d01d3..33a74ec71ca22 100644 --- a/lib/web_ui/test/text/canvas_paragraph_test.dart +++ b/lib/web_ui/test/text/canvas_paragraph_test.dart @@ -29,7 +29,7 @@ void main() { } Future testMain() async { - await ui.webOnlyInitializeTestDomRenderer(); + await initializeTestFlutterViewEmbedder(); group('$CanvasParagraph.getBoxesForRange', () { test('return empty list for invalid ranges', () { diff --git a/lib/web_ui/test/text/font_loading_test.dart b/lib/web_ui/test/text/font_loading_test.dart index 26bfdafcb2726..d6795bbb20c1c 100644 --- a/lib/web_ui/test/text/font_loading_test.dart +++ b/lib/web_ui/test/text/font_loading_test.dart @@ -17,7 +17,7 @@ void main() { } Future testMain() async { - await ui.webOnlyInitializeTestDomRenderer(); + await initializeTestFlutterViewEmbedder(); group('loadFontFromList', () { const String _testFontUrl = '/assets/fonts/ahem.ttf'; diff --git a/lib/web_ui/test/text/layout_service_plain_test.dart b/lib/web_ui/test/text/layout_service_plain_test.dart index 4e829eb16cb0d..9cdb9a5b67650 100644 --- a/lib/web_ui/test/text/layout_service_plain_test.dart +++ b/lib/web_ui/test/text/layout_service_plain_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 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; @@ -39,7 +38,7 @@ void main() { } Future testMain() async { - await ui.webOnlyInitializeTestDomRenderer(); + await initializeTestFlutterViewEmbedder(); test('no text', () { final CanvasParagraph paragraph = CanvasParagraphBuilder(ahemStyle).build(); diff --git a/lib/web_ui/test/text/layout_service_rich_test.dart b/lib/web_ui/test/text/layout_service_rich_test.dart index e022830908d84..28d50bc784de8 100644 --- a/lib/web_ui/test/text/layout_service_rich_test.dart +++ b/lib/web_ui/test/text/layout_service_rich_test.dart @@ -27,7 +27,7 @@ void main() { } Future testMain() async { - await ui.webOnlyInitializeTestDomRenderer(); + await initializeTestFlutterViewEmbedder(); test('does not crash on empty spans', () { final CanvasParagraph paragraph = rich(ahemStyle, (CanvasParagraphBuilder builder) { diff --git a/lib/web_ui/test/text_editing_test.dart b/lib/web_ui/test/text_editing_test.dart index dc4b67fa6eb62..ee935a3d8d1fc 100644 --- a/lib/web_ui/test/text_editing_test.dart +++ b/lib/web_ui/test/text_editing_test.dart @@ -10,7 +10,7 @@ import 'dart:typed_data'; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; -import 'package:ui/src/engine.dart' show domRenderer; +import 'package:ui/src/engine.dart' show flutterViewEmbedder; import 'package:ui/src/engine/browser_detection.dart'; import 'package:ui/src/engine/services.dart'; import 'package:ui/src/engine/text_editing/autofill_hint.dart'; @@ -76,7 +76,7 @@ void testMain() { testTextEditing.debugTextEditingStrategyOverride = editingStrategy; testTextEditing.configuration = singlelineConfig; // Ensure the glass-pane and its shadow root exist. - domRenderer.reset(); + flutterViewEmbedder.reset(); }); test('Creates element when enabled and removes it when disabled', () { @@ -101,7 +101,7 @@ void testMain() { final Element input = defaultTextEditingRoot.querySelector('input')!; // Now the editing element should have focus. - expect(document.activeElement, domRenderer.glassPaneElement); + expect(document.activeElement, flutterViewEmbedder.glassPaneElement); expect(defaultTextEditingRoot.activeElement, input); expect(editingStrategy!.domElement, input); diff --git a/lib/web_ui/test/text_test.dart b/lib/web_ui/test/text_test.dart index d51fb80fa6197..028ede8b2142d 100644 --- a/lib/web_ui/test/text_test.dart +++ b/lib/web_ui/test/text_test.dart @@ -20,7 +20,7 @@ void main() { Future testMain() async { const double baselineRatio = 1.1662499904632568; - await webOnlyInitializeTestDomRenderer(); + await initializeTestFlutterViewEmbedder(); late String fallback; setUp(() {