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

Commit dc0969b

Browse files
committed
[36]
1 parent 739240e commit dc0969b

File tree

13 files changed

+177
-122
lines changed

13 files changed

+177
-122
lines changed

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

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ extension DomWindowExtension on DomWindow {
4040
external DomURL get URL;
4141
external bool dispatchEvent(DomEvent event);
4242
external DomMediaQueryList matchMedia(String? query);
43-
external DomCSSStyleDeclaration getComputedStyle(DomElement elt);
43+
DomCSSStyleDeclaration getComputedStyle(DomElement elt,
44+
[String? pseudoElt]) =>
45+
js_util.callMethod(this, 'getComputedStyle', <Object>[
46+
elt,
47+
if (pseudoElt != null) pseudoElt
48+
]) as DomCSSStyleDeclaration;
4449
}
4550

4651
@JS()
@@ -88,6 +93,7 @@ extension DomDocumentExtension on DomDocument {
8893
String namespaceURI, String qualifiedName);
8994
external DomText createTextNode(String data);
9095
external DomEvent createEvent(String eventType);
96+
external DomElement? get activeElement;
9197
}
9298

9399
@JS()
@@ -195,6 +201,14 @@ extension DomNodeExtension on DomNode {
195201
js_util.setProperty<String?>(this, 'textContent', value);
196202
external DomNode cloneNode(bool? deep);
197203
external bool contains(DomNode? other);
204+
external void append(DomNode node);
205+
external DomNodeList get childNodes;
206+
external DomDocument? get ownerDocument;
207+
void clearChildren() {
208+
while (firstChild != null) {
209+
removeChild(firstChild!);
210+
}
211+
}
198212
}
199213

200214
@JS()
@@ -248,11 +262,10 @@ extension DomElementExtension on DomElement {
248262
external void click();
249263
external bool hasAttribute(String name);
250264
external DomNodeList get childNodes;
251-
void clearChildren() {
252-
while (firstChild != null) {
253-
removeChild(firstChild!);
254-
}
255-
}
265+
DomShadowRoot attachShadow(Map<Object?, Object?> initDict) => js_util
266+
.callMethod(this, 'attachShadow', <Object?>[js_util.jsify(initDict)])
267+
as DomShadowRoot;
268+
external DomShadowRoot? get shadowRoot;
256269
}
257270

258271
@JS()
@@ -501,8 +514,12 @@ class DomHTMLStyleElement extends DomHTMLElement {}
501514

502515
extension DomHTMLStyleElementExtension on DomHTMLStyleElement {
503516
external set type(String? value);
517+
external DomStyleSheet? get sheet;
504518
}
505519

520+
DomHTMLStyleElement createDomHTMLStyleElement() =>
521+
domDocument.createElement('style') as DomHTMLStyleElement;
522+
506523
@JS()
507524
@staticInterop
508525
class DomPerformance extends DomEventTarget {}
@@ -1146,6 +1163,34 @@ DomFileReader createDomFileReader() =>
11461163
js_util.callConstructor(domGetConstructor('FileReader')!, <Object>[])
11471164
as DomFileReader;
11481165

1166+
@JS()
1167+
@staticInterop
1168+
class DomDocumentFragment extends DomNode {}
1169+
1170+
extension DomDocumentFragmentExtension on DomDocumentFragment {
1171+
external DomElement? querySelector(String selectors);
1172+
external DomNodeList querySelectorAll(String selectors);
1173+
}
1174+
1175+
@JS()
1176+
@staticInterop
1177+
class DomShadowRoot extends DomDocumentFragment {}
1178+
1179+
extension DomShadowRootExtension on DomShadowRoot {
1180+
external DomElement? get activeElement;
1181+
external DomElement? get host;
1182+
external String? get mode;
1183+
external bool? get delegatesFocus;
1184+
}
1185+
1186+
@JS()
1187+
@staticInterop
1188+
class DomStyleSheet {}
1189+
1190+
@JS()
1191+
@staticInterop
1192+
class DomCSSStyleSheet extends DomStyleSheet {}
1193+
11491194
// A helper class for managing a subscription. On construction it will add an
11501195
// event listener of the requested type to the target. Calling [cancel] will
11511196
// remove the listener. Caller is still responsible for calling [allowInterop]

lib/web_ui/lib/src/engine/embedder.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,9 @@ class FlutterViewEmbedder {
313313
.instance.semanticsHelper
314314
.prepareAccessibilityPlaceholder() as html.Element;
315315

316-
glassPaneElementHostNode.nodes.addAll(<html.Node>[
317-
_accessibilityPlaceholder,
318-
_sceneHostElement!,
316+
glassPaneElementHostNode.appendAll(<DomNode>[
317+
_accessibilityPlaceholder as DomNode,
318+
_sceneHostElement! as DomNode,
319319

320320
// The semantic host goes last because hit-test order-wise it must be
321321
// first. If semantics goes under the scene host, platform views will
@@ -327,7 +327,7 @@ class FlutterViewEmbedder {
327327
// elements transparent. This way, if a platform view appears among other
328328
// interactive Flutter widgets, as long as those widgets do not intersect
329329
// with the platform view, the platform view will be reachable.
330-
semanticsHostElement,
330+
semanticsHostElement as DomNode,
331331
]);
332332

333333
// When debugging semantics, make the scene semi-transparent so that the
@@ -384,10 +384,10 @@ class FlutterViewEmbedder {
384384
// Creates a [HostNode] into a `root` [html.Element].
385385
HostNode _createHostNode(html.Element root) {
386386
if (getJsProperty<Object?>(root, 'attachShadow') != null) {
387-
return ShadowDomHostNode(root);
387+
return ShadowDomHostNode(root as DomElement);
388388
} else {
389389
// attachShadow not available, fall back to ElementHostNode.
390-
return ElementHostNode(root);
390+
return ElementHostNode(root as DomElement);
391391
}
392392
}
393393

@@ -526,7 +526,7 @@ class FlutterViewEmbedder {
526526
bodyNode.insertBefore(_resourcesHost!, bodyNode.firstChild);
527527
} else {
528528
_glassPaneShadow!.node.insertBefore(
529-
_resourcesHost!, _glassPaneShadow!.node.firstChild);
529+
_resourcesHost! as DomNode, _glassPaneShadow!.node.firstChild);
530530
}
531531
}
532532
_resourcesHost!.append(element);

lib/web_ui/lib/src/engine/host_node.dart

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,22 @@
55
import 'dart:html' as html;
66

77
import 'browser_detection.dart';
8+
import 'dom.dart';
89
import 'embedder.dart';
910
import 'text_editing/text_editing.dart';
1011

1112
/// The interface required to host a flutter app in the DOM, and its tests.
1213
///
13-
/// Consider this as the intersection in functionality between [html.ShadowRoot]
14-
/// (preferred Flutter rendering method) and [html.Document] (fallback).
14+
/// Consider this as the intersection in functionality between [DomShadowRoot]
15+
/// (preferred Flutter rendering method) and [DomDocument] (fallback).
1516
///
16-
/// Not to be confused with [html.DocumentOrShadowRoot].
17+
/// Not to be confused with [DomDocumentOrShadowRoot].
1718
abstract class HostNode {
18-
/// Retrieves the [html.Element] that currently has focus.
19+
/// Retrieves the [DomElement] that currently has focus.
1920
///
2021
/// See:
2122
/// * [Document.activeElement](https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement)
22-
html.Element? get activeElement;
23+
DomElement? get activeElement;
2324

2425
/// Adds a node to the end of the child [nodes] list of this node.
2526
///
@@ -31,18 +32,18 @@ abstract class HostNode {
3132
///
3233
/// See:
3334
/// * [Node.appendChild](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild)
34-
html.Node append(html.Node node);
35+
DomNode append(DomNode node);
36+
37+
/// Appends all of an [Iterable<DomNode>] to this [HostNode].
38+
void appendAll(Iterable<DomNode> nodes);
3539

3640
/// Returns true if this node contains the specified node.
3741
/// See:
3842
/// * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)
39-
bool contains(html.Node? other);
40-
41-
/// Returns the currently wrapped [html.Node].
42-
html.Node get node;
43+
bool contains(DomNode? other);
4344

44-
/// A modifiable list of this node's children.
45-
List<html.Node> get nodes;
45+
/// Returns the currently wrapped [DomNode].
46+
DomNode get node;
4647

4748
/// Finds the first descendant element of this document that matches the
4849
/// specified group of selectors.
@@ -59,7 +60,7 @@ abstract class HostNode {
5960
///
6061
/// See:
6162
/// * [Document.querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
62-
html.Element? querySelector(String selectors);
63+
DomElement? querySelector(String selectors);
6364

6465
/// Finds all descendant elements of this document that match the specified
6566
/// group of selectors.
@@ -75,10 +76,10 @@ abstract class HostNode {
7576
///
7677
/// See:
7778
/// * [Document.querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll)
78-
List<html.Element> querySelectorAll(String selectors);
79+
List<DomElement> querySelectorAll(String selectors);
7980
}
8081

81-
/// A [HostNode] implementation, backed by a [html.ShadowRoot].
82+
/// A [HostNode] implementation, backed by a [DomShadowRoot].
8283
///
8384
/// This is the preferred flutter implementation, but it might not be supported
8485
/// by all browsers yet.
@@ -87,12 +88,12 @@ abstract class HostNode {
8788
/// supported in the current environment. In this case, a fallback [ElementHostNode]
8889
/// should be created instead.
8990
class ShadowDomHostNode implements HostNode {
90-
late html.ShadowRoot _shadow;
91+
late DomShadowRoot _shadow;
9192

92-
/// Build a HostNode by attaching a [html.ShadowRoot] to the `root` element.
93+
/// Build a HostNode by attaching a [DomShadowRoot] to the `root` element.
9394
///
9495
/// This also calls [applyGlobalCssRulesToSheet], defined in dom_renderer.
95-
ShadowDomHostNode(html.Element root) :
96+
ShadowDomHostNode(DomElement root) :
9697
assert(
9798
root.isConnected ?? true,
9899
'The `root` of a ShadowDomHostNode must be connected to the Document object or a ShadowRoot.',
@@ -104,9 +105,9 @@ class ShadowDomHostNode implements HostNode {
104105
'delegatesFocus': false,
105106
});
106107

107-
final html.StyleElement shadowRootStyleElement = html.StyleElement();
108+
final DomHTMLStyleElement shadowRootStyleElement = createDomHTMLStyleElement();
108109
// The shadowRootStyleElement must be appended to the DOM, or its `sheet` will be null later.
109-
_shadow.append(shadowRootStyleElement);
110+
_shadow.appendChild(shadowRootStyleElement);
110111

111112
// TODO(dit): Apply only rules for the shadow root
112113
applyGlobalCssRulesToSheet(
@@ -117,74 +118,74 @@ class ShadowDomHostNode implements HostNode {
117118
}
118119

119120
@override
120-
html.Element? get activeElement => _shadow.activeElement;
121+
DomElement? get activeElement => _shadow.activeElement;
121122

122123
@override
123-
html.Element? querySelector(String selectors) {
124+
DomElement? querySelector(String selectors) {
124125
return _shadow.querySelector(selectors);
125126
}
126127

127128
@override
128-
List<html.Element> querySelectorAll(String selectors) {
129-
return _shadow.querySelectorAll(selectors);
129+
List<DomElement> querySelectorAll(String selectors) {
130+
return _shadow.querySelectorAll(selectors) as List<DomElement>;
130131
}
131132

132133
@override
133-
html.Node append(html.Node node) {
134-
return _shadow.append(node);
134+
DomNode append(DomNode node) {
135+
return _shadow.appendChild(node);
135136
}
136137

137138
@override
138-
bool contains(html.Node? other) {
139+
bool contains(DomNode? other) {
139140
return _shadow.contains(other);
140141
}
141142

142143
@override
143-
html.Node get node => _shadow;
144+
DomNode get node => _shadow;
144145

145146
@override
146-
List<html.Node> get nodes => _shadow.nodes;
147+
void appendAll(Iterable<DomNode> nodes) => nodes.forEach(append);
147148
}
148149

149-
/// A [HostNode] implementation, backed by a [html.Element].
150+
/// A [HostNode] implementation, backed by a [DomElement].
150151
///
151152
/// This is a fallback implementation, in case [ShadowDomHostNode] fails when
152153
/// being constructed.
153154
class ElementHostNode implements HostNode {
154-
late html.Element _element;
155+
late DomElement _element;
155156

156-
/// Build a HostNode by attaching a child [html.Element] to the `root` element.
157-
ElementHostNode(html.Element root) {
158-
_element = html.document.createElement('flt-element-host-node');
159-
root.append(_element);
157+
/// Build a HostNode by attaching a child [DomElement] to the `root` element.
158+
ElementHostNode(DomElement root) {
159+
_element = domDocument.createElement('flt-element-host-node');
160+
root.appendChild(_element);
160161
}
161162

162163
@override
163-
html.Element? get activeElement => _element.ownerDocument?.activeElement;
164+
DomElement? get activeElement => _element.ownerDocument?.activeElement;
164165

165166
@override
166-
html.Element? querySelector(String selectors) {
167+
DomElement? querySelector(String selectors) {
167168
return _element.querySelector(selectors);
168169
}
169170

170171
@override
171-
List<html.Element> querySelectorAll(String selectors) {
172+
List<DomElement> querySelectorAll(String selectors) {
172173
return _element.querySelectorAll(selectors);
173174
}
174175

175176
@override
176-
html.Node append(html.Node node) {
177-
return _element.append(node);
177+
DomNode append(DomNode node) {
178+
return _element.appendChild(node);
178179
}
179180

180181
@override
181-
bool contains(html.Node? other) {
182+
bool contains(DomNode? other) {
182183
return _element.contains(other);
183184
}
184185

185186
@override
186-
html.Node get node => _element;
187+
DomNode get node => _element;
187188

188189
@override
189-
List<html.Node> get nodes => _element.nodes;
190+
void appendAll(Iterable<DomNode> nodes) => nodes.forEach(append);
190191
}

lib/web_ui/lib/src/engine/platform_views/content_manager.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
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;
6-
75
import '../browser_detection.dart';
86
import '../dom.dart';
97
import '../embedder.dart';
@@ -163,7 +161,7 @@ class PlatformViewManager {
163161
final DomElement slot = domDocument.createElement('slot')
164162
..style.display = 'none'
165163
..setAttribute('name', tombstoneName);
166-
flutterViewEmbedder.glassPaneShadow!.append(slot as html.Node);
164+
flutterViewEmbedder.glassPaneShadow!.append(slot);
167165
// Link the element to the new slot
168166
element.setAttribute('slot', tombstoneName);
169167
// Delete both the element, and the new slot

lib/web_ui/lib/src/engine/text/measurement.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
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;
6-
75
import '../../engine.dart' show registerHotRestartListener;
86
import '../dom.dart';
97
import '../embedder.dart';
@@ -31,7 +29,7 @@ class RulerHost {
3129
..height = '0';
3230

3331
if (root == null) {
34-
flutterViewEmbedder.glassPaneShadow!.node.append(_rulerHost as html.Node);
32+
flutterViewEmbedder.glassPaneShadow!.node.appendChild(_rulerHost);
3533
} else {
3634
root.appendChild(_rulerHost);
3735
}

0 commit comments

Comments
 (0)