Alphabetize events.dart and extensions.dart (#557)

* Alphabetize events.dart and extensions.dart

Extension names in events.dart and extensions.dart
are coalesced to 1 per type name and follow the
syntax <TypeName>Events and <TypeName>Extension.

Extension names and members are sorted.

* Gemini comments
diff --git a/web/CHANGELOG.md b/web/CHANGELOG.md
index ebd6c29..b25ed97 100644
--- a/web/CHANGELOG.md
+++ b/web/CHANGELOG.md
@@ -17,6 +17,7 @@
 - Various extension methods bridging `dart:html` APIs are added to make it
   easier to migrate. `@Equivalence` annotations are now added to extension
   methods to document 1-1 replacements of `dart:html` APIs.
+- Combined stream provider extensions to one per type.
 
 ## 1.1.1
 
diff --git a/web/lib/src/helpers/events/events.dart b/web/lib/src/helpers/events/events.dart
index 63f3999..6d5fcb2 100644
--- a/web/lib/src/helpers/events/events.dart
+++ b/web/lib/src/helpers/events/events.dart
@@ -6,7 +6,93 @@
 import 'providers.dart';
 import 'streams.dart';
 
-extension ElementEventGetters on Element {
+extension AudioNodeEvents on AudioNode {
+  Stream<Event> get onEnded => EventStreamProviders.endedEvent.forTarget(this);
+}
+
+extension BroadcastChannelEvents on BroadcastChannel {
+  Stream<MessageEvent> get onMessage =>
+      EventStreamProviders.messageEvent.forTarget(this);
+}
+
+extension DocumentEvents on Document {
+  Stream<Event> get onBlur => EventStreamProviders.blurEvent.forTarget(this);
+
+  Stream<MouseEvent> get onClick =>
+      EventStreamProviders.clickEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDrag =>
+      EventStreamProviders.dragEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragEnd =>
+      EventStreamProviders.dragEndEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragEnter =>
+      EventStreamProviders.dragEnterEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragLeave =>
+      EventStreamProviders.dragLeaveEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragOver =>
+      EventStreamProviders.dragOverEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDragStart =>
+      EventStreamProviders.dragStartEvent.forTarget(this);
+
+  Stream<MouseEvent> get onDrop =>
+      EventStreamProviders.dropEvent.forTarget(this);
+
+  Stream<Event> get onInput => EventStreamProviders.inputEvent.forTarget(this);
+
+  Stream<KeyboardEvent> get onKeyDown =>
+      EventStreamProviders.keyDownEvent.forTarget(this);
+
+  Stream<KeyboardEvent> get onKeyUp =>
+      EventStreamProviders.keyUpEvent.forTarget(this);
+
+  Stream<Event> get onLoad => EventStreamProviders.loadEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseDown =>
+      EventStreamProviders.mouseDownEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseEnter =>
+      EventStreamProviders.mouseEnterEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseLeave =>
+      EventStreamProviders.mouseLeaveEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseMove =>
+      EventStreamProviders.mouseMoveEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseOut =>
+      EventStreamProviders.mouseOutEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseOver =>
+      EventStreamProviders.mouseOverEvent.forTarget(this);
+
+  Stream<MouseEvent> get onMouseUp =>
+      EventStreamProviders.mouseUpEvent.forTarget(this);
+
+  Stream<WheelEvent> get onMouseWheel =>
+      EventStreamProviders.mouseWheelEvent.forTarget(this);
+
+  Stream<TouchEvent> get onTouchCancel =>
+      EventStreamProviders.touchCancelEvent.forTarget(this);
+
+  Stream<TouchEvent> get onTouchEnd =>
+      EventStreamProviders.touchEndEvent.forTarget(this);
+
+  Stream<TouchEvent> get onTouchMove =>
+      EventStreamProviders.touchMoveEvent.forTarget(this);
+
+  Stream<TouchEvent> get onTouchStart =>
+      EventStreamProviders.touchStartEvent.forTarget(this);
+
+  Stream<Event> get onVisibilityChange =>
+      EventStreamProviders.visibilityChangeEvent.forTarget(this);
+}
+
+extension ElementEvents on Element {
   ElementStream<Event> get onAbort =>
       EventStreamProviders.abortEvent.forElement(this);
 
@@ -106,9 +192,6 @@
   ElementStream<Event> get onLoad =>
       EventStreamProviders.loadEvent.forElement(this);
 
-  ElementStream<Event> get onUnload =>
-      EventStreamProviders.unloadEvent.forElement(this);
-
   ElementStream<Event> get onLoadedData =>
       EventStreamProviders.loadedDataEvent.forElement(this);
 
@@ -136,6 +219,9 @@
   ElementStream<MouseEvent> get onMouseUp =>
       EventStreamProviders.mouseUpEvent.forElement(this);
 
+  ElementStream<WheelEvent> get onMouseWheel =>
+      EventStreamProviders.mouseWheelEvent.forElement(this);
+
   ElementStream<ClipboardEvent> get onPaste =>
       EventStreamProviders.pasteEvent.forElement(this);
 
@@ -205,6 +291,12 @@
   ElementStream<TouchEvent> get onTouchStart =>
       EventStreamProviders.touchStartEvent.forElement(this);
 
+  ElementStream<TransitionEvent> get onTransitionEnd =>
+      EventStreamProviders.transitionEndEvent.forElement(this);
+
+  ElementStream<Event> get onUnload =>
+      EventStreamProviders.unloadEvent.forElement(this);
+
   ElementStream<Event> get onVolumeChange =>
       EventStreamProviders.volumeChangeEvent.forElement(this);
 
@@ -221,19 +313,7 @@
       EventStreamProviders.wheelEvent.forElement(this);
 }
 
-extension XHRGetters on XMLHttpRequest {
-  Stream<ProgressEvent> get onLoad =>
-      EventStreamProviders.loadEvent.forTarget(this);
-  Stream<ProgressEvent> get onError =>
-      EventStreamProviders.errorEvent.forTarget(this);
-  Stream<ProgressEvent> get onProgress =>
-      EventStreamProviders.progressEvent.forTarget(this);
-
-  Stream<Event> get onReadyStateChange =>
-      EventStreamProviders.readyStateChangeEvent.forTarget(this);
-}
-
-extension EventSourceEventGetters on EventSource {
+extension EventSourceEvents on EventSource {
   Stream<Event> get onError =>
       EventStreamProviders.errorEventSourceEvent.forTarget(this);
 
@@ -243,82 +323,57 @@
   Stream<Event> get onOpen => EventStreamProviders.openEvent.forTarget(this);
 }
 
-extension FileReaderEventGetters on FileReader {
+extension FileReaderEvents on FileReader {
   Stream<ProgressEvent> get onAbort =>
       EventStreamProviders.abortEvent.forTarget(this);
+
   Stream<ProgressEvent> get onError =>
       EventStreamProviders.errorEvent.forTarget(this);
+
   Stream<ProgressEvent> get onLoad =>
       EventStreamProviders.loadEvent.forTarget(this);
+
   Stream<ProgressEvent> get onLoadEnd =>
       EventStreamProviders.loadEndEvent.forTarget(this);
+
   Stream<ProgressEvent> get onLoadStart =>
       EventStreamProviders.loadStartEvent.forTarget(this);
+
   Stream<ProgressEvent> get onProgress =>
       EventStreamProviders.progressEvent.forTarget(this);
 }
 
-extension AutoElementEventGetters on AudioNode {
-  Stream<Event> get onEnded => EventStreamProviders.endedEvent.forTarget(this);
-}
-
-extension FontFaceSetGetters on FontFaceSet {
+extension FontFaceSetEvents on FontFaceSet {
   Stream<FontFaceSetLoadEvent> get onLoadingDone =>
       EventStreamProviders.loadingDoneEvent.forTarget(this);
 }
 
-extension WindowEventGetters on Window {
-  Stream<BeforeUnloadEvent> get onBeforeUnload =>
-      EventStreamProviders.beforeUnloadEvent.forTarget(this);
+extension PerformanceEvents on Performance {
+  Stream<Event> get onResourceTimingBufferFull =>
+      EventStreamProviders.resourceTimingBufferFull.forTarget(this);
+}
 
-  Stream<Event> get onBlur => EventStreamProviders.blurEvent.forTarget(this);
+extension WebSocketEvents on WebSocket {
+  Stream<CloseEvent> get onClose =>
+      EventStreamProviders.closeEvent.forTarget(this);
 
-  Stream<KeyboardEvent> get onKeyDown =>
-      EventStreamProviders.keyDownEvent.forTarget(this);
-
-  Stream<KeyboardEvent> get onKeyPress =>
-      EventStreamProviders.keyPressEvent.forTarget(this);
-
-  Stream<Event> get onLoad => EventStreamProviders.loadEvent.forTarget(this);
+  Stream<Event> get onError =>
+      EventStreamProviders.errorEventSourceEvent.forTarget(this);
 
   Stream<MessageEvent> get onMessage =>
       EventStreamProviders.messageEvent.forTarget(this);
 
-  Stream<PopStateEvent> get onPopState =>
-      EventStreamProviders.popStateEvent.forTarget(this);
+  Stream<Event> get onOpen => EventStreamProviders.openEvent.forTarget(this);
+}
 
-  Stream<TouchEvent> get onTouchCancel =>
-      EventStreamProviders.touchCancelEvent.forTarget(this);
+extension WindowEvents on Window {
+  Stream<Event> get onAnimationEnd =>
+      EventStreamProviders.animationEndEvent.forTarget(this);
 
-  Stream<TouchEvent> get onTouchEnd =>
-      EventStreamProviders.touchEndEvent.forTarget(this);
+  Stream<BeforeUnloadEvent> get onBeforeUnload =>
+      EventStreamProviders.beforeUnloadEvent.forTarget(this);
 
-  Stream<TouchEvent> get onTouchMove =>
-      EventStreamProviders.touchMoveEvent.forTarget(this);
-
-  Stream<TouchEvent> get onTouchStart =>
-      EventStreamProviders.touchStartEvent.forTarget(this);
-
-  Stream<MouseEvent> get onMouseDown =>
-      EventStreamProviders.mouseDownEvent.forTarget(this);
-
-  Stream<MouseEvent> get onMouseEnter =>
-      EventStreamProviders.mouseEnterEvent.forTarget(this);
-
-  Stream<MouseEvent> get onMouseLeave =>
-      EventStreamProviders.mouseLeaveEvent.forTarget(this);
-
-  Stream<MouseEvent> get onMouseMove =>
-      EventStreamProviders.mouseMoveEvent.forTarget(this);
-
-  Stream<MouseEvent> get onMouseOut =>
-      EventStreamProviders.mouseOutEvent.forTarget(this);
-
-  Stream<MouseEvent> get onMouseOver =>
-      EventStreamProviders.mouseOverEvent.forTarget(this);
-
-  Stream<MouseEvent> get onMouseUp =>
-      EventStreamProviders.mouseUpEvent.forTarget(this);
+  Stream<Event> get onBlur => EventStreamProviders.blurEvent.forTarget(this);
 
   Stream<MouseEvent> get onDrag =>
       EventStreamProviders.dragEvent.forTarget(this);
@@ -340,34 +395,19 @@
 
   Stream<Event> get onFocus => EventStreamProviders.focusEvent.forTarget(this);
 
-  Stream<Event> get onAnimationEnd =>
-      EventStreamProviders.animationEndEvent.forTarget(this);
+  Stream<KeyboardEvent> get onKeyDown =>
+      EventStreamProviders.keyDownEvent.forTarget(this);
 
-  Stream<Event> get onResize =>
-      EventStreamProviders.resizeEvent.forTarget(this);
-
-  Stream<Event> get onScroll =>
-      EventStreamProviders.scrollEvent.forTarget(this);
-
-  Stream<Event> get onStorage =>
-      EventStreamProviders.storageEvent.forTarget(this);
+  Stream<KeyboardEvent> get onKeyPress =>
+      EventStreamProviders.keyPressEvent.forTarget(this);
 
   Stream<KeyboardEvent> get onKeyUp =>
       EventStreamProviders.keyUpEvent.forTarget(this);
-}
 
-extension DocumentEventGetters on Document {
-  Stream<TouchEvent> get onTouchCancel =>
-      EventStreamProviders.touchCancelEvent.forTarget(this);
+  Stream<Event> get onLoad => EventStreamProviders.loadEvent.forTarget(this);
 
-  Stream<TouchEvent> get onTouchEnd =>
-      EventStreamProviders.touchEndEvent.forTarget(this);
-
-  Stream<TouchEvent> get onTouchMove =>
-      EventStreamProviders.touchMoveEvent.forTarget(this);
-
-  Stream<TouchEvent> get onTouchStart =>
-      EventStreamProviders.touchStartEvent.forTarget(this);
+  Stream<MessageEvent> get onMessage =>
+      EventStreamProviders.messageEvent.forTarget(this);
 
   Stream<MouseEvent> get onMouseDown =>
       EventStreamProviders.mouseDownEvent.forTarget(this);
@@ -390,81 +430,47 @@
   Stream<MouseEvent> get onMouseUp =>
       EventStreamProviders.mouseUpEvent.forTarget(this);
 
-  Stream<MouseEvent> get onDrag =>
-      EventStreamProviders.dragEvent.forTarget(this);
-
-  Stream<MouseEvent> get onDragEnd =>
-      EventStreamProviders.dragEndEvent.forTarget(this);
-
-  Stream<MouseEvent> get onDragEnter =>
-      EventStreamProviders.dragEnterEvent.forTarget(this);
-
-  Stream<MouseEvent> get onDragLeave =>
-      EventStreamProviders.dragLeaveEvent.forTarget(this);
-
-  Stream<MouseEvent> get onDragOver =>
-      EventStreamProviders.dragOverEvent.forTarget(this);
-
-  Stream<MouseEvent> get onDragStart =>
-      EventStreamProviders.dragStartEvent.forTarget(this);
-
-  Stream<MouseEvent> get onDrop =>
-      EventStreamProviders.dropEvent.forTarget(this);
-
-  Stream<Event> get onInput => EventStreamProviders.inputEvent.forTarget(this);
-
-  Stream<KeyboardEvent> get onKeyUp =>
-      EventStreamProviders.keyUpEvent.forTarget(this);
-
-  Stream<KeyboardEvent> get onKeyDown =>
-      EventStreamProviders.keyDownEvent.forTarget(this);
-
   Stream<WheelEvent> get onMouseWheel =>
       EventStreamProviders.mouseWheelEvent.forTarget(this);
 
-  Stream<Event> get onVisibilityChange =>
-      EventStreamProviders.visibilityChangeEvent.forTarget(this);
+  Stream<PopStateEvent> get onPopState =>
+      EventStreamProviders.popStateEvent.forTarget(this);
 
-  Stream<Event> get onBlur => EventStreamProviders.blurEvent.forTarget(this);
+  Stream<Event> get onResize =>
+      EventStreamProviders.resizeEvent.forTarget(this);
 
-  Stream<Event> get onLoad => EventStreamProviders.loadEvent.forTarget(this);
+  Stream<Event> get onScroll =>
+      EventStreamProviders.scrollEvent.forTarget(this);
 
-  Stream<MouseEvent> get onClick =>
-      EventStreamProviders.clickEvent.forTarget(this);
-}
+  Stream<Event> get onStorage =>
+      EventStreamProviders.storageEvent.forTarget(this);
 
-extension ElementCustomEvents on Element {
-  ElementStream<WheelEvent> get onMouseWheel =>
-      EventStreamProviders.mouseWheelEvent.forElement(this);
+  Stream<TouchEvent> get onTouchCancel =>
+      EventStreamProviders.touchCancelEvent.forTarget(this);
 
-  ElementStream<TransitionEvent> get onTransitionEnd =>
-      EventStreamProviders.transitionEndEvent.forElement(this);
-}
+  Stream<TouchEvent> get onTouchEnd =>
+      EventStreamProviders.touchEndEvent.forTarget(this);
 
-extension BroadcastChannelEvents on BroadcastChannel {
-  Stream<MessageEvent> get onMessage =>
-      EventStreamProviders.messageEvent.forTarget(this);
-}
+  Stream<TouchEvent> get onTouchMove =>
+      EventStreamProviders.touchMoveEvent.forTarget(this);
 
-extension PerformanceEvents on Performance {
-  Stream<Event> get onResourceTimingBufferFull =>
-      EventStreamProviders.resourceTimingBufferFull.forTarget(this);
-}
-
-extension WindowCustomEvents on Window {
-  Stream<WheelEvent> get onMouseWheel =>
-      EventStreamProviders.mouseWheelEvent.forTarget(this);
+  Stream<TouchEvent> get onTouchStart =>
+      EventStreamProviders.touchStartEvent.forTarget(this);
 
   Stream<TransitionEvent> get onTransitionEnd =>
       EventStreamProviders.transitionEndEvent.forTarget(this);
 }
 
-extension WebSocketEvents on WebSocket {
-  Stream<Event> get onOpen => EventStreamProviders.openEvent.forTarget(this);
-  Stream<MessageEvent> get onMessage =>
-      EventStreamProviders.messageEvent.forTarget(this);
-  Stream<CloseEvent> get onClose =>
-      EventStreamProviders.closeEvent.forTarget(this);
-  Stream<Event> get onError =>
-      EventStreamProviders.errorEventSourceEvent.forTarget(this);
+extension XMLHttpRequestEvents on XMLHttpRequest {
+  Stream<ProgressEvent> get onError =>
+      EventStreamProviders.errorEvent.forTarget(this);
+
+  Stream<ProgressEvent> get onLoad =>
+      EventStreamProviders.loadEvent.forTarget(this);
+
+  Stream<ProgressEvent> get onProgress =>
+      EventStreamProviders.progressEvent.forTarget(this);
+
+  Stream<Event> get onReadyStateChange =>
+      EventStreamProviders.readyStateChangeEvent.forTarget(this);
 }
diff --git a/web/lib/src/helpers/extensions.dart b/web/lib/src/helpers/extensions.dart
index f3022cf..ba458c0 100644
--- a/web/lib/src/helpers/extensions.dart
+++ b/web/lib/src/helpers/extensions.dart
@@ -84,6 +84,11 @@
   }
 }
 
+extension DataTransferExtension on DataTransfer {
+  @Equivalence(type: 'DataTransfer', member: 'files')
+  List<File>? get filesAsList => has('files') ? files.asList() : null;
+}
+
 extension DocumentExtension on Document {
   @Equivalence(
     type: 'Document',
@@ -113,58 +118,8 @@
 
 /// Contains subtype members that were moved up in `dart:html` to `Element`.
 extension ElementExtension on Element {
-  @Equivalence(type: 'Element', member: 'style')
-  external CSSStyleDeclaration get style;
-
-  @Equivalence(type: 'Element', member: 'classes')
-  CssClassSet get classes => ElementCssClassSet(this);
-
-  @Equivalence(type: 'Element', member: 'getComputedStyle')
-  CSSStyleDeclaration getComputedStyle([String? pseudoElement]) {
-    pseudoElement ??= '';
-    return window.getComputedStyle(this, pseudoElement);
-  }
-
-  @Equivalence(type: 'Element', member: 'tabIndex')
-  external int? get tabIndex;
-  @Equivalence(type: 'Element', member: 'tabIndex')
-  external set tabIndex(int? v);
-
-  @Equivalence(type: 'Element', member: 'dir')
-  external String? get dir;
-  @Equivalence(type: 'Element', member: 'dir')
-  external set dir(String? s);
-
-  @Equivalence(type: 'Element', member: 'innerText')
-  external String get innerText;
-  @Equivalence(type: 'Element', member: 'innerText')
-  external set innerText(String value);
-
-  @Equivalence(type: 'Element', member: 'offsetLeft')
-  external int get offsetLeft;
-  @Equivalence(type: 'Element', member: 'offsetTop')
-  external int get offsetTop;
-  @Equivalence(type: 'Element', member: 'offsetWidth')
-  external int get offsetWidth;
-  @Equivalence(type: 'Element', member: 'offsetHeight')
-  external int get offsetHeight;
-
-  @Equivalence(type: 'Element', member: 'offset')
-  Rectangle get offset =>
-      Rectangle(offsetLeft, offsetTop, offsetWidth, offsetHeight);
-
-  @Equivalence(type: 'Element', member: 'offsetParent')
-  external Element? get offsetParent;
-
-  @Equivalence(type: 'Element', member: 'focus')
-  external void focus();
-  @Equivalence(type: 'Element', member: 'click')
-  external void click();
-  @Equivalence(type: 'Element', member: 'blur')
-  external void blur();
-
-  @Equivalence(type: 'Element', member: 'attributes')
-  Map<String, String> get attributesAsMap => ElementAttributeMap(this);
+  @Equivalence(type: 'Element', member: 'appendText')
+  void appendText(String text) => append(Text(text));
 
   @Equivalence(type: 'Element', member: 'attributes')
   set attributes(Map<String, String> value) {
@@ -175,9 +130,53 @@
     });
   }
 
+  @Equivalence(type: 'Element', member: 'attributes')
+  Map<String, String> get attributesAsMap => ElementAttributeMap(this);
+
+  @Equivalence(type: 'Element', member: 'blur')
+  external void blur();
+
+  @Equivalence(type: 'Element', member: 'borderEdge')
+  CssRect get borderEdge => BorderCssRect(this);
+
+  /// Returns [children] as a modifiable [List].
+  @Equivalence(type: 'Element', member: 'children')
+  List<Element> get childrenAsList => HTMLCollectionListWrapper(this, children);
+
+  @Equivalence(type: 'Element', member: 'classes')
+  CssClassSet get classes => ElementCssClassSet(this);
+
+  @Equivalence(type: 'Element', member: 'click')
+  external void click();
+
   @Equivalence(type: 'Element', member: 'dataset')
   Map<String, String> get dataset => DataAttributeMap(attributesAsMap);
 
+  @Equivalence(type: 'Element', member: 'dir')
+  external String? get dir;
+  @Equivalence(type: 'Element', member: 'dir')
+  external set dir(String? s);
+
+  @Equivalence(type: 'Element', member: 'documentOffset')
+  Point get documentOffset => offsetTo(document.documentElement!);
+
+  @Equivalence(type: 'Element', member: 'focus')
+  external void focus();
+
+  @Equivalence(type: 'Element', member: 'getComputedStyle')
+  CSSStyleDeclaration getComputedStyle([String? pseudoElement]) {
+    pseudoElement ??= '';
+    return window.getComputedStyle(this, pseudoElement);
+  }
+
+  @Equivalence(type: 'Element', member: 'innerText')
+  external String get innerText;
+  @Equivalence(type: 'Element', member: 'innerText')
+  external set innerText(String value);
+
+  @Equivalence(type: 'Element', member: 'marginEdge')
+  CssRect get marginEdge => MarginCssRect(this);
+
   @Equivalence(type: 'Element', member: 'matchesWithAncestors')
   bool matchesWithAncestors(String selectors) {
     var elem = this as Element?;
@@ -191,19 +190,18 @@
   @Equivalence(type: 'Element', member: 'namespaceUri')
   String? get namespaceUri => namespaceURI;
 
-  @Equivalence(
-    type: 'Element',
-    member: 'querySelectorAll',
-    details:
-        "'dart:html' returned a `_FrozenElementList`, which provided "
-        'additional helpers like stream listeners.',
-  )
-  JSImmutableListWrapper<NodeList, T> querySelectorAllAsList<T extends Element>(
-    String selectors,
-  ) => JSImmutableListWrapper<NodeList, T>(querySelectorAll(selectors));
+  @Equivalence(type: 'Element', member: 'offset')
+  Rectangle get offset =>
+      Rectangle(offsetLeft, offsetTop, offsetWidth, offsetHeight);
 
-  @Equivalence(type: 'Element', member: 'appendText')
-  void appendText(String text) => append(Text(text));
+  @Equivalence(type: 'Element', member: 'offsetHeight')
+  external int get offsetHeight;
+
+  @Equivalence(type: 'Element', member: 'offsetLeft')
+  external int get offsetLeft;
+
+  @Equivalence(type: 'Element', member: 'offsetParent')
+  external Element? get offsetParent;
 
   @Equivalence(type: 'Element', member: 'offsetTo')
   Point offsetTo(Element parent) =>
@@ -227,8 +225,26 @@
     return Point(p.x + current.offsetLeft, p.y + current.offsetTop);
   }
 
-  @Equivalence(type: 'Element', member: 'marginEdge')
-  CssRect get marginEdge => MarginCssRect(this);
+  @Equivalence(type: 'Element', member: 'offsetTop')
+  external int get offsetTop;
+
+  @Equivalence(type: 'Element', member: 'offsetWidth')
+  external int get offsetWidth;
+
+  @Equivalence(
+    type: 'Element',
+    member: 'querySelectorAll',
+    details:
+        "'dart:html' returned a `_FrozenElementList`, which provided "
+        'additional helpers like stream listeners.',
+  )
+  JSImmutableListWrapper<NodeList, T> querySelectorAllAsList<T extends Element>(
+    String selectors,
+  ) => JSImmutableListWrapper<NodeList, T>(querySelectorAll(selectors));
+
+  @Equivalence(type: 'Element', member: 'scrollIntoViewIfNeeded')
+  @JS('scrollIntoViewIfNeeded')
+  external void scrollIntoViewIfNeeded([bool? centerIfNeeded]);
 
   @Equivalence(type: 'Element', member: 'scrollIntoView')
   void scrollIntoViewWithAlignment([ScrollAlignment? alignment]) {
@@ -248,19 +264,13 @@
     }
   }
 
-  @Equivalence(type: 'Element', member: 'scrollIntoViewIfNeeded')
-  @JS('scrollIntoViewIfNeeded')
-  external void scrollIntoViewIfNeeded([bool? centerIfNeeded]);
+  @Equivalence(type: 'Element', member: 'style')
+  external CSSStyleDeclaration get style;
 
-  @Equivalence(type: 'Element', member: 'borderEdge')
-  CssRect get borderEdge => BorderCssRect(this);
-
-  @Equivalence(type: 'Element', member: 'documentOffset')
-  Point get documentOffset => offsetTo(document.documentElement!);
-
-  /// Returns [children] as a modifiable [List].
-  @Equivalence(type: 'Element', member: 'children')
-  List<Element> get childrenAsList => HTMLCollectionListWrapper(this, children);
+  @Equivalence(type: 'Element', member: 'tabIndex')
+  external int? get tabIndex;
+  @Equivalence(type: 'Element', member: 'tabIndex')
+  external set tabIndex(int? v);
 }
 
 extension EventExtension on Event {
@@ -280,24 +290,17 @@
   }
 }
 
-extension InputElementExtension on HTMLInputElement {
-  @Equivalence(type: 'InputElement', member: 'files')
-  List<File>? get filesAsList => files?.asList();
-}
-
-extension DataTransferExtension on DataTransfer {
-  @Equivalence(type: 'DataTransfer', member: 'files')
-  List<File>? get filesAsList => has('files') ? files.asList() : null;
-}
-
 extension FileListExtension on FileList {
   List<File> asList() => JSImmutableListWrapper<FileList, File>(this);
-  @Equivalence(type: 'FileList', member: 'first')
-  File get first => item(0)!;
-  @Equivalence(type: 'FileList', member: 'isEmpty')
-  bool get isEmpty => length == 0;
+
   @Equivalence(type: 'FileList', member: 'elementAt')
   File elementAt(int i) => item(i)!;
+
+  @Equivalence(type: 'FileList', member: 'first')
+  File get first => item(0)!;
+
+  @Equivalence(type: 'FileList', member: 'isEmpty')
+  bool get isEmpty => length == 0;
 }
 
 extension HTMLCanvasElementExtension on HTMLCanvasElement {
@@ -305,10 +308,6 @@
   CanvasRenderingContext2D get context2D =>
       getContext('2d') as CanvasRenderingContext2D;
 
-  @Equivalence(type: 'CanvasElement', member: 'toDataUrl')
-  String toDataUrl([String type = 'image/png', num? quality]) =>
-      (quality == null) ? toDataURL(type) : toDataURL(type, quality.toJS);
-
   @Equivalence(type: 'CanvasElement', member: 'getContext3d')
   RenderingContext? getContext3d({
     bool alpha = true,
@@ -346,18 +345,25 @@
     }
     return completer.future;
   }
+
+  @Equivalence(type: 'CanvasElement', member: 'toDataUrl')
+  String toDataUrl([String type = 'image/png', num? quality]) =>
+      (quality == null) ? toDataURL(type) : toDataURL(type, quality.toJS);
 }
 
 extension HTMLCollectionExtension on HTMLCollection {
+  List<Element> asList() =>
+      JSImmutableListWrapper<HTMLCollection, Element>(this);
+
+  @Equivalence(type: 'HtmlCollection', member: 'first')
+  Element get first => item(0)!;
+
   @Equivalence(type: 'HtmlCollection', member: 'isEmpty')
   bool get isEmpty => length == 0;
 
   @Equivalence(type: 'HtmlCollection', member: 'isNotEmpty')
   bool get isNotEmpty => length > 0;
 
-  @Equivalence(type: 'HtmlCollection', member: 'first')
-  Element get first => item(0)!;
-
   @Equivalence(type: 'HtmlCollection', member: 'last')
   Element get last => item(length - 1)!;
 
@@ -371,36 +377,178 @@
 
   @Equivalence(type: 'HtmlCollection', member: '[]')
   Element operator [](int i) => item(i)!;
+}
 
-  List<Element> asList() =>
-      JSImmutableListWrapper<HTMLCollection, Element>(this);
+extension HTMLInputElementExtension on HTMLInputElement {
+  @Equivalence(type: 'InputElement', member: 'files')
+  List<File>? get filesAsList => files?.asList();
+}
+
+extension MouseEventExtension on MouseEvent {
+  @Equivalence(type: 'MouseEvent', member: 'client')
+  Point get client => Point(clientX, clientY);
+
+  // This really belongs on the `DragEvent` subtype, but `dart:html` moved it
+  // up.
+  @Equivalence(type: 'MouseEvent', member: 'dataTransfer')
+  external DataTransfer get dataTransfer;
+
+  @Equivalence(type: 'MouseEvent', member: 'page')
+  Point get page => Point(pageX, pageY);
+
+  @Equivalence(type: 'MouseEvent', member: 'screen')
+  Point get screen => Point(screenX, screenY);
+}
+
+extension NodeExtension on Node {
+  @Equivalence(type: 'Node', member: 'append')
+  Node append(Node other) => appendChild(other);
+
+  /// Returns [childNodes] as a modifiable [List].
+  @Equivalence(type: 'Node', member: 'childNodes')
+  List<Node> get childNodesAsList => NodeListListWrapper(this, childNodes);
+
+  @Equivalence(type: 'Node', member: 'clone')
+  Node clone(bool? deep) => cloneNode(deep ?? false);
+
+  @Equivalence(type: 'Node', member: 'insertAllBefore')
+  void insertAllBefore(Iterable<Node> newNodes, Node child) {
+    // `toList` to avoid potential infinite recursion if `newNodes` is a wrapper
+    // around this `Node`.
+    for (var node in newNodes.toList()) {
+      insertBefore(node, child);
+    }
+  }
+
+  @Equivalence(type: 'Node', member: 'nextNode')
+  Node? get nextNode => nextSibling;
+
+  @Equivalence(type: 'Node', member: 'nodes')
+  List<Node> get nodes => childNodesAsList;
+
+  @Equivalence(type: 'Node', member: 'nodes')
+  set nodes(Iterable<Node> value) {
+    final copy = value.toList();
+    text = '';
+    for (final node in copy) {
+      appendChild(node);
+    }
+  }
+
+  @Equivalence(type: 'Node', member: 'parent')
+  Element? get parent => parentElement;
+
+  @Equivalence(type: 'Node', member: 'remove')
+  void remove() {
+    final parent = parentNode;
+    if (parent != null) {
+      parent.removeChild(this);
+    }
+  }
+
+  @Equivalence(type: 'Node', member: 'text')
+  String? get text => textContent;
+
+  @Equivalence(type: 'Node', member: 'text')
+  set text(String? s) => textContent = s;
+}
+
+extension NodeListExtension on NodeList {
+  /// Returns node list as an immutable [List].
+  List<T> asList<T extends Node>() => JSImmutableListWrapper<NodeList, T>(this);
+
+  @Equivalence(type: 'NodeList', member: 'elementAt')
+  Node elementAt(int i) => item(i)!;
+
+  @Equivalence(type: 'NodeList', member: 'isEmpty')
+  bool get isEmpty => length == 0;
+}
+
+extension StorageExtension on Storage {
+  @Equivalence(type: 'Storage', member: '[]')
+  String? operator [](String key) => getItem(key);
+
+  @Equivalence(type: 'Storage', member: '[]=')
+  void operator []=(String key, String value) => setItem(key, value);
+}
+
+extension TouchEventExtension on TouchEvent {
+  // Safari still doesn't support `TouchEvent`s:
+  // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent
+  @Equivalence(type: 'TouchEvent', member: 'supported')
+  static bool get supported {
+    try {
+      TouchEvent('touches');
+      return true;
+    } catch (e) {
+      return false;
+    }
+  }
+}
+
+extension TouchExtension on Touch {
+  @Equivalence(type: 'Touch', member: 'client')
+  Point get client => Point(clientX, clientY);
+
+  @Equivalence(type: 'Touch', member: 'page')
+  Point get page => Point(pageX, pageY);
+}
+
+extension TouchListExtension on TouchList {
+  List<Touch> asList() => JSImmutableListWrapper<TouchList, Touch>(this);
+
+  @Equivalence(type: 'TouchList', member: 'elementAt')
+  Touch elementAt(int i) => item(i)!;
+
+  @Equivalence(type: 'TouchList', member: 'first')
+  Touch get first => item(0)!;
+
+  @Equivalence(type: 'TouchList', member: 'isEmpty')
+  bool get isEmpty => length == 0;
+}
+
+extension UriExtension on Uri {
+  /// Converts this to a JavaScript [URL] object.
+  ///
+  /// Throws an [ArgumentError] if this isn't an absolute URL, since [URL] can
+  /// only represent absolute URLs.
+  URL get toJS {
+    try {
+      return URL(toString());
+    } catch (_) {
+      throw ArgumentError.value(this, 'this', '"$this" isn\'t a valid JS URL.');
+    }
+  }
+}
+
+extension URLExtension on URL {
+  /// Converts this to a Dart [Uri] object.
+  Uri get toDart => Uri.parse(toString());
+}
+
+extension WindowExtension on Window {
+  @Equivalence(type: 'Window', member: 'animationFrame')
+  Future<num> get animationFrame {
+    final completer = Completer<num>.sync();
+    void getTimestamp(num timestamp) {
+      completer.complete(timestamp);
+    }
+
+    requestAnimationFrame(getTimestamp.toJS);
+    return completer.future;
+  }
+
+  @Equivalence(type: 'Window', member: 'console')
+  StringConsole get console => StringConsole(dom.console);
+
+  @Equivalence(type: 'Window', member: 'localStorage')
+  StorageMap get localStorageAsMap => StorageMap(localStorage);
+
+  @Equivalence(type: 'Window', member: 'sessionStorage')
+  StorageMap get sessionStorageAsMap => StorageMap(sessionStorage);
 }
 
 extension XMLHttpRequestExtension on XMLHttpRequest {
-  @Equivalence(type: 'HttpRequest', member: 'responseHeaders')
-  Map<String, String> get responseHeaders {
-    final headers = <String, String>{};
-    final headersString = getAllResponseHeaders();
-    final headersList = headersString.split('\r\n');
-    for (final header in headersList) {
-      if (header.isEmpty) {
-        continue;
-      }
-      final splitIdx = header.indexOf(': ');
-      if (splitIdx == -1) {
-        continue;
-      }
-      final key = header.substring(0, splitIdx).toLowerCase();
-      final value = header.substring(splitIdx + 2);
-      if (headers.containsKey(key)) {
-        headers[key] = '${headers[key]}, $value';
-      } else {
-        headers[key] = value;
-      }
-    }
-    return headers;
-  }
-
   @Equivalence(type: 'HttpRequest', member: 'request')
   static Future<XMLHttpRequest> request(
     String url, {
@@ -469,168 +617,31 @@
 
     return completer.future;
   }
-}
 
-extension URLToUri on URL {
-  /// Converts this to a Dart [Uri] object.
-  Uri get toDart => Uri.parse(toString());
-}
-
-extension UriToURL on Uri {
-  /// Converts this to a JavaScript [URL] object.
-  ///
-  /// Throws an [ArgumentError] if this isn't an absolute URL, since [URL] can
-  /// only represent absolute URLs.
-  URL get toJS {
-    try {
-      return URL(toString());
-    } catch (_) {
-      throw ArgumentError.value(this, 'this', '"$this" isn\'t a valid JS URL.');
+  @Equivalence(type: 'HttpRequest', member: 'responseHeaders')
+  Map<String, String> get responseHeaders {
+    final headers = <String, String>{};
+    final headersString = getAllResponseHeaders();
+    final headersList = headersString.split('\r\n');
+    for (final header in headersList) {
+      if (header.isEmpty) {
+        continue;
+      }
+      final splitIdx = header.indexOf(': ');
+      if (splitIdx == -1) {
+        continue;
+      }
+      final key = header.substring(0, splitIdx).toLowerCase();
+      final value = header.substring(splitIdx + 2);
+      if (headers.containsKey(key)) {
+        headers[key] = '${headers[key]}, $value';
+      } else {
+        headers[key] = value;
+      }
     }
+    return headers;
   }
 }
 
-extension MouseEventExtension on MouseEvent {
-  @Equivalence(type: 'MouseEvent', member: 'client')
-  Point get client => Point(clientX, clientY);
-
-  @Equivalence(type: 'MouseEvent', member: 'screen')
-  Point get screen => Point(screenX, screenY);
-
-  @Equivalence(type: 'MouseEvent', member: 'page')
-  Point get page => Point(pageX, pageY);
-
-  // This really belongs on the `DragEvent` subtype, but `dart:html` moved it
-  // up.
-  @Equivalence(type: 'MouseEvent', member: 'dataTransfer')
-  external DataTransfer get dataTransfer;
-}
-
-extension NodeExtension on Node {
-  @Equivalence(type: 'Node', member: 'text')
-  String? get text => textContent;
-
-  @Equivalence(type: 'Node', member: 'text')
-  set text(String? s) => textContent = s;
-
-  @Equivalence(type: 'Node', member: 'append')
-  Node append(Node other) => appendChild(other);
-
-  @Equivalence(type: 'Node', member: 'clone')
-  Node clone(bool? deep) => cloneNode(deep ?? false);
-
-  @Equivalence(type: 'Node', member: 'parent')
-  Element? get parent => parentElement;
-
-  @Equivalence(type: 'Node', member: 'nextNode')
-  Node? get nextNode => nextSibling;
-
-  @Equivalence(type: 'Node', member: 'remove')
-  void remove() {
-    final parent = parentNode;
-    if (parent != null) {
-      parent.removeChild(this);
-    }
-  }
-
-  @Equivalence(type: 'Node', member: 'insertAllBefore')
-  void insertAllBefore(Iterable<Node> newNodes, Node child) {
-    // `toList` to avoid potential infinite recursion if `newNodes` is a wrapper
-    // around this `Node`.
-    for (var node in newNodes.toList()) {
-      insertBefore(node, child);
-    }
-  }
-
-  /// Returns [childNodes] as a modifiable [List].
-  @Equivalence(type: 'Node', member: 'childNodes')
-  List<Node> get childNodesAsList => NodeListListWrapper(this, childNodes);
-
-  @Equivalence(type: 'Node', member: 'nodes')
-  List<Node> get nodes => childNodesAsList;
-
-  @Equivalence(type: 'Node', member: 'nodes')
-  set nodes(Iterable<Node> value) {
-    final copy = value.toList();
-    text = '';
-    for (final node in copy) {
-      appendChild(node);
-    }
-  }
-}
-
-extension NodeListExtension on NodeList {
-  /// Returns node list as an immutable [List].
-  List<T> asList<T extends Node>() => JSImmutableListWrapper<NodeList, T>(this);
-
-  @Equivalence(type: 'NodeList', member: 'isEmpty')
-  bool get isEmpty => length == 0;
-
-  @Equivalence(type: 'NodeList', member: 'elementAt')
-  Node elementAt(int i) => item(i)!;
-}
-
-extension StorageExtension on Storage {
-  @Equivalence(type: 'Storage', member: '[]')
-  String? operator [](String key) => getItem(key);
-
-  @Equivalence(type: 'Storage', member: '[]=')
-  void operator []=(String key, String value) => setItem(key, value);
-}
-
-extension TouchEventExtension on TouchEvent {
-  // Safari still doesn't support `TouchEvent`s:
-  // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent
-  @Equivalence(type: 'TouchEvent', member: 'supported')
-  static bool get supported {
-    try {
-      TouchEvent('touches');
-      return true;
-    } catch (e) {
-      return false;
-    }
-  }
-}
-
-extension TouchExtension on Touch {
-  @Equivalence(type: 'Touch', member: 'page')
-  Point get page => Point(pageX, pageY);
-
-  @Equivalence(type: 'Touch', member: 'client')
-  Point get client => Point(clientX, clientY);
-}
-
-extension TouchListExtension on TouchList {
-  List<Touch> asList() => JSImmutableListWrapper<TouchList, Touch>(this);
-  @Equivalence(type: 'TouchList', member: 'first')
-  Touch get first => item(0)!;
-  @Equivalence(type: 'TouchList', member: 'isEmpty')
-  bool get isEmpty => length == 0;
-  @Equivalence(type: 'TouchList', member: 'elementAt')
-  Touch elementAt(int i) => item(i)!;
-}
-
-extension WindowExtension on Window {
-  @Equivalence(type: 'Window', member: 'animationFrame')
-  Future<num> get animationFrame {
-    final completer = Completer<num>.sync();
-    void getTimestamp(num timestamp) {
-      completer.complete(timestamp);
-    }
-
-    requestAnimationFrame(getTimestamp.toJS);
-    return completer.future;
-  }
-
-  @Equivalence(type: 'Window', member: 'console')
-  StringConsole get console => StringConsole(dom.console);
-
-  @Equivalence(type: 'Window', member: 'localStorage')
-  StorageMap get localStorageAsMap => StorageMap(localStorage);
-
-  @Equivalence(type: 'Window', member: 'sessionStorage')
-  StorageMap get sessionStorageAsMap => StorageMap(sessionStorage);
-}
-
 @Equivalence(type: null, member: 'querySelector')
 Element? querySelector(String selectors) => document.querySelector(selectors);