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

Commit 2b2bc95

Browse files
committed
[web] Migrate Flutter Web DOM usage to JS static interop - 17.
1 parent 77b3253 commit 2b2bc95

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+197
-195
lines changed

lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,15 +261,15 @@ class HtmlViewEmbedder {
261261
DomElement headClipView,
262262
) {
263263
int indexInFlutterView = -1;
264-
if (headClipView.parentElement != null) {
264+
if (headClipView.parent != null) {
265265
indexInFlutterView = skiaSceneHost!.children.indexOf(headClipView);
266266
headClipView.remove();
267267
}
268268
DomElement head = platformView;
269269
int clipIndex = 0;
270270
// Re-use as much existing clip views as needed.
271271
while (head != headClipView && clipIndex < numClips) {
272-
head = head.parentElement!;
272+
head = head.parent!;
273273
clipIndex++;
274274
}
275275
// If there weren't enough existing clip views, add more.
@@ -329,7 +329,7 @@ class HtmlViewEmbedder {
329329
case MutatorType.clipRect:
330330
case MutatorType.clipRRect:
331331
case MutatorType.clipPath:
332-
final DomElement clipView = head.parentElement!;
332+
final DomElement clipView = head.parent!;
333333
clipView.style.clip = '';
334334
clipView.style.clipPath = '';
335335
headTransform = Matrix4.identity();

lib/web_ui/lib/src/engine/dom.dart

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class DomWindow {}
2424

2525
extension DomWindowExtension on DomWindow {
2626
external DomConsole get console;
27+
external num get devicePixelRatio;
2728
external DomDocument get document;
2829
external int? get innerHeight;
2930
external int? get innerWidth;
@@ -134,8 +135,12 @@ extension DomProgressEventExtension on DomProgressEvent {
134135
class DomNode extends DomEventTarget {}
135136

136137
extension DomNodeExtension on DomNode {
138+
external DomNode? get firstChild;
139+
external String get innerText;
140+
external DomNode? get lastChild;
137141
external DomNode appendChild(DomNode node);
138-
external DomElement? get parentElement;
142+
DomElement? get parent => js_util.getProperty(this, 'parentElement');
143+
String? get text => js_util.getProperty(this, 'textContent');
139144
external DomNode? get parentNode;
140145
external DomNode insertBefore(DomNode newNode, DomNode? referenceNode);
141146
void remove() {
@@ -219,6 +224,18 @@ extension DomCSSStyleDeclarationExtension on DomCSSStyleDeclaration {
219224
set fontVariationSettings(String value) =>
220225
setProperty('font-variation-settings', value, '');
221226
set visibility(String value) => setProperty('visibility', value, '');
227+
set overflow(String value) => setProperty('overflow', value, '');
228+
set boxShadow(String value) => setProperty('box-shadow', value, '');
229+
set borderTopLeftRadius(String value) =>
230+
setProperty('border-top-left-radius', value, '');
231+
set borderTopRightRadius(String value) =>
232+
setProperty('border-top-right-radius', value, '');
233+
set borderBottomLeftRadius(String value) =>
234+
setProperty('border-bottom-left-radius', value, '');
235+
set borderBottomRightRadius(String value) =>
236+
setProperty('border-bottom-right-radius', value, '');
237+
set borderRadius(String value) => setProperty('border-radius', value, '');
238+
set perspective(String value) => setProperty('perspective', value, '');
222239
String get width => getPropertyValue('width');
223240
String get height => getPropertyValue('height');
224241
String get position => getPropertyValue('position');
@@ -251,6 +268,17 @@ extension DomCSSStyleDeclarationExtension on DomCSSStyleDeclaration {
251268
String get fontVariationSettings =>
252269
getPropertyValue('font-variation-settings');
253270
String get visibility => getPropertyValue('visibility');
271+
String get overflow => getPropertyValue('overflow');
272+
String get boxShadow => getPropertyValue('box-shadow');
273+
String get borderTopLeftRadius => getPropertyValue('border-top-left-radius');
274+
String get borderTopRightRadius =>
275+
getPropertyValue('border-top-right-radius');
276+
String get borderBottomLeftRadius =>
277+
getPropertyValue('border-bottom-left-radius');
278+
String get borderBottomRightRadius =>
279+
getPropertyValue('border-bottom-right-radius');
280+
String get borderRadius => getPropertyValue('border-radius');
281+
String get perspective => getPropertyValue('perspective');
254282

255283
external String getPropertyValue(String property);
256284
void setProperty(String propertyName, String value, [String? priority]) {

lib/web_ui/lib/src/engine/engine_canvas.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import 'vector_math.dart';
2323
/// This can be used either as an interface or super-class.
2424
abstract class EngineCanvas {
2525
/// The element that is attached to the DOM.
26-
html.Element get rootElement;
26+
DomElement get rootElement;
2727

2828
void dispose() {
2929
clear();
@@ -296,7 +296,7 @@ mixin SaveElementStackTracking on EngineCanvas {
296296
/// The element at the top of the element stack, or [rootElement] if the stack
297297
/// is empty.
298298
html.Element get currentElement =>
299-
_elementStack.isEmpty ? rootElement : _elementStack.last;
299+
_elementStack.isEmpty ? rootElement as html.Element : _elementStack.last;
300300

301301
/// The stack that maintains the DOM elements used to express certain paint
302302
/// operations, such as clips.

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

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class BitmapCanvas extends EngineCanvas {
5858
static const int kPaddingPixels = 1;
5959

6060
@override
61-
final html.Element rootElement = html.Element.tag('flt-canvas');
61+
final DomElement rootElement = createDomElement('flt-canvas');
6262

6363
final CanvasPool _canvasPool;
6464

@@ -239,7 +239,7 @@ class BitmapCanvas extends EngineCanvas {
239239
for (int i = 0; i < len; i++) {
240240
final html.Element child = _children[i];
241241
// Don't remove children that have been reused by CrossFrameCache.
242-
if (child.parent == rootElement) {
242+
if (child.parent == rootElement as html.Element) {
243243
child.remove();
244244
}
245245
}
@@ -458,11 +458,11 @@ class BitmapCanvas extends EngineCanvas {
458458
ui.Offset.zero,
459459
transformWithOffset(_canvasPool.currentTransform, offset));
460460
for (final html.Element clipElement in clipElements) {
461-
rootElement.append(clipElement);
461+
rootElement.append(clipElement as DomElement);
462462
_children.add(clipElement);
463463
}
464464
} else {
465-
rootElement.append(element);
465+
rootElement.append(element as DomElement);
466466
_children.add(element);
467467
}
468468
final ui.BlendMode? blendMode = paint.blendMode;
@@ -675,7 +675,7 @@ class BitmapCanvas extends EngineCanvas {
675675
final List<html.Element> clipElements = _clipContent(
676676
_canvasPool.clipStack!, imgElement, p, _canvasPool.currentTransform);
677677
for (final html.Element clipElement in clipElements) {
678-
rootElement.append(clipElement);
678+
rootElement.append(clipElement as DomElement);
679679
_children.add(clipElement);
680680
}
681681
} else {
@@ -687,7 +687,7 @@ class BitmapCanvas extends EngineCanvas {
687687
// Reset width/height since they may have been previously set.
688688
..removeProperty('width')
689689
..removeProperty('height');
690-
rootElement.append(imgElement);
690+
rootElement.append(imgElement as DomElement);
691691
_children.add(imgElement);
692692
}
693693
return imgElement;
@@ -851,7 +851,7 @@ class BitmapCanvas extends EngineCanvas {
851851
SurfacePaintData paint) {
852852
// For srcIn blendMode, we use an svg filter to apply to image element.
853853
final SvgFilter svgFilter = svgFilterFromBlendMode(filterColor, colorFilterBlendMode);
854-
rootElement.append(svgFilter.element);
854+
rootElement.append(svgFilter.element as DomElement);
855855
_children.add(svgFilter.element);
856856
final html.HtmlElement imgElement = _reuseOrCreateImage(image);
857857
imgElement.style.filter = 'url(#${svgFilter.id})';
@@ -866,7 +866,7 @@ class BitmapCanvas extends EngineCanvas {
866866
HtmlImage image, List<double> matrix, SurfacePaintData paint) {
867867
// For srcIn blendMode, we use an svg filter to apply to image element.
868868
final SvgFilter svgFilter = svgFilterFromColorMatrix(matrix);
869-
rootElement.append(svgFilter.element);
869+
rootElement.append(svgFilter.element as DomElement);
870870
_children.add(svgFilter.element);
871871
final html.HtmlElement imgElement = _reuseOrCreateImage(image);
872872
imgElement.style.filter = 'url(#${svgFilter.id})';
@@ -971,15 +971,15 @@ class BitmapCanvas extends EngineCanvas {
971971
offset,
972972
_canvasPool.currentTransform);
973973
for (final html.Element clipElement in clipElements) {
974-
rootElement.append(clipElement);
974+
rootElement.append(clipElement as DomElement);
975975
_children.add(clipElement);
976976
}
977977
} else {
978978
setElementTransform(
979979
paragraphElement,
980980
transformWithOffset(_canvasPool.currentTransform, offset).storage,
981981
);
982-
rootElement.append(paragraphElement);
982+
rootElement.append(paragraphElement as DomElement);
983983
}
984984
_children.add(paragraphElement);
985985
// If there is a prior sibling such as img prevent left/top shift.
@@ -1070,19 +1070,22 @@ class BitmapCanvas extends EngineCanvas {
10701070
_elementCache?.commitFrame();
10711071
// Wrap all elements in translate3d (workaround for webkit paint order bug).
10721072
if (_contains3dTransform && browserEngine == BrowserEngine.webkit) {
1073-
for (final html.Element element in rootElement.children) {
1074-
final html.DivElement paintOrderElement = html.DivElement()
1073+
for (final DomElement element in rootElement.children) {
1074+
final DomHTMLDivElement paintOrderElement = createDomHTMLDivElement()
10751075
..style.transform = 'translate3d(0,0,0)';
10761076
paintOrderElement.append(element);
10771077
rootElement.append(paintOrderElement);
1078-
_children.add(paintOrderElement);
1078+
_children.add(paintOrderElement as html.Element);
10791079
}
10801080
}
1081-
final html.Node? firstChild = rootElement.firstChild;
1082-
if (firstChild != null && firstChild is html.HtmlElement &&
1083-
firstChild.tagName.toLowerCase() ==
1084-
'canvas') {
1085-
firstChild.style.zIndex = '-1';
1081+
final DomNode? firstChild = rootElement.firstChild;
1082+
if (firstChild != null) {
1083+
if (domInstanceOfString(firstChild, 'HTMLElement')) {
1084+
final DomHTMLElement maybeCanvas = firstChild as DomHTMLElement;
1085+
if (maybeCanvas.tagName.toLowerCase() == 'canvas') {
1086+
maybeCanvas.style.zIndex = '-1';
1087+
}
1088+
}
10861089
}
10871090
}
10881091

@@ -1368,7 +1371,7 @@ List<html.Element> _clipContent(List<SaveClipEntry> clipStack,
13681371
final SaveClipEntry entry = clipStack[clipIndex];
13691372
final html.HtmlElement newElement = html.DivElement();
13701373
newElement.style.position = 'absolute';
1371-
applyWebkitClipFix(newElement);
1374+
applyWebkitClipFix(newElement as DomElement);
13721375
if (root == null) {
13731376
root = newElement;
13741377
} else {

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ mixin _DomClip on PersistedContainerSurface {
5959
_childContainer = null;
6060
}
6161

62-
void applyOverflow(html.Element element, ui.Clip? clipBehaviour) {
62+
void applyOverflow(DomElement element, ui.Clip? clipBehaviour) {
6363
if (!debugShowClipLayers) {
6464
// Hide overflow in production mode. When debugging we want to see the
6565
// clipped picture in full.
@@ -161,7 +161,7 @@ class PersistedClipRRect extends PersistedContainerSurface
161161

162162
@override
163163
void apply() {
164-
final html.CssStyleDeclaration style = rootElement!.style;
164+
final DomCSSStyleDeclaration style = rootElement!.style;
165165
style
166166
..left = '${rrect.left}px'
167167
..top = '${rrect.top}px'
@@ -236,7 +236,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
236236
}
237237

238238
void _applyColor() {
239-
rootElement!.style.backgroundColor = colorToCssString(color);
239+
rootElement!.style.backgroundColor = colorToCssString(color)!;
240240
}
241241

242242
@override
@@ -267,7 +267,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
267267
final String borderRadius =
268268
'${roundRect.tlRadiusX}px ${roundRect.trRadiusX}px '
269269
'${roundRect.brRadiusX}px ${roundRect.blRadiusX}px';
270-
final html.CssStyleDeclaration style = rootElement!.style;
270+
final DomCSSStyleDeclaration style = rootElement!.style;
271271
style
272272
..left = '${roundRect.left}px'
273273
..top = '${roundRect.top}px'
@@ -285,7 +285,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
285285
} else {
286286
final ui.Rect? rect = path.toRect();
287287
if (rect != null) {
288-
final html.CssStyleDeclaration style = rootElement!.style;
288+
final DomCSSStyleDeclaration style = rootElement!.style;
289289
style
290290
..left = '${rect.left}px'
291291
..top = '${rect.top}px'
@@ -307,7 +307,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
307307
final double ry = ovalRect.height / 2.0;
308308
final String borderRadius =
309309
rx == ry ? '${rx}px ' : '${rx}px ${ry}px ';
310-
final html.CssStyleDeclaration style = rootElement!.style;
310+
final DomCSSStyleDeclaration style = rootElement!.style;
311311
final double left = ovalRect.left;
312312
final double top = ovalRect.top;
313313
style
@@ -362,10 +362,10 @@ class PersistedPhysicalShape extends PersistedContainerSurface
362362
_clipElement?.remove();
363363
_svgElement?.remove();
364364
_clipElement = svgClipPath;
365-
rootElement!.append(_clipElement!);
365+
rootElement!.append(_clipElement! as DomElement);
366366
if (elevation == 0.0) {
367-
setClipPath(rootElement! as DomElement, createSvgClipUrl());
368-
final html.CssStyleDeclaration rootElementStyle = rootElement!.style;
367+
setClipPath(rootElement!, createSvgClipUrl());
368+
final DomCSSStyleDeclaration rootElementStyle = rootElement!.style;
369369
rootElementStyle
370370
..overflow = ''
371371
..left = '${pathBounds.left}px'
@@ -380,7 +380,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
380380
}
381381

382382
setClipPath(childContainer!, createSvgClipUrl());
383-
final html.CssStyleDeclaration rootElementStyle = rootElement!.style;
383+
final DomCSSStyleDeclaration rootElementStyle = rootElement!.style;
384384
rootElementStyle
385385
..overflow = ''
386386
..left = '${pathBounds.left}px'
@@ -404,7 +404,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
404404
'${pathBounds2.bottom}');
405405

406406
/// Render element behind the clipped content.
407-
rootElement!.insertBefore(_svgElement!, childContainer as html.Node?);
407+
rootElement!.insertBefore(_svgElement! as DomElement, childContainer);
408408

409409
final SurfaceShadowData shadow = computeShadow(pathBounds, elevation)!;
410410
final ui.Color boxShadowColor = toShadowColor(shadowColor);
@@ -439,18 +439,18 @@ class PersistedPhysicalShape extends PersistedContainerSurface
439439
_svgElement = null;
440440
// Reset style on prior element since we may have switched between
441441
// rect/rrect and arbitrary path.
442-
setClipPath(rootElement! as DomElement, '');
442+
setClipPath(rootElement!, '');
443443
_applyShape();
444444
} else {
445445
// Reuse clipElement from prior surface.
446446
_clipElement = oldSurface._clipElement;
447447
if (_clipElement != null) {
448-
rootElement!.append(_clipElement!);
448+
rootElement!.append(_clipElement! as DomElement);
449449
}
450450
oldSurface._clipElement = null;
451451
_svgElement = oldSurface._svgElement;
452452
if (_svgElement != null) {
453-
rootElement!.insertBefore(_svgElement!, childContainer as html.Node?);
453+
rootElement!.insertBefore(_svgElement! as DomElement, childContainer);
454454
}
455455
oldSurface._svgElement = null;
456456
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'dart:typed_data';
1010
import 'package:ui/ui.dart' as ui;
1111

1212
import '../browser_detection.dart';
13+
import '../dom.dart';
1314
import '../engine_canvas.dart';
1415
import '../text/canvas_paragraph.dart';
1516
import '../util.dart';
@@ -23,7 +24,7 @@ import 'shaders/shader.dart';
2324
/// A canvas that renders to DOM elements and CSS properties.
2425
class DomCanvas extends EngineCanvas with SaveElementStackTracking {
2526
@override
26-
final html.Element rootElement;
27+
final DomElement rootElement;
2728

2829
DomCanvas(this.rootElement);
2930

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class PersistedOpacity extends PersistedContainerSurface
5050

5151
@override
5252
void apply() {
53-
final DomElement element = rootElement! as DomElement;
53+
final DomElement element = rootElement!;
5454
setElementStyle(element, 'opacity', '${alpha / 255}');
5555
element.style.transform = 'translate(${offset.dx}px, ${offset.dy}px)';
5656
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'dart:html' as html;
56
import 'dart:typed_data';
67

78
import 'package:ui/ui.dart' as ui;
89

910
import '../../engine.dart' show kProfileApplyFrame, kProfilePrerollFrame;
11+
import '../dom.dart';
1012
import '../picture.dart';
1113
import '../profiler.dart';
1214
import '../util.dart';
@@ -563,7 +565,7 @@ class SurfaceSceneBuilder implements ui.SceneBuilder {
563565
}
564566
commitScene(_persistedScene);
565567
_lastFrameScene = _persistedScene;
566-
return SurfaceScene(_persistedScene.rootElement);
568+
return SurfaceScene(_persistedScene.rootElement as html.Element?);
567569
});
568570
}
569571

0 commit comments

Comments
 (0)