Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 5 additions & 57 deletions lib/web_ui/lib/src/engine/dom_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class DomRenderer {
if (sceneElement != _sceneElement) {
_sceneElement?.remove();
_sceneElement = sceneElement;
append(_sceneHostElement!, sceneElement!);
_sceneHostElement!.append(sceneElement!);
}
assert(() {
_clearOnHotRestart();
Expand All @@ -175,40 +175,16 @@ class DomRenderer {

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

void addElementClass(html.Element element, String className) {
element.classes.add(className);
}

html.Element createElement(String tagName, {html.Element? parent}) {
final html.Element element = html.document.createElement(tagName);
parent?.append(element);
return element;
}

void append(html.Element parent, html.Element child) {
parent.append(child);
}

void appendText(html.Element parent, String text) {
parent.appendText(text);
}

void detachElement(html.Element element) {
element.remove();
}

void removeElementClass(html.Element element, String className) {
element.classes.remove(className);
}

void setElementAttribute(html.Element element, String name, String value) {
element.setAttribute(name, value);
}

void setElementProperty(html.Element element, String name, Object value) {
js_util.setProperty(element, name, value);
}

static void setElementStyle(
html.Element element, String name, String? value) {
if (value == null) {
Expand All @@ -233,29 +209,6 @@ class DomRenderer {
}
}

static void setElementTransform(html.Element element, String transformValue) {
js_util.setProperty(
// ignore: implicit_dynamic_function
js_util.getProperty(element, 'style') as Object,
'transform',
transformValue,
);
}

void setText(html.Element element, String text) {
element.text = text;
}

void removeAllChildren(html.Element element) {
element.children.clear();
}

html.Element? getParent(html.Element element) => element.parent;

void setTitle(String title) {
html.document.title = title;
}

void setThemeColor(ui.Color color) {
html.MetaElement? theme =
html.document.querySelector('#flutterweb-theme') as html.MetaElement?;
Expand Down Expand Up @@ -292,12 +245,11 @@ class DomRenderer {

final html.BodyElement bodyElement = html.document.body!;

setElementAttribute(
bodyElement,
bodyElement.setAttribute(
'flt-renderer',
'${useCanvasKit ? 'canvaskit' : 'html'} (${FlutterConfiguration.flutterWebAutoDetect ? 'auto-selected' : 'requested explicitly'})',
);
setElementAttribute(bodyElement, 'flt-build-mode', buildMode);
bodyElement.setAttribute('flt-build-mode', buildMode);

setElementStyle(bodyElement, 'position', 'fixed');
setElementStyle(bodyElement, 'top', '0');
Expand Down Expand Up @@ -412,7 +364,7 @@ class DomRenderer {
// Hide the DOM nodes used to render the scene from accessibility, because
// the accessibility tree is built from the SemanticsNode tree as a parallel
// DOM tree.
setElementAttribute(_sceneHostElement!, 'aria-hidden', 'true');
_sceneHostElement!.setAttribute('aria-hidden', 'true');

if (html.window.visualViewport == null && isWebKit) {
// Older Safari versions sometimes give us bogus innerWidth/innerHeight
Expand Down Expand Up @@ -504,12 +456,8 @@ class DomRenderer {
}
}

void focus(html.Element element) {
element.focus();
}

/// Removes all children of a DOM node.
void clearDom(html.Node node) {
void removeAllChildren(html.Node node) {
while (node.lastChild != null) {
node.lastChild!.remove();
}
Expand Down
5 changes: 2 additions & 3 deletions lib/web_ui/lib/src/engine/html/bitmap_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import '../browser_detection.dart';
import '../canvas_pool.dart';
import '../canvaskit/color_filter.dart';
import '../color_filter.dart';
import '../dom_renderer.dart';
import '../engine_canvas.dart';
import '../frame_reference.dart';
import '../html_image_codec.dart';
Expand Down Expand Up @@ -1354,7 +1353,7 @@ List<html.Element> _clipContent(List<SaveClipEntry> clipStack,
if (root == null) {
root = newElement;
} else {
domRenderer.append(curElement!, newElement);
curElement!.append(newElement);
}
curElement = newElement;
final ui.Rect? rect = entry.rect;
Expand Down Expand Up @@ -1434,7 +1433,7 @@ List<html.Element> _clipContent(List<SaveClipEntry> clipStack,
}

root!.style.position = 'absolute';
domRenderer.append(curElement!, content);
curElement!.append(content);
setElementTransform(
content,
transformWithOffset(currentTransform, offset).storage,
Expand Down
6 changes: 3 additions & 3 deletions lib/web_ui/lib/src/engine/html/clip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
_clipElement?.remove();
_svgElement?.remove();
_clipElement = svgClipPath;
domRenderer.append(rootElement!, _clipElement!);
rootElement!.append(_clipElement!);
if (elevation == 0.0) {
DomRenderer.setClipPath(rootElement!, createSvgClipUrl());
final html.CssStyleDeclaration rootElementStyle = rootElement!.style;
Expand Down Expand Up @@ -444,7 +444,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
// Reuse clipElement from prior surface.
_clipElement = oldSurface._clipElement;
if (_clipElement != null) {
domRenderer.append(rootElement!, _clipElement!);
rootElement!.append(_clipElement!);
}
oldSurface._clipElement = null;
_svgElement = oldSurface._svgElement;
Expand Down Expand Up @@ -486,7 +486,7 @@ class PersistedClipPath extends PersistedContainerSurface
void apply() {
_clipElement?.remove();
_clipElement = createSvgClipDef(childContainer! as html.HtmlElement, clipPath);
domRenderer.append(childContainer!, _clipElement!);
childContainer!.append(_clipElement!);
}

@override
Expand Down
3 changes: 1 addition & 2 deletions lib/web_ui/lib/src/engine/html/dom_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking {
@override
void clear() {
super.clear();
// TODO(yjbanov): we should measure if reusing old elements is beneficial.
domRenderer.clearDom(rootElement);
domRenderer.removeAllChildren(rootElement);
}

@override
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/html/offset.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class PersistedOffset extends PersistedContainerSurface

@override
void apply() {
DomRenderer.setElementTransform(rootElement!, 'translate(${dx}px, ${dy}px)');
rootElement!.style.transform = 'translate(${dx}px, ${dy}px)';
}

@override
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/html/opacity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class PersistedOpacity extends PersistedContainerSurface
void apply() {
final html.Element element = rootElement!;
DomRenderer.setElementStyle(element, 'opacity', '${alpha / 255}');
DomRenderer.setElementTransform(element, 'translate(${offset.dx}px, ${offset.dy}px)');
element.style.transform = 'translate(${offset.dx}px, ${offset.dy}px)';
}

@override
Expand Down
6 changes: 3 additions & 3 deletions lib/web_ui/lib/src/engine/html/picture.dart
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ class PersistedPicture extends PersistedLeafSurface {
oldSurface._canvas = null;
}
if (rootElement != null) {
domRenderer.clearDom(rootElement!);
domRenderer.removeAllChildren(rootElement!);
}
if (_canvas != null && _canvas != oldCanvas) {
_recycleCanvas(_canvas);
Expand Down Expand Up @@ -432,7 +432,7 @@ class PersistedPicture extends PersistedLeafSurface {
_recycleCanvas(_canvas);
final DomCanvas domCanvas = DomCanvas(rootElement!);
_canvas = domCanvas;
domRenderer.clearDom(rootElement!);
domRenderer.removeAllChildren(rootElement!);
picture.recordingCanvas!.apply(domCanvas, _optimalLocalCullRect!);
}

Expand Down Expand Up @@ -473,7 +473,7 @@ class PersistedPicture extends PersistedLeafSurface {
surfaceStatsFor(this).paintPixelCount +=
bitmapCanvas.bitmapPixelCount;
}
domRenderer.clearDom(rootElement!);
domRenderer.removeAllChildren(rootElement!);
rootElement!.append(bitmapCanvas.rootElement);
bitmapCanvas.clear();
picture.recordingCanvas!.apply(bitmapCanvas, _optimalLocalCullRect!);
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
// TODO(ferhat): Find more appropriate defaults? Or noop when values are null?
final String label = arguments['label'] as String? ?? '';
final int primaryColor = arguments['primaryColor'] as int? ?? 0xFF000000;
domRenderer.setTitle(label);
html.document.title = label;
domRenderer.setThemeColor(ui.Color(primaryColor));
replyToPlatformMessage(callback, codec.encodeSuccessEnvelope(true));
return;
Expand Down
7 changes: 3 additions & 4 deletions lib/web_ui/lib/src/engine/text/canvas_paragraph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class CanvasParagraph implements EngineParagraph {
for (int i = 0; i < lines.length; i++) {
// Insert a <BR> element before each line except the first line.
if (i > 0) {
domRenderer.append(element, domRenderer.createElement('br'));
element.append(domRenderer.createElement('br'));
}

final EngineLineMetrics line = lines[i];
Expand Down Expand Up @@ -209,15 +209,14 @@ class CanvasParagraph implements EngineParagraph {
style: box.span.style,
isSpan: true,
);
domRenderer.append(rootElement, element);
rootElement.append(element);
buffer.write(box.toText());
} else if (box is PlaceholderBox) {
span = null;
// If there's a line-end after this placeholder, we want the <BR> to
// be inserted in the root paragraph element.
element = rootElement;
domRenderer.append(
rootElement,
rootElement.append(
createPlaceholderElement(placeholder: box.placeholder),
);
} else {
Expand Down
54 changes: 3 additions & 51 deletions lib/web_ui/test/dom_renderer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,46 +29,6 @@ void testMain() {
expect(element, isNotNull);
});

test('can append children to parents', () {
final DomRenderer renderer = DomRenderer();
final html.Element parent = renderer.createElement('div');
final html.Element child = renderer.createElement('div');
renderer.append(parent, child);
expect(parent.children, hasLength(1));
});

test('can set text on elements', () {
final DomRenderer renderer = DomRenderer();
final html.Element element = renderer.createElement('div');
renderer.setText(element, 'Hello World');
expect(element.text, 'Hello World');
});

test('can set attributes on elements', () {
final DomRenderer renderer = DomRenderer();
final html.Element element = renderer.createElement('div');
renderer.setElementAttribute(element, 'id', 'foo');
expect(element.id, 'foo');
});

test('can add classes to elements', () {
final DomRenderer renderer = DomRenderer();
final html.Element element = renderer.createElement('div');
renderer.addElementClass(element, 'foo');
renderer.addElementClass(element, 'bar');
expect(element.classes, <String>['foo', 'bar']);
});

test('can remove classes from elements', () {
final DomRenderer renderer = DomRenderer();
final html.Element element = renderer.createElement('div');
renderer.addElementClass(element, 'foo');
renderer.addElementClass(element, 'bar');
expect(element.classes, <String>['foo', 'bar']);
renderer.removeElementClass(element, 'foo');
expect(element.classes, <String>['bar']);
});

test('can set style properties on elements', () {
final DomRenderer renderer = DomRenderer();
final html.Element element = renderer.createElement('div');
Expand All @@ -92,14 +52,6 @@ void testMain() {
expect(element.children, hasLength(1));
});

test('can detach elements', () {
final DomRenderer renderer = DomRenderer();
final html.Element element = renderer.createElement('div');
final html.Element child = renderer.createElement('div', parent: element);
renderer.detachElement(child);
expect(element.children, isEmpty);
});

test('innerHeight/innerWidth are equal to visualViewport height and width',
() {
if (html.window.visualViewport != null) {
Expand Down Expand Up @@ -176,17 +128,17 @@ void testMain() {
regularTextField.placeholder = 'Now you see me';
renderer.addResource(regularTextField);

renderer.focus(regularTextField);
regularTextField.focus();
html.CssStyleDeclaration? style = renderer.glassPaneShadow?.querySelector('input')?.getComputedStyle('::placeholder');
expect(style, isNotNull);
expect(style?.opacity, isNot('0'));

final html.InputElement textField = html.InputElement();
textField.placeholder = 'Now you dont';
renderer.addElementClass(textField, 'flt-text-editing');
textField.classes.add('flt-text-editing');
renderer.addResource(textField);

renderer.focus(textField);
textField.focus();
style = renderer.glassPaneShadow?.querySelector('input.flt-text-editing')?.getComputedStyle('::placeholder');
expect(style, isNotNull);
expect(style?.opacity, '0');
Expand Down