[web] clean-up dom_renderer.dart (flutter/engine#29934)

This commit is contained in:
Yegor
2021-11-29 09:26:53 -08:00
committed by GitHub
parent 148dac4f98
commit d9e349481c
10 changed files with 23 additions and 126 deletions

View File

@@ -152,7 +152,7 @@ class DomRenderer {
if (sceneElement != _sceneElement) {
_sceneElement?.remove();
_sceneElement = sceneElement;
append(_sceneHostElement!, sceneElement!);
_sceneHostElement!.append(sceneElement!);
}
assert(() {
_clearOnHotRestart();
@@ -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) {
@@ -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?;
@@ -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');
@@ -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
@@ -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();
}

View File

@@ -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';
@@ -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;
@@ -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,

View File

@@ -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;
@@ -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;
@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
@@ -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!);
}
@@ -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!);

View File

@@ -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;

View File

@@ -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];
@@ -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 {

View File

@@ -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');
@@ -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) {
@@ -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');