Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions src/content/interop/js-interop/package-web.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -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<HTMLInputElement>(); // Add
```

### Type signatures
Expand Down Expand Up @@ -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