From 5d089efef1ad581a83e80f8c8885c7cfc3982253 Mon Sep 17 00:00:00 2001 From: Franciszek S Wawrzak Date: Sun, 23 Nov 2025 21:58:25 +0100 Subject: [PATCH 1/3] add more examples to package:web migration --- src/content/interop/js-interop/package-web.md | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/content/interop/js-interop/package-web.md b/src/content/interop/js-interop/package-web.md index 40ddf16935..dc0eac132e 100644 --- a/src/content/interop/js-interop/package-web.md +++ b/src/content/interop/js-interop/package-web.md @@ -156,6 +156,66 @@ Node append(Node node) native; `native` is an internal keyword that means the same as `external` in this context. +### Element and HTMLElement + +`Element` is now `HTMLElement` but `Element` class also exists as base class for +HTMLElement, SVGElement etc. See [msdn element]. +`querySelector` returns `Element` as it can query in SVG as well so cast is +required to access `HTMLElement` methods. + +```dart +element.querySelector('#selectme')!.className = 'test'; // valid in both + +element.querySelector('#selectme')!.style.color = 'red'; // Remove +(element.querySelector('#selectme') as HTMLElement).style.color = 'red'; // Add +``` + +### List operations + +Methods like `Element::querySelectorAll` or `Element::children` return values no +longer implement `List` interface. + +For immutable operations you can use `JSImmutableListWrapper`: + +```dart +final anchors = document.querySelectorAll('a'); +for (final anchor in anchors)) {} // Remove +for (final anchor in JSImmutableListWrapper(anchors)) {} //Add + +for (final child in parent.children) {} // Remove +for (final child in JSImmutableListWrapper(parent.children)) {} // Add +``` + +You need to add implementation for simple mutable operations like `removeWhere`: + +```dart +parent.children.removeWhere(test); // Remove + +for (var i = parent.children.length - 1; i >= 0; --i) { + if (test(parent.children.item(i)!)) { + parent.children.item(i)!.remove(); + } +} // Add + +``` + +### Common DOM manipulation examples + +```dart +element.querySelector('#selector')?.innerHtml = 'something'; // Remove +element.querySelector('#selector')?.innerHTML = 'something'.toJS; // Add + +element.classes.add('class'); // Remove +element.classList.add('class'); // Add + +element.appendHtml(html); // Remove +element.insertAdjacentHTML('beforeend', html.toJS); // Add +``` + +{% comment %} +TODO: add more examples +{% endcomment -%} + ### Type tests It's common for code that uses `dart:html` to utilize runtime checks like `is`. @@ -175,6 +235,9 @@ section of the JS types page covers alternatives in detail. ```dart obj is Window; // Remove obj.instanceOfString('Window'); // Add + +element is InputElement; // Remove +element.isA(); // Add ``` ### Type signatures @@ -325,3 +388,4 @@ Do we have any other package migrations to show off here? [restricts]: /interop/js-interop/js-types#requirements-on-external-declarations-and-function-tojs [#54507]: {{site.repo.dart.sdk}}/issues/54507 [mocking tutorial]: /interop/js-interop/mock +[msdn element]: https://developer.mozilla.org/en-US/docs/Web/API/Element From f24cd56d11531d455bc5c95dce39a6a5b031cc61 Mon Sep 17 00:00:00 2001 From: Franciszek S Wawrzak Date: Sun, 23 Nov 2025 22:08:11 +0100 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- src/content/interop/js-interop/package-web.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/interop/js-interop/package-web.md b/src/content/interop/js-interop/package-web.md index dc0eac132e..de01c027b9 100644 --- a/src/content/interop/js-interop/package-web.md +++ b/src/content/interop/js-interop/package-web.md @@ -159,7 +159,7 @@ context. ### Element and HTMLElement `Element` is now `HTMLElement` but `Element` class also exists as base class for -HTMLElement, SVGElement etc. See [msdn element]. +HTMLElement, SVGElement etc. See [mdn element]. `querySelector` returns `Element` as it can query in SVG as well so cast is required to access `HTMLElement` methods. @@ -179,7 +179,7 @@ For immutable operations you can use `JSImmutableListWrapper`: ```dart final anchors = document.querySelectorAll('a'); -for (final anchor in anchors)) {} // Remove +for (final anchor in anchors) {} // Remove for (final anchor in JSImmutableListWrapper(anchors)) {} //Add for (final child in parent.children) {} // Remove @@ -388,4 +388,4 @@ Do we have any other package migrations to show off here? [restricts]: /interop/js-interop/js-types#requirements-on-external-declarations-and-function-tojs [#54507]: {{site.repo.dart.sdk}}/issues/54507 [mocking tutorial]: /interop/js-interop/mock -[msdn element]: https://developer.mozilla.org/en-US/docs/Web/API/Element +[mdn element]: https://developer.mozilla.org/en-US/docs/Web/API/Element From afbaa5d46702776a1a8447e9eda3d329834c6548 Mon Sep 17 00:00:00 2001 From: Franciszek S Wawrzak Date: Mon, 24 Nov 2025 11:53:38 +0100 Subject: [PATCH 3/3] add some more examples for DOM manipulation --- src/content/interop/js-interop/package-web.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/content/interop/js-interop/package-web.md b/src/content/interop/js-interop/package-web.md index de01c027b9..f8f4de6c01 100644 --- a/src/content/interop/js-interop/package-web.md +++ b/src/content/interop/js-interop/package-web.md @@ -201,15 +201,27 @@ for (var i = parent.children.length - 1; i >= 0; --i) { ### Common DOM manipulation examples +All non standard `dart:html` fields and helpers not present in IDL definitions +are not available. Hence tiny changes are required for some DOM manipulation +operations. + ```dart element.querySelector('#selector')?.innerHtml = 'something'; // Remove element.querySelector('#selector')?.innerHTML = 'something'.toJS; // Add -element.classes.add('class'); // Remove -element.classList.add('class'); // Add +element.parent.classes.add('class'); // Remove +element.parentElement.classList.add('class'); // Add element.appendHtml(html); // Remove element.insertAdjacentHTML('beforeend', html.toJS); // Add + +var checkbox = CheckboxInputElement(); // Remove +var checkbox = HTMLInputElement()..type='checkbox'; // Add + +element.querySelectorAll('a').classes.add('link'); // Remove +for (final a in JSImmutableListWrapper(element.querySelectorAll('a'))) { + a.classList.add('a'); +} // Add ``` {% comment %}