diff --git a/src/content/interop/js-interop/package-web.md b/src/content/interop/js-interop/package-web.md index 40ddf16935..f8f4de6c01 100644 --- a/src/content/interop/js-interop/package-web.md +++ b/src/content/interop/js-interop/package-web.md @@ -156,6 +156,78 @@ 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 [mdn 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 + +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.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 %} +TODO: add more examples +{% endcomment -%} + ### Type tests It's common for code that uses `dart:html` to utilize runtime checks like `is`. @@ -175,6 +247,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 +400,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 +[mdn element]: https://developer.mozilla.org/en-US/docs/Web/API/Element