Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
2 changes: 2 additions & 0 deletions web/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- Added `childNodesAsList` to `Node` and `childrenAsList` to `Element` via
extensions to support mutable operations on node lists.
- Added `asList` to `NodeList` via extension.
- Added `data` to `HTMLElement` and `SVGElement` via extension. It provides
nullable interface for `dataset` allowing to check if data attribute is set.

## 1.1.1

Expand Down
1 change: 1 addition & 0 deletions web/lib/src/helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
library;

export 'helpers/cross_origin.dart' show CrossOriginLocation, CrossOriginWindow;
export 'helpers/dataset.dart';
export 'helpers/enums.dart';
export 'helpers/events/events.dart';
export 'helpers/events/providers.dart';
Expand Down
44 changes: 44 additions & 0 deletions web/lib/src/helpers/dataset.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
Comment thread
fsw marked this conversation as resolved.
Outdated
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:js_interop';
import 'dart:js_interop_unsafe';

import '../dom/html.dart';
import '../dom/svg.dart';

/// Provides nullable api on `DOMStringMap`.
/// When data-* attribute is missing, `[]` operator will return null.
/// It also allows to remove data-* attributes by using `remove()`.
extension type NullableDOMStringMap._(JSObject _) implements JSObject {
/// `DOMStringMap` returns non nullable `DOMString` from getter.
Comment thread
fsw marked this conversation as resolved.
Outdated
/// It returns `undefined` when given key does not exist.
/// As in Dart there is no `undefined` we return null in such case.
external String? operator [](String name);

external void operator []=(
String name,
String value,
Comment thread
fsw marked this conversation as resolved.
Outdated
);

/// `DomStringMap` uses unnamed deleter that cant be mapped to dart.
/// This allows calling js `delete` operator on dataset.
String? remove(String name) {
final ret = this[name];
delete(name.toJS);
return ret;
}
}

Comment thread
fsw marked this conversation as resolved.
extension HTMLElementDatasetExtension on HTMLElement {
/// Wrapper for nullable dataset. See [NullableDOMStringMap] for details.
Comment thread
fsw marked this conversation as resolved.
Outdated
@JS('dataset')
external NullableDOMStringMap get data;
}

extension SVGElementDatasetExtension on SVGElement {
/// Wrapper for nullable dataset. See [NullableDOMStringMap] for details.
@JS('dataset')
external NullableDOMStringMap get data;
}
20 changes: 20 additions & 0 deletions web/test/helpers_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,24 @@ void main() {
test('Uri.toJS throws an ArgumentError for a relative URL', () {
expect(() => Uri.parse('/path').toJS, throwsArgumentError);
});

test('nullable dataset extension', () {
final div = (document.createElement('div') as HTMLElement)
..setAttribute('data-foo', 'bar')
..setAttribute('data-foo-camel', 'bar');

//read existing and not existing data
expect(div.data['foo'], equals('bar'));
expect(div.data['fooCamel'], equals('bar'));
expect(div.data['nonexisting'], isNull);

//update data
div.data['foo'] = div.data['fooCamel'] = 'bar2';
expect(div.data['foo'], equals('bar2'));
expect(div.data['fooCamel'], equals('bar2'));

//unset data
expect(div.data.remove('foo'), equals('bar2'));
expect(div.data['foo'], isNull);
});
Comment thread
fsw marked this conversation as resolved.
}