diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index a3bcc029cc3..4144280eb77 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -11722,6 +11722,10 @@ class _ChildrenElementList extends ListBase
Iterator get iterator => toList().iterator;
void addAll(Iterable iterable) {
+ _addAll(_element, iterable);
+ }
+
+ static void _addAll(Element _element, Iterable iterable) {
if (iterable is _ChildNodeListLazy) {
iterable = new List.from(iterable);
}
@@ -11775,6 +11779,10 @@ class _ChildrenElementList extends ListBase
}
bool remove(Object? object) {
+ return _remove(_element, object);
+ }
+
+ static bool _remove(Element _element, Object? object) {
if (object is Element) {
Element element = object;
if (identical(element.parentNode, _element)) {
@@ -11823,7 +11831,10 @@ class _ChildrenElementList extends ListBase
return result;
}
- Element get first {
+ Element get first => _first(_element);
+
+ @pragma('dart2js:noInline')
+ static Element _first(Element _element) {
Element? result = _element._firstElementChild;
if (result == null) throw new StateError("No elements");
return result;
@@ -12965,6 +12976,16 @@ class Element extends Node
*/
List get children => new _ChildrenElementList._wrap(this);
+ List get _children =>
+ // Element.children always returns the same list-like object which is a
+ // live view on the underlying DOM tree. So we can GVN it and remove it if
+ // unused.
+ JS(
+ 'returns:HtmlCollection;creates:HtmlCollection;'
+ 'depends:none;effects:none;gvn:true',
+ '#.children',
+ this);
+
set children(List value) {
// Copy list first since we don't want liveness during iteration.
var copy = value.toList();
@@ -14824,11 +14845,6 @@ class Element extends Node
@JSName('childElementCount')
int get _childElementCount native;
- @JSName('children')
- @Returns('HtmlCollection')
- @Creates('HtmlCollection')
- List get _children native;
-
@JSName('firstElementChild')
Element? get _firstElementChild native;
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 623f5e9061a..014e8116258 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -387,7 +387,6 @@ private_html_members = monitored.Set(
# Not prefixed but requires custom implementation for cross-browser compatibility.
'Document.visibilityState',
'Element.animate',
- 'Element.children',
'Element.childElementCount',
'Element.firstElementChild',
'Element.getClientRects',
@@ -791,6 +790,7 @@ removed_html_members = monitored.Set(
'DOMException.WRONG_DOCUMENT_ERR',
'Element.accessKey',
'Element.append',
+ 'Element.children',
'Element.dataset',
'Element.get:classList',
'Element.getAttributeNode',
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index bdca7ed4d7b..b0d5ff880bd 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -46,6 +46,10 @@ class _ChildrenElementList extends ListBase
Iterator get iterator => toList().iterator;
void addAll(Iterable iterable) {
+ _addAll(_element, iterable);
+ }
+
+ static void _addAll(Element _element, Iterable iterable) {
if (iterable is _ChildNodeListLazy) {
iterable = new List.from(iterable);
}
@@ -99,6 +103,10 @@ class _ChildrenElementList extends ListBase
}
bool remove(Object$NULLABLE object) {
+ return _remove(_element, object);
+ }
+
+ static bool _remove(Element _element, Object$NULLABLE object) {
if (object is Element) {
Element element = object;
if (identical(element.parentNode, _element)) {
@@ -149,7 +157,10 @@ class _ChildrenElementList extends ListBase
return result;
}
- Element get first {
+ Element get first => _first(_element);
+
+ @pragma('dart2js:noInline')
+ static Element _first(Element _element) {
Element$NULLABLE result = _element._firstElementChild;
if (result == null) throw new StateError("No elements");
return result;
@@ -667,6 +678,15 @@ $endif
*/
List get children => new _ChildrenElementList._wrap(this);
+ List get _children =>
+ // Element.children always returns the same list-like object which is a
+ // live view on the underlying DOM tree. So we can GVN it and remove it if
+ // unused.
+ JS('returns:HtmlCollection;creates:HtmlCollection;'
+ 'depends:none;effects:none;gvn:true',
+ '#.children',
+ this);
+
set children(List value) {
// Copy list first since we don't want liveness during iteration.
var copy = value.toList();