// Copyright (c) 2025, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// API docs from [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web).
// Attributions and copyright licensing by Mozilla Contributors is licensed
// under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/.

// Generated from Web IDL definitions.

// ignore_for_file: unintended_html_in_doc_comment

@JS()
library;

import 'dart:js_interop';

import 'css_font_loading.dart';
import 'css_typed_om.dart';
import 'css_view_transitions.dart';
import 'cssom.dart';
import 'cssom_view.dart';
import 'fullscreen.dart';
import 'geometry.dart';
import 'html.dart';
import 'pointerlock.dart';
import 'scroll_to_text_fragment.dart';
import 'selection_api.dart';
import 'svg.dart';
import 'web_animations.dart';

typedef MutationCallback = JSFunction;
typedef EventListener = JSFunction;
typedef NodeFilter = JSFunction;
typedef XPathNSResolver = JSFunction;
typedef ShadowRootMode = String;
typedef SlotAssignmentMode = String;

/// The **`Event`** interface represents an event which takes place on an
/// [`EventTarget`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget).
///
/// An event can be triggered by the user action e.g. clicking the mouse button
/// or tapping keyboard, or generated by APIs to represent the progress of an
/// asynchronous task. It can also be triggered programmatically, such as by
/// calling the
/// [`HTMLElement.click()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click)
/// method of an element, or by defining the event, then sending it to a
/// specified target using
/// [`EventTarget.dispatchEvent()`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent).
///
/// There are many types of events, some of which use other interfaces based on
/// the main `Event` interface. `Event` itself contains the properties and
/// methods which are common to all events.
///
/// Many DOM elements can be set up to accept (or "listen" for) these events,
/// and execute code in response to process (or "handle") them. Event-handlers
/// are usually connected (or "attached") to various
/// [HTML elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element)
/// (such as `<button>`, `<div>`, `<span>`, etc.) using
/// [`EventTarget.addEventListener()`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener),
/// and this generally replaces using the old HTML
/// [event handler attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes).
/// Further, when properly added, such handlers can also be disconnected if
/// needed using
/// [`removeEventListener()`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener).
///
/// > [!NOTE]
/// > One element can have several such handlers, even for the exact same
/// > event—particularly if separate, independent code modules attach them, each
/// > for its own independent purposes. (For example, a webpage with an
/// > advertising-module and statistics-module both monitoring video-watching.)
///
/// When there are many nested elements, each with its own handler(s), event
/// processing can become very complicated—especially where a parent element
/// receives the very same event as its child elements because "spatially" they
/// overlap so the event technically occurs in both, and the processing order of
/// such events depends on the
/// [Event bubbling](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling)
/// settings of each handler triggered.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Event).
extension type Event._(JSObject _) implements JSObject {
  external factory Event(
    String type, [
    EventInit eventInitDict,
  ]);

  static const int NONE = 0;

  static const int CAPTURING_PHASE = 1;

  static const int AT_TARGET = 2;

  static const int BUBBLING_PHASE = 3;

  /// The **`composedPath()`** method of the [Event]
  /// interface returns the event's path which is an array of the objects on
  /// which listeners
  /// will be invoked. This does not include nodes in shadow trees if the shadow
  /// root was
  /// created with its [ShadowRoot.mode] closed.
  external JSArray<EventTarget> composedPath();

  /// The **`stopPropagation()`** method of the [Event]
  /// interface prevents further propagation of the current event in the
  /// capturing and
  /// bubbling phases. It does not, however, prevent any default behaviors from
  /// occurring; for
  /// instance, clicks on links are still processed. If you want to stop those
  /// behaviors, see
  /// the [Event.preventDefault] method. It also does not
  /// prevent propagation to other event-handlers of the current element. If you
  /// want to stop those,
  /// see [Event.stopImmediatePropagation].
  external void stopPropagation();

  /// The **`stopImmediatePropagation()`** method of the
  /// [Event] interface prevents other listeners of the same event from being
  /// called.
  ///
  /// If several listeners are attached to the same element for the same event
  /// type, they are called in the order in which they were added. If
  /// `stopImmediatePropagation()` is invoked during one such call, no remaining
  /// listeners will be called, either on that element or any other element.
  external void stopImmediatePropagation();

  /// The **`preventDefault()`** method of the [Event] interface tells the  that
  /// if the event does not get explicitly handled, its default action should
  /// not be taken as it normally would be.
  ///
  /// The event continues to propagate as usual,
  /// unless one of its event listeners calls
  /// [Event.stopPropagation]
  /// or [Event.stopImmediatePropagation],
  /// either of which terminates propagation at once.
  ///
  /// As noted below, calling **`preventDefault()`** for a
  /// non-cancelable event, such as one dispatched via
  /// [EventTarget.dispatchEvent], without specifying
  /// `cancelable: true` has no effect.
  ///
  /// If a passive listener calls `preventDefault()`, nothing will happen and a
  /// console warning may be generated.
  external void preventDefault();

  /// The **`Event.initEvent()`** method is used to initialize the
  /// value of an [event] created using [Document.createEvent].
  ///
  /// Events initialized in this way must have been created with the
  /// [Document.createEvent] method.
  /// This method must be called to set the event
  /// before it is dispatched, using [EventTarget.dispatchEvent].
  /// Once dispatched, it doesn't do anything anymore.
  ///
  /// > **Note:** _Do not use this method anymore as it is deprecated._
  /// > Instead use specific event constructors, like [Event.Event].
  /// > The page on
  /// > [Creating and triggering events](https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events)
  /// > gives more information about the way to use these.
  external void initEvent(
    String type, [
    bool bubbles,
    bool cancelable,
  ]);

  /// The **`type`** read-only property of the [Event]
  /// interface returns a string containing the event's type. It is set when the
  /// event is
  /// constructed and is the name commonly used to refer to the specific event,
  /// such as
  /// `click`, `load`, or `error`.
  external String get type;

  /// The read-only **`target`** property of the
  /// [Event] interface is a reference to the object onto which the event was
  /// dispatched. It is different from [Event.currentTarget] when the event
  /// handler is called during the bubbling or capturing phase of the event.
  external EventTarget? get target;

  /// The deprecated **`Event.srcElement`** is an alias for the [Event.target]
  /// property. Use [Event.target] instead.
  external EventTarget? get srcElement;

  /// The **`currentTarget`** read-only property of the [Event] interface
  /// identifies the element to which the event handler has been attached.
  ///
  /// This will not always be the same as the element on which the event was
  /// fired, because the event may have fired on a descendant of the element
  /// with the handler, and then
  /// [bubbled](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling)
  /// up to the element with the handler. The element on which the event was
  /// fired is given by [Event.target].
  ///
  /// Note that the value of `currentTarget` is only available in a handler for
  /// the event. Outside an event handler it will be `null`. This means that,
  /// for example, if you take a reference to the `Event` object inside an event
  /// handler and then access its `currentTarget` property outside the event
  /// handler, its value will be `null`.
  external EventTarget? get currentTarget;

  /// The **`eventPhase`** read-only property of the
  /// [Event] interface indicates which phase of the event flow is currently
  /// being evaluated.
  external int get eventPhase;

  /// The **`cancelBubble`** property of the [Event]
  /// interface is deprecated. Use [Event.stopPropagation] instead.
  /// Setting its value to `true` before returning from an event handler
  /// prevents propagation
  /// of the event. In later implementations, setting this to `false` does
  /// nothing.
  /// See [Browser compatibility](#browser_compatibility) for details.
  external bool get cancelBubble;
  external set cancelBubble(bool value);

  /// The **`bubbles`** read-only property of the [Event] interface indicates
  /// whether the event bubbles up through the DOM tree or not.
  ///
  /// > [!NOTE]
  /// > See
  /// > [Event bubbling](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling)
  /// > for more information on bubbling.
  external bool get bubbles;

  /// The **`cancelable`** read-only property of the [Event] interface indicates
  /// whether the event
  /// can be canceled, and therefore prevented as if the event never happened.
  ///
  /// If the event is _not_ cancelable, then its `cancelable` property will be
  /// `false` and the event listener cannot stop the event from occurring.
  ///
  /// Most browser-native events that can be canceled are the ones that result
  /// from the user
  /// interacting with the page. Canceling the [Element.click_event],
  /// [Element.wheel_event], or
  /// [Window.beforeunload_event] events would prevent the user
  /// from clicking on something, scrolling the page with the mouse wheel, or
  /// navigating away from the page, respectively.
  ///
  /// [Synthetic events](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event)
  /// created by other JavaScript
  /// code define if they can be canceled when they are created.
  ///
  /// To cancel an event, call the [event.preventDefault]
  /// method on the event. This keeps the implementation from executing the
  /// default action
  /// that is associated with the event.
  ///
  /// Event listeners that handle multiple kinds of events may want to check
  /// `cancelable` before invoking their [event.preventDefault] methods.
  external bool get cancelable;

  /// The [Event] property
  /// **`returnValue`** indicates whether the default action for
  /// this event has been prevented or not.
  ///
  /// It is set to `true` by
  /// default, allowing the default action to occur. Setting this property to
  /// `false` prevents the default action.
  ///
  /// > [!NOTE]
  /// > While `returnValue` has been adopted into the DOM
  /// > standard, it is present primarily to support existing code. Use
  /// > [Event.preventDefault], and
  /// > [Event.defaultPrevented] instead of this historical
  /// > property.
  external bool get returnValue;
  external set returnValue(bool value);

  /// The **`defaultPrevented`** read-only property of the [Event] interface
  /// returns a boolean value indicating whether or not the call to
  /// [Event.preventDefault] canceled the event.
  external bool get defaultPrevented;

  /// The read-only **`composed`** property of the
  /// [Event] interface returns a boolean value which indicates whether
  /// or not the event will propagate across the shadow DOM boundary into the
  /// standard DOM.
  ///
  /// All UA-dispatched UI events are composed
  /// (click/touch/mouseover/copy/paste, etc.). Most
  /// other types of events are not composed, and so will return `false`. For
  /// example, this includes synthetic events that are created without their
  /// `composed` option set to `true`.
  ///
  /// Propagation only occurs if the [Event.bubbles] property is also
  /// `true`. However, capturing only composed events are also handled at host
  /// as
  /// if they were in `AT_TARGET` phase. You can determine the path the event
  /// will
  /// follow through the shadow root to the DOM root by calling
  /// [Event.composedPath].
  external bool get composed;

  /// The **`isTrusted`** read-only property of the
  /// [Event] interface is a boolean value that is `true`
  /// when the event was generated by the user agent (including via user actions
  /// and programmatic methods such as [HTMLElement.focus]),
  /// and `false` when the event was dispatched via
  /// [EventTarget.dispatchEvent].
  /// The only exception is the `click` event, which initializes the `isTrusted`
  /// property to `false` in user agents.
  external bool get isTrusted;

  /// The **`timeStamp`** read-only property of the [Event] interface returns
  /// the time (in milliseconds) at which the event was created.
  external double get timeStamp;
}
extension type EventInit._(JSObject _) implements JSObject {
  external factory EventInit({
    bool bubbles,
    bool cancelable,
    bool composed,
  });

  external bool get bubbles;
  external set bubbles(bool value);
  external bool get cancelable;
  external set cancelable(bool value);
  external bool get composed;
  external set composed(bool value);
}

/// The **`CustomEvent`** interface represents events initialized by an
/// application for any purpose.
///
/// > [!NOTE]
/// > If used to attempt to communicate between a web extension content script
/// > and a web page script, a non-string `detail` property throws with
/// > "Permission denied to access property" in Firefox. To avoid this issue
/// > clone the object. See
/// > [Share objects with page scripts](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts)
/// > for more information.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent).
extension type CustomEvent._(JSObject _) implements Event, JSObject {
  external factory CustomEvent(
    String type, [
    CustomEventInit eventInitDict,
  ]);

  /// The **`CustomEvent.initCustomEvent()`** method initializes a [CustomEvent]
  /// object.
  /// If the event has already been dispatched, this method does nothing.
  ///
  /// Events initialized in this way must have been created with the
  /// [Document.createEvent] method.
  /// This method must be called to set the event before it is dispatched using
  /// [EventTarget.dispatchEvent].
  /// Once dispatched, it doesn't do anything anymore.
  ///
  /// > **Note:** **Do not use this method anymore, as it is deprecated.**
  /// >
  /// > Rather than using the feature, instead use specific event constructors,
  /// > like [CustomEvent.CustomEvent].
  /// > The page on
  /// > [Creating and triggering events](https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events)
  /// > gives more information about the way to use those.
  external void initCustomEvent(
    String type, [
    bool bubbles,
    bool cancelable,
    JSAny? detail,
  ]);

  /// The read-only **`detail`** property of the [CustomEvent] interface returns
  /// any data passed when initializing the event.
  external JSAny? get detail;
}
extension type CustomEventInit._(JSObject _) implements EventInit, JSObject {
  external factory CustomEventInit({
    bool bubbles,
    bool cancelable,
    bool composed,
    JSAny? detail,
  });

  external JSAny? get detail;
  external set detail(JSAny? value);
}

/// The **`EventTarget`** interface is implemented by objects that can receive
/// events and may have listeners for them.
/// In other words, any target of events implements the three methods associated
/// with this interface.
///
/// [Element], and its children, as well as [Document] and [Window], are the
/// most common event targets,
/// but other objects can be event targets, too.
/// For example [IDBRequest], [AudioNode], and [AudioContext] are also event
/// targets.
///
/// Many event targets (including elements, documents, and windows) also support
/// setting
/// [event handlers](https://developer.mozilla.org/en-US/docs/Web/Events/Event_handlers)
/// via `onevent` properties and attributes.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget).
extension type EventTarget._(JSObject _) implements JSObject {
  external factory EventTarget();

  /// The **`addEventListener()`** method of the [EventTarget] interface
  /// sets up a function that will be called whenever the specified event is
  /// delivered to the target.
  ///
  /// Common targets are [Element], or its children, [Document], and [Window],
  /// but the target may be any object that supports events (such as
  /// [IDBRequest]).
  ///
  /// > [!NOTE]
  /// > The `addEventListener()` method is the _recommended_ way to register an
  /// > event listener. The benefits are as follows:
  /// >
  /// > - It allows adding more than one handler for an event. This is
  /// > particularly
  /// > useful for libraries, JavaScript modules, or any other kind of
  /// > code that needs to work well with other libraries or extensions.
  /// > - In contrast to using an `onXYZ` property, it gives you finer-grained
  /// > control of the phase when the listener is activated (capturing vs.
  /// > bubbling).
  /// > - It works on any event target, not just HTML or SVG elements.
  ///
  /// The method `addEventListener()` works by adding a function, or an object
  /// that implements a `handleEvent()` function, to the list of event listeners
  /// for the specified event type
  /// on the [EventTarget] on which it's called. If the function or object is
  /// already in the list of event listeners for this target, the function or
  /// object is not added a second time.
  ///
  /// > [!NOTE]
  /// > If a particular anonymous function is in the list of event listeners
  /// > registered for a certain target, and then later in the code, an
  /// > identical anonymous function is given in an `addEventListener` call, the
  /// > second function will _also_ be added to the list of event listeners for
  /// > that target.
  /// >
  /// > Indeed, anonymous functions are not identical even if defined using
  /// > the _same_ unchanging source-code called repeatedly, **even if in a
  /// > loop**.
  /// >
  /// > Repeatedly defining the same unnamed function in such cases can be
  /// > problematic. (See [Memory issues](#memory_issues), below.)
  ///
  /// If an event listener is added to an [EventTarget] from inside another
  /// listener —
  /// that is, during the processing of the event —
  /// that event will not trigger the new listener.
  /// However, the new listener may be triggered during a later stage of event
  /// flow,
  /// such as during the bubbling phase.
  external void addEventListener(
    String type,
    EventListener? callback, [
    JSAny options,
  ]);

  /// The **`removeEventListener()`** method of the [EventTarget] interface
  /// removes an event listener previously registered with
  /// [EventTarget.addEventListener] from the target.
  /// The event listener to be removed is identified using a combination of the
  /// event type,
  /// the event listener function itself, and various optional options that may
  /// affect the matching process;
  /// see
  /// [Matching event listeners for removal](#matching_event_listeners_for_removal).
  ///
  /// Calling `removeEventListener()` with arguments that do not identify any
  /// currently registered
  /// [event listener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#the_event_listener_callback)
  /// on the `EventTarget` has no
  /// effect.
  ///
  /// If an
  /// [event listener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#the_event_listener_callback)
  /// is removed from an [EventTarget] while another listener of the target is
  /// processing an event, it will not be triggered by the event. However, it
  /// can be reattached.
  ///
  /// > [!WARNING]
  /// > If a listener is registered twice, one with the _capture_ flag set and
  /// > one without, you must remove each one separately. Removal of a capturing
  /// > listener does not affect a non-capturing version of the same listener,
  /// > and vice versa.
  ///
  /// Event listeners can also be removed by passing an [AbortSignal] to an
  /// [EventTarget.addEventListener] and then later calling
  /// [AbortController.abort] on the controller owning the signal.
  external void removeEventListener(
    String type,
    EventListener? callback, [
    JSAny options,
  ]);

  /// The **`dispatchEvent()`** method of the [EventTarget] sends an [Event] to
  /// the object, (synchronously) invoking the affected
  /// event listeners in the appropriate order. The normal event processing
  /// rules (including the capturing and optional bubbling phase) also apply to
  /// events
  /// dispatched manually with `dispatchEvent()`.
  ///
  /// Calling `dispatchEvent()` is the last step to _firing an event_. The event
  /// should have already been created and initialized using an [Event.Event]
  /// constructor.
  ///
  /// > [!NOTE]
  /// > When calling this method, the [Event.target] property is initialized to
  /// > the current `EventTarget`.
  ///
  /// Unlike "native" events, which are fired by the browser and invoke event
  /// handlers
  /// asynchronously via the
  /// [event loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop),
  /// `dispatchEvent()` invokes event handlers _synchronously_. All applicable
  /// event
  /// handlers are called and return before `dispatchEvent()` returns.
  external bool dispatchEvent(Event event);
}
extension type EventListenerOptions._(JSObject _) implements JSObject {
  external factory EventListenerOptions({bool capture});

  external bool get capture;
  external set capture(bool value);
}
extension type AddEventListenerOptions._(JSObject _)
    implements EventListenerOptions, JSObject {
  external factory AddEventListenerOptions({
    bool capture,
    bool passive,
    bool once,
    AbortSignal signal,
  });

  external bool get passive;
  external set passive(bool value);
  external bool get once;
  external set once(bool value);
  external AbortSignal get signal;
  external set signal(AbortSignal value);
}

/// The **`AbortController`** interface represents a controller object that
/// allows you to abort one or more Web requests as and when desired.
///
/// You can create a new `AbortController` object using the
/// [AbortController.AbortController] constructor. Communicating with an
/// asynchronous operation is done using an [AbortSignal] object.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
extension type AbortController._(JSObject _) implements JSObject {
  external factory AbortController();

  /// The **`abort()`** method of the [AbortController] interface aborts an
  /// asynchronous operation before it has completed.
  /// This is able to abort
  /// [fetch requests](https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch),
  /// the consumption of any response bodies, or streams.
  external void abort([JSAny? reason]);

  /// The **`signal`** read-only property of the [AbortController] interface
  /// returns an [AbortSignal] object instance, which can be used to communicate
  /// with/abort an asynchronous operation as desired.
  external AbortSignal get signal;
}

/// The **`AbortSignal`** interface represents a signal object that allows you
/// to communicate with an asynchronous operation (such as a fetch request) and
/// abort it if required via an [AbortController] object.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
extension type AbortSignal._(JSObject _) implements EventTarget, JSObject {
  /// The **`AbortSignal.abort()`** static method returns an [AbortSignal] that
  /// is already set as aborted (and which does not trigger an
  /// [AbortSignal.abort_event] event).
  ///
  /// This is shorthand for the following code:
  ///
  /// ```js
  /// const controller = new AbortController();
  /// controller.abort();
  /// return controller.signal;
  /// ```
  ///
  /// This could, for example, be passed to a fetch method in order to run its
  /// abort logic (i.e. it may be that code is organized such that the abort
  /// logic should be run even if the intended fetch operation has not been
  /// started).
  ///
  /// > [!NOTE]
  /// > The method is similar in purpose to `Promise.reject`.
  external static AbortSignal abort([JSAny? reason]);

  /// The **`AbortSignal.timeout()`** static method returns an [AbortSignal]
  /// that will automatically abort after a specified time.
  ///
  /// The signal aborts with a `TimeoutError` [DOMException] on timeout.
  ///
  /// The timeout is based on active rather than elapsed time, and will
  /// effectively be paused if the code is running in a suspended worker, or
  /// while the document is in a back-forward cache
  /// ("[bfcache](https://web.dev/articles/bfcache)").
  ///
  /// To combine multiple signals, you can use [AbortSignal.any_static], for
  /// example, to directly abort a download using either a timeout signal or by
  /// calling [AbortController.abort].
  external static AbortSignal timeout(int milliseconds);

  /// The **`AbortSignal.any()`** static method takes an iterable of abort
  /// signals and returns an [AbortSignal]. The returned abort signal is aborted
  /// when any of the input iterable abort signals are aborted. The
  /// [AbortSignal.reason] will be set to the reason of the first signal that is
  /// aborted. If any of the given abort signals are already aborted then so
  /// will be the returned [AbortSignal].
  external static AbortSignal any(JSArray<AbortSignal> signals);

  /// The **`throwIfAborted()`** method throws the signal's abort
  /// [AbortSignal.reason] if the signal has been aborted; otherwise it does
  /// nothing.
  ///
  /// An API that needs to support aborting can accept an [AbortSignal] object
  /// and use `throwIfAborted()` to test and throw when the
  /// [`abort`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/abort_event)
  /// event is signalled.
  ///
  /// This method can also be used to abort operations at particular points in
  /// code, rather than passing to functions that take a signal.
  external void throwIfAborted();

  /// The **`aborted`** read-only property returns a value that indicates
  /// whether the asynchronous operations the signal is communicating with are
  /// aborted (`true`) or not (`false`).
  external bool get aborted;

  /// The **`reason`** read-only property returns a JavaScript value that
  /// indicates the abort reason.
  ///
  /// The property is `undefined` when the signal has not been aborted.
  /// It can be set to a specific value when the signal is aborted, using
  /// [AbortController.abort] or [AbortSignal.abort_static].
  /// If not explicitly set in those methods, it defaults to "AbortError"
  /// [DOMException].
  external JSAny? get reason;
  external EventHandler get onabort;
  external set onabort(EventHandler value);
}

/// **`NodeList`** objects are collections of
/// [nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node), usually
/// returned by properties such as [Node.childNodes] and methods such as
/// [document.querySelectorAll].
///
/// This interface was an
/// [attempt to create an unmodifiable list](https://stackoverflow.com/questions/74630989/why-use-domstringlist-rather-than-an-array/74641156#74641156)
/// and only continues to be supported to not break code that's already using
/// it. Modern APIs represent list structures using types based on JavaScript
/// [arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array),
/// thus making many array methods available, and at the same time imposing
/// additional semantics on their usage (such as making their items read-only).
///
/// These historical reasons do not mean that you as a developer should avoid
/// `NodeList`. You don't create `NodeList` objects yourself, but you get them
/// from APIs such as [Document.querySelectorAll], and these APIs are not
/// deprecated. However, be careful of the semantic differences from a real
/// array.
///
/// Although `NodeList` is not an `Array`, it is possible to iterate over it
/// with `forEach()`. It can also be converted to a real `Array` using
/// `Array.from()`.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/NodeList).
extension type NodeList._(JSObject _) implements JSObject {
  /// Returns a node from a
  /// [`NodeList`](https://developer.mozilla.org/en-US/docs/Web/API/NodeList) by
  /// index. This method
  /// doesn't throw exceptions as long as you provide arguments. A value of
  /// `null`
  /// is returned if the index is out of range, and a `TypeError` is thrown if
  /// no
  /// argument is provided.
  ///
  /// In JavaScript, instead of calling `nodeList.item(index)`, you can also
  /// access the `index` directly, like `nodeList[index]`.
  external Node? item(int index);

  /// The **`NodeList.length`** property returns the number of items
  /// in a [NodeList].
  external int get length;
}

/// The **`HTMLCollection`** interface represents a generic collection
/// (array-like object similar to `arguments`) of elements (in document order)
/// and offers methods and properties for selecting from the list.
///
/// An `HTMLCollection` in the HTML DOM is live; it is automatically updated
/// when the underlying document is changed. For this reason it is a good idea
/// to make a copy (e.g., using `Array.from`) to iterate over if adding, moving,
/// or removing nodes.
///
/// This interface is called `HTMLCollection` for historical reasons, because
/// before the modern DOM, collections implementing this interface could only
/// have HTML elements as their items.
///
/// This interface was an
/// [attempt to create an unmodifiable list](https://stackoverflow.com/questions/74630989/why-use-domstringlist-rather-than-an-array/74641156#74641156)
/// and only continues to be supported to not break code that's already using
/// it. Modern APIs represent list structures using types based on JavaScript
/// [arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array),
/// thus making many array methods available, and at the same time imposing
/// additional semantics on their usage (such as making their items read-only).
///
/// These historical reasons do not mean that you as a developer should avoid
/// `HTMLCollection`. You don't create `HTMLCollection` objects yourself, but
/// you get them from APIs such as [Document.getElementsByClassName], and these
/// APIs are not deprecated. However, be careful of the semantic differences
/// from a real array.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection).
extension type HTMLCollection._(JSObject _) implements JSObject {
  /// The [HTMLCollection] method `item()`
  /// returns the element located at the specified offset into the collection.
  ///
  /// > [!NOTE]
  /// > Because the contents of an `HTMLCollection` are
  /// > live, changes to the underlying DOM can and will cause the position of
  /// > individual
  /// > elements in the collection to change, so the index value will not
  /// > necessarily remain
  /// > constant for a given element.
  external Element? item(int index);

  /// The **`namedItem()`** method of the [HTMLCollection] interface returns
  /// the first [Element] in the collection whose `id` or `name` attribute match
  /// the specified name, or `null` if no element matches.
  ///
  /// In JavaScript, instead of calling `collection.namedItem("value")`, you can
  /// also directly access the name on the collection, like
  /// `collection["value"]`, unless the name collides with one of the existing
  /// `HTMLCollection` properties.
  external Element? namedItem(String name);

  /// The **`HTMLCollection.length`** property returns the number of
  /// items in a [HTMLCollection].
  external int get length;
}

/// The **`MutationObserver`** interface provides the ability to watch for
/// changes being made to the
/// [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)
/// tree. It is designed as a replacement for the older
/// [Mutation Events](https://developer.mozilla.org/en-US/docs/Web/API/MutationEvent)
/// feature, which was part of the DOM3 Events specification.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).
extension type MutationObserver._(JSObject _) implements JSObject {
  external factory MutationObserver(MutationCallback callback);

  /// The [MutationObserver] method **`observe()`** configures the
  /// `MutationObserver`
  /// callback to begin receiving notifications of changes to the DOM that match
  /// the given options.
  ///
  /// Depending on the configuration, the observer may watch a single [Node] in
  /// the DOM tree, or that node and some or all of its descendant nodes. The
  /// same node can be observed by multiple observers, and the same
  /// `MutationObserver` can watch for changes to different parts of the DOM
  /// tree and/or different types of changes by calling `observe()` multiple
  /// times on the same
  /// `MutationObserver`.
  ///
  /// To stop the `MutationObserver` (so that none of its callbacks will be
  /// triggered any longer), call [MutationObserver.disconnect].
  external void observe(
    Node target, [
    MutationObserverInit options,
  ]);

  /// The [MutationObserver] method
  /// **`disconnect()`** tells the observer to stop watching for
  /// mutations.
  ///
  /// The observer can be reused by calling its
  /// [MutationObserver.observe] method again.
  external void disconnect();

  /// The [MutationObserver] method
  /// **`takeRecords()`** returns a list of all matching DOM changes
  /// that have been detected but not yet processed by the observer's callback
  /// function,
  /// leaving the mutation queue empty.
  ///
  /// The most common use case for this is to
  /// immediately fetch all pending mutation records immediately prior to
  /// disconnecting the
  /// observer, so that any pending mutations can be processed when shutting
  /// down the
  /// observer.
  external JSArray<MutationRecord> takeRecords();
}
extension type MutationObserverInit._(JSObject _) implements JSObject {
  external factory MutationObserverInit({
    bool childList,
    bool attributes,
    bool characterData,
    bool subtree,
    bool attributeOldValue,
    bool characterDataOldValue,
    JSArray<JSString> attributeFilter,
  });

  external bool get childList;
  external set childList(bool value);
  external bool get attributes;
  external set attributes(bool value);
  external bool get characterData;
  external set characterData(bool value);
  external bool get subtree;
  external set subtree(bool value);
  external bool get attributeOldValue;
  external set attributeOldValue(bool value);
  external bool get characterDataOldValue;
  external set characterDataOldValue(bool value);
  external JSArray<JSString> get attributeFilter;
  external set attributeFilter(JSArray<JSString> value);
}

/// The **`MutationRecord`** is a read-only interface that represents an
/// individual DOM mutation observed by a [MutationObserver]. It is the object
/// inside the array passed to the callback of a [MutationObserver].
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/MutationRecord).
extension type MutationRecord._(JSObject _) implements JSObject {
  /// The [MutationRecord] read-only property **`type`** is the type of the
  /// [MutationRecord] observed by a [MutationObserver].
  external String get type;

  /// The [MutationRecord] read-only property **`target`** is the target (i.e.
  /// the mutated/changed node) of a mutation observed with a
  /// [MutationObserver].
  external Node get target;

  /// The [MutationRecord] read-only property **`addedNodes`** is a [NodeList]
  /// of nodes added to a target node by a mutation observed with a
  /// [MutationObserver].
  external NodeList get addedNodes;

  /// The [MutationRecord] read-only property **`removedNodes`** is a [NodeList]
  /// of nodes removed from a target node by a mutation observed with a
  /// [MutationObserver].
  external NodeList get removedNodes;

  /// The [MutationRecord] read-only property **`previousSibling`** is the
  /// previous sibling of an added or removed child node of the
  /// [`target`](https://developer.mozilla.org/en-US/docs/Web/API/MutationRecord/target)
  /// of a [MutationObserver].
  external Node? get previousSibling;

  /// The [MutationRecord] read-only property **`nextSibling`** is the next
  /// sibling of an added or removed child node of the
  /// [`target`](https://developer.mozilla.org/en-US/docs/Web/API/MutationRecord/target)
  /// of a [MutationObserver].
  external Node? get nextSibling;

  /// The [MutationRecord] read-only property **`attributeName`** contains the
  /// name of a changed attribute belonging to a node that is observed by a
  /// [MutationObserver].
  external String? get attributeName;

  /// The [MutationRecord] read-only property **`attributeNamespace`** is the
  /// namespace of the mutated attribute in the [MutationRecord] observed by a
  /// [MutationObserver].
  external String? get attributeNamespace;

  /// The [MutationRecord] read-only property **`oldValue`** contains the
  /// character data or attribute value of an observed node before it was
  /// changed.
  external String? get oldValue;
}

/// The  **`Node`** interface is an abstract base
/// class upon which many other DOM API objects are based, thus letting those
/// object types
/// to be used similarly and often interchangeably. As an abstract class, there
/// is
/// no such thing as a plain `Node` object. All objects that implement
/// `Node` functionality are based on one of its subclasses. Most notable are
/// [Document], [Element], and [DocumentFragment].
///
/// In addition, every kind of DOM node is represented by an interface based on
/// `Node`. These include [Attr], [CharacterData]
/// (which [Text], [Comment], [CDATASection] and
/// [ProcessingInstruction] are all based on), and [DocumentType].
///
/// In some cases, a particular feature of the base `Node` interface may not
/// apply to one of its child interfaces; in that case, the inheriting node may
/// return `null` or throw an exception, depending on circumstances. For
/// example,
/// attempting to add children to a node type that cannot have children will
/// throw an
/// exception.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Node).
extension type Node._(JSObject _) implements EventTarget, JSObject {
  static const int ELEMENT_NODE = 1;

  static const int ATTRIBUTE_NODE = 2;

  static const int TEXT_NODE = 3;

  static const int CDATA_SECTION_NODE = 4;

  static const int ENTITY_REFERENCE_NODE = 5;

  static const int ENTITY_NODE = 6;

  static const int PROCESSING_INSTRUCTION_NODE = 7;

  static const int COMMENT_NODE = 8;

  static const int DOCUMENT_NODE = 9;

  static const int DOCUMENT_TYPE_NODE = 10;

  static const int DOCUMENT_FRAGMENT_NODE = 11;

  static const int NOTATION_NODE = 12;

  static const int DOCUMENT_POSITION_DISCONNECTED = 1;

  static const int DOCUMENT_POSITION_PRECEDING = 2;

  static const int DOCUMENT_POSITION_FOLLOWING = 4;

  static const int DOCUMENT_POSITION_CONTAINS = 8;

  static const int DOCUMENT_POSITION_CONTAINED_BY = 16;

  static const int DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;

  /// The **`getRootNode()`** method of the [Node] interface
  /// returns the context object's root,
  /// which optionally includes the shadow root if it is available.
  external Node getRootNode([GetRootNodeOptions options]);

  /// The **`hasChildNodes()`** method of the [Node] interface
  /// returns a boolean value indicating
  /// whether the given [Node] has
  /// [child nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes)
  /// or not.
  external bool hasChildNodes();

  /// The **`normalize()`** method of the [Node] interface puts the specified
  /// node
  /// and all of its sub-tree into a _normalized_ form.
  /// In a normalized sub-tree, no text nodes in the sub-tree are empty and
  /// there are no adjacent text nodes.
  external void normalize();

  /// The **`cloneNode()`** method of the [Node] interface
  /// returns a duplicate of the node on which this method was called.
  /// Its parameter controls if the subtree contained in a node is also cloned
  /// or not.
  ///
  /// Cloning a node copies all of its attributes and their values,
  /// including intrinsic (inline) listeners. It does _not_ copy event listeners
  /// added
  /// using
  /// [`addEventListener()`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
  /// or
  /// those assigned to element properties (e.g., `node.onclick =
  /// someFunction`).
  /// Additionally, for a `canvas` element, the painted image is not copied.
  ///
  /// > **Warning:** `cloneNode()` may lead to duplicate element IDs in a
  /// > document!
  /// >
  /// > If the original node has an `id` attribute, and the clone
  /// > will be placed in the same document, then you should modify the clone's
  /// > ID to be
  /// > unique.
  /// >
  /// > Also, `name` attributes may need to be modified,
  /// > depending on whether duplicate names are expected.
  ///
  /// To clone a node to insert into a _different_ document, use
  /// [Document.importNode] instead.
  external Node cloneNode([bool subtree]);

  /// The **`isEqualNode()`** method of the [Node] interface tests whether two
  /// nodes are equal.
  /// Two nodes are equal when they have the same type, defining characteristics
  /// (for
  /// elements, this would be their ID, number of children, and so forth), its
  /// attributes
  /// match, and so on. The specific set of data points that must match varies
  /// depending on
  /// the types of the nodes.
  external bool isEqualNode(Node? otherNode);

  /// The **`isSameNode()`** method of the [Node] interface
  /// is a legacy alias the [for the `===` strict equality
  /// operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality).
  /// That is, it tests whether two nodes are the same
  /// (in other words, whether they reference the same object).
  ///
  /// > [!NOTE]
  /// > There is no need to use `isSameNode()`; instead use the `===` strict
  /// > equality operator.
  external bool isSameNode(Node? otherNode);

  /// The **`compareDocumentPosition()`** method of the [Node] interface
  /// reports the position of its argument node relative to the node on which it
  /// is called.
  external int compareDocumentPosition(Node other);

  /// The **`contains()`** method of the [Node] interface
  /// returns a boolean value indicating
  /// whether a node is a descendant of a given node, that is the node itself,
  /// one of its direct children ([Node.childNodes]),
  /// one of the children's direct children, and so on.
  ///
  /// > [!NOTE]
  /// > A node is _contained_ inside itself.
  external bool contains(Node? other);

  /// The **`lookupPrefix()`** method of the [Node] interface
  /// returns a string containing the prefix for a given namespace URI, if
  /// present,
  /// and `null` if not.
  /// When multiple prefixes are possible, the first prefix is returned.
  external String? lookupPrefix(String? namespace);

  /// The **`lookupNamespaceURI()`** method of the [Node] interface
  /// takes a prefix as parameter and returns the namespace URI associated with
  /// it on the given node if found (and
  /// `null` if not). This method's existence allows `Node` objects to be passed
  /// as a namespace resolver to [XPathEvaluator.createExpression] and
  /// [XPathEvaluator.evaluate].
  external String? lookupNamespaceURI(String? prefix);

  /// The **`isDefaultNamespace()`** method of the [Node] interface accepts a
  /// namespace URI as an argument.
  /// It returns a boolean value that is `true` if the namespace is the default
  /// namespace on the given node and `false` if not.
  ///
  /// > [!NOTE]
  /// > The default namespace of an HTML element is always `""`. For a SVG
  /// > element, it is set by the `xmlns` attribute.
  external bool isDefaultNamespace(String? namespace);

  /// The **`insertBefore()`** method of the [Node] interface
  /// inserts a node before a _reference node_ as a child of a specified _parent
  /// node_.
  ///
  /// If the given node already exists in the document,
  /// `insertBefore()` moves it from its current position to the new position.
  /// (That is, it will automatically be removed from its existing parent
  /// before appending it to the specified new parent.)
  ///
  /// This means that a node cannot be in two locations of the document
  /// simultaneously.
  ///
  /// > [!NOTE]
  /// > The [Node.cloneNode] can be used to make a copy
  /// > of the node before appending it under the new parent. Note that the
  /// > copies made with
  /// > `cloneNode()` will not be automatically kept in sync.
  ///
  /// If the given child is a [DocumentFragment], the entire contents of the
  /// `DocumentFragment` are moved into the child list of the specified parent
  /// node.
  external Node insertBefore(
    Node node,
    Node? child,
  );

  /// The **`appendChild()`** method of the [Node] interface adds a node to the
  /// end of the list of children of a specified parent node.
  ///
  /// > [!NOTE]
  /// > If the given child is a reference to an existing node in the document,
  /// > `appendChild()` moves it from its current position to the new position.
  ///
  /// If the given child is a [DocumentFragment], the entire contents of the
  /// [DocumentFragment] are moved into the child list of the specified parent
  /// node.
  ///
  /// `appendChild()` returns the newly appended node, or if the child is a
  /// [DocumentFragment], the emptied fragment.
  ///
  /// > [!NOTE]
  /// > Unlike this method, the [Element.append] method supports multiple
  /// > arguments and appending strings. You can prefer using it if your node is
  /// > an element.
  external Node appendChild(Node node);

  /// The **`replaceChild()`** method of the [Node] interface replaces a child
  /// node within the given (parent) node.
  external Node replaceChild(
    Node node,
    Node child,
  );

  /// The **`removeChild()`** method of the [Node] interface
  /// removes a child node from the DOM and returns the removed node.
  ///
  /// > [!NOTE]
  /// > As long as a reference is kept on the removed child,
  /// > it still exists in memory, but is no longer part of the DOM.
  /// > It can still be reused later in the code.
  /// >
  /// > If the return value of `removeChild()` is not stored, and no other
  /// > reference is kept,
  /// > it will be
  /// > [automatically deleted](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management)
  /// > from memory after a short time.
  ///
  /// Unlike [Node.cloneNode] the return value preserves the `EventListener`
  /// objects associated with it.
  external Node removeChild(Node child);

  /// The read-only **`nodeType`** property of a [Node] interface is an integer
  /// that identifies what the node is. It distinguishes different kind of nodes
  /// from each other,
  /// such as [Element], [Text] and [Comment].
  external int get nodeType;

  /// The read-only **`nodeName`** property of [Node] returns the name of the
  /// current node as a string.
  external String get nodeName;

  /// The read-only **`baseURI`** property of the [Node] interface
  /// returns the absolute base URL of the document containing the node.
  ///
  /// The base URL is used to resolve relative URLs when the browser needs to
  /// obtain an absolute URL, for example when processing the HTML `img`
  /// element's `src` attribute or the `xlink:href`  or `href` attributes in
  /// SVG.
  ///
  /// Although this property is read-only, its value is determined by an
  /// algorithm each time
  /// the property is accessed, and may change if the conditions changed.
  ///
  /// The base URL is determined as follows:
  ///
  /// 1. By default, the base URL is the location of the document (as determined
  /// by [window.location]).
  /// 2. If it is an HTML Document and there is a `Base` element in the
  /// document,
  /// the `href` value of the _first_ `Base` element with such an attribute is
  /// used instead.
  external String get baseURI;

  /// The read-only **`isConnected`** property of the [Node] interface
  /// returns a boolean indicating whether the node is connected
  /// (directly or indirectly) to a [Document] object.
  external bool get isConnected;

  /// The read-only **`ownerDocument`** property of the [Node] interface
  /// returns the top-level document object of the node.
  external Document? get ownerDocument;

  /// The read-only **`parentNode`** property of the [Node] interface
  /// returns the parent of the specified node in the DOM tree.
  ///
  /// `Document` and `DocumentFragment`
  /// [nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType)
  /// can never have a parent, so
  /// `parentNode` will always return `null`.
  /// It also returns `null` if the node has just been created
  /// and is not yet attached to the tree. [Node.parentElement] on the other
  /// hand only returns `Element` nodes.
  external Node? get parentNode;

  /// The read-only **`parentElement`** property of [Node] interface
  /// returns the DOM node's parent [Element], or `null` if the node either has
  /// no
  /// parent, or its parent isn't a DOM [Element]. [Node.parentNode] on the
  /// other hand returns any kind of parent, regardless of its type.
  external Element? get parentElement;

  /// The read-only **`childNodes`** property of the [Node] interface returns a
  /// live
  /// [NodeList] of child [Node] of the given element where
  /// the first child node is assigned index `0`. Child nodes include elements,
  /// text and
  /// comments.
  ///
  /// > [!NOTE]
  /// > The [NodeList] being live means that its content is changed each time
  /// > new children are added or removed.
  /// >
  /// > Browsers insert text nodes into a document to represent whitespace in
  /// > the source markup.
  /// > Therefore a node obtained, for example, using `Node.childNodes[0]`
  /// > may refer to a whitespace text node rather than the actual element the
  /// > author intended to get.
  /// >
  /// > See
  /// > [Whitespace in the DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace)
  /// > for more information.
  ///
  /// The items in the collection of nodes are objects, not strings. To get data
  /// from node
  /// objects, use their properties. For example, to get the name of the first
  /// childNode, you can use `elementNodeReference.childNodes[0].nodeName`.
  ///
  /// The [document] object itself has two children: the Doctype declaration and
  /// the
  /// root element, typically referred to as `documentElement`. In HTML
  /// documents the latter is the `html` element.
  ///
  /// It is important to keep in mind that `childNodes` includes _all_ child
  /// nodes,
  /// including non-element nodes like text and comment.
  /// To get a collection containing only elements, use [Element.children]
  /// instead.
  external NodeList get childNodes;

  /// The read-only **`firstChild`** property of the [Node] interface
  /// returns the node's first child in the tree,
  /// or `null` if the node has no children.
  ///
  /// If the node is a [Document],
  /// this property returns the first node in the list of its direct children.
  ///
  /// > [!NOTE]
  /// > This property returns any type of node that is the first child of this
  /// > one.
  /// > It may be a [Text] or a [Comment] node.
  /// > If you want to get the first [Element] that is a child of another
  /// > element,
  /// > consider using [Element.firstElementChild].
  external Node? get firstChild;

  /// The read-only **`lastChild`** property of the [Node] interface
  /// returns the last child of the node, or `null` if there are no child nodes.
  ///
  /// > [!NOTE]
  /// > This property returns any type of node that is the last child of this
  /// > one.
  /// > It may be a [Text] or a [Comment] node.
  /// > If you want to get the last [Element] that is a child of another
  /// > element,
  /// > consider using [Element.lastElementChild].
  external Node? get lastChild;

  /// The read-only **`previousSibling`** property of the [Node] interface
  /// returns the node immediately preceding the specified one in its parent's
  /// [Node.childNodes] list,
  /// or `null` if the specified node is the first in that list.
  ///
  /// > [!NOTE]
  /// > Browsers insert text nodes into a document to represent whitespace in
  /// > the source markup.
  /// > Therefore a node obtained, for example, using
  /// > [`Node.firstChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild)
  /// > or `Node.previousSibling`
  /// > may refer to a whitespace text node rather than the actual element the
  /// > author intended to get.
  /// >
  /// > See
  /// > [Whitespace in the DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace)
  /// > for more information.
  /// >
  /// > You can use
  /// > [`previousElementSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Element/previousElementSibling)
  /// > to get the previous element node (skipping text nodes and any other
  /// > non-element nodes).
  /// >
  /// > To navigate the opposite way through the child nodes list use
  /// > [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling).
  external Node? get previousSibling;

  /// The read-only **`nextSibling`** property of the [Node] interface
  /// returns the node immediately following the specified one in their
  /// parent's [Node.childNodes], or returns `null`
  /// if the specified node is the last child in the parent element.
  ///
  /// > [!NOTE]
  /// > Browsers insert [Text] nodes into a document to represent whitespace in
  /// > the source markup.
  /// > Therefore a node obtained, for example, using
  /// > [`Node.firstChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild)
  /// > or
  /// > [`Node.previousSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling)
  /// > may refer to a whitespace text node rather than the actual element the
  /// > author
  /// > intended to get.
  /// >
  /// > The article
  /// > [Whitespace in the DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace)
  /// > contains more information about this behavior.
  /// >
  /// > You can use [Element.nextElementSibling] to obtain the next element
  /// > skipping any whitespace nodes, other between-element text, or comments.
  /// >
  /// > To navigate the opposite way through the child nodes list use
  /// > [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling).
  external Node? get nextSibling;

  /// The **`nodeValue`** property of the [Node] interface returns or sets the
  /// value of the current node.
  external String? get nodeValue;
  external set nodeValue(String? value);

  /// The **`textContent`** property of the [Node]
  /// interface represents the text content of the node and its descendants.
  ///
  /// > **Note:** `textContent` and [HTMLElement.innerText] are easily confused,
  /// > but the two properties are
  /// > [different in important ways](#differences_from_innertext).
  external String? get textContent;
  external set textContent(String? value);
}
extension type GetRootNodeOptions._(JSObject _) implements JSObject {
  external factory GetRootNodeOptions({bool composed});

  external bool get composed;
  external set composed(bool value);
}
@JS()
external Document get document;

/// The **`Document`** interface represents any web page loaded in the browser
/// and serves as an entry point into the web page's content, which is the
/// [DOM tree](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Using_the_Document_Object_Model#what_is_a_dom_tree).
///
/// The DOM tree includes elements such as `body` and `table`, among
/// [many others](https://developer.mozilla.org/en-US/docs/Web/HTML/Element). It
/// provides functionality globally to the document, like how to obtain the
/// page's URL and create new elements in the document.
///
/// The `Document` interface describes the common properties and methods for any
/// kind of document. Depending on the document's type (e.g.
/// [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML),
/// [XML](https://developer.mozilla.org/en-US/docs/Web/XML), SVG, …), a larger
/// API is available: HTML documents, served with the `"text/html"` content
/// type, also implement the [HTMLDocument] interface, whereas XML and SVG
/// documents implement the [XMLDocument] interface.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Document).
extension type Document._(JSObject _) implements Node, JSObject {
  external factory Document();

  /// The **`parseHTMLUnsafe()`** static method of the [Document] object is used
  /// to parse a string of HTML, which may contain
  /// [declarative shadow roots](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#declarative_shadow_dom),
  /// in order to create a new [Document] instance.
  ///
  /// The suffix "Unsafe" in the method name indicates that, while `<script>`
  /// elements are not evaluated during parsing, the method does not sanitize
  /// other potentially unsafe XSS-relevant input.
  ///
  /// The resulting `Document` will have a
  /// [content type](https://developer.mozilla.org/en-US/docs/Web/API/Document/contentType)
  /// of "text/html", a
  /// [character set](https://developer.mozilla.org/en-US/docs/Web/API/Document/characterSet)
  /// of UTF-8, and a URL of "about:blank"
  external static Document parseHTMLUnsafe(JSAny html);

  /// The **`getElementsByTagName`** method of
  /// [Document] interface returns an
  /// [HTMLCollection] of elements with the given tag name.
  ///
  /// The complete
  /// document is searched, including the root node. The returned
  /// `HTMLCollection`
  /// is live, meaning that it updates itself automatically to stay in sync with
  /// the DOM tree
  /// without having to call `document.getElementsByTagName()` again.
  external HTMLCollection getElementsByTagName(String qualifiedName);

  /// Returns a list of elements with the given tag name belonging to the given
  /// namespace.
  /// The complete document is searched, including the root node.
  external HTMLCollection getElementsByTagNameNS(
    String? namespace,
    String localName,
  );

  /// The **`getElementsByClassName`** method of
  /// [Document] interface returns an array-like object
  /// of all child elements which have all of the given class name(s).
  ///
  /// When called on
  /// the [document] object, the complete document is searched, including the
  /// root node. You may also call [Element.getElementsByClassName] on any
  /// element; it will return only elements which are descendants of the
  /// specified root element with the given class name(s).
  ///
  /// > [!WARNING]
  /// > This is a live [HTMLCollection]. Changes in the DOM will
  /// > reflect in the array as the changes occur. If an element selected by
  /// > this array no
  /// > longer qualifies for the selector, it will automatically be removed. Be
  /// > aware of this
  /// > for iteration purposes.
  external HTMLCollection getElementsByClassName(String classNames);

  /// In an [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) document,
  /// the **`document.createElement()`** method creates the HTML element
  /// specified by `localName`, or an [HTMLUnknownElement] if `localName` isn't
  /// recognized.
  external Element createElement(
    String localName, [
    JSAny options,
  ]);

  /// Creates an element with the specified namespace URI and qualified name.
  ///
  /// To create an element without specifying a namespace URI, use the
  /// [Document.createElement] method.
  external Element createElementNS(
    String? namespace,
    String qualifiedName, [
    JSAny options,
  ]);

  /// Creates a new empty [DocumentFragment] into which
  /// DOM nodes can be added to build an offscreen DOM tree.
  external DocumentFragment createDocumentFragment();

  /// Creates a new [Text] node. This method can be used to escape HTML
  /// characters.
  external Text createTextNode(String data);

  /// **`createCDATASection()`** creates a new CDATA section node,
  /// and returns it.
  external CDATASection createCDATASection(String data);

  /// **`createComment()`** creates a new comment node, and returns
  /// it.
  external Comment createComment(String data);

  /// `createProcessingInstruction()` generates a new
  /// [processing instruction](https://developer.mozilla.org/en-US/docs/Web/API/ProcessingInstruction)
  /// node and returns it.
  ///
  /// The new node usually will be inserted into an XML document in order to
  /// accomplish anything with it, such as with [node.insertBefore].
  external ProcessingInstruction createProcessingInstruction(
    String target,
    String data,
  );

  /// The [Document] object's **`importNode()`** method creates a copy of a
  /// [Node] or [DocumentFragment] from another document, to be
  /// inserted into the current document later.
  ///
  /// The imported node is not yet included in the document tree. To include it,
  /// you need to
  /// call an insertion method such as [Node.appendChild] or
  /// [Node.insertBefore] with a node that _is_
  /// currently in the document tree.
  ///
  /// Unlike [document.adoptNode], the original node is not removed from its
  /// original document. The imported node is a clone of the original.
  external Node importNode(
    Node node, [
    bool subtree,
  ]);

  /// **`Document.adoptNode()`** transfers a  from another [Document] into the
  /// method's document.
  /// The adopted node and its subtree are removed from their original document
  /// (if any), and their [Node.ownerDocument] is changed to the current
  /// document.
  /// The node can then be inserted into the current document.
  external Node adoptNode(Node node);

  /// The **`Document.createAttribute()`** method creates a new
  /// attribute node, and returns it. The object created is a node implementing
  /// the
  /// [Attr] interface. The DOM does not enforce what sort of attributes can be
  /// added to a particular element in this manner.
  ///
  /// > [!NOTE]
  /// > The string given in parameter is converted to lowercase.
  external Attr createAttribute(String localName);

  /// The **`Document.createAttributeNS()`** method creates a new attribute node
  /// with the specified namespace URI and qualified name, and returns it.
  /// The object created is a node implementing the
  /// [Attr] interface. The DOM does not enforce what sort of attributes can be
  /// added to a particular element in this manner.
  external Attr createAttributeNS(
    String? namespace,
    String qualifiedName,
  );

  /// > [!WARNING]
  /// > Many methods used with `createEvent`, such as `initCustomEvent`, are
  /// > deprecated.
  /// > Use
  /// > [event constructors](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent)
  /// > instead.
  ///
  /// Creates an [event](https://developer.mozilla.org/en-US/docs/Web/API/Event)
  /// of the type specified. The
  /// returned object should be first initialized and can then be passed to
  /// [EventTarget.dispatchEvent].
  external Event createEvent(String interface);

  /// The **`Document.createRange()`** method returns a new
  /// [Range] object.
  external Range createRange();

  /// The **`Document.createNodeIterator()`** method returns a new
  /// [`NodeIterator`](https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator)
  /// object.
  external NodeIterator createNodeIterator(
    Node root, [
    int whatToShow,
    NodeFilter? filter,
  ]);

  /// The **`Document.createTreeWalker()`** creator method returns a newly
  /// created [TreeWalker] object.
  external TreeWalker createTreeWalker(
    Node root, [
    int whatToShow,
    NodeFilter? filter,
  ]);

  /// The **`startViewTransition()`** method of the [Document] interface starts
  /// a new same-document (SPA)
  /// [view transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API)
  /// and returns a [ViewTransition] object to represent it.
  ///
  /// When `startViewTransition()` is invoked, a sequence of steps is followed
  /// as explained in
  /// [The view transition process](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#the_view_transition_process).
  external ViewTransition startViewTransition([JSObject callbackOptions]);

  /// The **`elementFromPoint()`**
  /// method, available on the [Document] object, returns the topmost [Element]
  /// at the specified coordinates
  /// (relative to the viewport).
  ///
  /// If the element at the specified point belongs to another document (for
  /// example, the
  /// document of an `iframe`), that document's parent element is returned
  /// (the `<iframe>` itself). If the element at the given point is anonymous
  /// or XBL generated content, such as a textbox's scroll bars, then the first
  /// non-anonymous
  /// ancestor element (for example, the textbox) is returned.
  ///
  /// Elements with  set to `none` will be ignored,
  /// and the element below it will be returned.
  ///
  /// If the method is run on another document (like an `<iframe>`'s
  /// subdocument), the coordinates are relative to the document where the
  /// method is being
  /// called.
  ///
  /// If the specified point is outside the visible bounds of the document or
  /// either
  /// coordinate is negative, the result is `null`.
  ///
  /// If you need to find the specific position inside the element, use
  /// [Document.caretPositionFromPoint].
  external Element? elementFromPoint(
    num x,
    num y,
  );

  /// The **`elementsFromPoint()`** method
  /// of the [Document] interface returns an array of all elements
  /// at the specified coordinates (relative to the viewport).
  /// The elements are ordered from the topmost to the bottommost box of the
  /// viewport.
  ///
  /// It operates in a similar way to the [Document.elementFromPoint] method.
  external JSArray<Element> elementsFromPoint(
    num x,
    num y,
  );

  /// The **`caretPositionFromPoint()`** method of the [Document] interface
  /// returns a [CaretPosition] object, containing the DOM node, along with the
  /// caret and caret's character offset within that node.
  external CaretPosition? caretPositionFromPoint(
    num x,
    num y, [
    CaretPositionFromPointOptions options,
  ]);

  /// The [Document] method
  /// **`exitFullscreen()`** requests that the element on this
  /// document which is currently being presented in fullscreen mode be taken
  /// out of
  /// fullscreen mode, restoring the previous state of the screen. This usually
  /// reverses the effects of a previous call to [Element.requestFullscreen].
  external JSPromise<JSAny?> exitFullscreen();
  external JSObject operator [](String name);

  /// The **`getElementsByName()`** method
  /// of the [Document] object returns a [NodeList] Collection of
  /// elements with a given `name` attribute in the document.
  external NodeList getElementsByName(String elementName);

  /// The **`Document.open()`** method opens a document for
  /// [Document.write].
  ///
  /// This does come with some side effects. For example:
  ///
  /// - All event listeners currently registered on the document, nodes inside
  ///   the document,
  /// or the document's window are removed.
  /// - All existing nodes are removed from the document.
  external JSObject? open([
    String unused1OrUrl,
    String nameOrUnused2,
    String features,
  ]);

  /// The **`Document.close()`** method finishes writing to a
  /// document, opened with [Document.open].
  external void close();

  /// > [!WARNING]
  /// > Use of the `document.write()` method is strongly discouraged.
  /// >
  /// > As
  /// > [the HTML spec itself warns](<https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#document.write()>):
  /// >
  /// > > This method has very idiosyncratic behavior. In some cases, this
  /// > method can affect the state of the
  /// > [HTML parser](https://html.spec.whatwg.org/multipage/parsing.html#html-parser)
  /// > while the parser is running, resulting in a DOM that does not correspond
  /// > to the source of the document (e.g. if the string written is the string
  /// > "`<plaintext>`" or "`<!--`"). In other cases, the call can clear the
  /// > current page first, as if
  /// > [`document.open()`](https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-document-open)
  /// > had been called. In yet more cases, the method is simply ignored, or
  /// > throws an exception. Users agents are
  /// > [explicitly allowed to avoid executing `script` elements inserted via this method](https://html.spec.whatwg.org/multipage/parsing.html#document-written-scripts-intervention).
  /// > And to make matters even worse, the exact behavior of this method can in
  /// > some cases be dependent on network latency, which can lead to failures
  /// > that are very hard to debug. For all these reasons, use of this method
  /// > is strongly discouraged.
  /// > > Therefore, avoid using `document.write()` — and if possible, update
  /// > any existing code that is still using it.
  ///
  /// The **`document.write()`** method writes a string of text to a document
  /// stream opened by [document.open].
  ///
  /// > [!NOTE]
  /// > Because `document.write()` writes to the document **stream**, calling
  /// > `document.write()` on a closed (loaded) document automatically calls
  /// > `document.open()`,
  /// > [which will clear the document](https://developer.mozilla.org/en-US/docs/Web/API/Document/open#notes).
  external void write([
    JSAny text1,
    JSAny text2,
    JSAny text3,
    JSAny text4,
  ]);

  /// Writes a string of text followed by a newline character to a document.
  external void writeln([
    JSAny text1,
    JSAny text2,
    JSAny text3,
    JSAny text4,
  ]);

  /// The **`hasFocus()`** method of the [Document] interface returns a boolean
  /// value indicating whether the document or any element inside the document
  /// has focus.
  /// This method can be used to determine whether the active element in a
  /// document has focus.
  ///
  /// > [!NOTE]
  /// > When viewing a document, an element with focus is always the
  /// > [active element](https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement)
  /// > in the document, but an active element does not necessarily have focus.
  /// > For example, an active element within a popup window that is not the
  /// > foreground doesn't have focus.
  external bool hasFocus();

  /// The **`execCommand`** method implements multiple different commands. Some
  /// of them provide access to the clipboard, while others are for editing
  /// [form inputs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input),
  /// [`contenteditable`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable)
  /// elements or entire documents (when switched to
  /// [design mode](https://developer.mozilla.org/en-US/docs/Web/API/Document/designMode)).
  ///
  /// To access the clipboard, the newer
  /// [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API)
  /// is recommended over `execCommand()`. However, there is no replacement for
  /// the editing commands: unlike direct DOM manipulation, modifications
  /// performed by `execCommand()` preserve the undo buffer (edit history).
  ///
  /// Most commands affect the document's
  /// [selection](https://developer.mozilla.org/en-US/docs/Web/API/Selection).
  /// For example, some commands (bold, italics, etc.) format the currently
  /// selected text, while others delete the selection, insert new elements
  /// (replacing the selection) or affect an entire line (indenting). Only the
  /// currently active editable element can be modified, but some commands (e.g.
  /// `copy`) can work without an editable element.
  ///
  /// > [!NOTE]
  /// > Modifications performed by `execCommand()` may or may not trigger
  /// > [Element.beforeinput_event] and [Element.input_event] events, depending
  /// > on the browser and configuration. If triggered, the handlers for the
  /// > events will run before `execCommand()` returns. Authors need to be
  /// > careful about such recursive calls, especially if they call
  /// > `execCommand()` in response to these events. From Firefox 82, nested
  /// > `execCommand()` calls will always fail, see
  /// > [bug 1634262](https://bugzil.la/1634262).
  external bool execCommand(
    String commandId, [
    bool showUI,
    String value,
  ]);
  external bool queryCommandIndeterm(String commandId);
  external String queryCommandValue(String commandId);

  /// The **`Document.clear()`** method does nothing, but doesn't raise any
  /// error.
  external void clear();
  external void captureEvents();
  external void releaseEvents();

  /// The **`exitPictureInPicture()`** method of the [Document] interface
  /// requests that a video contained
  /// in this document, which is currently floating, be taken out of
  /// picture-in-picture
  /// mode, restoring the previous state of the screen. This usually reverses
  /// the
  /// effects of a previous call to [HTMLVideoElement.requestPictureInPicture].
  external JSPromise<JSAny?> exitPictureInPicture();

  /// The **`exitPointerLock()`** method of the [Document] interface
  /// asynchronously releases a pointer lock previously requested through
  /// [Element.requestPointerLock].
  ///
  /// > [!NOTE]
  /// > While the **`exitPointerLock()`** method is called on the document, the
  /// > **`requestPointerLock()`** method is called on an element.
  ///
  /// To track the success or failure of the request, it is necessary to listen
  /// for the [Document.pointerlockchange_event] and
  /// [Document.pointerlockerror_event] events.
  external void exitPointerLock();

  /// The **`hasUnpartitionedCookieAccess()`** method of the [Document]
  /// interface returns a `Promise` that resolves with a boolean value
  /// indicating whether the document has access to
  /// [third-party](https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Third-party_cookies),
  /// [unpartitioned](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API#unpartitioned_versus_partitioned_cookies)
  /// cookies.
  ///
  /// This method is part of the
  /// [Storage Access API](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API).
  ///
  /// This method is a new name for [Document.hasStorageAccess].
  external JSPromise<JSBoolean> hasUnpartitionedCookieAccess();

  /// The **`getSelection()`** method of the [Document] interface returns the
  /// [Selection] object associated with this document, representing the range
  /// of text selected by the user, or the current position of the caret.
  external Selection? getSelection();

  /// The **`hasStorageAccess()`** method of the [Document] interface returns a
  /// `Promise` that resolves with a boolean value indicating whether the
  /// document has access to
  /// [third-party](https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Third-party_cookies),
  /// [unpartitioned](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API#unpartitioned_versus_partitioned_cookies)
  /// cookies.
  ///
  /// This method is part of the
  /// [Storage Access API](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API).
  ///
  /// > [!NOTE]
  /// > This method is another name for [Document.hasUnpartitionedCookieAccess].
  /// > There are no current plans to remove this method in favor of
  /// > [Document.hasUnpartitionedCookieAccess].
  external JSPromise<JSBoolean> hasStorageAccess();

  /// The **`requestStorageAccess()`** method of the [Document] interface allows
  /// content loaded in a third-party context (i.e., embedded in an `iframe`) to
  /// request access to
  /// [third-party cookies](https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Third-party_cookies)
  /// and
  /// [unpartitioned state](https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/State_Partitioning#state_partitioning).
  /// This is relevant to user agents that, by default, block access to
  /// third-party,
  /// [unpartitioned](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API#unpartitioned_versus_partitioned_cookies)
  /// cookies to improve privacy (e.g., to prevent tracking), and is part of the
  /// [Storage Access API](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API).
  ///
  /// To check whether permission to access third-party cookies has already been
  /// granted, you can call [Permissions.query], specifying the feature name
  /// `"storage-access"`.
  ///
  /// > [!NOTE]
  /// > Usage of this feature may be blocked by a
  /// > [Permissions Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy)
  /// > set on your server. In addition, the document must pass additional
  /// > browser-specific checks such as allowlists, blocklists, on-device
  /// > classification, user settings,
  /// > anti-[clickjacking](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/Clickjacking)
  /// > heuristics, or prompting the user for explicit permission.
  external JSPromise<JSAny?> requestStorageAccess();

  /// The **`getElementById()`** method of the [Document] interface returns an
  /// [Element] object representing the element whose [Element.id] property
  /// matches the specified string. Since element IDs are required to be unique
  /// if specified, they're a useful way to get access to a specific element
  /// quickly.
  ///
  /// If you need to get access to an element which doesn't have an ID, you can
  /// use [Document.querySelector] to find the element using any .
  ///
  /// > [!NOTE]
  /// > IDs should be unique inside a document. If two or more elements in a
  /// > document have the same ID, this method returns the first element found.
  external Element? getElementById(String elementId);

  /// The `getAnimations()` method of the [Document] interface
  /// returns an array of all [Animation] objects currently in effect whose
  /// target elements are descendants of the document. This array includes
  /// [CSS Animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations),
  /// [CSS Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_transitions),
  /// and
  /// [Web Animations](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).
  external JSArray<Animation> getAnimations();

  /// The **`Document.prepend()`** method
  /// inserts a set of [Node] objects or strings before
  /// the first child of the document. Strings
  /// are inserted as equivalent [Text] nodes.
  ///
  /// This method prepends a child to a `Document`. To prepend to an arbitrary
  /// element in the tree, see [Element.prepend].
  external void prepend([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`Document.append()`** method
  /// inserts a set of [Node] objects or strings after
  /// the last child of the document. Strings
  /// are inserted as equivalent [Text] nodes.
  ///
  /// This method appends a child to a `Document`. To append to an arbitrary
  /// element in the tree, see [Element.append].
  external void append([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`Document.replaceChildren()`** method replaces the
  /// existing children of a `Document` with a specified new set of children.
  external void replaceChildren([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The [Document] method **`querySelector()`**
  /// returns the first [Element] within the document that matches the specified
  /// [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors),
  /// or group of CSS selectors. If no matches are found, `null` is returned.
  ///
  /// The matching is done using depth-first pre-order traversal of the
  /// document's nodes starting with the first element in the document's markup
  /// and iterating through sequential nodes by order of the number of child
  /// nodes.
  ///
  /// If the specified selector matches an ID that is incorrectly used more than
  /// once in the
  /// document, the first element with that ID is returned.
  ///
  /// [CSS pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements)
  /// will never return
  /// any elements, as specified in the
  /// [Selectors API](https://www.w3.org/TR/selectors-api/#grammar).
  external Element? querySelector(String selectors);

  /// The [Document] method **`querySelectorAll()`**
  /// returns a static (not live) [NodeList] representing a list of the
  /// document's elements that match the specified group of selectors.
  external NodeList querySelectorAll(String selectors);

  /// This method compiles an [XPathExpression] which can then be used for
  /// (repeated) evaluations.
  ///
  /// You must call this method on the same document that you run the expression
  /// against.
  external XPathExpression createExpression(
    String expression, [
    XPathNSResolver? resolver,
  ]);

  /// The **`createNSResolver()`** method of the [Document] interface used to
  /// create a custom `XPathNSResolver` object. It now returns the input as-is
  /// and is only kept for compatibility reasons.
  external Node createNSResolver(Node nodeResolver);

  /// The **`evaluate()`** method of the [Document] interface selects elements
  /// based on the
  /// [XPath](https://developer.mozilla.org/en-US/docs/Web/XML/XPath)
  /// expression given in parameters.
  ///
  /// XPath expressions can be evaluated on both HTML and XML documents.
  external XPathResult evaluate(
    String expression,
    Node contextNode, [
    XPathNSResolver? resolver,
    int type,
    XPathResult? result,
  ]);

  /// The **`Document.implementation`** property returns a
  /// [DOMImplementation] object associated with the current document.
  external DOMImplementation get implementation;

  /// The **`URL`** read-only property of the [Document]
  /// interface returns the document location as a string.
  external String get URL;

  /// The **`documentURI`** read-only property of the
  /// [Document] interface returns the document location as a string.
  external String get documentURI;

  /// The **`Document.compatMode`** read-only property indicates
  /// whether the document is rendered in
  /// [Quirks mode](https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode)
  /// or
  /// Standards mode.
  external String get compatMode;

  /// The **`Document.characterSet`**
  /// read-only property returns the
  /// [character encoding](https://developer.mozilla.org/en-US/docs/Glossary/Character_encoding)
  /// of the
  /// document that it's currently rendered with.
  ///
  /// > [!NOTE]
  /// > A "character set" and a "character encoding" are related, but different.
  /// > Despite the
  /// > name of this property, it returns the _encoding_.
  external String get characterSet;

  /// The **`Document.contentType`** read-only property returns the
  /// MIME type that the document is being rendered as. This may come from HTTP
  /// headers or
  /// other sources of MIME information, and might be affected by automatic type
  /// conversions
  /// performed by either the browser or extensions.
  ///
  /// > [!NOTE]
  /// > This property is unaffected by `meta`
  /// > elements.
  external String get contentType;

  /// The **`doctype`** read-only property of the [Document] interface is a
  /// [DocumentType] object representing the  associated with the current
  /// document.
  external DocumentType? get doctype;

  /// The **`documentElement`** read-only property of the [Document] interface
  /// returns the
  /// [Element] that is the root element of the [document] (for
  /// example, the `html` element for HTML documents).
  external Element? get documentElement;

  /// **`Document.rootElement`** returns the [Element]
  /// that is the root element of the [document] if it is an
  /// element, otherwise `null`. It is deprecated in favor of
  /// [Document.documentElement], which returns the root element for all
  /// documents.
  external SVGSVGElement? get rootElement;

  /// The **`scrollingElement`** read-only property of the
  /// [Document] interface returns a reference to the [Element] that
  /// scrolls the document. In standards mode, this is the root element of the
  /// document, [document.documentElement].
  ///
  /// When in quirks mode, the `scrollingElement` attribute returns the HTML
  /// `body` element if it exists and is _not_
  /// [potentially scrollable](https://drafts.csswg.org/cssom-view/#potentially-scrollable),
  /// otherwise it returns `null`. This may look surprising but is true
  /// according to both the specification and browsers.
  external Element? get scrollingElement;

  /// The read-only **`fullscreenEnabled`**
  /// property on the [Document] interface indicates whether or not fullscreen
  /// mode is available.
  ///
  /// fullscreen mode is available only for a page that has no
  /// windowed plug-ins in any of its documents, and if all `iframe` elements
  /// which contain the document have their
  /// [`allowfullscreen`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#allowfullscreen)
  /// attribute set.
  ///
  /// Although this property is read-only, it will not throw if it is modified
  /// (even in
  /// strict mode); the setter is a no-operation and it will be ignored.
  external bool get fullscreenEnabled;

  /// The obsolete [Document] interface's **`fullscreen`** read-only property
  /// reports whether or not the document is currently displaying content in
  /// fullscreen mode.
  ///
  /// Although this property is read-only, it will not throw if it is modified
  /// (even in strict mode); the setter is a no-operation and it will be
  /// ignored.
  ///
  /// > [!NOTE]
  /// > Since this property is deprecated, you can determine if fullscreen mode
  /// > is active on the document by checking to see if
  /// > [Document.fullscreenElement] is not `null`.
  external bool get fullscreen;
  external EventHandler get onfullscreenchange;
  external set onfullscreenchange(EventHandler value);
  external EventHandler get onfullscreenerror;
  external set onfullscreenerror(EventHandler value);

  /// The **`Document.location`** read-only property returns a
  /// [Location] object, which contains information about the URL of the
  /// document
  /// and provides methods for changing that URL and loading another URL.
  ///
  /// Though `Document.location` is a _read-only_ `Location`
  /// object, you can also assign a string to it. This means that you can
  /// work with document.location as if it were a string in most cases:
  /// `document.location = 'http://www.example.com'` is a synonym of
  /// `document.location.href = 'http://www.example.com'`. If you assign another
  /// string to it, browser will load the website you assigned.
  ///
  /// To retrieve just the URL as a string, the read-only [document.URL]
  /// property can also be used.
  ///
  /// If the current document is not in a browsing context, the returned value
  /// is
  /// `null`.
  external Location? get location;

  /// The **`domain`** property of the [Document]
  /// interface gets/sets the domain portion of the  of the current
  /// document, as used by the
  /// [same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy).
  external String get domain;
  external set domain(String value);

  /// The **`Document.referrer`** property returns the
  /// [URI](https://www.w3.org/Addressing/#background) of the page that linked
  /// to
  /// this page.
  external String get referrer;

  /// The [Document] property `cookie` lets you read and write
  /// [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)
  /// associated with the document.
  /// It serves as a getter and setter for the actual values of the cookies.
  external String get cookie;
  external set cookie(String value);

  /// The **`lastModified`** property of the [Document]
  /// interface returns a string containing the date and local time on which the
  /// current document
  /// was last modified.
  external String get lastModified;

  /// The **`Document.readyState`** property describes the loading state of the
  /// [document].
  /// When the value of this property changes, a
  /// [Document.readystatechange_event] event fires on the [document] object.
  external DocumentReadyState get readyState;

  /// The **`document.title`** property gets or sets the current title of the
  /// document.
  /// When present, it defaults to the value of the
  /// [`<title>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title).
  external String get title;
  external set title(String value);

  /// The **`Document.dir`** property is a string
  /// representing the directionality of the text of the document, whether left
  /// to right
  /// (default) or right to left. Possible values are `'rtl'`, right to left,
  /// and
  /// `'ltr'`, left to right.
  external String get dir;
  external set dir(String value);

  /// The **`Document.body`** property represents the
  /// `body` or `frameset` node of the current document, or
  /// `null` if no such element exists.
  external HTMLElement? get body;
  external set body(HTMLElement? value);

  /// The **`head`** read-only property of
  /// the [Document] interface returns the `head` element of
  /// the current document.
  external HTMLHeadElement? get head;

  /// The **`images`** read-only property of the [Document] interface returns a
  /// [collection](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection)
  /// of the
  /// [images](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement)
  /// in the current HTML document.
  external HTMLCollection get images;

  /// The **`embeds`** read-only property of the
  /// [Document] interface returns a list of the embedded
  /// `embed` elements within the current document.
  external HTMLCollection get embeds;

  /// The **`plugins`** read-only property of the
  /// [Document] interface returns an [HTMLCollection] object
  /// containing one or more [HTMLEmbedElement]s representing the
  /// `embed` elements in the current document.
  ///
  /// > [!NOTE]
  /// > For a list of installed plugins, use
  /// > [Navigator.plugins](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/plugins)
  /// > instead.
  external HTMLCollection get plugins;

  /// The **`links`** read-only property of the [Document] interface returns a
  /// collection of all `area` elements and `a` elements in a document with a
  /// value for the
  /// [href](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#href)
  /// attribute.
  external HTMLCollection get links;

  /// The **`forms`** read-only property of
  /// the [Document] interface returns an [HTMLCollection] listing
  /// all the `form` elements contained in the document.
  ///
  /// > [!NOTE]
  /// > Similarly, you can access a list of a form's component user
  /// > input elements using the [HTMLFormElement.elements] property.
  external HTMLCollection get forms;

  /// The **`scripts`** property of the [Document]
  /// interface returns a list of the `script`
  /// elements in the document. The returned object is an
  /// [HTMLCollection].
  external HTMLCollection get scripts;

  /// The **`Document.currentScript`** property returns the `script` element
  /// whose script is currently being processed and [isn't a JavaScript
  /// module](https://github.com/whatwg/html/issues/997). (For modules use
  /// [`import.meta`](/en-US/docs/Web/JavaScript/Reference/Operators/import.meta)
  /// instead.)
  ///
  /// It's important to note that this will not reference the `script`
  /// element if the code in the script is being called as a callback or event
  /// handler; it
  /// will only reference the element while it's initially being processed.
  external HTMLOrSVGScriptElement? get currentScript;

  /// In browsers, **`document.defaultView`** returns the
  /// [Window] object associated with , or `null` if none is available.
  ///
  /// This property is read-only.
  external Window? get defaultView;

  /// **`document.designMode`** controls whether the entire document
  /// is editable. Valid values are `"on"` and `"off"`. According to the
  /// specification, this property is meant to default to `"off"`. Firefox
  /// follows
  /// this standard. The earlier versions of Chrome and IE default to
  /// `"inherit"`.
  /// Starting in Chrome 43, the default is `"off"` and `"inherit"` is
  /// no longer supported. In IE6-10, the value is capitalized.
  external String get designMode;
  external set designMode(String value);

  /// The **`Document.hidden`** read-only property returns a Boolean
  /// value indicating if the page is considered hidden or not.
  ///
  /// The [Document.visibilityState] property provides an alternative way to
  /// determine whether the page is hidden.
  external bool get hidden;

  /// The **`Document.visibilityState`**
  /// read-only property returns the visibility of the document. It can be used
  /// to check whether the document is in the background or in a minimized
  /// window, or is otherwise not visible to the user.
  ///
  /// When the value of this property changes, the
  /// [Document.visibilitychange_event] event is sent to the [Document].
  ///
  /// The [Document.hidden] property provides an alternative way to determine
  /// whether the page is hidden.
  external DocumentVisibilityState get visibilityState;
  external EventHandler get onreadystatechange;
  external set onreadystatechange(EventHandler value);
  external EventHandler get onvisibilitychange;
  external set onvisibilitychange(EventHandler value);

  /// **`fgColor`** gets/sets the foreground color, or text color, of
  /// the current document.
  external String get fgColor;
  external set fgColor(String value);

  /// The **`Document.linkColor`** property gets/sets the color of
  /// links within the document.
  ///
  /// This property is deprecated. As an alternative, you can set the CSS
  /// `color` property on either HTML anchor links (`a`) or on
  /// pseudo-classes. Another alternative is
  /// `document.body.link`, although this is [deprecated in HTML
  /// 4.01](https://www.w3.org/TR/html401/struct/global.html#adef-link).
  external String get linkColor;
  external set linkColor(String value);

  /// The **`Document.vlinkColor`** property gets/sets the color of
  /// links that the user has visited in the document.
  external String get vlinkColor;
  external set vlinkColor(String value);

  /// Returns or sets the color of an active link in the document body. A link
  /// is active
  /// during the time between `mousedown` and `mouseup` events.
  external String get alinkColor;
  external set alinkColor(String value);

  /// The deprecated `bgColor` property gets or sets the background color of the
  /// current document.
  external String get bgColor;
  external set bgColor(String value);

  /// The **`anchors`** read-only property of the
  /// [Document] interface returns a list of all of the anchors in the document.
  external HTMLCollection get anchors;

  /// The **`applets`** property of the [Document] returns an empty
  /// [HTMLCollection]. This property is kept only for compatibility reasons; in
  /// older versions of browsers, it returned a list of the applets within a
  /// document.
  ///
  /// > [!NOTE]
  /// > Support for the `<applet>` element has been removed by all browsers.
  /// > Therefore, calling `document.applets` always
  /// > returns an empty collection.
  external HTMLCollection get applets;

  /// The [Document] interface's read-only **`all`** property returns an
  /// [HTMLAllCollection] rooted at the document node.
  ///
  /// Rather than using `document.all` to return an [HTMLAllCollection] of all
  /// the document's elements in document order, you can use
  /// [Document.querySelectorAll] to return a [NodeList] of all the document's
  /// elements in document order:
  ///
  /// ```js
  /// const allElements = document.querySelectorAll("*");
  /// ```
  external HTMLAllCollection get all;

  /// The read-only
  /// **`pictureInPictureEnabled`** property of the
  /// [Document] interface indicates whether or not picture-in-picture mode is
  /// available.
  ///
  /// Picture-in-Picture mode is available by default unless specified
  /// otherwise by a
  /// [Permissions-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/picture-in-picture).
  ///
  /// Although this property is read-only, it will not throw if it is modified
  /// (even in
  /// strict mode); the setter is a no-operation and will be ignored.
  external bool get pictureInPictureEnabled;
  external EventHandler get onpointerlockchange;
  external set onpointerlockchange(EventHandler value);
  external EventHandler get onpointerlockerror;
  external set onpointerlockerror(EventHandler value);

  /// The **`fragmentDirective`** read-only property of the [Document] interface
  /// returns the [FragmentDirective] for the current document.
  external FragmentDirective get fragmentDirective;

  /// The `timeline` readonly property of the [Document] interface represents
  /// the default timeline of the current document. This timeline is a special
  /// instance of [DocumentTimeline].
  ///
  /// This timeline is unique to each `document` and persists for the lifetime
  /// of the `document` including calls to [Document.open].
  ///
  /// This timeline expresses the time in milliseconds since
  /// [Performance.timeOrigin].
  /// Prior to the time origin, the timeline is inactive, and its
  /// [AnimationTimeline.currentTime] is `null`.
  ///
  /// > [!NOTE]
  /// > A document timeline that is associated with a non-active document (a
  /// > [Document] not associated with a [Window], `iframe`, or `frame`) is also
  /// > considered to be inactive.
  external DocumentTimeline get timeline;

  /// The **`fonts`** property of the [Document] interface returns the
  /// [FontFaceSet] interface of the document.
  ///
  /// This feature is part of the
  /// [CSS Font Loading API](https://developer.mozilla.org/en-US/docs/Web/API/CSS_Font_Loading_API).
  external FontFaceSet get fonts;

  /// The **`styleSheets`** read-only property of the [Document] interface
  /// returns a [StyleSheetList] of [CSSStyleSheet] objects, for stylesheets
  /// explicitly linked into or embedded in a document.
  external StyleSheetList get styleSheets;

  /// The **`adoptedStyleSheets`** property of the [Document] interface is used
  /// for setting an array of constructed stylesheets to be used by the
  /// document.
  ///
  /// > [!NOTE]
  /// > A constructed stylesheet is a stylesheet created programmatically using
  /// > the [`CSSStyleSheet()`
  /// > constructor](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet)
  /// > (as compared to one created by a user-agent when importing a stylesheet
  /// > from a script, imported using `style` and , or linked to via `link`).
  ///
  /// The same constructed stylesheets can also be shared with one or more
  /// [ShadowRoot] instances using the
  /// [`ShadowRoot.adoptedStyleSheets`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/adoptedStyleSheets)
  /// property.
  /// Changing an adopted stylesheet will affect all the objects that adopt it.
  ///
  /// Stylesheets in the property are evaluated along with the document's other
  /// stylesheets using the
  /// [CSS cascade algorithm](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Cascade).
  /// Where the resolution of rules considers stylesheet order,
  /// `adoptedStyleSheets` are assumed to be ordered after those in
  /// [`Document.styleSheets`](https://developer.mozilla.org/en-US/docs/Web/API/Document/styleSheets).
  ///
  /// Only stylesheets created using the [`CSSStyleSheet()`
  /// constructor](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet)
  /// within the context of the current [Document] may be adopted.
  external JSArray<CSSStyleSheet> get adoptedStyleSheets;
  external set adoptedStyleSheets(JSArray<CSSStyleSheet> value);

  /// The
  /// **`Document.fullscreenElement`** read-only
  /// property returns the [Element] that is currently being presented in
  /// fullscreen mode in this document, or `null` if fullscreen mode is not
  /// currently in use.
  ///
  /// Although this property is read-only, it will not throw if it is modified
  /// (even in
  /// strict mode); the setter is a no-operation and it will be ignored.
  external Element? get fullscreenElement;

  /// The **`activeElement`** read-only property of the [Document] interface
  /// returns the [Element] within the DOM that is receiving keyboard events
  /// such as [Element.keydown_event] and [Element.keyup_event]. This is usually
  /// analogous to the focused element.
  ///
  /// Which elements are focusable varies depending on the platform and the
  /// browser's current configuration. For example, on Safari, following the
  /// behavior of macOS, elements that aren't text input elements are not
  /// focusable by default, unless the "Full Keyboard Access" setting is enabled
  /// in System Preferences.
  ///
  /// Typically a user can press the <kbd>Tab</kbd> key to move the focus around
  /// the page among focusable elements, and use keyboard gestures such as
  /// <kbd>Space</kbd> or <kbd>Enter</kbd> to simulate clicks on the focused
  /// element.
  ///
  /// > [!NOTE]
  /// > Focus (which element is receiving user input events) is not the same
  /// > thing as selection (the currently highlighted part of the document). You
  /// > can get the current selection using [window.getSelection].
  external Element? get activeElement;

  /// The read-only **`pictureInPictureElement`** property of the [Document]
  /// interface returns the [Element] that is currently being
  /// presented in picture-in-picture mode in this document, or `null` if
  /// picture-in-picture mode is not currently in use.
  ///
  /// Although this property is read-only, it will not throw if it is modified
  /// (even in
  /// strict mode); the setter is a no-operation and will be ignored.
  external Element? get pictureInPictureElement;

  /// The **`pointerLockElement`** read-only property of the [Document]
  /// interface provides the element set as the target for mouse events while
  /// the pointer is locked.
  /// It is `null` if lock is pending, pointer is unlocked, or the target is in
  /// another document.
  external Element? get pointerLockElement;

  /// The read-only **`children`** property returns a live [HTMLCollection]
  /// which contains all of the child [Element] of the document upon which it
  /// was called.
  ///
  /// For HTML documents, this is usually only the root `<html>` element.
  ///
  /// See [Element.children] for child elements of specific HTML elements within
  /// the document.
  external HTMLCollection get children;

  /// The **`Document.firstElementChild`** read-only property
  /// returns the document's first child [Element], or `null` if there
  /// are no child elements.
  ///
  /// For HTML documents, this is usually the only child, the root `<html>`
  /// element.
  ///
  /// See [Element.firstElementChild] for the first child element of specific
  /// elements within a document.
  external Element? get firstElementChild;

  /// The **`Document.lastElementChild`** read-only property
  /// returns the document's last child [Element], or `null` if there
  /// are no child elements.
  ///
  /// For HTML documents, this is usually the only child, the root `<html>`
  /// element.
  ///
  /// See [Element.lastElementChild] for the last child element of specific
  /// elements within a document.
  external Element? get lastElementChild;

  /// The **`Document.childElementCount`** read-only property
  /// returns the number of child elements of the document.
  ///
  /// To get the number of children of a specific element, see
  /// [Element.childElementCount].
  external int get childElementCount;
  external EventHandler get onabort;
  external set onabort(EventHandler value);
  external EventHandler get onauxclick;
  external set onauxclick(EventHandler value);
  external EventHandler get onbeforeinput;
  external set onbeforeinput(EventHandler value);
  external EventHandler get onbeforetoggle;
  external set onbeforetoggle(EventHandler value);
  external EventHandler get onblur;
  external set onblur(EventHandler value);
  external EventHandler get oncancel;
  external set oncancel(EventHandler value);
  external EventHandler get oncanplay;
  external set oncanplay(EventHandler value);
  external EventHandler get oncanplaythrough;
  external set oncanplaythrough(EventHandler value);
  external EventHandler get onchange;
  external set onchange(EventHandler value);
  external EventHandler get onclick;
  external set onclick(EventHandler value);
  external EventHandler get onclose;
  external set onclose(EventHandler value);
  external EventHandler get oncontextlost;
  external set oncontextlost(EventHandler value);
  external EventHandler get oncontextmenu;
  external set oncontextmenu(EventHandler value);
  external EventHandler get oncontextrestored;
  external set oncontextrestored(EventHandler value);
  external EventHandler get oncopy;
  external set oncopy(EventHandler value);
  external EventHandler get oncuechange;
  external set oncuechange(EventHandler value);
  external EventHandler get oncut;
  external set oncut(EventHandler value);
  external EventHandler get ondblclick;
  external set ondblclick(EventHandler value);
  external EventHandler get ondrag;
  external set ondrag(EventHandler value);
  external EventHandler get ondragend;
  external set ondragend(EventHandler value);
  external EventHandler get ondragenter;
  external set ondragenter(EventHandler value);
  external EventHandler get ondragleave;
  external set ondragleave(EventHandler value);
  external EventHandler get ondragover;
  external set ondragover(EventHandler value);
  external EventHandler get ondragstart;
  external set ondragstart(EventHandler value);
  external EventHandler get ondrop;
  external set ondrop(EventHandler value);
  external EventHandler get ondurationchange;
  external set ondurationchange(EventHandler value);
  external EventHandler get onemptied;
  external set onemptied(EventHandler value);
  external EventHandler get onended;
  external set onended(EventHandler value);
  external OnErrorEventHandler get onerror;
  external set onerror(OnErrorEventHandler value);
  external EventHandler get onfocus;
  external set onfocus(EventHandler value);
  external EventHandler get onformdata;
  external set onformdata(EventHandler value);
  external EventHandler get oninput;
  external set oninput(EventHandler value);
  external EventHandler get oninvalid;
  external set oninvalid(EventHandler value);
  external EventHandler get onkeydown;
  external set onkeydown(EventHandler value);
  external EventHandler get onkeypress;
  external set onkeypress(EventHandler value);
  external EventHandler get onkeyup;
  external set onkeyup(EventHandler value);
  external EventHandler get onload;
  external set onload(EventHandler value);
  external EventHandler get onloadeddata;
  external set onloadeddata(EventHandler value);
  external EventHandler get onloadedmetadata;
  external set onloadedmetadata(EventHandler value);
  external EventHandler get onloadstart;
  external set onloadstart(EventHandler value);
  external EventHandler get onmousedown;
  external set onmousedown(EventHandler value);
  external EventHandler get onmouseenter;
  external set onmouseenter(EventHandler value);
  external EventHandler get onmouseleave;
  external set onmouseleave(EventHandler value);
  external EventHandler get onmousemove;
  external set onmousemove(EventHandler value);
  external EventHandler get onmouseout;
  external set onmouseout(EventHandler value);
  external EventHandler get onmouseover;
  external set onmouseover(EventHandler value);
  external EventHandler get onmouseup;
  external set onmouseup(EventHandler value);
  external EventHandler get onpaste;
  external set onpaste(EventHandler value);
  external EventHandler get onpause;
  external set onpause(EventHandler value);
  external EventHandler get onplay;
  external set onplay(EventHandler value);
  external EventHandler get onplaying;
  external set onplaying(EventHandler value);
  external EventHandler get onprogress;
  external set onprogress(EventHandler value);
  external EventHandler get onratechange;
  external set onratechange(EventHandler value);
  external EventHandler get onreset;
  external set onreset(EventHandler value);
  external EventHandler get onresize;
  external set onresize(EventHandler value);
  external EventHandler get onscroll;
  external set onscroll(EventHandler value);
  external EventHandler get onscrollend;
  external set onscrollend(EventHandler value);
  external EventHandler get onsecuritypolicyviolation;
  external set onsecuritypolicyviolation(EventHandler value);
  external EventHandler get onseeked;
  external set onseeked(EventHandler value);
  external EventHandler get onseeking;
  external set onseeking(EventHandler value);
  external EventHandler get onselect;
  external set onselect(EventHandler value);
  external EventHandler get onslotchange;
  external set onslotchange(EventHandler value);
  external EventHandler get onstalled;
  external set onstalled(EventHandler value);
  external EventHandler get onsubmit;
  external set onsubmit(EventHandler value);
  external EventHandler get onsuspend;
  external set onsuspend(EventHandler value);
  external EventHandler get ontimeupdate;
  external set ontimeupdate(EventHandler value);
  external EventHandler get ontoggle;
  external set ontoggle(EventHandler value);
  external EventHandler get onvolumechange;
  external set onvolumechange(EventHandler value);
  external EventHandler get onwaiting;
  external set onwaiting(EventHandler value);
  external EventHandler get onwheel;
  external set onwheel(EventHandler value);
  external EventHandler get onanimationstart;
  external set onanimationstart(EventHandler value);
  external EventHandler get onanimationiteration;
  external set onanimationiteration(EventHandler value);
  external EventHandler get onanimationend;
  external set onanimationend(EventHandler value);
  external EventHandler get onanimationcancel;
  external set onanimationcancel(EventHandler value);
  external EventHandler get ontransitionrun;
  external set ontransitionrun(EventHandler value);
  external EventHandler get ontransitionstart;
  external set ontransitionstart(EventHandler value);
  external EventHandler get ontransitionend;
  external set ontransitionend(EventHandler value);
  external EventHandler get ontransitioncancel;
  external set ontransitioncancel(EventHandler value);
  external EventHandler get onpointerover;
  external set onpointerover(EventHandler value);
  external EventHandler get onpointerenter;
  external set onpointerenter(EventHandler value);
  external EventHandler get onpointerdown;
  external set onpointerdown(EventHandler value);
  external EventHandler get onpointermove;
  external set onpointermove(EventHandler value);
  external EventHandler get onpointerup;
  external set onpointerup(EventHandler value);
  external EventHandler get onpointercancel;
  external set onpointercancel(EventHandler value);
  external EventHandler get onpointerout;
  external set onpointerout(EventHandler value);
  external EventHandler get onpointerleave;
  external set onpointerleave(EventHandler value);
  external EventHandler get ongotpointercapture;
  external set ongotpointercapture(EventHandler value);
  external EventHandler get onlostpointercapture;
  external set onlostpointercapture(EventHandler value);
  external EventHandler get onselectstart;
  external set onselectstart(EventHandler value);
  external EventHandler get onselectionchange;
  external set onselectionchange(EventHandler value);
  external EventHandler get ontouchstart;
  external set ontouchstart(EventHandler value);
  external EventHandler get ontouchend;
  external set ontouchend(EventHandler value);
  external EventHandler get ontouchmove;
  external set ontouchmove(EventHandler value);
  external EventHandler get ontouchcancel;
  external set ontouchcancel(EventHandler value);
}

/// The **XMLDocument** interface represents an XML document. It inherits from
/// the generic [Document] and does not add any specific methods or properties
/// to it: nevertheless, several algorithms behave differently with the two
/// types of documents.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/XMLDocument).
extension type XMLDocument._(JSObject _) implements Document, JSObject {}
extension type ElementCreationOptions._(JSObject _) implements JSObject {
  external factory ElementCreationOptions({String is_});

  @JS('is')
  external String get is_;
  @JS('is')
  external set is_(String value);
}

/// The **`DOMImplementation`** interface represents an object providing methods
/// which are not dependent on any particular document. Such an object is
/// returned by the [Document.implementation] property.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation).
extension type DOMImplementation._(JSObject _) implements JSObject {
  /// The **`DOMImplementation.createDocumentType()`** method returns
  /// a [DocumentType] object which can either be used with
  /// [DOMImplementation.createDocument] upon document creation or can be put
  /// into the document via methods like [Node.insertBefore] or
  /// [Node.replaceChild].
  external DocumentType createDocumentType(
    String qualifiedName,
    String publicId,
    String systemId,
  );

  /// The **`DOMImplementation.createDocument()`** method creates and
  /// returns an [XMLDocument].
  external XMLDocument createDocument(
    String? namespace,
    String qualifiedName, [
    DocumentType? doctype,
  ]);

  /// The
  /// **`DOMImplementation.createHTMLDocument()`** method creates a
  /// new HTML [Document].
  external Document createHTMLDocument([String title]);

  /// The
  /// **`DOMImplementation.hasFeature()`** method returns a
  /// boolean flag indicating if a given feature is supported. It is
  /// deprecated and modern browsers return `true` in all cases.
  ///
  /// The different implementations fairly diverged in what kind of features
  /// were reported.
  /// The latest version of the spec settled to force this method to always
  /// return
  /// `true`, where the functionality was accurate and in use.
  external bool hasFeature();
}

/// The **`DocumentType`** interface represents a [Node] containing a doctype.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/DocumentType).
extension type DocumentType._(JSObject _) implements Node, JSObject {
  /// The **`DocumentType.before()`** method inserts a set of
  /// [Node] objects or strings in the children list of the
  /// `DocumentType`'s parent, just before the `DocumentType`.
  /// Strings are inserted as equivalent [Text] nodes.
  external void before([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`DocumentType.after()`** method inserts a set of
  /// [Node] objects or strings in the children list of the
  /// `DocumentType`'s parent, just after the `DocumentType`.
  /// Strings are inserted as equivalent [Text] nodes.
  external void after([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`DocumentType.replaceWith()`** method replaces the document type
  /// with a set of given nodes.
  external void replaceWith([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`DocumentType.remove()`** method removes a document's `doctype`.
  external void remove();

  /// The read-only **`name`** property of the [DocumentType] returns the type
  /// of the document.
  ///
  /// For synthetic `DocumentType`, this property reflects the value given in
  /// parameter to [DOMImplementation.createDocumentType].
  ///
  /// For HTML documents, browsers always set it up to `html`, whatever the
  /// actual `doctype` in the source code is.
  external String get name;

  /// The read-only **`publicId`** property of the [DocumentType] returns a
  /// formal identifier of the document.
  ///
  /// For synthetic `DocumentType`, this property reflects the value given in
  /// parameter to [DOMImplementation.createDocumentType].
  external String get publicId;

  /// The read-only **`systemId`** property of the [DocumentType] returns the
  /// URL of the associated DTD.
  ///
  /// For synthetic `DocumentType`, this property reflects the value given in
  /// parameter to [DOMImplementation.createDocumentType].
  external String get systemId;
}

/// The **`DocumentFragment`** interface represents a minimal document object
/// that has no parent.
///
/// It is used as a lightweight version of [Document] that stores a segment of a
/// document structure comprised of nodes just like a standard document. The key
/// difference is due to the fact that the document fragment isn't part of the
/// active document tree structure. Changes made to the fragment don't affect
/// the document.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment).
extension type DocumentFragment._(JSObject _) implements Node, JSObject {
  external factory DocumentFragment();

  /// The **`getElementById()`** method of the [DocumentFragment] returns an
  /// [Element] object representing the element whose [Element.id] property
  /// matches the specified string. Since element IDs are required to be unique
  /// if specified, they're a useful way to get access to a specific element
  /// quickly.
  ///
  /// If you need to get access to an element which doesn't have an ID, you can
  /// use [Document.querySelector] to find the element using any .
  ///
  /// > [!NOTE]
  /// > IDs should be unique inside a document fragment. If two or more elements
  /// > in a document fragment have the same ID, this method returns the first
  /// > element found.
  external Element? getElementById(String elementId);

  /// The **`DocumentFragment.prepend()`** method
  /// inserts a set of [Node] objects or strings before
  /// the first child of the document fragment. Strings
  /// are inserted as equivalent [Text] nodes.
  ///
  /// This method prepends a child to a `DocumentFragment`. To prepend to an
  /// arbitrary element in the tree, see [Element.prepend].
  external void prepend([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`DocumentFragment.append()`** method
  /// inserts a set of [Node] objects or strings after
  /// the last child of the document fragment. Strings
  /// are inserted as equivalent [Text] nodes.
  ///
  /// This method appends a child to a `DocumentFragment`. To append to an
  /// arbitrary element in the tree, see [Element.append].
  external void append([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`DocumentFragment.replaceChildren()`** method replaces the
  /// existing children of a `DocumentFragment` with a specified new set of
  /// children. These
  /// can be string or [Node] objects.
  external void replaceChildren([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`DocumentFragment.querySelector()`** method returns the
  /// first element, or `null` if no matches are found, within the
  /// [DocumentFragment] (using depth-first pre-order traversal of the
  /// document's nodes) that matches the specified group of selectors.
  ///
  /// If the selector matches an ID and this ID is erroneously used several
  /// times in the
  /// document, it returns the first matching element.
  ///
  /// If the selectors specified in parameter are invalid a [DOMException] with
  /// a `SYNTAX_ERR` value is raised.
  external Element? querySelector(String selectors);

  /// The **`DocumentFragment.querySelectorAll()`** method returns a
  /// [NodeList] of elements within the [DocumentFragment] (using
  /// depth-first pre-order traversal of the document's nodes) that matches the
  /// specified
  /// group of selectors.
  ///
  /// If the selectors specified in parameter are invalid a [DOMException] with
  /// a `SYNTAX_ERR` value is raised.
  external NodeList querySelectorAll(String selectors);

  /// The read-only **`children`** property returns a live [HTMLCollection]
  /// which contains all of the child [Element] of the document fragment upon
  /// which it was called.
  external HTMLCollection get children;

  /// The **`DocumentFragment.firstElementChild`** read-only property
  /// returns the document fragment's first child [Element], or `null` if there
  /// are no child elements.
  external Element? get firstElementChild;

  /// The **`DocumentFragment.lastElementChild`** read-only property
  /// returns the document fragment's last child [Element], or `null` if there
  /// are no child elements.
  external Element? get lastElementChild;

  /// The **`DocumentFragment.childElementCount`** read-only property
  /// returns the number of child elements of a `DocumentFragment`.
  ///
  /// To get the number of children of a specific element, see
  /// [Element.childElementCount].
  external int get childElementCount;
}

/// The **`ShadowRoot`** interface of the Shadow DOM API is the root node of a
/// DOM subtree that is rendered separately from a document's main DOM tree.
///
/// You can retrieve a reference to an element's shadow root using its
/// [Element.shadowRoot] property, provided it was created using
/// [Element.attachShadow] with the `mode` option set to `open`.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot).
extension type ShadowRoot._(JSObject _) implements DocumentFragment, JSObject {
  /// The **`setHTMLUnsafe()`** method of the [ShadowRoot] interface is used to
  /// parse a string of HTML into a [DocumentFragment], which then replaces the
  /// element's subtree in the DOM.
  /// The input HTML may include
  /// [declarative shadow roots](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#declarative_shadow_dom).
  ///
  /// The suffix "Unsafe" in the method name indicates that the method does not
  /// sanitize or remove potentially unsafe XSS-relevant input, such as
  /// `<script>` elements, and script or event handler content attributes.
  ///
  /// If the string of HTML defines more than one
  /// [declarative shadow root](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#declarative_shadow_dom)
  /// in a particular shadow host then only the first [ShadowRoot] is created —
  /// subsequent declarations are parsed as `<template>` elements within that
  /// shadow root.
  ///
  /// > [!NOTE]
  /// > This method should be used instead of [ShadowRoot.innerHTML] when a
  /// > string of HTML may contain declarative shadow roots.
  external void setHTMLUnsafe(JSAny html);

  /// The **`getHTML()`** method of the [ShadowRoot] interface is used to
  /// serialize a shadow root's DOM to an HTML string.
  ///
  /// The method provides an options argument that enables the serialization of
  /// child nodes that are shadow roots.
  /// The options can be used to include nested shadow roots that have been set
  /// as [ShadowRoot.serializable], and/or a specified array of [ShadowRoot]
  /// objects, which may be either open or closed.
  ///
  /// Without arguments, child nodes that are shadow roots are not serialized,
  /// and this method behaves in the same way as reading the value of
  /// [Element.innerHTML].
  external String getHTML([GetHTMLOptions options]);

  /// The **`getAnimations()`** method of the [ShadowRoot] interface
  /// returns an array of all [Animation] objects currently in effect whose
  /// target elements are descendants of the shadow tree. This array includes
  /// [CSS Animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations),
  /// [CSS Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_transitions),
  /// and
  /// [Web Animations](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).
  external JSArray<Animation> getAnimations();

  /// The **`mode`** read-only property of the [ShadowRoot] specifies its mode —
  /// either `open` or `closed`.
  /// This defines whether or not the shadow root's internal features are
  /// accessible from JavaScript.
  ///
  /// When the `mode` of a shadow root is `"closed"`, the shadow root's
  /// implementation internals are inaccessible and unchangeable from
  /// JavaScript—in the same way the implementation internals of, for example,
  /// the `video` element are inaccessible and unchangeable from JavaScript.
  ///
  /// The property value is set using the `options.mode` property of the object
  /// passed to [Element.attachShadow], or using the
  /// [`shadowrootmode`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#shadowrootmode)
  /// attribute of the
  /// [`<template>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)
  /// element when a shadow root is created declaratively.
  external ShadowRootMode get mode;

  /// The **`delegatesFocus`** read-only property of the [ShadowRoot] interface
  /// returns `true` if the shadow root delegates focus, and `false` otherwise.
  ///
  /// If `true`, when a non-focusable part of the shadow DOM is clicked, or
  /// `.focus()` is called on the host element, the first focusable part inside
  /// the host's shadow DOM is given focus, and the shadow host is given any
  /// available `:focus` styling.
  ///
  /// Focus is of particular importance for keyboard users (including those
  /// using screen readers). `delegatesFocus` default behavior is to focus the
  /// first focusable element — which may be undesirable if that element is not
  /// meant to be part of the tabbing order (for example, an element with
  /// `tabindex="-1"`), or if a more 'important' focusable element should
  /// receive initial focus (for instance, the first text field rather than the
  /// 'close' button which precedes it). In such cases, the `autofocus`
  /// attribute can be specified on the element which should receive initial
  /// focus. Use the `autofocus` attribute with caution as it can introduce
  /// accessibility issues, such as bypassing important content which may go
  /// unnoticed due to focus being set to an element later in the DOM order.
  ///
  /// The property value is originally set using the `delegatesFocus` property
  /// of the object passed to [Element.attachShadow], or using the
  /// [`shadowrootdelegatesfocus`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#shadowrootclonable)
  /// attribute of the
  /// [`<template>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)
  /// element when a shadow root is created declaratively.
  external bool get delegatesFocus;

  /// The read-only **`slotAssignment`** property of the [ShadowRoot] interface
  /// returns the _slot assignment mode_ for the shadow DOM tree. Nodes are
  /// either automatically assigned (`named`) or manually assigned (`manual`).
  /// The value of this property defined using the `slotAssignment` option when
  /// calling [Element.attachShadow].
  external SlotAssignmentMode get slotAssignment;

  /// The **`clonable`** read-only property of the [ShadowRoot] interface
  /// returns `true` if the shadow root is clonable, and `false` otherwise.
  ///
  /// When the value is `true`, a shadow host cloned with [Node.cloneNode] or
  /// [Document.importNode] will include a copy of the shadow root.
  ///
  /// By default the value is `false`.
  /// It can be set to `true` using the `clonable` option of the
  /// [Element.attachShadow] method or by setting the
  /// [`shadowrootclonable`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#shadowrootclonable)
  /// attribute of the `<template>` element that is being used to declaratively
  /// attach a shadow root.
  external bool get clonable;

  /// The **`serializable`** read-only property of the [ShadowRoot] interface
  /// returns `true` if the shadow root is serializable.
  ///
  /// If set, the shadow root may be serialized by calling the [Element.getHTML]
  /// or [ShadowRoot.getHTML] methods with the `options.serializableShadowRoots`
  /// parameter set `true`.
  ///
  /// The serializable property of a shadow root is specified when the shadow
  /// root is created, either declaratively by adding the
  /// [`shadowrootserializable`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#shadowrootserializable)
  /// attribute on a `<template>` element (along with an allowed
  /// [`shadowrootmode`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#shadowrootmode)
  /// value), or by setting the
  /// [`options.serializable`](/en-US/docs/Web/API/Element/attachShadow#serializable)
  /// parameter to `true` when using
  /// [`Element.attachShadow()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow).
  external bool get serializable;

  /// The **`host`** read-only property of
  /// the [ShadowRoot] returns a reference to the DOM element the
  /// `ShadowRoot` is attached to.
  external Element get host;
  external EventHandler get onslotchange;
  external set onslotchange(EventHandler value);

  /// The **`innerHTML`** property of the [ShadowRoot]
  /// interface sets or returns a reference to the DOM tree inside the
  /// `ShadowRoot`.
  external JSAny get innerHTML;
  external set innerHTML(JSAny value);

  /// The **`styleSheets`** read-only property of the [ShadowRoot] interface
  /// returns a [StyleSheetList] of [CSSStyleSheet] objects, for stylesheets
  /// explicitly linked into or embedded in a shadow tree.
  external StyleSheetList get styleSheets;

  /// The **`adoptedStyleSheets`** property of the [ShadowRoot] interface sets
  /// an array of constructed stylesheets to be used by the shadow DOM subtree.
  ///
  /// > [!NOTE]
  /// > A constructed stylesheet is a stylesheet created programmatically using
  /// > the [`CSSStyleSheet()`
  /// > constructor](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet)
  /// > (as compared to one created by a user-agent when importing a stylesheet
  /// > from a script, imported using `style` and , or linked to via `link`).
  ///
  /// The same constructed stylesheet can be adopted by multiple [ShadowRoot]
  /// instances, and by the parent document (using the
  /// [Document.adoptedStyleSheets] property).
  /// Changing an adopted stylesheet will affect all the adopting objects.
  ///
  /// Stylesheets in the `adoptedStyleSheets` property are considered along with
  /// the shadow DOM's other stylesheets.
  /// For the purpose of determining the final computed CSS of any element, they
  /// are considered to have been added _after_ the other stylesheets in the
  /// shadow DOM
  /// ([`ShadowRoot.styleSheets`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/styleSheets)).
  ///
  /// Only stylesheets created using the [`CSSStyleSheet()`
  /// constructor](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet),
  /// and from within the same parent [Document] as the shadow root, may be
  /// adopted.
  external JSArray<CSSStyleSheet> get adoptedStyleSheets;
  external set adoptedStyleSheets(JSArray<CSSStyleSheet> value);

  /// The **`fullscreenElement`** read-only property of the
  /// [ShadowRoot] interface returns the element within the shadow tree that is
  /// currently displayed in full screen.
  external Element? get fullscreenElement;

  /// The **`activeElement`** read-only property of the
  /// [ShadowRoot] interface returns the element within the shadow tree that has
  /// focus.
  external Element? get activeElement;

  /// The **`pictureInPictureElement`** read-only property of the
  /// [ShadowRoot] interface returns the [Element] that is currently being
  /// presented in picture-in-picture mode in this shadow tree, or `null` if
  /// picture-in-picture mode is not currently in use.
  external Element? get pictureInPictureElement;

  /// The **`pointerLockElement`** read-only property of the [ShadowRoot]
  /// interface provides the element set as the target for mouse events while
  /// the pointer is locked.
  /// It is `null` if lock is pending, pointer is unlocked, or the target is in
  /// another tree.
  external Element? get pointerLockElement;
}

/// **`Element`** is the most general base class from which all element objects
/// (i.e. objects that represent elements) in a [Document] inherit. It only has
/// methods and properties common to all kinds of elements. More specific
/// classes inherit from `Element`.
///
/// For example, the [HTMLElement] interface is the base interface for HTML
/// elements. Similarly, the [SVGElement] interface is the basis for all SVG
/// elements, and the [MathMLElement] interface is the base interface for MathML
/// elements. Most functionality is specified further down the class hierarchy.
///
/// Languages outside the realm of the Web platform, like XUL through the
/// `XULElement` interface, also implement `Element`.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Element).
extension type Element._(JSObject _) implements Node, JSObject {
  /// The **`hasAttributes()`** method of the [Element]
  /// interface returns a boolean value indicating whether the current element
  /// has any
  /// attributes or not.
  external bool hasAttributes();

  /// The **`getAttributeNames()`** method of the
  /// [Element] interface returns the attribute names of the element as an
  /// `Array` of strings. If the element has no attributes it returns an empty
  /// array.
  ///
  /// Using `getAttributeNames()` along with
  /// [Element.getAttribute], is a memory-efficient and
  /// performant alternative to accessing [Element.attributes].
  ///
  /// The names returned by **`getAttributeNames()`** are _qualified_ attribute
  /// names, meaning that attributes with a namespace prefix have their names
  /// returned with that namespace prefix (_not_ the actual namespace), followed
  /// by a colon, followed by the attribute name (for example,
  /// **`xlink:href`**), while any attributes which have no namespace prefix
  /// have their names returned as-is (for example, **`href`**).
  external JSArray<JSString> getAttributeNames();

  /// The **`getAttribute()`** method of the
  /// [Element] interface returns the value of a specified attribute on the
  /// element.
  ///
  /// If the given attribute does not exist, the value returned will be `null`.
  ///
  /// If you need to inspect the [Attr] node's properties, you can use the
  /// [Element.getAttributeNode] method instead.
  external String? getAttribute(String qualifiedName);

  /// The **`getAttributeNS()`** method of the [Element]
  /// interface returns the string value of the attribute with the specified
  /// namespace and
  /// name. If the named attribute does not exist, the value returned will
  /// either be
  /// `null` or `""` (the empty string); see [Notes](#notes) for
  /// details.
  ///
  /// If you are working with HTML documents and you don't need to specify the
  /// requested attribute as being part of a specific namespace, use the
  /// [Element.getAttribute] method instead.
  external String? getAttributeNS(
    String? namespace,
    String localName,
  );

  /// The **`setAttribute()`** method of the [Element] interface sets the value
  /// of an attribute on the specified element. If the attribute already exists,
  /// the value is updated; otherwise a new attribute is added with the
  /// specified name and value.
  ///
  /// To get the current value of an attribute, use [Element.getAttribute]; to
  /// remove an attribute, call [Element.removeAttribute].
  ///
  /// If you need to work with the [Attr] node (such as cloning from another
  /// element) before adding it, you can use the [Element.setAttributeNode]
  /// method instead.
  external void setAttribute(
    String qualifiedName,
    String value,
  );

  /// `setAttributeNS` adds a new attribute or changes the value of an attribute
  /// with the given namespace and name.
  ///
  /// If you are working with HTML documents and you don't need to specify the
  /// requested attribute as being part of a specific namespace, use the
  /// [Element.setAttribute] method instead.
  external void setAttributeNS(
    String? namespace,
    String qualifiedName,
    String value,
  );

  /// The [Element] method
  /// **`removeAttribute()`** removes the attribute with the
  /// specified name from the element.
  external void removeAttribute(String qualifiedName);

  /// The **`removeAttributeNS()`** method of the
  /// [Element] interface removes the specified attribute with the specified
  /// namespace from an element.
  ///
  /// If you are working with HTML and you don't need to specify the requested
  /// attribute as being part of a specific namespace, use the
  /// [Element.removeAttribute] method instead.
  external void removeAttributeNS(
    String? namespace,
    String localName,
  );

  /// The **`toggleAttribute()`** method of the
  /// [Element] interface toggles a Boolean attribute (removing it if it is
  /// present and adding it if it is not present) on the given element.
  external bool toggleAttribute(
    String qualifiedName, [
    bool force,
  ]);

  /// The **`Element.hasAttribute()`** method returns a
  /// **Boolean** value indicating whether the specified element has the
  /// specified attribute or not.
  external bool hasAttribute(String qualifiedName);

  /// The **`hasAttributeNS()`** method of the [Element] interface returns a
  /// boolean value indicating whether the current element has the specified
  /// attribute with the specified namespace.
  ///
  /// If you are working with HTML documents and you don't need to specify the
  /// requested attribute as being part of a specific namespace, use the
  /// [Element.hasAttribute] method instead.
  external bool hasAttributeNS(
    String? namespace,
    String localName,
  );

  /// Returns the specified attribute of the specified element, as an [Attr]
  /// node.
  ///
  /// This method is useful if you need the attribute's
  /// [instance properties](https://developer.mozilla.org/en-US/docs/Web/API/Attr#instance_properties).
  /// If you only need the attribute's value, you can use the
  /// [Element.getAttribute] method instead.
  external Attr? getAttributeNode(String qualifiedName);

  /// The **`getAttributeNodeNS()`** method of the [Element] interface returns
  /// the namespaced [Attr] node of an element.
  ///
  /// This method is useful if you need the namespaced attribute's
  /// [instance properties](https://developer.mozilla.org/en-US/docs/Web/API/Attr#instance_properties).
  /// If you only need the namespaced attribute's value, you can use the
  /// [Element.getAttributeNS] method instead.
  ///
  /// If you need the [Attr] node of an element in HTML documents and the
  /// attribute is not namespaced, use the [Element.getAttributeNode] method
  /// instead.
  external Attr? getAttributeNodeNS(
    String? namespace,
    String localName,
  );

  /// The **`setAttributeNode()`** method of the [Element] interface adds a new
  /// [Attr] node to the specified element.
  ///
  /// If you don't need to work with the attribute node (such as cloning from
  /// another element) before adding it, you can use the [Element.setAttribute]
  /// method instead.
  external Attr? setAttributeNode(Attr attr);

  /// The **`setAttributeNodeNS()`** method of the [Element] interface adds a
  /// new namespaced [Attr] node to an element.
  ///
  /// If you don't need to work with the attribute node (such as cloning from
  /// another element) before adding it, you can use the
  /// [Element.setAttributeNS] method instead.
  ///
  /// If you are working with HTML documents and you don't need to specify the
  /// requested attribute as being part of a specific namespace, use the
  /// [Element.setAttribute] method instead.
  external Attr? setAttributeNodeNS(Attr attr);

  /// The **`removeAttributeNode()`** method of the [Element] interface removes
  /// the specified [Attr] node from the element.
  ///
  /// If you don't need to inspect the attribute node before removing it, you
  /// can use the [Element.removeAttribute] method instead.
  external Attr removeAttributeNode(Attr attr);

  /// The **`Element.attachShadow()`** method attaches a shadow DOM tree to the
  /// specified element and returns a reference to its [ShadowRoot].
  external ShadowRoot attachShadow(ShadowRootInit init);

  /// The **`closest()`** method of the [Element] interface traverses the
  /// element and its parents (heading toward the document root) until it finds
  /// a node that matches the specified
  /// [CSS selector](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Basic_selectors).
  external Element? closest(String selectors);

  /// The **`matches()`** method of the [Element] interface tests whether the
  /// element would be selected by the specified
  /// [CSS selector](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Basic_selectors).
  external bool matches(String selectors);

  /// The
  /// **`Element.getElementsByTagName()`** method returns a live
  /// [HTMLCollection] of elements with the given
  /// [tag name](https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName).
  ///
  /// All descendants of the
  /// specified element are searched, but not the element itself. The returned
  /// list is
  /// _live_, which means it updates itself with the DOM tree automatically.
  /// Therefore, there is no need to call `Element.getElementsByTagName()` with
  /// the same element and arguments repeatedly if the DOM changes in between
  /// calls.
  ///
  /// When called on an HTML element in an HTML document, `getElementsByTagName`
  /// lower-cases the argument before searching for it. This is undesirable when
  /// trying to
  /// match  SVG elements (such as
  /// [`<linearGradient>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/linearGradient))
  /// in an HTML document. Instead, use [Element.getElementsByTagNameNS],
  /// which preserves the capitalization of the tag name.
  ///
  /// `Element.getElementsByTagName` is similar to
  /// [Document.getElementsByTagName], except that it only searches for
  /// elements that are descendants of the specified element.
  external HTMLCollection getElementsByTagName(String qualifiedName);

  /// The **`Element.getElementsByTagNameNS()`** method returns a
  /// live [HTMLCollection] of elements with the given tag name belonging to the
  /// given namespace. It is similar to [Document.getElementsByTagNameNS],
  /// except
  /// that its search is restricted to descendants of the specified element.
  external HTMLCollection getElementsByTagNameNS(
    String? namespace,
    String localName,
  );

  /// The [Element] method
  /// **`getElementsByClassName()`** returns a live
  /// [HTMLCollection] which contains every descendant element which has the
  /// specified class name or names.
  ///
  /// The method [Document.getElementsByClassName]
  /// on the [Document] interface works essentially the same way, except it acts
  /// on the entire document, starting at the document root.
  external HTMLCollection getElementsByClassName(String classNames);

  /// The **`insertAdjacentElement()`** method of the
  /// [Element] interface inserts a given element node at a given position
  /// relative to the element it is invoked upon.
  external Element? insertAdjacentElement(
    String where,
    Element element,
  );

  /// The **`insertAdjacentText()`** method of the [Element] interface, given a
  /// relative position and a string, inserts a new text node at the given
  /// position relative to the element it is called from.
  external void insertAdjacentText(
    String where,
    String data,
  );

  /// The **`computedStyleMap()`** method of
  /// the [Element] interface returns a [StylePropertyMapReadOnly]
  /// interface which provides a read-only representation of a CSS declaration
  /// block that is
  /// an alternative to [CSSStyleDeclaration].
  external StylePropertyMapReadOnly computedStyleMap();

  /// The **`getClientRects()`** method of the [Element]
  /// interface returns a collection of [DOMRect] objects that indicate the
  /// bounding rectangles for each
  /// [CSS border box](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_box_model/Introduction_to_the_CSS_box_model)
  /// in a client.
  ///
  /// Most elements only have one border box each, but a multiline
  /// [inline-level element](https://developer.mozilla.org/en-US/docs/Glossary/Inline-level_content)
  /// (such as a multiline
  /// `span` element, by default) has a border box around each line.
  external DOMRectList getClientRects();

  /// The **`Element.getBoundingClientRect()`** method returns a
  /// [DOMRect] object providing information about the size of an element and
  /// its
  /// position relative to the
  /// [viewport](https://developer.mozilla.org/en-US/docs/Glossary/Viewport).
  external DOMRect getBoundingClientRect();

  /// The **`checkVisibility()`** method of the [Element] interface checks
  /// whether the element is visible.
  ///
  /// The method returns `false` in either of the following situations:
  ///
  /// - The element doesn't have an associated box, for example because the CSS
  ///   `display` property is set to
  ///   [`none`](https://developer.mozilla.org/en-US/docs/Web/CSS/display#none)
  ///   or
  ///   [`contents`](https://developer.mozilla.org/en-US/docs/Web/CSS/display#contents).
  /// - The element is not being rendered because the element or an ancestor
  ///   element sets the  property to
  ///   [`hidden`](https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility#hidden).
  ///
  /// The optional parameter enables additional checks to test for other
  /// interpretations of what "visible" means.
  /// For example, you can further check whether an element has an opacity of
  /// `0`, if the value of the element
  /// [`visibility`](https://developer.mozilla.org/en-US/docs/Web/CSS/visibility)
  /// property makes it invisible, or if the element  property has a value of
  /// [`auto`](https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility#auto)
  /// and its rendering is currently being skipped.
  external bool checkVisibility([CheckVisibilityOptions options]);

  /// The [Element] interface's
  /// **`scrollIntoView()`** method scrolls the element's ancestor
  /// containers such that the element on which `scrollIntoView()` is called is
  /// visible to the user.
  external void scrollIntoView([JSAny arg]);

  /// The **`scroll()`** method of the [Element]
  /// interface scrolls the element to a particular set of coordinates inside a
  /// given
  /// element.
  external void scroll([
    JSAny optionsOrX,
    num y,
  ]);

  /// The **`scrollTo()`** method of the [Element]
  /// interface scrolls to a particular set of coordinates inside a given
  /// element.
  external void scrollTo([
    JSAny optionsOrX,
    num y,
  ]);

  /// The **`scrollBy()`** method of the [Element]
  /// interface scrolls an element by the given amount.
  external void scrollBy([
    JSAny optionsOrX,
    num y,
  ]);

  /// The **`Element.requestFullscreen()`**
  /// method issues an asynchronous request to make the element be displayed in
  /// fullscreen
  /// mode.
  ///
  /// It's not guaranteed that the element will be put into full screen mode. If
  /// permission
  /// to enter full screen mode is granted, the returned `Promise` will resolve
  /// and the element will receive a [Element.fullscreenchange_event] event to
  /// let it know that
  /// it's now in full screen mode. If permission is denied, the promise is
  /// rejected and the
  /// element receives a [Element.fullscreenerror_event] event instead. If the
  /// element has been
  /// detached from the original document, then the document receives these
  /// events instead.
  external JSPromise<JSAny?> requestFullscreen([FullscreenOptions options]);

  /// The **`setHTMLUnsafe()`** method of the [Element] interface is used to
  /// parse a string of HTML into a [DocumentFragment], which then replaces the
  /// element's subtree in the DOM.
  /// The input HTML may include
  /// [declarative shadow roots](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#declarative_shadow_dom).
  ///
  /// The suffix "Unsafe" in the method name indicates that the method does not
  /// sanitize or remove potentially unsafe XSS-relevant input, such as
  /// `<script>` elements, and script or event handler content attributes.
  ///
  /// If the string of HTML defines more than one
  /// [declarative shadow root](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#declarative_shadow_dom)
  /// in a particular shadow host then only the first [ShadowRoot] is created —
  /// subsequent declarations are parsed as `<template>` elements within that
  /// shadow root.
  ///
  /// > [!NOTE]
  /// > This method should be used instead of [Element.innerHTML] when a string
  /// > of HTML may contain declarative shadow roots.
  external void setHTMLUnsafe(JSAny html);

  /// The **`getHTML()`** method of the [Element] interface is used to serialize
  /// an element's DOM to an HTML string.
  ///
  /// The method provides an options argument that enables the serialization of
  /// child nodes that are shadow roots.
  /// The options can be used to include nested shadow roots that have been set
  /// as [ShadowRoot.serializable], and/or a specified array of [ShadowRoot]
  /// objects, which may be either open or closed.
  ///
  /// Without arguments, child nodes that are shadow roots are not serialized,
  /// and this method behaves in the same way as reading the value of
  /// [Element.innerHTML].
  external String getHTML([GetHTMLOptions options]);

  /// The **`insertAdjacentHTML()`** method of the
  /// [Element] interface parses the specified text as HTML or XML and inserts
  /// the resulting nodes into the DOM tree at a specified position.
  external void insertAdjacentHTML(
    String position,
    JSAny string,
  );

  /// The **`setPointerCapture()`** method of the
  /// [Element] interface is used to designate a specific element as the
  /// _capture target_ of future pointer events. Subsequent events for the
  /// pointer will
  /// be targeted at the capture element until capture is released (via
  /// [Element.releasePointerCapture] or the
  /// [Element.pointerup_event] event is fired).
  ///
  /// See
  /// [pointer events](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events#pointer_capture)
  /// for an overview and examples of how pointer capture works.
  external void setPointerCapture(int pointerId);

  /// The **`releasePointerCapture()`** method of the
  /// [Element] interface releases (stops)
  /// [_pointer capture_](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events#pointer_capture)
  /// that was
  /// previously set for a specific ([PointerEvent]) _pointer_.
  external void releasePointerCapture(int pointerId);

  /// The **`hasPointerCapture()`** method of the
  /// [Element] interface checks whether the element on which it is invoked has
  /// [pointer capture](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events#pointer_capture)
  /// for the pointer identified by the given pointer ID.
  external bool hasPointerCapture(int pointerId);

  /// The **`requestPointerLock()`** method of the [Element] interface lets you
  /// asynchronously ask for the pointer to be locked on the given element.
  ///
  /// To track the success or failure of the request, it is necessary to listen
  /// for the [Document.pointerlockchange_event] and
  /// [Document.pointerlockerror_event] events at the [Document] level.
  ///
  /// > [!NOTE]
  /// > In the current specification, `requestPointerLock()` only communicates
  /// > the success or failure of the request by firing
  /// > [Document.pointerlockchange_event] or [Document.pointerlockerror_event]
  /// > events.
  /// > [A proposed update to the specification](https://github.com/w3c/pointerlock/pull/49)
  /// > updates `requestPointerLock()` to return a `Promise` which communicates
  /// > success or failure. This page documents the version that returns a
  /// > `Promise`. However, note that this version is not yet a standard and is
  /// > not implemented by all browsers. See
  /// > [Browser compatibility](#browser_compatibility) for more information.
  external JSPromise<JSAny?> requestPointerLock([PointerLockOptions options]);

  /// The **`Element.prepend()`** method inserts a set of
  /// [Node] objects or strings before the first child
  /// of the [Element]. Strings are inserted as
  /// equivalent [Text] nodes.
  external void prepend([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`Element.append()`** method
  /// inserts a set of [Node] objects or strings after
  /// the last child of the `Element`. Strings
  /// are inserted as equivalent [Text] nodes.
  ///
  /// Differences from [Node.appendChild]:
  ///
  /// - `Element.append()` allows you to also append strings, whereas
  ///   `Node.appendChild()` only accepts [Node]
  /// objects.
  /// - `Element.append()` has no return value, whereas
  /// `Node.appendChild()` returns the appended [Node] object.
  /// - `Element.append()` can append several nodes and strings, whereas
  /// `Node.appendChild()` can only append one node.
  external void append([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`Element.replaceChildren()`** method replaces the
  /// existing children of a [Node] with a specified new set of children. These
  /// can be string or [Node] objects.
  external void replaceChildren([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`querySelector()`** method of the [Element]
  /// interface returns the first element that is a descendant of the element on
  /// which it is
  /// invoked that matches the specified group of selectors.
  external Element? querySelector(String selectors);

  /// The [Element] method **`querySelectorAll()`**
  /// returns a static (not live) [NodeList] representing a list of elements
  /// matching the specified group of selectors which are descendants of the
  /// element on which
  /// the method was called.
  external NodeList querySelectorAll(String selectors);

  /// The **`Element.before()`** method inserts a set of
  /// [Node] objects or strings in the children list of this
  /// `Element`'s parent, just before this `Element`.
  /// Strings are inserted as equivalent [Text] nodes.
  external void before([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`Element.after()`** method inserts a set of
  /// [Node] objects or strings in the children list of the
  /// `Element`'s parent, just after the `Element`.
  /// Strings are inserted as equivalent [Text] nodes.
  external void after([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`Element.replaceWith()`** method replaces this
  /// `Element` in the children list of its parent with a set of
  /// [Node] objects or strings. Strings are inserted as equivalent [Text]
  /// nodes.
  external void replaceWith([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`Element.remove()`** method removes the element from the DOM.
  external void remove();

  /// The [Element] interface's **`animate()`** method
  /// is a shortcut method which creates a new [Animation], applies it to the
  /// element, then plays the animation. It returns the created [Animation]
  /// object instance.
  ///
  /// > [!NOTE]
  /// > Elements can have multiple animations applied to them. You can get a
  /// > list of the
  /// > animations that affect an element by calling [Element.getAnimations].
  external Animation animate(
    JSObject? keyframes, [
    JSAny options,
  ]);

  /// The `getAnimations()` method of the [Element] interface
  /// (specified on the `Animatable` mixin) returns an array of all
  /// [Animation] objects affecting this element or which are scheduled to do so
  /// in future. It can optionally return [Animation] objects for descendant
  /// elements too.
  ///
  /// > [!NOTE]
  /// > This array includes
  /// > [CSS Animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations),
  /// > [CSS Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_transitions),
  /// > and
  /// > [Web Animations](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).
  external JSArray<Animation> getAnimations([GetAnimationsOptions options]);

  /// The **`Element.namespaceURI`** read-only property returns the namespace
  /// URI of the element, or `null` if the element is not in a namespace.
  external String? get namespaceURI;

  /// The **`Element.prefix`** read-only property returns the
  /// namespace prefix of the specified element, or `null` if no prefix is
  /// specified.
  external String? get prefix;

  /// The **`Element.localName`** read-only property returns the
  /// local part of the qualified name of an element.
  external String get localName;

  /// The **`tagName`** read-only property
  /// of the [Element] interface returns the tag name of the element on which
  /// it's called.
  ///
  /// For example, if the element is an `img`, its
  /// `tagName` property is `IMG` (for HTML documents; it may be cased
  /// differently for XML/XHTML documents). Note: You can use the
  /// [Element.localName] property
  /// to access the Element's local name — which for the case in the example is
  /// `img` (lowercase).
  external String get tagName;

  /// The **`id`** property of the [Element] interface
  /// represents the element's identifier, reflecting the
  /// [**`id`**](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id)
  /// global attribute.
  ///
  /// If the `id` value is not the empty string, it must be unique in a
  /// document.
  ///
  /// The `id` is often used with [Document.getElementById] to retrieve a
  /// particular element.
  /// Another common case is to use an element's
  /// [ID as a selector](https://developer.mozilla.org/en-US/docs/Web/CSS/ID_selectors)
  /// when styling the document with
  /// [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS).
  ///
  /// > [!NOTE]
  /// > Identifiers are case-sensitive, but you should avoid creating
  /// > IDs that differ only in the capitalization.
  external String get id;
  external set id(String value);

  /// The **`className`** property of the
  /// [Element] interface gets and sets the value of the
  /// [`class` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class)
  /// of the specified element.
  external String get className;
  external set className(String value);

  /// The **`Element.classList`** is a read-only property that
  /// returns a live [DOMTokenList] collection of the `class`
  /// attributes of the element. This can then be used to manipulate the class
  /// list.
  ///
  /// Using `classList` is a convenient alternative to accessing an element's
  /// list
  /// of classes as a space-delimited string via [element.className].
  external DOMTokenList get classList;

  /// The **`slot`** property of the [Element] interface
  /// returns the name of the shadow DOM slot the element is inserted in.
  ///
  /// A slot is a placeholder inside a
  /// [web component](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
  /// that users can fill with their own markup (see
  /// [Using templates and slots](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots)
  /// for more information).
  external String get slot;
  external set slot(String value);

  /// The **`Element.attributes`** property returns a live collection
  /// of all attribute nodes registered to the specified node. It is a
  /// [NamedNodeMap], not an `Array`, so it has no `Array`
  /// methods and the [Attr] nodes' indexes may differ among browsers. To be
  /// more
  /// specific, `attributes` is a key/value pair of strings that represents any
  /// information regarding that attribute.
  external NamedNodeMap get attributes;

  /// The `Element.shadowRoot` read-only property
  /// represents the shadow root hosted by the element.
  ///
  /// Use [Element.attachShadow] to add a shadow root to an existing element.
  external ShadowRoot? get shadowRoot;

  /// The **`part`** property of the [Element] interface
  /// represents the part identifier(s) of the element (i.e. set using the
  /// `part`
  /// attribute), returned as a [DOMTokenList]. These can be used to style parts
  /// of a shadow DOM, via the  pseudo-element.
  external DOMTokenList get part;

  /// The **`Element.scrollTop`** property gets or sets the number of pixels by
  /// which an element's content is scrolled from its top edge. This value is
  /// subpixel precise in modern browsers, meaning that it isn't necessarily a
  /// whole number.
  external double get scrollTop;
  external set scrollTop(num value);

  /// The **`Element.scrollLeft`** property gets or sets the number of pixels by
  /// which an element's content is scrolled from its left edge. This value is
  /// subpixel precise in modern browsers, meaning that it isn't necessarily a
  /// whole number.
  external double get scrollLeft;
  external set scrollLeft(num value);

  /// The **`Element.scrollWidth`** read-only property is a
  /// measurement of the width of an element's content, including content not
  /// visible on the
  /// screen due to overflow.
  ///
  /// The `scrollWidth` value is equal to the minimum width the element would
  /// require in order to fit all the content in the viewport without using a
  /// horizontal
  /// scrollbar. The width is measured in the same way as [Element.clientWidth]:
  /// it includes the element's padding, but not its border, margin or
  /// vertical scrollbar (if present). It can also include the width of
  /// pseudo-elements such
  /// as  or . If the element's content can fit
  /// without a need for horizontal scrollbar, its `scrollWidth` is equal to
  /// [Element.clientWidth].
  ///
  /// > [!NOTE]
  /// > This property will round the value to an integer. If you need a
  /// > fractional value,
  /// > use [Element.getBoundingClientRect].
  external int get scrollWidth;

  /// The **`Element.scrollHeight`** read-only property is a
  /// measurement of the height of an element's content, including content not
  /// visible on the
  /// screen due to overflow.
  ///
  /// ![The user's viewport is an element with four regions labeled padding-top,
  /// border-top, border-bottom, padding-bottom. The scroll height goes from the
  /// container's padding top to the end of the padding bottom, well beyond the
  /// top and bottom of the viewport.](scrollheight.png)
  ///
  /// The `scrollHeight` value is equal to the minimum height the element would
  /// require in order to fit all the content in the viewport without using a
  /// vertical
  /// scrollbar. The height is measured in the same way as
  /// [Element.clientHeight]:
  /// it includes the element's padding, but not its border, margin or
  /// horizontal scrollbar (if present). It can also include the height of
  /// pseudo-elements
  /// such as  or . If the element's content can
  /// fit without a need for vertical scrollbar, its `scrollHeight` is equal to
  /// [Element.clientHeight]
  ///
  /// > [!NOTE]
  /// > This property will round the value to an integer. If you need a
  /// > fractional value, use
  /// > [Element.getBoundingClientRect].
  external int get scrollHeight;

  /// The width of the top border of an element in pixels. It is a read-only,
  /// integer
  /// property of element.
  ///
  /// As it happens, all that lies between the two locations (`offsetTop` and
  /// client area top) is the element's border. This is because the `offsetTop`
  /// indicates the location of the top of the border (not the margin) while the
  /// client area
  /// starts immediately below the border, (client area includes padding.)
  /// Therefore, the
  /// **clientTop** value will always equal the integer portion of the
  /// `.getComputedStyle()` value for "border-top-width". (Actually might be
  /// Math.round(parseFloat()).) For example, if the computed "border-top-width"
  /// is zero,
  /// then **`clientTop`** is also zero.
  ///
  /// > [!NOTE]
  /// > This property will round the value to an integer. If you
  /// > need a fractional value, use [element.getBoundingClientRect].
  external int get clientTop;

  /// The width of the left border of an element in pixels. It includes the
  /// width of the
  /// vertical scrollbar if the text direction of the element is right-to-left
  /// and if there
  /// is an overflow causing a left vertical scrollbar to be rendered.
  /// `clientLeft` does not include the left margin or the left padding.
  /// `clientLeft` is read-only.
  ///
  /// > [!NOTE]
  /// > This property will round the value to an integer. If you
  /// > need a fractional value, use [element.getBoundingClientRect].
  ///
  /// > [!NOTE]
  /// > When an element has
  /// > `display: inline`, `clientLeft` returns `0`
  /// > regardless of the element's border.
  external int get clientLeft;

  /// The **`Element.clientWidth`** property is zero for inline
  /// elements and elements with no CSS; otherwise, it's the inner width of an
  /// element in
  /// pixels. It includes padding but excludes borders, margins, and vertical
  /// scrollbars (if
  /// present).
  ///
  /// When `clientWidth` is used on the root element (the
  /// `<html>` element), (or on `<body>` if the document is
  /// in quirks mode), the viewport's width (excluding any scrollbar) is
  /// returned.
  ///
  /// > [!NOTE]
  /// > This property will round the value to an integer. If you need
  /// > a fractional value, use [element.getBoundingClientRect].
  external int get clientWidth;

  /// The **`Element.clientHeight`** read-only property is zero for
  /// elements with no CSS or inline layout boxes; otherwise, it's the inner
  /// height of an
  /// element in pixels. It includes padding but excludes borders, margins, and
  /// horizontal
  /// scrollbars (if present).
  ///
  /// `clientHeight` can be calculated as: CSS `height` + CSS
  /// `padding` - height of horizontal scrollbar (if present).
  ///
  /// When `clientHeight` is used on the root element (the
  /// `<html>` element), (or on `<body>` if the document is
  /// in quirks mode), the viewport's height (excluding any scrollbar) is
  /// returned.
  ///
  /// > [!NOTE]
  /// > This property will round the value to an integer. If you need
  /// > a fractional value, use [element.getBoundingClientRect].
  external int get clientHeight;

  /// The **`currentCSSZoom`** read-only property of the [Element] interface
  /// provides the "effective"
  /// [CSS `zoom`](https://developer.mozilla.org/en-US/docs/Web/CSS/zoom) of an
  /// element, taking into account the zoom applied to the element and all its
  /// parent elements.
  ///
  /// The value calculated by multiplying the CSS `zoom` values of the element
  /// and all of its parents.
  /// For example, if three elements with zoom values of 2, 1.5, and 3, are
  /// nested within each other, the most deeply nested element will have a
  /// `currentCSSZoom` value of 9.
  /// If the element doesn't have a CSS box, for example because `display: none`
  /// is set on the element or one of its parents, then the `currentCSSZoom` is
  /// set to 1.
  ///
  /// Note that some methods, such as [Element.getBoundingClientRect], return
  /// dimensions and position that are relative to the viewport, and hence
  /// include the effects of CSS `zoom`.
  /// Other properties and methods return values that are relative to the
  /// element itself, and do not include the effects of zooming.
  /// These include, for example, `client*` properties such as
  /// [Element.clientHeight], `scroll*()` methods like [Element.scroll], and
  /// `offset*` properties such as [HTMLElement.offsetHeight].
  /// The `currentCSSZoom` property can be used to scale these values to adjust
  /// for the effects of zooming.
  external double get currentCSSZoom;
  external EventHandler get onfullscreenchange;
  external set onfullscreenchange(EventHandler value);
  external EventHandler get onfullscreenerror;
  external set onfullscreenerror(EventHandler value);

  /// The [Element] property **`innerHTML`** gets or sets the HTML or XML markup
  /// contained within the element.
  ///
  /// More precisely, `innerHTML` gets a serialization of the nested child DOM
  /// elements within the element, or sets HTML or XML that should be parsed to
  /// replace the DOM tree within the element.
  ///
  /// To insert the HTML into the document rather than replace the contents of
  /// an element, use the method [Element.insertAdjacentHTML].
  ///
  /// The serialization of the DOM tree read from the property does not include
  /// — if you want to get a HTML string that includes shadow roots, you must
  /// instead use the [Element.getHTML] or [ShadowRoot.getHTML] methods.
  /// Similarly, when setting element content using `innerHTML`, the HTML string
  /// is parsed into DOM elements that do not contain shadow roots.
  ///
  /// So for example
  /// [`<template>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)
  /// is parsed into as [HTMLTemplateElement], whether or not the
  /// [`shadowrootmode`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#shadowrootmode)
  /// attribute is specified
  /// In order to set an element's contents from an HTML string that includes
  /// declarative shadow roots, you must use either [Element.setHTMLUnsafe] or
  /// [ShadowRoot.setHTMLUnsafe].
  external JSAny get innerHTML;
  external set innerHTML(JSAny value);

  /// The **`outerHTML`** attribute of the [Element]
  /// DOM interface gets the serialized HTML fragment describing the element
  /// including its
  /// descendants. It can also be set to replace the element with nodes parsed
  /// from the given
  /// string.
  ///
  /// To only obtain the HTML representation of the contents of an element, or
  /// to replace the
  /// contents of an element, use the [Element.innerHTML] property
  /// instead.
  external JSAny get outerHTML;
  external set outerHTML(JSAny value);

  /// The read-only **`children`** property returns a live [HTMLCollection]
  /// which contains all of the child [Element] of the element upon which it was
  /// called.
  ///
  /// `Element.children` includes only element nodes. To get all child nodes,
  /// including non-element nodes like text and comment nodes, use
  /// [Node.childNodes].
  external HTMLCollection get children;

  /// The **`Element.firstElementChild`** read-only property
  /// returns an element's first child [Element], or `null` if there
  /// are no child elements.
  ///
  /// `Element.firstElementChild` includes only element nodes.
  /// To get all child nodes, including non-element nodes like text and comment
  /// nodes, use [Node.firstChild].
  external Element? get firstElementChild;

  /// The **`Element.lastElementChild`** read-only property
  /// returns an element's last child [Element], or `null` if there
  /// are no child elements.
  ///
  /// `Element.lastElementChild` includes only element nodes.
  /// To get all child nodes, including non-element nodes like text and comment
  /// nodes, use [Node.lastChild].
  external Element? get lastElementChild;

  /// The **`Element.childElementCount`** read-only property
  /// returns the number of child elements of this element.
  external int get childElementCount;

  /// The **`Element.previousElementSibling`**
  /// read-only property returns the [Element] immediately prior to the
  /// specified
  /// one in its parent's [Element.children] list, or `null` if the specified
  /// element is the first one in the list.
  external Element? get previousElementSibling;

  /// The **`Element.nextElementSibling`** read-only
  /// property returns the element immediately following the specified one in
  /// its parent's
  /// [Element.children] list, or `null` if the specified element is the last
  /// one in the list.
  external Element? get nextElementSibling;

  /// The **`assignedSlot`** read-only
  /// property of the [Element] interface returns an
  /// [HTMLSlotElement] representing the `slot` element the
  /// node is inserted in.
  external HTMLSlotElement? get assignedSlot;
  external String? get role;
  external set role(String? value);

  /// The **`ariaAtomic`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-atomic`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-atomic)
  /// attribute, which indicates whether assistive technologies will present
  /// all, or only parts of, the changed region based on the change
  /// notifications defined by the
  /// [`aria-relevant`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-relevant)
  /// attribute.
  external String? get ariaAtomic;
  external set ariaAtomic(String? value);

  /// The **`ariaAutoComplete`** property of the [Element] interface reflects
  /// the value of the
  /// [`aria-autocomplete`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-autocomplete)
  /// attribute, which indicates whether inputting text could trigger display of
  /// one or more predictions of the user's intended value for a combobox,
  /// searchbox, or textbox and specifies how predictions would be presented if
  /// they were made.
  external String? get ariaAutoComplete;
  external set ariaAutoComplete(String? value);

  /// The **`ariaBrailleLabel`** property of the [Element] interface reflects
  /// the value of the
  /// [`aria-braillelabel`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-braillelabel)
  /// attribute, which defines the ARIA braille label of the element.
  ///
  /// This element label may be used by assistive technologies that can present
  /// content in braille, but should only be set if a braille-specific label
  /// would improve the user experience.
  /// The
  /// [`aria-braillelabel`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-braillelabel)
  /// contains additional information about when the property should be set.
  external String? get ariaBrailleLabel;
  external set ariaBrailleLabel(String? value);

  /// The **`ariaBrailleRoleDescription`** property of the [Element] interface
  /// reflects the value of the
  /// [`aria-brailleroledescription`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-brailleroledescription)
  /// attribute, which defines the ARIA braille role description of the element.
  ///
  /// This property may be used to provide an abbreviated version of the
  /// [`aria-roledescription`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-roledescription)
  /// value.
  /// It should only be used if `aria-roledescription` is present and in the
  /// rare case where it is too verbose for braille.
  /// The
  /// [`aria-brailleroledescription`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-brailleroledescription)
  /// contains additional information about when the property should be set.
  external String? get ariaBrailleRoleDescription;
  external set ariaBrailleRoleDescription(String? value);

  /// The **`ariaBusy`** property of the [Element] interface reflects the value
  /// of the
  /// [`aria-busy`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-busy)
  /// attribute, which indicates whether an element is being modified, as
  /// assistive technologies may want to wait until the modifications are
  /// complete before exposing them to the user.
  external String? get ariaBusy;
  external set ariaBusy(String? value);

  /// The **`ariaChecked`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-checked`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-checked)
  /// attribute, which indicates the current "checked" state of checkboxes,
  /// radio buttons, and other widgets that have a checked state.
  ///
  /// > [!NOTE]
  /// > Where possible use an HTML `input` element with `type="checkbox"` as
  /// > this element has built in semantics and does not require ARIA
  /// > attributes.
  external String? get ariaChecked;
  external set ariaChecked(String? value);

  /// The **`ariaColCount`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-colcount`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-colcount)
  /// attribute, which defines the number of columns in a table, grid, or
  /// treegrid.
  external String? get ariaColCount;
  external set ariaColCount(String? value);

  /// The **`ariaColIndex`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-colindex`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-colindex)
  /// attribute, which defines an element's column index or position with
  /// respect to the total number of columns within a table, grid, or treegrid.
  external String? get ariaColIndex;
  external set ariaColIndex(String? value);

  /// The **`ariaColIndexText`** property of the [Element] interface reflects
  /// the value of the
  /// [`aria-colindextext`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-colindextext)
  /// attribute, which defines a human readable text alternative of
  /// aria-colindex.
  external String? get ariaColIndexText;
  external set ariaColIndexText(String? value);

  /// The **`ariaColSpan`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-colspan`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-colspan)
  /// attribute, which defines the number of columns spanned by a cell or
  /// gridcell within a table, grid, or treegrid.
  external String? get ariaColSpan;
  external set ariaColSpan(String? value);

  /// The **`ariaCurrent`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-current`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)
  /// attribute, which indicates the element that represents the current item
  /// within a container or set of related elements.
  external String? get ariaCurrent;
  external set ariaCurrent(String? value);

  /// The **`ariaDescription`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-description`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-description)
  /// attribute, which defines a string value that describes or annotates the
  /// current element.
  external String? get ariaDescription;
  external set ariaDescription(String? value);

  /// The **`ariaDisabled`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-disabled`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-disabled)
  /// attribute, which indicates that the element is perceivable but disabled,
  /// so it is not editable or otherwise operable.
  ///
  /// > [!NOTE]
  /// > Where possible, use the `input` element with `type="button"` or the
  /// > `button` element — because those elements have built in semantics and do
  /// > not require ARIA attributes.
  external String? get ariaDisabled;
  external set ariaDisabled(String? value);

  /// The **`ariaExpanded`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-expanded`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-expanded)
  /// attribute, which indicates whether a grouping element owned or controlled
  /// by this element is expanded or collapsed.
  external String? get ariaExpanded;
  external set ariaExpanded(String? value);

  /// The **`ariaHasPopup`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-haspopup`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-haspopup)
  /// attribute, which indicates the availability and type of interactive popup
  /// element, such as menu or dialog, that can be triggered by an element.
  external String? get ariaHasPopup;
  external set ariaHasPopup(String? value);

  /// The **`ariaHidden`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-hidden`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-hidden))
  /// attribute, which indicates whether the element is exposed to an
  /// accessibility API.
  external String? get ariaHidden;
  external set ariaHidden(String? value);
  external String? get ariaInvalid;
  external set ariaInvalid(String? value);

  /// The **`ariaKeyShortcuts`** property of the [Element] interface reflects
  /// the value of the `aria-keyshortcuts` attribute, which indicates keyboard
  /// shortcuts that an author has implemented to activate or give focus to an
  /// element.
  external String? get ariaKeyShortcuts;
  external set ariaKeyShortcuts(String? value);

  /// The **`ariaLabel`** property of the [Element] interface reflects the value
  /// of the
  /// [`aria-label`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label)
  /// attribute, which defines a string value that labels the current element.
  external String? get ariaLabel;
  external set ariaLabel(String? value);

  /// The **`ariaLevel`** property of the [Element] interface reflects the value
  /// of the `aria-level` attribute, which defines the hierarchical level of an
  /// element within a structure.
  ///
  /// > [!NOTE]
  /// > Where possible use an HTML `h1` or other correct heading level as these
  /// > have built in semantics and do not require ARIA attributes.
  external String? get ariaLevel;
  external set ariaLevel(String? value);

  /// The **`ariaLive`** property of the [Element] interface reflects the value
  /// of the
  /// [`aria-live`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-live)
  /// attribute, which indicates that an element will be updated, and describes
  /// the types of updates the user agents, assistive technologies, and user can
  /// expect from the
  /// [live region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions).
  external String? get ariaLive;
  external set ariaLive(String? value);

  /// The **`ariaModal`** property of the [Element] interface reflects the value
  /// of the `aria-modal` attribute, which indicates whether an element is modal
  /// when displayed. Applying the `aria-modal` property to an element with
  /// `role="dialog"` replaces the technique of using aria-hidden on the
  /// background for informing assistive technologies that content outside a
  /// dialog is inert.
  external String? get ariaModal;
  external set ariaModal(String? value);

  /// The **`ariaMultiLine`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-multiline`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-multiline)
  /// attribute, which indicates whether a text box accepts multiple lines of
  /// input or only a single line.
  ///
  /// > [!NOTE]
  /// > Where possible use an HTML `input` element with `type="text"` or a
  /// > `textarea` as these have built in semantics and do not require ARIA
  /// > attributes.
  external String? get ariaMultiLine;
  external set ariaMultiLine(String? value);

  /// The **`ariaMultiSelectable`** property of the [Element] interface reflects
  /// the value of the
  /// [`aria-multiselectable`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-multiselectable)
  /// attribute, which indicates that the user may select more than one item
  /// from the current selectable descendants.
  ///
  /// > [!NOTE]
  /// > Where possible use an HTML `select` element as this has built in
  /// > semantics and does not require ARIA attributes.
  external String? get ariaMultiSelectable;
  external set ariaMultiSelectable(String? value);

  /// The **`ariaOrientation`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-orientation`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-orientation)
  /// attribute, which indicates whether the element's orientation is
  /// horizontal, vertical, or unknown/ambiguous.
  external String? get ariaOrientation;
  external set ariaOrientation(String? value);

  /// The **`ariaPlaceholder`** property of the [Element] interface reflects the
  /// value of the `aria-placeholder` attribute, which defines a short hint
  /// intended to aid the user with data entry when the control has no value.
  ///
  /// > [!NOTE]
  /// > Where possible use an HTML `input` element with `type="text"` or a
  /// > `textarea` as these have built in semantics and do not require ARIA
  /// > attributes.
  external String? get ariaPlaceholder;
  external set ariaPlaceholder(String? value);

  /// The **`ariaPosInSet`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-posinset`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-posinset)
  /// attribute, which defines an element's number or position in the current
  /// set of listitems or treeitems.
  external String? get ariaPosInSet;
  external set ariaPosInSet(String? value);

  /// The **`ariaPressed`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-pressed`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-pressed)
  /// attribute, which indicates the current "pressed" state of toggle buttons.
  ///
  /// > [!NOTE]
  /// > Where possible use an HTML `input` element with `type="button"` or the
  /// > `button` element as these have built in semantics and do not require
  /// > ARIA attributes.
  external String? get ariaPressed;
  external set ariaPressed(String? value);

  /// The **`ariaReadOnly`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-readonly`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-readonly)
  /// attribute, which indicates that the element is not editable, but is
  /// otherwise operable.
  ///
  /// > [!NOTE]
  /// > Where possible use an HTML `input` element with `type="text"` or a
  /// > `textarea` as these have built in semantics and do not require ARIA
  /// > attributes.
  external String? get ariaReadOnly;
  external set ariaReadOnly(String? value);

  /// The **`ariaRequired`** property of the [Element] interface reflects the
  /// value of the `aria-required` attribute, which indicates that user input is
  /// required on the element before a form may be submitted.
  ///
  /// > [!NOTE]
  /// > Where possible use an HTML `input` element with `type="text"` or a
  /// > `textarea` as these have built in semantics and do not require ARIA
  /// > attributes.
  external String? get ariaRequired;
  external set ariaRequired(String? value);

  /// The **`ariaRoleDescription`** property of the [Element] interface reflects
  /// the value of the
  /// [`aria-roledescription`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-roledescription)
  /// attribute, which defines a human-readable, author-localized description
  /// for the role of an element.
  external String? get ariaRoleDescription;
  external set ariaRoleDescription(String? value);

  /// The **`ariaRowCount`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-rowcount`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-rowcount)
  /// attribute, which defines the total number of rows in a table, grid, or
  /// treegrid.
  external String? get ariaRowCount;
  external set ariaRowCount(String? value);

  /// The **`ariaRowIndex`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-rowindex`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-rowindex)
  /// attribute, which defines an element's row index or position with respect
  /// to the total number of rows within a table, grid, or treegrid.
  external String? get ariaRowIndex;
  external set ariaRowIndex(String? value);

  /// The **`ariaRowIndexText`** property of the [Element] interface reflects
  /// the value of the
  /// [`aria-rowindextext`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-rowindextext)
  /// attribute, which defines a human readable text alternative of
  /// aria-rowindex.
  external String? get ariaRowIndexText;
  external set ariaRowIndexText(String? value);

  /// The **`ariaRowSpan`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-rowspan`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-rowspan)
  /// attribute, which defines the number of rows spanned by a cell or gridcell
  /// within a table, grid, or treegrid.
  external String? get ariaRowSpan;
  external set ariaRowSpan(String? value);

  /// The **`ariaSelected`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-selected`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-selected)
  /// attribute, which indicates the current "selected" state of elements that
  /// have a selected state.
  external String? get ariaSelected;
  external set ariaSelected(String? value);

  /// The **`ariaSetSize`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-setsize`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-setsize)
  /// attribute, which defines the number of items in the current set of
  /// listitems or treeitems.
  external String? get ariaSetSize;
  external set ariaSetSize(String? value);

  /// The **`ariaSort`** property of the [Element] interface reflects the value
  /// of the
  /// [`aria-sort`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-sort)
  /// attribute, which indicates if items in a table or grid are sorted in
  /// ascending or descending order.
  external String? get ariaSort;
  external set ariaSort(String? value);

  /// The **`ariaValueMax`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-valuemax`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-valuemax)
  /// attribute, which defines the maximum allowed value for a range widget.
  external String? get ariaValueMax;
  external set ariaValueMax(String? value);

  /// The **`ariaValueMin`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-valuemin`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-valuemin)
  /// attribute, which defines the minimum allowed value for a range widget.
  external String? get ariaValueMin;
  external set ariaValueMin(String? value);

  /// The **`ariaValueNow`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-valuenow`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-valuenow)
  /// attribute, which defines the current value for a range widget.
  external String? get ariaValueNow;
  external set ariaValueNow(String? value);

  /// The **`ariaValueText`** property of the [Element] interface reflects the
  /// value of the
  /// [`aria-valuetext`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-valuetext)
  /// attribute, which defines the human-readable text alternative of
  /// aria-valuenow for a range widget.
  external String? get ariaValueText;
  external set ariaValueText(String? value);
}
extension type ShadowRootInit._(JSObject _) implements JSObject {
  external factory ShadowRootInit({
    required ShadowRootMode mode,
    bool delegatesFocus,
    SlotAssignmentMode slotAssignment,
    bool clonable,
    bool serializable,
  });

  external ShadowRootMode get mode;
  external set mode(ShadowRootMode value);
  external bool get delegatesFocus;
  external set delegatesFocus(bool value);
  external SlotAssignmentMode get slotAssignment;
  external set slotAssignment(SlotAssignmentMode value);
  external bool get clonable;
  external set clonable(bool value);
  external bool get serializable;
  external set serializable(bool value);
}

/// The **`NamedNodeMap`** interface represents a collection of [Attr] objects.
/// Objects inside a `NamedNodeMap` are not in any particular order, unlike
/// [NodeList], although they may be accessed by an index as in an array.
///
/// A `NamedNodeMap` object is _live_ and will thus be auto-updated if changes
/// are made to its contents internally or elsewhere.
///
/// > [!NOTE]
/// > Although called `NamedNodeMap`, this interface doesn't deal with [Node]
/// > objects but with [Attr] objects, which are a specialized class of [Node]
/// > objects.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap).
extension type NamedNodeMap._(JSObject _) implements JSObject {
  /// The **`item()`** method of the [NamedNodeMap] interface
  /// returns the item in the map matching the index.
  ///
  /// > [!NOTE]
  /// > This method is also called when you use the operator `[]` syntax.
  /// > So, `myMap[i]` is equivalent to `myMap.item(i)` where `i` is a number.
  external Attr? item(int index);

  /// The **`getNamedItem()`** method of the [NamedNodeMap] interface returns
  /// the [Attr] corresponding to the given name, or `null` if there is no
  /// corresponding attribute.
  ///
  /// > [!NOTE]
  /// > This method is also called when you use the operator `[]` syntax.
  /// > So, `myMap[str]` is equivalent to `myMap.getNamedItem(str)` where `str`
  /// > is a string.
  external Attr? getNamedItem(String qualifiedName);

  /// The **`getNamedItemNS()`** method of the [NamedNodeMap] interface returns
  /// the [Attr] corresponding to the given local name in the given namespace,
  /// or `null` if there is no corresponding attribute.
  external Attr? getNamedItemNS(
    String? namespace,
    String localName,
  );

  /// The **`setNamedItem()`** method of the [NamedNodeMap] interface
  /// puts the [Attr] identified by its name in the map.
  /// If there is already an [Attr] with the same name in the map,
  /// it is _replaced_.
  external Attr? setNamedItem(Attr attr);

  /// The **`setNamedItemNS()`** method of the [NamedNodeMap] interface
  /// puts the [Attr] identified by its name in the map.
  /// If there was already an [Attr] with the same name in the map,
  /// it is _replaced_.
  ///
  /// > [!NOTE]
  /// > This method is an alias of `setNamedItem()` you can use them
  /// > interchangeably.
  external Attr? setNamedItemNS(Attr attr);

  /// The **`removeNamedItem()`** method of the [NamedNodeMap] interface
  /// removes the [Attr] corresponding to the given name from the map.
  external Attr removeNamedItem(String qualifiedName);

  /// The **`removeNamedItemNS()`** method of the [NamedNodeMap] interface
  /// removes the [Attr] corresponding to the given namespace and local name
  /// from the map.
  external Attr removeNamedItemNS(
    String? namespace,
    String localName,
  );

  /// The read-only **`length`** property of the [NamedNodeMap] interface
  /// is the number of objects stored in the map.
  external int get length;
}

/// The **`Attr`** interface represents one of an element's attributes as an
/// object. In most situations, you will directly retrieve the attribute value
/// as a string (e.g., [Element.getAttribute]), but some cases may require
/// interacting with `Attr` instances (e.g., [Element.getAttributeNode]).
///
/// The core idea of an object of type `Attr` is the association between a
/// _name_ and a _value_. An attribute may also be part of a _namespace_ and, in
/// this case, it also has a URI identifying the namespace, and a prefix that is
/// an abbreviation for the namespace.
///
/// The name is deemed _local_ when it ignores the eventual namespace prefix and
/// deemed _qualified_ when it includes the prefix of the namespace, if any,
/// separated from the local name by a colon (`:`). We have three cases: an
/// attribute outside of a namespace, an attribute inside a namespace without a
/// prefix defined, an attribute inside a namespace with a prefix:
///
/// | Attribute | Namespace name | Namespace prefix | Attribute local name | Attribute qualified name |
/// | --------- | -------------- | ---------------- | -------------------- | ------------------------ |
/// | `myAttr`  | _none_         | _none_           | `myAttr`             | `myAttr`                 |
/// | `myAttr`  | `mynamespace`  | _none_           | `myAttr`             | `myAttr`                 |
/// | `myAttr`  | `mynamespace`  | `myns`           | `myAttr`             | `myns:myAttr`            |
///
/// > [!NOTE]
/// > This interface represents only attributes present in the tree
/// > representation of the [Element], being a SVG, an HTML or a MathML element.
/// > It doesn't represent the _property_ of an interface associated with such
/// > element, such as [HTMLTableElement] for a `table` element. (See  for more
/// > information about attributes and how they are _reflected_ into
/// > properties.)
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Attr).
extension type Attr._(JSObject _) implements Node, JSObject {
  /// The read-only **`namespaceURI`** property of the [Attr] interface returns
  /// the namespace URI of the attribute,
  /// or `null` if the element is not in a namespace.
  ///
  /// The namespace URI is set at the [Attr] creation and cannot be changed.
  /// An attribute with a namespace can be created using
  /// [Element.setAttributeNS].
  ///
  /// > [!NOTE]
  /// > An attribute does not inherit its namespace from the element it is
  /// > attached to.
  /// > If an attribute is not explicitly given a namespace, it has no
  /// > namespace.
  ///
  /// The browser does not handle or enforce namespace validation per se. It is
  /// up to the JavaScript
  /// application to do any necessary validation. Note, too, that the namespace
  /// prefix, once it
  /// is associated with a particular attribute node, cannot be changed.
  external String? get namespaceURI;

  /// The read-only **`prefix`** property of the [Attr] returns the namespace
  /// prefix of the attribute, or `null` if no prefix is specified.
  ///
  /// The prefix is always in lower case, whatever case is used at the attribute
  /// creation.
  ///
  /// > [!NOTE]
  /// > Only XML supports namespaces. HTML does not. That means that the prefix
  /// > of an attribute of an HTML element will always be `null`.
  ///
  /// Also, only the `xml` (for the `xml:lang` attribute), `xlink` (for the
  /// `xlink:href`, `xlink:show`, `xlink:target` and `xlink:title` attributes)
  /// and `xpath` namespaces are supported, and only on SVG and MathML elements.
  external String? get prefix;

  /// The read-only **`localName`** property of the [Attr] interface returns the
  /// _local part_ of the _qualified name_ of an attribute, that is the name of
  /// the attribute, stripped from any namespace in front of it. For example, if
  /// the qualified name is `xml:lang`, the returned local name is `lang`, if
  /// the element supports that namespace.
  ///
  /// The local name is always in lower case, whatever case at the attribute
  /// creation.
  ///
  /// > [!NOTE]
  /// > HTML only supports a fixed set of namespaces on SVG and MathML elements.
  /// > These are `xml` (for the `xml:lang` attribute), `xlink` (for the
  /// > `xlink:href`, `xlink:show`, `xlink:target` and `xlink:title` attributes)
  /// > and `xpath`.
  /// >
  /// > That means that the local name of an attribute of an HTML element is
  /// > always be equal to its qualified name: Colons are treated as regular
  /// > characters. In XML, like in SVG or MathML, the colon denotes the end of
  /// > the prefix and what is before is the namespace; the local name may be
  /// > different from the qualified name.
  external String get localName;

  /// The read-only **`name`** property of the [Attr] interface returns the
  /// _qualified name_ of an attribute, that is the name of the attribute, with
  /// the namespace prefix, if any, in front of it. For example, if the local
  /// name is `lang` and the namespace prefix is `xml`, the returned qualified
  /// name is `xml:lang`.
  ///
  /// The qualified name is always in lower case, whatever case at the attribute
  /// creation.
  external String get name;

  /// The **`value`** property of the [Attr] interface contains the value of the
  /// attribute.
  external String get value;
  external set value(String value);

  /// The read-only **`ownerElement`** property of the [Attr] interface returns
  /// the [Element] the attribute belongs to.
  external Element? get ownerElement;

  /// The read-only **`specified`** property of the [Attr] interface always
  /// returns `true`.
  external bool get specified;
}

/// The **`CharacterData`** abstract interface represents a [Node] object that
/// contains characters. This is an abstract interface, meaning there aren't any
/// objects of type `CharacterData`: it is implemented by other interfaces like
/// [Text], [Comment], [CDATASection], or [ProcessingInstruction], which aren't
/// abstract.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData).
extension type CharacterData._(JSObject _) implements Node, JSObject {
  /// The **`substringData()`** method of the [CharacterData] interface
  /// returns a portion of the existing data,
  /// starting at the specified index
  /// and extending for a given number of characters afterwards.
  external String substringData(
    int offset,
    int count,
  );

  /// The **`appendData()`** method of the [CharacterData] interface
  /// adds the provided data to the end of the node's current data.
  external void appendData(String data);

  /// The **`insertData()`** method of the [CharacterData] interface
  /// inserts the provided data into this `CharacterData` node's current data,
  /// at the provided offset from the start of the existing data.
  /// The provided data is spliced into the existing data.
  external void insertData(
    int offset,
    String data,
  );

  /// The **`deleteData()`** method of the [CharacterData] interface
  /// removes all or part of the data from this `CharacterData` node.
  external void deleteData(
    int offset,
    int count,
  );

  /// The **`replaceData()`** method of the [CharacterData] interface removes a
  /// certain number of characters of the existing text in a given
  /// `CharacterData` node and replaces those characters with the text provided.
  external void replaceData(
    int offset,
    int count,
    String data,
  );

  /// The **`before()`** method of the [CharacterData] interface
  /// inserts a set of [Node] objects and strings
  /// in the children list of the `CharacterData`'s parent, just before the
  /// `CharacterData` node.
  ///
  /// Strings are inserted as [Text] nodes; the string is being passed as
  /// argument to the [Text.Text] constructor.
  external void before([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`after()`** method of the [CharacterData] interface
  /// inserts a set of [Node] objects or strings in the children list of the
  /// object's parent, just after the object itself.
  ///
  /// Strings are inserted as [Text] nodes; the string is being passed as
  /// argument to the [Text.Text] constructor.
  external void after([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`replaceWith()`** method of the [CharacterData] interface
  /// replaces this node in the children list of its parent
  /// with a set of [Node] objects or string.
  ///
  /// Strings are inserted as [Text] nodes; the string is being passed as
  /// argument to the [Text.Text] constructor.
  external void replaceWith([
    JSAny node1,
    JSAny node2,
    JSAny node3,
    JSAny node4,
  ]);

  /// The **`remove()`** method of the [CharacterData] removes the text
  /// contained in the node.
  external void remove();

  /// The **`data`** property of the [CharacterData] interface represent the
  /// value of the current object's data.
  external String get data;
  external set data(String value);

  /// The read-only **`CharacterData.length`** property
  /// returns the number of characters in the contained data, as a positive
  /// integer.
  external int get length;

  /// The read-only **`previousElementSibling`** property of the [CharacterData]
  /// interface
  /// returns the first [Element] before the current node in its parent's
  /// children list,
  /// or `null` if there is none.
  external Element? get previousElementSibling;

  /// The read-only **`nextElementSibling`** property of the [CharacterData]
  /// interface
  /// returns the first [Element] node following the specified one in its
  /// parent's
  /// children list, or `null` if the specified element is the last one in the
  /// list.
  external Element? get nextElementSibling;
}

/// The **`Text`** interface represents a text [Node] in a DOM tree.
///
/// To understand what a text node is, consider the following document:
///
/// ```html
/// <html lang="en" class="e">
///   <head>
///     <title>Aliens?</title>
///   </head>
///   <body>
///     Why yes.
///   </body>
/// </html>
/// ```
///
/// In that document, there are five text nodes, with the following contents:
///
/// - `"\n    "` (after the `<head>` start tag, a newline followed by four
///   spaces)
/// - `"Aliens?"` (the contents of the `title` element)
/// - `"\n  "` (after the `</head>` end tag, a newline followed by two spaces)
/// - `"\n  "` (after the `<body>` start tag, a newline followed by two spaces)
/// - `"\n Why yes.\n \n\n"` (the contents of the `body` element)
///
/// Each of those text nodes is an object that has the properties and methods
/// documented in this article.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Text).
extension type Text._(JSObject _) implements CharacterData, JSObject {
  external factory Text([String data]);

  /// The **`splitText()`** method of the [Text] interface
  /// breaks the [Text] node into two nodes at the specified offset,
  /// keeping both nodes in the tree as siblings.
  ///
  /// After the split, the current node contains all the content
  /// up to the specified offset point,
  /// and a newly created node of the same type contains the remaining text.
  /// The newly created node is returned to the caller.
  /// If the original node had a parent, the new node is inserted as the next
  /// sibling of the original node.
  /// If the offset is equal to the length of the original node,
  /// the newly created node has no data.
  ///
  /// Separated text nodes can be concatenated using the [Node.normalize]
  /// method.
  external Text splitText(int offset);

  /// The read-only **`wholeText`** property of the [Text] interface
  /// returns the full text of all [Text] nodes logically adjacent to the node.
  /// The text is concatenated in document order.
  /// This allows specifying any text node and obtaining all adjacent text as a
  /// single string.
  ///
  /// > [!NOTE]
  /// > This is similar to calling [Node.normalize] followed by reading the text
  /// > value,
  /// > but without modifying the tree.
  external String get wholeText;

  /// The read-only **`assignedSlot`** property of the [Text] interface
  /// returns the [HTMLSlotElement] object associated with the element.
  external HTMLSlotElement? get assignedSlot;
}

/// The **`CDATASection`** interface represents a CDATA section
/// that can be used within XML to include extended portions of unescaped text.
/// When inside a CDATA section, the symbols `<` and `&` don't need escaping
/// as they normally do.
///
/// In XML, a CDATA section looks like:
///
/// ```xml
/// <![CDATA[ … ]]>
/// ```
///
/// For example:
///
/// ```xml
/// <foo>
///   Here is a CDATA section: <![CDATA[ < > & ]]> with all kinds of unescaped text.
/// </foo>
/// ```
///
/// The only sequence which is not allowed within a CDATA section is the closing
/// sequence
/// of a CDATA section itself, `]]>`.
///
/// > [!NOTE]
/// > CDATA sections should not be used within HTML. They are considered
/// > comments and are not displayed.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/CDATASection).
extension type CDATASection._(JSObject _) implements Text, JSObject {}

/// The **`ProcessingInstruction`** interface represents a
/// [processing instruction](https://www.w3.org/TR/xml/#sec-pi); that is, a
/// [Node] which embeds an instruction targeting a specific application but that
/// can be ignored by any other applications which don't recognize the
/// instruction.
///
/// > **Warning:** `ProcessingInstruction` nodes are only supported in XML
/// > documents, not in HTML documents. In these, a process instruction will be
/// > considered as a comment and be represented as a [Comment] object in the
/// > tree.
///
/// A processing instruction may be different than the
/// [XML declaration](https://developer.mozilla.org/en-US/docs/Web/XML/Guides/XML_introduction#xml_declaration).
///
/// > [!NOTE]
/// > User-defined processing instructions cannot begin with `"xml"`, as
/// > `xml`-prefixed processing-instruction target names are reserved by the XML
/// > specification for particular, standard uses (see, for example,
/// > `<?xml-stylesheet ?>`.
///
/// For example:
///
/// ```html
/// <?xml version="1.0"?>
/// ```
///
/// is a processing instruction whose `target` is `xml`.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/ProcessingInstruction).
extension type ProcessingInstruction._(JSObject _)
    implements CharacterData, JSObject {
  /// The read-only **`target`** property of the [ProcessingInstruction]
  /// interface
  /// represent the application to which the `ProcessingInstruction` is
  /// targeted.
  ///
  /// For example:
  ///
  /// ```html
  /// <?xml version="1.0"?>
  /// ```
  ///
  /// is a processing instruction whose `target` is `xml`.
  external String get target;

  /// The read-only **`sheet`** property of the [ProcessingInstruction]
  /// interface
  /// contains the stylesheet associated to the `ProcessingInstruction`.
  ///
  /// The `xml-stylesheet` processing instruction is used to associate a
  /// stylesheet in an XML file.
  external CSSStyleSheet? get sheet;
}

/// The **`Comment`** interface represents textual notations within markup;
/// although it is generally not visually shown, such comments are available to
/// be read in the source view.
///
/// Comments are represented in HTML and XML as content between `<!--` and
/// `-->`. In XML, like inside SVG or MathML markup, the character sequence `--`
/// cannot be used within a comment.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Comment).
extension type Comment._(JSObject _) implements CharacterData, JSObject {
  external factory Comment([String data]);
}

/// The **`AbstractRange`** abstract interface is the base class upon which all
/// range types are defined. A **range** is an object that indicates the start
/// and end points of a section of content within the document.
///
/// > [!NOTE]
/// > As an abstract interface, you will not directly instantiate an object of
/// > type `AbstractRange`. Instead, you will use the [Range] or [StaticRange]
/// > interfaces. To understand the difference between those two interfaces, and
/// > how to choose which is appropriate for your needs, consult each
/// > interface's documentation.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/AbstractRange).
extension type AbstractRange._(JSObject _) implements JSObject {
  /// The read-only **`startContainer`** property of the [AbstractRange]
  /// interface returns the start [Node] for the range.
  external Node get startContainer;

  /// The read-only **`startOffset`** property of the [AbstractRange] interface
  /// returns the offset into the start node of the range's start position.
  external int get startOffset;

  /// The read-only **`endContainer`** property of the [AbstractRange] interface
  /// returns the [Node] in which the end of the range is located.
  external Node get endContainer;

  /// The **`endOffset`** property of the [AbstractRange] interface returns the
  /// offset into the end node of the range's end position.
  external int get endOffset;

  /// The read-only **`collapsed`** property of the [AbstractRange] interface
  /// returns `true` if the range's start position and end position are the
  /// same.
  external bool get collapsed;
}
extension type StaticRangeInit._(JSObject _) implements JSObject {
  external factory StaticRangeInit({
    required Node startContainer,
    required int startOffset,
    required Node endContainer,
    required int endOffset,
  });

  external Node get startContainer;
  external set startContainer(Node value);
  external int get startOffset;
  external set startOffset(int value);
  external Node get endContainer;
  external set endContainer(Node value);
  external int get endOffset;
  external set endOffset(int value);
}

/// The
/// [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)
/// **`StaticRange`** interface extends [AbstractRange] to provide a method to
/// specify a range of content in the DOM whose contents don't update to reflect
/// changes which occur within the DOM tree.
///
/// This interface offers the same set of properties and methods as
/// `AbstractRange`.
///
/// `AbstractRange` and `StaticRange` are not available from
/// [web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API).
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/StaticRange).
extension type StaticRange._(JSObject _) implements AbstractRange, JSObject {
  external factory StaticRange(StaticRangeInit init);
}

/// The **`Range`** interface represents a fragment of a document that can
/// contain nodes and parts of text nodes.
///
/// A range can be created by using the [Document.createRange] method. Range
/// objects can also be retrieved by using the [Selection.getRangeAt] method of
/// the [Selection] object or the [Document.caretRangeFromPoint] method of the
/// [Document] object.
///
/// There also is the [Range.Range] constructor available.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Range).
extension type Range._(JSObject _) implements AbstractRange, JSObject {
  external factory Range();

  static const int START_TO_START = 0;

  static const int START_TO_END = 1;

  static const int END_TO_END = 2;

  static const int END_TO_START = 3;

  /// The **`Range.setStart()`** method sets the start position of a
  /// [Range].
  ///
  /// If the `startNode` is a [Node] of type [Text],
  /// [Comment], or [CDataSection], then `startOffset` is
  /// the number of characters from the start of `startNode`. For other
  /// `Node` types, `startOffset` is the number of child nodes between
  /// the start of the `startNode`.
  ///
  /// Setting the start point below (lower in the document) the end point will
  /// result in a
  /// collapsed range with the start and end points both set to the specified
  /// start position.
  external void setStart(
    Node node,
    int offset,
  );

  /// The **`Range.setEnd()`** method sets the end position of a [Range] to be
  /// located at the given offset into the specified node x.Setting
  /// the end point above (higher in the document) than the start point will
  /// result in a
  /// collapsed range with the start and end points both set to the specified
  /// end position.
  external void setEnd(
    Node node,
    int offset,
  );

  /// The **`Range.setStartBefore()`** method sets the start position
  /// of a [Range] relative to another [Node]. The parent
  /// [Node] of the start of the [Range] will be the same as that
  /// for the `referenceNode`.
  external void setStartBefore(Node node);

  /// The **`Range.setStartAfter()`** method sets the start position
  /// of a [Range] relative to a [Node]. The parent
  /// [Node] of the start of the [Range] will be the same as that
  /// for the `referenceNode`.
  external void setStartAfter(Node node);

  /// The **`Range.setEndBefore()`** method sets the end position of
  /// a `Range` relative to another [Node]. The parent
  /// `Node` of end of the `Range` will be the same as that for the
  /// `referenceNode`.
  external void setEndBefore(Node node);

  /// The **`Range.setEndAfter()`** method sets the end position of a
  /// [Range] relative to another [Node]. The parent
  /// `Node` of end of the `Range` will be the same as that for the
  /// `referenceNode`.
  external void setEndAfter(Node node);

  /// The **`Range.collapse()`** method collapses the
  /// [Range] to one of its boundary points.
  ///
  /// A collapsed [Range] is empty, containing no content, specifying a
  /// single-point in a DOM tree. To determine if a [Range] is already
  /// collapsed,
  /// see the [Range.collapsed] property.
  external void collapse([bool toStart]);

  /// The **`Range.selectNode()`** method sets the
  /// [Range] to contain the [Node] and its contents. The parent
  /// [Node] of the start and end of the [Range] will be the same as
  /// the parent of the _referenceNode_.
  external void selectNode(Node node);

  /// The **`Range.selectNodeContents()`** method sets the [Range] to contain
  /// the contents of a [Node].
  ///
  /// The parent `Node` of the start and end of the `Range` will be the
  /// reference node. The `startOffset` is 0, and the `endOffset` is the
  /// number of child `Node`s or number of characters contained in the reference
  /// node.
  external void selectNodeContents(Node node);

  /// The
  /// **`Range.compareBoundaryPoints()`** method compares the
  /// boundary points of the [Range] with those of another range.
  external int compareBoundaryPoints(
    int how,
    Range sourceRange,
  );

  /// The **`Range.deleteContents()`** method removes the contents of
  /// the [Range] from the [Document].
  ///
  /// In the context of a [Range], when a node is partially selected—meaning it
  /// overlaps with the start or end of the selection—only the selected portion
  /// of the text is deleted, while the node itself remains intact. However, if
  /// a node is fully selected, the entire node and its contents are removed.
  ///
  /// Unlike [Range.extractContents], this method does not return a
  /// [DocumentFragment] containing the deleted content.
  external void deleteContents();

  /// The **`Range.extractContents()`** method moves contents of the
  /// [Range] from the document tree into a [DocumentFragment].
  ///
  /// Event listeners added using DOM Events are not retained during extraction.
  /// HTML
  /// attribute events are retained or duplicated as they are for the
  /// [Node.cloneNode] method. HTML `id` attributes are also cloned,
  /// which can lead to an invalid document if a partially-selected node is
  /// extracted and
  /// appended to the document.
  ///
  /// Partially selected nodes are cloned to include the parent tags necessary
  /// to make the
  /// document fragment valid.
  external DocumentFragment extractContents();

  /// The **`Range.cloneContents()`** returns a [DocumentFragment] copying the
  /// objects of type [Node]
  /// included in the [Range].
  ///
  /// Event listeners added using [EventTarget.addEventListener]
  /// are not copied during cloning. HTML attribute events are duplicated as
  /// they are
  /// for the [Node.cloneNode] method. HTML `id` attributes
  /// are also cloned, which can lead to an invalid document through cloning.
  ///
  /// Partially selected nodes include the parent tags necessary to make the
  /// document
  /// fragment valid.
  external DocumentFragment cloneContents();

  /// The **`Range.insertNode()`** method inserts a node at the start
  /// of the [Range].
  ///
  /// The new node is inserted at the start boundary point of the `Range`. If
  /// the
  /// new node is to be added to a text [Node], that `Node` is split
  /// at the insertion point, and the insertion occurs between the two text
  /// nodes.
  ///
  /// If the new node is a document fragment, the children of the document
  /// fragment are
  /// inserted instead.
  external void insertNode(Node node);

  /// The **`Range.surroundContents()`** method moves content of the
  /// [Range] into a new node, placing the new node at the start of the
  /// specified range.
  ///
  /// This method is nearly equivalent to
  /// `newNode.appendChild(range.extractContents()); range.insertNode(newNode)`.
  /// After surrounding, the boundary points of the `range` include
  /// `newNode`.
  ///
  /// An exception will be thrown, however, if the [Range] splits a non-[Text]
  /// node with only one of its boundary points. That is, unlike the
  /// alternative above, if there are partially selected nodes, they will not be
  /// cloned and
  /// instead the operation will fail.
  external void surroundContents(Node newParent);

  /// The **`Range.cloneRange()`** method returns a
  /// [Range] object with boundary points identical to the cloned
  /// [Range].
  ///
  /// The returned clone is copied by value, not reference, so a change in
  /// either
  /// [Range] does not affect the other.
  external Range cloneRange();

  /// The **`Range.detach()`** method does nothing. It used to
  /// disable the [Range] object and enable the browser to release associated
  /// resources. The method has been kept for compatibility.
  external void detach();

  /// The **`Range.isPointInRange()`** method returns a boolean
  /// indicating whether the given point is in the [Range]. It returns
  /// `true` if the point (cursor position) at `offset` within
  /// `ReferenceNode` is within this range.
  external bool isPointInRange(
    Node node,
    int offset,
  );

  /// The **`Range.comparePoint()`** method returns `-1`,
  /// `0`, or `1` depending on whether the `referenceNode` is
  /// before, the same as, or after the [Range].
  ///
  /// If the _reference node_ is a [Node] of type [Text],
  /// [Comment], or [CDATASection], then offset is the number of
  /// characters from the start of _reference node_. For other [Node]
  /// types, offset is the number of child nodes between the start of the
  /// _reference
  /// node_.
  external int comparePoint(
    Node node,
    int offset,
  );

  /// The **`Range.intersectsNode()`** method returns a boolean
  /// indicating whether the given [Node] intersects the [Range].
  external bool intersectsNode(Node node);

  /// The **`Range.getClientRects()`** method returns a list of [DOMRect]
  /// objects representing the area of the screen occupied by the
  /// [range](https://developer.mozilla.org/en-US/docs/Web/API/Range). This is
  /// created by aggregating the results of calls to
  /// [Element.getClientRects] for all the elements in the range.
  external DOMRectList getClientRects();

  /// The **`Range.getBoundingClientRect()`** method returns a [DOMRect] object
  /// that bounds the contents of the range; this is a rectangle
  /// enclosing the union of the bounding rectangles for all the elements in the
  /// range.
  ///
  /// This method is useful for determining the viewport coordinates of the
  /// cursor or
  /// selection inside a text box. See [Element.getBoundingClientRect] for
  /// details on the returned value.
  external DOMRect getBoundingClientRect();

  /// The **`Range.createContextualFragment()`** method returns a
  /// [DocumentFragment] by invoking the HTML fragment parsing algorithm or the
  /// XML fragment parsing algorithm with the start of the range (the _parent_
  /// of the
  /// selected node) as the context node. The HTML fragment parsing algorithm is
  /// used if the
  /// range belongs to a `Document` whose HTMLness bit is set. In the HTML case,
  /// if
  /// the context node would be `html`, for historical reasons the fragment
  /// parsing
  /// algorithm is invoked with `body` as the context instead.
  external DocumentFragment createContextualFragment(JSAny string);

  /// The **`Range.commonAncestorContainer`** read-only property
  /// returns the deepest — or furthest down the document tree — [Node] that
  /// contains both
  /// [boundary points](https://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position-h3)
  /// of the [Range]. This means that if
  /// [Range.startContainer] and [Range.endContainer] both refer to
  /// the same node, this node is the **common ancestor container**.
  ///
  /// Since a `Range` need not be continuous, and may also partially select
  /// nodes,
  /// this is a convenient way to find a `Node` which encloses a
  /// `Range`.
  ///
  /// This property is read-only. To change the ancestor container of a `Node`,
  /// consider using the various methods available to set the start and end
  /// positions of the
  /// `Range`, such as [Range.setStart] and
  /// [Range.setEnd].
  external Node get commonAncestorContainer;
}

/// The **`NodeIterator`** interface represents an iterator to traverse nodes of
/// a DOM subtree in document order.
///
/// A `NodeIterator` can be created using the [Document.createNodeIterator]
/// method, as follows:
///
/// ```js
/// const nodeIterator = document.createNodeIterator(root, whatToShow, filter);
/// ```
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator).
extension type NodeIterator._(JSObject _) implements JSObject {
  /// The **`NodeIterator.nextNode()`** method returns the next node
  /// in the set represented by the [NodeIterator] and advances the position of
  /// the iterator within the set. The first call to `nextNode()` returns the
  /// first node in the set.
  ///
  /// This method returns `null` when there are no nodes left in the set.
  ///
  /// In old browsers, as specified in old versions of the specifications, the
  /// method may
  /// throws the `INVALID_STATE_ERR` [DOMException] if this method
  /// is called after the [NodeIterator.detach] method. Recent browsers never
  /// throw.
  external Node? nextNode();

  /// The **`NodeIterator.previousNode()`** method returns the
  /// previous node in the set represented by the [NodeIterator] and moves the
  /// position of the iterator backwards within the set.
  ///
  /// This method returns `null` when the current node is the first node in the
  /// set.
  ///
  /// In old browsers, as specified in old versions of the specifications, the
  /// method may
  /// throws the `INVALID_STATE_ERR` [DOMException] if this method
  /// is called after the [NodeIterator.detach] method. Recent browsers never
  /// throw.
  external Node? previousNode();

  /// The **`NodeIterator.detach()`** method is a no-op, kept for
  /// backward compatibility only.
  ///
  /// Originally, it detached the [NodeIterator] from the set over which it
  /// iterates, releasing any resources used by the set and setting the
  /// iterator's state to
  /// `INVALID`. Once this method had been called, calls to other methods on
  /// `NodeIterator` would raise the `INVALID_STATE_ERR` exception.
  external void detach();

  /// The **`NodeIterator.root`** read-only property represents the
  /// [Node] that is the root of what the [NodeIterator]
  /// traverses.
  external Node get root;

  /// The **`NodeIterator.referenceNode`** read-only property returns the
  /// [Node] to which the iterator is anchored; as new nodes are inserted, the
  /// iterator remains anchored to the reference node as specified by this
  /// property.
  external Node get referenceNode;

  /// The **`NodeIterator.pointerBeforeReferenceNode`** read-only
  /// property returns a boolean flag that indicates whether the
  /// `NodeFilter` is anchored before (if this value is `true`) or
  /// after (if this value is `false`) the anchor node indicated by the
  /// [NodeIterator.referenceNode] property.
  external bool get pointerBeforeReferenceNode;

  /// The **`NodeIterator.whatToShow`** read-only property represents
  /// an `unsigned integer` representing a bitmask signifying what types of
  /// nodes
  /// should be returned by the [NodeIterator].
  external int get whatToShow;

  /// The **`NodeIterator.filter`** read-only property returns a
  /// `NodeFilter` object, that is an object which implements an
  /// `acceptNode(node)` method, used to screen nodes.
  ///
  /// When creating the [NodeIterator], the filter object is passed in as the
  /// third parameter, and the object method `acceptNode(node)` is
  /// called on every single node to determine whether or not to accept it. This
  /// function
  /// should return the constant `NodeFilter.FILTER_ACCEPT` for cases when the
  /// node should be accepted and `NodeFilter.FILTER_REJECT` for cases when the
  /// node should be rejected.
  external NodeFilter? get filter;
}

/// The **`TreeWalker`** object represents the nodes of a document subtree and a
/// position within them.
///
/// A `TreeWalker` can be created using the [Document.createTreeWalker] method.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker).
extension type TreeWalker._(JSObject _) implements JSObject {
  /// The **`TreeWalker.parentNode()`** method moves the current
  /// [Node] to the first _visible_ ancestor node in the document order,
  /// and returns the found node. If no such node exists, or if it is above the
  /// `TreeWalker`'s _root node_, it returns `null` and the current
  /// node is not changed.
  external Node? parentNode();

  /// The **`TreeWalker.firstChild()`** method moves the current
  /// [Node] to the first _visible_ child of the current node, and returns
  /// the found child. If no such child exists, it returns `null` and the
  /// current node is not changed.
  external Node? firstChild();

  /// The **`TreeWalker.lastChild()`** method moves the current
  /// [Node] to the last _visible_ child of the current node, and returns
  /// the found child. If no such child exists, it returns `null` and the
  /// current node is not changed.
  external Node? lastChild();

  /// The **`TreeWalker.previousSibling()`** method moves the current
  /// [Node] to its previous sibling, if any, and returns the found sibling. If
  /// there is no such node, it returns `null` and the current node is not
  /// changed.
  external Node? previousSibling();

  /// The **`TreeWalker.nextSibling()`** method moves the current
  /// [Node] to its next sibling, if any, and returns the found sibling. If
  /// there
  /// is no such node, it returns `null` and the current node is not changed.
  external Node? nextSibling();

  /// The **`TreeWalker.previousNode()`** method moves the current
  /// [Node] to the previous _visible_ node in the document order, and
  /// returns the found node. If no such node
  /// exists, or if it is before that the _root node_ defined at the object
  /// construction, it returns `null` and the current node is not changed.
  external Node? previousNode();

  /// The **`TreeWalker.nextNode()`** method moves the current
  /// [Node] to the next _visible_ node in the document order, and returns
  /// the found node. If no such node exists, it returns `null` and the current
  /// node is not changed.
  external Node? nextNode();

  /// The **`TreeWalker.root`** read-only property returns the root [Node] that
  /// the [TreeWalker] traverses.
  external Node get root;

  /// The **`TreeWalker.whatToShow`** read-only property returns a
  /// bitmask that indicates the types of
  /// [nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node) to show.
  /// Non-matching nodes are skipped, but their
  /// children may be included, if relevant. The possible values are:
  ///
  /// <table class="no-markdown">
  ///   <thead>
  ///     <tr>
  ///       <th>Constant</th>
  ///       <th>Numerical value</th>
  ///       <th>Description</th>
  ///     </tr>
  ///   </thead>
  ///   <tbody>
  ///     <tr>
  ///       <td><code>NodeFilter.SHOW_ALL</code></td>
  ///       <td>
  ///         <code>4294967295</code> (that is the max value of <code>unsigned long</code>)
  ///       </td>
  ///       <td>Shows all nodes.</td>
  ///     </tr>
  ///     <tr>
  ///       <td>
  ///         <code>NodeFilter.SHOW_ATTRIBUTE</code>
  ///       </td>
  ///       <td><code>2</code></td>
  ///       <td>
  /// Shows attribute [Attr] nodes. This is meaningful
  /// only when creating a [TreeWalker] with an
  /// [Attr] node as its root; in this case, it means
  /// that the attribute node will appear in the first position of the
  /// iteration or traversal. Since attributes are never children of other
  /// nodes, they do not appear when traversing over the document tree.
  ///       </td>
  ///     </tr>
  ///     <tr>
  ///       <td>
  ///         <code>NodeFilter.SHOW_CDATA_SECTION</code>
  ///       </td>
  ///       <td><code>8</code></td>
  ///       <td>Shows [CDATASection] nodes.</td>
  ///     </tr>
  ///     <tr>
  ///       <td><code>NodeFilter.SHOW_COMMENT</code></td>
  ///       <td><code>128</code></td>
  ///       <td>Shows [Comment] nodes.</td>
  ///     </tr>
  ///     <tr>
  ///       <td><code>NodeFilter.SHOW_DOCUMENT</code></td>
  ///       <td><code>256</code></td>
  ///       <td>Shows [Document] nodes.</td>
  ///     </tr>
  ///     <tr>
  ///       <td><code>NodeFilter.SHOW_DOCUMENT_FRAGMENT</code></td>
  ///       <td><code>1024</code></td>
  ///       <td>Shows [DocumentFragment] nodes.</td>
  ///     </tr>
  ///     <tr>
  ///       <td><code>NodeFilter.SHOW_DOCUMENT_TYPE</code></td>
  ///       <td><code>512</code></td>
  ///       <td>Shows [DocumentType] nodes.</td>
  ///     </tr>
  ///     <tr>
  ///       <td><code>NodeFilter.SHOW_ELEMENT</code></td>
  ///       <td><code>1</code></td>
  ///       <td>Shows [Element] nodes.</td>
  ///     </tr>
  ///     <tr>
  ///       <td><code>NodeFilter.SHOW_ENTITY</code> </td>
  ///       <td><code>32</code></td>
  ///       <td>Legacy, no more used.</td>
  ///     </tr>
  ///     <tr>
  ///       <td>
  ///         <code>NodeFilter.SHOW_ENTITY_REFERENCE</code>
  ///       </td>
  ///       <td><code>16</code></td>
  ///       <td>Legacy, no more used.</td>
  ///     </tr>
  ///     <tr>
  ///       <td>
  ///         <code>NodeFilter.SHOW_NOTATION</code>
  ///       </td>
  ///       <td><code>2048</code></td>
  ///       <td>Legacy, no more used.</td>
  ///     </tr>
  ///     <tr>
  ///       <td><code>NodeFilter.SHOW_PROCESSING_INSTRUCTION</code></td>
  ///       <td><code>64</code></td>
  ///       <td>Shows [ProcessingInstruction] nodes.</td>
  ///     </tr>
  ///     <tr>
  ///       <td><code>NodeFilter.SHOW_TEXT</code></td>
  ///       <td><code>4</code></td>
  ///       <td>Shows [Text] nodes.</td>
  ///     </tr>
  ///   </tbody>
  /// </table>
  external int get whatToShow;

  /// The **`TreeWalker.filter`** read-only property returns the `NodeFilter`
  /// associated with the [TreeWalker].
  ///
  /// When creating the `TreeWalker`, the filter object is passed in as the
  /// third
  /// parameter, and its method `acceptNode()` is called on every
  /// single node to determine whether or not to accept it.
  external NodeFilter? get filter;

  /// The **`TreeWalker.currentNode`** property represents the
  /// [Node] which the [TreeWalker] is currently pointing at.
  external Node get currentNode;
  external set currentNode(Node value);
}

/// The **`DOMTokenList`** interface represents a set of space-separated tokens.
/// Such a set is returned by [Element.classList] or [HTMLLinkElement.relList],
/// and many others.
///
/// A `DOMTokenList` is indexed beginning with `0` as with JavaScript `Array`
/// objects. `DOMTokenList` is always case-sensitive.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList).
extension type DOMTokenList._(JSObject _) implements JSObject {
  /// The **`item()`** method of the [DOMTokenList] interface returns an item in
  /// the list,
  /// determined by its position in the list, its index.
  ///
  /// > [!NOTE]
  /// > This method is equivalent as the
  /// > [bracket notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors#bracket_notation).
  /// > So `aList.item(i)` is the same as `aList[i]`.
  external String? item(int index);

  /// The **`contains()`** method of the [DOMTokenList] interface
  /// returns a boolean value — `true` if the underlying list contains the given
  /// token,
  /// otherwise `false`.
  external bool contains(String token);

  /// The **`add()`** method of the [DOMTokenList] interface adds the given
  /// tokens to the list, omitting any that are already present.
  external void add([
    String token1,
    String token2,
    String token3,
    String token4,
  ]);

  /// The **`remove()`** method of the [DOMTokenList] interface
  /// removes the specified _tokens_ from the list.
  external void remove([
    String token1,
    String token2,
    String token3,
    String token4,
  ]);

  /// The **`toggle()`** method of the [DOMTokenList] interface
  /// removes an existing token from the list and returns `false`.
  /// If the token doesn't exist it's added and the function returns `true`.
  external bool toggle(
    String token, [
    bool force,
  ]);

  /// The **`replace()`** method of the [DOMTokenList] interface
  /// replaces an existing token with a new token.
  /// If the first token doesn't exist, `replace()` returns `false` immediately,
  /// without adding the new token to the token list.
  external bool replace(
    String token,
    String newToken,
  );

  /// The **`supports()`** method of the [DOMTokenList] interface
  /// returns `true` if a given `token` is in the associated attribute's
  /// supported tokens.
  /// This method is intended to support feature detection.
  external bool supports(String token);

  /// The read-only **`length`** property of the [DOMTokenList] interface is an
  /// `integer` representing the number
  /// of objects stored in the object.
  external int get length;

  /// The **`value`** property of the [DOMTokenList]
  /// interface is a  that returns the value of the list serialized as a
  /// string, or clears and sets the list to the given value.
  external String get value;
  external set value(String value);
}

/// The **`XPathResult`** interface represents the results generated by
/// evaluating an XPath expression within the context of a given node.
///
/// Since XPath expressions can result in a variety of result types, this
/// interface makes it possible to determine and handle the type and value of
/// the result.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/XPathResult).
extension type XPathResult._(JSObject _) implements JSObject {
  static const int ANY_TYPE = 0;

  static const int NUMBER_TYPE = 1;

  static const int STRING_TYPE = 2;

  static const int BOOLEAN_TYPE = 3;

  static const int UNORDERED_NODE_ITERATOR_TYPE = 4;

  static const int ORDERED_NODE_ITERATOR_TYPE = 5;

  static const int UNORDERED_NODE_SNAPSHOT_TYPE = 6;

  static const int ORDERED_NODE_SNAPSHOT_TYPE = 7;

  static const int ANY_UNORDERED_NODE_TYPE = 8;

  static const int FIRST_ORDERED_NODE_TYPE = 9;

  /// The **`iterateNext()`** method of the
  /// [XPathResult] interface iterates over a node set result and returns the
  /// next node from it or `null` if there are no more nodes.
  external Node? iterateNext();

  /// The **`snapshotItem()`** method of the
  /// [XPathResult] interface returns an item of the snapshot collection or
  /// `null` in case the index is not within the range of nodes. Unlike the
  /// iterator result, the snapshot does not become invalid, but may not
  /// correspond to the
  /// current document if it is mutated.
  external Node? snapshotItem(int index);

  /// The read-only **`resultType`** property of the
  /// [XPathResult] interface represents the type of the result, as defined by
  /// the type constants.
  external int get resultType;

  /// The read-only **`numberValue`** property of the
  /// [XPathResult] interface returns the numeric value of a result with
  /// [XPathResult.resultType] being `NUMBER_TYPE`.
  external double get numberValue;

  /// The read-only **`stringValue`** property of the
  /// [XPathResult] interface returns the string value of a result with
  /// [XPathResult.resultType] being `STRING_TYPE`.
  external String get stringValue;

  /// The read-only **`booleanValue`** property of the
  /// [XPathResult] interface returns the boolean value of a result with
  /// [XPathResult.resultType] being `BOOLEAN_TYPE`.
  external bool get booleanValue;

  /// The read-only **`singleNodeValue`** property of the
  /// [XPathResult] interface returns a [Node] value or
  /// `null` in case no node was matched of a result with
  /// [XPathResult.resultType] being `ANY_UNORDERED_NODE_TYPE` or
  /// `FIRST_ORDERED_NODE_TYPE`.
  external Node? get singleNodeValue;

  /// The read-only **`invalidIteratorState`** property of the
  /// [XPathResult] interface signifies that the iterator has become invalid. It
  /// is `true` if [XPathResult.resultType] is
  /// `UNORDERED_NODE_ITERATOR_TYPE` or `ORDERED_NODE_ITERATOR_TYPE` and
  /// the document has been modified since this result was returned.
  external bool get invalidIteratorState;

  /// The read-only **`snapshotLength`** property of the
  /// [XPathResult] interface represents the number of nodes in the result
  /// snapshot.
  external int get snapshotLength;
}

/// This interface is a compiled XPath expression that can be evaluated on a
/// document or specific node to return information from its  tree.
///
/// This is useful when an expression will be reused in an application, because
/// it is just compiled once and all namespace prefixes which occur within the
/// expression are preresolved.
///
/// Objects of this type are created by calling
/// [XPathEvaluator.createExpression].
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/XPathExpression).
extension type XPathExpression._(JSObject _) implements JSObject {
  /// The **`evaluate()`** method of the
  /// [XPathExpression] interface executes an
  /// [XPath](https://developer.mozilla.org/en-US/docs/Web/XML/XPath) expression
  /// on the given node or document and
  /// returns an [XPathResult].
  external XPathResult evaluate(
    Node contextNode, [
    int type,
    XPathResult? result,
  ]);
}

/// The `XPathEvaluator` interface allows to compile and evaluate  expressions.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/XPathEvaluator).
extension type XPathEvaluator._(JSObject _) implements JSObject {
  external factory XPathEvaluator();

  /// This method compiles an [XPathExpression] which can then be used for
  /// (repeated) evaluations of the  expression.
  external XPathExpression createExpression(
    String expression, [
    XPathNSResolver? resolver,
  ]);

  /// The **`createNSResolver()`** method of the [XPathEvaluator] interface used
  /// to create a custom `XPathNSResolver` object. It now returns the input
  /// as-is and is only kept for compatibility reasons.
  external Node createNSResolver(Node nodeResolver);

  /// The `evaluate()` method of the [XPathEvaluator] interface
  /// executes an XPath expression on the given node or document and returns an
  /// [XPathResult].
  external XPathResult evaluate(
    String expression,
    Node contextNode, [
    XPathNSResolver? resolver,
    int type,
    XPathResult? result,
  ]);
}

/// An **`XSLTProcessor`** applies an
/// [XSLT](https://developer.mozilla.org/en-US/docs/Web/XML/XSLT) stylesheet
/// transformation to an XML document to
/// produce a new XML document as output. It has methods to load the XSLT
/// stylesheet, to
/// manipulate `<xsl:param>` parameter values, and to apply the
/// transformation to documents.
///
/// ---
///
/// API documentation sourced from
/// [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/XSLTProcessor).
extension type XSLTProcessor._(JSObject _) implements JSObject {
  external factory XSLTProcessor();

  /// The `importStylesheet()` method of the [XSLTProcessor] interface imports
  /// an XSLT stylesheet for the processor.
  external void importStylesheet(Node style);

  /// The `transformToFragment()` method of the [XSLTProcessor] interface
  /// transforms a provided [Node] source to a [DocumentFragment] using the XSLT
  /// stylesheet associated with the `XSLTProcessor`.
  external DocumentFragment transformToFragment(
    Node source,
    Document output,
  );

  /// The `transformToDocument()` method of the [XSLTProcessor] interface
  /// transforms the provided [Node] source to a [Document] using the XSLT
  /// stylesheet associated with `XSLTProcessor`.
  external Document transformToDocument(Node source);

  /// The `setParameter()` method of the [XSLTProcessor] interface sets the
  /// value of a parameter (`<xsl:param>`) in the stylesheet imported in the
  /// processor.
  external void setParameter(
    String namespaceURI,
    String localName,
    JSAny? value,
  );

  /// The `getParameter()` method of the [XSLTProcessor] interface returns the
  /// value of a parameter (`<xsl:param>`) from the stylesheet imported in the
  /// processor.
  external JSAny? getParameter(
    String namespaceURI,
    String localName,
  );

  /// The `removeParameter()` method of the [XSLTProcessor] interface removes
  /// the parameter (`<xsl:param>`) and its value from the stylesheet imported
  /// in the processor.
  external void removeParameter(
    String namespaceURI,
    String localName,
  );

  /// The `clearParameters()` method of the [XSLTProcessor] interface removes
  /// all parameters (`<xsl:param>`) and their values from the stylesheet
  /// imported in the processor. The `XSLTProcessor` will then use the default
  /// values specified in the XSLT stylesheet.
  external void clearParameters();

  /// The `reset()` method of the [XSLTProcessor] interface removes all
  /// parameters (`<xsl:param>`) and the XSLT stylesheet from the processor. The
  /// `XSLTProcessor` will then be in its original state when it was created.
  external void reset();
}
