@@ -21,26 +21,29 @@ import 'text_editing/text_editing.dart';
2121import 'util.dart' ;
2222import 'window.dart' ;
2323
24- class DomRenderer {
25- DomRenderer () {
26- if (assertionsEnabled) {
27- _debugFrameStatistics = DebugDomRendererFrameStatistics ();
28- }
29-
24+ /// Controls the placement and lifecycle of a Flutter view on the web page.
25+ ///
26+ /// Manages several top-level elements that host Flutter-generated content,
27+ /// including:
28+ ///
29+ /// - [glassPaneElement] , the root element of a Flutter view.
30+ /// - [glassPaneShadow] , the shadow root used to isolate Flutter-rendered
31+ /// content from the surrounding page content, including from the platform
32+ /// views.
33+ /// - [sceneElement] , the element that hosts Flutter layers and pictures, and
34+ /// projects platform views.
35+ /// - [sceneHostElement] , the anchor that provides a stable location in the DOM
36+ /// tree for the [sceneElement] .
37+ /// - [semanticsHostElement] , hosts the ARIA-annotated semantics tree.
38+ class FlutterViewEmbedder {
39+ FlutterViewEmbedder () {
3040 reset ();
31-
3241 assert (() {
3342 _setupHotRestart ();
3443 return true ;
3544 }());
3645 }
3746
38- static const int vibrateLongPress = 50 ;
39- static const int vibrateLightImpact = 10 ;
40- static const int vibrateMediumImpact = 20 ;
41- static const int vibrateHeavyImpact = 30 ;
42- static const int vibrateSelectionClick = 10 ;
43-
4447 // The tag name for the root view of the flutter app (glass-pane)
4548 static const String _glassPaneTagName = 'flt-glass-pane' ;
4649
@@ -175,52 +178,6 @@ class DomRenderer {
175178
176179 final html.Element rootElement = html.document.body! ;
177180
178- html.Element createElement (String tagName, {html.Element ? parent}) {
179- final html.Element element = html.document.createElement (tagName);
180- parent? .append (element);
181- return element;
182- }
183-
184- void appendText (html.Element parent, String text) {
185- parent.appendText (text);
186- }
187-
188- static void setElementStyle (
189- html.Element element, String name, String ? value) {
190- if (value == null ) {
191- element.style.removeProperty (name);
192- } else {
193- element.style.setProperty (name, value);
194- }
195- }
196-
197- static void setClipPath (html.Element element, String ? value) {
198- if (browserEngine == BrowserEngine .webkit) {
199- if (value == null ) {
200- element.style.removeProperty ('-webkit-clip-path' );
201- } else {
202- element.style.setProperty ('-webkit-clip-path' , value);
203- }
204- }
205- if (value == null ) {
206- element.style.removeProperty ('clip-path' );
207- } else {
208- element.style.setProperty ('clip-path' , value);
209- }
210- }
211-
212- void setThemeColor (ui.Color color) {
213- html.MetaElement ? theme =
214- html.document.querySelector ('#flutterweb-theme' ) as html.MetaElement ? ;
215- if (theme == null ) {
216- theme = html.MetaElement ()
217- ..id = 'flutterweb-theme'
218- ..name = 'theme-color' ;
219- html.document.head! .append (theme);
220- }
221- theme.content = colorToCssString (color)! ;
222- }
223-
224181 static const String defaultFontStyle = 'normal' ;
225182 static const String defaultFontWeight = 'normal' ;
226183 static const double defaultFontSize = 14 ;
@@ -313,7 +270,7 @@ class DomRenderer {
313270 // IMPORTANT: the glass pane element must come after the scene element in the DOM node list so
314271 // it can intercept input events.
315272 _glassPaneElement? .remove ();
316- final html.Element glassPaneElement = createElement (_glassPaneTagName);
273+ final html.Element glassPaneElement = html.document. createElement (_glassPaneTagName);
317274 _glassPaneElement = glassPaneElement;
318275 glassPaneElement.style
319276 ..position = 'absolute'
@@ -331,11 +288,11 @@ class DomRenderer {
331288 _glassPaneShadow = glassPaneElementHostNode;
332289
333290 // Don't allow the scene to receive pointer events.
334- _sceneHostElement = createElement ('flt-scene-host' )
291+ _sceneHostElement = html.document. createElement ('flt-scene-host' )
335292 ..style.pointerEvents = 'none' ;
336293
337294 final html.Element semanticsHostElement =
338- createElement ('flt-semantics-host' );
295+ html.document. createElement ('flt-semantics-host' );
339296 semanticsHostElement.style
340297 ..position = 'absolute'
341298 ..transformOrigin = '0 0 0' ;
@@ -456,41 +413,6 @@ class DomRenderer {
456413 }
457414 }
458415
459- /// Removes all children of a DOM node.
460- void removeAllChildren (html.Node node) {
461- while (node.lastChild != null ) {
462- node.lastChild! .remove ();
463- }
464- }
465-
466- static bool ? _ellipseFeatureDetected;
467-
468- /// Draws CanvasElement ellipse with fallback.
469- static void ellipse (
470- html.CanvasRenderingContext2D context,
471- double centerX,
472- double centerY,
473- double radiusX,
474- double radiusY,
475- double rotation,
476- double startAngle,
477- double endAngle,
478- bool antiClockwise) {
479- // ignore: implicit_dynamic_function
480- _ellipseFeatureDetected ?? = js_util.getProperty (context, 'ellipse' ) != null ;
481- if (_ellipseFeatureDetected! ) {
482- context.ellipse (centerX, centerY, radiusX, radiusY, rotation, startAngle,
483- endAngle, antiClockwise);
484- } else {
485- context.save ();
486- context.translate (centerX, centerY);
487- context.rotate (rotation);
488- context.scale (radiusX, radiusY);
489- context.arc (0 , 0 , 1 , startAngle, endAngle, antiClockwise);
490- context.restore ();
491- }
492- }
493-
494416 static const String orientationLockTypeAny = 'any' ;
495417 static const String orientationLockTypeNatural = 'natural' ;
496418 static const String orientationLockTypeLandscape = 'landscape' ;
@@ -596,44 +518,22 @@ class DomRenderer {
596518
597519 /// Removes a global resource element.
598520 void removeResource (html.Element ? element) {
599- element? .remove ();
600- }
601-
602- /// Provides haptic feedback.
603- void vibrate (int durationMs) {
604- final html.Navigator navigator = html.window.navigator;
605- if (js_util.hasProperty (navigator, 'vibrate' )) {
606- // ignore: implicit_dynamic_function
607- js_util.callMethod (navigator, 'vibrate' , < num > [durationMs]);
521+ if (element == null ) {
522+ return ;
608523 }
524+ assert (element.parent == _resourcesHost);
525+ element.remove ();
609526 }
610527
611528 String get currentHtml => _rootApplicationElement? .outerHtml ?? '' ;
612-
613- DebugDomRendererFrameStatistics ? _debugFrameStatistics;
614-
615- DebugDomRendererFrameStatistics ? debugFlushFrameStatistics () {
616- if (! assertionsEnabled) {
617- throw Exception ('This code should not be reachable in production.' );
618- }
619- final DebugDomRendererFrameStatistics ? current = _debugFrameStatistics;
620- _debugFrameStatistics = DebugDomRendererFrameStatistics ();
621- return current;
622- }
623-
624- void debugRulerCacheHit () => _debugFrameStatistics! .paragraphRulerCacheHits++ ;
625- void debugRulerCacheMiss () =>
626- _debugFrameStatistics! .paragraphRulerCacheMisses++ ;
627- void debugRichTextLayout () => _debugFrameStatistics! .richTextLayouts++ ;
628- void debugPlainTextLayout () => _debugFrameStatistics! .plainTextLayouts++ ;
629529}
630530
631531// Applies the required global CSS to an incoming [html.CssStyleSheet] `sheet`.
632532void applyGlobalCssRulesToSheet (
633533 html.CssStyleSheet sheet, {
634534 required BrowserEngine browserEngine,
635535 required bool hasAutofillOverlay,
636- String glassPaneTagName = DomRenderer ._glassPaneTagName,
536+ String glassPaneTagName = FlutterViewEmbedder ._glassPaneTagName,
637537}) {
638538 final bool isWebKit = browserEngine == BrowserEngine .webkit;
639539 final bool isFirefox = browserEngine == BrowserEngine .firefox;
@@ -752,48 +652,9 @@ void applyGlobalCssRulesToSheet(
752652 }
753653}
754654
755- /// Miscellaneous statistics collecting during a single frame's execution.
756- ///
757- /// This is useful when profiling the app. This class should only be used when
758- /// assertions are enabled and therefore is not suitable for collecting any
759- /// time measurements. It is mostly useful for counting certain events.
760- class DebugDomRendererFrameStatistics {
761- /// The number of times we reused a previously initialized paragraph ruler to
762- /// measure a paragraph of text.
763- int paragraphRulerCacheHits = 0 ;
764-
765- /// The number of times we had to create a new paragraph ruler to measure a
766- /// paragraph of text.
767- int paragraphRulerCacheMisses = 0 ;
768-
769- /// The number of times we used a paragraph ruler to measure a paragraph of
770- /// text.
771- int get totalParagraphRulerAccesses =>
772- paragraphRulerCacheHits + paragraphRulerCacheMisses;
773-
774- /// The number of times a paragraph of rich text was laid out this frame.
775- int richTextLayouts = 0 ;
776-
777- /// The number of times a paragraph of plain text was laid out this frame.
778- int plainTextLayouts = 0 ;
779-
780- @override
781- String toString () {
782- return '''
783- Frame statistics:
784- Paragraph ruler cache hits: $paragraphRulerCacheHits
785- Paragraph ruler cache misses: $paragraphRulerCacheMisses
786- Paragraph ruler accesses: $totalParagraphRulerAccesses
787- Rich text layouts: $richTextLayouts
788- Plain text layouts: $plainTextLayouts
789- '''
790- .trim ();
791- }
792- }
793-
794- /// Singleton DOM renderer.
795- DomRenderer get domRenderer => ensureDomRendererInitialized ();
655+ /// The embedder singleton.
656+ FlutterViewEmbedder get flutterViewEmbedder => ensureFlutterViewEmbedderInitialized ();
796657
797- /// Initializes the [DomRenderer ] , if it's not already initialized.
798- DomRenderer ensureDomRendererInitialized () => _domRenderer ?? = DomRenderer ();
799- DomRenderer ? _domRenderer ;
658+ /// Initializes the [FlutterViewEmbedder ] , if it's not already initialized.
659+ FlutterViewEmbedder ensureFlutterViewEmbedderInitialized () => _flutterViewEmbedder ?? = FlutterViewEmbedder ();
660+ FlutterViewEmbedder ? _flutterViewEmbedder ;
0 commit comments