Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c5ad34c

Browse files
committed
[web] move useful utilities out DomRenderer
1 parent e90ef8b commit c5ad34c

21 files changed

+154
-229
lines changed

lib/web_ui/lib/src/engine/canvas_pool.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import 'package:meta/meta.dart';
1111
import 'package:ui/ui.dart' as ui;
1212

1313
import 'browser_detection.dart';
14-
import 'dom_renderer.dart';
1514
import 'engine_canvas.dart';
1615
import 'html/bitmap_canvas.dart';
1716
import 'html/painting.dart';
@@ -751,7 +750,7 @@ class CanvasPool extends _SaveStackTracking {
751750
rect.center.dx - shaderBounds.left;
752751
final double cy = shaderBounds == null ? rect.center.dy :
753752
rect.center.dy - shaderBounds.top;
754-
DomRenderer.ellipse(context, cx, cy, rect.width / 2,
753+
drawEllipse(context, cx, cy, rect.width / 2,
755754
rect.height / 2, 0, 0, 2.0 * math.pi, false);
756755
contextHandle.paint(style);
757756
}
@@ -762,7 +761,7 @@ class CanvasPool extends _SaveStackTracking {
762761
final ui.Rect? shaderBounds = contextHandle._shaderBounds;
763762
final double cx = shaderBounds == null ? c.dx : c.dx - shaderBounds.left;
764763
final double cy = shaderBounds == null ? c.dy : c.dy - shaderBounds.top;
765-
DomRenderer.ellipse(context, cx, cy, radius, radius, 0, 0, 2.0 * math.pi, false);
764+
drawEllipse(context, cx, cy, radius, radius, 0, 0, 2.0 * math.pi, false);
766765
contextHandle.paint(style);
767766
}
768767

lib/web_ui/lib/src/engine/dom_renderer.dart

Lines changed: 7 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ import 'window.dart';
2323

2424
class DomRenderer {
2525
DomRenderer() {
26-
if (assertionsEnabled) {
27-
_debugFrameStatistics = DebugDomRendererFrameStatistics();
28-
}
29-
3026
reset();
3127

3228
assert(() {
@@ -35,12 +31,6 @@ class DomRenderer {
3531
}());
3632
}
3733

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-
4434
// The tag name for the root view of the flutter app (glass-pane)
4535
static const String _glassPaneTagName = 'flt-glass-pane';
4636

@@ -175,52 +165,6 @@ class DomRenderer {
175165

176166
final html.Element rootElement = html.document.body!;
177167

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-
224168
static const String defaultFontStyle = 'normal';
225169
static const String defaultFontWeight = 'normal';
226170
static const double defaultFontSize = 14;
@@ -313,7 +257,7 @@ class DomRenderer {
313257
// IMPORTANT: the glass pane element must come after the scene element in the DOM node list so
314258
// it can intercept input events.
315259
_glassPaneElement?.remove();
316-
final html.Element glassPaneElement = createElement(_glassPaneTagName);
260+
final html.Element glassPaneElement = html.document.createElement(_glassPaneTagName);
317261
_glassPaneElement = glassPaneElement;
318262
glassPaneElement.style
319263
..position = 'absolute'
@@ -331,11 +275,11 @@ class DomRenderer {
331275
_glassPaneShadow = glassPaneElementHostNode;
332276

333277
// Don't allow the scene to receive pointer events.
334-
_sceneHostElement = createElement('flt-scene-host')
278+
_sceneHostElement = html.document.createElement('flt-scene-host')
335279
..style.pointerEvents = 'none';
336280

337281
final html.Element semanticsHostElement =
338-
createElement('flt-semantics-host');
282+
html.document.createElement('flt-semantics-host');
339283
semanticsHostElement.style
340284
..position = 'absolute'
341285
..transformOrigin = '0 0 0';
@@ -463,34 +407,6 @@ class DomRenderer {
463407
}
464408
}
465409

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-
494410
static const String orientationLockTypeAny = 'any';
495411
static const String orientationLockTypeNatural = 'natural';
496412
static const String orientationLockTypeLandscape = 'landscape';
@@ -596,36 +512,14 @@ class DomRenderer {
596512

597513
/// Removes a global resource element.
598514
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]);
515+
if (element == null) {
516+
return;
608517
}
518+
assert(element.parent == _resourcesHost);
519+
element.remove();
609520
}
610521

611522
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++;
629523
}
630524

631525
// Applies the required global CSS to an incoming [html.CssStyleSheet] `sheet`.
@@ -752,45 +646,6 @@ void applyGlobalCssRulesToSheet(
752646
}
753647
}
754648

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-
794649
/// Singleton DOM renderer.
795650
DomRenderer get domRenderer => ensureDomRendererInitialized();
796651

lib/web_ui/lib/src/engine/html/backdrop_filter.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import 'dart:html' as html;
77
import 'package:ui/ui.dart' as ui;
88

99
import '../browser_detection.dart';
10-
import '../dom_renderer.dart';
1110
import '../util.dart';
1211
import '../vector_math.dart';
1312
import 'shaders/shader.dart';
@@ -122,10 +121,10 @@ class PersistedBackdropFilter extends PersistedContainerSurface
122121
// Gaussian blur with standard deviation (normal distribution),
123122
// the blur will fall within 2 * sigma pixels.
124123
if (browserEngine == BrowserEngine.webkit) {
125-
DomRenderer.setElementStyle(_filterElement!, '-webkit-backdrop-filter',
124+
setElementStyle(_filterElement!, '-webkit-backdrop-filter',
126125
filter.filterAttribute);
127126
}
128-
DomRenderer.setElementStyle(_filterElement!, 'backdrop-filter', filter.filterAttribute);
127+
setElementStyle(_filterElement!, 'backdrop-filter', filter.filterAttribute);
129128
}
130129
}
131130

lib/web_ui/lib/src/engine/html/clip.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import 'dart:svg' as svg;
77

88
import 'package:ui/ui.dart' as ui;
99

10-
import '../dom_renderer.dart';
1110
import '../shadow.dart';
1211
import '../util.dart';
1312
import 'dom_canvas.dart';
@@ -363,7 +362,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
363362
_clipElement = svgClipPath;
364363
rootElement!.append(_clipElement!);
365364
if (elevation == 0.0) {
366-
DomRenderer.setClipPath(rootElement!, createSvgClipUrl());
365+
setClipPath(rootElement!, createSvgClipUrl());
367366
final html.CssStyleDeclaration rootElementStyle = rootElement!.style;
368367
rootElementStyle
369368
..overflow = ''
@@ -378,7 +377,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
378377
return;
379378
}
380379

381-
DomRenderer.setClipPath(childContainer!, createSvgClipUrl());
380+
setClipPath(childContainer!, createSvgClipUrl());
382381
final html.CssStyleDeclaration rootElementStyle = rootElement!.style;
383382
rootElementStyle
384383
..overflow = ''
@@ -438,7 +437,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
438437
_svgElement = null;
439438
// Reset style on prior element since we may have switched between
440439
// rect/rrect and arbitrary path.
441-
DomRenderer.setClipPath(rootElement!, '');
440+
setClipPath(rootElement!, '');
442441
_applyShape();
443442
} else {
444443
// Reuse clipElement from prior surface.
@@ -518,7 +517,7 @@ svg.SvgSvgElement createSvgClipDef(html.HtmlElement element, ui.Path clipPath) {
518517
final ui.Rect pathBounds = clipPath.getBounds();
519518
final svg.SvgSvgElement svgClipPath = pathToSvgClipPath(clipPath,
520519
scaleX: 1.0 / pathBounds.right, scaleY: 1.0 / pathBounds.bottom);
521-
DomRenderer.setClipPath(element, createSvgClipUrl());
520+
setClipPath(element, createSvgClipUrl());
522521
// We need to set width and height for the clipElement to cover the
523522
// bounds of the path since browsers such as Safari and Edge
524523
// seem to incorrectly intersect the element bounding rect with

lib/web_ui/lib/src/engine/html/dom_canvas.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ html.HtmlElement buildDrawRectElement(
165165
ui.Rect rect, SurfacePaintData paint, String tagName, Matrix4 transform) {
166166
assert(paint.shader == null);
167167
final html.HtmlElement rectangle =
168-
domRenderer.createElement(tagName) as html.HtmlElement;
168+
html.document.createElement(tagName) as html.HtmlElement;
169169
assert(() {
170170
rectangle.setAttribute('flt-rect', '$rect');
171171
rectangle.setAttribute('flt-paint', '$paint');

lib/web_ui/lib/src/engine/html/offset.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'dart:html' as html;
66

77
import 'package:ui/ui.dart' as ui;
88

9-
import '../dom_renderer.dart';
9+
import '../util.dart';
1010
import '../vector_math.dart';
1111
import 'surface.dart';
1212

@@ -42,8 +42,8 @@ class PersistedOffset extends PersistedContainerSurface
4242
@override
4343
html.Element createElement() {
4444
final html.Element element = html.document.createElement('flt-offset');
45-
DomRenderer.setElementStyle(element, 'position', 'absolute');
46-
DomRenderer.setElementStyle(element, 'transform-origin', '0 0 0');
45+
setElementStyle(element, 'position', 'absolute');
46+
setElementStyle(element, 'transform-origin', '0 0 0');
4747
return element;
4848
}
4949

lib/web_ui/lib/src/engine/html/opacity.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'dart:html' as html;
66

77
import 'package:ui/ui.dart' as ui;
88

9-
import '../dom_renderer.dart';
9+
import '../util.dart';
1010
import '../vector_math.dart';
1111
import 'surface.dart';
1212

@@ -43,16 +43,16 @@ class PersistedOpacity extends PersistedContainerSurface
4343

4444
@override
4545
html.Element createElement() {
46-
final html.Element element = domRenderer.createElement('flt-opacity');
47-
DomRenderer.setElementStyle(element, 'position', 'absolute');
48-
DomRenderer.setElementStyle(element, 'transform-origin', '0 0 0');
46+
final html.Element element = html.document.createElement('flt-opacity');
47+
setElementStyle(element, 'position', 'absolute');
48+
setElementStyle(element, 'transform-origin', '0 0 0');
4949
return element;
5050
}
5151

5252
@override
5353
void apply() {
5454
final html.Element element = rootElement!;
55-
DomRenderer.setElementStyle(element, 'opacity', '${alpha / 255}');
55+
setElementStyle(element, 'opacity', '${alpha / 255}');
5656
element.style.transform = 'translate(${offset.dx}px, ${offset.dy}px)';
5757
}
5858

lib/web_ui/lib/src/engine/html/transform.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import 'dart:typed_data';
77

88
import 'package:ui/ui.dart' as ui;
99

10-
import '../dom_renderer.dart';
1110
import '../util.dart';
1211
import '../vector_math.dart';
1312
import 'surface.dart';
@@ -43,9 +42,9 @@ class PersistedTransform extends PersistedContainerSurface
4342

4443
@override
4544
html.Element createElement() {
46-
final html.Element element = domRenderer.createElement('flt-transform');
47-
DomRenderer.setElementStyle(element, 'position', 'absolute');
48-
DomRenderer.setElementStyle(element, 'transform-origin', '0 0 0');
45+
final html.Element element = html.document.createElement('flt-transform');
46+
setElementStyle(element, 'position', 'absolute');
47+
setElementStyle(element, 'transform-origin', '0 0 0');
4948
return element;
5049
}
5150

0 commit comments

Comments
 (0)