From 2995b6aefb8c2597f8e921a42aba37f4045f5b2c Mon Sep 17 00:00:00 2001 From: terrier989 Date: Sun, 16 Nov 2025 00:10:41 +0000 Subject: [PATCH 1/2] Improves dependency constraints --- .github/workflows/dart.yml | 2 +- CHANGELOG.md | 3 +++ pubspec.yaml | 7 +++---- test_in_flutter/pubspec.yaml | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 180505a..88ca649 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - sdk: [stable, beta, dev] + sdk: [3.0, stable, beta, dev] steps: - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8407dc7..f22cfd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.2.6 +* Removes an unnecesary dependency. + ## 2.2.5 * Updates the library for new Dart SDK and fixes most analyzer warnings. diff --git a/pubspec.yaml b/pubspec.yaml index f8387b3..bb04929 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,12 +1,12 @@ name: universal_html -version: 2.2.5 +version: 2.2.6 description: A 'dart:html' that works in all platforms, including Flutter and server-side. Eases cross-platform development and HTML / XML processing. homepage: https://github.com/dint-dev/universal_html environment: - sdk: ^3.7.0 + sdk: ^3.0.0 dependencies: async: ^2.11.0 @@ -18,9 +18,8 @@ dependencies: source_span: ^1.9.1 typed_data: ^1.3.2 universal_io: ^2.2.3 - web: ^1.1.1 dev_dependencies: - lints: ^6.0.0 + lints: '>=3.0.0 <7.0.0' stream_channel: ^2.1.1 test: ^1.24.3 \ No newline at end of file diff --git a/test_in_flutter/pubspec.yaml b/test_in_flutter/pubspec.yaml index 6e0b1df..c57e77e 100644 --- a/test_in_flutter/pubspec.yaml +++ b/test_in_flutter/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: 'none' environment: - sdk: '>=2.17.0 <4.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: flutter: @@ -14,6 +14,6 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - lints: ^6.0.0 + lints: stream_channel: test: \ No newline at end of file From 27f0fdf41a12b425c12ccf8805b98d6c1313bd92 Mon Sep 17 00:00:00 2001 From: terrier989 Date: Sun, 16 Nov 2025 20:24:42 +0000 Subject: [PATCH 2/2] Improves CI and documentation --- .github/FUNDING.yml | 2 - .github/workflows/dart.yml | 64 +++++++- .github/workflows/publish.yml | 14 ++ CHANGELOG.md | 5 +- README.md | 12 +- lib/html.dart | 26 +--- lib/src/_sdk_html_additions.dart | 6 +- lib/src/controller/internal_element_data.dart | 3 +- lib/src/controller/window_behavior.dart | 3 +- .../window_behavior_impl_browser.dart | 7 +- lib/src/html.dart | 66 ++++++++- lib/src/html/_html_parser.dart | 7 +- lib/src/html/api/animation.dart | 2 + lib/src/html/api/canvas.dart | 4 + lib/src/html/api/dom_matrix.dart | 21 +++ lib/src/html/api/event.dart | 6 +- lib/src/html/api/event_source.dart | 20 +-- lib/src/html/api/event_subclasses.dart | 80 +++++----- lib/src/html/api/geolocation.dart | 5 +- lib/src/html/api/history.dart | 2 + lib/src/html/api/http_request.dart | 6 + lib/src/html/api/navigator_misc.dart | 6 +- lib/src/html/api/web_rtc.dart | 2 +- lib/src/html/api/web_socket.dart | 4 + lib/src/html/api/window.dart | 8 +- lib/src/html/api/window_misc.dart | 2 +- lib/src/html/dom/css_computed_style.dart | 5 +- lib/src/html/dom/css_rect.dart | 37 +++-- .../html/dom/css_style_declaration_set.dart | 10 +- lib/src/html/dom/document.dart | 8 +- lib/src/html/dom/element.dart | 24 ++- lib/src/html/dom/element_subclasses.dart | 52 +++---- .../dom/element_subclasses_for_inputs.dart | 5 + lib/src/html/dom/html_node_validator.dart | 2 +- lib/src/html/dom/node.dart | 16 +- lib/src/html/dom/node_validator_builder.dart | 38 +++-- .../shared_with_dart2js/css_class_set.dart | 23 +-- .../dom/shared_with_dart2js/metadata.dart | 3 + lib/src/html/dom/validators.dart | 7 +- lib/src/parsing/parsing.dart | 5 +- lib/universal_html.dart | 38 +++++ pubspec.yaml | 6 +- test/src/html/dom/css_queries.dart | 139 ++++++++---------- test/src/html/dom/document.dart | 7 +- test/src/html/dom/element.dart | 67 ++++----- test/src/html/dom/element_computed_style.dart | 3 +- test/src/html/dom/element_subclasses.dart | 14 +- test/src/html/dom/node.dart | 22 ++- 48 files changed, 534 insertions(+), 380 deletions(-) delete mode 100644 .github/FUNDING.yml create mode 100644 .github/workflows/publish.yml create mode 100644 lib/universal_html.dart diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index b1c2f8e..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -github: [terrier989] -open_collective: [cryptography] \ No newline at end of file diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 88ca649..e50fa2f 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -1,20 +1,70 @@ name: Dart CI -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + +env: + PANA_SCORE_MAX_DIFFERENCE: 20 jobs: + format: + name: Verify code formatting + runs-on: ubuntu-slim + steps: + - uses: actions/checkout@v3 + - uses: dart-lang/setup-dart@v1 + - name: Install dependencies + run: dart --version && dart pub get + - name: Verify formatting + run: dart format --set-exit-if-changed . + lints: + name: Analyze source code + needs: [format] + runs-on: ubuntu-slim + strategy: + fail-fast: false + matrix: + sdk: [3.6, stable, beta, dev] + steps: + - uses: actions/checkout@v3 + - uses: dart-lang/setup-dart@v1 + with: + sdk: ${{ matrix.sdk }} + - name: Install dependencies + run: dart --version && dart pub get + - name: Analyze project source + run: dart analyze + package_health: + name: Analyze package health + needs: [lints] + runs-on: ubuntu-slim + steps: + - uses: actions/checkout@v3 + - uses: dart-lang/setup-dart@v1 + - name: Install dependencies + run: dart --version && dart pub get && dart pub global activate pana + - name: Run package analyzer + run: dart pub global run pana --exit-code-threshold $PANA_SCORE_MAX_DIFFERENCE test: - runs-on: ${{ matrix.os }} + name: Run tests + needs: [lints] + runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - os: [ubuntu-latest] - sdk: [3.0, stable, beta, dev] + sdk: [stable, beta, dev] steps: - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} + - uses: browser-actions/setup-chrome@v2 - name: Install dependencies - run: dart pub get - - name: Run tests - run: dart test --platform vm \ No newline at end of file + run: dart --version && dart pub get + - name: Run tests (VM) + run: dart test --platform vm + - name: Run tests (Chrome, JS) + run: dart test --platform chrome --compiler dart2js \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..11669bc --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,14 @@ +name: Publish to pub.dev + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + +jobs: + publish: + permissions: + id-token: write + uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 + with: + environment: pub.dev diff --git a/CHANGELOG.md b/CHANGELOG.md index f22cfd6..7c7d71e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ +## 2.2.7 +* Improves documentation and tests. + ## 2.2.6 -* Removes an unnecesary dependency. +* Removes an unnecessary dependency. ## 2.2.5 * Updates the library for new Dart SDK and fixes most analyzer warnings. diff --git a/README.md b/README.md index 69429d5..2f27354 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ [![Github Actions CI](https://github.com/dint-dev/universal_html/workflows/Dart%20CI/badge.svg)](https://github.com/dint-dev/universal_html/actions) # Introduction -A cross-platform `dart:html`: +A cross-platform replacement for `dart:html` (or `package:web`): * __Eases cross-platform development__ * You can use this package in browsers, mobile, desktop, and server-side VM, and Node.JS. - * Just replace `dart:html` imports with `package:universal_html/html.dart`. Normal + * Just replace `dart:html` / `package:web` imports with `package:universal_html/universal_html.dart`. Normal _dart:html_ will continue to be used when application run in browsers. * __Extensive support for processing HTML and XML documents__ - * Parse, manipulate, and print [DOM nodes](https://api.dart.dev/stable/2.19.3/dart-html/Node-class.html). + * Parse, manipulate, and print [DOM nodes](https://api.flutter.dev/flutter/dart-html/Node-class.html). * Find DOM nodes with [querySelectorAll](https://api.dart.dev/stable/2.19.3/dart-html/querySelectorAll.html) and other CSS query methods. * __EventSource streaming support__ @@ -35,12 +35,12 @@ which is documented in the relevant files. In `pubspec.yaml`: ```yaml dependencies: - universal_html: ^2.2.5 + universal_html: ^2.2.7 ``` ## 2. Use ```dart -import "package:universal_html/html.dart"; +import "package:universal_html/universal_html.dart"; void main() { // Create a DOM tree @@ -121,7 +121,7 @@ is a browser API for reading "application/event-stream" streams. It has been sup for a long time. ```dart -import 'package:universal_html/html.dart'; +import 'package:universal_html/universal_html.dart'; Future main() async { final eventSource = EventSource('http://example.com/events'); diff --git a/lib/html.dart b/lib/html.dart index 32c319e..96da24c 100644 --- a/lib/html.dart +++ b/lib/html.dart @@ -12,28 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -/// Cross-platform "dart:html" library. -/// -/// You can choose from the following libraries: -/// * `package:universal_html/html.dart` -/// * `package:universal_html/prefer_sdk/html.dart` -/// * `package:universal_html/prefer_universal/html.dart` -/// -/// # Introduction -/// -/// HTML elements and other resources for web-based applications that need to -/// interact with the browser and the DOM (Document Object Model). -/// -/// This library includes DOM element types, CSS styling, local storage, -/// media, speech, events, and more. -/// To get started, -/// check out the [Element] class, the base class for many of the HTML -/// DOM types. -/// -/// For information on writing web apps with Dart, see https://webdev.dartlang.org. +/// @nodoc +@Deprecated('Replace with "package:universal_html/universal_html.dart.') library; -export 'src/_sdk/html.dart' - if (dart.library.html) 'src/_sdk/html.dart' // Browser - if (dart.library.io) 'src/html.dart' // VM - if (dart.library.js) 'src/html.dart'; // Node.JS +export 'universal_html.dart'; diff --git a/lib/src/_sdk_html_additions.dart b/lib/src/_sdk_html_additions.dart index 3a10f10..85c6dc8 100644 --- a/lib/src/_sdk_html_additions.dart +++ b/lib/src/_sdk_html_additions.dart @@ -52,8 +52,7 @@ abstract class EventSourceOutsideBrowser implements EventSource { FutureOr Function( EventSourceOutsideBrowser eventSource, HttpClientRequest request, - )? - onHttpClientRequest; + )? onHttpClientRequest; /// A callback called when a [HttpClientResponse] arrives (only outside /// browsers). @@ -63,8 +62,7 @@ abstract class EventSourceOutsideBrowser implements EventSource { EventSourceOutsideBrowser eventSource, HttpClientRequest request, HttpClientResponse response, - )? - onHttpClientResponse; + )? onHttpClientResponse; /// Current timeout. Duration retryDuration = Duration(seconds: 3); diff --git a/lib/src/controller/internal_element_data.dart b/lib/src/controller/internal_element_data.dart index eff9ddc..22e73b8 100644 --- a/lib/src/controller/internal_element_data.dart +++ b/lib/src/controller/internal_element_data.dart @@ -15,8 +15,7 @@ import 'package:universal_html/html.dart'; import 'internal_element_data_impl_others.dart' - if (dart.library.html) 'internal_element_data_impl_browser.dart' - as impl; + if (dart.library.html) 'internal_element_data_impl_browser.dart' as impl; /// Internal data of [Element]. /// diff --git a/lib/src/controller/window_behavior.dart b/lib/src/controller/window_behavior.dart index 5d72d2a..2b36548 100644 --- a/lib/src/controller/window_behavior.dart +++ b/lib/src/controller/window_behavior.dart @@ -19,8 +19,7 @@ import 'package:universal_html/html.dart'; import 'window_behavior_impl_browser.dart' if (dart.library.html) 'window_behavior_impl_browser.dart' // Browser if (dart.library.io) 'window_behavior_impl_others.dart' // VM - if (dart.library.js) 'window_behavior_impl_others.dart' - as impl; // Node.JS + if (dart.library.js) 'window_behavior_impl_others.dart' as impl; // Node.JS /// Defines behavior of the browser APIs (such as navigation events). /// diff --git a/lib/src/controller/window_behavior_impl_browser.dart b/lib/src/controller/window_behavior_impl_browser.dart index ca4e866..791e34e 100644 --- a/lib/src/controller/window_behavior_impl_browser.dart +++ b/lib/src/controller/window_behavior_impl_browser.dart @@ -27,10 +27,9 @@ Document newDocument({ HtmlDocument newHtmlDocument({required Window window, String? contentType}) { return DomParser().parseFromString( - '', - contentType ?? 'text/html', - ) - as HtmlDocument; + '', + contentType ?? 'text/html', + ) as HtmlDocument; } Navigator newNavigator({required Window window}) { diff --git a/lib/src/html.dart b/lib/src/html.dart index cdacdba..c5b54c8 100644 --- a/lib/src/html.dart +++ b/lib/src/html.dart @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// The library name is needed for generating differences between our library -// and dart:html. library; import 'dart:async'; @@ -31,7 +29,8 @@ import 'package:csslib/parser.dart' as css; import 'package:csslib/visitor.dart' as css; import 'package:meta/meta.dart'; import 'package:typed_data/typed_buffers.dart'; -import 'package:universal_html/html.dart' as universal_html_in_browser_or_vm; +import 'package:universal_html/universal_html.dart' + as universal_html_in_browser_or_vm; import '../controller.dart'; import 'html.dart' as universal_html; @@ -52,64 +51,125 @@ export 'html_top_level_functions.dart'; export 'js_util.dart' show promiseToFuture; part 'html/api/accessible_node.dart'; + part 'html/api/animation.dart'; + part 'html/api/application_cache.dart'; + part 'html/api/blob.dart'; + part 'html/api/canvas.dart'; + part 'html/api/console.dart'; + part 'html/api/crypto.dart'; + part 'html/api/data_transfer.dart'; + part 'html/api/device.dart'; + part 'html/api/dom_matrix.dart'; + part 'html/api/event.dart'; + part 'html/api/event_handlers.dart'; + part 'html/api/event_source.dart'; + part 'html/api/event_stream.dart'; + part 'html/api/event_subclasses.dart'; + part 'html/api/event_target.dart'; + part 'html/api/file.dart'; + part 'html/api/geolocation.dart'; + part 'html/api/history.dart'; + part 'html/api/http_request.dart'; + part 'html/api/keycode.dart'; + part 'html/api/media.dart'; + part 'html/api/navigator.dart'; + part 'html/api/navigator_misc.dart'; + part 'html/api/notification.dart'; + part 'html/api/payment.dart'; + part 'html/api/performance.dart'; + part 'html/api/permissions.dart'; + part 'html/api/scroll.dart'; + part 'html/api/speech_synthesis.dart'; + part 'html/api/storage.dart'; + part 'html/api/web_rtc.dart'; + part 'html/api/web_socket.dart'; + part 'html/api/window.dart'; + part 'html/api/window_misc.dart'; + part 'html/api/workers.dart'; + part 'html/dom/css.dart'; + part 'html/dom/css_computed_style.dart'; + part 'html/dom/css_rect.dart'; + part 'html/dom/css_selectors.dart'; + part 'html/dom/css_style_declaration.dart'; + part 'html/dom/css_style_declaration_base.dart'; + part 'html/dom/css_style_declaration_set.dart'; + part 'html/dom/document.dart'; + part 'html/dom/document_fragment.dart'; + part 'html/dom/dom_exception.dart'; + part 'html/dom/element.dart'; + part 'html/dom/element_attributes.dart'; + part 'html/dom/element_list.dart'; + part 'html/dom/element_misc.dart'; + part 'html/dom/element_subclasses.dart'; + part 'html/dom/element_subclasses_for_inputs.dart'; + part 'html/dom/html_document.dart'; + part 'html/dom/html_node_validator.dart'; + part 'html/dom/node.dart'; + part 'html/dom/node_child_node_list.dart'; + part 'html/dom/node_printing.dart'; + part 'html/dom/node_validator_builder.dart'; + part 'html/dom/parser.dart'; + part 'html/dom/shared_with_dart2js/css_class_set.dart'; + part 'html/dom/validators.dart'; + part 'html/dom/xml_document.dart'; diff --git a/lib/src/html/_html_parser.dart b/lib/src/html/_html_parser.dart index 779833c..dfeb7de 100644 --- a/lib/src/html/_html_parser.dart +++ b/lib/src/html/_html_parser.dart @@ -163,10 +163,9 @@ class _HtmlParser { if (name is html_parsing.AttributeName) { result.internalSetAttributeNSFromParser( namespaceUri: name.namespace, - qualifiedName: - name.prefix == null - ? name.name - : '${name.prefix}:${name.name}', + qualifiedName: name.prefix == null + ? name.name + : '${name.prefix}:${name.name}', localName: name.name, value: value, ); diff --git a/lib/src/html/api/animation.dart b/lib/src/html/api/animation.dart index 9648d5b..95b4610 100644 --- a/lib/src/html/api/animation.dart +++ b/lib/src/html/api/animation.dart @@ -105,6 +105,7 @@ abstract class AnimationEffectTiming extends AnimationEffectTimingReadOnly { String? fill; num? iterations; num? iterationStart; + AnimationEffectTiming._() : super._(); } @@ -114,6 +115,7 @@ abstract class AnimationEffectTimingReadOnly { abstract class AnimationTimeline { AnimationTimeline._(); + num get currentTime; } diff --git a/lib/src/html/api/canvas.dart b/lib/src/html/api/canvas.dart index e844fc1..f284671 100644 --- a/lib/src/html/api/canvas.dart +++ b/lib/src/html/api/canvas.dart @@ -48,6 +48,7 @@ part of '../../html.dart'; abstract class CanvasGradient { CanvasGradient._(); + void addColorStop(num offset, String color); } @@ -61,6 +62,7 @@ abstract class CanvasPattern { abstract class CanvasRenderingContext { CanvasRenderingContext._(); + CanvasElement get canvas; } @@ -92,6 +94,7 @@ class ImageData { throw ArgumentError.value(dataOrSw); } } + ImageData._(this.data, this.width, this.height); } @@ -129,6 +132,7 @@ abstract class OffscreenCanvasRenderingContext2D { Object? strokeStyle; String? textAlign; String? textBaseline; + OffscreenCanvasRenderingContext2D._(); void arc( diff --git a/lib/src/html/api/dom_matrix.dart b/lib/src/html/api/dom_matrix.dart index dbb40aa..387bbf8 100644 --- a/lib/src/html/api/dom_matrix.dart +++ b/lib/src/html/api/dom_matrix.dart @@ -103,26 +103,47 @@ abstract class DomMatrix extends DomMatrixReadOnly { abstract class DomMatrixReadOnly { int get a; + int get b; + int get c; + int get d; + int get e; + int get f; + int get m11; + int get m12; + int get m13; + int get m14; + int get m21; + int get m22; + int get m23; + int get m24; + int get m31; + int get m32; + int get m33; + int get m34; + int get m41; + int get m42; + int get m43; + int get m44; DomMatrix flipX(); diff --git a/lib/src/html/api/event.dart b/lib/src/html/api/event.dart index b25b103..5288656 100644 --- a/lib/src/html/api/event.dart +++ b/lib/src/html/api/event.dart @@ -152,9 +152,9 @@ class Event { this.composed = false, bool canBubble = true, this.cancelable = true, - }) : bubbles = canBubble, - _target = target, - timeStamp = DateTime.now().microsecondsSinceEpoch; + }) : bubbles = canBubble, + _target = target, + timeStamp = DateTime.now().microsecondsSinceEpoch; EventTarget? get currentTarget => _currentTarget; diff --git a/lib/src/html/api/event_source.dart b/lib/src/html/api/event_source.dart index a134bc4..6bc4f78 100644 --- a/lib/src/html/api/event_source.dart +++ b/lib/src/html/api/event_source.dart @@ -106,8 +106,7 @@ abstract class EventSourceOutsideBrowser implements EventSource { FutureOr Function( EventSourceOutsideBrowser eventSource, io.HttpClientRequest request, - )? - onHttpClientRequest; + )? onHttpClientRequest; /// A callback called when a [HttpClientResponse] arrives (only outside /// browsers). @@ -117,8 +116,7 @@ abstract class EventSourceOutsideBrowser implements EventSource { EventSourceOutsideBrowser eventSource, io.HttpClientRequest request, io.HttpClientResponse response, - )? - onHttpClientResponse; + )? onHttpClientResponse; Duration retryDuration = Duration(seconds: 3); } @@ -130,16 +128,14 @@ class _EventSource extends EventSource implements EventSourceOutsideBrowser { FutureOr Function( EventSourceOutsideBrowser eventSource, io.HttpClientRequest request, - )? - onHttpClientRequest; + )? onHttpClientRequest; @override FutureOr Function( EventSourceOutsideBrowser eventSource, io.HttpClientRequest request, io.HttpClientResponse response, - )? - onHttpClientResponse; + )? onHttpClientResponse; /// URL of this event source. @override @@ -333,10 +329,8 @@ class _EventSource extends EventSource implements EventSourceOutsideBrowser { httpResponse.listen((_) {}).cancel(); rethrow; } - yield* (httpResponse - .map((data) { - return data; - }) - .transform(transformer)); + yield* (httpResponse.map((data) { + return data; + }).transform(transformer)); } } diff --git a/lib/src/html/api/event_subclasses.dart b/lib/src/html/api/event_subclasses.dart index 2d159e4..8d53cfd 100644 --- a/lib/src/html/api/event_subclasses.dart +++ b/lib/src/html/api/event_subclasses.dart @@ -113,7 +113,7 @@ class BlobEvent extends Event { final num? timecode; BlobEvent(String type, [Map? dict]) - : this._(type, data: dict?['data'], timecode: dict?['timecode']); + : this._(type, data: dict?['data'], timecode: dict?['timecode']); BlobEvent._(super.type, {this.data, this.timecode}) : super.internal(); } @@ -152,7 +152,7 @@ class CloseEvent extends Event { final bool? wasClean; CloseEvent.constructor(super.type, {this.code, this.reason, this.wasClean}) - : super.internal(); + : super.internal(); } class CompositionEvent extends Event { @@ -242,13 +242,13 @@ class ErrorEvent extends Event { final String? message; ErrorEvent(String type, [Map? eventInitDict]) - : this.internal( - colno: eventInitDict?['colno'], - error: eventInitDict?['error'], - filename: eventInitDict?['filename'], - lineno: eventInitDict?['lineno'], - message: eventInitDict?['message'], - ); + : this.internal( + colno: eventInitDict?['colno'], + error: eventInitDict?['error'], + filename: eventInitDict?['filename'], + lineno: eventInitDict?['lineno'], + message: eventInitDict?['message'], + ); /// Internal constructor. __Not part of dart:html__. ErrorEvent.internal({ @@ -352,8 +352,8 @@ class KeyboardEvent extends UIEvent { this.shiftKey = false, super.canBubble, super.cancelable, - }) : charCode = charCode ?? -1, - keyCode = keyCode ?? -1; + }) : charCode = charCode ?? -1, + keyCode = keyCode ?? -1; String? get key => throw UnimplementedError(); @@ -408,10 +408,10 @@ class MessageEvent extends Event { String? lastEventId, this.source, List? messagePorts, - }) : lastEventId = lastEventId ?? '', - origin = origin ?? '', - ports = messagePorts ?? const [], - super.internal(); + }) : lastEventId = lastEventId ?? '', + origin = origin ?? '', + ports = messagePorts ?? const [], + super.internal(); String? get suborigin => null; } @@ -519,17 +519,17 @@ class MouseEvent extends UIEvent { super.cancelable, int super.detail = 0, super.view, - }) : buttons = 0, - _screenX = screenX, - _screenY = screenY, - _clientX = clientX, - _clientY = clientY, - _layerX = layerX, - _layerY = layerY, - _movementX = movementX, - _movementY = movementY, - _pageX = pageX, - _pageY = pageY; + }) : buttons = 0, + _screenX = screenX, + _screenY = screenY, + _clientX = clientX, + _clientY = clientY, + _layerX = layerX, + _layerY = layerY, + _movementX = movementX, + _movementY = movementY, + _pageX = pageX, + _pageY = pageY; Point get client => Point(_clientX!, _clientY!); @@ -568,7 +568,7 @@ class NotificationEvent extends ExtendableEvent { } NotificationEvent.internal({this.action, this.notification, this.reply}) - : super._('Notification'); + : super._('Notification'); } class PageTransitionEvent extends Event { @@ -621,18 +621,18 @@ class PointerEvent extends MouseEvent { EventTarget? relatedTarget, Object? view, }) : super._( - type, - view: view, - detail: detail, - button: button, - canBubble: canBubble, - cancelable: cancelable, - ctrlKey: ctrlKey, - altKey: altKey, - shiftKey: shiftKey, - metaKey: metaKey, - relatedTarget: relatedTarget, - ); + type, + view: view, + detail: detail, + button: button, + canBubble: canBubble, + cancelable: cancelable, + ctrlKey: ctrlKey, + altKey: altKey, + shiftKey: shiftKey, + metaKey: metaKey, + relatedTarget: relatedTarget, + ); } class PopStateEvent extends Event { @@ -641,7 +641,7 @@ class PopStateEvent extends Event { PopStateEvent(String type) : this._(type: type); PopStateEvent._({String type = 'popstate', this.state}) - : super.internal(type); + : super.internal(type); } class ProgressEvent extends Event { diff --git a/lib/src/html/api/geolocation.dart b/lib/src/html/api/geolocation.dart index 0209c8c..69d3ee2 100644 --- a/lib/src/html/api/geolocation.dart +++ b/lib/src/html/api/geolocation.dart @@ -100,12 +100,13 @@ class Geoposition { /// Internal constructor. __Not part of dart:html__. Geoposition.internal({required Coordinates? coords, required int? timestamp}) - : coords = coords ?? const Coordinates.internal(), - timestamp = timestamp ?? DateTime.now().millisecondsSinceEpoch; + : coords = coords ?? const Coordinates.internal(), + timestamp = timestamp ?? DateTime.now().millisecondsSinceEpoch; } class PositionError { final int code; final String message; + PositionError._(this.code, this.message); } diff --git a/lib/src/html/api/history.dart b/lib/src/html/api/history.dart index 21ed16a..0659ef1 100644 --- a/lib/src/html/api/history.dart +++ b/lib/src/html/api/history.dart @@ -131,7 +131,9 @@ class History extends HistoryBase { abstract class HistoryBase { void back(); + void forward(); + void go(int distance); } diff --git a/lib/src/html/api/http_request.dart b/lib/src/html/api/http_request.dart index a1bf1ae..053e622 100644 --- a/lib/src/html/api/http_request.dart +++ b/lib/src/html/api/http_request.dart @@ -844,10 +844,16 @@ abstract class HttpRequestUpload { HttpRequestUpload._(); Stream get onAbort; + Stream get onError; + Stream get onLoad; + Stream get onLoadEnd; + Stream get onLoadStart; + Stream get onProgress; + Stream get onTimeout; } diff --git a/lib/src/html/api/navigator_misc.dart b/lib/src/html/api/navigator_misc.dart index 3c7ffd0..e172e42 100644 --- a/lib/src/html/api/navigator_misc.dart +++ b/lib/src/html/api/navigator_misc.dart @@ -51,8 +51,8 @@ typedef StorageErrorCallback = void Function(DomError error); typedef StorageQuotaCallback = void Function(int grantedQuotaInBytes); -typedef StorageUsageCallback = - void Function(int currentUsageInBytes, int currentQuotaInBytes); +typedef StorageUsageCallback = void Function( + int currentUsageInBytes, int currentQuotaInBytes); class BudgetService { factory BudgetService._() { @@ -402,7 +402,9 @@ class PresentationRequest extends EventTarget { abstract class RelatedApplication { RelatedApplication._(); + String? get id; + String? get platform; String? get url; diff --git a/lib/src/html/api/web_rtc.dart b/lib/src/html/api/web_rtc.dart index 8bc79d9..ff190b7 100644 --- a/lib/src/html/api/web_rtc.dart +++ b/lib/src/html/api/web_rtc.dart @@ -266,7 +266,7 @@ abstract class RtcPeerConnection extends EventTarget { /// /// See [EventStreamProvider] for usage information. static const EventStreamProvider - iceCandidateEvent = EventStreamProvider( + iceCandidateEvent = EventStreamProvider( 'icecandidate', ); diff --git a/lib/src/html/api/web_socket.dart b/lib/src/html/api/web_socket.dart index 12f3746..c93e6e8 100644 --- a/lib/src/html/api/web_socket.dart +++ b/lib/src/html/api/web_socket.dart @@ -184,6 +184,7 @@ class WebSocket extends EventTarget { } @JSName('send') + /// Transmit data to the server over this connection. /// /// This method accepts data of type [Blob], [ByteBuffer], [String], or @@ -194,6 +195,7 @@ class WebSocket extends EventTarget { } @JSName('send') + /// Transmit data to the server over this connection. /// /// This method accepts data of type [Blob], [ByteBuffer], [String], or @@ -204,6 +206,7 @@ class WebSocket extends EventTarget { } @JSName('send') + /// Transmit data to the server over this connection. /// /// This method accepts data of type [Blob], [ByteBuffer], [String], or @@ -214,6 +217,7 @@ class WebSocket extends EventTarget { } @JSName('send') + /// Transmit data to the server over this connection. /// /// This method accepts data of type [Blob], [ByteBuffer], [String], or diff --git a/lib/src/html/api/window.dart b/lib/src/html/api/window.dart index 189a700..e561050 100644 --- a/lib/src/html/api/window.dart +++ b/lib/src/html/api/window.dart @@ -77,7 +77,7 @@ class Window extends EventTarget /// /// See [EventStreamProvider] for usage information. static const EventStreamProvider - deviceOrientationEvent = EventStreamProvider( + deviceOrientationEvent = EventStreamProvider( 'deviceorientation', ); @@ -380,8 +380,8 @@ class Window extends EventTarget required String href, this.outerWidth = 0, this.outerHeight = 0, - }) : _initialHref = href, - super.internal(); + }) : _initialHref = href, + super.internal(); /// Returns a Future that completes just before the window is about to /// repaint so the user can draw an animation frame. @@ -928,6 +928,7 @@ class Window extends EventTarget } @JSName('getMatchedCSSRules') + /// Returns all CSS rules that apply to the element's pseudo-element. List getMatchedCssRules(Element? element, String? pseudoElement) { throw UnimplementedError(); @@ -1060,6 +1061,7 @@ class Window extends EventTarget void resizeTo(int x, int y) {} @JSName('webkitResolveLocalFileSystemURL') + /// Asynchronously retrieves a local filesystem entry. /// /// ## Other resources diff --git a/lib/src/html/api/window_misc.dart b/lib/src/html/api/window_misc.dart index cc8f231..b5fb4b1 100644 --- a/lib/src/html/api/window_misc.dart +++ b/lib/src/html/api/window_misc.dart @@ -166,7 +166,7 @@ class ScreenOrientation extends EventTarget { final String type; ScreenOrientation.constructor({this.angle = 1, this.type = 'vertical'}) - : super.internal(); + : super.internal(); Stream get onChange => changeEvent.forTarget(this); diff --git a/lib/src/html/dom/css_computed_style.dart b/lib/src/html/dom/css_computed_style.dart index 54e4945..de3d3dc 100644 --- a/lib/src/html/dom/css_computed_style.dart +++ b/lib/src/html/dom/css_computed_style.dart @@ -161,9 +161,8 @@ class _ComputedStyle extends CssStyleDeclaration { } final parent = node.parent; if (parent == null) { - for (var styleSheet - in (node.ownerDocument as HtmlDocument).styleSheets ?? - const []) { + for (var styleSheet in (node.ownerDocument as HtmlDocument).styleSheets ?? + const []) { if (!result.contains(styleSheet)) { result.add(styleSheet); } diff --git a/lib/src/html/dom/css_rect.dart b/lib/src/html/dom/css_rect.dart index 40eaacc..0a5b49a 100644 --- a/lib/src/html/dom/css_rect.dart +++ b/lib/src/html/dom/css_rect.dart @@ -78,11 +78,11 @@ abstract class CssRect implements Rectangle { @override int get hashCode => _JenkinsSmiHash.hash4( - left.hashCode, - top.hashCode, - right.hashCode, - bottom.hashCode, - ); + left.hashCode, + top.hashCode, + right.hashCode, + bottom.hashCode, + ); /// The height of this rectangle. /// @@ -240,28 +240,25 @@ abstract class CssRect implements Rectangle { // The border-box and default box model both exclude margin in the regular // height/width calculation, so add it if we want it for this measurement. if (augmentingMeasurement == _marginProperty) { - val += - Dimension.css( - styles.getPropertyValue('$augmentingMeasurement-$measurement'), - ).value; + val += Dimension.css( + styles.getPropertyValue('$augmentingMeasurement-$measurement'), + ).value; } // The border-box includes padding and border, so remove it if we want // just the content itself. if (augmentingMeasurement == _content) { - val -= - Dimension.css( - styles.getPropertyValue('$_paddingProperty-$measurement'), - ).value; + val -= Dimension.css( + styles.getPropertyValue('$_paddingProperty-$measurement'), + ).value; } // At this point, we don't wan't to augment with border or margin, // so remove border. if (augmentingMeasurement != _marginProperty) { - val -= - Dimension.css( - styles.getPropertyValue('border-$measurement-width'), - ).value; + val -= Dimension.css( + styles.getPropertyValue('border-$measurement-width'), + ).value; } } return val; @@ -273,6 +270,7 @@ abstract class CssRect implements Rectangle { /// [box model](http://www.w3.org/TR/CSS2/box.html). class _BorderCssRect extends CssRect { _BorderCssRect(super.element); + @override num get height => _element.offsetHeight; @@ -292,8 +290,8 @@ class _ContentCssListRect extends _ContentCssRect { final List _elementList; _ContentCssListRect(List elementList) - : _elementList = elementList, - super(elementList.first); + : _elementList = elementList, + super(elementList.first); /// Set the height to `newHeight`. /// @@ -425,6 +423,7 @@ class _JenkinsSmiHash { /// [box model](http://www.w3.org/TR/CSS2/box.html). class _MarginCssRect extends CssRect { _MarginCssRect(super.element); + @override num get height => _element.offsetHeight + diff --git a/lib/src/html/dom/css_style_declaration_set.dart b/lib/src/html/dom/css_style_declaration_set.dart index fd65952..3aaad09 100644 --- a/lib/src/html/dom/css_style_declaration_set.dart +++ b/lib/src/html/dom/css_style_declaration_set.dart @@ -618,9 +618,9 @@ class _CssStyleDeclarationSet extends CssStyleDeclarationBase { } } - // Important note: CssStyleDeclarationSet does NOT implement every method - // available in CssStyleDeclaration. Some of the methods don't make so much - // sense in terms of having a resonable value to return when you're - // considering a list of Elements. You will need to manually add any of the - // items in the MEMBERS set if you want that functionality. +// Important note: CssStyleDeclarationSet does NOT implement every method +// available in CssStyleDeclaration. Some of the methods don't make so much +// sense in terms of having a resonable value to return when you're +// considering a list of Elements. You will need to manually add any of the +// items in the MEMBERS set if you want that functionality. } diff --git a/lib/src/html/dom/document.dart b/lib/src/html/dom/document.dart index 44b4363..32b0cdc 100644 --- a/lib/src/html/dom/document.dart +++ b/lib/src/html/dom/document.dart @@ -66,10 +66,10 @@ abstract class Document extends Node /// /// See [EventStreamProvider] for usage information. static const EventStreamProvider - securityPolicyViolationEvent = + securityPolicyViolationEvent = EventStreamProvider( - 'securitypolicyviolation', - ); + 'securitypolicyviolation', + ); /// Static factory designed to expose `selectionchange` events to event /// handlers that are not necessarily instances of [Document]. @@ -98,7 +98,7 @@ abstract class Document extends Node } Document._({required this.contentType, required this.window, this.origin}) - : super._document(); + : super._document(); /// Outside the browser, returns null. Element? get activeElement => null; diff --git a/lib/src/html/dom/element.dart b/lib/src/html/dom/element.dart index df013a7..113f7ed 100644 --- a/lib/src/html/dom/element.dart +++ b/lib/src/html/dom/element.dart @@ -555,12 +555,10 @@ abstract class Element extends Node @override late final InternalElementData internalElementData = ownerDocument! - .window - .internalWindowController - .windowBehavior + .window.internalWindowController.windowBehavior .newInternalElementData( - element: this as universal_html_in_browser_or_vm.Element, - ); + element: this as universal_html_in_browser_or_vm.Element, + ); /// Creates a new `` element. /// @@ -593,9 +591,9 @@ abstract class Element extends Node factory Element.canvas() = CanvasElement; Element.created() - : _nodeName = '', - _lowerCaseTagName = '', - super._(window.document) { + : _nodeName = '', + _lowerCaseTagName = '', + super._(window.document) { throw UnimplementedError(); } @@ -666,7 +664,7 @@ abstract class Element extends Node /// Internal constructor. __Not part of dart:html__. Element.internal(Document document, String tagName) - : this._(document, tagName); + : this._(document, tagName); /// Internal constructor. __Not part of dart:html__. factory Element.internalTag( @@ -789,10 +787,10 @@ abstract class Element extends Node /// Internal constructor that does not normalize or validate element name. /// Used by Element subclasses such as [AnchorElement]. Element._(Document super.ownerDocument, String nodeName) - : _nodeName = nodeName, - _lowerCaseTagName = - ownerDocument is XmlDocument ? nodeName : nodeName.toLowerCase(), - super._(); + : _nodeName = nodeName, + _lowerCaseTagName = + ownerDocument is XmlDocument ? nodeName : nodeName.toLowerCase(), + super._(); factory Element._internalTag( Document ownerDocument, diff --git a/lib/src/html/dom/element_subclasses.dart b/lib/src/html/dom/element_subclasses.dart index 4d8982a..7b54d66 100644 --- a/lib/src/html/dom/element_subclasses.dart +++ b/lib/src/html/dom/element_subclasses.dart @@ -102,7 +102,7 @@ class AreaElement extends HtmlElement factory AreaElement() => AreaElement._(window.document); AreaElement._(Document ownerDocument, {String nodeName = 'AREA'}) - : super._(ownerDocument, nodeName); + : super._(ownerDocument, nodeName); String? get download => _getAttribute('download'); @@ -387,7 +387,7 @@ class CanvasElement extends HtmlElement implements CanvasImageSource { late final CanvasRenderingContext2D context2D = throw UnimplementedError(); CanvasElement({int? width, int? height}) - : super._(window.document, 'CANVAS') { + : super._(window.document, 'CANVAS') { if (width != null) { _setAttributeInt('width', width); } @@ -545,7 +545,7 @@ class DataListElement extends HtmlElement { factory DataListElement() => DataListElement._(window.document); DataListElement._(Document ownerDocument) - : super._(ownerDocument, 'DATALIST'); + : super._(ownerDocument, 'DATALIST'); @override Element _newInstance(Document ownerDocument) => @@ -622,10 +622,8 @@ class DomTokenList { void add(String tokens) { final list = _getList(); - final splitTokens = tokens - .split(' ') - .map((e) => e.trim()) - .where((e) => e.isNotEmpty); + final splitTokens = + tokens.split(' ').map((e) => e.trim()).where((e) => e.isNotEmpty); list.addAll(splitTokens); _setList(list); } @@ -640,10 +638,8 @@ class DomTokenList { void remove(String tokens) { final list = _getList(); - final splitTokens = tokens - .split(' ') - .map((e) => e.trim()) - .where((e) => e.isNotEmpty); + final splitTokens = + tokens.split(' ').map((e) => e.trim()).where((e) => e.isNotEmpty); for (var token in splitTokens) { list.remove(token); } @@ -706,7 +702,7 @@ class FieldSetElement extends HtmlElement with _FormFieldElement { factory FieldSetElement() => FieldSetElement._(window.document); FieldSetElement._(Document ownerDocument) - : super._(ownerDocument, 'FIELDSET'); + : super._(ownerDocument, 'FIELDSET'); bool get disabled => _getAttributeBool('disabled'); @@ -790,8 +786,8 @@ class FormElement extends HtmlElement { /// Returns all items of this form. Iterable get _items { return _treeAsIterable(this).whereType().where( - (element) => identical(element.form, this), - ); + (element) => identical(element.form, this), + ); } bool checkValidity() { @@ -2219,7 +2215,7 @@ class OptGroupElement extends HtmlElement { factory OptGroupElement() => OptGroupElement._(window.document); OptGroupElement._(Document ownerDocument) - : super._(ownerDocument, 'OPTGROUP'); + : super._(ownerDocument, 'OPTGROUP'); bool get disabled => _getAttributeBool('disabled'); @@ -2238,7 +2234,7 @@ class OptionElement extends HtmlElement bool? _selected; OptionElement({String data = '', String value = '', bool selected = false}) - : super._(window.document, 'option') { + : super._(window.document, 'option') { if (data.isNotEmpty) { appendText(data); } @@ -2256,7 +2252,7 @@ class OptionElement extends HtmlElement OptionElement.created() : super.created(); OptionElement._(Document ownerDocument, {String nodeName = 'OPTION'}) - : super._(ownerDocument, nodeName); + : super._(ownerDocument, nodeName); bool get defaultSelected => _getAttributeBool('selected'); @@ -2358,7 +2354,7 @@ class ParagraphElement extends HtmlElement { factory ParagraphElement() => ParagraphElement._(window.document); ParagraphElement._(Document ownerDocument, {String nodeName = 'P'}) - : super._(ownerDocument, nodeName); + : super._(ownerDocument, nodeName); @override Element _newInstance(Document ownerDocument) => @@ -2390,7 +2386,7 @@ class PictureElement extends HtmlElement { factory PictureElement.created() => PictureElement._(window.document); PictureElement._(Document ownerDocument, {String nodeName = 'PICTURE'}) - : super._(ownerDocument, nodeName); + : super._(ownerDocument, nodeName); @override Element _newInstance(Document ownerDocument) => @@ -2401,7 +2397,7 @@ class PreElement extends HtmlElement { factory PreElement() => PreElement._(window.document); PreElement._(Document ownerDocument, {String nodeName = 'PRE'}) - : super._(ownerDocument, nodeName); + : super._(ownerDocument, nodeName); @override Element _newInstance(Document ownerDocument) => PreElement._(ownerDocument); @@ -2413,7 +2409,7 @@ class ProgressElement extends HtmlElement { factory ProgressElement() => ProgressElement._(window.document); ProgressElement._(Document ownerDocument, {String nodeName = 'PROGRESS'}) - : super._(ownerDocument, nodeName); + : super._(ownerDocument, nodeName); num? get max => _getAttributeNum('max', defaultValue: null); @@ -2445,7 +2441,7 @@ class ScriptElement extends HtmlElement { factory ScriptElement() => ScriptElement._(window.document); ScriptElement._(Document ownerDocument, {String nodeName = 'SCRIPT'}) - : super._(ownerDocument, nodeName); + : super._(ownerDocument, nodeName); bool get async => _getAttributeBool('async'); @@ -2774,7 +2770,7 @@ class TableCaptionElement extends HtmlElement { factory TableCaptionElement() => TableCaptionElement._(window.document); TableCaptionElement._(Document ownerDocument) - : super._(ownerDocument, 'CAPTION'); + : super._(ownerDocument, 'CAPTION'); @override Element _newInstance(Document ownerDocument) => @@ -2918,9 +2914,9 @@ class TableElement extends HtmlElement { required T Function() constructor, }) { final existing = children.whereType().firstWhere( - (e) => e != null && e._lowerCaseTagName == lowerCaseTagName, - orElse: () => null, - ); + (e) => e != null && e._lowerCaseTagName == lowerCaseTagName, + orElse: () => null, + ); if (existing != null) { return existing; } @@ -3044,7 +3040,7 @@ class TemplateElement extends HtmlElement { factory TemplateElement() => TemplateElement._(window.document); TemplateElement._(Document ownerDocument) - : super._(ownerDocument, 'TEMPLATE'); + : super._(ownerDocument, 'TEMPLATE'); DocumentFragment get content { throw UnimplementedError(); @@ -3090,7 +3086,7 @@ class TextAreaElement extends HtmlElement TextAreaElement.created() : super.created(); TextAreaElement._(Document ownerDocument) - : super._(ownerDocument, 'TEXTAREA'); + : super._(ownerDocument, 'TEXTAREA'); String? get autocapitalize => _getAttribute('autocapitalize'); diff --git a/lib/src/html/dom/element_subclasses_for_inputs.dart b/lib/src/html/dom/element_subclasses_for_inputs.dart index 5c6502a..c0784f4 100644 --- a/lib/src/html/dom/element_subclasses_for_inputs.dart +++ b/lib/src/html/dom/element_subclasses_for_inputs.dart @@ -62,7 +62,9 @@ abstract class DateInputElement implements RangeInputElementBase { bool? readOnly; bool required = false; + factory DateInputElement() => InputElement(type: 'date'); + DateTime get valueAsDate => throw UnimplementedError(); set valueAsDate(DateTime value); @@ -179,7 +181,9 @@ abstract class MonthInputElement implements RangeInputElementBase { bool? readOnly; bool required = false; + factory MonthInputElement() => InputElement(type: 'month'); + DateTime get valueAsDate; set valueAsDate(DateTime value); @@ -316,6 +320,7 @@ abstract class WeekInputElement implements RangeInputElementBase { bool? readOnly; bool required = false; + factory WeekInputElement() => InputElement(type: 'week'); DateTime? get valueAsDate => throw UnimplementedError(); diff --git a/lib/src/html/dom/html_node_validator.dart b/lib/src/html/dom/html_node_validator.dart index 9ab4d75..3c76139 100644 --- a/lib/src/html/dom/html_node_validator.dart +++ b/lib/src/html/dom/html_node_validator.dart @@ -445,7 +445,7 @@ class _Html5NodeValidator implements NodeValidator { /// All known URI attributes will be validated against the UriPolicy, if /// [uriPolicy] is null then a default UriPolicy will be used. _Html5NodeValidator({UriPolicy? uriPolicy}) - : uriPolicy = uriPolicy ?? UriPolicy() { + : uriPolicy = uriPolicy ?? UriPolicy() { if (_attributeValidators.isEmpty) { for (var attr in _standardAttributes) { _attributeValidators[attr] = _standardAttributeValidator; diff --git a/lib/src/html/dom/node.dart b/lib/src/html/dom/node.dart index 06f2df0..ee8546c 100644 --- a/lib/src/html/dom/node.dart +++ b/lib/src/html/dom/node.dart @@ -52,7 +52,9 @@ abstract class CharacterData extends Node with _ChildNode, _NonDocumentTypeChildNode implements ChildNode, NonDocumentTypeChildNode { String _data = ''; + CharacterData._(Document super.ownerDocument, this._data) : super._(); + String? get data => _data; set data(String? value) { @@ -136,8 +138,11 @@ abstract class CharacterData extends Node abstract class ChildNode { ChildNode._(); + void after(Object nodes); + void before(Object nodes); + void remove(); } @@ -150,7 +155,7 @@ class Comment extends CharacterData { } Comment.internal(Document ownerDocument, String? value) - : super._(ownerDocument, value ?? ''); + : super._(ownerDocument, value ?? ''); @override int get nodeType => Node.COMMENT_NODE; @@ -168,7 +173,7 @@ class InternalDocumentType extends Node { /// Internal constructor. __Not part of dart:html__. InternalDocumentType.internal(Document super.ownerDocument, this._value) - : super._(); + : super._(); @override String get nodeName { @@ -225,7 +230,9 @@ abstract class Node extends EventTarget { Node._(this.ownerDocument) : super.internal(); /// Constructor used by [Document]. - Node._document() : ownerDocument = null, super.internal(); + Node._document() + : ownerDocument = null, + super.internal(); String? get baseUri { return ownerDocument?.baseUri; @@ -534,12 +541,15 @@ abstract class Node extends EventTarget { abstract class NonDocumentTypeChildNode { NonDocumentTypeChildNode._(); + Element? get nextElementSibling; + Element? get previousElementSibling; } abstract class ParentNode { ParentNode._(); + Element? querySelector(String selectors); } diff --git a/lib/src/html/dom/node_validator_builder.dart b/lib/src/html/dom/node_validator_builder.dart index 2171c6b..a3071a0 100644 --- a/lib/src/html/dom/node_validator_builder.dart +++ b/lib/src/html/dom/node_validator_builder.dart @@ -112,13 +112,11 @@ class NodeValidatorBuilder implements NodeValidator { Iterable? uriAttributes, }) { var tagNameUpper = tagName.toUpperCase(); - var attrs = - attributes?.map( + var attrs = attributes?.map( (name) => '$tagNameUpper::${name.toLowerCase()}', ) ?? const []; - var uriAttrs = - uriAttributes?.map( + var uriAttrs = uriAttributes?.map( (name) => '$tagNameUpper::${name.toLowerCase()}', ) ?? const []; @@ -225,13 +223,11 @@ class NodeValidatorBuilder implements NodeValidator { }) { var baseNameUpper = baseName.toUpperCase(); var tagNameUpper = tagName.toUpperCase(); - var attrs = - attributes?.map( + var attrs = attributes?.map( (name) => '$baseNameUpper::${name.toLowerCase()}', ) ?? const []; - var uriAttrs = - uriAttributes?.map( + var uriAttrs = uriAttributes?.map( (name) => '$baseNameUpper::${name.toLowerCase()}', ) ?? const []; @@ -296,13 +292,13 @@ class _CustomElementNodeValidator extends _SimpleNodeValidator { Iterable allowedUriAttributes, bool allowTypeExtension, bool allowCustomTag, - ) : allowTypeExtension = allowTypeExtension == true, - allowCustomTag = allowCustomTag == true, - super( - allowedElements: allowedElements, - allowedAttributes: allowedAttributes, - allowedUriAttributes: allowedUriAttributes, - ); + ) : allowTypeExtension = allowTypeExtension == true, + allowCustomTag = allowCustomTag == true, + super( + allowedElements: allowedElements, + allowedAttributes: allowedAttributes, + allowedUriAttributes: allowedUriAttributes, + ); @override bool allowsAttribute(Element element, String attributeName, String value) { @@ -496,12 +492,12 @@ class _TemplatingNodeValidator extends _SimpleNodeValidator { final Set _templateAttrs; _TemplatingNodeValidator() - : _templateAttrs = Set.from(_TEMPLATE_ATTRS), - super( - null, - allowedElements: ['TEMPLATE'], - allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr'), - ); + : _templateAttrs = Set.from(_TEMPLATE_ATTRS), + super( + null, + allowedElements: ['TEMPLATE'], + allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr'), + ); @override bool allowsAttribute(Element element, String attributeName, String value) { diff --git a/lib/src/html/dom/shared_with_dart2js/css_class_set.dart b/lib/src/html/dom/shared_with_dart2js/css_class_set.dart index feff6c7..253ca2e 100644 --- a/lib/src/html/dom/shared_with_dart2js/css_class_set.dart +++ b/lib/src/html/dom/shared_with_dart2js/css_class_set.dart @@ -220,7 +220,8 @@ abstract class _CssClassSetImpl extends SetBase implements CssClassSet { String firstWhere( bool Function(String value) test, { String Function()? orElse, - }) => readClasses().firstWhere(test, orElse: orElse); + }) => + readClasses().firstWhere(test, orElse: orElse); @override T fold( @@ -246,7 +247,8 @@ abstract class _CssClassSetImpl extends SetBase implements CssClassSet { String lastWhere( bool Function(String value) test, { String Function()? orElse, - }) => readClasses().lastWhere(test, orElse: orElse); + }) => + readClasses().lastWhere(test, orElse: orElse); /// Lookup from the Set interface. Not interesting for a String set. @override @@ -325,7 +327,8 @@ abstract class _CssClassSetImpl extends SetBase implements CssClassSet { String singleWhere( bool Function(String value) test, { String Function()? orElse, - }) => readClasses().singleWhere(test, orElse: orElse); + }) => + readClasses().singleWhere(test, orElse: orElse); @override Iterable skip(int n) => readClasses().skip(n); @@ -391,6 +394,7 @@ abstract class _CssClassSetImpl extends SetBase implements CssClassSet { @override Set union(Set other) => readClasses().union(other); + // interface Set - END @override @@ -486,9 +490,9 @@ class _MultiElementCssClassSet extends _CssClassSetImpl { /// [removeClass](http://api.jquery.com/removeClass/). @override bool remove(Object? value) => _sets.fold( - false, - (bool changed, _CssClassSetImpl e) => e.remove(value) || changed, - ); + false, + (bool changed, _CssClassSetImpl e) => e.remove(value) || changed, + ); /// Adds the class [value] to the element if it is not on it, removes it if it /// is. @@ -497,9 +501,10 @@ class _MultiElementCssClassSet extends _CssClassSetImpl { /// underlying toggle returns an 'is set' flag. @override bool toggle(String value, [bool? shouldAdd]) => _sets.fold( - false, - (bool changed, _CssClassSetImpl e) => e.toggle(value, shouldAdd) || changed, - ); + false, + (bool changed, _CssClassSetImpl e) => + e.toggle(value, shouldAdd) || changed, + ); @override void writeClasses(Set s) { diff --git a/lib/src/html/dom/shared_with_dart2js/metadata.dart b/lib/src/html/dom/shared_with_dart2js/metadata.dart index 0f2c1a8..9e37a40 100644 --- a/lib/src/html/dom/shared_with_dart2js/metadata.dart +++ b/lib/src/html/dom/shared_with_dart2js/metadata.dart @@ -48,6 +48,7 @@ class DocsEditable { /// [name] should be formatted as `interface.member`. class DomName { final String name; + const DomName(this.name); } @@ -75,12 +76,14 @@ class Experimental { /// } class JSName { final String name; + const JSName(this.name); } /// Marks a class as native and defines its JavaScript name(s). class Native { final String name; + const Native(this.name); } diff --git a/lib/src/html/dom/validators.dart b/lib/src/html/dom/validators.dart index 6f06c1d..973c22a 100644 --- a/lib/src/html/dom/validators.dart +++ b/lib/src/html/dom/validators.dart @@ -322,10 +322,9 @@ class _ValidatingTreeSanitizer implements NodeTreeSanitizer { // On IE, erratically, the hasCorruptedAttributes test can return false, // even though it clearly is corrupted. A separate copy of the test // inlining just the basic check seems to help. - corrupted = - corruptedTest1 - ? true - : Element._hasCorruptedAttributesAdditionalCheck(element); + corrupted = corruptedTest1 + ? true + : Element._hasCorruptedAttributesAdditionalCheck(element); } catch (e) { // Ignore } diff --git a/lib/src/parsing/parsing.dart b/lib/src/parsing/parsing.dart index 25fbcd5..1661efd 100644 --- a/lib/src/parsing/parsing.dart +++ b/lib/src/parsing/parsing.dart @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -import 'package:universal_html/html.dart'; import 'package:universal_html/html.dart' as universal_html; +import 'package:universal_html/html.dart'; import 'parsing_impl_browser.dart' if (dart.library.html) 'parsing_impl_browser.dart' // Browser if (dart.library.io) 'parsing_impl_vm.dart' // VM - if (dart.library.js) 'parsing_impl_vm.dart' - as impl; // Node.JS + if (dart.library.js) 'parsing_impl_vm.dart' as impl; // Node.JS /// Parses a [HtmlDocument]. /// diff --git a/lib/universal_html.dart b/lib/universal_html.dart new file mode 100644 index 0000000..c6a68d4 --- /dev/null +++ b/lib/universal_html.dart @@ -0,0 +1,38 @@ +// Copyright 2019 terrier989@gmail.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/// Cross-platform "dart:html" library. +/// +/// You can choose from the following libraries: +/// * `package:universal_html/html.dart` +/// * `package:universal_html/prefer_sdk/html.dart` +/// * `package:universal_html/prefer_universal/html.dart` +/// +/// # Introduction +/// +/// HTML elements and other resources for web-based applications that need to +/// interact with the browser and the DOM (Document Object Model). +/// +/// This library includes DOM element types, CSS styling, local storage, +/// media, speech, events, and more. +/// To get started, +/// check out the [Element] class, the base class for many of the HTML +/// DOM types. +/// +/// For information on writing web apps with Dart, see https://webdev.dartlang.org. +library; + +export 'src/_sdk/html.dart' + if (dart.library.js_interop) 'src/_sdk/html.dart' // Browser + if (dart.library.io) 'src/html.dart'; // VM diff --git a/pubspec.yaml b/pubspec.yaml index bb04929..996096d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,12 +1,12 @@ name: universal_html -version: 2.2.6 +version: 2.2.7 description: A 'dart:html' that works in all platforms, including Flutter and server-side. Eases cross-platform development and HTML / XML processing. homepage: https://github.com/dint-dev/universal_html environment: - sdk: ^3.0.0 + sdk: ^3.6.0 dependencies: async: ^2.11.0 @@ -17,7 +17,7 @@ dependencies: meta: ^1.9.1 source_span: ^1.9.1 typed_data: ^1.3.2 - universal_io: ^2.2.3 + universal_io: ^2.3.1 dev_dependencies: lints: '>=3.0.0 <7.0.0' diff --git a/test/src/html/dom/css_queries.dart b/test/src/html/dom/css_queries.dart index 3f9415b..7453580 100644 --- a/test/src/html/dom/css_queries.dart +++ b/test/src/html/dom/css_queries.dart @@ -54,8 +54,7 @@ void _testCss() { expect( element.matches(selector), matcher, - reason: - 'Element: "$idOrOuterHtml"\n' + reason: 'Element: "$idOrOuterHtml"\n' 'Selector: "$selector"\n' 'Tree: ${root.outerHtml}', ); @@ -108,33 +107,30 @@ void _testCss() { expectMatches(e, ':not(div)', isFalse); }); test(':first-child', () { - final e = - DivElement() - ..id = 'e0' - ..append(DivElement()..id = 'e1') - ..append(DivElement()..id = 'e2'); + final e = DivElement() + ..id = 'e0' + ..append(DivElement()..id = 'e1') + ..append(DivElement()..id = 'e2'); expectMatches(e.firstChild as Element, ':first-child', isTrue); expectMatches(e.lastChild as Element, ':first-child', isFalse); }); test(':last-child', () { - final e = - DivElement() - ..id = 'e0' - ..append(DivElement()..id = 'e1') - ..append(DivElement()..id = 'e2'); + final e = DivElement() + ..id = 'e0' + ..append(DivElement()..id = 'e1') + ..append(DivElement()..id = 'e2'); expectMatches(e.firstChild as Element, ':last-child', isFalse); expectMatches(e.lastChild as Element, ':last-child', isTrue); }); test(':nth-child(2)', () { - final e = + final e = DivElement() + ..id = 'root' + ..append( DivElement() - ..id = 'root' - ..append( - DivElement() - ..id = 'child0' - ..append(DivElement()..append(DivElement())), - ) - ..append(DivElement()..id = 'child1'); + ..id = 'child0' + ..append(DivElement()..append(DivElement())), + ) + ..append(DivElement()..id = 'child1'); expectMatches(e.childNodes[0] as Element, ':nth-child(1)', isTrue); expectMatches(e.childNodes[0] as Element, ':nth-child(2)', isFalse); expectMatches(e.childNodes[1] as Element, ':nth-child(1)', isFalse); @@ -151,26 +147,24 @@ void _testCss() { expect(p.querySelectorAll('#root div:nth-child(3)'), hasLength(0)); }); test(':nth-child(2n)', () { - final e = - DivElement() - ..id = 'root' - ..append(DivElement()..id = 'child0') - ..append(DivElement()..id = 'child1') - ..append(DivElement()..id = 'child2') - ..append(DivElement()..id = 'child3'); + final e = DivElement() + ..id = 'root' + ..append(DivElement()..id = 'child0') + ..append(DivElement()..id = 'child1') + ..append(DivElement()..id = 'child2') + ..append(DivElement()..id = 'child3'); expectMatches(e.childNodes[0] as Element, ':nth-child(2n)', isFalse); expectMatches(e.childNodes[1] as Element, ':nth-child(2n)', isTrue); expectMatches(e.childNodes[2] as Element, ':nth-child(2n)', isFalse); expectMatches(e.childNodes[3] as Element, ':nth-child(2n)', isTrue); }); test(':nth-child(2n+1)', () { - final e = - DivElement() - ..id = 'root' - ..append(DivElement()..id = 'child0') - ..append(DivElement()..id = 'child1') - ..append(DivElement()..id = 'child2') - ..append(DivElement()..id = 'child3'); + final e = DivElement() + ..id = 'root' + ..append(DivElement()..id = 'child0') + ..append(DivElement()..id = 'child1') + ..append(DivElement()..id = 'child2') + ..append(DivElement()..id = 'child3'); expectMatches(e.childNodes[0] as Element, ':nth-child(2n+1)', isTrue); expectMatches(e.childNodes[1] as Element, ':nth-child(2n+1)', isFalse); expectMatches(e.childNodes[2] as Element, ':nth-child(2n+1)', isTrue); @@ -228,26 +222,21 @@ void _testCss() { }); test('Complex example #1', () { - final e0 = - DivElement() - ..id = 'e0' - ..className = 'c0 all'; - final e0_0 = - DivElement() - ..id = 'e0_0' - ..className = 'c0_0 all'; - final e0_1 = - DivElement() - ..id = 'e0_1' - ..className = 'c0_1 all'; - final e0_2 = - DivElement() - ..id = 'e0_2' - ..className = 'c0_2 all'; - final e0_2_0 = - DivElement() - ..id = 'e0_2_0' - ..className = 'c0_2_0 all'; + final e0 = DivElement() + ..id = 'e0' + ..className = 'c0 all'; + final e0_0 = DivElement() + ..id = 'e0_0' + ..className = 'c0_0 all'; + final e0_1 = DivElement() + ..id = 'e0_1' + ..className = 'c0_1 all'; + final e0_2 = DivElement() + ..id = 'e0_2' + ..className = 'c0_2 all'; + final e0_2_0 = DivElement() + ..id = 'e0_2_0' + ..className = 'c0_2_0 all'; e0.append((e0_0)); e0.append(e0_1); e0.append(e0_2); @@ -336,35 +325,29 @@ void _testCss() { test('Complex example #1', () { final root = DivElement(); - final e0 = - DivElement() - ..id = 'e0' - ..className = 'all'; + final e0 = DivElement() + ..id = 'e0' + ..className = 'all'; - final e0_0 = - DivElement() - ..id = 'e0-0' - ..className = 'all'; + final e0_0 = DivElement() + ..id = 'e0-0' + ..className = 'all'; - final e0_1 = - DivElement() - ..id = 'e0-1' - ..className = 'all'; + final e0_1 = DivElement() + ..id = 'e0-1' + ..className = 'all'; - final e0_2 = - Element.nav() - ..id = 'e0-2' - ..className = 'all'; + final e0_2 = Element.nav() + ..id = 'e0-2' + ..className = 'all'; - final e0_2_0 = - DivElement() - ..id = 'e0-2-0' - ..className = 'all'; + final e0_2_0 = DivElement() + ..id = 'e0-2-0' + ..className = 'all'; - final e1 = - DivElement() - ..id = 'e1' - ..className = 'all last'; + final e1 = DivElement() + ..id = 'e1' + ..className = 'all last'; root.append(e0); e0.append((e0_0)); diff --git a/test/src/html/dom/document.dart b/test/src/html/dom/document.dart index a96eda3..c3979e2 100644 --- a/test/src/html/dom/document.dart +++ b/test/src/html/dom/document.dart @@ -90,10 +90,9 @@ void _testDocument() { _expectSaneDocument(document); // Insert - final n0N0 = - Element.tag('div') - ..setAttribute('id', 'n0_n0') - ..id = 'n0_n0'; + final n0N0 = Element.tag('div') + ..setAttribute('id', 'n0_n0') + ..id = 'n0_n0'; n0.insertBefore(n0N0, n0N2); // Document: diff --git a/test/src/html/dom/element.dart b/test/src/html/dom/element.dart index 964e6d1..d81f6bd 100644 --- a/test/src/html/dom/element.dart +++ b/test/src/html/dom/element.dart @@ -60,21 +60,19 @@ void _testElement() { group('innerHtml:', () { test('attributes', () { - final input = - Element.tag('a') - ..setAttribute('someAttribute', 'someValue') - ..appendText('a') - ..appendText('b') - ..appendText('c'); + final input = Element.tag('a') + ..setAttribute('someAttribute', 'someValue') + ..appendText('a') + ..appendText('b') + ..appendText('c'); expect(input.innerHtml, 'abc'); }); test('text, comments', () { - final input = - Element.tag('a') - ..appendText('a') - ..append(Comment('b')) - ..appendText('c'); + final input = Element.tag('a') + ..appendText('a') + ..append(Comment('b')) + ..appendText('c'); expect(input.innerHtml, 'ac'); }); }); @@ -127,10 +125,9 @@ void _testElement() { }); test('uses lowerCase for element/attribute names', () { - final input = - Element.tag('aA') - ..setAttribute('bB', 'cC') - ..appendText('dD'); + final input = Element.tag('aA') + ..setAttribute('bB', 'cC') + ..appendText('dD'); final expected = 'dD'; expect(input.outerHtml, equals(expected)); }); @@ -204,34 +201,31 @@ void _testElement() { }); test('supports multiple attributes', () { - final input = - Element.tag('a') - ..className = 'x' - ..setAttribute('id', 'y') - ..setAttribute('href', 'z'); + final input = Element.tag('a') + ..className = 'x' + ..setAttribute('id', 'y') + ..setAttribute('href', 'z'); final expected = ''; expect(input.outerHtml, equals(expected)); }); test('supports multiple children', () { - final input = - Element.tag('sometag') - ..appendText('a') - ..append(Element.tag('b')..appendText('c')) - ..append(Comment('d')); + final input = Element.tag('sometag') + ..appendText('a') + ..append(Element.tag('b')..appendText('c')) + ..append(Comment('d')); final expected = 'ac'; expect(input.outerHtml, equals(expected)); }); test('supports multiple attributes and multiple children', () { - final input = - Element.tag('sometag') - ..className = 'x' - ..setAttribute('k0', 'v0') - ..setAttribute('k1', 'v1') - ..appendText('a') - ..append(Element.tag('b')..appendText('c')) - ..append(Comment('d')); + final input = Element.tag('sometag') + ..className = 'x' + ..setAttribute('k0', 'v0') + ..setAttribute('k1', 'v1') + ..appendText('a') + ..append(Element.tag('b')..appendText('c')) + ..append(Comment('d')); final expected = 'ac'; expect(input.outerHtml, equals(expected)); @@ -252,10 +246,9 @@ void _testElement() { expect(node.toString(), '
'); }); test('complex element', () { - final node = - Element.div() - ..setAttribute('data-k0', 'v0') - ..appendText('abc'); + final node = Element.div() + ..setAttribute('data-k0', 'v0') + ..appendText('abc'); expect(node.toString(), '''
abc
'''); }); }, testOn: 'vm'); diff --git a/test/src/html/dom/element_computed_style.dart b/test/src/html/dom/element_computed_style.dart index 62bbc25..9111b7f 100644 --- a/test/src/html/dom/element_computed_style.dart +++ b/test/src/html/dom/element_computed_style.dart @@ -21,8 +21,7 @@ void _testElementComputedStyle() { test('Case #1', () { _temporarilyRemoveChildrenFromDocument(root: document.body!); - final styleElement = - StyleElement()..appendText(''' + final styleElement = StyleElement()..appendText(''' .exampleClass { font-family: exampleFont }'''); diff --git a/test/src/html/dom/element_subclasses.dart b/test/src/html/dom/element_subclasses.dart index 9042a9a..061abd8 100644 --- a/test/src/html/dom/element_subclasses.dart +++ b/test/src/html/dom/element_subclasses.dart @@ -496,10 +496,9 @@ void _testElementSubclasses() { test('children after setting innerHtml', () { final innerHtml = '&<>'; - final iframe = - IFrameElement() - ..className = 'example' - ..innerHtml = innerHtml; + final iframe = IFrameElement() + ..className = 'example' + ..innerHtml = innerHtml; expect(iframe.children, hasLength(0)); expect(iframe.childNodes, hasLength(1)); expect(iframe.text, innerHtml); @@ -509,10 +508,9 @@ void _testElementSubclasses() { test('outerHtml after setting innerHtml', () { final innerHtml = '&<>'; - final iframe = - IFrameElement() - ..className = 'example' - ..innerHtml = innerHtml; + final iframe = IFrameElement() + ..className = 'example' + ..innerHtml = innerHtml; expect(iframe.outerHtml, ''); }); diff --git a/test/src/html/dom/node.dart b/test/src/html/dom/node.dart index cddd7b4..11a5d43 100644 --- a/test/src/html/dom/node.dart +++ b/test/src/html/dom/node.dart @@ -38,12 +38,11 @@ void _testNode() { final e0 = Element.tag('e0')..appendText('e0-text'); final e1 = Element.tag('e1')..appendText('e1-text'); final e2 = Element.tag('e2')..appendText('e2-text'); - final root = - Element.tag('sometag') - ..setAttribute('k', 'v') - ..append(e0) - ..append(e1) - ..append(e2); + final root = Element.tag('sometag') + ..setAttribute('k', 'v') + ..append(e0) + ..append(e1) + ..append(e2); // Initial tree expect( @@ -103,12 +102,11 @@ void _testNode() { final e0 = Element.tag('e0')..appendText('e0-text'); final e1 = Element.tag('e1')..appendText('e1-text'); final e2 = Element.tag('e2')..appendText('e2-text'); - final root = - Element.tag('sometag') - ..setAttribute('k', 'v') - ..append(e0) - ..append(e1) - ..append(e2); + final root = Element.tag('sometag') + ..setAttribute('k', 'v') + ..append(e0) + ..append(e1) + ..append(e2); // Initial tree expect(